1
2
3
4
5
6
7
8
9#include <common.h>
10#include <linux/delay.h>
11#include <linux/errno.h>
12#include <asm/io.h>
13#include <asm/processor.h>
14#include <asm/arch/psc_defs.h>
15
16
17
18
19
20
21int psc_delay(void)
22{
23 udelay(10);
24 return 10;
25}
26
27
28
29
30
31
32
33
34
35
36
37
38int psc_wait(u32 domain_num)
39{
40 u32 retry;
41 u32 ptstat;
42
43
44
45
46
47
48
49
50
51 retry = 0;
52
53 do {
54 ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT);
55 ptstat = ptstat & (1 << domain_num);
56 } while ((ptstat != 0) && ((retry += psc_delay()) <
57 PSC_PTSTAT_TIMEOUT_LIMIT));
58
59 if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
60 return -1;
61
62 return 0;
63}
64
65
66
67
68
69u32 psc_get_domain_num(u32 mod_num)
70{
71 u32 domain_num;
72
73
74 domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
75 domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
76
77 return domain_num;
78}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94int psc_set_state(u32 mod_num, u32 state)
95{
96 u32 domain_num;
97 u32 pdctl;
98 u32 mdctl;
99 u32 ptcmd;
100 u32 reset_iso;
101 u32 v;
102
103
104
105
106
107 v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
108 domain_num = PSC_REG_MDCFG_GET_PD(v);
109 reset_iso = PSC_REG_MDCFG_GET_RESET_ISO(v);
110
111
112 if (psc_wait(domain_num) != 0)
113 return -1;
114
115
116
117
118
119
120
121
122
123 if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
124 pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
125 pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
126 PSC_REG_VAL_PDCTL_NEXT_ON);
127 __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
128 }
129
130
131 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
132 mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
133 mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
134 __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
135
136
137 ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
138 ptcmd |= (u32)(1<<domain_num);
139 __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
140
141
142 return psc_wait(domain_num);
143}
144
145
146
147
148
149
150
151
152
153
154
155
156int psc_enable_module(u32 mod_num)
157{
158 u32 mdctl;
159
160
161 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
162 if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
163 return 0;
164
165 return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
166}
167
168
169
170
171
172
173
174int psc_disable_module(u32 mod_num)
175{
176 u32 mdctl;
177
178
179 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
180 if ((mdctl & 0x3f) == 0)
181 return 0;
182 mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
183 __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
184
185 return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
186}
187
188
189
190
191
192
193
194
195
196
197
198
199int psc_set_reset_iso(u32 mod_num)
200{
201 u32 v;
202 u32 mdctl;
203
204
205 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
206 mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
207 __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
208
209 v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
210 if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
211 return 0;
212
213 return 1;
214}
215
216
217
218
219
220int psc_disable_domain(u32 domain_num)
221{
222 u32 pdctl;
223 u32 ptcmd;
224
225 pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
226 pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
227 pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
228 __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
229
230 ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
231 ptcmd |= (u32)(1 << domain_num);
232 __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
233
234 return psc_wait(domain_num);
235}
236
237
238
239
240
241
242
243
244
245
246
247int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks)
248{
249 u32 mdctl, ptcmd, mdstat;
250 u32 next_state;
251 int domain_num = psc_get_domain_num(mod_num);
252 int timeout = 100000;
253
254
255 psc_wait(domain_num);
256 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
257
258 if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) {
259 mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
260 __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
261
262 psc_wait(domain_num);
263 }
264
265
266 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
267 next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF :
268 PSC_REG_VAL_MDCTL_NEXT_ON;
269 mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state);
270 __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
271
272 ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
273 ptcmd |= (u32)(1 << domain_num);
274 __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
275 psc_wait(domain_num);
276
277 mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
278 while (timeout) {
279 mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
280
281 if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
282 PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
283 PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
284 break;
285 timeout--;
286 }
287
288 if (!timeout) {
289 printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
290 __func__, mdstat);
291 return -ETIMEDOUT;
292 }
293 return 0;
294}
295
296
297
298
299
300
301
302
303
304
305int psc_module_release_from_reset(u32 mod_num)
306{
307 u32 mdctl, mdstat;
308 int domain_num = psc_get_domain_num(mod_num);
309 int timeout = 100000;
310
311
312 psc_wait(domain_num);
313 mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
314
315 if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) {
316 mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1);
317 __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
318
319 psc_wait(domain_num);
320 }
321 mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
322 while (timeout) {
323 mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
324
325 if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
326 PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
327 PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
328 break;
329 timeout--;
330 }
331
332 if (!timeout) {
333 printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
334 __func__, mdstat);
335 return -ETIMEDOUT;
336 }
337
338 return 0;
339}
340