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