blob: 2f6e67af60fe805f9ddc479bd4fdd5d1158df983 [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),
46
Tony Xief6118cc2016-01-15 17:17:32 +080047 { 0 }
48};
49
50/* The RockChip power domain tree descriptor */
51const unsigned char rockchip_power_domain_tree_desc[] = {
52 /* No of root nodes */
53 PLATFORM_SYSTEM_COUNT,
54 /* No of children for the root node */
55 PLATFORM_CLUSTER_COUNT,
56 /* No of children for the first cluster node */
57 PLATFORM_CLUSTER0_CORE_COUNT,
58 /* No of children for the second cluster node */
59 PLATFORM_CLUSTER1_CORE_COUNT
60};
61
62void secure_timer_init(void)
63{
64 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT0, 0xffffffff);
65 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT1, 0xffffffff);
66
67 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0);
68 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0);
69
70 /* auto reload & enable the timer */
71 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
72 TIMER_EN | TIMER_FMODE);
73}
74
75void sgrf_init(void)
76{
77 /* security config for master */
78 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(5),
79 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
80 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(6),
81 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
82 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(7),
83 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
84
85 /* security config for slave */
86 mmio_write_32(SGRF_BASE + SGRF_PMU_SLV_CON0_1(0),
87 SGRF_PMU_SLV_S_CFGED |
88 SGRF_PMU_SLV_CRYPTO1_NS);
89 mmio_write_32(SGRF_BASE + SGRF_PMU_SLV_CON0_1(1),
90 SGRF_PMU_SLV_CON1_CFG);
91 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(0),
92 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
93 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(1),
94 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
95 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(2),
96 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
97 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(3),
98 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
99 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(4),
100 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
101
102 /* security config for ddr memery */
103 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
104 SGRF_DDR_RGN_BYPS);
105}
106
107static void dma_secure_cfg(uint32_t secure)
108{
109 if (secure) {
110 /* rgn0 secure for dmac0 and dmac1 */
111 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON20_34(22),
112 SGRF_L_MST_S_DDR_RGN(0) | /* dmac0 */
113 SGRF_H_MST_S_DDR_RGN(0) /* dmac1 */
114 );
115
116 /* set dmac0 boot, under secure state */
117 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(8),
118 SGRF_DMAC_CFG_S);
119 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(9),
120 SGRF_DMAC_CFG_S);
121 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(10),
122 SGRF_DMAC_CFG_S);
123
124 /* dmac0 soft reset */
125 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
126 CRU_DMAC0_RST);
127 udelay(5);
128 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
129 CRU_DMAC0_RST_RLS);
130
131 /* set dmac1 boot, under secure state */
132 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(11),
133 SGRF_DMAC_CFG_S);
134 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(12),
135 SGRF_DMAC_CFG_S);
136 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(13),
137 SGRF_DMAC_CFG_S);
138 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(14),
139 SGRF_DMAC_CFG_S);
140 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(15),
141 SGRF_DMAC_CFG_S);
142
143 /* dmac1 soft reset */
144 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
145 CRU_DMAC1_RST);
146 udelay(5);
147 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
148 CRU_DMAC1_RST_RLS);
149 } else {
150 /* rgn non-secure for dmac0 and dmac1 */
151 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON20_34(22),
152 DMAC1_RGN_NS | DMAC0_RGN_NS);
153
154 /* set dmac0 boot, under non-secure state */
155 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(8),
156 DMAC0_BOOT_CFG_NS);
157 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(9),
158 DMAC0_BOOT_PERIPH_NS);
159 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(10),
160 DMAC0_BOOT_ADDR_NS);
161
162 /* dmac0 soft reset */
163 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
164 CRU_DMAC0_RST);
165 udelay(5);
166 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
167 CRU_DMAC0_RST_RLS);
168
169 /* set dmac1 boot, under non-secure state */
170 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(11),
171 DMAC1_BOOT_CFG_NS);
172 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(12),
173 DMAC1_BOOT_PERIPH_L_NS);
174 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(13),
175 DMAC1_BOOT_ADDR_NS);
176 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(14),
177 DMAC1_BOOT_PERIPH_H_NS);
178 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(15),
179 DMAC1_BOOT_IRQ_NS);
180
181 /* dmac1 soft reset */
182 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
183 CRU_DMAC1_RST);
184 udelay(5);
185 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
186 CRU_DMAC1_RST_RLS);
187 }
188}
189
190/* pll suspend */
191struct deepsleep_data_s slp_data;
192
193static void pll_suspend_prepare(uint32_t pll_id)
194{
195 int i;
196
197 if (pll_id == PPLL_ID)
198 for (i = 0; i < PLL_CON_COUNT; i++)
199 slp_data.plls_con[pll_id][i] =
200 mmio_read_32(PMUCRU_BASE + PMUCRU_PPLL_CON(i));
201 else
202 for (i = 0; i < PLL_CON_COUNT; i++)
203 slp_data.plls_con[pll_id][i] =
204 mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
205}
206
207static void set_pll_slow_mode(uint32_t pll_id)
208{
209 if (pll_id == PPLL_ID)
210 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
211 else
212 mmio_write_32((CRU_BASE +
213 CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
214}
215
216static void set_pll_normal_mode(uint32_t pll_id)
217{
218 if (pll_id == PPLL_ID)
219 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
220 else
221 mmio_write_32(CRU_BASE +
222 CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
223}
224
225static void set_pll_bypass(uint32_t pll_id)
226{
227 if (pll_id == PPLL_ID)
228 mmio_write_32(PMUCRU_BASE +
229 PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
230 else
231 mmio_write_32(CRU_BASE +
232 CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
233}
234
235static void _pll_suspend(uint32_t pll_id)
236{
237 set_pll_slow_mode(pll_id);
238 set_pll_bypass(pll_id);
239}
240
Caesar Wanged6b9a52016-08-11 02:11:45 +0800241void disable_dvfs_plls(void)
242{
243 _pll_suspend(CPLL_ID);
244 _pll_suspend(NPLL_ID);
245 _pll_suspend(VPLL_ID);
246 _pll_suspend(GPLL_ID);
247 _pll_suspend(ABPLL_ID);
248 _pll_suspend(ALPLL_ID);
249}
250
251void disable_nodvfs_plls(void)
252{
253 _pll_suspend(PPLL_ID);
254}
255
256void plls_suspend_prepare(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800257{
258 uint32_t i, pll_id;
259
260 for (pll_id = ALPLL_ID; pll_id < END_PLL_ID; pll_id++)
261 pll_suspend_prepare(pll_id);
262
263 for (i = 0; i < CRU_CLKSEL_COUNT; i++)
264 slp_data.cru_clksel_con[i] =
Tony Xie42e113e2016-07-16 11:16:51 +0800265 mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(i));
Tony Xief6118cc2016-01-15 17:17:32 +0800266
267 for (i = 0; i < PMUCRU_CLKSEL_CONUT; i++)
268 slp_data.pmucru_clksel_con[i] =
269 mmio_read_32(PMUCRU_BASE +
270 PMUCRU_CLKSEL_OFFSET + i * REG_SIZE);
Tony Xief6118cc2016-01-15 17:17:32 +0800271}
272
Tony Xie42e113e2016-07-16 11:16:51 +0800273void clk_gate_con_save(void)
274{
275 uint32_t i = 0;
276
277 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
278 slp_data.pmucru_gate_con[i] =
279 mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
280
281 for (i = 0; i < CRU_GATE_COUNT; i++)
282 slp_data.cru_gate_con[i] =
283 mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
284}
285
286void clk_gate_con_disable(void)
287{
288 uint32_t i;
289
290 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
291 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
292
293 for (i = 0; i < CRU_GATE_COUNT; i++)
294 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
295}
296
297void clk_gate_con_restore(void)
298{
299 uint32_t i;
300
301 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
302 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
303 REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
304
305 for (i = 0; i < CRU_GATE_COUNT; i++)
306 mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
307 REG_SOC_WMSK | slp_data.cru_gate_con[i]);
308}
309
Tony Xief6118cc2016-01-15 17:17:32 +0800310static void set_plls_nobypass(uint32_t pll_id)
311{
312 if (pll_id == PPLL_ID)
313 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
314 PLL_NO_BYPASS_MODE);
315 else
316 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
317 PLL_NO_BYPASS_MODE);
318}
319
Caesar Wanged6b9a52016-08-11 02:11:45 +0800320static void _pll_resume(uint32_t pll_id)
321{
322 set_plls_nobypass(pll_id);
323 set_pll_normal_mode(pll_id);
324}
325
326void plls_resume_finish(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800327{
328 int i;
329
Caesar Wang47e157c2016-09-27 18:19:30 -0700330 for (i = 0; i < CRU_CLKSEL_COUNT; i++) {
331 /* CRU_CLKSEL_CON96~107 the high 16-bit isb't write_mask */
332 if (i > 95)
333 mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
334 slp_data.cru_clksel_con[i]);
335 else
336 mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
337 REG_SOC_WMSK |
338 slp_data.cru_clksel_con[i]);
339 }
Tony Xief6118cc2016-01-15 17:17:32 +0800340 for (i = 0; i < PMUCRU_CLKSEL_CONUT; i++)
341 mmio_write_32((PMUCRU_BASE +
342 PMUCRU_CLKSEL_OFFSET + i * REG_SIZE),
343 REG_SOC_WMSK | slp_data.pmucru_clksel_con[i]);
344}
345
Caesar Wanged6b9a52016-08-11 02:11:45 +0800346void enable_dvfs_plls(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800347{
Caesar Wanged6b9a52016-08-11 02:11:45 +0800348 _pll_resume(ALPLL_ID);
349 _pll_resume(ABPLL_ID);
350 _pll_resume(GPLL_ID);
351 _pll_resume(VPLL_ID);
352 _pll_resume(NPLL_ID);
353 _pll_resume(CPLL_ID);
354}
Tony Xief6118cc2016-01-15 17:17:32 +0800355
Caesar Wanged6b9a52016-08-11 02:11:45 +0800356void enable_nodvfs_plls(void)
357{
358 _pll_resume(PPLL_ID);
Tony Xief6118cc2016-01-15 17:17:32 +0800359}
360
361void soc_global_soft_reset_init(void)
362{
363 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
364 CRU_PMU_SGRF_RST_RLS);
Caesar Wang59e41b52016-04-10 14:11:07 +0800365
366 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
367 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
Tony Xief6118cc2016-01-15 17:17:32 +0800368}
369
370void __dead2 soc_global_soft_reset(void)
371{
Tony Xief6118cc2016-01-15 17:17:32 +0800372 set_pll_slow_mode(VPLL_ID);
373 set_pll_slow_mode(NPLL_ID);
374 set_pll_slow_mode(GPLL_ID);
375 set_pll_slow_mode(CPLL_ID);
376 set_pll_slow_mode(PPLL_ID);
377 set_pll_slow_mode(ABPLL_ID);
378 set_pll_slow_mode(ALPLL_ID);
Caesar Wang59e41b52016-04-10 14:11:07 +0800379
380 dsb();
381
Tony Xief6118cc2016-01-15 17:17:32 +0800382 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
383
384 /*
385 * Maybe the HW needs some times to reset the system,
386 * so we do not hope the core to excute valid codes.
387 */
388 while (1)
Tony Xie42e113e2016-07-16 11:16:51 +0800389 ;
Tony Xief6118cc2016-01-15 17:17:32 +0800390}
391
Caesar Wangbb228622016-10-12 01:47:51 +0800392static void soc_m0_init(void)
393{
394 /* secure config for pmu M0 */
395 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
396
397 /* set the execute address for M0 */
398 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
399 BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
400 0xffff, 0));
401 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
402 BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
403 0xf, 0));
404}
405
Tony Xief6118cc2016-01-15 17:17:32 +0800406void plat_rockchip_soc_init(void)
407{
408 secure_timer_init();
409 dma_secure_cfg(0);
410 sgrf_init();
411 soc_global_soft_reset_init();
Caesar Wang038f6aa2016-05-25 19:21:43 +0800412 plat_rockchip_gpio_init();
Caesar Wangbb228622016-10-12 01:47:51 +0800413 soc_m0_init();
Caesar Wanga8456902016-10-27 01:12:34 +0800414 dram_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800415}