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