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