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