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