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