xref: /rk3399_ARM-atf/plat/rockchip/rk3399/drivers/soc/soc.c (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
1 /*
2  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <platform_def.h>
10 
11 #include <arch_helpers.h>
12 #include <common/debug.h>
13 #include <drivers/delay_timer.h>
14 #include <lib/mmio.h>
15 
16 #include <dfs.h>
17 #include <dram.h>
18 #include <m0_ctl.h>
19 #include <plat_private.h>
20 #include <rk3399_def.h>
21 #include <secure.h>
22 #include <soc.h>
23 
24 /* Table of regions to map using the MMU.  */
25 const mmap_region_t plat_rk_mmap[] = {
26 	MAP_REGION_FLAT(DEV_RNG0_BASE, DEV_RNG0_SIZE,
27 			MT_DEVICE | MT_RW | MT_SECURE),
28 	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
29 			MT_MEMORY | MT_RW | MT_SECURE),
30 
31 	{ 0 }
32 };
33 
34 /* The RockChip power domain tree descriptor */
35 const unsigned char rockchip_power_domain_tree_desc[] = {
36 	/* No of root nodes */
37 	PLATFORM_SYSTEM_COUNT,
38 	/* No of children for the root node */
39 	PLATFORM_CLUSTER_COUNT,
40 	/* No of children for the first cluster node */
41 	PLATFORM_CLUSTER0_CORE_COUNT,
42 	/* No of children for the second cluster node */
43 	PLATFORM_CLUSTER1_CORE_COUNT
44 };
45 
46 /* sleep data for pll suspend */
47 static struct deepsleep_data_s slp_data;
48 
49 /* sleep data that needs to be accessed from pmusram */
50 __pmusramdata struct pmu_sleep_data pmu_slp_data;
51 
52 static void set_pll_slow_mode(uint32_t pll_id)
53 {
54 	if (pll_id == PPLL_ID)
55 		mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
56 	else
57 		mmio_write_32((CRU_BASE +
58 			      CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
59 }
60 
61 static void set_pll_normal_mode(uint32_t pll_id)
62 {
63 	if (pll_id == PPLL_ID)
64 		mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
65 	else
66 		mmio_write_32(CRU_BASE +
67 			      CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
68 }
69 
70 static void set_pll_bypass(uint32_t pll_id)
71 {
72 	if (pll_id == PPLL_ID)
73 		mmio_write_32(PMUCRU_BASE +
74 			      PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
75 	else
76 		mmio_write_32(CRU_BASE +
77 			      CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
78 }
79 
80 static void _pll_suspend(uint32_t pll_id)
81 {
82 	set_pll_slow_mode(pll_id);
83 	set_pll_bypass(pll_id);
84 }
85 
86 /**
87  * disable_dvfs_plls - To suspend the specific PLLs
88  *
89  * When we close the center logic, the DPLL will be closed,
90  * so we need to keep the ABPLL and switch to it to supply
91  * clock for DDR during suspend, then we should not close
92  * the ABPLL and exclude ABPLL_ID.
93  */
94 void disable_dvfs_plls(void)
95 {
96 	_pll_suspend(CPLL_ID);
97 	_pll_suspend(NPLL_ID);
98 	_pll_suspend(VPLL_ID);
99 	_pll_suspend(GPLL_ID);
100 	_pll_suspend(ALPLL_ID);
101 }
102 
103 /**
104  * disable_nodvfs_plls - To suspend the PPLL
105  */
106 void disable_nodvfs_plls(void)
107 {
108 	_pll_suspend(PPLL_ID);
109 }
110 
111 /**
112  * restore_pll - Copy PLL settings from memory to a PLL.
113  *
114  * This will copy PLL settings from an array in memory to the memory mapped
115  * registers for a PLL.
116  *
117  * Note that: above the PLL exclude PPLL.
118  *
119  * pll_id: One of the values from enum plls_id
120  * src: Pointer to the array of values to restore from
121  */
122 static void restore_pll(int pll_id, uint32_t *src)
123 {
124 	/* Nice to have PLL off while configuring */
125 	mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
126 
127 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
128 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
129 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
130 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
131 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
132 
133 	/* Do PLL_CON3 since that will enable things */
134 	mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
135 
136 	/* Wait for PLL lock done */
137 	while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
138 		0x80000000) == 0x0)
139 		;
140 }
141 
142 /**
143  * save_pll - Copy PLL settings a PLL to memory
144  *
145  * This will copy PLL settings from the memory mapped registers for a PLL to
146  * an array in memory.
147  *
148  * Note that: above the PLL exclude PPLL.
149  *
150  * pll_id: One of the values from enum plls_id
151  * src: Pointer to the array of values to save to.
152  */
153 static void save_pll(uint32_t *dst, int pll_id)
154 {
155 	int i;
156 
157 	for (i = 0; i < PLL_CON_COUNT; i++)
158 		dst[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
159 }
160 
161 /**
162  * prepare_abpll_for_ddrctrl - Copy DPLL settings to ABPLL
163  *
164  * This will copy DPLL settings from the memory mapped registers for a PLL to
165  * an array in memory.
166  */
167 void prepare_abpll_for_ddrctrl(void)
168 {
169 	save_pll(slp_data.plls_con[ABPLL_ID], ABPLL_ID);
170 	save_pll(slp_data.plls_con[DPLL_ID], DPLL_ID);
171 
172 	restore_pll(ABPLL_ID, slp_data.plls_con[DPLL_ID]);
173 }
174 
175 void restore_abpll(void)
176 {
177 	restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
178 }
179 
180 void clk_gate_con_save(void)
181 {
182 	uint32_t i = 0;
183 
184 	for (i = 0; i < PMUCRU_GATE_COUNT; i++)
185 		slp_data.pmucru_gate_con[i] =
186 			mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
187 
188 	for (i = 0; i < CRU_GATE_COUNT; i++)
189 		slp_data.cru_gate_con[i] =
190 			mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
191 }
192 
193 void clk_gate_con_disable(void)
194 {
195 	uint32_t i;
196 
197 	for (i = 0; i < PMUCRU_GATE_COUNT; i++)
198 		mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
199 
200 	for (i = 0; i < CRU_GATE_COUNT; i++)
201 		mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
202 }
203 
204 void clk_gate_con_restore(void)
205 {
206 	uint32_t i;
207 
208 	for (i = 0; i < PMUCRU_GATE_COUNT; i++)
209 		mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
210 			      REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
211 
212 	for (i = 0; i < CRU_GATE_COUNT; i++)
213 		mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
214 			      REG_SOC_WMSK | slp_data.cru_gate_con[i]);
215 }
216 
217 static void set_plls_nobypass(uint32_t pll_id)
218 {
219 	if (pll_id == PPLL_ID)
220 		mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
221 			      PLL_NO_BYPASS_MODE);
222 	else
223 		mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
224 			      PLL_NO_BYPASS_MODE);
225 }
226 
227 static void _pll_resume(uint32_t pll_id)
228 {
229 	set_plls_nobypass(pll_id);
230 	set_pll_normal_mode(pll_id);
231 }
232 
233 void set_pmu_rsthold(void)
234 {
235 	uint32_t rstnhold_cofig0;
236 	uint32_t rstnhold_cofig1;
237 
238 	pmu_slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE +
239 					    PMUCRU_RSTNHOLD_CON0);
240 	pmu_slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE +
241 					    PMUCRU_RSTNHOLD_CON1);
242 	rstnhold_cofig0 = BIT_WITH_WMSK(PRESETN_NOC_PMU_HOLD) |
243 			  BIT_WITH_WMSK(PRESETN_INTMEM_PMU_HOLD) |
244 			  BIT_WITH_WMSK(HRESETN_CM0S_PMU_HOLD) |
245 			  BIT_WITH_WMSK(HRESETN_CM0S_NOC_PMU_HOLD) |
246 			  BIT_WITH_WMSK(DRESETN_CM0S_PMU_HOLD) |
247 			  BIT_WITH_WMSK(POESETN_CM0S_PMU_HOLD) |
248 			  BIT_WITH_WMSK(PRESETN_TIMER_PMU_0_1_HOLD) |
249 			  BIT_WITH_WMSK(RESETN_TIMER_PMU_0_HOLD) |
250 			  BIT_WITH_WMSK(RESETN_TIMER_PMU_1_HOLD) |
251 			  BIT_WITH_WMSK(PRESETN_UART_M0_PMU_HOLD) |
252 			  BIT_WITH_WMSK(RESETN_UART_M0_PMU_HOLD) |
253 			  BIT_WITH_WMSK(PRESETN_WDT_PMU_HOLD);
254 	rstnhold_cofig1 = BIT_WITH_WMSK(PRESETN_RKPWM_PMU_HOLD) |
255 			  BIT_WITH_WMSK(PRESETN_PMUGRF_HOLD) |
256 			  BIT_WITH_WMSK(PRESETN_SGRF_HOLD) |
257 			  BIT_WITH_WMSK(PRESETN_GPIO0_HOLD) |
258 			  BIT_WITH_WMSK(PRESETN_GPIO1_HOLD) |
259 			  BIT_WITH_WMSK(PRESETN_CRU_PMU_HOLD) |
260 			  BIT_WITH_WMSK(PRESETN_PVTM_PMU_HOLD);
261 
262 	mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, rstnhold_cofig0);
263 	mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, rstnhold_cofig1);
264 }
265 
266 void pmu_sgrf_rst_hld(void)
267 {
268 	mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
269 		      CRU_PMU_SGRF_RST_HOLD);
270 }
271 
272 /*
273  * When system reset in running state, we want the cpus to be reboot
274  * from maskrom (system reboot),
275  * the pmusgrf reset-hold bits needs to be released.
276  * When system wake up from system deep suspend, some soc will be reset
277  * when waked up,
278  * we want the bootcpu to be reboot from pmusram,
279  * the pmusgrf reset-hold bits needs to be held.
280  */
281 __pmusramfunc void pmu_sgrf_rst_hld_release(void)
282 {
283 	mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
284 		      CRU_PMU_SGRF_RST_RLS);
285 }
286 
287 __pmusramfunc void restore_pmu_rsthold(void)
288 {
289 	mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0,
290 		      pmu_slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK);
291 	mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1,
292 		      pmu_slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK);
293 }
294 
295 /**
296  * enable_dvfs_plls - To resume the specific PLLs
297  *
298  * Please see the comment at the disable_dvfs_plls()
299  * we don't suspend the ABPLL, so don't need resume
300  * it too.
301  */
302 void enable_dvfs_plls(void)
303 {
304 	_pll_resume(ALPLL_ID);
305 	_pll_resume(GPLL_ID);
306 	_pll_resume(VPLL_ID);
307 	_pll_resume(NPLL_ID);
308 	_pll_resume(CPLL_ID);
309 }
310 
311 /**
312  * enable_nodvfs_plls - To resume the PPLL
313  */
314 void enable_nodvfs_plls(void)
315 {
316 	_pll_resume(PPLL_ID);
317 }
318 
319 void soc_global_soft_reset_init(void)
320 {
321 	mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
322 		      CRU_PMU_SGRF_RST_RLS);
323 
324 	mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
325 			CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
326 }
327 
328 void __dead2 soc_global_soft_reset(void)
329 {
330 	set_pll_slow_mode(VPLL_ID);
331 	set_pll_slow_mode(NPLL_ID);
332 	set_pll_slow_mode(GPLL_ID);
333 	set_pll_slow_mode(CPLL_ID);
334 	set_pll_slow_mode(PPLL_ID);
335 	set_pll_slow_mode(ABPLL_ID);
336 	set_pll_slow_mode(ALPLL_ID);
337 
338 	dsb();
339 
340 	mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
341 
342 	/*
343 	 * Maybe the HW needs some times to reset the system,
344 	 * so we do not hope the core to excute valid codes.
345 	 */
346 	while (1)
347 		;
348 }
349 
350 void plat_rockchip_soc_init(void)
351 {
352 	secure_timer_init();
353 	secure_sgrf_init();
354 	secure_sgrf_ddr_rgn_init();
355 	soc_global_soft_reset_init();
356 	plat_rockchip_gpio_init();
357 	m0_init();
358 	dram_init();
359 	dram_dfs_init();
360 }
361