blob: 741adde66d5a8afc506bcd7a799f197b11f36c5e [file] [log] [blame]
Tony Xief6118cc2016-01-15 17:17:32 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Tony Xief6118cc2016-01-15 17:17:32 +08005 */
6
7#include <arch_helpers.h>
Xing Zheng5e1e48f2017-02-24 14:47:51 +08008#include <assert.h>
Tony Xief6118cc2016-01-15 17:17:32 +08009#include <debug.h>
10#include <delay_timer.h>
Derek Basehoreff461d02016-10-20 20:46:43 -070011#include <dfs.h>
12#include <dram.h>
Xing Zheng93280b72016-10-26 21:25:26 +080013#include <m0_ctl.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010014#include <mmio.h>
Tony Xief6118cc2016-01-15 17:17:32 +080015#include <plat_private.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010016#include <platform_def.h>
Tony Xief6118cc2016-01-15 17:17:32 +080017#include <rk3399_def.h>
Xing Zheng22a98712017-02-24 14:56:41 +080018#include <secure.h>
Tony Xief6118cc2016-01-15 17:17:32 +080019#include <soc.h>
20
21/* Table of regions to map using the MMU. */
22const mmap_region_t plat_rk_mmap[] = {
Xing Zhengb4bcc1d2017-02-24 16:26:11 +080023 MAP_REGION_FLAT(DEV_RNG0_BASE, DEV_RNG0_SIZE,
Tony Xie42e113e2016-07-16 11:16:51 +080024 MT_DEVICE | MT_RW | MT_SECURE),
Caesar Wang5339d182016-10-27 01:13:34 +080025 MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
26 MT_MEMORY | MT_RW | MT_SECURE),
Tony Xie42e113e2016-07-16 11:16:51 +080027
Tony Xief6118cc2016-01-15 17:17:32 +080028 { 0 }
29};
30
31/* The RockChip power domain tree descriptor */
32const unsigned char rockchip_power_domain_tree_desc[] = {
33 /* No of root nodes */
34 PLATFORM_SYSTEM_COUNT,
35 /* No of children for the root node */
36 PLATFORM_CLUSTER_COUNT,
37 /* No of children for the first cluster node */
38 PLATFORM_CLUSTER0_CORE_COUNT,
39 /* No of children for the second cluster node */
40 PLATFORM_CLUSTER1_CORE_COUNT
41};
42
Xing Zheng22a98712017-02-24 14:56:41 +080043/* sleep data for pll suspend */
44static struct deepsleep_data_s slp_data;
Xing Zheng5e1e48f2017-02-24 14:47:51 +080045
Derek Basehoref900a062018-04-23 14:49:22 -070046/* sleep data that needs to be accessed from pmusram */
47__pmusramdata struct pmu_sleep_data pmu_slp_data;
48
Tony Xief6118cc2016-01-15 17:17:32 +080049static void set_pll_slow_mode(uint32_t pll_id)
50{
51 if (pll_id == PPLL_ID)
52 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
53 else
54 mmio_write_32((CRU_BASE +
55 CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
56}
57
58static void set_pll_normal_mode(uint32_t pll_id)
59{
60 if (pll_id == PPLL_ID)
61 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
62 else
63 mmio_write_32(CRU_BASE +
64 CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
65}
66
67static void set_pll_bypass(uint32_t pll_id)
68{
69 if (pll_id == PPLL_ID)
70 mmio_write_32(PMUCRU_BASE +
71 PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
72 else
73 mmio_write_32(CRU_BASE +
74 CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
75}
76
77static void _pll_suspend(uint32_t pll_id)
78{
79 set_pll_slow_mode(pll_id);
80 set_pll_bypass(pll_id);
81}
82
Caesar Wang5339d182016-10-27 01:13:34 +080083/**
84 * disable_dvfs_plls - To suspend the specific PLLs
85 *
86 * When we close the center logic, the DPLL will be closed,
87 * so we need to keep the ABPLL and switch to it to supply
88 * clock for DDR during suspend, then we should not close
89 * the ABPLL and exclude ABPLL_ID.
90 */
Caesar Wanged6b9a52016-08-11 02:11:45 +080091void disable_dvfs_plls(void)
92{
93 _pll_suspend(CPLL_ID);
94 _pll_suspend(NPLL_ID);
95 _pll_suspend(VPLL_ID);
96 _pll_suspend(GPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +080097 _pll_suspend(ALPLL_ID);
98}
99
Caesar Wang5339d182016-10-27 01:13:34 +0800100/**
101 * disable_nodvfs_plls - To suspend the PPLL
102 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800103void disable_nodvfs_plls(void)
104{
105 _pll_suspend(PPLL_ID);
106}
107
Caesar Wang5339d182016-10-27 01:13:34 +0800108/**
109 * restore_pll - Copy PLL settings from memory to a PLL.
110 *
111 * This will copy PLL settings from an array in memory to the memory mapped
112 * registers for a PLL.
113 *
114 * Note that: above the PLL exclude PPLL.
115 *
116 * pll_id: One of the values from enum plls_id
117 * src: Pointer to the array of values to restore from
118 */
119static void restore_pll(int pll_id, uint32_t *src)
120{
121 /* Nice to have PLL off while configuring */
122 mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
123
124 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
125 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
126 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
127 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
128 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
129
130 /* Do PLL_CON3 since that will enable things */
131 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
132
133 /* Wait for PLL lock done */
134 while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
135 0x80000000) == 0x0)
136 ;
137}
138
139/**
140 * save_pll - Copy PLL settings a PLL to memory
141 *
142 * This will copy PLL settings from the memory mapped registers for a PLL to
143 * an array in memory.
144 *
145 * Note that: above the PLL exclude PPLL.
146 *
147 * pll_id: One of the values from enum plls_id
148 * src: Pointer to the array of values to save to.
149 */
150static void save_pll(uint32_t *dst, int pll_id)
151{
152 int i;
153
154 for (i = 0; i < PLL_CON_COUNT; i++)
155 dst[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
156}
157
158/**
159 * prepare_abpll_for_ddrctrl - Copy DPLL settings to ABPLL
160 *
161 * This will copy DPLL settings from the memory mapped registers for a PLL to
162 * an array in memory.
163 */
164void prepare_abpll_for_ddrctrl(void)
165{
166 save_pll(slp_data.plls_con[ABPLL_ID], ABPLL_ID);
167 save_pll(slp_data.plls_con[DPLL_ID], DPLL_ID);
168
169 restore_pll(ABPLL_ID, slp_data.plls_con[DPLL_ID]);
170}
171
172void restore_abpll(void)
173{
174 restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
175}
176
Tony Xie42e113e2016-07-16 11:16:51 +0800177void clk_gate_con_save(void)
178{
179 uint32_t i = 0;
180
181 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
182 slp_data.pmucru_gate_con[i] =
183 mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
184
185 for (i = 0; i < CRU_GATE_COUNT; i++)
186 slp_data.cru_gate_con[i] =
187 mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
188}
189
190void clk_gate_con_disable(void)
191{
192 uint32_t i;
193
194 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
195 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
196
197 for (i = 0; i < CRU_GATE_COUNT; i++)
198 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
199}
200
201void clk_gate_con_restore(void)
202{
203 uint32_t i;
204
205 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
206 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
207 REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
208
209 for (i = 0; i < CRU_GATE_COUNT; i++)
210 mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
211 REG_SOC_WMSK | slp_data.cru_gate_con[i]);
212}
213
Tony Xief6118cc2016-01-15 17:17:32 +0800214static void set_plls_nobypass(uint32_t pll_id)
215{
216 if (pll_id == PPLL_ID)
217 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
218 PLL_NO_BYPASS_MODE);
219 else
220 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
221 PLL_NO_BYPASS_MODE);
222}
223
Caesar Wanged6b9a52016-08-11 02:11:45 +0800224static void _pll_resume(uint32_t pll_id)
225{
226 set_plls_nobypass(pll_id);
227 set_pll_normal_mode(pll_id);
228}
229
Lin Huang127527f2017-05-22 10:29:59 +0800230void set_pmu_rsthold(void)
231{
232 uint32_t rstnhold_cofig0;
233 uint32_t rstnhold_cofig1;
234
Derek Basehoref900a062018-04-23 14:49:22 -0700235 pmu_slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE +
Lin Huang127527f2017-05-22 10:29:59 +0800236 PMUCRU_RSTNHOLD_CON0);
Derek Basehoref900a062018-04-23 14:49:22 -0700237 pmu_slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE +
Lin Huang127527f2017-05-22 10:29:59 +0800238 PMUCRU_RSTNHOLD_CON1);
239 rstnhold_cofig0 = BIT_WITH_WMSK(PRESETN_NOC_PMU_HOLD) |
240 BIT_WITH_WMSK(PRESETN_INTMEM_PMU_HOLD) |
241 BIT_WITH_WMSK(HRESETN_CM0S_PMU_HOLD) |
242 BIT_WITH_WMSK(HRESETN_CM0S_NOC_PMU_HOLD) |
243 BIT_WITH_WMSK(DRESETN_CM0S_PMU_HOLD) |
244 BIT_WITH_WMSK(POESETN_CM0S_PMU_HOLD) |
245 BIT_WITH_WMSK(PRESETN_TIMER_PMU_0_1_HOLD) |
246 BIT_WITH_WMSK(RESETN_TIMER_PMU_0_HOLD) |
247 BIT_WITH_WMSK(RESETN_TIMER_PMU_1_HOLD) |
248 BIT_WITH_WMSK(PRESETN_UART_M0_PMU_HOLD) |
249 BIT_WITH_WMSK(RESETN_UART_M0_PMU_HOLD) |
250 BIT_WITH_WMSK(PRESETN_WDT_PMU_HOLD);
251 rstnhold_cofig1 = BIT_WITH_WMSK(PRESETN_RKPWM_PMU_HOLD) |
252 BIT_WITH_WMSK(PRESETN_PMUGRF_HOLD) |
253 BIT_WITH_WMSK(PRESETN_SGRF_HOLD) |
254 BIT_WITH_WMSK(PRESETN_GPIO0_HOLD) |
255 BIT_WITH_WMSK(PRESETN_GPIO1_HOLD) |
256 BIT_WITH_WMSK(PRESETN_CRU_PMU_HOLD) |
257 BIT_WITH_WMSK(PRESETN_PVTM_PMU_HOLD);
258
259 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, rstnhold_cofig0);
260 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, rstnhold_cofig1);
261}
262
Derek Basehoref900a062018-04-23 14:49:22 -0700263void pmu_sgrf_rst_hld(void)
264{
265 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
266 CRU_PMU_SGRF_RST_HOLD);
267}
268
269/*
270 * When system reset in running state, we want the cpus to be reboot
271 * from maskrom (system reboot),
272 * the pmusgrf reset-hold bits needs to be released.
273 * When system wake up from system deep suspend, some soc will be reset
274 * when waked up,
275 * we want the bootcpu to be reboot from pmusram,
276 * the pmusgrf reset-hold bits needs to be held.
277 */
278__pmusramfunc void pmu_sgrf_rst_hld_release(void)
279{
280 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
281 CRU_PMU_SGRF_RST_RLS);
282}
283
284__pmusramfunc void restore_pmu_rsthold(void)
Lin Huang127527f2017-05-22 10:29:59 +0800285{
286 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0,
Derek Basehoref900a062018-04-23 14:49:22 -0700287 pmu_slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK);
Lin Huang127527f2017-05-22 10:29:59 +0800288 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1,
Derek Basehoref900a062018-04-23 14:49:22 -0700289 pmu_slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK);
Lin Huang127527f2017-05-22 10:29:59 +0800290}
291
Caesar Wang5339d182016-10-27 01:13:34 +0800292/**
293 * enable_dvfs_plls - To resume the specific PLLs
294 *
295 * Please see the comment at the disable_dvfs_plls()
296 * we don't suspend the ABPLL, so don't need resume
297 * it too.
298 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800299void enable_dvfs_plls(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800300{
Caesar Wanged6b9a52016-08-11 02:11:45 +0800301 _pll_resume(ALPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +0800302 _pll_resume(GPLL_ID);
303 _pll_resume(VPLL_ID);
304 _pll_resume(NPLL_ID);
305 _pll_resume(CPLL_ID);
306}
Tony Xief6118cc2016-01-15 17:17:32 +0800307
Caesar Wang5339d182016-10-27 01:13:34 +0800308/**
309 * enable_nodvfs_plls - To resume the PPLL
310 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800311void enable_nodvfs_plls(void)
312{
313 _pll_resume(PPLL_ID);
Tony Xief6118cc2016-01-15 17:17:32 +0800314}
315
316void soc_global_soft_reset_init(void)
317{
318 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
319 CRU_PMU_SGRF_RST_RLS);
Caesar Wang59e41b52016-04-10 14:11:07 +0800320
321 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
322 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
Tony Xief6118cc2016-01-15 17:17:32 +0800323}
324
Xing Zheng22a98712017-02-24 14:56:41 +0800325void __dead2 soc_global_soft_reset(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800326{
Tony Xief6118cc2016-01-15 17:17:32 +0800327 set_pll_slow_mode(VPLL_ID);
328 set_pll_slow_mode(NPLL_ID);
329 set_pll_slow_mode(GPLL_ID);
330 set_pll_slow_mode(CPLL_ID);
331 set_pll_slow_mode(PPLL_ID);
332 set_pll_slow_mode(ABPLL_ID);
333 set_pll_slow_mode(ALPLL_ID);
Caesar Wang59e41b52016-04-10 14:11:07 +0800334
335 dsb();
336
Tony Xief6118cc2016-01-15 17:17:32 +0800337 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
338
339 /*
340 * Maybe the HW needs some times to reset the system,
341 * so we do not hope the core to excute valid codes.
342 */
343 while (1)
Tony Xie42e113e2016-07-16 11:16:51 +0800344 ;
Tony Xief6118cc2016-01-15 17:17:32 +0800345}
346
347void plat_rockchip_soc_init(void)
348{
349 secure_timer_init();
Xing Zheng22a98712017-02-24 14:56:41 +0800350 secure_sgrf_init();
Xing Zheng5e1e48f2017-02-24 14:47:51 +0800351 secure_sgrf_ddr_rgn_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800352 soc_global_soft_reset_init();
Caesar Wang038f6aa2016-05-25 19:21:43 +0800353 plat_rockchip_gpio_init();
Xing Zheng93280b72016-10-26 21:25:26 +0800354 m0_init();
Caesar Wanga8456902016-10-27 01:12:34 +0800355 dram_init();
Derek Basehoreff461d02016-10-20 20:46:43 -0700356 dram_dfs_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800357}