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