1 /*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <arch_helpers.h>
8 #include <assert.h>
9 #include <ddr_rk3368.h>
10 #include <debug.h>
11 #include <delay_timer.h>
12 #include <errno.h>
13 #include <mmio.h>
14 #include <plat_private.h>
15 #include <platform.h>
16 #include <platform_def.h>
17 #include <pmu.h>
18 #include <pmu_com.h>
19 #include <rk3368_def.h>
20 #include <soc.h>
21
22 DEFINE_BAKERY_LOCK(rockchip_pd_lock);
23
24 static uint32_t cpu_warm_boot_addr;
25
rk3368_flash_l2_b(void)26 void rk3368_flash_l2_b(void)
27 {
28 uint32_t wait_cnt = 0;
29
30 regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_l2flsh_clst_b);
31 dsb();
32
33 while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST)
34 & BIT(clst_b_l2_flsh_done))) {
35 wait_cnt++;
36 if (!(wait_cnt % MAX_WAIT_CONUT))
37 WARN("%s:reg %x,wait\n", __func__,
38 mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST));
39 }
40
41 regs_updata_bit_clr(PMU_BASE + PMU_SFT_CON, pmu_sft_l2flsh_clst_b);
42 }
43
rk3368_pmu_bus_idle(uint32_t req,uint32_t idle)44 static inline int rk3368_pmu_bus_idle(uint32_t req, uint32_t idle)
45 {
46 uint32_t mask = BIT(req);
47 uint32_t idle_mask = 0;
48 uint32_t idle_target = 0;
49 uint32_t val;
50 uint32_t wait_cnt = 0;
51
52 switch (req) {
53 case bus_ide_req_clst_l:
54 idle_mask = BIT(pmu_idle_ack_cluster_l);
55 idle_target = (idle << pmu_idle_ack_cluster_l);
56 break;
57
58 case bus_ide_req_clst_b:
59 idle_mask = BIT(pmu_idle_ack_cluster_b);
60 idle_target = (idle << pmu_idle_ack_cluster_b);
61 break;
62
63 case bus_ide_req_cxcs:
64 idle_mask = BIT(pmu_idle_ack_cxcs);
65 idle_target = ((!idle) << pmu_idle_ack_cxcs);
66 break;
67
68 case bus_ide_req_cci400:
69 idle_mask = BIT(pmu_idle_ack_cci400);
70 idle_target = ((!idle) << pmu_idle_ack_cci400);
71 break;
72
73 case bus_ide_req_gpu:
74 idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
75 idle_target = (idle << pmu_idle_ack_gpu) |
76 (idle << pmu_idle_gpu);
77 break;
78
79 case bus_ide_req_core:
80 idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
81 idle_target = (idle << pmu_idle_ack_core) |
82 (idle << pmu_idle_core);
83 break;
84
85 case bus_ide_req_bus:
86 idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
87 idle_target = (idle << pmu_idle_ack_bus) |
88 (idle << pmu_idle_bus);
89 break;
90 case bus_ide_req_dma:
91 idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
92 idle_target = (idle << pmu_idle_ack_dma) |
93 (idle << pmu_idle_dma);
94 break;
95
96 case bus_ide_req_peri:
97 idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
98 idle_target = (idle << pmu_idle_ack_peri) |
99 (idle << pmu_idle_peri);
100 break;
101
102 case bus_ide_req_video:
103 idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
104 idle_target = (idle << pmu_idle_ack_video) |
105 (idle << pmu_idle_video);
106 break;
107
108 case bus_ide_req_vio:
109 idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
110 idle_target = (pmu_idle_ack_vio) |
111 (idle << pmu_idle_vio);
112 break;
113
114 case bus_ide_req_alive:
115 idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
116 idle_target = (idle << pmu_idle_ack_alive) |
117 (idle << pmu_idle_alive);
118 break;
119
120 case bus_ide_req_pmu:
121 idle_mask = BIT(pmu_idle_ack_pmu) | BIT(pmu_idle_pmu);
122 idle_target = (idle << pmu_idle_ack_pmu) |
123 (idle << pmu_idle_pmu);
124 break;
125
126 case bus_ide_req_msch:
127 idle_mask = BIT(pmu_idle_ack_msch) | BIT(pmu_idle_msch);
128 idle_target = (idle << pmu_idle_ack_msch) |
129 (idle << pmu_idle_msch);
130 break;
131
132 case bus_ide_req_cci:
133 idle_mask = BIT(pmu_idle_ack_cci) | BIT(pmu_idle_cci);
134 idle_target = (idle << pmu_idle_ack_cci) |
135 (idle << pmu_idle_cci);
136 break;
137
138 default:
139 ERROR("%s: Unsupported the idle request\n", __func__);
140 break;
141 }
142
143 val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
144 if (idle)
145 val |= mask;
146 else
147 val &= ~mask;
148
149 mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
150
151 while ((mmio_read_32(PMU_BASE +
152 PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
153 wait_cnt++;
154 if (!(wait_cnt % MAX_WAIT_CONUT))
155 WARN("%s:st=%x(%x)\n", __func__,
156 mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
157 idle_mask);
158 }
159
160 return 0;
161 }
162
pmu_scu_b_pwrup(void)163 void pmu_scu_b_pwrup(void)
164 {
165 regs_updata_bit_clr(PMU_BASE + PMU_SFT_CON, pmu_sft_acinactm_clst_b);
166 rk3368_pmu_bus_idle(bus_ide_req_clst_b, 0);
167 }
168
pmu_scu_b_pwrdn(void)169 static void pmu_scu_b_pwrdn(void)
170 {
171 uint32_t wait_cnt = 0;
172
173 if ((mmio_read_32(PMU_BASE + PMU_PWRDN_ST) &
174 PM_PWRDM_CPUSB_MSK) != PM_PWRDM_CPUSB_MSK) {
175 ERROR("%s: not all cpus is off\n", __func__);
176 return;
177 }
178
179 rk3368_flash_l2_b();
180
181 regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_acinactm_clst_b);
182
183 while (!(mmio_read_32(PMU_BASE +
184 PMU_CORE_PWR_ST) & BIT(clst_b_l2_wfi))) {
185 wait_cnt++;
186 if (!(wait_cnt % MAX_WAIT_CONUT))
187 ERROR("%s:wait cluster-b l2(%x)\n", __func__,
188 mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST));
189 }
190 rk3368_pmu_bus_idle(bus_ide_req_clst_b, 1);
191 }
192
pmu_sleep_mode_config(void)193 static void pmu_sleep_mode_config(void)
194 {
195 uint32_t pwrmd_core, pwrmd_com;
196
197 pwrmd_core = BIT(pmu_mdcr_cpu0_pd) |
198 BIT(pmu_mdcr_scu_l_pd) |
199 BIT(pmu_mdcr_l2_flush) |
200 BIT(pmu_mdcr_l2_idle) |
201 BIT(pmu_mdcr_clr_clst_l) |
202 BIT(pmu_mdcr_clr_core) |
203 BIT(pmu_mdcr_clr_cci) |
204 BIT(pmu_mdcr_core_pd);
205
206 pwrmd_com = BIT(pmu_mode_en) |
207 BIT(pmu_mode_sref_enter) |
208 BIT(pmu_mode_pwr_off);
209
210 regs_updata_bit_set(PMU_BASE + PMU_WKUP_CFG2, pmu_cluster_l_wkup_en);
211 regs_updata_bit_set(PMU_BASE + PMU_WKUP_CFG2, pmu_cluster_b_wkup_en);
212 regs_updata_bit_clr(PMU_BASE + PMU_WKUP_CFG2, pmu_gpio_wkup_en);
213
214 mmio_write_32(PMU_BASE + PMU_PLLLOCK_CNT, CYCL_24M_CNT_MS(2));
215 mmio_write_32(PMU_BASE + PMU_PLLRST_CNT, CYCL_24M_CNT_US(100));
216 mmio_write_32(PMU_BASE + PMU_STABLE_CNT, CYCL_24M_CNT_MS(2));
217 mmio_write_32(PMU_BASE + PMU_PWRMD_CORE, pwrmd_core);
218 mmio_write_32(PMU_BASE + PMU_PWRMD_COM, pwrmd_com);
219 dsb();
220 }
221
pmu_set_sleep_mode(void)222 static void pmu_set_sleep_mode(void)
223 {
224 pmu_sleep_mode_config();
225 soc_sleep_config();
226 regs_updata_bit_set(PMU_BASE + PMU_PWRMD_CORE, pmu_mdcr_global_int_dis);
227 regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_glbl_int_dis_b);
228 pmu_scu_b_pwrdn();
229 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
230 ((uintptr_t)&pmu_cpuson_entrypoint >>
231 CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK);
232 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2),
233 ((uintptr_t)&pmu_cpuson_entrypoint >>
234 CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK);
235 }
236
cpus_id_power_domain(uint32_t cluster,uint32_t cpu,uint32_t pd_state,uint32_t wfie_msk)237 static int cpus_id_power_domain(uint32_t cluster,
238 uint32_t cpu,
239 uint32_t pd_state,
240 uint32_t wfie_msk)
241 {
242 uint32_t pd;
243 uint64_t mpidr;
244
245 if (cluster)
246 pd = PD_CPUB0 + cpu;
247 else
248 pd = PD_CPUL0 + cpu;
249
250 if (pmu_power_domain_st(pd) == pd_state)
251 return 0;
252
253 if (pd_state == pmu_pd_off) {
254 mpidr = (cluster << MPIDR_AFF1_SHIFT) | cpu;
255 if (check_cpu_wfie(mpidr, wfie_msk))
256 return -EINVAL;
257 }
258
259 return pmu_power_domain_ctr(pd, pd_state);
260 }
261
nonboot_cpus_off(void)262 static void nonboot_cpus_off(void)
263 {
264 uint32_t boot_cpu, boot_cluster, cpu;
265
266 boot_cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
267 boot_cluster = MPIDR_AFFLVL1_VAL(read_mpidr_el1());
268
269 /* turn off noboot cpus */
270 for (cpu = 0; cpu < PLATFORM_CLUSTER0_CORE_COUNT; cpu++) {
271 if (!boot_cluster && (cpu == boot_cpu))
272 continue;
273 cpus_id_power_domain(0, cpu, pmu_pd_off, CKECK_WFEI_MSK);
274 }
275
276 for (cpu = 0; cpu < PLATFORM_CLUSTER1_CORE_COUNT; cpu++) {
277 if (boot_cluster && (cpu == boot_cpu))
278 continue;
279 cpus_id_power_domain(1, cpu, pmu_pd_off, CKECK_WFEI_MSK);
280 }
281 }
282
sram_save(void)283 void sram_save(void)
284 {
285 /* TODO: support the sdram save for rk3368 SoCs*/
286 }
287
sram_restore(void)288 void sram_restore(void)
289 {
290 /* TODO: support the sdram restore for rk3368 SoCs */
291 }
292
rockchip_soc_cores_pwr_dm_on(unsigned long mpidr,uint64_t entrypoint)293 int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
294 {
295 uint32_t cpu, cluster;
296 uint32_t cpuon_id;
297
298 cpu = MPIDR_AFFLVL0_VAL(mpidr);
299 cluster = MPIDR_AFFLVL1_VAL(mpidr);
300
301 /* Make sure the cpu is off,Before power up the cpu! */
302 cpus_id_power_domain(cluster, cpu, pmu_pd_off, CKECK_WFEI_MSK);
303
304 cpuon_id = (cluster * PLATFORM_CLUSTER0_CORE_COUNT) + cpu;
305 assert(cpuon_id < PLATFORM_CORE_COUNT);
306 assert(cpuson_flags[cpuon_id] == 0);
307 cpuson_flags[cpuon_id] = PMU_CPU_HOTPLUG;
308 cpuson_entry_point[cpuon_id] = entrypoint;
309
310 /* Switch boot addr to pmusram */
311 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1 + cluster),
312 (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) |
313 CPU_BOOT_ADDR_WMASK);
314 dsb();
315
316 cpus_id_power_domain(cluster, cpu, pmu_pd_on, CKECK_WFEI_MSK);
317
318 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1 + cluster),
319 (COLD_BOOT_BASE >> CPU_BOOT_ADDR_ALIGN) |
320 CPU_BOOT_ADDR_WMASK);
321
322 return 0;
323 }
324
rockchip_soc_cores_pwr_dm_on_finish(void)325 int rockchip_soc_cores_pwr_dm_on_finish(void)
326 {
327 return 0;
328 }
329
rockchip_soc_sys_pwr_dm_resume(void)330 int rockchip_soc_sys_pwr_dm_resume(void)
331 {
332 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
333 (COLD_BOOT_BASE >> CPU_BOOT_ADDR_ALIGN) |
334 CPU_BOOT_ADDR_WMASK);
335 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2),
336 (COLD_BOOT_BASE >> CPU_BOOT_ADDR_ALIGN) |
337 CPU_BOOT_ADDR_WMASK);
338 pm_plls_resume();
339 pmu_scu_b_pwrup();
340
341 return 0;
342 }
343
rockchip_soc_sys_pwr_dm_suspend(void)344 int rockchip_soc_sys_pwr_dm_suspend(void)
345 {
346 nonboot_cpus_off();
347 pmu_set_sleep_mode();
348
349 return 0;
350 }
351
rockchip_plat_mmu_el3(void)352 void rockchip_plat_mmu_el3(void)
353 {
354 /* TODO: support the el3 for rk3368 SoCs */
355 }
356
plat_rockchip_pmu_init(void)357 void plat_rockchip_pmu_init(void)
358 {
359 uint32_t cpu;
360
361 /* register requires 32bits mode, switch it to 32 bits */
362 cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot;
363
364 for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
365 cpuson_flags[cpu] = 0;
366
367 nonboot_cpus_off();
368 INFO("%s(%d): pd status %x\n", __func__, __LINE__,
369 mmio_read_32(PMU_BASE + PMU_PWRDN_ST));
370 }
371