blob: 7dd0b72e255b85a8d3401fb55f94efc9d8c50277 [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
Tony Xief6118cc2016-01-15 17:17:32 +080046static void set_pll_slow_mode(uint32_t pll_id)
47{
48 if (pll_id == PPLL_ID)
49 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
50 else
51 mmio_write_32((CRU_BASE +
52 CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
53}
54
55static void set_pll_normal_mode(uint32_t pll_id)
56{
57 if (pll_id == PPLL_ID)
58 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
59 else
60 mmio_write_32(CRU_BASE +
61 CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
62}
63
64static void set_pll_bypass(uint32_t pll_id)
65{
66 if (pll_id == PPLL_ID)
67 mmio_write_32(PMUCRU_BASE +
68 PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
69 else
70 mmio_write_32(CRU_BASE +
71 CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
72}
73
74static void _pll_suspend(uint32_t pll_id)
75{
76 set_pll_slow_mode(pll_id);
77 set_pll_bypass(pll_id);
78}
79
Caesar Wang5339d182016-10-27 01:13:34 +080080/**
81 * disable_dvfs_plls - To suspend the specific PLLs
82 *
83 * When we close the center logic, the DPLL will be closed,
84 * so we need to keep the ABPLL and switch to it to supply
85 * clock for DDR during suspend, then we should not close
86 * the ABPLL and exclude ABPLL_ID.
87 */
Caesar Wanged6b9a52016-08-11 02:11:45 +080088void disable_dvfs_plls(void)
89{
90 _pll_suspend(CPLL_ID);
91 _pll_suspend(NPLL_ID);
92 _pll_suspend(VPLL_ID);
93 _pll_suspend(GPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +080094 _pll_suspend(ALPLL_ID);
95}
96
Caesar Wang5339d182016-10-27 01:13:34 +080097/**
98 * disable_nodvfs_plls - To suspend the PPLL
99 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800100void disable_nodvfs_plls(void)
101{
102 _pll_suspend(PPLL_ID);
103}
104
Caesar Wang5339d182016-10-27 01:13:34 +0800105/**
106 * restore_pll - Copy PLL settings from memory to a PLL.
107 *
108 * This will copy PLL settings from an array in memory to the memory mapped
109 * registers for a PLL.
110 *
111 * Note that: above the PLL exclude PPLL.
112 *
113 * pll_id: One of the values from enum plls_id
114 * src: Pointer to the array of values to restore from
115 */
116static void restore_pll(int pll_id, uint32_t *src)
117{
118 /* Nice to have PLL off while configuring */
119 mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
120
121 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
122 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
123 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
124 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
125 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
126
127 /* Do PLL_CON3 since that will enable things */
128 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
129
130 /* Wait for PLL lock done */
131 while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
132 0x80000000) == 0x0)
133 ;
134}
135
136/**
137 * save_pll - Copy PLL settings a PLL to memory
138 *
139 * This will copy PLL settings from the memory mapped registers for a PLL to
140 * an array in memory.
141 *
142 * Note that: above the PLL exclude PPLL.
143 *
144 * pll_id: One of the values from enum plls_id
145 * src: Pointer to the array of values to save to.
146 */
147static void save_pll(uint32_t *dst, int pll_id)
148{
149 int i;
150
151 for (i = 0; i < PLL_CON_COUNT; i++)
152 dst[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
153}
154
155/**
156 * prepare_abpll_for_ddrctrl - Copy DPLL settings to ABPLL
157 *
158 * This will copy DPLL settings from the memory mapped registers for a PLL to
159 * an array in memory.
160 */
161void prepare_abpll_for_ddrctrl(void)
162{
163 save_pll(slp_data.plls_con[ABPLL_ID], ABPLL_ID);
164 save_pll(slp_data.plls_con[DPLL_ID], DPLL_ID);
165
166 restore_pll(ABPLL_ID, slp_data.plls_con[DPLL_ID]);
167}
168
169void restore_abpll(void)
170{
171 restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
172}
173
Tony Xie42e113e2016-07-16 11:16:51 +0800174void clk_gate_con_save(void)
175{
176 uint32_t i = 0;
177
178 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
179 slp_data.pmucru_gate_con[i] =
180 mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
181
182 for (i = 0; i < CRU_GATE_COUNT; i++)
183 slp_data.cru_gate_con[i] =
184 mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
185}
186
187void clk_gate_con_disable(void)
188{
189 uint32_t i;
190
191 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
192 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
193
194 for (i = 0; i < CRU_GATE_COUNT; i++)
195 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
196}
197
198void clk_gate_con_restore(void)
199{
200 uint32_t i;
201
202 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
203 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
204 REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
205
206 for (i = 0; i < CRU_GATE_COUNT; i++)
207 mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
208 REG_SOC_WMSK | slp_data.cru_gate_con[i]);
209}
210
Tony Xief6118cc2016-01-15 17:17:32 +0800211static void set_plls_nobypass(uint32_t pll_id)
212{
213 if (pll_id == PPLL_ID)
214 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
215 PLL_NO_BYPASS_MODE);
216 else
217 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
218 PLL_NO_BYPASS_MODE);
219}
220
Caesar Wanged6b9a52016-08-11 02:11:45 +0800221static void _pll_resume(uint32_t pll_id)
222{
223 set_plls_nobypass(pll_id);
224 set_pll_normal_mode(pll_id);
225}
226
Lin Huang127527f2017-05-22 10:29:59 +0800227void set_pmu_rsthold(void)
228{
229 uint32_t rstnhold_cofig0;
230 uint32_t rstnhold_cofig1;
231
232 slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE +
233 PMUCRU_RSTNHOLD_CON0);
234 slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE +
235 PMUCRU_RSTNHOLD_CON1);
236 rstnhold_cofig0 = BIT_WITH_WMSK(PRESETN_NOC_PMU_HOLD) |
237 BIT_WITH_WMSK(PRESETN_INTMEM_PMU_HOLD) |
238 BIT_WITH_WMSK(HRESETN_CM0S_PMU_HOLD) |
239 BIT_WITH_WMSK(HRESETN_CM0S_NOC_PMU_HOLD) |
240 BIT_WITH_WMSK(DRESETN_CM0S_PMU_HOLD) |
241 BIT_WITH_WMSK(POESETN_CM0S_PMU_HOLD) |
242 BIT_WITH_WMSK(PRESETN_TIMER_PMU_0_1_HOLD) |
243 BIT_WITH_WMSK(RESETN_TIMER_PMU_0_HOLD) |
244 BIT_WITH_WMSK(RESETN_TIMER_PMU_1_HOLD) |
245 BIT_WITH_WMSK(PRESETN_UART_M0_PMU_HOLD) |
246 BIT_WITH_WMSK(RESETN_UART_M0_PMU_HOLD) |
247 BIT_WITH_WMSK(PRESETN_WDT_PMU_HOLD);
248 rstnhold_cofig1 = BIT_WITH_WMSK(PRESETN_RKPWM_PMU_HOLD) |
249 BIT_WITH_WMSK(PRESETN_PMUGRF_HOLD) |
250 BIT_WITH_WMSK(PRESETN_SGRF_HOLD) |
251 BIT_WITH_WMSK(PRESETN_GPIO0_HOLD) |
252 BIT_WITH_WMSK(PRESETN_GPIO1_HOLD) |
253 BIT_WITH_WMSK(PRESETN_CRU_PMU_HOLD) |
254 BIT_WITH_WMSK(PRESETN_PVTM_PMU_HOLD);
255
256 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, rstnhold_cofig0);
257 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, rstnhold_cofig1);
258}
259
260void restore_pmu_rsthold(void)
261{
262 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0,
263 slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK);
264 mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1,
265 slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK);
266}
267
Caesar Wang5339d182016-10-27 01:13:34 +0800268/**
269 * enable_dvfs_plls - To resume the specific PLLs
270 *
271 * Please see the comment at the disable_dvfs_plls()
272 * we don't suspend the ABPLL, so don't need resume
273 * it too.
274 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800275void enable_dvfs_plls(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800276{
Caesar Wanged6b9a52016-08-11 02:11:45 +0800277 _pll_resume(ALPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +0800278 _pll_resume(GPLL_ID);
279 _pll_resume(VPLL_ID);
280 _pll_resume(NPLL_ID);
281 _pll_resume(CPLL_ID);
282}
Tony Xief6118cc2016-01-15 17:17:32 +0800283
Caesar Wang5339d182016-10-27 01:13:34 +0800284/**
285 * enable_nodvfs_plls - To resume the PPLL
286 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800287void enable_nodvfs_plls(void)
288{
289 _pll_resume(PPLL_ID);
Tony Xief6118cc2016-01-15 17:17:32 +0800290}
291
292void soc_global_soft_reset_init(void)
293{
294 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
295 CRU_PMU_SGRF_RST_RLS);
Caesar Wang59e41b52016-04-10 14:11:07 +0800296
297 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
298 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
Tony Xief6118cc2016-01-15 17:17:32 +0800299}
300
Xing Zheng22a98712017-02-24 14:56:41 +0800301void __dead2 soc_global_soft_reset(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800302{
Tony Xief6118cc2016-01-15 17:17:32 +0800303 set_pll_slow_mode(VPLL_ID);
304 set_pll_slow_mode(NPLL_ID);
305 set_pll_slow_mode(GPLL_ID);
306 set_pll_slow_mode(CPLL_ID);
307 set_pll_slow_mode(PPLL_ID);
308 set_pll_slow_mode(ABPLL_ID);
309 set_pll_slow_mode(ALPLL_ID);
Caesar Wang59e41b52016-04-10 14:11:07 +0800310
311 dsb();
312
Tony Xief6118cc2016-01-15 17:17:32 +0800313 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
314
315 /*
316 * Maybe the HW needs some times to reset the system,
317 * so we do not hope the core to excute valid codes.
318 */
319 while (1)
Tony Xie42e113e2016-07-16 11:16:51 +0800320 ;
Tony Xief6118cc2016-01-15 17:17:32 +0800321}
322
323void plat_rockchip_soc_init(void)
324{
325 secure_timer_init();
Xing Zheng22a98712017-02-24 14:56:41 +0800326 secure_sgrf_init();
Xing Zheng5e1e48f2017-02-24 14:47:51 +0800327 secure_sgrf_ddr_rgn_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800328 soc_global_soft_reset_init();
Caesar Wang038f6aa2016-05-25 19:21:43 +0800329 plat_rockchip_gpio_init();
Xing Zheng93280b72016-10-26 21:25:26 +0800330 m0_init();
Caesar Wanga8456902016-10-27 01:12:34 +0800331 dram_init();
Derek Basehoreff461d02016-10-20 20:46:43 -0700332 dram_dfs_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800333}