xref: /rk3399_ARM-atf/plat/rockchip/rk3399/drivers/soc/soc.c (revision d19ce2cb44d2aeea576ba70fdd0bc9e432af3d5d)
1 /*
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 <dram.h>
38 #include <rk3399_def.h>
39 #include <rk3399m0.h>
40 #include <soc.h>
41 
42 /* Table of regions to map using the MMU.  */
43 const mmap_region_t plat_rk_mmap[] = {
44 	MAP_REGION_FLAT(RK3399_DEV_RNG0_BASE, RK3399_DEV_RNG0_SIZE,
45 			MT_DEVICE | MT_RW | MT_SECURE),
46 	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
47 			MT_MEMORY | MT_RW | MT_SECURE),
48 
49 	{ 0 }
50 };
51 
52 /* The RockChip power domain tree descriptor */
53 const 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 
64 void 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 
77 void 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 
109 static 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 */
193 struct deepsleep_data_s slp_data;
194 
195 static void pll_suspend_prepare(uint32_t pll_id)
196 {
197 	int i;
198 
199 	if (pll_id == PPLL_ID)
200 		for (i = 0; i < PLL_CON_COUNT; i++)
201 			slp_data.plls_con[pll_id][i] =
202 				mmio_read_32(PMUCRU_BASE + PMUCRU_PPLL_CON(i));
203 	else
204 		for (i = 0; i < PLL_CON_COUNT; i++)
205 			slp_data.plls_con[pll_id][i] =
206 				mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
207 }
208 
209 static void set_pll_slow_mode(uint32_t pll_id)
210 {
211 	if (pll_id == PPLL_ID)
212 		mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
213 	else
214 		mmio_write_32((CRU_BASE +
215 			      CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
216 }
217 
218 static void set_pll_normal_mode(uint32_t pll_id)
219 {
220 	if (pll_id == PPLL_ID)
221 		mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
222 	else
223 		mmio_write_32(CRU_BASE +
224 			      CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
225 }
226 
227 static void set_pll_bypass(uint32_t pll_id)
228 {
229 	if (pll_id == PPLL_ID)
230 		mmio_write_32(PMUCRU_BASE +
231 			      PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
232 	else
233 		mmio_write_32(CRU_BASE +
234 			      CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
235 }
236 
237 static void _pll_suspend(uint32_t pll_id)
238 {
239 	set_pll_slow_mode(pll_id);
240 	set_pll_bypass(pll_id);
241 }
242 
243 /**
244  * disable_dvfs_plls - To suspend the specific PLLs
245  *
246  * When we close the center logic, the DPLL will be closed,
247  * so we need to keep the ABPLL and switch to it to supply
248  * clock for DDR during suspend, then we should not close
249  * the ABPLL and exclude ABPLL_ID.
250  */
251 void disable_dvfs_plls(void)
252 {
253 	_pll_suspend(CPLL_ID);
254 	_pll_suspend(NPLL_ID);
255 	_pll_suspend(VPLL_ID);
256 	_pll_suspend(GPLL_ID);
257 	_pll_suspend(ALPLL_ID);
258 }
259 
260 /**
261  * disable_nodvfs_plls - To suspend the PPLL
262  */
263 void disable_nodvfs_plls(void)
264 {
265 	_pll_suspend(PPLL_ID);
266 }
267 
268 /**
269  * restore_pll - Copy PLL settings from memory to a PLL.
270  *
271  * This will copy PLL settings from an array in memory to the memory mapped
272  * registers for a PLL.
273  *
274  * Note that: above the PLL exclude PPLL.
275  *
276  * pll_id: One of the values from enum plls_id
277  * src: Pointer to the array of values to restore from
278  */
279 static void restore_pll(int pll_id, uint32_t *src)
280 {
281 	/* Nice to have PLL off while configuring */
282 	mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
283 
284 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
285 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
286 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
287 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
288 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
289 
290 	/* Do PLL_CON3 since that will enable things */
291 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
292 
293 	/* Wait for PLL lock done */
294 	while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
295 		0x80000000) == 0x0)
296 		;
297 }
298 
299 /**
300  * save_pll - Copy PLL settings a PLL to memory
301  *
302  * This will copy PLL settings from the memory mapped registers for a PLL to
303  * an array in memory.
304  *
305  * Note that: above the PLL exclude PPLL.
306  *
307  * pll_id: One of the values from enum plls_id
308  * src: Pointer to the array of values to save to.
309  */
310 static void save_pll(uint32_t *dst, int pll_id)
311 {
312 	int i;
313 
314 	for (i = 0; i < PLL_CON_COUNT; i++)
315 		dst[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
316 }
317 
318 /**
319  * prepare_abpll_for_ddrctrl - Copy DPLL settings to ABPLL
320  *
321  * This will copy DPLL settings from the memory mapped registers for a PLL to
322  * an array in memory.
323  */
324 void prepare_abpll_for_ddrctrl(void)
325 {
326 	save_pll(slp_data.plls_con[ABPLL_ID], ABPLL_ID);
327 	save_pll(slp_data.plls_con[DPLL_ID], DPLL_ID);
328 
329 	restore_pll(ABPLL_ID, slp_data.plls_con[DPLL_ID]);
330 }
331 
332 void restore_abpll(void)
333 {
334 	restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
335 }
336 
337 void restore_dpll(void)
338 {
339 	restore_pll(DPLL_ID, slp_data.plls_con[DPLL_ID]);
340 }
341 
342 void plls_suspend_prepare(void)
343 {
344 	uint32_t i, pll_id;
345 
346 	for (pll_id = ALPLL_ID; pll_id < END_PLL_ID; pll_id++)
347 		pll_suspend_prepare(pll_id);
348 
349 	for (i = 0; i < CRU_CLKSEL_COUNT; i++)
350 		slp_data.cru_clksel_con[i] =
351 			mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(i));
352 
353 	for (i = 0; i < PMUCRU_CLKSEL_CONUT; i++)
354 		slp_data.pmucru_clksel_con[i] =
355 			mmio_read_32(PMUCRU_BASE +
356 				     PMUCRU_CLKSEL_OFFSET + i * REG_SIZE);
357 }
358 
359 void clk_gate_con_save(void)
360 {
361 	uint32_t i = 0;
362 
363 	for (i = 0; i < PMUCRU_GATE_COUNT; i++)
364 		slp_data.pmucru_gate_con[i] =
365 			mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
366 
367 	for (i = 0; i < CRU_GATE_COUNT; i++)
368 		slp_data.cru_gate_con[i] =
369 			mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
370 }
371 
372 void clk_gate_con_disable(void)
373 {
374 	uint32_t i;
375 
376 	for (i = 0; i < PMUCRU_GATE_COUNT; i++)
377 		mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
378 
379 	for (i = 0; i < CRU_GATE_COUNT; i++)
380 		mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
381 }
382 
383 void clk_gate_con_restore(void)
384 {
385 	uint32_t i;
386 
387 	for (i = 0; i < PMUCRU_GATE_COUNT; i++)
388 		mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
389 			      REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
390 
391 	for (i = 0; i < CRU_GATE_COUNT; i++)
392 		mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
393 			      REG_SOC_WMSK | slp_data.cru_gate_con[i]);
394 }
395 
396 static void set_plls_nobypass(uint32_t pll_id)
397 {
398 	if (pll_id == PPLL_ID)
399 		mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
400 			      PLL_NO_BYPASS_MODE);
401 	else
402 		mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
403 			      PLL_NO_BYPASS_MODE);
404 }
405 
406 static void _pll_resume(uint32_t pll_id)
407 {
408 	set_plls_nobypass(pll_id);
409 	set_pll_normal_mode(pll_id);
410 }
411 
412 void plls_resume_finish(void)
413 {
414 	int i;
415 
416 	for (i = 0; i < CRU_CLKSEL_COUNT; i++) {
417 		/* CRU_CLKSEL_CON96~107 the high 16-bit isb't write_mask */
418 		if (i > 95)
419 			mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
420 				      slp_data.cru_clksel_con[i]);
421 		else
422 			mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
423 				      REG_SOC_WMSK |
424 				      slp_data.cru_clksel_con[i]);
425 	}
426 	for (i = 0; i < PMUCRU_CLKSEL_CONUT; i++)
427 		mmio_write_32((PMUCRU_BASE +
428 			      PMUCRU_CLKSEL_OFFSET + i * REG_SIZE),
429 			      REG_SOC_WMSK | slp_data.pmucru_clksel_con[i]);
430 }
431 
432 /**
433  * enable_dvfs_plls - To resume the specific PLLs
434  *
435  * Please see the comment at the disable_dvfs_plls()
436  * we don't suspend the ABPLL, so don't need resume
437  * it too.
438  */
439 void enable_dvfs_plls(void)
440 {
441 	_pll_resume(ALPLL_ID);
442 	_pll_resume(GPLL_ID);
443 	_pll_resume(VPLL_ID);
444 	_pll_resume(NPLL_ID);
445 	_pll_resume(CPLL_ID);
446 }
447 
448 /**
449  * enable_nodvfs_plls - To resume the PPLL
450  */
451 void enable_nodvfs_plls(void)
452 {
453 	_pll_resume(PPLL_ID);
454 }
455 
456 void soc_global_soft_reset_init(void)
457 {
458 	mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
459 		      CRU_PMU_SGRF_RST_RLS);
460 
461 	mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
462 			CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
463 }
464 
465 void  __dead2 soc_global_soft_reset(void)
466 {
467 	set_pll_slow_mode(VPLL_ID);
468 	set_pll_slow_mode(NPLL_ID);
469 	set_pll_slow_mode(GPLL_ID);
470 	set_pll_slow_mode(CPLL_ID);
471 	set_pll_slow_mode(PPLL_ID);
472 	set_pll_slow_mode(ABPLL_ID);
473 	set_pll_slow_mode(ALPLL_ID);
474 
475 	dsb();
476 
477 	mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
478 
479 	/*
480 	 * Maybe the HW needs some times to reset the system,
481 	 * so we do not hope the core to excute valid codes.
482 	 */
483 	while (1)
484 		;
485 }
486 
487 static void soc_m0_init(void)
488 {
489 	/* secure config for pmu M0 */
490 	mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
491 
492 	/* set the execute address for M0 */
493 	mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
494 		      BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
495 				      0xffff, 0));
496 	mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
497 		      BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
498 				      0xf, 0));
499 }
500 
501 void plat_rockchip_soc_init(void)
502 {
503 	secure_timer_init();
504 	dma_secure_cfg(0);
505 	sgrf_init();
506 	soc_global_soft_reset_init();
507 	plat_rockchip_gpio_init();
508 	soc_m0_init();
509 	dram_init();
510 }
511