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