Add Broadcom's code for bcm63xx support
[project/bcm63xx/atf.git] / plat / bcm / drivers / pmc_cpu_core.c
1 /*
2 <:copyright-BRCM:2020:DUAL/GPL:standard
3
4 Copyright (c) 2020 Broadcom
5 All Rights Reserved
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License, version 2, as published by
9 the Free Software Foundation (the "GPL").
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16
17 A copy of the GPL is available at http://www.broadcom.com/licenses/GPLv2.php, or by
18 writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 :>
22 */
23 #include <debug.h>
24 #include <platform_def.h>
25 #include <delay_timer.h>
26 #include "pmc_drv.h"
27 #include "pmc_cpu_core.h"
28 #include "BPCM.h"
29
30 void udelay(uint32_t usec);
31
32 #if defined (PLATFORM_FLAVOR_63138)
33 /* this power up function is implemented with assumption that cpu#0 will always
34 * be the first one that's powered up. */
35 int pmc_cpu_core_power_up(unsigned cpu)
36 {
37 int ret;
38 ARM_CONTROL_REG arm_ctrl;
39 ARM_CPUx_PWR_CTRL_REG arm_pwr_ctrl;
40
41 if (cpu == 0) {
42 /* in 63138, cpu#0 should've been powered on either by default or by PMC ROM.
43 * This code is for the future if PMC can shut down all the CPUs in
44 * hibernation and power them back up from other blocks. */
45
46 /* 1) Power on PLL */
47 ret = ReadBPCMRegister(PMB_ADDR_AIP,
48 ARMBPCMRegOffset(arm_control),
49 &arm_ctrl.Reg32);
50 if (ret)
51 return ret;
52 arm_ctrl.Bits.pll_ldo_pwr_on = 1;
53
54 ret = WriteBPCMRegister(PMB_ADDR_AIP,
55 ARMBPCMRegOffset(arm_control),
56 arm_ctrl.Reg32);
57 if (ret)
58 return ret;
59
60 /* wait at least 1.0 usec */
61 udelay(2);
62
63 arm_ctrl.Bits.pll_pwr_on = 1;
64 ret = WriteBPCMRegister(PMB_ADDR_AIP,
65 ARMBPCMRegOffset(arm_control),
66 arm_ctrl.Reg32);
67 if (ret)
68 return ret;
69
70 /* 2) Power up CPU0 */
71 ret = ReadBPCMRegister(PMB_ADDR_AIP,
72 ARMBPCMRegOffset(arm_pwr_ctrl_0),
73 &arm_pwr_ctrl.Reg32);
74 if (ret)
75 return ret;
76 arm_pwr_ctrl.Bits.pwr_on = 0xf;
77
78 ret = WriteBPCMRegister(PMB_ADDR_AIP,
79 ARMBPCMRegOffset(arm_pwr_ctrl_0),
80 arm_pwr_ctrl.Reg32);
81 if (ret)
82 return ret;
83
84 do {
85 ret = ReadBPCMRegister(PMB_ADDR_AIP,
86 ARMBPCMRegOffset(arm_pwr_ctrl_0),
87 &arm_pwr_ctrl.Reg32);
88 if (ret)
89 return ret;
90 } while (arm_pwr_ctrl.Bits.pwr_on_status != 0xf);
91
92 arm_pwr_ctrl.Bits.pwr_ok = 0xf;
93
94 ret = WriteBPCMRegister(PMB_ADDR_AIP,
95 ARMBPCMRegOffset(arm_pwr_ctrl_0),
96 arm_pwr_ctrl.Reg32);
97 if (ret)
98 return ret;
99
100 do {
101 ret = ReadBPCMRegister(PMB_ADDR_AIP,
102 ARMBPCMRegOffset(arm_pwr_ctrl_0),
103 &arm_pwr_ctrl.Reg32);
104 if (ret)
105 return ret;
106 } while (arm_pwr_ctrl.Bits.pwr_ok_status != 0xf);
107
108 arm_ctrl.Bits.pll_clamp_on = 0;
109
110 ret = WriteBPCMRegister(PMB_ADDR_AIP,
111 ARMBPCMRegOffset(arm_control),
112 arm_ctrl.Reg32);
113 if (ret)
114 return ret;
115
116 arm_pwr_ctrl.Bits.clamp_on = 0;
117
118 ret = WriteBPCMRegister(PMB_ADDR_AIP,
119 ARMBPCMRegOffset(arm_pwr_ctrl_0),
120 arm_pwr_ctrl.Reg32);
121 if (ret)
122 return ret;
123
124 /* 3) Power up CPU0 RAM */
125 arm_pwr_ctrl.Bits.mem_pda &= 0xe;
126
127 ret = WriteBPCMRegister(PMB_ADDR_AIP,
128 ARMBPCMRegOffset(arm_pwr_ctrl_0), arm_pwr_ctrl.Reg32);
129 if (ret)
130 return ret;
131
132 arm_pwr_ctrl.Bits.mem_pwr_on = 1;
133
134 ret = WriteBPCMRegister(PMB_ADDR_AIP,
135 ARMBPCMRegOffset(arm_pwr_ctrl_0), arm_pwr_ctrl.Reg32);
136 if (ret)
137 return ret;
138
139 do {
140 ret = ReadBPCMRegister(PMB_ADDR_AIP,
141 ARMBPCMRegOffset(arm_pwr_ctrl_0), &arm_pwr_ctrl.Reg32);
142 if (ret)
143 return ret;
144 } while (arm_pwr_ctrl.Bits.mem_pwr_on_status == 0);
145
146 arm_pwr_ctrl.Bits.mem_pwr_ok = 1;
147
148 ret = WriteBPCMRegister(PMB_ADDR_AIP,
149 ARMBPCMRegOffset(arm_pwr_ctrl_0), arm_pwr_ctrl.Reg32);
150 if (ret)
151 return ret;
152
153 do {
154 ret = ReadBPCMRegister(PMB_ADDR_AIP,
155 ARMBPCMRegOffset(arm_pwr_ctrl_0), &arm_pwr_ctrl.Reg32);
156 if (ret)
157 return ret;
158 } while (arm_pwr_ctrl.Bits.mem_pwr_ok_status == 0);
159
160 arm_pwr_ctrl.Bits.mem_clamp_on = 0;
161
162 ret = WriteBPCMRegister(PMB_ADDR_AIP,
163 ARMBPCMRegOffset(arm_pwr_ctrl_0),
164 arm_pwr_ctrl.Reg32);
165 if (ret)
166 return ret;
167
168 /* 4) Power up L2 cache */
169 pmc_cpu_l2cache_power_up();
170
171 /* 5) de-assert CPU0 reset */
172 arm_ctrl.Bits.cpu0_reset_n = 1;
173
174 ret = WriteBPCMRegister(PMB_ADDR_AIP,
175 ARMBPCMRegOffset(arm_control),
176 arm_ctrl.Reg32);
177 if (ret)
178 return ret;
179 } else if (cpu == 1) {
180 /* check whether CPU1 is up and running already.
181 * Assuming once cpu1_reset_n is set, cpu1 is powered on
182 * and running */
183 ret = ReadBPCMRegister(PMB_ADDR_AIP,
184 ARMBPCMRegOffset(arm_control),
185 &arm_ctrl.Reg32);
186 if (ret)
187 return ret;
188 if (arm_ctrl.Bits.cpu1_reset_n == 1)
189 return 0;
190
191 /* 1) Power up CPU1 */
192 ret = ReadBPCMRegister(PMB_ADDR_AIP,
193 ARMBPCMRegOffset(arm_pwr_ctrl_1),
194 &arm_pwr_ctrl.Reg32);
195 if (ret)
196 return ret;
197 arm_pwr_ctrl.Bits.pwr_on |= 0x3;
198
199 ret = WriteBPCMRegister(PMB_ADDR_AIP,
200 ARMBPCMRegOffset(arm_pwr_ctrl_1),
201 arm_pwr_ctrl.Reg32);
202 if (ret)
203 return ret;
204
205 do {
206 ret = ReadBPCMRegister(PMB_ADDR_AIP,
207 ARMBPCMRegOffset(arm_pwr_ctrl_1),
208 &arm_pwr_ctrl.Reg32);
209 if (ret)
210 return ret;
211 } while ((arm_pwr_ctrl.Bits.pwr_on_status & 0x3) != 0x3);
212
213 arm_pwr_ctrl.Bits.pwr_ok |= 0x3;
214
215 ret = WriteBPCMRegister(PMB_ADDR_AIP,
216 ARMBPCMRegOffset(arm_pwr_ctrl_1),
217 arm_pwr_ctrl.Reg32);
218 if (ret)
219 return ret;
220
221 do {
222 ret = ReadBPCMRegister(PMB_ADDR_AIP,
223 ARMBPCMRegOffset(arm_pwr_ctrl_1),
224 &arm_pwr_ctrl.Reg32);
225 if (ret)
226 return ret;
227 } while ((arm_pwr_ctrl.Bits.pwr_ok_status & 0x3) != 0x3);
228
229 arm_pwr_ctrl.Bits.clamp_on = 0;
230
231 ret = WriteBPCMRegister(PMB_ADDR_AIP,
232 ARMBPCMRegOffset(arm_pwr_ctrl_1),
233 arm_pwr_ctrl.Reg32);
234 if (ret)
235 return ret;
236
237 /* 2) Power up CPU1 RAM */
238 arm_pwr_ctrl.Bits.mem_pda &= 0xe;
239
240 ret = WriteBPCMRegister(PMB_ADDR_AIP,
241 ARMBPCMRegOffset(arm_pwr_ctrl_1),
242 arm_pwr_ctrl.Reg32);
243 if (ret)
244 return ret;
245
246 arm_pwr_ctrl.Bits.mem_pwr_on = 1;
247
248 ret = WriteBPCMRegister(PMB_ADDR_AIP,
249 ARMBPCMRegOffset(arm_pwr_ctrl_1),
250 arm_pwr_ctrl.Reg32);
251 if (ret)
252 return ret;
253
254 do {
255 ret = ReadBPCMRegister(PMB_ADDR_AIP,
256 ARMBPCMRegOffset(arm_pwr_ctrl_1),
257 &arm_pwr_ctrl.Reg32);
258 if (ret)
259 return ret;
260 } while (arm_pwr_ctrl.Bits.mem_pwr_on_status == 0);
261
262 arm_pwr_ctrl.Bits.mem_pwr_ok = 1;
263
264 ret = WriteBPCMRegister(PMB_ADDR_AIP,
265 ARMBPCMRegOffset(arm_pwr_ctrl_1),
266 arm_pwr_ctrl.Reg32);
267 if (ret)
268 return ret;
269
270 do {
271 ret = ReadBPCMRegister(PMB_ADDR_AIP,
272 ARMBPCMRegOffset(arm_pwr_ctrl_1),
273 &arm_pwr_ctrl.Reg32);
274 if (ret)
275 return ret;
276 } while (arm_pwr_ctrl.Bits.mem_pwr_ok_status == 0);
277
278 arm_pwr_ctrl.Bits.mem_clamp_on = 0;
279
280 ret = WriteBPCMRegister(PMB_ADDR_AIP,
281 ARMBPCMRegOffset(arm_pwr_ctrl_1),
282 arm_pwr_ctrl.Reg32);
283 if (ret)
284 return ret;
285
286 /* 3) de-assert reset to CPU1 */
287 arm_ctrl.Bits.cpu1_reset_n = 1;
288
289 ret = WriteBPCMRegister(PMB_ADDR_AIP,
290 ARMBPCMRegOffset(arm_control),
291 arm_ctrl.Reg32);
292 if (ret)
293 return ret;
294 } else {
295 printk("error in %s: we do not have CPU#%d\n", __func__, cpu);
296 return -1;
297 }
298
299 return 0;
300 }
301
302 /* this power_down function is implemented with assumption that CPU#0 will
303 * always be the last one to be powered down */
304 /* Note: all the power_down codes have never been tested in 63138 */
305 int pmc_cpu_core_power_down(unsigned cpu)
306 {
307 int ret;
308 ARM_CONTROL_REG arm_ctrl;
309 ARM_CPUx_PWR_CTRL_REG arm_pwr_ctrl;
310
311 if (cpu == 0) {
312 /* 1) assert reset to CPU0 */
313 ret = ReadBPCMRegister(PMB_ADDR_AIP,
314 ARMBPCMRegOffset(arm_control),
315 &arm_ctrl.Reg32);
316 if (ret)
317 return ret;
318 arm_ctrl.Bits.cpu0_reset_n = 0;
319
320 ret = WriteBPCMRegister(PMB_ADDR_AIP,
321 ARMBPCMRegOffset(arm_control),
322 arm_ctrl.Reg32);
323 if (ret)
324 return ret;
325
326 /* 2) power down L2 cache */
327 pmc_cpu_l2cache_power_down();
328
329 /* 3) power down CPU0 RAM */
330 ret = ReadBPCMRegister(PMB_ADDR_AIP,
331 ARMBPCMRegOffset(arm_pwr_ctrl_0),
332 &arm_pwr_ctrl.Reg32);
333 if (ret)
334 return ret;
335 arm_pwr_ctrl.Bits.mem_clamp_on = 1;
336
337 ret = WriteBPCMRegister(PMB_ADDR_AIP,
338 ARMBPCMRegOffset(arm_pwr_ctrl_0),
339 arm_pwr_ctrl.Reg32);
340 if (ret)
341 return ret;
342
343 arm_pwr_ctrl.Bits.mem_pwr_ok = 0;
344
345 ret = WriteBPCMRegister(PMB_ADDR_AIP,
346 ARMBPCMRegOffset(arm_pwr_ctrl_0),
347 arm_pwr_ctrl.Reg32);
348 if (ret)
349 return ret;
350
351 do {
352 ret = ReadBPCMRegister(PMB_ADDR_AIP,
353 ARMBPCMRegOffset(arm_pwr_ctrl_0),
354 &arm_pwr_ctrl.Reg32);
355 if (ret)
356 return ret;
357 } while (arm_pwr_ctrl.Bits.mem_pwr_ok_status == 0);
358
359 arm_pwr_ctrl.Bits.mem_pwr_on = 0;
360
361 ret = WriteBPCMRegister(PMB_ADDR_AIP,
362 ARMBPCMRegOffset(arm_pwr_ctrl_0),
363 arm_pwr_ctrl.Reg32);
364 if (ret)
365 return ret;
366
367 do {
368 ret = ReadBPCMRegister(PMB_ADDR_AIP,
369 ARMBPCMRegOffset(arm_pwr_ctrl_0),
370 &arm_pwr_ctrl.Reg32);
371 if (ret)
372 return ret;
373 } while (arm_pwr_ctrl.Bits.mem_pwr_on_status == 0);
374
375 arm_pwr_ctrl.Bits.mem_pda |= 0x1;
376
377 ret = WriteBPCMRegister(PMB_ADDR_AIP,
378 ARMBPCMRegOffset(arm_pwr_ctrl_0),
379 arm_pwr_ctrl.Reg32);
380 if (ret)
381 return ret;
382
383 /* 4) Power down CPU0 */
384
385 arm_pwr_ctrl.Bits.clamp_on = 1;
386
387 ret = WriteBPCMRegister(PMB_ADDR_AIP,
388 ARMBPCMRegOffset(arm_pwr_ctrl_0),
389 arm_pwr_ctrl.Reg32);
390 if (ret)
391 return ret;
392
393 arm_ctrl.Bits.pll_clamp_on = 1;
394
395 ret = WriteBPCMRegister(PMB_ADDR_AIP,
396 ARMBPCMRegOffset(arm_control),
397 arm_ctrl.Reg32);
398 if (ret)
399 return ret;
400
401 arm_pwr_ctrl.Bits.pwr_ok = 0x0;
402
403 ret = WriteBPCMRegister(PMB_ADDR_AIP,
404 ARMBPCMRegOffset(arm_pwr_ctrl_0),
405 arm_pwr_ctrl.Reg32);
406 if (ret)
407 return ret;
408
409 do {
410 ret = ReadBPCMRegister(PMB_ADDR_AIP,
411 ARMBPCMRegOffset(arm_pwr_ctrl_0),
412 &arm_pwr_ctrl.Reg32);
413 if (ret)
414 return ret;
415 } while (arm_pwr_ctrl.Bits.pwr_ok_status != 0xf);
416
417 arm_pwr_ctrl.Bits.pwr_on = 0x0;
418
419 ret = WriteBPCMRegister(PMB_ADDR_AIP,
420 ARMBPCMRegOffset(arm_pwr_ctrl_0),
421 arm_pwr_ctrl.Reg32);
422 if (ret)
423 return ret;
424
425 do {
426 ret = ReadBPCMRegister(PMB_ADDR_AIP,
427 ARMBPCMRegOffset(arm_pwr_ctrl_0),
428 &arm_pwr_ctrl.Reg32);
429 if (ret)
430 return ret;
431 } while (arm_pwr_ctrl.Bits.pwr_on_status != 0xf);
432
433 /* 5) power down PLL */
434 arm_ctrl.Bits.pll_pwr_on = 0;
435 ret = WriteBPCMRegister(PMB_ADDR_AIP,
436 ARMBPCMRegOffset(arm_control),
437 arm_ctrl.Reg32);
438 if (ret)
439 return ret;
440
441 /* wait at least 1.0 usec */
442 udelay(2);
443
444 arm_ctrl.Bits.pll_ldo_pwr_on = 0;
445 ret = WriteBPCMRegister(PMB_ADDR_AIP,
446 ARMBPCMRegOffset(arm_control),
447 arm_ctrl.Reg32);
448 if (ret)
449 return ret;
450 } else if (cpu == 1) {
451 /* 1) assert reset to CPU1 */
452 ret = ReadBPCMRegister(PMB_ADDR_AIP,
453 ARMBPCMRegOffset(arm_control),
454 &arm_ctrl.Reg32);
455 if (ret)
456 return ret;
457 arm_ctrl.Bits.cpu1_reset_n = 0;
458
459 ret = WriteBPCMRegister(PMB_ADDR_AIP,
460 ARMBPCMRegOffset(arm_control),
461 arm_ctrl.Reg32);
462 if (ret)
463 return ret;
464
465 /* 2) Power down RAM CPU1 */
466 ret = ReadBPCMRegister(PMB_ADDR_AIP,
467 ARMBPCMRegOffset(arm_pwr_ctrl_1),
468 &arm_pwr_ctrl.Reg32);
469 if (ret)
470 return ret;
471 arm_pwr_ctrl.Bits.mem_clamp_on = 1;
472
473 ret = WriteBPCMRegister(PMB_ADDR_AIP,
474 ARMBPCMRegOffset(arm_pwr_ctrl_1),
475 arm_pwr_ctrl.Reg32);
476 if (ret)
477 return ret;
478
479 arm_pwr_ctrl.Bits.mem_pwr_ok = 0;
480
481 ret = WriteBPCMRegister(PMB_ADDR_AIP,
482 ARMBPCMRegOffset(arm_pwr_ctrl_1),
483 arm_pwr_ctrl.Reg32);
484 if (ret)
485 return ret;
486
487 do {
488 ret = ReadBPCMRegister(PMB_ADDR_AIP,
489 ARMBPCMRegOffset(arm_pwr_ctrl_1),
490 &arm_pwr_ctrl.Reg32);
491 if (ret)
492 return ret;
493 } while (arm_pwr_ctrl.Bits.mem_pwr_ok_status == 0);
494
495 arm_pwr_ctrl.Bits.mem_pwr_on = 0;
496
497 ret = WriteBPCMRegister(PMB_ADDR_AIP,
498 ARMBPCMRegOffset(arm_pwr_ctrl_1),
499 arm_pwr_ctrl.Reg32);
500 if (ret)
501 return ret;
502
503 do {
504 ret = ReadBPCMRegister(PMB_ADDR_AIP,
505 ARMBPCMRegOffset(arm_pwr_ctrl_1),
506 &arm_pwr_ctrl.Reg32);
507 if (ret)
508 return ret;
509 } while (arm_pwr_ctrl.Bits.mem_pwr_on_status == 0);
510
511 arm_pwr_ctrl.Bits.mem_pda |= 0x1;
512
513 ret = WriteBPCMRegister(PMB_ADDR_AIP,
514 ARMBPCMRegOffset(arm_pwr_ctrl_1),
515 arm_pwr_ctrl.Reg32);
516 if (ret)
517 return ret;
518
519 /* 3) Power Down CPU1 */
520 arm_pwr_ctrl.Bits.clamp_on = 1;
521
522 ret = WriteBPCMRegister(PMB_ADDR_AIP,
523 ARMBPCMRegOffset(arm_pwr_ctrl_1),
524 arm_pwr_ctrl.Reg32);
525 if (ret)
526 return ret;
527
528 arm_pwr_ctrl.Bits.pwr_ok &= 0xc;
529
530 ret = WriteBPCMRegister(PMB_ADDR_AIP,
531 ARMBPCMRegOffset(arm_pwr_ctrl_1),
532 arm_pwr_ctrl.Reg32);
533 if (ret)
534 return ret;
535
536 do {
537 ret = ReadBPCMRegister(PMB_ADDR_AIP,
538 ARMBPCMRegOffset(arm_pwr_ctrl_1),
539 &arm_pwr_ctrl.Reg32);
540 if (ret)
541 return ret;
542 } while ((arm_pwr_ctrl.Bits.pwr_ok_status & 0x3) != 0x3);
543
544 arm_pwr_ctrl.Bits.pwr_on &= 0xc;
545
546 ret = WriteBPCMRegister(PMB_ADDR_AIP,
547 ARMBPCMRegOffset(arm_pwr_ctrl_1),
548 arm_pwr_ctrl.Reg32);
549 if (ret)
550 return ret;
551
552 do {
553 ret = ReadBPCMRegister(PMB_ADDR_AIP,
554 ARMBPCMRegOffset(arm_pwr_ctrl_1),
555 &arm_pwr_ctrl.Reg32);
556 if (ret)
557 return ret;
558 } while ((arm_pwr_ctrl.Bits.pwr_on_status & 0x3) != 0x3);
559 } else {
560 printk("error in %s: we do not have CPU#%d\n", __func__, cpu);
561 return -1;
562 }
563
564 return 0;
565 }
566
567 int pmc_cpu_l2cache_power_up(void)
568 {
569 int ret;
570 ARM_CPUx_PWR_CTRL_REG arm_pwr_ctrl;
571
572 ret = ReadBPCMRegister(PMB_ADDR_AIP,
573 ARMBPCMRegOffset(arm_neon_l2),
574 &arm_pwr_ctrl.Reg32);
575 if (ret)
576 return ret;
577
578 /* check if L2 cache is already power on. If it is, then just return 0 */
579 if ((arm_pwr_ctrl.Bits.mem_clamp_on == 0) &&
580 (arm_pwr_ctrl.Bits.mem_clamp_on == 0) &&
581 (arm_pwr_ctrl.Bits.mem_pwr_ok == 0x1) &&
582 (arm_pwr_ctrl.Bits.mem_pwr_on == 0x1))
583 return 0;
584
585 arm_pwr_ctrl.Bits.mem_pda = 0x0; /* set 0 to bit#8:11 */
586
587 ret = WriteBPCMRegister(PMB_ADDR_AIP,
588 ARMBPCMRegOffset(arm_neon_l2),
589 arm_pwr_ctrl.Reg32);
590 if (ret)
591 return ret;
592
593 arm_pwr_ctrl.Bits.mem_pwr_on = 1;
594
595 ret = WriteBPCMRegister(PMB_ADDR_AIP,
596 ARMBPCMRegOffset(arm_neon_l2),
597 arm_pwr_ctrl.Reg32);
598 if (ret)
599 return ret;
600
601 do {
602 ret = ReadBPCMRegister(PMB_ADDR_AIP,
603 ARMBPCMRegOffset(arm_neon_l2),
604 &arm_pwr_ctrl.Reg32);
605 if (ret)
606 return ret;
607 } while (arm_pwr_ctrl.Bits.mem_pwr_on_status == 0);
608
609 arm_pwr_ctrl.Bits.mem_pwr_ok = 1;
610
611 ret = WriteBPCMRegister(PMB_ADDR_AIP,
612 ARMBPCMRegOffset(arm_neon_l2),
613 arm_pwr_ctrl.Reg32);
614 if (ret)
615 return ret;
616
617 do {
618 ret = ReadBPCMRegister(PMB_ADDR_AIP,
619 ARMBPCMRegOffset(arm_neon_l2),
620 &arm_pwr_ctrl.Reg32);
621 if (ret)
622 return ret;
623 } while (arm_pwr_ctrl.Bits.mem_pwr_ok_status == 0);
624
625 arm_pwr_ctrl.Bits.mem_clamp_on = 0;
626
627 ret = WriteBPCMRegister(PMB_ADDR_AIP,
628 ARMBPCMRegOffset(arm_neon_l2),
629 arm_pwr_ctrl.Reg32);
630 if (ret)
631 return ret;
632
633 return 0;
634 }
635
636 int pmc_cpu_l2cache_power_down(void)
637 {
638 int ret;
639 ARM_CPUx_PWR_CTRL_REG arm_pwr_ctrl;
640
641 ret = ReadBPCMRegister(PMB_ADDR_AIP,
642 ARMBPCMRegOffset(arm_neon_l2),
643 &arm_pwr_ctrl.Reg32);
644 if (ret)
645 return ret;
646
647 arm_pwr_ctrl.Bits.mem_clamp_on = 1;
648
649 ret = WriteBPCMRegister(PMB_ADDR_AIP,
650 ARMBPCMRegOffset(arm_neon_l2),
651 arm_pwr_ctrl.Reg32);
652 if (ret)
653 return ret;
654
655 arm_pwr_ctrl.Bits.mem_pwr_ok = 0;
656
657 ret = WriteBPCMRegister(PMB_ADDR_AIP,
658 ARMBPCMRegOffset(arm_neon_l2),
659 arm_pwr_ctrl.Reg32);
660 if (ret)
661 return ret;
662
663 do {
664 ret = ReadBPCMRegister(PMB_ADDR_AIP,
665 ARMBPCMRegOffset(arm_neon_l2),
666 &arm_pwr_ctrl.Reg32);
667 if (ret)
668 return ret;
669 } while (arm_pwr_ctrl.Bits.mem_pwr_ok_status == 0);
670
671 arm_pwr_ctrl.Bits.mem_pwr_on = 0;
672
673 ret = WriteBPCMRegister(PMB_ADDR_AIP,
674 ARMBPCMRegOffset(arm_neon_l2),
675 arm_pwr_ctrl.Reg32);
676 if (ret)
677 return ret;
678
679 do {
680 ret = ReadBPCMRegister(PMB_ADDR_AIP,
681 ARMBPCMRegOffset(arm_neon_l2),
682 &arm_pwr_ctrl.Reg32);
683 if (ret)
684 return ret;
685 } while (arm_pwr_ctrl.Bits.mem_pwr_on_status == 0);
686
687 arm_pwr_ctrl.Bits.mem_pda = 0xf; /* set 0xf to bit#8:11 */
688
689 ret = WriteBPCMRegister(PMB_ADDR_AIP,
690 ARMBPCMRegOffset(arm_neon_l2),
691 arm_pwr_ctrl.Reg32);
692 if (ret)
693 return ret;
694
695 return 0;
696 }
697
698 int pmc_cpu_neon_power_up(unsigned cpu)
699 {
700 int ret;
701 ARM_CONTROL_REG arm_ctrl;
702 ARM_CPUx_PWR_CTRL_REG arm_pwr_ctrl;
703
704 ret = ReadBPCMRegister(PMB_ADDR_AIP,
705 ARMBPCMRegOffset(arm_control),
706 &arm_ctrl.Reg32);
707 if (ret)
708 return ret;
709
710 ret = ReadBPCMRegister(PMB_ADDR_AIP,
711 ARMBPCMRegOffset(arm_neon_l2),
712 &arm_pwr_ctrl.Reg32);
713 if (ret)
714 return ret;
715
716 /* check if neon is on and running aready. */
717 if ((arm_ctrl.Bits.neon_reset_n == 1) &&
718 (arm_pwr_ctrl.Bits.clamp_on == 0) &&
719 (arm_pwr_ctrl.Bits.pwr_ok & 0x1) &&
720 (arm_pwr_ctrl.Bits.pwr_on & 0x1))
721 return 0;
722
723 /* 1) Power up Neon */
724 arm_pwr_ctrl.Bits.pwr_on |= 1;
725
726 ret = WriteBPCMRegister(PMB_ADDR_AIP,
727 ARMBPCMRegOffset(arm_neon_l2),
728 arm_pwr_ctrl.Reg32);
729 if (ret)
730 return ret;
731
732 do {
733 ret = ReadBPCMRegister(PMB_ADDR_AIP,
734 ARMBPCMRegOffset(arm_neon_l2),
735 &arm_pwr_ctrl.Reg32);
736 if (ret)
737 return ret;
738 } while ((arm_pwr_ctrl.Bits.pwr_on_status & 0x1) == 0);
739
740 arm_pwr_ctrl.Bits.pwr_ok |= 1;
741
742 ret = WriteBPCMRegister(PMB_ADDR_AIP,
743 ARMBPCMRegOffset(arm_neon_l2),
744 arm_pwr_ctrl.Reg32);
745 if (ret)
746 return ret;
747
748 do {
749 ret = ReadBPCMRegister(PMB_ADDR_AIP,
750 ARMBPCMRegOffset(arm_neon_l2),
751 &arm_pwr_ctrl.Reg32);
752 if (ret)
753 return ret;
754 } while ((arm_pwr_ctrl.Bits.pwr_ok_status & 0x1) == 0);
755
756 arm_pwr_ctrl.Bits.clamp_on = 0;
757
758 ret = WriteBPCMRegister(PMB_ADDR_AIP,
759 ARMBPCMRegOffset(arm_neon_l2),
760 arm_pwr_ctrl.Reg32);
761 if (ret)
762 return ret;
763
764 /* 2) De-assert reset to Neon */
765 arm_ctrl.Bits.neon_reset_n = 1;
766
767 ret = WriteBPCMRegister(PMB_ADDR_AIP,
768 ARMBPCMRegOffset(arm_control),
769 arm_ctrl.Reg32);
770 if (ret)
771 return ret;
772
773 return 0;
774 }
775
776 int pmc_cpu_neon_power_down(unsigned cpu)
777 {
778 int ret;
779 ARM_CONTROL_REG arm_ctrl;
780 ARM_CPUx_PWR_CTRL_REG arm_pwr_ctrl;
781
782 ret = ReadBPCMRegister(PMB_ADDR_AIP,
783 ARMBPCMRegOffset(arm_control),
784 &arm_ctrl.Reg32);
785 if (ret)
786 return ret;
787
788 ret = ReadBPCMRegister(PMB_ADDR_AIP,
789 ARMBPCMRegOffset(arm_neon_l2),
790 &arm_pwr_ctrl.Reg32);
791 if (ret)
792 return ret;
793
794 /* 1) assert reset to Neon */
795 arm_ctrl.Bits.neon_reset_n = 0;
796
797 ret = WriteBPCMRegister(PMB_ADDR_AIP,
798 ARMBPCMRegOffset(arm_control),
799 arm_ctrl.Reg32);
800 if (ret)
801 return ret;
802
803 /* 2) Power down Neon */
804 arm_pwr_ctrl.Bits.clamp_on = 1;
805
806 ret = WriteBPCMRegister(PMB_ADDR_AIP,
807 ARMBPCMRegOffset(arm_neon_l2),
808 arm_pwr_ctrl.Reg32);
809 if (ret)
810 return ret;
811
812 arm_pwr_ctrl.Bits.pwr_ok &= 0xe;
813
814 ret = WriteBPCMRegister(PMB_ADDR_AIP,
815 ARMBPCMRegOffset(arm_neon_l2),
816 arm_pwr_ctrl.Reg32);
817 if (ret)
818 return ret;
819
820 do {
821 ret = ReadBPCMRegister(PMB_ADDR_AIP,
822 ARMBPCMRegOffset(arm_neon_l2),
823 &arm_pwr_ctrl.Reg32);
824 if (ret)
825 return ret;
826 } while ((arm_pwr_ctrl.Bits.pwr_ok_status & 0x1) == 1);
827
828 arm_pwr_ctrl.Bits.pwr_on &= 0xe;
829
830 ret = WriteBPCMRegister(PMB_ADDR_AIP,
831 ARMBPCMRegOffset(arm_neon_l2),
832 arm_pwr_ctrl.Reg32);
833 if (ret)
834 return ret;
835
836 do {
837 ret = ReadBPCMRegister(PMB_ADDR_AIP,
838 ARMBPCMRegOffset(arm_neon_l2),
839 &arm_pwr_ctrl.Reg32);
840 if (ret)
841 return ret;
842 } while ((arm_pwr_ctrl.Bits.pwr_on_status & 0x1) == 1);
843
844 return 0;
845 }
846
847 #else
848
849 #if defined (PMB_ADDR_ORION_CPU0)
850 static uint32_t pmb_cpu_id[] = {
851 PMB_ADDR_ORION_CPU0,
852 PMB_ADDR_ORION_CPU1,
853 #if defined(PMB_ADDR_ORION_CPU2)
854 PMB_ADDR_ORION_CPU2,
855 #endif
856 #if defined(PMB_ADDR_ORION_CPU3)
857 PMB_ADDR_ORION_CPU3
858 #endif
859 };
860 #endif
861
862 int pmc_cpu_core_power_up(unsigned cpu)
863 {
864 #if defined (PLATFORM_FLAVOR_63148)
865 B15CTRL->cpu_ctrl.cpu1_pwr_zone_ctrl |= 0x400;
866 B15CTRL->cpu_ctrl.reset_cfg &= 0xfffffffd;
867 #elif defined (PMB_ADDR_ORION_CPU0) || defined (PLATFORM_FLAVOR_6846)
868 int error;
869 uint32_t arm_control;
870
871 #if defined (PMB_ADDR_ORION_CPU0)
872 error = ResetDevice(pmb_cpu_id[cpu]);
873 if (error) {
874 ERROR("unable to power on CPU%d\n", cpu);
875 return error;
876 }
877 #endif
878
879 error = ReadBPCMRegister(PMB_ADDR_BIU_BPCM,
880 ARMBPCMRegOffset(arm_control),
881 &arm_control);
882 if (error) {
883 ERROR("unable to release CPU%d reset.\n", cpu);
884 return error;
885 }
886 arm_control &= ~(1 << cpu);
887 error = WriteBPCMRegister(PMB_ADDR_BIU_BPCM,
888 ARMBPCMRegOffset(arm_control),
889 arm_control);
890 if (error) {
891 ERROR("unable to release CPU%d reset.\n", cpu);
892 return error;
893 }
894 udelay(100); // wait for cpu to come out of reset
895 INFO("pmc_cpu: powered up CPU%d\n", cpu);
896 #elif defined (BIUCTRL_BASE)
897 if (BIUCTRL->cpu_pwr_zone_ctrl[cpu] & BIU_CPU_CTRL_PWR_ZONE_CTRL_ZONE_RESET) {
898 BIUCTRL->power_cfg |= BIU_CPU_CTRL_PWR_CFG_CPU0_BPCM_INIT_ON << cpu;
899 BIUCTRL->cpu_pwr_zone_ctrl[cpu] = BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_UP_REQ |
900 (BIUCTRL->cpu_pwr_zone_ctrl[cpu] & ~BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_DN_REQ);
901
902 udelay(100); // wait for cpu to come out of reset
903 }
904 #endif
905 return 0;
906 }
907
908 int pmc_cpu_core_power_down(unsigned cpu)
909 {
910 #if defined (BIUCTRL_BASE)
911 BIUCTRL->power_cfg &= ~(BIU_CPU_CTRL_PWR_CFG_CPU0_BPCM_INIT_ON << cpu);
912 BIUCTRL->cpu_pwr_zone_ctrl[cpu] = BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_DN_REQ |
913 (BIUCTRL->cpu_pwr_zone_ctrl[cpu] & ~BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_UP_REQ);
914 #endif
915 return 0;
916 }
917 #endif /* PLATFORM_FLAVOR_63138 */