1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021-2022, Stephan Gerhold <stephan@gerhold.net> 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <arch_helpers.h> 8*91f16700Schasinglulu #include <common/debug.h> 9*91f16700Schasinglulu #include <drivers/delay_timer.h> 10*91f16700Schasinglulu #include <lib/mmio.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include "msm8916_pm.h" 13*91f16700Schasinglulu 14*91f16700Schasinglulu #define CPU_PWR_CTL 0x4 15*91f16700Schasinglulu #define APC_PWR_GATE_CTL 0x14 16*91f16700Schasinglulu 17*91f16700Schasinglulu #define CPU_PWR_CTL_CLAMP BIT_32(0) 18*91f16700Schasinglulu #define CPU_PWR_CTL_CORE_MEM_CLAMP BIT_32(1) 19*91f16700Schasinglulu #define CPU_PWR_CTL_L1_RST_DIS BIT_32(2) 20*91f16700Schasinglulu #define CPU_PWR_CTL_CORE_MEM_HS BIT_32(3) 21*91f16700Schasinglulu #define CPU_PWR_CTL_CORE_RST BIT_32(4) 22*91f16700Schasinglulu #define CPU_PWR_CTL_COREPOR_RST BIT_32(5) 23*91f16700Schasinglulu #define CPU_PWR_CTL_GATE_CLK BIT_32(6) 24*91f16700Schasinglulu #define CPU_PWR_CTL_CORE_PWRD_UP BIT_32(7) 25*91f16700Schasinglulu 26*91f16700Schasinglulu #define APC_PWR_GATE_CTL_GHDS_EN BIT_32(0) 27*91f16700Schasinglulu #define APC_PWR_GATE_CTL_GHDS_CNT(cnt) ((cnt) << 24) 28*91f16700Schasinglulu 29*91f16700Schasinglulu #define PWR_CTL_OVERRIDE 0xc 30*91f16700Schasinglulu #define L2_PWR_CTL 0x14 31*91f16700Schasinglulu #define L2_PWR_STATUS 0x18 32*91f16700Schasinglulu #define CORE_CBCR 0x58 33*91f16700Schasinglulu 34*91f16700Schasinglulu #define PWR_CTL_OVERRIDE_PRESETDBG BIT_32(22) 35*91f16700Schasinglulu 36*91f16700Schasinglulu #define L2_PWR_CTL_L2_ARRAY_HS BIT_32(0) 37*91f16700Schasinglulu #define L2_PWR_CTL_SCU_ARRAY_HS BIT_32(1) 38*91f16700Schasinglulu #define L2_PWR_CTL_L2_RST_DIS BIT_32(2) 39*91f16700Schasinglulu #define L2_PWR_CTL_L2_HS_CLAMP BIT_32(8) 40*91f16700Schasinglulu #define L2_PWR_CTL_L2_HS_EN BIT_32(9) 41*91f16700Schasinglulu #define L2_PWR_CTL_L2_HS_RST BIT_32(10) 42*91f16700Schasinglulu #define L2_PWR_CTL_L2_SLEEP_STATE BIT_32(11) 43*91f16700Schasinglulu #define L2_PWR_CTL_SYS_RESET BIT_32(12) 44*91f16700Schasinglulu #define L2_PWR_CTL_L2_RET_SLP BIT_32(13) 45*91f16700Schasinglulu #define L2_PWR_CTL_SCU_ARRAY_HS_CLAMP BIT_32(14) 46*91f16700Schasinglulu #define L2_PWR_CTL_L2_ARRAY_HS_CLAMP BIT_32(15) 47*91f16700Schasinglulu #define L2_PWR_CTL_L2_HS_CNT(cnt) ((cnt) << 16) 48*91f16700Schasinglulu #define L2_PWR_CTL_PMIC_APC_ON BIT_32(28) 49*91f16700Schasinglulu 50*91f16700Schasinglulu #define L2_PWR_STATUS_L2_HS_STS BIT_32(9) 51*91f16700Schasinglulu 52*91f16700Schasinglulu #define CORE_CBCR_CLK_ENABLE BIT_32(0) 53*91f16700Schasinglulu #define CORE_CBCR_HW_CTL BIT_32(1) 54*91f16700Schasinglulu 55*91f16700Schasinglulu /* Boot a secondary CPU core for the first time. */ 56*91f16700Schasinglulu void msm8916_cpu_boot(uintptr_t acs) 57*91f16700Schasinglulu { 58*91f16700Schasinglulu uint32_t pwr_ctl; 59*91f16700Schasinglulu 60*91f16700Schasinglulu VERBOSE("PSCI: Powering on CPU @ 0x%08lx\n", acs); 61*91f16700Schasinglulu 62*91f16700Schasinglulu pwr_ctl = CPU_PWR_CTL_CLAMP | CPU_PWR_CTL_CORE_MEM_CLAMP | 63*91f16700Schasinglulu CPU_PWR_CTL_CORE_RST | CPU_PWR_CTL_COREPOR_RST; 64*91f16700Schasinglulu mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl); 65*91f16700Schasinglulu dsb(); 66*91f16700Schasinglulu 67*91f16700Schasinglulu mmio_write_32(acs + APC_PWR_GATE_CTL, APC_PWR_GATE_CTL_GHDS_EN | 68*91f16700Schasinglulu APC_PWR_GATE_CTL_GHDS_CNT(16)); 69*91f16700Schasinglulu dsb(); 70*91f16700Schasinglulu udelay(2); 71*91f16700Schasinglulu 72*91f16700Schasinglulu pwr_ctl &= ~CPU_PWR_CTL_CORE_MEM_CLAMP; 73*91f16700Schasinglulu mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl); 74*91f16700Schasinglulu dsb(); 75*91f16700Schasinglulu 76*91f16700Schasinglulu pwr_ctl |= CPU_PWR_CTL_CORE_MEM_HS; 77*91f16700Schasinglulu mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl); 78*91f16700Schasinglulu dsb(); 79*91f16700Schasinglulu udelay(2); 80*91f16700Schasinglulu 81*91f16700Schasinglulu pwr_ctl &= ~CPU_PWR_CTL_CLAMP; 82*91f16700Schasinglulu mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl); 83*91f16700Schasinglulu dsb(); 84*91f16700Schasinglulu udelay(2); 85*91f16700Schasinglulu 86*91f16700Schasinglulu pwr_ctl &= ~(CPU_PWR_CTL_CORE_RST | CPU_PWR_CTL_COREPOR_RST); 87*91f16700Schasinglulu mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl); 88*91f16700Schasinglulu dsb(); 89*91f16700Schasinglulu 90*91f16700Schasinglulu pwr_ctl |= CPU_PWR_CTL_CORE_PWRD_UP; 91*91f16700Schasinglulu mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl); 92*91f16700Schasinglulu dsb(); 93*91f16700Schasinglulu } 94*91f16700Schasinglulu 95*91f16700Schasinglulu /* Power on cluster L2 cache for the first time. */ 96*91f16700Schasinglulu void msm8916_l2_boot(uintptr_t base) 97*91f16700Schasinglulu { 98*91f16700Schasinglulu uint32_t pwr_ctl, cbcr, ovr; 99*91f16700Schasinglulu 100*91f16700Schasinglulu /* Skip if cluster L2 is already powered on */ 101*91f16700Schasinglulu if (mmio_read_32(base + L2_PWR_STATUS) & L2_PWR_STATUS_L2_HS_STS) { 102*91f16700Schasinglulu VERBOSE("PSCI: L2 cache @ 0x%08lx is already powered on\n", base); 103*91f16700Schasinglulu return; 104*91f16700Schasinglulu } 105*91f16700Schasinglulu 106*91f16700Schasinglulu VERBOSE("PSCI: Powering on L2 cache @ 0x%08lx\n", base); 107*91f16700Schasinglulu 108*91f16700Schasinglulu pwr_ctl = L2_PWR_CTL_L2_HS_CLAMP | L2_PWR_CTL_L2_HS_EN | 109*91f16700Schasinglulu L2_PWR_CTL_L2_HS_RST | L2_PWR_CTL_SYS_RESET | 110*91f16700Schasinglulu L2_PWR_CTL_SCU_ARRAY_HS_CLAMP | L2_PWR_CTL_L2_ARRAY_HS_CLAMP | 111*91f16700Schasinglulu L2_PWR_CTL_L2_HS_CNT(16); 112*91f16700Schasinglulu mmio_write_32(base + L2_PWR_CTL, pwr_ctl); 113*91f16700Schasinglulu 114*91f16700Schasinglulu ovr = PWR_CTL_OVERRIDE_PRESETDBG; 115*91f16700Schasinglulu mmio_write_32(base + PWR_CTL_OVERRIDE, ovr); 116*91f16700Schasinglulu dsb(); 117*91f16700Schasinglulu udelay(2); 118*91f16700Schasinglulu 119*91f16700Schasinglulu pwr_ctl &= ~(L2_PWR_CTL_SCU_ARRAY_HS_CLAMP | 120*91f16700Schasinglulu L2_PWR_CTL_L2_ARRAY_HS_CLAMP); 121*91f16700Schasinglulu mmio_write_32(base + L2_PWR_CTL, pwr_ctl); 122*91f16700Schasinglulu 123*91f16700Schasinglulu pwr_ctl |= (L2_PWR_CTL_L2_ARRAY_HS | L2_PWR_CTL_SCU_ARRAY_HS); 124*91f16700Schasinglulu mmio_write_32(base + L2_PWR_CTL, pwr_ctl); 125*91f16700Schasinglulu dsb(); 126*91f16700Schasinglulu udelay(2); 127*91f16700Schasinglulu 128*91f16700Schasinglulu cbcr = CORE_CBCR_CLK_ENABLE; 129*91f16700Schasinglulu mmio_write_32(base + CORE_CBCR, cbcr); 130*91f16700Schasinglulu 131*91f16700Schasinglulu pwr_ctl &= ~L2_PWR_CTL_L2_HS_CLAMP; 132*91f16700Schasinglulu mmio_write_32(base + L2_PWR_CTL, pwr_ctl); 133*91f16700Schasinglulu dsb(); 134*91f16700Schasinglulu udelay(2); 135*91f16700Schasinglulu 136*91f16700Schasinglulu ovr &= ~PWR_CTL_OVERRIDE_PRESETDBG; 137*91f16700Schasinglulu mmio_write_32(base + PWR_CTL_OVERRIDE, ovr); 138*91f16700Schasinglulu 139*91f16700Schasinglulu pwr_ctl &= ~(L2_PWR_CTL_L2_HS_RST | L2_PWR_CTL_SYS_RESET); 140*91f16700Schasinglulu mmio_write_32(base + L2_PWR_CTL, pwr_ctl); 141*91f16700Schasinglulu dsb(); 142*91f16700Schasinglulu udelay(54); 143*91f16700Schasinglulu 144*91f16700Schasinglulu pwr_ctl |= L2_PWR_CTL_PMIC_APC_ON; 145*91f16700Schasinglulu mmio_write_32(base + L2_PWR_CTL, pwr_ctl); 146*91f16700Schasinglulu 147*91f16700Schasinglulu cbcr |= CORE_CBCR_HW_CTL; 148*91f16700Schasinglulu mmio_write_32(base + CORE_CBCR, cbcr); 149*91f16700Schasinglulu dsb(); 150*91f16700Schasinglulu } 151