]> Git Repo - J-u-boot.git/blob - cmd/ti/pd.c
Merge patch series "clk: mediatek: add OPs to support OF_UPSTREAM"
[J-u-boot.git] / cmd / ti / pd.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Power Domain test commands
4  *
5  * Copyright (C) 2020 Texas Instruments Incorporated, <www.ti.com>
6  */
7
8 #include <command.h>
9 #include <dm.h>
10 #include <k3-dev.h>
11
12 static const struct udevice_id ti_pd_of_match[] = {
13         { .compatible = "ti,sci-pm-domain" },
14         { /* sentinel */ }
15 };
16
17 static struct ti_k3_pd_platdata *ti_pd_find_data(void)
18 {
19         struct udevice *dev;
20         int i = 0;
21
22         while (1) {
23                 uclass_get_device(UCLASS_POWER_DOMAIN, i++, &dev);
24                 if (!dev)
25                         return NULL;
26
27                 if (device_is_compatible(dev,
28                                          ti_pd_of_match[0].compatible))
29                         return  dev_get_priv(dev);
30         }
31
32         return NULL;
33 }
34
35 static void dump_lpsc(struct ti_k3_pd_platdata *data, struct ti_pd *pd)
36 {
37         int i;
38         struct ti_lpsc *lpsc;
39         u8 state;
40         static const char * const lpsc_states[] = {
41                 "swrstdis", "syncrst", "disable", "enable", "autosleep",
42                 "autowake", "unknown",
43         };
44
45         for (i = 0; i < data->num_lpsc; i++) {
46                 lpsc = &data->lpsc[i];
47                 if (lpsc->pd != pd)
48                         continue;
49                 state = lpsc_get_state(lpsc);
50                 if (state > ARRAY_SIZE(lpsc_states))
51                         state = ARRAY_SIZE(lpsc_states) - 1;
52                 printf("    LPSC%d: state=%s, usecount=%d\n",
53                        lpsc->id, lpsc_states[state], lpsc->usecount);
54         }
55 }
56
57 static void dump_pd(struct ti_k3_pd_platdata *data, struct ti_psc *psc)
58 {
59         int i;
60         struct ti_pd *pd;
61         u8 state;
62         static const char * const pd_states[] = {
63                 "off", "on", "unknown"
64         };
65
66         for (i = 0; i < data->num_pd; i++) {
67                 pd = &data->pd[i];
68                 if (pd->psc != psc)
69                         continue;
70                 state = ti_pd_state(pd);
71                 if (state > ARRAY_SIZE(pd_states))
72                         state = ARRAY_SIZE(pd_states) - 1;
73                 printf("  PD%d: state=%s, usecount=%d:\n",
74                        pd->id, pd_states[state], pd->usecount);
75                 dump_lpsc(data, pd);
76         }
77 }
78
79 static void dump_psc(struct ti_k3_pd_platdata *data)
80 {
81         int i;
82         struct ti_psc *psc;
83
84         for (i = 0; i < data->num_psc; i++) {
85                 psc = &data->psc[i];
86                 printf("PSC%d [%p]:\n", psc->id, psc->base);
87                 dump_pd(data, psc);
88         }
89 }
90
91 static int do_pd_dump(struct cmd_tbl *cmdtp, int flag, int argc,
92                       char *const argv[])
93 {
94         struct ti_k3_pd_platdata *data;
95
96         data = ti_pd_find_data();
97         if (!data)
98                 return CMD_RET_FAILURE;
99
100         dump_psc(data);
101
102         return 0;
103 }
104
105 static int do_pd_endis(int argc, char *const argv[], u8 state)
106 {
107         u32 psc_id;
108         u32 lpsc_id;
109         int i;
110         struct ti_k3_pd_platdata *data;
111         struct ti_lpsc *lpsc;
112         int ret;
113
114         if (argc < 3)
115                 return CMD_RET_FAILURE;
116
117         data = ti_pd_find_data();
118         if (!data)
119                 return CMD_RET_FAILURE;
120
121         psc_id = dectoul(argv[1], NULL);
122         lpsc_id = dectoul(argv[2], NULL);
123
124         for (i = 0; i < data->num_lpsc; i++) {
125                 lpsc = &data->lpsc[i];
126                 if (lpsc->pd->psc->id != psc_id)
127                         continue;
128                 if (lpsc->id != lpsc_id)
129                         continue;
130                 printf("%s pd [PSC:%d,LPSC:%d]...\n",
131                        state == MDSTAT_STATE_ENABLE ? "Enabling" : "Disabling",
132                        psc_id, lpsc_id);
133                 ret = ti_lpsc_transition(lpsc, state);
134                 if (ret)
135                         return CMD_RET_FAILURE;
136                 else
137                         return 0;
138         }
139
140         printf("No matching psc/lpsc found.\n");
141
142         return CMD_RET_FAILURE;
143 }
144
145 static int do_pd_enable(struct cmd_tbl *cmdtp, int flag, int argc,
146                         char *const argv[])
147 {
148         return do_pd_endis(argc, argv, MDSTAT_STATE_ENABLE);
149 }
150
151 static int do_pd_disable(struct cmd_tbl *cmdtp, int flag, int argc,
152                          char *const argv[])
153 {
154         return do_pd_endis(argc, argv, MDSTAT_STATE_SWRSTDISABLE);
155 }
156
157 static struct cmd_tbl cmd_pd[] = {
158         U_BOOT_CMD_MKENT(dump, 1, 0, do_pd_dump, "", ""),
159         U_BOOT_CMD_MKENT(enable, 3, 0, do_pd_enable, "", ""),
160         U_BOOT_CMD_MKENT(disable, 3, 0, do_pd_disable, "", ""),
161 };
162
163 static int ti_do_pd(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
164 {
165         struct cmd_tbl *c;
166
167         argc--;
168         argv++;
169
170         c = find_cmd_tbl(argv[0], cmd_pd, ARRAY_SIZE(cmd_pd));
171         if (c)
172                 return c->cmd(cmdtp, flag, argc, argv);
173         else
174                 return CMD_RET_USAGE;
175 }
176
177 U_BOOT_LONGHELP(pd,
178            "dump                 - show power domain status\n"
179            "enable [psc] [lpsc]  - enable power domain\n"
180            "disable [psc] [lpsc] - disable power domain\n");
181
182 U_BOOT_CMD(pd, 4, 1, ti_do_pd,
183            "TI power domain control", pd_help_text
184 );
This page took 0.033926 seconds and 4 git commands to generate.