blob: c769b73bbac58576bf80d9d180a4351a761a2be3 [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 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch_helpers.h>
32#include <debug.h>
33#include <delay_timer.h>
34#include <mmio.h>
35#include <platform_def.h>
36#include <plat_private.h>
Caesar Wanga8456902016-10-27 01:12:34 +080037#include <dram.h>
Tony Xief6118cc2016-01-15 17:17:32 +080038#include <rk3399_def.h>
Caesar Wangbb228622016-10-12 01:47:51 +080039#include <rk3399m0.h>
Tony Xief6118cc2016-01-15 17:17:32 +080040#include <soc.h>
41
42/* Table of regions to map using the MMU. */
43const mmap_region_t plat_rk_mmap[] = {
Caesar Wangad39cfe2016-07-21 10:36:22 +080044 MAP_REGION_FLAT(RK3399_DEV_RNG0_BASE, RK3399_DEV_RNG0_SIZE,
Tony Xie42e113e2016-07-16 11:16:51 +080045 MT_DEVICE | MT_RW | MT_SECURE),
Caesar Wang5339d182016-10-27 01:13:34 +080046 MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
47 MT_MEMORY | MT_RW | MT_SECURE),
Tony Xie42e113e2016-07-16 11:16:51 +080048
Tony Xief6118cc2016-01-15 17:17:32 +080049 { 0 }
50};
51
52/* The RockChip power domain tree descriptor */
53const unsigned char rockchip_power_domain_tree_desc[] = {
54 /* No of root nodes */
55 PLATFORM_SYSTEM_COUNT,
56 /* No of children for the root node */
57 PLATFORM_CLUSTER_COUNT,
58 /* No of children for the first cluster node */
59 PLATFORM_CLUSTER0_CORE_COUNT,
60 /* No of children for the second cluster node */
61 PLATFORM_CLUSTER1_CORE_COUNT
62};
63
64void secure_timer_init(void)
65{
66 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT0, 0xffffffff);
67 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT1, 0xffffffff);
68
69 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0);
70 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0);
71
72 /* auto reload & enable the timer */
73 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
74 TIMER_EN | TIMER_FMODE);
75}
76
77void sgrf_init(void)
78{
79 /* security config for master */
80 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(5),
81 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
82 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(6),
83 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
84 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(7),
85 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
86
87 /* security config for slave */
88 mmio_write_32(SGRF_BASE + SGRF_PMU_SLV_CON0_1(0),
89 SGRF_PMU_SLV_S_CFGED |
90 SGRF_PMU_SLV_CRYPTO1_NS);
91 mmio_write_32(SGRF_BASE + SGRF_PMU_SLV_CON0_1(1),
92 SGRF_PMU_SLV_CON1_CFG);
93 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(0),
94 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
95 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(1),
96 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
97 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(2),
98 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
99 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(3),
100 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
101 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(4),
102 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
103
104 /* security config for ddr memery */
105 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
106 SGRF_DDR_RGN_BYPS);
107}
108
109static void dma_secure_cfg(uint32_t secure)
110{
111 if (secure) {
112 /* rgn0 secure for dmac0 and dmac1 */
113 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON20_34(22),
114 SGRF_L_MST_S_DDR_RGN(0) | /* dmac0 */
115 SGRF_H_MST_S_DDR_RGN(0) /* dmac1 */
116 );
117
118 /* set dmac0 boot, under secure state */
119 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(8),
120 SGRF_DMAC_CFG_S);
121 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(9),
122 SGRF_DMAC_CFG_S);
123 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(10),
124 SGRF_DMAC_CFG_S);
125
126 /* dmac0 soft reset */
127 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
128 CRU_DMAC0_RST);
129 udelay(5);
130 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
131 CRU_DMAC0_RST_RLS);
132
133 /* set dmac1 boot, under secure state */
134 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(11),
135 SGRF_DMAC_CFG_S);
136 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(12),
137 SGRF_DMAC_CFG_S);
138 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(13),
139 SGRF_DMAC_CFG_S);
140 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(14),
141 SGRF_DMAC_CFG_S);
142 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(15),
143 SGRF_DMAC_CFG_S);
144
145 /* dmac1 soft reset */
146 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
147 CRU_DMAC1_RST);
148 udelay(5);
149 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
150 CRU_DMAC1_RST_RLS);
151 } else {
152 /* rgn non-secure for dmac0 and dmac1 */
153 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON20_34(22),
154 DMAC1_RGN_NS | DMAC0_RGN_NS);
155
156 /* set dmac0 boot, under non-secure state */
157 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(8),
158 DMAC0_BOOT_CFG_NS);
159 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(9),
160 DMAC0_BOOT_PERIPH_NS);
161 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(10),
162 DMAC0_BOOT_ADDR_NS);
163
164 /* dmac0 soft reset */
165 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
166 CRU_DMAC0_RST);
167 udelay(5);
168 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
169 CRU_DMAC0_RST_RLS);
170
171 /* set dmac1 boot, under non-secure state */
172 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(11),
173 DMAC1_BOOT_CFG_NS);
174 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(12),
175 DMAC1_BOOT_PERIPH_L_NS);
176 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(13),
177 DMAC1_BOOT_ADDR_NS);
178 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(14),
179 DMAC1_BOOT_PERIPH_H_NS);
180 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(15),
181 DMAC1_BOOT_IRQ_NS);
182
183 /* dmac1 soft reset */
184 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
185 CRU_DMAC1_RST);
186 udelay(5);
187 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
188 CRU_DMAC1_RST_RLS);
189 }
190}
191
192/* pll suspend */
193struct deepsleep_data_s slp_data;
194
Caesar Wang813a89a2016-11-04 21:13:01 +0800195void secure_watchdog_disable(void)
196{
197 slp_data.sgrf_con[3] = mmio_read_32(SGRF_BASE + SGRF_SOC_CON3_7(3));
198
199 /* disable CA53 wdt pclk */
200 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(3),
201 BITS_WITH_WMASK(WDT_CA53_DIS, WDT_CA53_1BIT_MASK,
202 PCLK_WDT_CA53_GATE_SHIFT));
203 /* disable CM0 wdt pclk */
204 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(3),
205 BITS_WITH_WMASK(WDT_CM0_DIS, WDT_CM0_1BIT_MASK,
206 PCLK_WDT_CM0_GATE_SHIFT));
207}
208
209void secure_watchdog_restore(void)
210{
211 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(3),
212 slp_data.sgrf_con[3] |
213 WMSK_BIT(PCLK_WDT_CA53_GATE_SHIFT) |
214 WMSK_BIT(PCLK_WDT_CM0_GATE_SHIFT));
215}
216
Tony Xief6118cc2016-01-15 17:17:32 +0800217static void set_pll_slow_mode(uint32_t pll_id)
218{
219 if (pll_id == PPLL_ID)
220 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
221 else
222 mmio_write_32((CRU_BASE +
223 CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
224}
225
226static void set_pll_normal_mode(uint32_t pll_id)
227{
228 if (pll_id == PPLL_ID)
229 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
230 else
231 mmio_write_32(CRU_BASE +
232 CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
233}
234
235static void set_pll_bypass(uint32_t pll_id)
236{
237 if (pll_id == PPLL_ID)
238 mmio_write_32(PMUCRU_BASE +
239 PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
240 else
241 mmio_write_32(CRU_BASE +
242 CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
243}
244
245static void _pll_suspend(uint32_t pll_id)
246{
247 set_pll_slow_mode(pll_id);
248 set_pll_bypass(pll_id);
249}
250
Caesar Wang5339d182016-10-27 01:13:34 +0800251/**
252 * disable_dvfs_plls - To suspend the specific PLLs
253 *
254 * When we close the center logic, the DPLL will be closed,
255 * so we need to keep the ABPLL and switch to it to supply
256 * clock for DDR during suspend, then we should not close
257 * the ABPLL and exclude ABPLL_ID.
258 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800259void disable_dvfs_plls(void)
260{
261 _pll_suspend(CPLL_ID);
262 _pll_suspend(NPLL_ID);
263 _pll_suspend(VPLL_ID);
264 _pll_suspend(GPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +0800265 _pll_suspend(ALPLL_ID);
266}
267
Caesar Wang5339d182016-10-27 01:13:34 +0800268/**
269 * disable_nodvfs_plls - To suspend the PPLL
270 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800271void disable_nodvfs_plls(void)
272{
273 _pll_suspend(PPLL_ID);
274}
275
Caesar Wang5339d182016-10-27 01:13:34 +0800276/**
277 * restore_pll - Copy PLL settings from memory to a PLL.
278 *
279 * This will copy PLL settings from an array in memory to the memory mapped
280 * registers for a PLL.
281 *
282 * Note that: above the PLL exclude PPLL.
283 *
284 * pll_id: One of the values from enum plls_id
285 * src: Pointer to the array of values to restore from
286 */
287static void restore_pll(int pll_id, uint32_t *src)
288{
289 /* Nice to have PLL off while configuring */
290 mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
291
292 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
293 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
294 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
295 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
296 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
297
298 /* Do PLL_CON3 since that will enable things */
299 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
300
301 /* Wait for PLL lock done */
302 while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
303 0x80000000) == 0x0)
304 ;
305}
306
307/**
308 * save_pll - Copy PLL settings a PLL to memory
309 *
310 * This will copy PLL settings from the memory mapped registers for a PLL to
311 * an array in memory.
312 *
313 * Note that: above the PLL exclude PPLL.
314 *
315 * pll_id: One of the values from enum plls_id
316 * src: Pointer to the array of values to save to.
317 */
318static void save_pll(uint32_t *dst, int pll_id)
319{
320 int i;
321
322 for (i = 0; i < PLL_CON_COUNT; i++)
323 dst[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
324}
325
326/**
327 * prepare_abpll_for_ddrctrl - Copy DPLL settings to ABPLL
328 *
329 * This will copy DPLL settings from the memory mapped registers for a PLL to
330 * an array in memory.
331 */
332void prepare_abpll_for_ddrctrl(void)
333{
334 save_pll(slp_data.plls_con[ABPLL_ID], ABPLL_ID);
335 save_pll(slp_data.plls_con[DPLL_ID], DPLL_ID);
336
337 restore_pll(ABPLL_ID, slp_data.plls_con[DPLL_ID]);
338}
339
340void restore_abpll(void)
341{
342 restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
343}
344
345void restore_dpll(void)
346{
347 restore_pll(DPLL_ID, slp_data.plls_con[DPLL_ID]);
348}
349
Tony Xie42e113e2016-07-16 11:16:51 +0800350void clk_gate_con_save(void)
351{
352 uint32_t i = 0;
353
354 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
355 slp_data.pmucru_gate_con[i] =
356 mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
357
358 for (i = 0; i < CRU_GATE_COUNT; i++)
359 slp_data.cru_gate_con[i] =
360 mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
361}
362
363void clk_gate_con_disable(void)
364{
365 uint32_t i;
366
367 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
368 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
369
370 for (i = 0; i < CRU_GATE_COUNT; i++)
371 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
372}
373
374void clk_gate_con_restore(void)
375{
376 uint32_t i;
377
378 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
379 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
380 REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
381
382 for (i = 0; i < CRU_GATE_COUNT; i++)
383 mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
384 REG_SOC_WMSK | slp_data.cru_gate_con[i]);
385}
386
Tony Xief6118cc2016-01-15 17:17:32 +0800387static void set_plls_nobypass(uint32_t pll_id)
388{
389 if (pll_id == PPLL_ID)
390 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
391 PLL_NO_BYPASS_MODE);
392 else
393 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
394 PLL_NO_BYPASS_MODE);
395}
396
Caesar Wanged6b9a52016-08-11 02:11:45 +0800397static void _pll_resume(uint32_t pll_id)
398{
399 set_plls_nobypass(pll_id);
400 set_pll_normal_mode(pll_id);
401}
402
Caesar Wang5339d182016-10-27 01:13:34 +0800403/**
404 * enable_dvfs_plls - To resume the specific PLLs
405 *
406 * Please see the comment at the disable_dvfs_plls()
407 * we don't suspend the ABPLL, so don't need resume
408 * it too.
409 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800410void enable_dvfs_plls(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800411{
Caesar Wanged6b9a52016-08-11 02:11:45 +0800412 _pll_resume(ALPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +0800413 _pll_resume(GPLL_ID);
414 _pll_resume(VPLL_ID);
415 _pll_resume(NPLL_ID);
416 _pll_resume(CPLL_ID);
417}
Tony Xief6118cc2016-01-15 17:17:32 +0800418
Caesar Wang5339d182016-10-27 01:13:34 +0800419/**
420 * enable_nodvfs_plls - To resume the PPLL
421 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800422void enable_nodvfs_plls(void)
423{
424 _pll_resume(PPLL_ID);
Tony Xief6118cc2016-01-15 17:17:32 +0800425}
426
427void soc_global_soft_reset_init(void)
428{
429 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
430 CRU_PMU_SGRF_RST_RLS);
Caesar Wang59e41b52016-04-10 14:11:07 +0800431
432 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
433 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
Tony Xief6118cc2016-01-15 17:17:32 +0800434}
435
436void __dead2 soc_global_soft_reset(void)
437{
Tony Xief6118cc2016-01-15 17:17:32 +0800438 set_pll_slow_mode(VPLL_ID);
439 set_pll_slow_mode(NPLL_ID);
440 set_pll_slow_mode(GPLL_ID);
441 set_pll_slow_mode(CPLL_ID);
442 set_pll_slow_mode(PPLL_ID);
443 set_pll_slow_mode(ABPLL_ID);
444 set_pll_slow_mode(ALPLL_ID);
Caesar Wang59e41b52016-04-10 14:11:07 +0800445
446 dsb();
447
Tony Xief6118cc2016-01-15 17:17:32 +0800448 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
449
450 /*
451 * Maybe the HW needs some times to reset the system,
452 * so we do not hope the core to excute valid codes.
453 */
454 while (1)
Tony Xie42e113e2016-07-16 11:16:51 +0800455 ;
Tony Xief6118cc2016-01-15 17:17:32 +0800456}
457
Caesar Wangbb228622016-10-12 01:47:51 +0800458static void soc_m0_init(void)
459{
460 /* secure config for pmu M0 */
461 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
462
463 /* set the execute address for M0 */
464 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
465 BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
466 0xffff, 0));
467 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
468 BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
469 0xf, 0));
470}
471
Tony Xief6118cc2016-01-15 17:17:32 +0800472void plat_rockchip_soc_init(void)
473{
474 secure_timer_init();
475 dma_secure_cfg(0);
476 sgrf_init();
477 soc_global_soft_reset_init();
Caesar Wang038f6aa2016-05-25 19:21:43 +0800478 plat_rockchip_gpio_init();
Caesar Wangbb228622016-10-12 01:47:51 +0800479 soc_m0_init();
Caesar Wanga8456902016-10-27 01:12:34 +0800480 dram_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800481}