1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <string.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <arch.h> 11*91f16700Schasinglulu #include <arch_helpers.h> 12*91f16700Schasinglulu #include <common/debug.h> 13*91f16700Schasinglulu #include <lib/bakery_lock.h> 14*91f16700Schasinglulu #include <lib/mmio.h> 15*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_v2.h> 16*91f16700Schasinglulu #include <plat/common/platform.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu #include "iic_dvfs.h" 19*91f16700Schasinglulu #include "micro_delay.h" 20*91f16700Schasinglulu #include "pwrc.h" 21*91f16700Schasinglulu #include "rcar_def.h" 22*91f16700Schasinglulu #include "rcar_private.h" 23*91f16700Schasinglulu #include "cpg_registers.h" 24*91f16700Schasinglulu 25*91f16700Schasinglulu /* 26*91f16700Schasinglulu * Someday there will be a generic power controller api. At the moment each 27*91f16700Schasinglulu * platform has its own pwrc so just exporting functions should be acceptable. 28*91f16700Schasinglulu */ 29*91f16700Schasinglulu RCAR_INSTANTIATE_LOCK 30*91f16700Schasinglulu 31*91f16700Schasinglulu #define WUP_IRQ_SHIFT (0U) 32*91f16700Schasinglulu #define WUP_FIQ_SHIFT (8U) 33*91f16700Schasinglulu #define WUP_CSD_SHIFT (16U) 34*91f16700Schasinglulu #define BIT_SOFTRESET (1U << 15) 35*91f16700Schasinglulu #define BIT_CA53_SCU (1U << 21) 36*91f16700Schasinglulu #define BIT_CA57_SCU (1U << 12) 37*91f16700Schasinglulu #define REQ_RESUME (1U << 1) 38*91f16700Schasinglulu #define REQ_OFF (1U << 0) 39*91f16700Schasinglulu #define STATUS_PWRUP (1U << 4) 40*91f16700Schasinglulu #define STATUS_PWRDOWN (1U << 0) 41*91f16700Schasinglulu #define STATE_CA57_CPU (27U) 42*91f16700Schasinglulu #define STATE_CA53_CPU (22U) 43*91f16700Schasinglulu #define MODE_L2_DOWN (0x00000002U) 44*91f16700Schasinglulu #define CPU_PWR_OFF (0x00000003U) 45*91f16700Schasinglulu #define RCAR_PSTR_MASK (0x00000003U) 46*91f16700Schasinglulu #define ST_ALL_STANDBY (0x00003333U) 47*91f16700Schasinglulu #define SYSCEXTMASK_EXTMSK0 (0x00000001U) 48*91f16700Schasinglulu /* Suspend to ram */ 49*91f16700Schasinglulu #define DBSC4_REG_BASE (0xE6790000U) 50*91f16700Schasinglulu #define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U) 51*91f16700Schasinglulu #define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U) 52*91f16700Schasinglulu #define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U) 53*91f16700Schasinglulu #define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U) 54*91f16700Schasinglulu #define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U) 55*91f16700Schasinglulu #define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U) 56*91f16700Schasinglulu #define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U) 57*91f16700Schasinglulu #define DBSC4_REG_DBPDLK0 (DBSC4_REG_BASE + 0x0620U) 58*91f16700Schasinglulu #define DBSC4_REG_DBPDRGA0 (DBSC4_REG_BASE + 0x0624U) 59*91f16700Schasinglulu #define DBSC4_REG_DBPDRGD0 (DBSC4_REG_BASE + 0x0628U) 60*91f16700Schasinglulu #define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U) 61*91f16700Schasinglulu #define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U) 62*91f16700Schasinglulu #define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U) 63*91f16700Schasinglulu #define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U) 64*91f16700Schasinglulu #define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U) 65*91f16700Schasinglulu #define DBSC4_BIT_DBACEN_ACCEN ((uint32_t)(1U << 0)) 66*91f16700Schasinglulu #define DBSC4_BIT_DBRFEN_ARFEN ((uint32_t)(1U << 0)) 67*91f16700Schasinglulu #define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U) 68*91f16700Schasinglulu #define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U) 69*91f16700Schasinglulu #define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U) 70*91f16700Schasinglulu #define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U) 71*91f16700Schasinglulu #define DBSC4_SET_DBCMD_OPC_PD (0x08000000U) 72*91f16700Schasinglulu #define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U) 73*91f16700Schasinglulu #define DBSC4_SET_DBCMD_CH_ALL (0x00800000U) 74*91f16700Schasinglulu #define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U) 75*91f16700Schasinglulu #define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U) 76*91f16700Schasinglulu #define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U) 77*91f16700Schasinglulu #define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U) 78*91f16700Schasinglulu #define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U) 79*91f16700Schasinglulu #define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U) 80*91f16700Schasinglulu #define DBSC4_SET_DBPDLK0_PHY_ACCESS (0x0000A55AU) 81*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_ACIOCR0 (0x0000001AU) 82*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_ACIOCR0 (0x33C03C11U) 83*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DXCCR (0x00000020U) 84*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DXCCR (0x00181006U) 85*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_PGCR1 (0x00000003U) 86*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_PGCR1 (0x0380C600U) 87*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_ACIOCR1 (0x0000001BU) 88*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_ACIOCR1 (0xAAAAAAAAU) 89*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_ACIOCR3 (0x0000001DU) 90*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_ACIOCR3 (0xAAAAAAAAU) 91*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_ACIOCR5 (0x0000001FU) 92*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_ACIOCR5 (0x000000AAU) 93*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX0GCR2 (0x000000A2U) 94*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX0GCR2 (0xAAAA0000U) 95*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX1GCR2 (0x000000C2U) 96*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX1GCR2 (0xAAAA0000U) 97*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX2GCR2 (0x000000E2U) 98*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX2GCR2 (0xAAAA0000U) 99*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX3GCR2 (0x00000102U) 100*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX3GCR2 (0xAAAA0000U) 101*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_ZQCR (0x00000090U) 102*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 (0x04058904U) 103*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_ZQCR_MD19_1 (0x04058A04U) 104*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX0GCR0 (0x000000A0U) 105*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX0GCR0 (0x7C0002E5U) 106*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX1GCR0 (0x000000C0U) 107*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX1GCR0 (0x7C0002E5U) 108*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX2GCR0 (0x000000E0U) 109*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX2GCR0 (0x7C0002E5U) 110*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX3GCR0 (0x00000100U) 111*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX3GCR0 (0x7C0002E5U) 112*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX0GCR1 (0x000000A1U) 113*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX0GCR1 (0x55550000U) 114*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX1GCR1 (0x000000C1U) 115*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX1GCR1 (0x55550000U) 116*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX2GCR1 (0x000000E1U) 117*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX2GCR1 (0x55550000U) 118*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX3GCR1 (0x00000101U) 119*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX3GCR1 (0x55550000U) 120*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX0GCR3 (0x000000A3U) 121*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX0GCR3 (0x00008484U) 122*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX1GCR3 (0x000000C3U) 123*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX1GCR3 (0x00008484U) 124*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX2GCR3 (0x000000E3U) 125*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX2GCR3 (0x00008484U) 126*91f16700Schasinglulu #define DBSC4_SET_DBPDRGA0_DX3GCR3 (0x00000103U) 127*91f16700Schasinglulu #define DBSC4_SET_DBPDRGD0_DX3GCR3 (0x00008484U) 128*91f16700Schasinglulu #define RST_BASE (0xE6160000U) 129*91f16700Schasinglulu #define RST_MODEMR (RST_BASE + 0x0060U) 130*91f16700Schasinglulu #define RST_MODEMR_BIT0 (0x00000001U) 131*91f16700Schasinglulu 132*91f16700Schasinglulu #define RCAR_CNTCR_OFF (0x00U) 133*91f16700Schasinglulu #define RCAR_CNTCVL_OFF (0x08U) 134*91f16700Schasinglulu #define RCAR_CNTCVU_OFF (0x0CU) 135*91f16700Schasinglulu #define RCAR_CNTFID_OFF (0x20U) 136*91f16700Schasinglulu 137*91f16700Schasinglulu #define RCAR_CNTCR_EN ((uint32_t)1U << 0U) 138*91f16700Schasinglulu #define RCAR_CNTCR_FCREQ(x) ((uint32_t)(x) << 8U) 139*91f16700Schasinglulu 140*91f16700Schasinglulu #if PMIC_ROHM_BD9571 141*91f16700Schasinglulu #define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4)) 142*91f16700Schasinglulu #define PMIC_BKUP_MODE_CNT (0x20U) 143*91f16700Schasinglulu #define PMIC_QLLM_CNT (0x27U) 144*91f16700Schasinglulu #define PMIC_RETRY_MAX (100U) 145*91f16700Schasinglulu #endif /* PMIC_ROHM_BD9571 */ 146*91f16700Schasinglulu #define SCTLR_EL3_M_BIT ((uint32_t)1U << 0) 147*91f16700Schasinglulu #define RCAR_CA53CPU_NUM_MAX (4U) 148*91f16700Schasinglulu #define RCAR_CA57CPU_NUM_MAX (4U) 149*91f16700Schasinglulu #define IS_A53A57(c) ((c) == RCAR_CLUSTER_A53A57) 150*91f16700Schasinglulu #define IS_CA57(c) ((c) == RCAR_CLUSTER_CA57) 151*91f16700Schasinglulu #define IS_CA53(c) ((c) == RCAR_CLUSTER_CA53) 152*91f16700Schasinglulu 153*91f16700Schasinglulu #ifndef __ASSEMBLER__ 154*91f16700Schasinglulu IMPORT_SYM(unsigned long, __system_ram_start__, SYSTEM_RAM_START); 155*91f16700Schasinglulu IMPORT_SYM(unsigned long, __system_ram_end__, SYSTEM_RAM_END); 156*91f16700Schasinglulu IMPORT_SYM(unsigned long, __SRAM_COPY_START__, SRAM_COPY_START); 157*91f16700Schasinglulu #endif 158*91f16700Schasinglulu 159*91f16700Schasinglulu uint32_t rcar_pwrc_status(u_register_t mpidr) 160*91f16700Schasinglulu { 161*91f16700Schasinglulu uint32_t ret = 0; 162*91f16700Schasinglulu uint64_t cm, cpu; 163*91f16700Schasinglulu uint32_t reg; 164*91f16700Schasinglulu uint32_t c; 165*91f16700Schasinglulu 166*91f16700Schasinglulu rcar_lock_get(); 167*91f16700Schasinglulu 168*91f16700Schasinglulu c = rcar_pwrc_get_cluster(); 169*91f16700Schasinglulu cm = mpidr & MPIDR_CLUSTER_MASK; 170*91f16700Schasinglulu 171*91f16700Schasinglulu if (!IS_A53A57(c) && cm != 0) { 172*91f16700Schasinglulu ret = RCAR_INVALID; 173*91f16700Schasinglulu goto done; 174*91f16700Schasinglulu } 175*91f16700Schasinglulu 176*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 177*91f16700Schasinglulu cpu = mpidr & MPIDR_CPU_MASK; 178*91f16700Schasinglulu 179*91f16700Schasinglulu if (IS_CA53(c)) 180*91f16700Schasinglulu if (reg & (1 << (STATE_CA53_CPU + cpu))) 181*91f16700Schasinglulu ret = RCAR_INVALID; 182*91f16700Schasinglulu if (IS_CA57(c)) 183*91f16700Schasinglulu if (reg & (1 << (STATE_CA57_CPU + cpu))) 184*91f16700Schasinglulu ret = RCAR_INVALID; 185*91f16700Schasinglulu done: 186*91f16700Schasinglulu rcar_lock_release(); 187*91f16700Schasinglulu 188*91f16700Schasinglulu return ret; 189*91f16700Schasinglulu } 190*91f16700Schasinglulu 191*91f16700Schasinglulu static void scu_power_up(u_register_t mpidr) 192*91f16700Schasinglulu { 193*91f16700Schasinglulu uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer; 194*91f16700Schasinglulu uint32_t c, sysc_reg_bit; 195*91f16700Schasinglulu uint32_t lsi_product; 196*91f16700Schasinglulu uint32_t lsi_cut; 197*91f16700Schasinglulu 198*91f16700Schasinglulu c = rcar_pwrc_get_mpidr_cluster(mpidr); 199*91f16700Schasinglulu reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR; 200*91f16700Schasinglulu sysc_reg_bit = IS_CA57(c) ? BIT_CA57_SCU : BIT_CA53_SCU; 201*91f16700Schasinglulu reg_pwron = IS_CA57(c) ? RCAR_PWRONCR5 : RCAR_PWRONCR3; 202*91f16700Schasinglulu reg_pwrer = IS_CA57(c) ? RCAR_PWRER5 : RCAR_PWRER3; 203*91f16700Schasinglulu reg_pwrsr = IS_CA57(c) ? RCAR_PWRSR5 : RCAR_PWRSR3; 204*91f16700Schasinglulu 205*91f16700Schasinglulu if ((mmio_read_32(reg_pwrsr) & STATUS_PWRDOWN) == 0) 206*91f16700Schasinglulu return; 207*91f16700Schasinglulu 208*91f16700Schasinglulu if (mmio_read_32(reg_cpumcr) != 0) 209*91f16700Schasinglulu mmio_write_32(reg_cpumcr, 0); 210*91f16700Schasinglulu 211*91f16700Schasinglulu lsi_product = mmio_read_32((uintptr_t)RCAR_PRR); 212*91f16700Schasinglulu lsi_cut = lsi_product & PRR_CUT_MASK; 213*91f16700Schasinglulu lsi_product &= PRR_PRODUCT_MASK; 214*91f16700Schasinglulu 215*91f16700Schasinglulu if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) || 216*91f16700Schasinglulu lsi_product == PRR_PRODUCT_H3 || 217*91f16700Schasinglulu lsi_product == PRR_PRODUCT_M3N || 218*91f16700Schasinglulu lsi_product == PRR_PRODUCT_E3) { 219*91f16700Schasinglulu mmio_setbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0); 220*91f16700Schasinglulu } 221*91f16700Schasinglulu 222*91f16700Schasinglulu mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit); 223*91f16700Schasinglulu mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit); 224*91f16700Schasinglulu 225*91f16700Schasinglulu do { 226*91f16700Schasinglulu while ((mmio_read_32(RCAR_SYSCSR) & REQ_RESUME) == 0) 227*91f16700Schasinglulu ; 228*91f16700Schasinglulu mmio_write_32(reg_pwron, 1); 229*91f16700Schasinglulu } while (mmio_read_32(reg_pwrer) & 1); 230*91f16700Schasinglulu 231*91f16700Schasinglulu while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0) 232*91f16700Schasinglulu ; 233*91f16700Schasinglulu mmio_write_32(RCAR_SYSCISCR, sysc_reg_bit); 234*91f16700Schasinglulu 235*91f16700Schasinglulu if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) || 236*91f16700Schasinglulu lsi_product == PRR_PRODUCT_H3 || 237*91f16700Schasinglulu lsi_product == PRR_PRODUCT_M3N || 238*91f16700Schasinglulu lsi_product == PRR_PRODUCT_E3) { 239*91f16700Schasinglulu mmio_clrbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0); 240*91f16700Schasinglulu } 241*91f16700Schasinglulu 242*91f16700Schasinglulu while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0) 243*91f16700Schasinglulu ; 244*91f16700Schasinglulu } 245*91f16700Schasinglulu 246*91f16700Schasinglulu void rcar_pwrc_cpuon(u_register_t mpidr) 247*91f16700Schasinglulu { 248*91f16700Schasinglulu uint32_t res_data, on_data; 249*91f16700Schasinglulu uintptr_t res_reg, on_reg; 250*91f16700Schasinglulu uint32_t limit, c; 251*91f16700Schasinglulu uint64_t cpu; 252*91f16700Schasinglulu 253*91f16700Schasinglulu rcar_lock_get(); 254*91f16700Schasinglulu 255*91f16700Schasinglulu c = rcar_pwrc_get_mpidr_cluster(mpidr); 256*91f16700Schasinglulu res_reg = IS_CA53(c) ? RCAR_CA53RESCNT : RCAR_CA57RESCNT; 257*91f16700Schasinglulu on_reg = IS_CA53(c) ? RCAR_CA53WUPCR : RCAR_CA57WUPCR; 258*91f16700Schasinglulu limit = IS_CA53(c) ? 0x5A5A0000 : 0xA5A50000; 259*91f16700Schasinglulu 260*91f16700Schasinglulu res_data = mmio_read_32(res_reg) | limit; 261*91f16700Schasinglulu scu_power_up(mpidr); 262*91f16700Schasinglulu cpu = mpidr & MPIDR_CPU_MASK; 263*91f16700Schasinglulu on_data = 1 << cpu; 264*91f16700Schasinglulu mmio_write_32(CPG_CPGWPR, ~on_data); 265*91f16700Schasinglulu mmio_write_32(on_reg, on_data); 266*91f16700Schasinglulu mmio_write_32(res_reg, res_data & (~(1 << (3 - cpu)))); 267*91f16700Schasinglulu 268*91f16700Schasinglulu rcar_lock_release(); 269*91f16700Schasinglulu } 270*91f16700Schasinglulu 271*91f16700Schasinglulu void rcar_pwrc_cpuoff(u_register_t mpidr) 272*91f16700Schasinglulu { 273*91f16700Schasinglulu uint32_t c; 274*91f16700Schasinglulu uintptr_t reg; 275*91f16700Schasinglulu uint64_t cpu; 276*91f16700Schasinglulu 277*91f16700Schasinglulu rcar_lock_get(); 278*91f16700Schasinglulu 279*91f16700Schasinglulu cpu = mpidr & MPIDR_CPU_MASK; 280*91f16700Schasinglulu c = rcar_pwrc_get_mpidr_cluster(mpidr); 281*91f16700Schasinglulu reg = IS_CA53(c) ? RCAR_CA53CPU0CR : RCAR_CA57CPU0CR; 282*91f16700Schasinglulu 283*91f16700Schasinglulu if (read_mpidr_el1() != mpidr) 284*91f16700Schasinglulu panic(); 285*91f16700Schasinglulu 286*91f16700Schasinglulu mmio_write_32(CPG_CPGWPR, ~CPU_PWR_OFF); 287*91f16700Schasinglulu mmio_write_32(reg + cpu * 0x0010, CPU_PWR_OFF); 288*91f16700Schasinglulu 289*91f16700Schasinglulu rcar_lock_release(); 290*91f16700Schasinglulu } 291*91f16700Schasinglulu 292*91f16700Schasinglulu void rcar_pwrc_enable_interrupt_wakeup(u_register_t mpidr) 293*91f16700Schasinglulu { 294*91f16700Schasinglulu uint32_t c, shift_irq, shift_fiq; 295*91f16700Schasinglulu uintptr_t reg; 296*91f16700Schasinglulu uint64_t cpu; 297*91f16700Schasinglulu 298*91f16700Schasinglulu rcar_lock_get(); 299*91f16700Schasinglulu 300*91f16700Schasinglulu cpu = mpidr & MPIDR_CPU_MASK; 301*91f16700Schasinglulu c = rcar_pwrc_get_mpidr_cluster(mpidr); 302*91f16700Schasinglulu reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57; 303*91f16700Schasinglulu 304*91f16700Schasinglulu shift_irq = WUP_IRQ_SHIFT + cpu; 305*91f16700Schasinglulu shift_fiq = WUP_FIQ_SHIFT + cpu; 306*91f16700Schasinglulu 307*91f16700Schasinglulu mmio_clrbits_32(reg, ((uint32_t) 1 << shift_irq) | 308*91f16700Schasinglulu ((uint32_t) 1 << shift_fiq)); 309*91f16700Schasinglulu rcar_lock_release(); 310*91f16700Schasinglulu } 311*91f16700Schasinglulu 312*91f16700Schasinglulu void rcar_pwrc_disable_interrupt_wakeup(u_register_t mpidr) 313*91f16700Schasinglulu { 314*91f16700Schasinglulu uint32_t c, shift_irq, shift_fiq; 315*91f16700Schasinglulu uintptr_t reg; 316*91f16700Schasinglulu uint64_t cpu; 317*91f16700Schasinglulu 318*91f16700Schasinglulu rcar_lock_get(); 319*91f16700Schasinglulu 320*91f16700Schasinglulu cpu = mpidr & MPIDR_CPU_MASK; 321*91f16700Schasinglulu c = rcar_pwrc_get_mpidr_cluster(mpidr); 322*91f16700Schasinglulu reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57; 323*91f16700Schasinglulu 324*91f16700Schasinglulu shift_irq = WUP_IRQ_SHIFT + cpu; 325*91f16700Schasinglulu shift_fiq = WUP_FIQ_SHIFT + cpu; 326*91f16700Schasinglulu 327*91f16700Schasinglulu mmio_setbits_32(reg, ((uint32_t) 1 << shift_irq) | 328*91f16700Schasinglulu ((uint32_t) 1 << shift_fiq)); 329*91f16700Schasinglulu rcar_lock_release(); 330*91f16700Schasinglulu } 331*91f16700Schasinglulu 332*91f16700Schasinglulu void rcar_pwrc_all_disable_interrupt_wakeup(void) 333*91f16700Schasinglulu { 334*91f16700Schasinglulu uint32_t cpu_num; 335*91f16700Schasinglulu u_register_t cl, cpu, mpidr; 336*91f16700Schasinglulu 337*91f16700Schasinglulu const uint32_t cluster[PLATFORM_CLUSTER_COUNT] = { 338*91f16700Schasinglulu RCAR_CLUSTER_CA57, 339*91f16700Schasinglulu RCAR_CLUSTER_CA53 340*91f16700Schasinglulu }; 341*91f16700Schasinglulu 342*91f16700Schasinglulu for (cl = 0; cl < PLATFORM_CLUSTER_COUNT; cl++) { 343*91f16700Schasinglulu cpu_num = rcar_pwrc_get_cpu_num(cluster[cl]); 344*91f16700Schasinglulu for (cpu = 0; cpu < cpu_num; cpu++) { 345*91f16700Schasinglulu mpidr = ((cl << MPIDR_AFFINITY_BITS) | cpu); 346*91f16700Schasinglulu if (mpidr == rcar_boot_mpidr) { 347*91f16700Schasinglulu rcar_pwrc_enable_interrupt_wakeup(mpidr); 348*91f16700Schasinglulu } else { 349*91f16700Schasinglulu rcar_pwrc_disable_interrupt_wakeup(mpidr); 350*91f16700Schasinglulu } 351*91f16700Schasinglulu } 352*91f16700Schasinglulu } 353*91f16700Schasinglulu } 354*91f16700Schasinglulu 355*91f16700Schasinglulu void rcar_pwrc_clusteroff(u_register_t mpidr) 356*91f16700Schasinglulu { 357*91f16700Schasinglulu uint32_t c, product, cut, reg; 358*91f16700Schasinglulu uintptr_t dst; 359*91f16700Schasinglulu 360*91f16700Schasinglulu rcar_lock_get(); 361*91f16700Schasinglulu 362*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 363*91f16700Schasinglulu product = reg & PRR_PRODUCT_MASK; 364*91f16700Schasinglulu cut = reg & PRR_CUT_MASK; 365*91f16700Schasinglulu 366*91f16700Schasinglulu c = rcar_pwrc_get_mpidr_cluster(mpidr); 367*91f16700Schasinglulu dst = IS_CA53(c) ? RCAR_CA53CPUCMCR : RCAR_CA57CPUCMCR; 368*91f16700Schasinglulu 369*91f16700Schasinglulu if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { 370*91f16700Schasinglulu goto done; 371*91f16700Schasinglulu } 372*91f16700Schasinglulu 373*91f16700Schasinglulu if (product == PRR_PRODUCT_H3 && cut <= PRR_PRODUCT_20) { 374*91f16700Schasinglulu goto done; 375*91f16700Schasinglulu } 376*91f16700Schasinglulu 377*91f16700Schasinglulu /* all of the CPUs in the cluster is in the CoreStandby mode */ 378*91f16700Schasinglulu mmio_write_32(dst, MODE_L2_DOWN); 379*91f16700Schasinglulu done: 380*91f16700Schasinglulu rcar_lock_release(); 381*91f16700Schasinglulu } 382*91f16700Schasinglulu 383*91f16700Schasinglulu static uint64_t rcar_pwrc_saved_cntpct_el0; 384*91f16700Schasinglulu static uint32_t rcar_pwrc_saved_cntfid; 385*91f16700Schasinglulu 386*91f16700Schasinglulu #if RCAR_SYSTEM_SUSPEND 387*91f16700Schasinglulu static void rcar_pwrc_save_timer_state(void) 388*91f16700Schasinglulu { 389*91f16700Schasinglulu rcar_pwrc_saved_cntpct_el0 = read_cntpct_el0(); 390*91f16700Schasinglulu 391*91f16700Schasinglulu rcar_pwrc_saved_cntfid = 392*91f16700Schasinglulu mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF)); 393*91f16700Schasinglulu } 394*91f16700Schasinglulu #endif /* RCAR_SYSTEM_SUSPEND */ 395*91f16700Schasinglulu 396*91f16700Schasinglulu void rcar_pwrc_restore_timer_state(void) 397*91f16700Schasinglulu { 398*91f16700Schasinglulu /* Stop timer before restoring counter value */ 399*91f16700Schasinglulu mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), 0U); 400*91f16700Schasinglulu 401*91f16700Schasinglulu mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVL_OFF), 402*91f16700Schasinglulu (uint32_t)(rcar_pwrc_saved_cntpct_el0 & 0xFFFFFFFFU)); 403*91f16700Schasinglulu mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVU_OFF), 404*91f16700Schasinglulu (uint32_t)(rcar_pwrc_saved_cntpct_el0 >> 32U)); 405*91f16700Schasinglulu 406*91f16700Schasinglulu mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF), 407*91f16700Schasinglulu rcar_pwrc_saved_cntfid); 408*91f16700Schasinglulu 409*91f16700Schasinglulu /* Start generic timer back */ 410*91f16700Schasinglulu write_cntfrq_el0((u_register_t)plat_get_syscnt_freq2()); 411*91f16700Schasinglulu 412*91f16700Schasinglulu mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), 413*91f16700Schasinglulu (RCAR_CNTCR_FCREQ(0U) | RCAR_CNTCR_EN)); 414*91f16700Schasinglulu } 415*91f16700Schasinglulu 416*91f16700Schasinglulu #if !PMIC_ROHM_BD9571 417*91f16700Schasinglulu void rcar_pwrc_system_reset(void) 418*91f16700Schasinglulu { 419*91f16700Schasinglulu mmio_write_32(RCAR_SRESCR, 0x5AA50000U | BIT_SOFTRESET); 420*91f16700Schasinglulu } 421*91f16700Schasinglulu #endif /* PMIC_ROHM_BD9571 */ 422*91f16700Schasinglulu 423*91f16700Schasinglulu #define RST_CA53_CPU0_BARH (0xE6160080U) 424*91f16700Schasinglulu #define RST_CA53_CPU0_BARL (0xE6160084U) 425*91f16700Schasinglulu #define RST_CA57_CPU0_BARH (0xE61600C0U) 426*91f16700Schasinglulu #define RST_CA57_CPU0_BARL (0xE61600C4U) 427*91f16700Schasinglulu 428*91f16700Schasinglulu void rcar_pwrc_setup(void) 429*91f16700Schasinglulu { 430*91f16700Schasinglulu uintptr_t rst_barh; 431*91f16700Schasinglulu uintptr_t rst_barl; 432*91f16700Schasinglulu uint32_t i, j; 433*91f16700Schasinglulu uint64_t reset = (uint64_t) (&plat_secondary_reset) & 0xFFFFFFFF; 434*91f16700Schasinglulu 435*91f16700Schasinglulu const uint32_t cluster[PLATFORM_CLUSTER_COUNT] = { 436*91f16700Schasinglulu RCAR_CLUSTER_CA53, 437*91f16700Schasinglulu RCAR_CLUSTER_CA57 438*91f16700Schasinglulu }; 439*91f16700Schasinglulu const uintptr_t reg_barh[PLATFORM_CLUSTER_COUNT] = { 440*91f16700Schasinglulu RST_CA53_CPU0_BARH, 441*91f16700Schasinglulu RST_CA57_CPU0_BARH 442*91f16700Schasinglulu }; 443*91f16700Schasinglulu const uintptr_t reg_barl[PLATFORM_CLUSTER_COUNT] = { 444*91f16700Schasinglulu RST_CA53_CPU0_BARL, 445*91f16700Schasinglulu RST_CA57_CPU0_BARL 446*91f16700Schasinglulu }; 447*91f16700Schasinglulu 448*91f16700Schasinglulu for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) { 449*91f16700Schasinglulu rst_barh = reg_barh[i]; 450*91f16700Schasinglulu rst_barl = reg_barl[i]; 451*91f16700Schasinglulu for (j = 0; j < rcar_pwrc_get_cpu_num(cluster[i]); j++) { 452*91f16700Schasinglulu mmio_write_32(rst_barh, 0); 453*91f16700Schasinglulu mmio_write_32(rst_barl, (uint32_t) reset); 454*91f16700Schasinglulu rst_barh += 0x10; 455*91f16700Schasinglulu rst_barl += 0x10; 456*91f16700Schasinglulu } 457*91f16700Schasinglulu } 458*91f16700Schasinglulu 459*91f16700Schasinglulu rcar_lock_init(); 460*91f16700Schasinglulu } 461*91f16700Schasinglulu 462*91f16700Schasinglulu #if RCAR_SYSTEM_SUSPEND 463*91f16700Schasinglulu #define DBCAM_FLUSH(__bit) \ 464*91f16700Schasinglulu do { \ 465*91f16700Schasinglulu ; \ 466*91f16700Schasinglulu } while (!(mmio_read_32(DBSC4_REG_DBCAM##__bit##STAT0) & DBSC4_BIT_DBCAMxSTAT0)) 467*91f16700Schasinglulu 468*91f16700Schasinglulu 469*91f16700Schasinglulu static void __attribute__ ((section(".system_ram"))) 470*91f16700Schasinglulu rcar_pwrc_set_self_refresh(void) 471*91f16700Schasinglulu { 472*91f16700Schasinglulu uint32_t reg = mmio_read_32(RCAR_PRR); 473*91f16700Schasinglulu uint32_t cut, product; 474*91f16700Schasinglulu 475*91f16700Schasinglulu product = reg & PRR_PRODUCT_MASK; 476*91f16700Schasinglulu cut = reg & PRR_CUT_MASK; 477*91f16700Schasinglulu 478*91f16700Schasinglulu if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { 479*91f16700Schasinglulu goto self_refresh; 480*91f16700Schasinglulu } 481*91f16700Schasinglulu 482*91f16700Schasinglulu if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) { 483*91f16700Schasinglulu goto self_refresh; 484*91f16700Schasinglulu } 485*91f16700Schasinglulu 486*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); 487*91f16700Schasinglulu 488*91f16700Schasinglulu self_refresh: 489*91f16700Schasinglulu 490*91f16700Schasinglulu /* DFI_PHYMSTR_ACK setting */ 491*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBDFIPMSTRCNF, 492*91f16700Schasinglulu mmio_read_32(DBSC4_REG_DBDFIPMSTRCNF) & 493*91f16700Schasinglulu (~DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN)); 494*91f16700Schasinglulu 495*91f16700Schasinglulu /* Set the Self-Refresh mode */ 496*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBACEN, 0); 497*91f16700Schasinglulu 498*91f16700Schasinglulu if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) 499*91f16700Schasinglulu rcar_micro_delay(100); 500*91f16700Schasinglulu else if (product == PRR_PRODUCT_H3) { 501*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); 502*91f16700Schasinglulu DBCAM_FLUSH(0); 503*91f16700Schasinglulu DBCAM_FLUSH(1); 504*91f16700Schasinglulu DBCAM_FLUSH(2); 505*91f16700Schasinglulu DBCAM_FLUSH(3); 506*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); 507*91f16700Schasinglulu } else if (product == PRR_PRODUCT_M3) { 508*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); 509*91f16700Schasinglulu DBCAM_FLUSH(0); 510*91f16700Schasinglulu DBCAM_FLUSH(1); 511*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); 512*91f16700Schasinglulu } else { 513*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); 514*91f16700Schasinglulu DBCAM_FLUSH(0); 515*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); 516*91f16700Schasinglulu } 517*91f16700Schasinglulu 518*91f16700Schasinglulu /* Set the SDRAM calibration configuration register */ 519*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCALCNF, 0); 520*91f16700Schasinglulu 521*91f16700Schasinglulu reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL | 522*91f16700Schasinglulu DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL; 523*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCMD, reg); 524*91f16700Schasinglulu while (mmio_read_32(DBSC4_REG_DBWAIT)) 525*91f16700Schasinglulu ; 526*91f16700Schasinglulu 527*91f16700Schasinglulu /* Self-Refresh entry command */ 528*91f16700Schasinglulu reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL | 529*91f16700Schasinglulu DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; 530*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCMD, reg); 531*91f16700Schasinglulu while (mmio_read_32(DBSC4_REG_DBWAIT)) 532*91f16700Schasinglulu ; 533*91f16700Schasinglulu 534*91f16700Schasinglulu /* Mode Register Write command. (ODT disabled) */ 535*91f16700Schasinglulu reg = DBSC4_SET_DBCMD_OPC_MRW | DBSC4_SET_DBCMD_CH_ALL | 536*91f16700Schasinglulu DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_MRW_ODTC; 537*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCMD, reg); 538*91f16700Schasinglulu while (mmio_read_32(DBSC4_REG_DBWAIT)) 539*91f16700Schasinglulu ; 540*91f16700Schasinglulu 541*91f16700Schasinglulu /* Power Down entry command */ 542*91f16700Schasinglulu reg = DBSC4_SET_DBCMD_OPC_PD | DBSC4_SET_DBCMD_CH_ALL | 543*91f16700Schasinglulu DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; 544*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCMD, reg); 545*91f16700Schasinglulu while (mmio_read_32(DBSC4_REG_DBWAIT)) 546*91f16700Schasinglulu ; 547*91f16700Schasinglulu 548*91f16700Schasinglulu /* Set the auto-refresh enable register */ 549*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBRFEN, 0U); 550*91f16700Schasinglulu rcar_micro_delay(1U); 551*91f16700Schasinglulu 552*91f16700Schasinglulu if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) 553*91f16700Schasinglulu return; 554*91f16700Schasinglulu 555*91f16700Schasinglulu if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) 556*91f16700Schasinglulu return; 557*91f16700Schasinglulu 558*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE); 559*91f16700Schasinglulu } 560*91f16700Schasinglulu 561*91f16700Schasinglulu static void __attribute__ ((section(".system_ram"))) 562*91f16700Schasinglulu rcar_pwrc_set_self_refresh_e3(void) 563*91f16700Schasinglulu { 564*91f16700Schasinglulu uint32_t ddr_md; 565*91f16700Schasinglulu uint32_t reg; 566*91f16700Schasinglulu 567*91f16700Schasinglulu ddr_md = (mmio_read_32(RST_MODEMR) >> 19) & RST_MODEMR_BIT0; 568*91f16700Schasinglulu 569*91f16700Schasinglulu /* Write enable */ 570*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); 571*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBACEN, 0); 572*91f16700Schasinglulu DBCAM_FLUSH(0); 573*91f16700Schasinglulu 574*91f16700Schasinglulu reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL | 575*91f16700Schasinglulu DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL; 576*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCMD, reg); 577*91f16700Schasinglulu while (mmio_read_32(DBSC4_REG_DBWAIT)) 578*91f16700Schasinglulu ; 579*91f16700Schasinglulu 580*91f16700Schasinglulu reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL | 581*91f16700Schasinglulu DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; 582*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBCMD, reg); 583*91f16700Schasinglulu while (mmio_read_32(DBSC4_REG_DBWAIT)) 584*91f16700Schasinglulu ; 585*91f16700Schasinglulu 586*91f16700Schasinglulu /* 587*91f16700Schasinglulu * Set the auto-refresh enable register 588*91f16700Schasinglulu * Set the ARFEN bit to 0 in the DBRFEN 589*91f16700Schasinglulu */ 590*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBRFEN, 0); 591*91f16700Schasinglulu 592*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDLK0, DBSC4_SET_DBPDLK0_PHY_ACCESS); 593*91f16700Schasinglulu 594*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR0); 595*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR0); 596*91f16700Schasinglulu 597*91f16700Schasinglulu /* DDR_DXCCR */ 598*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DXCCR); 599*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DXCCR); 600*91f16700Schasinglulu 601*91f16700Schasinglulu /* DDR_PGCR1 */ 602*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_PGCR1); 603*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_PGCR1); 604*91f16700Schasinglulu 605*91f16700Schasinglulu /* DDR_ACIOCR1 */ 606*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR1); 607*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR1); 608*91f16700Schasinglulu 609*91f16700Schasinglulu /* DDR_ACIOCR3 */ 610*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR3); 611*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR3); 612*91f16700Schasinglulu 613*91f16700Schasinglulu /* DDR_ACIOCR5 */ 614*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR5); 615*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR5); 616*91f16700Schasinglulu 617*91f16700Schasinglulu /* DDR_DX0GCR2 */ 618*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR2); 619*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR2); 620*91f16700Schasinglulu 621*91f16700Schasinglulu /* DDR_DX1GCR2 */ 622*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR2); 623*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR2); 624*91f16700Schasinglulu 625*91f16700Schasinglulu /* DDR_DX2GCR2 */ 626*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR2); 627*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR2); 628*91f16700Schasinglulu 629*91f16700Schasinglulu /* DDR_DX3GCR2 */ 630*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR2); 631*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR2); 632*91f16700Schasinglulu 633*91f16700Schasinglulu /* DDR_ZQCR */ 634*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ZQCR); 635*91f16700Schasinglulu 636*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, ddr_md == 0 ? 637*91f16700Schasinglulu DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 : 638*91f16700Schasinglulu DBSC4_SET_DBPDRGD0_ZQCR_MD19_1); 639*91f16700Schasinglulu 640*91f16700Schasinglulu /* DDR_DX0GCR0 */ 641*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR0); 642*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR0); 643*91f16700Schasinglulu 644*91f16700Schasinglulu /* DDR_DX1GCR0 */ 645*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR0); 646*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR0); 647*91f16700Schasinglulu 648*91f16700Schasinglulu /* DDR_DX2GCR0 */ 649*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR0); 650*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR0); 651*91f16700Schasinglulu 652*91f16700Schasinglulu /* DDR_DX3GCR0 */ 653*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR0); 654*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR0); 655*91f16700Schasinglulu 656*91f16700Schasinglulu /* DDR_DX0GCR1 */ 657*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR1); 658*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR1); 659*91f16700Schasinglulu 660*91f16700Schasinglulu /* DDR_DX1GCR1 */ 661*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR1); 662*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR1); 663*91f16700Schasinglulu 664*91f16700Schasinglulu /* DDR_DX2GCR1 */ 665*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR1); 666*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR1); 667*91f16700Schasinglulu 668*91f16700Schasinglulu /* DDR_DX3GCR1 */ 669*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR1); 670*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR1); 671*91f16700Schasinglulu 672*91f16700Schasinglulu /* DDR_DX0GCR3 */ 673*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR3); 674*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR3); 675*91f16700Schasinglulu 676*91f16700Schasinglulu /* DDR_DX1GCR3 */ 677*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR3); 678*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR3); 679*91f16700Schasinglulu 680*91f16700Schasinglulu /* DDR_DX2GCR3 */ 681*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR3); 682*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR3); 683*91f16700Schasinglulu 684*91f16700Schasinglulu /* DDR_DX3GCR3 */ 685*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR3); 686*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR3); 687*91f16700Schasinglulu 688*91f16700Schasinglulu /* Write disable */ 689*91f16700Schasinglulu mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE); 690*91f16700Schasinglulu } 691*91f16700Schasinglulu 692*91f16700Schasinglulu void __attribute__ ((section(".system_ram"))) __attribute__ ((noinline)) 693*91f16700Schasinglulu rcar_pwrc_go_suspend_to_ram(void) 694*91f16700Schasinglulu { 695*91f16700Schasinglulu #if PMIC_ROHM_BD9571 696*91f16700Schasinglulu int32_t rc = -1, qllm = -1; 697*91f16700Schasinglulu uint8_t mode; 698*91f16700Schasinglulu uint32_t i; 699*91f16700Schasinglulu #endif 700*91f16700Schasinglulu uint32_t reg, product; 701*91f16700Schasinglulu 702*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 703*91f16700Schasinglulu product = reg & PRR_PRODUCT_MASK; 704*91f16700Schasinglulu 705*91f16700Schasinglulu if (product != PRR_PRODUCT_E3) 706*91f16700Schasinglulu rcar_pwrc_set_self_refresh(); 707*91f16700Schasinglulu else 708*91f16700Schasinglulu rcar_pwrc_set_self_refresh_e3(); 709*91f16700Schasinglulu 710*91f16700Schasinglulu #if PMIC_ROHM_BD9571 711*91f16700Schasinglulu /* Set QLLM Cnt Disable */ 712*91f16700Schasinglulu for (i = 0; (i < PMIC_RETRY_MAX) && (qllm != 0); i++) 713*91f16700Schasinglulu qllm = rcar_iic_dvfs_send(PMIC, PMIC_QLLM_CNT, 0); 714*91f16700Schasinglulu 715*91f16700Schasinglulu /* Set trigger of power down to PMIV */ 716*91f16700Schasinglulu for (i = 0; (i < PMIC_RETRY_MAX) && (rc != 0) && (qllm == 0); i++) { 717*91f16700Schasinglulu rc = rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode); 718*91f16700Schasinglulu if (rc == 0) { 719*91f16700Schasinglulu mode |= BIT_BKUP_CTRL_OUT; 720*91f16700Schasinglulu rc = rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode); 721*91f16700Schasinglulu } 722*91f16700Schasinglulu } 723*91f16700Schasinglulu #endif 724*91f16700Schasinglulu wfi(); 725*91f16700Schasinglulu 726*91f16700Schasinglulu while (1) 727*91f16700Schasinglulu ; 728*91f16700Schasinglulu } 729*91f16700Schasinglulu 730*91f16700Schasinglulu void rcar_pwrc_set_suspend_to_ram(void) 731*91f16700Schasinglulu { 732*91f16700Schasinglulu uintptr_t jump = (uintptr_t) &rcar_pwrc_go_suspend_to_ram; 733*91f16700Schasinglulu uintptr_t stack = (uintptr_t) (DEVICE_SRAM_STACK_BASE + 734*91f16700Schasinglulu DEVICE_SRAM_STACK_SIZE); 735*91f16700Schasinglulu uint32_t sctlr; 736*91f16700Schasinglulu 737*91f16700Schasinglulu rcar_pwrc_save_timer_state(); 738*91f16700Schasinglulu 739*91f16700Schasinglulu /* disable MMU */ 740*91f16700Schasinglulu sctlr = (uint32_t) read_sctlr_el3(); 741*91f16700Schasinglulu sctlr &= (uint32_t) ~SCTLR_EL3_M_BIT; 742*91f16700Schasinglulu write_sctlr_el3((uint64_t) sctlr); 743*91f16700Schasinglulu 744*91f16700Schasinglulu rcar_pwrc_switch_stack(jump, stack, NULL); 745*91f16700Schasinglulu } 746*91f16700Schasinglulu 747*91f16700Schasinglulu void rcar_pwrc_init_suspend_to_ram(void) 748*91f16700Schasinglulu { 749*91f16700Schasinglulu #if PMIC_ROHM_BD9571 750*91f16700Schasinglulu uint8_t mode; 751*91f16700Schasinglulu 752*91f16700Schasinglulu if (rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode)) 753*91f16700Schasinglulu panic(); 754*91f16700Schasinglulu 755*91f16700Schasinglulu mode &= (uint8_t) (~BIT_BKUP_CTRL_OUT); 756*91f16700Schasinglulu if (rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode)) 757*91f16700Schasinglulu panic(); 758*91f16700Schasinglulu #endif 759*91f16700Schasinglulu } 760*91f16700Schasinglulu 761*91f16700Schasinglulu void rcar_pwrc_suspend_to_ram(void) 762*91f16700Schasinglulu { 763*91f16700Schasinglulu #if RCAR_SYSTEM_RESET_KEEPON_DDR 764*91f16700Schasinglulu int32_t error; 765*91f16700Schasinglulu 766*91f16700Schasinglulu error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, 0); 767*91f16700Schasinglulu if (error) { 768*91f16700Schasinglulu ERROR("Failed send KEEP10 init ret=%d\n", error); 769*91f16700Schasinglulu return; 770*91f16700Schasinglulu } 771*91f16700Schasinglulu #endif 772*91f16700Schasinglulu rcar_pwrc_set_suspend_to_ram(); 773*91f16700Schasinglulu } 774*91f16700Schasinglulu #endif 775*91f16700Schasinglulu 776*91f16700Schasinglulu void rcar_pwrc_code_copy_to_system_ram(void) 777*91f16700Schasinglulu { 778*91f16700Schasinglulu int ret __attribute__ ((unused)); /* in assert */ 779*91f16700Schasinglulu uint32_t attr; 780*91f16700Schasinglulu struct device_sram_t { 781*91f16700Schasinglulu uintptr_t base; 782*91f16700Schasinglulu size_t len; 783*91f16700Schasinglulu } sram = { 784*91f16700Schasinglulu .base = (uintptr_t) DEVICE_SRAM_BASE, 785*91f16700Schasinglulu .len = DEVICE_SRAM_SIZE, 786*91f16700Schasinglulu }; 787*91f16700Schasinglulu struct ddr_code_t { 788*91f16700Schasinglulu void *base; 789*91f16700Schasinglulu size_t len; 790*91f16700Schasinglulu } code = { 791*91f16700Schasinglulu .base = (void *) SRAM_COPY_START, 792*91f16700Schasinglulu .len = SYSTEM_RAM_END - SYSTEM_RAM_START, 793*91f16700Schasinglulu }; 794*91f16700Schasinglulu 795*91f16700Schasinglulu attr = MT_MEMORY | MT_RW | MT_SECURE | MT_EXECUTE_NEVER; 796*91f16700Schasinglulu ret = xlat_change_mem_attributes(sram.base, sram.len, attr); 797*91f16700Schasinglulu assert(ret == 0); 798*91f16700Schasinglulu 799*91f16700Schasinglulu memcpy((void *)sram.base, code.base, code.len); 800*91f16700Schasinglulu flush_dcache_range((uint64_t) sram.base, code.len); 801*91f16700Schasinglulu 802*91f16700Schasinglulu attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE; 803*91f16700Schasinglulu ret = xlat_change_mem_attributes(sram.base, sram.len, attr); 804*91f16700Schasinglulu assert(ret == 0); 805*91f16700Schasinglulu 806*91f16700Schasinglulu /* Invalidate instruction cache */ 807*91f16700Schasinglulu plat_invalidate_icache(); 808*91f16700Schasinglulu dsb(); 809*91f16700Schasinglulu isb(); 810*91f16700Schasinglulu } 811*91f16700Schasinglulu 812*91f16700Schasinglulu uint32_t rcar_pwrc_get_cluster(void) 813*91f16700Schasinglulu { 814*91f16700Schasinglulu uint32_t reg; 815*91f16700Schasinglulu 816*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 817*91f16700Schasinglulu 818*91f16700Schasinglulu if (reg & (1U << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX))) 819*91f16700Schasinglulu return RCAR_CLUSTER_CA57; 820*91f16700Schasinglulu 821*91f16700Schasinglulu if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX))) 822*91f16700Schasinglulu return RCAR_CLUSTER_CA53; 823*91f16700Schasinglulu 824*91f16700Schasinglulu return RCAR_CLUSTER_A53A57; 825*91f16700Schasinglulu } 826*91f16700Schasinglulu 827*91f16700Schasinglulu uint32_t rcar_pwrc_get_mpidr_cluster(u_register_t mpidr) 828*91f16700Schasinglulu { 829*91f16700Schasinglulu uint32_t c = rcar_pwrc_get_cluster(); 830*91f16700Schasinglulu 831*91f16700Schasinglulu if (IS_A53A57(c)) { 832*91f16700Schasinglulu if (mpidr & MPIDR_CLUSTER_MASK) 833*91f16700Schasinglulu return RCAR_CLUSTER_CA53; 834*91f16700Schasinglulu 835*91f16700Schasinglulu return RCAR_CLUSTER_CA57; 836*91f16700Schasinglulu } 837*91f16700Schasinglulu 838*91f16700Schasinglulu return c; 839*91f16700Schasinglulu } 840*91f16700Schasinglulu 841*91f16700Schasinglulu #if RCAR_LSI == RCAR_D3 842*91f16700Schasinglulu uint32_t rcar_pwrc_get_cpu_num(uint32_t c) 843*91f16700Schasinglulu { 844*91f16700Schasinglulu return 1; 845*91f16700Schasinglulu } 846*91f16700Schasinglulu #else 847*91f16700Schasinglulu uint32_t rcar_pwrc_get_cpu_num(uint32_t c) 848*91f16700Schasinglulu { 849*91f16700Schasinglulu uint32_t reg = mmio_read_32(RCAR_PRR); 850*91f16700Schasinglulu uint32_t count = 0, i; 851*91f16700Schasinglulu 852*91f16700Schasinglulu if (IS_A53A57(c) || IS_CA53(c)) { 853*91f16700Schasinglulu if (reg & (1 << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX))) 854*91f16700Schasinglulu goto count_ca57; 855*91f16700Schasinglulu 856*91f16700Schasinglulu for (i = 0; i < RCAR_CA53CPU_NUM_MAX; i++) { 857*91f16700Schasinglulu if (reg & (1 << (STATE_CA53_CPU + i))) 858*91f16700Schasinglulu continue; 859*91f16700Schasinglulu count++; 860*91f16700Schasinglulu } 861*91f16700Schasinglulu } 862*91f16700Schasinglulu 863*91f16700Schasinglulu count_ca57: 864*91f16700Schasinglulu if (IS_A53A57(c) || IS_CA57(c)) { 865*91f16700Schasinglulu if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX))) 866*91f16700Schasinglulu goto done; 867*91f16700Schasinglulu 868*91f16700Schasinglulu for (i = 0; i < RCAR_CA57CPU_NUM_MAX; i++) { 869*91f16700Schasinglulu if (reg & (1 << (STATE_CA57_CPU + i))) 870*91f16700Schasinglulu continue; 871*91f16700Schasinglulu count++; 872*91f16700Schasinglulu } 873*91f16700Schasinglulu } 874*91f16700Schasinglulu 875*91f16700Schasinglulu done: 876*91f16700Schasinglulu return count; 877*91f16700Schasinglulu } 878*91f16700Schasinglulu #endif 879*91f16700Schasinglulu 880*91f16700Schasinglulu int32_t rcar_pwrc_cpu_on_check(u_register_t mpidr) 881*91f16700Schasinglulu { 882*91f16700Schasinglulu uint64_t i; 883*91f16700Schasinglulu uint64_t j; 884*91f16700Schasinglulu uint64_t cpu_count; 885*91f16700Schasinglulu uintptr_t reg_PSTR; 886*91f16700Schasinglulu uint32_t status; 887*91f16700Schasinglulu uint64_t my_cpu; 888*91f16700Schasinglulu int32_t rtn; 889*91f16700Schasinglulu uint32_t my_cluster_type; 890*91f16700Schasinglulu const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = { 891*91f16700Schasinglulu RCAR_CLUSTER_CA53, 892*91f16700Schasinglulu RCAR_CLUSTER_CA57 893*91f16700Schasinglulu }; 894*91f16700Schasinglulu const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = { 895*91f16700Schasinglulu RCAR_CA53PSTR, 896*91f16700Schasinglulu RCAR_CA57PSTR 897*91f16700Schasinglulu }; 898*91f16700Schasinglulu 899*91f16700Schasinglulu my_cluster_type = rcar_pwrc_get_cluster(); 900*91f16700Schasinglulu 901*91f16700Schasinglulu rtn = 0; 902*91f16700Schasinglulu my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK)); 903*91f16700Schasinglulu for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) { 904*91f16700Schasinglulu cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]); 905*91f16700Schasinglulu reg_PSTR = registerPSTR[i]; 906*91f16700Schasinglulu for (j = 0U; j < cpu_count; j++) { 907*91f16700Schasinglulu if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) { 908*91f16700Schasinglulu status = mmio_read_32(reg_PSTR) >> (j * 4U); 909*91f16700Schasinglulu if ((status & 0x00000003U) == 0U) { 910*91f16700Schasinglulu rtn--; 911*91f16700Schasinglulu } 912*91f16700Schasinglulu } 913*91f16700Schasinglulu } 914*91f16700Schasinglulu } 915*91f16700Schasinglulu 916*91f16700Schasinglulu return rtn; 917*91f16700Schasinglulu } 918