1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. 4 * Copyright 2017 NXP 5 */ 6 7#include <cpu_func.h> 8#include <asm/cache.h> 9#include <asm/io.h> 10#include <asm/psci.h> 11#include <asm/secure.h> 12#include <asm/arch/imx-regs.h> 13#include <asm/armv7.h> 14#include <asm/gic.h> 15#include <linux/bitops.h> 16#include <common.h> 17#include <fsl_wdog.h> 18 19#define GPC_LPCR_A7_BSC 0x0 20#define GPC_LPCR_A7_AD 0x4 21#define GPC_SLPCR 0x14 22#define GPC_PGC_ACK_SEL_A7 0x24 23#define GPC_IMR1_CORE0 0x30 24#define GPC_SLOT0_CFG 0xb0 25#define GPC_CPU_PGC_SW_PUP_REQ 0xf0 26#define GPC_CPU_PGC_SW_PDN_REQ 0xfc 27#define GPC_PGC_C0 0x800 28#define GPC_PGC_C0 0x800 29#define GPC_PGC_C1 0x840 30#define GPC_PGC_SCU 0x880 31 32#define BM_LPCR_A7_BSC_CPU_CLK_ON_LPM 0x4000 33#define BM_LPCR_A7_BSC_LPM1 0xc 34#define BM_LPCR_A7_BSC_LPM0 0x3 35#define BP_LPCR_A7_BSC_LPM0 0 36#define BM_SLPCR_EN_DSM 0x80000000 37#define BM_SLPCR_RBC_EN 0x40000000 38#define BM_SLPCR_REG_BYPASS_COUNT 0x3f000000 39#define BM_SLPCR_VSTBY 0x4 40#define BM_SLPCR_SBYOS 0x2 41#define BM_SLPCR_BYPASS_PMIC_READY 0x1 42#define BM_LPCR_A7_AD_L2PGE 0x10000 43#define BM_LPCR_A7_AD_EN_C1_PUP 0x800 44#define BM_LPCR_A7_AD_EN_C0_PUP 0x200 45#define BM_LPCR_A7_AD_EN_PLAT_PDN 0x10 46#define BM_LPCR_A7_AD_EN_C1_PDN 0x8 47#define BM_LPCR_A7_AD_EN_C0_PDN 0x2 48 49#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE0_A7 0x1 50#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2 51 52#define BM_GPC_PGC_ACK_SEL_A7_PD_DUMMY_ACK 0x8000 53#define BM_GPC_PGC_ACK_SEL_A7_PU_DUMMY_ACK 0x80000000 54 55#define MAX_SLOT_NUMBER 10 56#define A7_LPM_WAIT 0x5 57#define A7_LPM_STOP 0xa 58 59#define BM_SYS_COUNTER_CNTCR_FCR1 0x200 60#define BM_SYS_COUNTER_CNTCR_FCR0 0x100 61 62#define REG_SET 0x4 63#define REG_CLR 0x8 64 65#define ANADIG_ARM_PLL 0x60 66#define ANADIG_DDR_PLL 0x70 67#define ANADIG_SYS_PLL 0xb0 68#define ANADIG_ENET_PLL 0xe0 69#define ANADIG_AUDIO_PLL 0xf0 70#define ANADIG_VIDEO_PLL 0x130 71#define BM_ANATOP_ARM_PLL_OVERRIDE BIT(20) 72#define BM_ANATOP_DDR_PLL_OVERRIDE BIT(19) 73#define BM_ANATOP_SYS_PLL_OVERRIDE (0x1ff << 17) 74#define BM_ANATOP_ENET_PLL_OVERRIDE BIT(13) 75#define BM_ANATOP_AUDIO_PLL_OVERRIDE BIT(24) 76#define BM_ANATOP_VIDEO_PLL_OVERRIDE BIT(24) 77 78#define DDRC_STAT 0x4 79#define DDRC_PWRCTL 0x30 80#define DDRC_PSTAT 0x3fc 81 82#define SRC_GPR1_MX7D 0x074 83#define SRC_GPR2_MX7D 0x078 84#define SRC_A7RCR0 0x004 85#define SRC_A7RCR1 0x008 86 87#define BP_SRC_A7RCR0_A7_CORE_RESET0 0 88#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 89 90#define SNVS_LPCR 0x38 91#define BP_SNVS_LPCR_DP_EN 0x20 92#define BP_SNVS_LPCR_TOP 0x40 93 94#define CCM_CCGR_SNVS 0x4250 95 96#define CCM_ROOT_WDOG 0xbb80 97#define CCM_CCGR_WDOG1 0x49c0 98 99#define MPIDR_AFF0 GENMASK(7, 0) 100 101#define IMX7D_PSCI_NR_CPUS 2 102#if IMX7D_PSCI_NR_CPUS > CONFIG_ARMV7_PSCI_NR_CPUS 103#error "invalid value for CONFIG_ARMV7_PSCI_NR_CPUS" 104#endif 105 106#define imx_cpu_gpr_entry_offset(cpu) \ 107 (SRC_BASE_ADDR + SRC_GPR1_MX7D + cpu * 8) 108#define imx_cpu_gpr_para_offset(cpu) \ 109 (imx_cpu_gpr_entry_offset(cpu) + 4) 110 111#define IMX_CPU_SYNC_OFF ~0 112#define IMX_CPU_SYNC_ON 0 113 114u8 psci_state[IMX7D_PSCI_NR_CPUS] __secure_data = { 115 PSCI_AFFINITY_LEVEL_ON, 116 PSCI_AFFINITY_LEVEL_OFF}; 117 118enum imx_gpc_slot { 119 CORE0_A7, 120 CORE1_A7, 121 SCU_A7, 122 FAST_MEGA_MIX, 123 MIPI_PHY, 124 PCIE_PHY, 125 USB_OTG1_PHY, 126 USB_OTG2_PHY, 127 USB_HSIC_PHY, 128 CORE0_M4, 129}; 130 131enum mxc_cpu_pwr_mode { 132 RUN, 133 WAIT, 134 STOP, 135}; 136 137extern void psci_system_resume(void); 138 139static inline void psci_set_state(int cpu, u8 state) 140{ 141 psci_state[cpu] = state; 142 dsb(); 143 isb(); 144} 145 146static inline void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset) 147{ 148 writel(enable, GPC_IPS_BASE_ADDR + offset); 149} 150 151__secure void imx_gpcv2_set_core_power(int cpu, bool pdn) 152{ 153 u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ; 154 u32 pgc = cpu ? GPC_PGC_C1 : GPC_PGC_C0; 155 u32 pdn_pup_req = cpu ? BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 : 156 BM_CPU_PGC_SW_PDN_PUP_REQ_CORE0_A7; 157 u32 val; 158 159 imx_gpcv2_set_m_core_pgc(true, pgc); 160 161 val = readl(GPC_IPS_BASE_ADDR + reg); 162 val |= pdn_pup_req; 163 writel(val, GPC_IPS_BASE_ADDR + reg); 164 165 while ((readl(GPC_IPS_BASE_ADDR + reg) & pdn_pup_req) != 0) 166 ; 167 168 imx_gpcv2_set_m_core_pgc(false, pgc); 169} 170 171__secure void imx_enable_cpu_ca7(int cpu, bool enable) 172{ 173 u32 mask, val; 174 175 mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1); 176 val = readl(SRC_BASE_ADDR + SRC_A7RCR1); 177 val = enable ? val | mask : val & ~mask; 178 writel(val, SRC_BASE_ADDR + SRC_A7RCR1); 179} 180 181__secure void psci_arch_cpu_entry(void) 182{ 183 u32 cpu = psci_get_cpu_id(); 184 185 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON); 186} 187 188__secure s32 psci_cpu_on(u32 __always_unused function_id, u32 mpidr, u32 ep, 189 u32 context_id) 190{ 191 u32 cpu = mpidr & MPIDR_AFF0; 192 193 if (mpidr & ~MPIDR_AFF0) 194 return ARM_PSCI_RET_INVAL; 195 196 if (cpu >= IMX7D_PSCI_NR_CPUS) 197 return ARM_PSCI_RET_INVAL; 198 199 if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON) 200 return ARM_PSCI_RET_ALREADY_ON; 201 202 if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON_PENDING) 203 return ARM_PSCI_RET_ON_PENDING; 204 205 psci_save(cpu, ep, context_id); 206 207 writel((u32)psci_cpu_entry, imx_cpu_gpr_entry_offset(cpu)); 208 209 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON_PENDING); 210 211 imx_gpcv2_set_core_power(cpu, true); 212 imx_enable_cpu_ca7(cpu, true); 213 214 return ARM_PSCI_RET_SUCCESS; 215} 216 217__secure s32 psci_cpu_off(void) 218{ 219 int cpu; 220 221 cpu = psci_get_cpu_id(); 222 223 psci_cpu_off_common(); 224 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_OFF); 225 226 imx_enable_cpu_ca7(cpu, false); 227 imx_gpcv2_set_core_power(cpu, false); 228 /* 229 * We use the cpu jumping argument register to sync with 230 * psci_affinity_info() which is running on cpu0 to kill the cpu. 231 */ 232 writel(IMX_CPU_SYNC_OFF, imx_cpu_gpr_para_offset(cpu)); 233 234 while (1) 235 wfi(); 236} 237 238__secure void psci_system_reset(void) 239{ 240 struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; 241 242 /* make sure WDOG1 clock is enabled */ 243 writel(0x1 << 28, CCM_BASE_ADDR + CCM_ROOT_WDOG); 244 writel(0x3, CCM_BASE_ADDR + CCM_CCGR_WDOG1); 245 writew(WCR_WDE, &wdog->wcr); 246 247 while (1) 248 wfi(); 249} 250 251__secure void psci_system_off(void) 252{ 253 u32 val; 254 255 /* make sure SNVS clock is enabled */ 256 writel(0x3, CCM_BASE_ADDR + CCM_CCGR_SNVS); 257 258 val = readl(SNVS_BASE_ADDR + SNVS_LPCR); 259 val |= BP_SNVS_LPCR_DP_EN | BP_SNVS_LPCR_TOP; 260 writel(val, SNVS_BASE_ADDR + SNVS_LPCR); 261 262 while (1) 263 wfi(); 264} 265 266__secure u32 psci_version(void) 267{ 268 return ARM_PSCI_VER_1_0; 269} 270 271__secure s32 psci_cpu_suspend(u32 __always_unused function_id, u32 power_state, 272 u32 entry_point_address, 273 u32 context_id) 274{ 275 return ARM_PSCI_RET_INVAL; 276} 277 278__secure s32 psci_affinity_info(u32 __always_unused function_id, 279 u32 target_affinity, 280 u32 lowest_affinity_level) 281{ 282 u32 cpu = target_affinity & MPIDR_AFF0; 283 284 if (lowest_affinity_level > 0) 285 return ARM_PSCI_RET_INVAL; 286 287 if (target_affinity & ~MPIDR_AFF0) 288 return ARM_PSCI_RET_INVAL; 289 290 if (cpu >= IMX7D_PSCI_NR_CPUS) 291 return ARM_PSCI_RET_INVAL; 292 293 /* CPU is waiting for killed */ 294 if (readl(imx_cpu_gpr_para_offset(cpu)) == IMX_CPU_SYNC_OFF) { 295 imx_enable_cpu_ca7(cpu, false); 296 imx_gpcv2_set_core_power(cpu, false); 297 writel(IMX_CPU_SYNC_ON, imx_cpu_gpr_para_offset(cpu)); 298 } 299 300 return psci_state[cpu]; 301} 302 303__secure u32 psci_migrate_info_type(void) 304{ 305 /* Trusted OS is either not present or does not require migration */ 306 return 2; 307} 308 309__secure s32 psci_features(u32 __always_unused function_id, u32 psci_fid) 310{ 311 switch (psci_fid) { 312 case ARM_PSCI_0_2_FN_PSCI_VERSION: 313 case ARM_PSCI_0_2_FN_CPU_OFF: 314 case ARM_PSCI_0_2_FN_CPU_ON: 315 case ARM_PSCI_0_2_FN_AFFINITY_INFO: 316 case ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE: 317 case ARM_PSCI_0_2_FN_SYSTEM_OFF: 318 case ARM_PSCI_0_2_FN_SYSTEM_RESET: 319 case ARM_PSCI_1_0_FN_PSCI_FEATURES: 320 case ARM_PSCI_1_0_FN_SYSTEM_SUSPEND: 321 return 0x0; 322 } 323 return ARM_PSCI_RET_NI; 324} 325 326static __secure void imx_gpcv2_set_lpm_mode(enum mxc_cpu_pwr_mode mode) 327{ 328 u32 val1, val2, val3; 329 330 val1 = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC); 331 val2 = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 332 333 /* all cores' LPM settings must be same */ 334 val1 &= ~(BM_LPCR_A7_BSC_LPM0 | BM_LPCR_A7_BSC_LPM1); 335 val1 |= BM_LPCR_A7_BSC_CPU_CLK_ON_LPM; 336 337 val2 &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN | 338 BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY); 339 /* 340 * GPC: When improper low-power sequence is used, 341 * the SoC enters low power mode before the ARM core executes WFI. 342 * 343 * Software workaround: 344 * 1) Software should trigger IRQ #32 (IOMUX) to be always pending 345 * by setting IOMUX_GPR1_IRQ. 346 * 2) Software should then unmask IRQ #32 in GPC before setting GPC 347 * Low-Power mode. 348 * 3) Software should mask IRQ #32 right after GPC Low-Power mode 349 * is set. 350 */ 351 switch (mode) { 352 case RUN: 353 val3 = readl(GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0); 354 val3 &= ~0x1; 355 writel(val3, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0); 356 break; 357 case WAIT: 358 val1 |= A7_LPM_WAIT << BP_LPCR_A7_BSC_LPM0; 359 val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM; 360 val3 = readl(GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0); 361 val3 &= ~0x1; 362 writel(val3, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0); 363 break; 364 case STOP: 365 val1 |= A7_LPM_STOP << BP_LPCR_A7_BSC_LPM0; 366 val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM; 367 val2 |= BM_SLPCR_EN_DSM; 368 val2 |= BM_SLPCR_SBYOS; 369 val2 |= BM_SLPCR_VSTBY; 370 val2 |= BM_SLPCR_BYPASS_PMIC_READY; 371 val3 = readl(GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0); 372 val3 |= 0x1; 373 writel(val3, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0); 374 break; 375 default: 376 return; 377 } 378 writel(val1, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC); 379 writel(val2, GPC_IPS_BASE_ADDR + GPC_SLPCR); 380} 381 382static __secure void imx_gpcv2_set_plat_power_gate_by_lpm(bool pdn) 383{ 384 u32 val = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_AD); 385 386 val &= ~(BM_LPCR_A7_AD_EN_PLAT_PDN | BM_LPCR_A7_AD_L2PGE); 387 if (pdn) 388 val |= BM_LPCR_A7_AD_EN_PLAT_PDN | BM_LPCR_A7_AD_L2PGE; 389 390 writel(val, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_AD); 391} 392 393static __secure void imx_gpcv2_set_cpu_power_gate_by_lpm(u32 cpu, bool pdn) 394{ 395 u32 val; 396 397 val = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_AD); 398 if (cpu == 0) { 399 if (pdn) 400 val |= BM_LPCR_A7_AD_EN_C0_PDN | 401 BM_LPCR_A7_AD_EN_C0_PUP; 402 else 403 val &= ~(BM_LPCR_A7_AD_EN_C0_PDN | 404 BM_LPCR_A7_AD_EN_C0_PUP); 405 } 406 if (cpu == 1) { 407 if (pdn) 408 val |= BM_LPCR_A7_AD_EN_C1_PDN | 409 BM_LPCR_A7_AD_EN_C1_PUP; 410 else 411 val &= ~(BM_LPCR_A7_AD_EN_C1_PDN | 412 BM_LPCR_A7_AD_EN_C1_PUP); 413 } 414 writel(val, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_AD); 415} 416 417static __secure void imx_gpcv2_set_slot_ack(u32 index, enum imx_gpc_slot m_core, 418 bool mode, bool ack) 419{ 420 u32 val; 421 422 if (index >= MAX_SLOT_NUMBER) 423 return; 424 425 /* set slot */ 426 writel(readl(GPC_IPS_BASE_ADDR + GPC_SLOT0_CFG + index * 4) | 427 ((mode + 1) << (m_core * 2)), 428 GPC_IPS_BASE_ADDR + GPC_SLOT0_CFG + index * 4); 429 430 if (ack) { 431 /* set ack */ 432 val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_ACK_SEL_A7); 433 /* clear dummy ack */ 434 val &= ~(mode ? BM_GPC_PGC_ACK_SEL_A7_PU_DUMMY_ACK : 435 BM_GPC_PGC_ACK_SEL_A7_PD_DUMMY_ACK); 436 val |= 1 << (m_core + (mode ? 16 : 0)); 437 writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_ACK_SEL_A7); 438 } 439} 440 441static __secure void imx_system_counter_resume(void) 442{ 443 u32 val; 444 445 val = readl(SYSCNT_CTRL_IPS_BASE_ADDR); 446 val &= ~BM_SYS_COUNTER_CNTCR_FCR1; 447 val |= BM_SYS_COUNTER_CNTCR_FCR0; 448 writel(val, SYSCNT_CTRL_IPS_BASE_ADDR); 449} 450 451static __secure void imx_system_counter_suspend(void) 452{ 453 u32 val; 454 455 val = readl(SYSCNT_CTRL_IPS_BASE_ADDR); 456 val &= ~BM_SYS_COUNTER_CNTCR_FCR0; 457 val |= BM_SYS_COUNTER_CNTCR_FCR1; 458 writel(val, SYSCNT_CTRL_IPS_BASE_ADDR); 459} 460 461static __secure void gic_resume(void) 462{ 463 u32 itlinesnr, i; 464 u32 gic_dist_addr = GIC400_ARB_BASE_ADDR + GIC_DIST_OFFSET; 465 466 /* enable the GIC distributor */ 467 writel(readl(gic_dist_addr + GICD_CTLR) | 0x03, 468 gic_dist_addr + GICD_CTLR); 469 470 /* TYPER[4:0] contains an encoded number of available interrupts */ 471 itlinesnr = readl(gic_dist_addr + GICD_TYPER) & 0x1f; 472 473 /* set all bits in the GIC group registers to one to allow access 474 * from non-secure state. The first 32 interrupts are private per 475 * CPU and will be set later when enabling the GIC for each core 476 */ 477 for (i = 1; i <= itlinesnr; i++) 478 writel((u32)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); 479} 480 481static inline void imx_pll_suspend(void) 482{ 483 writel(BM_ANATOP_ARM_PLL_OVERRIDE, 484 ANATOP_BASE_ADDR + ANADIG_ARM_PLL + REG_SET); 485 writel(BM_ANATOP_DDR_PLL_OVERRIDE, 486 ANATOP_BASE_ADDR + ANADIG_DDR_PLL + REG_SET); 487 writel(BM_ANATOP_SYS_PLL_OVERRIDE, 488 ANATOP_BASE_ADDR + ANADIG_SYS_PLL + REG_SET); 489 writel(BM_ANATOP_ENET_PLL_OVERRIDE, 490 ANATOP_BASE_ADDR + ANADIG_ENET_PLL + REG_SET); 491 writel(BM_ANATOP_AUDIO_PLL_OVERRIDE, 492 ANATOP_BASE_ADDR + ANADIG_AUDIO_PLL + REG_SET); 493 writel(BM_ANATOP_VIDEO_PLL_OVERRIDE, 494 ANATOP_BASE_ADDR + ANADIG_VIDEO_PLL + REG_SET); 495} 496 497static inline void imx_pll_resume(void) 498{ 499 writel(BM_ANATOP_ARM_PLL_OVERRIDE, 500 ANATOP_BASE_ADDR + ANADIG_ARM_PLL + REG_CLR); 501 writel(BM_ANATOP_DDR_PLL_OVERRIDE, 502 ANATOP_BASE_ADDR + ANADIG_DDR_PLL + REG_CLR); 503 writel(BM_ANATOP_SYS_PLL_OVERRIDE, 504 ANATOP_BASE_ADDR + ANADIG_SYS_PLL + REG_CLR); 505 writel(BM_ANATOP_ENET_PLL_OVERRIDE, 506 ANATOP_BASE_ADDR + ANADIG_ENET_PLL + REG_CLR); 507 writel(BM_ANATOP_AUDIO_PLL_OVERRIDE, 508 ANATOP_BASE_ADDR + ANADIG_AUDIO_PLL + REG_CLR); 509 writel(BM_ANATOP_VIDEO_PLL_OVERRIDE, 510 ANATOP_BASE_ADDR + ANADIG_VIDEO_PLL + REG_CLR); 511} 512 513static inline void imx_udelay(u32 usec) 514{ 515 u32 freq; 516 u64 start, end; 517 518 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); 519 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (start)); 520 do { 521 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (end)); 522 if ((end - start) > usec * (freq / 1000000)) 523 break; 524 } while (1); 525} 526 527static inline void imx_ddrc_enter_self_refresh(void) 528{ 529 writel(0, DDRC_IPS_BASE_ADDR + DDRC_PWRCTL); 530 while (readl(DDRC_IPS_BASE_ADDR + DDRC_PSTAT) & 0x10001) 531 ; 532 533 writel(0x20, DDRC_IPS_BASE_ADDR + DDRC_PWRCTL); 534 while ((readl(DDRC_IPS_BASE_ADDR + DDRC_STAT) & 0x23) != 0x23) 535 ; 536 writel(readl(DDRC_IPS_BASE_ADDR + DDRC_PWRCTL) | 0x8, 537 DDRC_IPS_BASE_ADDR + DDRC_PWRCTL); 538} 539 540static inline void imx_ddrc_exit_self_refresh(void) 541{ 542 writel(0, DDRC_IPS_BASE_ADDR + DDRC_PWRCTL); 543 while ((readl(DDRC_IPS_BASE_ADDR + DDRC_STAT) & 0x3) == 0x3) 544 ; 545 writel(readl(DDRC_IPS_BASE_ADDR + DDRC_PWRCTL) | 0x1, 546 DDRC_IPS_BASE_ADDR + DDRC_PWRCTL); 547} 548 549__secure void imx_system_resume(void) 550{ 551 unsigned int i, val, imr[4], entry; 552 553 entry = psci_get_target_pc(0); 554 imx_ddrc_exit_self_refresh(); 555 imx_system_counter_resume(); 556 imx_gpcv2_set_lpm_mode(RUN); 557 imx_gpcv2_set_cpu_power_gate_by_lpm(0, false); 558 imx_gpcv2_set_plat_power_gate_by_lpm(false); 559 imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C0); 560 imx_gpcv2_set_m_core_pgc(false, GPC_PGC_SCU); 561 562 /* 563 * need to mask all interrupts in GPC before 564 * operating RBC configurations 565 */ 566 for (i = 0; i < 4; i++) { 567 imr[i] = readl(GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 568 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 569 } 570 571 /* configure RBC enable bit */ 572 val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 573 val &= ~BM_SLPCR_RBC_EN; 574 writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR); 575 576 /* configure RBC count */ 577 val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 578 val &= ~BM_SLPCR_REG_BYPASS_COUNT; 579 writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR); 580 581 /* 582 * need to delay at least 2 cycles of CKIL(32K) 583 * due to hardware design requirement, which is 584 * ~61us, here we use 65us for safe 585 */ 586 imx_udelay(65); 587 588 /* restore GPC interrupt mask settings */ 589 for (i = 0; i < 4; i++) 590 writel(imr[i], GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 591 592 /* initialize gic distributor */ 593 gic_resume(); 594 _nonsec_init(); 595 596 /* save cpu0 entry */ 597 psci_save(0, entry, 0); 598 psci_cpu_entry(); 599} 600 601__secure void psci_system_suspend(u32 __always_unused function_id, 602 u32 ep, u32 context_id) 603{ 604 u32 gpc_mask[4]; 605 u32 i, val; 606 607 psci_save(0, ep, context_id); 608 /* overwrite PLL to be controlled by low power mode */ 609 imx_pll_suspend(); 610 imx_system_counter_suspend(); 611 /* set CA7 platform to enter STOP mode */ 612 imx_gpcv2_set_lpm_mode(STOP); 613 /* enable core0/scu power down/up with low power mode */ 614 imx_gpcv2_set_cpu_power_gate_by_lpm(0, true); 615 imx_gpcv2_set_plat_power_gate_by_lpm(true); 616 /* time slot settings for core0 and scu */ 617 imx_gpcv2_set_slot_ack(0, CORE0_A7, false, false); 618 imx_gpcv2_set_slot_ack(1, SCU_A7, false, true); 619 imx_gpcv2_set_slot_ack(5, SCU_A7, true, false); 620 imx_gpcv2_set_slot_ack(6, CORE0_A7, true, true); 621 imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C0); 622 imx_gpcv2_set_m_core_pgc(true, GPC_PGC_SCU); 623 psci_v7_flush_dcache_all(); 624 625 imx_ddrc_enter_self_refresh(); 626 627 /* 628 * e10133: ARM: Boot failure after A7 enters into 629 * low-power idle mode 630 * 631 * Workaround: 632 * If both CPU0/CPU1 are IDLE, the last IDLE CPU should 633 * disable GIC first, then REG_BYPASS_COUNTER is used 634 * to mask wakeup INT, and then execute "wfi" is used to 635 * bring the system into power down processing safely. 636 * The counter must be enabled as close to the "wfi" state 637 * as possible. The following equation can be used to 638 * determine the RBC counter value: 639 * RBC_COUNT * (1/32K RTC frequency) >= 640 * (46 + PDNSCR_SW + PDNSCR_SW2ISO ) ( 1/IPG_CLK frequency ). 641 */ 642 643 /* disable GIC distributor */ 644 writel(0, GIC400_ARB_BASE_ADDR + GIC_DIST_OFFSET); 645 646 for (i = 0; i < 4; i++) { 647 gpc_mask[i] = readl(GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 648 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 649 } 650 651 /* 652 * enable the RBC bypass counter here 653 * to hold off the interrupts. RBC counter 654 * = 8 (240us). With this setting, the latency 655 * from wakeup interrupt to ARM power up 656 * is ~250uS. 657 */ 658 val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 659 val &= ~(0x3f << 24); 660 val |= (0x8 << 24); 661 writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR); 662 663 /* enable the counter. */ 664 val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 665 val |= (1 << 30); 666 writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR); 667 668 /* unmask all the GPC interrupts. */ 669 for (i = 0; i < 4; i++) 670 writel(gpc_mask[i], GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 671 672 /* 673 * now delay for a short while (~3usec) 674 * ARM is at 1GHz at this point 675 * so a short loop should be enough. 676 * this delay is required to ensure that 677 * the RBC counter can start counting in 678 * case an interrupt is already pending 679 * or in case an interrupt arrives just 680 * as ARM is about to assert DSM_request. 681 */ 682 for (i = 0; i < 2000; i++) 683 asm volatile(""); 684 685 /* save resume entry and sp in CPU0 GPR registers */ 686 asm volatile("mov %0, sp" : "=r" (val)); 687 writel((u32)psci_system_resume, SRC_BASE_ADDR + SRC_GPR1_MX7D); 688 writel(val, SRC_BASE_ADDR + SRC_GPR2_MX7D); 689 690 /* sleep */ 691 while (1) 692 wfi(); 693} 694