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 /** 228 * enable_dvfs_plls - To resume the specific PLLs 229 * 230 * Please see the comment at the disable_dvfs_plls() 231 * we don't suspend the ABPLL, so don't need resume 232 * it too. 233 */ 234 void enable_dvfs_plls(void) 235 { 236 _pll_resume(ALPLL_ID); 237 _pll_resume(GPLL_ID); 238 _pll_resume(VPLL_ID); 239 _pll_resume(NPLL_ID); 240 _pll_resume(CPLL_ID); 241 } 242 243 /** 244 * enable_nodvfs_plls - To resume the PPLL 245 */ 246 void enable_nodvfs_plls(void) 247 { 248 _pll_resume(PPLL_ID); 249 } 250 251 void soc_global_soft_reset_init(void) 252 { 253 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), 254 CRU_PMU_SGRF_RST_RLS); 255 256 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON, 257 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK); 258 } 259 260 void __dead2 soc_global_soft_reset(void) 261 { 262 set_pll_slow_mode(VPLL_ID); 263 set_pll_slow_mode(NPLL_ID); 264 set_pll_slow_mode(GPLL_ID); 265 set_pll_slow_mode(CPLL_ID); 266 set_pll_slow_mode(PPLL_ID); 267 set_pll_slow_mode(ABPLL_ID); 268 set_pll_slow_mode(ALPLL_ID); 269 270 dsb(); 271 272 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL); 273 274 /* 275 * Maybe the HW needs some times to reset the system, 276 * so we do not hope the core to excute valid codes. 277 */ 278 while (1) 279 ; 280 } 281 282 void plat_rockchip_soc_init(void) 283 { 284 secure_timer_init(); 285 secure_sgrf_init(); 286 secure_sgrf_ddr_rgn_init(); 287 soc_global_soft_reset_init(); 288 plat_rockchip_gpio_init(); 289 m0_init(); 290 dram_init(); 291 dram_dfs_init(); 292 } 293