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 <mmio.h> 14 #include <m0_ctl.h> 15 #include <platform_def.h> 16 #include <plat_private.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 restore_dpll(void) 175 { 176 restore_pll(DPLL_ID, slp_data.plls_con[DPLL_ID]); 177 } 178 179 void clk_gate_con_save(void) 180 { 181 uint32_t i = 0; 182 183 for (i = 0; i < PMUCRU_GATE_COUNT; i++) 184 slp_data.pmucru_gate_con[i] = 185 mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i)); 186 187 for (i = 0; i < CRU_GATE_COUNT; i++) 188 slp_data.cru_gate_con[i] = 189 mmio_read_32(CRU_BASE + CRU_GATE_CON(i)); 190 } 191 192 void clk_gate_con_disable(void) 193 { 194 uint32_t i; 195 196 for (i = 0; i < PMUCRU_GATE_COUNT; i++) 197 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK); 198 199 for (i = 0; i < CRU_GATE_COUNT; i++) 200 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK); 201 } 202 203 void clk_gate_con_restore(void) 204 { 205 uint32_t i; 206 207 for (i = 0; i < PMUCRU_GATE_COUNT; i++) 208 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), 209 REG_SOC_WMSK | slp_data.pmucru_gate_con[i]); 210 211 for (i = 0; i < CRU_GATE_COUNT; i++) 212 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), 213 REG_SOC_WMSK | slp_data.cru_gate_con[i]); 214 } 215 216 static void set_plls_nobypass(uint32_t pll_id) 217 { 218 if (pll_id == PPLL_ID) 219 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), 220 PLL_NO_BYPASS_MODE); 221 else 222 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), 223 PLL_NO_BYPASS_MODE); 224 } 225 226 static void _pll_resume(uint32_t pll_id) 227 { 228 set_plls_nobypass(pll_id); 229 set_pll_normal_mode(pll_id); 230 } 231 232 /** 233 * enable_dvfs_plls - To resume the specific PLLs 234 * 235 * Please see the comment at the disable_dvfs_plls() 236 * we don't suspend the ABPLL, so don't need resume 237 * it too. 238 */ 239 void enable_dvfs_plls(void) 240 { 241 _pll_resume(ALPLL_ID); 242 _pll_resume(GPLL_ID); 243 _pll_resume(VPLL_ID); 244 _pll_resume(NPLL_ID); 245 _pll_resume(CPLL_ID); 246 } 247 248 /** 249 * enable_nodvfs_plls - To resume the PPLL 250 */ 251 void enable_nodvfs_plls(void) 252 { 253 _pll_resume(PPLL_ID); 254 } 255 256 void soc_global_soft_reset_init(void) 257 { 258 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), 259 CRU_PMU_SGRF_RST_RLS); 260 261 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON, 262 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK); 263 } 264 265 void __dead2 soc_global_soft_reset(void) 266 { 267 set_pll_slow_mode(VPLL_ID); 268 set_pll_slow_mode(NPLL_ID); 269 set_pll_slow_mode(GPLL_ID); 270 set_pll_slow_mode(CPLL_ID); 271 set_pll_slow_mode(PPLL_ID); 272 set_pll_slow_mode(ABPLL_ID); 273 set_pll_slow_mode(ALPLL_ID); 274 275 dsb(); 276 277 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL); 278 279 /* 280 * Maybe the HW needs some times to reset the system, 281 * so we do not hope the core to excute valid codes. 282 */ 283 while (1) 284 ; 285 } 286 287 void plat_rockchip_soc_init(void) 288 { 289 secure_timer_init(); 290 secure_sgrf_init(); 291 secure_sgrf_ddr_rgn_init(); 292 soc_global_soft_reset_init(); 293 plat_rockchip_gpio_init(); 294 m0_init(); 295 dram_init(); 296 dram_dfs_init(); 297 } 298