blob: 305023af1e7d02babd16ab538ce6fb6a7e6c6e3e [file] [log] [blame]
Tero Kristof79753c2021-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
Tero Kristof79753c2021-06-11 11:45:16 +03008#include <command.h>
9#include <dm.h>
10#include <k3-dev.h>
11
12static const struct udevice_id ti_pd_of_match[] = {
13 { .compatible = "ti,sci-pm-domain" },
14 { /* sentinel */ }
15};
16
17static 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
35static 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
57static 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
79static 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
91static 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
105static 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
Simon Glass0b1284e2021-07-24 09:03:30 -0600121 psc_id = dectoul(argv[1], NULL);
122 lpsc_id = dectoul(argv[2], NULL);
Tero Kristof79753c2021-06-11 11:45:16 +0300123
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
145static 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
151static 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
157static 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
163static 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
Tom Rini36162182023-10-07 15:13:08 -0400177U_BOOT_LONGHELP(pd,
Tero Kristof79753c2021-06-11 11:45:16 +0300178 "dump - show power domain status\n"
179 "enable [psc] [lpsc] - enable power domain\n"
Tom Rini36162182023-10-07 15:13:08 -0400180 "disable [psc] [lpsc] - disable power domain\n");
181
182U_BOOT_CMD(pd, 4, 1, ti_do_pd,
183 "TI power domain control", pd_help_text
Tero Kristof79753c2021-06-11 11:45:16 +0300184);