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 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 169 void restore_abpll(void) 170 { 171 restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]); 172 } 173 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 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 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 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 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 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 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 */ 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 */ 287 void enable_nodvfs_plls(void) 288 { 289 _pll_resume(PPLL_ID); 290 } 291 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 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 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