1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <arch_helpers.h> 32 #include <assert.h> 33 #include <bakery_lock.h> 34 #include <debug.h> 35 #include <delay_timer.h> 36 #include <errno.h> 37 #include <gpio.h> 38 #include <mmio.h> 39 #include <platform.h> 40 #include <platform_def.h> 41 #include <plat_params.h> 42 #include <plat_private.h> 43 #include <rk3399_def.h> 44 #include <pmu_sram.h> 45 #include <soc.h> 46 #include <pmu.h> 47 #include <pmu_com.h> 48 49 static struct psram_data_t *psram_sleep_cfg = 50 (struct psram_data_t *)PSRAM_DT_BASE; 51 52 static uint32_t cpu_warm_boot_addr; 53 54 /* 55 * There are two ways to powering on or off on core. 56 * 1) Control it power domain into on or off in PMU_PWRDN_CON reg, 57 * it is core_pwr_pd mode 58 * 2) Enable the core power manage in PMU_CORE_PM_CON reg, 59 * then, if the core enter into wfi, it power domain will be 60 * powered off automatically. it is core_pwr_wfi or core_pwr_wfi_int mode 61 * so we need core_pm_cfg_info to distinguish which method be used now. 62 */ 63 64 static uint32_t core_pm_cfg_info[PLATFORM_CORE_COUNT] 65 #if USE_COHERENT_MEM 66 __attribute__ ((section("tzfw_coherent_mem"))) 67 #endif 68 ;/* coheront */ 69 70 void rk3399_flash_l2_b(void) 71 { 72 uint32_t wait_cnt = 0; 73 74 mmio_setbits_32(PMU_BASE + PMU_SFT_CON, BIT(L2_FLUSH_REQ_CLUSTER_B)); 75 dsb(); 76 77 while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & 78 BIT(L2_FLUSHDONE_CLUSTER_B))) { 79 wait_cnt++; 80 if (!(wait_cnt % MAX_WAIT_CONUT)) 81 WARN("%s:reg %x,wait\n", __func__, 82 mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST)); 83 } 84 85 mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(L2_FLUSH_REQ_CLUSTER_B)); 86 } 87 88 static void pmu_scu_b_pwrdn(void) 89 { 90 uint32_t wait_cnt = 0; 91 92 if ((mmio_read_32(PMU_BASE + PMU_PWRDN_ST) & 93 (BIT(PMU_A72_B0_PWRDWN_ST) | BIT(PMU_A72_B1_PWRDWN_ST))) != 94 (BIT(PMU_A72_B0_PWRDWN_ST) | BIT(PMU_A72_B1_PWRDWN_ST))) { 95 ERROR("%s: not all cpus is off\n", __func__); 96 return; 97 } 98 99 rk3399_flash_l2_b(); 100 101 mmio_setbits_32(PMU_BASE + PMU_SFT_CON, BIT(ACINACTM_CLUSTER_B_CFG)); 102 103 while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & 104 BIT(STANDBY_BY_WFIL2_CLUSTER_B))) { 105 wait_cnt++; 106 if (!(wait_cnt % MAX_WAIT_CONUT)) 107 ERROR("%s:wait cluster-b l2(%x)\n", __func__, 108 mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST)); 109 } 110 } 111 112 static void pmu_scu_b_pwrup(void) 113 { 114 mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(ACINACTM_CLUSTER_B_CFG)); 115 } 116 117 void plat_rockchip_pmusram_prepare(void) 118 { 119 uint32_t *sram_dst, *sram_src; 120 size_t sram_size = 2; 121 122 /* 123 * pmu sram code and data prepare 124 */ 125 sram_dst = (uint32_t *)PMUSRAM_BASE; 126 sram_src = (uint32_t *)&pmu_cpuson_entrypoint_start; 127 sram_size = (uint32_t *)&pmu_cpuson_entrypoint_end - 128 (uint32_t *)sram_src; 129 130 u32_align_cpy(sram_dst, sram_src, sram_size); 131 132 psram_sleep_cfg->sp = PSRAM_DT_BASE; 133 } 134 135 static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id) 136 { 137 assert(cpu_id < PLATFORM_CORE_COUNT); 138 return core_pm_cfg_info[cpu_id]; 139 } 140 141 static inline void set_cpus_pwr_domain_cfg_info(uint32_t cpu_id, uint32_t value) 142 { 143 assert(cpu_id < PLATFORM_CORE_COUNT); 144 core_pm_cfg_info[cpu_id] = value; 145 #if !USE_COHERENT_MEM 146 flush_dcache_range((uintptr_t)&core_pm_cfg_info[cpu_id], 147 sizeof(uint32_t)); 148 #endif 149 } 150 151 static int cpus_power_domain_on(uint32_t cpu_id) 152 { 153 uint32_t cfg_info; 154 uint32_t cpu_pd = PD_CPUL0 + cpu_id; 155 /* 156 * There are two ways to powering on or off on core. 157 * 1) Control it power domain into on or off in PMU_PWRDN_CON reg 158 * 2) Enable the core power manage in PMU_CORE_PM_CON reg, 159 * then, if the core enter into wfi, it power domain will be 160 * powered off automatically. 161 */ 162 163 cfg_info = get_cpus_pwr_domain_cfg_info(cpu_id); 164 165 if (cfg_info == core_pwr_pd) { 166 /* disable core_pm cfg */ 167 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), 168 CORES_PM_DISABLE); 169 /* if the cores have be on, power off it firstly */ 170 if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) { 171 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), 0); 172 pmu_power_domain_ctr(cpu_pd, pmu_pd_off); 173 } 174 175 pmu_power_domain_ctr(cpu_pd, pmu_pd_on); 176 } else { 177 if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) { 178 WARN("%s: cpu%d is not in off,!\n", __func__, cpu_id); 179 return -EINVAL; 180 } 181 182 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), 183 BIT(core_pm_sft_wakeup_en)); 184 dsb(); 185 } 186 187 return 0; 188 } 189 190 static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg) 191 { 192 uint32_t cpu_pd; 193 uint32_t core_pm_value; 194 195 cpu_pd = PD_CPUL0 + cpu_id; 196 if (pmu_power_domain_st(cpu_pd) == pmu_pd_off) 197 return 0; 198 199 if (pd_cfg == core_pwr_pd) { 200 if (check_cpu_wfie(cpu_id, CKECK_WFEI_MSK)) 201 return -EINVAL; 202 203 /* disable core_pm cfg */ 204 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), 205 CORES_PM_DISABLE); 206 207 set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg); 208 pmu_power_domain_ctr(cpu_pd, pmu_pd_off); 209 } else { 210 set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg); 211 212 core_pm_value = BIT(core_pm_en); 213 if (pd_cfg == core_pwr_wfi_int) 214 core_pm_value |= BIT(core_pm_int_wakeup_en); 215 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), 216 core_pm_value); 217 dsb(); 218 } 219 220 return 0; 221 } 222 223 static void nonboot_cpus_off(void) 224 { 225 uint32_t boot_cpu, cpu; 226 227 boot_cpu = plat_my_core_pos(); 228 229 /* turn off noboot cpus */ 230 for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) { 231 if (cpu == boot_cpu) 232 continue; 233 cpus_power_domain_off(cpu, core_pwr_pd); 234 } 235 } 236 237 static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) 238 { 239 uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr); 240 241 assert(cpu_id < PLATFORM_CORE_COUNT); 242 assert(cpuson_flags[cpu_id] == 0); 243 cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG; 244 cpuson_entry_point[cpu_id] = entrypoint; 245 dsb(); 246 247 cpus_power_domain_on(cpu_id); 248 249 return 0; 250 } 251 252 static int cores_pwr_domain_off(void) 253 { 254 uint32_t cpu_id = plat_my_core_pos(); 255 256 cpus_power_domain_off(cpu_id, core_pwr_wfi); 257 258 return 0; 259 } 260 261 static int cores_pwr_domain_suspend(void) 262 { 263 uint32_t cpu_id = plat_my_core_pos(); 264 265 assert(cpu_id < PLATFORM_CORE_COUNT); 266 assert(cpuson_flags[cpu_id] == 0); 267 cpuson_flags[cpu_id] = PMU_CPU_AUTO_PWRDN; 268 cpuson_entry_point[cpu_id] = (uintptr_t)psci_entrypoint; 269 dsb(); 270 271 cpus_power_domain_off(cpu_id, core_pwr_wfi_int); 272 273 return 0; 274 } 275 276 static int cores_pwr_domain_on_finish(void) 277 { 278 uint32_t cpu_id = plat_my_core_pos(); 279 280 /* Disable core_pm */ 281 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); 282 283 return 0; 284 } 285 286 static int cores_pwr_domain_resume(void) 287 { 288 uint32_t cpu_id = plat_my_core_pos(); 289 290 /* Disable core_pm */ 291 mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); 292 293 return 0; 294 } 295 296 static void sys_slp_config(void) 297 { 298 uint32_t slp_mode_cfg = 0; 299 300 mmio_write_32(PMU_BASE + PMU_CCI500_CON, 301 BIT_WITH_WMSK(PMU_CLR_PREQ_CCI500_HW) | 302 BIT_WITH_WMSK(PMU_CLR_QREQ_CCI500_HW) | 303 BIT_WITH_WMSK(PMU_QGATING_CCI500_CFG)); 304 305 mmio_write_32(PMU_BASE + PMU_ADB400_CON, 306 BIT_WITH_WMSK(PMU_CLR_CORE_L_HW) | 307 BIT_WITH_WMSK(PMU_CLR_CORE_L_2GIC_HW) | 308 BIT_WITH_WMSK(PMU_CLR_GIC2_CORE_L_HW)); 309 310 mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1A_IOMUX, 311 BIT_WITH_WMSK(AP_PWROFF)); 312 313 slp_mode_cfg = BIT(PMU_PWR_MODE_EN) | 314 BIT(PMU_POWER_OFF_REQ_CFG) | 315 BIT(PMU_CPU0_PD_EN) | 316 BIT(PMU_L2_FLUSH_EN) | 317 BIT(PMU_L2_IDLE_EN) | 318 BIT(PMU_SCU_PD_EN); 319 320 mmio_setbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_CLUSTER_L_WKUP_EN); 321 mmio_setbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_CLUSTER_B_WKUP_EN); 322 mmio_clrbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_GPIO_WKUP_EN); 323 324 mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, slp_mode_cfg); 325 326 mmio_write_32(PMU_BASE + PMU_STABLE_CNT, CYCL_24M_CNT_MS(5)); 327 mmio_write_32(PMU_BASE + PMU_SCU_L_PWRDN_CNT, CYCL_24M_CNT_MS(2)); 328 mmio_write_32(PMU_BASE + PMU_SCU_L_PWRUP_CNT, CYCL_24M_CNT_MS(2)); 329 mmio_write_32(PMU_BASE + PMU_SCU_B_PWRDN_CNT, CYCL_24M_CNT_MS(2)); 330 mmio_write_32(PMU_BASE + PMU_SCU_B_PWRUP_CNT, CYCL_24M_CNT_MS(2)); 331 } 332 333 static int sys_pwr_domain_suspend(void) 334 { 335 sys_slp_config(); 336 plls_suspend(); 337 pmu_sgrf_rst_hld(); 338 339 mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), 340 (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | 341 CPU_BOOT_ADDR_WMASK); 342 343 pmu_scu_b_pwrdn(); 344 345 mmio_write_32(PMU_BASE + PMU_ADB400_CON, 346 BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | 347 BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_SW) | 348 BIT_WITH_WMSK(PMU_PWRDWN_REQ_GIC2_CORE_B_SW)); 349 dsb(); 350 mmio_setbits_32(PMU_BASE + PMU_PWRDN_CON, BIT(PMU_SCU_B_PWRDWN_EN)); 351 352 return 0; 353 } 354 355 static int sys_pwr_domain_resume(void) 356 { 357 pmu_sgrf_rst_hld(); 358 359 mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), 360 (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | 361 CPU_BOOT_ADDR_WMASK); 362 363 plls_resume(); 364 365 mmio_write_32(PMU_BASE + PMU_CCI500_CON, 366 WMSK_BIT(PMU_CLR_PREQ_CCI500_HW) | 367 WMSK_BIT(PMU_CLR_QREQ_CCI500_HW) | 368 WMSK_BIT(PMU_QGATING_CCI500_CFG)); 369 370 mmio_write_32(PMU_BASE + PMU_ADB400_CON, 371 WMSK_BIT(PMU_CLR_CORE_L_HW) | 372 WMSK_BIT(PMU_CLR_CORE_L_2GIC_HW) | 373 WMSK_BIT(PMU_CLR_GIC2_CORE_L_HW)); 374 375 mmio_clrbits_32(PMU_BASE + PMU_PWRDN_CON, 376 BIT(PMU_SCU_B_PWRDWN_EN)); 377 378 mmio_write_32(PMU_BASE + PMU_ADB400_CON, 379 WMSK_BIT(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | 380 WMSK_BIT(PMU_PWRDWN_REQ_CORE_B_SW) | 381 WMSK_BIT(PMU_PWRDWN_REQ_GIC2_CORE_B_SW)); 382 383 pmu_scu_b_pwrup(); 384 385 plat_rockchip_gic_cpuif_enable(); 386 return 0; 387 } 388 389 void __dead2 soc_soft_reset(void) 390 { 391 struct gpio_info *rst_gpio; 392 393 rst_gpio = (struct gpio_info *)plat_get_rockchip_gpio_reset(); 394 395 if (rst_gpio) { 396 gpio_set_direction(rst_gpio->index, GPIO_DIR_OUT); 397 gpio_set_value(rst_gpio->index, rst_gpio->polarity); 398 } else { 399 soc_global_soft_reset(); 400 } 401 402 while (1) 403 ; 404 } 405 406 void __dead2 soc_system_off(void) 407 { 408 struct gpio_info *poweroff_gpio; 409 410 poweroff_gpio = (struct gpio_info *)plat_get_rockchip_gpio_poweroff(); 411 412 if (poweroff_gpio) { 413 /* 414 * if use tsadc over temp pin(GPIO1A6) as shutdown gpio, 415 * need to set this pin iomux back to gpio function 416 */ 417 if (poweroff_gpio->index == TSADC_INT_PIN) { 418 mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1A_IOMUX, 419 GPIO1A6_IOMUX); 420 } 421 gpio_set_direction(poweroff_gpio->index, GPIO_DIR_OUT); 422 gpio_set_value(poweroff_gpio->index, poweroff_gpio->polarity); 423 } else { 424 WARN("Do nothing when system off\n"); 425 } 426 427 while (1) 428 ; 429 } 430 431 static struct rockchip_pm_ops_cb pm_ops = { 432 .cores_pwr_dm_on = cores_pwr_domain_on, 433 .cores_pwr_dm_off = cores_pwr_domain_off, 434 .cores_pwr_dm_on_finish = cores_pwr_domain_on_finish, 435 .cores_pwr_dm_suspend = cores_pwr_domain_suspend, 436 .cores_pwr_dm_resume = cores_pwr_domain_resume, 437 .sys_pwr_dm_suspend = sys_pwr_domain_suspend, 438 .sys_pwr_dm_resume = sys_pwr_domain_resume, 439 .sys_gbl_soft_reset = soc_soft_reset, 440 .system_off = soc_system_off, 441 }; 442 443 void plat_rockchip_pmu_init(void) 444 { 445 uint32_t cpu; 446 447 rockchip_pd_lock_init(); 448 plat_setup_rockchip_pm_ops(&pm_ops); 449 450 /* register requires 32bits mode, switch it to 32 bits */ 451 cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot; 452 453 for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) 454 cpuson_flags[cpu] = 0; 455 456 psram_sleep_cfg->ddr_func = 0x00; 457 psram_sleep_cfg->ddr_data = 0x00; 458 psram_sleep_cfg->ddr_flag = 0x00; 459 psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff; 460 461 /* cpu boot from pmusram */ 462 mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), 463 (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | 464 CPU_BOOT_ADDR_WMASK); 465 466 nonboot_cpus_off(); 467 468 INFO("%s(%d): pd status %x\n", __func__, __LINE__, 469 mmio_read_32(PMU_BASE + PMU_PWRDN_ST)); 470 } 471