blob: fc31413cc3acf1b63a14ed4b36bdfb0a05ef30df [file] [log] [blame]
Tony Xief6118cc2016-01-15 17:17:32 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <arch_helpers.h>
28#include <assert.h>
29#include <debug.h>
30#include <delay_timer.h>
31#include <errno.h>
32#include <mmio.h>
33#include <platform.h>
34#include <platform_def.h>
35#include <plat_private.h>
36#include <rk3368_def.h>
37#include <pmu_sram.h>
38#include <soc.h>
39#include <pmu.h>
40#include <ddr_rk3368.h>
41#include <pmu_com.h>
42
43static struct psram_data_t *psram_sleep_cfg =
44 (struct psram_data_t *)PSRAM_DT_BASE;
45
46void rk3368_flash_l2_b(void)
47{
48 uint32_t wait_cnt = 0;
49
50 regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_l2flsh_clst_b);
51 dsb();
52
53 while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST)
54 & BIT(clst_b_l2_flsh_done))) {
55 wait_cnt++;
56 if (!(wait_cnt % MAX_WAIT_CONUT))
57 WARN("%s:reg %x,wait\n", __func__,
58 mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST));
59 }
60
61 regs_updata_bit_clr(PMU_BASE + PMU_SFT_CON, pmu_sft_l2flsh_clst_b);
62}
63
64static inline int rk3368_pmu_bus_idle(uint32_t req, uint32_t idle)
65{
66 uint32_t mask = BIT(req);
67 uint32_t idle_mask = 0;
68 uint32_t idle_target = 0;
69 uint32_t val;
70 uint32_t wait_cnt = 0;
71
72 switch (req) {
73 case bus_ide_req_clst_l:
74 idle_mask = BIT(pmu_idle_ack_cluster_l);
75 idle_target = (idle << pmu_idle_ack_cluster_l);
76 break;
77
78 case bus_ide_req_clst_b:
79 idle_mask = BIT(pmu_idle_ack_cluster_b);
80 idle_target = (idle << pmu_idle_ack_cluster_b);
81 break;
82
83 case bus_ide_req_cxcs:
84 idle_mask = BIT(pmu_idle_ack_cxcs);
85 idle_target = ((!idle) << pmu_idle_ack_cxcs);
86 break;
87
88 case bus_ide_req_cci400:
89 idle_mask = BIT(pmu_idle_ack_cci400);
90 idle_target = ((!idle) << pmu_idle_ack_cci400);
91 break;
92
93 case bus_ide_req_gpu:
94 idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
95 idle_target = (idle << pmu_idle_ack_gpu) |
96 (idle << pmu_idle_gpu);
97 break;
98
99 case bus_ide_req_core:
100 idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
101 idle_target = (idle << pmu_idle_ack_core) |
102 (idle << pmu_idle_core);
103 break;
104
105 case bus_ide_req_bus:
106 idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
107 idle_target = (idle << pmu_idle_ack_bus) |
108 (idle << pmu_idle_bus);
109 break;
110 case bus_ide_req_dma:
111 idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
112 idle_target = (idle << pmu_idle_ack_dma) |
113 (idle << pmu_idle_dma);
114 break;
115
116 case bus_ide_req_peri:
117 idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
118 idle_target = (idle << pmu_idle_ack_peri) |
119 (idle << pmu_idle_peri);
120 break;
121
122 case bus_ide_req_video:
123 idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
124 idle_target = (idle << pmu_idle_ack_video) |
125 (idle << pmu_idle_video);
126 break;
127
128 case bus_ide_req_vio:
129 idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
130 idle_target = (pmu_idle_ack_vio) |
131 (idle << pmu_idle_vio);
132 break;
133
134 case bus_ide_req_alive:
135 idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
136 idle_target = (idle << pmu_idle_ack_alive) |
137 (idle << pmu_idle_alive);
138 break;
139
140 case bus_ide_req_pmu:
141 idle_mask = BIT(pmu_idle_ack_pmu) | BIT(pmu_idle_pmu);
142 idle_target = (idle << pmu_idle_ack_pmu) |
143 (idle << pmu_idle_pmu);
144 break;
145
146 case bus_ide_req_msch:
147 idle_mask = BIT(pmu_idle_ack_msch) | BIT(pmu_idle_msch);
148 idle_target = (idle << pmu_idle_ack_msch) |
149 (idle << pmu_idle_msch);
150 break;
151
152 case bus_ide_req_cci:
153 idle_mask = BIT(pmu_idle_ack_cci) | BIT(pmu_idle_cci);
154 idle_target = (idle << pmu_idle_ack_cci) |
155 (idle << pmu_idle_cci);
156 break;
157
158 default:
159 ERROR("%s: Unsupported the idle request\n", __func__);
160 break;
161 }
162
163 val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
164 if (idle)
165 val |= mask;
166 else
167 val &= ~mask;
168
169 mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
170
171 while ((mmio_read_32(PMU_BASE +
172 PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
173 wait_cnt++;
174 if (!(wait_cnt % MAX_WAIT_CONUT))
175 WARN("%s:st=%x(%x)\n", __func__,
176 mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
177 idle_mask);
178 }
179
180 return 0;
181}
182
183void pmu_scu_b_pwrup(void)
184{
185 regs_updata_bit_clr(PMU_BASE + PMU_SFT_CON, pmu_sft_acinactm_clst_b);
186 rk3368_pmu_bus_idle(bus_ide_req_clst_b, 0);
187}
188
189static void pmu_scu_b_pwrdn(void)
190{
191 uint32_t wait_cnt = 0;
192
193 if ((mmio_read_32(PMU_BASE + PMU_PWRDN_ST) &
194 PM_PWRDM_CPUSB_MSK) != PM_PWRDM_CPUSB_MSK) {
195 ERROR("%s: not all cpus is off\n", __func__);
196 return;
197 }
198
199 rk3368_flash_l2_b();
200
201 regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_acinactm_clst_b);
202
203 while (!(mmio_read_32(PMU_BASE +
204 PMU_CORE_PWR_ST) & BIT(clst_b_l2_wfi))) {
205 wait_cnt++;
206 if (!(wait_cnt % MAX_WAIT_CONUT))
207 ERROR("%s:wait cluster-b l2(%x)\n", __func__,
208 mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST));
209 }
210 rk3368_pmu_bus_idle(bus_ide_req_clst_b, 1);
211}
212
213static void pmu_sleep_mode_config(void)
214{
215 uint32_t pwrmd_core, pwrmd_com;
216
217 pwrmd_core = BIT(pmu_mdcr_cpu0_pd) |
218 BIT(pmu_mdcr_scu_l_pd) |
219 BIT(pmu_mdcr_l2_flush) |
220 BIT(pmu_mdcr_l2_idle) |
221 BIT(pmu_mdcr_clr_clst_l) |
222 BIT(pmu_mdcr_clr_core) |
223 BIT(pmu_mdcr_clr_cci) |
224 BIT(pmu_mdcr_core_pd);
225
226 pwrmd_com = BIT(pmu_mode_en) |
227 BIT(pmu_mode_sref_enter) |
228 BIT(pmu_mode_pwr_off);
229
230 regs_updata_bit_set(PMU_BASE + PMU_WKUP_CFG2, pmu_cluster_l_wkup_en);
231 regs_updata_bit_set(PMU_BASE + PMU_WKUP_CFG2, pmu_cluster_b_wkup_en);
232 regs_updata_bit_clr(PMU_BASE + PMU_WKUP_CFG2, pmu_gpio_wkup_en);
233
234 mmio_write_32(PMU_BASE + PMU_PLLLOCK_CNT, CYCL_24M_CNT_MS(2));
235 mmio_write_32(PMU_BASE + PMU_PLLRST_CNT, CYCL_24M_CNT_US(100));
236 mmio_write_32(PMU_BASE + PMU_STABLE_CNT, CYCL_24M_CNT_MS(2));
237 mmio_write_32(PMU_BASE + PMU_PWRMD_CORE, pwrmd_core);
238 mmio_write_32(PMU_BASE + PMU_PWRMD_COM, pwrmd_com);
239 dsb();
240}
241
242static void ddr_suspend_save(void)
243{
244 ddr_reg_save(1, psram_sleep_cfg->ddr_data);
245}
246
247static void pmu_set_sleep_mode(void)
248{
249 ddr_suspend_save();
250 pmu_sleep_mode_config();
251 soc_sleep_config();
252 regs_updata_bit_set(PMU_BASE + PMU_PWRMD_CORE, pmu_mdcr_global_int_dis);
253 regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_glbl_int_dis_b);
254 pmu_scu_b_pwrdn();
255 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
256 (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) |
257 CPU_BOOT_ADDR_WMASK);
258 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2),
259 (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) |
260 CPU_BOOT_ADDR_WMASK);
261}
262
263void plat_rockchip_pmusram_prepare(void)
264{
265 uint32_t *sram_dst, *sram_src;
266 size_t sram_size = 2;
267 uint32_t code_size, data_size;
268
269 /* pmu sram code and data prepare */
270 sram_dst = (uint32_t *)PMUSRAM_BASE;
271 sram_src = (uint32_t *)&pmu_cpuson_entrypoint_start;
272 sram_size = (uint32_t *)&pmu_cpuson_entrypoint_end -
273 (uint32_t *)sram_src;
274 u32_align_cpy(sram_dst, sram_src, sram_size);
275
276 /* ddr code */
277 sram_dst += sram_size;
278 sram_src = ddr_get_resume_code_base();
279 code_size = ddr_get_resume_code_size();
280 u32_align_cpy(sram_dst, sram_src, code_size / 4);
281 psram_sleep_cfg->ddr_func = (uint64_t)sram_dst;
282
283 /* ddr data */
284 sram_dst += (code_size / 4);
285 data_size = ddr_get_resume_data_size();
286 psram_sleep_cfg->ddr_data = (uint64_t)sram_dst;
287
288 assert((uint64_t)(sram_dst + data_size / 4) < PSRAM_SP_BOTTOM);
289 psram_sleep_cfg->sp = PSRAM_SP_TOP;
290}
291
292static int cpus_id_power_domain(uint32_t cluster,
293 uint32_t cpu,
294 uint32_t pd_state,
295 uint32_t wfie_msk)
296{
297 uint32_t pd;
298 uint64_t mpidr;
299
300 if (cluster)
301 pd = PD_CPUB0 + cpu;
302 else
303 pd = PD_CPUL0 + cpu;
304
305 if (pmu_power_domain_st(pd) == pd_state)
306 return 0;
307
308 if (pd_state == pmu_pd_off) {
309 mpidr = (cluster << MPIDR_AFF1_SHIFT) | cpu;
310 if (check_cpu_wfie(mpidr, wfie_msk))
311 return -EINVAL;
312 }
313
314 return pmu_power_domain_ctr(pd, pd_state);
315}
316
317static void nonboot_cpus_off(void)
318{
319 uint32_t boot_cpu, boot_cluster, cpu;
320
321 boot_cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
322 boot_cluster = MPIDR_AFFLVL1_VAL(read_mpidr_el1());
323
324 /* turn off noboot cpus */
325 for (cpu = 0; cpu < PLATFORM_CLUSTER0_CORE_COUNT; cpu++) {
326 if (!boot_cluster && (cpu == boot_cpu))
327 continue;
328 cpus_id_power_domain(0, cpu, pmu_pd_off, CKECK_WFEI_MSK);
329 }
330
331 for (cpu = 0; cpu < PLATFORM_CLUSTER1_CORE_COUNT; cpu++) {
332 if (boot_cluster && (cpu == boot_cpu))
333 continue;
334 cpus_id_power_domain(1, cpu, pmu_pd_off, CKECK_WFEI_MSK);
335 }
336}
337
338static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint)
339{
340 uint32_t cpu, cluster;
341 uint32_t cpuon_id;
342
343 cpu = MPIDR_AFFLVL0_VAL(mpidr);
344 cluster = MPIDR_AFFLVL1_VAL(mpidr);
345
346 /* Make sure the cpu is off,Before power up the cpu! */
347 cpus_id_power_domain(cluster, cpu, pmu_pd_off, CKECK_WFEI_MSK);
348
349 cpuon_id = (cluster * PLATFORM_CLUSTER0_CORE_COUNT) + cpu;
350 assert(cpuson_flags[cpuon_id] == 0);
351 cpuson_flags[cpuon_id] = PMU_CPU_HOTPLUG;
352 cpuson_entry_point[cpuon_id] = entrypoint;
353
354 /* Switch boot addr to pmusram */
355 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1 + cluster),
356 (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) |
357 CPU_BOOT_ADDR_WMASK);
358 dsb();
359
360 cpus_id_power_domain(cluster, cpu, pmu_pd_on, CKECK_WFEI_MSK);
361
362 mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1 + cluster),
363 (COLD_BOOT_BASE >> CPU_BOOT_ADDR_ALIGN) |
364 CPU_BOOT_ADDR_WMASK);
365
366 return 0;
367}
368
369static int cores_pwr_domain_on_finish(void)
370{
371 uint32_t cpuon_id;
372
373 cpuon_id = plat_my_core_pos();
374 assert(cpuson_flags[cpuon_id] == 0);
375 cpuson_flags[cpuon_id] = 0x00;
376
377 return 0;
378}
379
380static int sys_pwr_domain_resume(void)
381{
382 psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE;
383
384 pm_plls_resume();
385 pmu_scu_b_pwrup();
386
387 return 0;
388}
389
390static int sys_pwr_domain_suspend(void)
391{
392 nonboot_cpus_off();
393 pmu_set_sleep_mode();
394
395 psram_sleep_cfg->sys_mode = PMU_SYS_SLP_MODE;
396 psram_sleep_cfg->ddr_flag = 0;
397
398 return 0;
399}
400
401static struct rockchip_pm_ops_cb pm_ops = {
402 .cores_pwr_dm_on = cores_pwr_domain_on,
403 .cores_pwr_dm_on_finish = cores_pwr_domain_on_finish,
404 .sys_pwr_dm_suspend = sys_pwr_domain_suspend,
405 .sys_pwr_dm_resume = sys_pwr_domain_resume,
406 .sys_gbl_soft_reset = soc_sys_global_soft_reset,
407};
408
409void plat_rockchip_pmu_init(void)
410{
411 uint32_t cpu;
412
413 plat_setup_rockchip_pm_ops(&pm_ops);
414
415 for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
416 cpuson_flags[cpu] = 0;
417
418 psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE;
419
420 psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
421
422 nonboot_cpus_off();
423 INFO("%s(%d): pd status %x\n", __func__, __LINE__,
424 mmio_read_32(PMU_BASE + PMU_PWRDN_ST));
425}