1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <arch_helpers.h> 10 #include <cortex_a53.h> 11 #include <common/debug.h> 12 #include <drivers/delay_timer.h> 13 #include <lib/mmio.h> 14 15 #include <flowctrl.h> 16 #include <lib/utils_def.h> 17 #include <pmc.h> 18 #include <tegra_def.h> 19 20 #define CLK_RST_DEV_L_SET 0x300 21 #define CLK_RST_DEV_L_CLR 0x304 22 #define CLK_BPMP_RST (1 << 1) 23 24 #define EVP_BPMP_RESET_VECTOR 0x200 25 26 static const uint64_t flowctrl_offset_cpu_csr[4] = { 27 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU0_CSR), 28 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR), 29 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR + 8), 30 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR + 16) 31 }; 32 33 static const uint64_t flowctrl_offset_halt_cpu[4] = { 34 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU0_EVENTS), 35 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS), 36 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS + 8), 37 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS + 16) 38 }; 39 40 static const uint64_t flowctrl_offset_cc4_ctrl[4] = { 41 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL), 42 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 4), 43 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 8), 44 (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 12) 45 }; 46 47 static inline void tegra_fc_cc4_ctrl(int cpu_id, uint32_t val) 48 { 49 mmio_write_32(flowctrl_offset_cc4_ctrl[cpu_id], val); 50 val = mmio_read_32(flowctrl_offset_cc4_ctrl[cpu_id]); 51 } 52 53 static inline void tegra_fc_cpu_csr(int cpu_id, uint32_t val) 54 { 55 mmio_write_32(flowctrl_offset_cpu_csr[cpu_id], val); 56 val = mmio_read_32(flowctrl_offset_cpu_csr[cpu_id]); 57 } 58 59 static inline void tegra_fc_halt_cpu(int cpu_id, uint32_t val) 60 { 61 mmio_write_32(flowctrl_offset_halt_cpu[cpu_id], val); 62 val = mmio_read_32(flowctrl_offset_halt_cpu[cpu_id]); 63 } 64 65 static void tegra_fc_prepare_suspend(int cpu_id, uint32_t csr) 66 { 67 uint32_t val; 68 69 val = FLOWCTRL_HALT_GIC_IRQ | FLOWCTRL_HALT_GIC_FIQ | 70 FLOWCTRL_HALT_LIC_IRQ | FLOWCTRL_HALT_LIC_FIQ | 71 FLOWCTRL_WAITEVENT; 72 tegra_fc_halt_cpu(cpu_id, val); 73 74 val = FLOWCTRL_CSR_INTR_FLAG | FLOWCTRL_CSR_EVENT_FLAG | 75 FLOWCTRL_CSR_ENABLE | (FLOWCTRL_WAIT_WFI_BITMAP << cpu_id); 76 tegra_fc_cpu_csr(cpu_id, val | csr); 77 } 78 79 /******************************************************************************* 80 * After this, no core can wake from C7 until the action is reverted. 81 * If a wake up event is asserted, the FC state machine will stall until 82 * the action is reverted. 83 ******************************************************************************/ 84 void tegra_fc_ccplex_pgexit_lock(void) 85 { 86 unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK; 87 uint32_t flags = tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT) & ~INTERCEPT_IRQ_PENDING; 88 uint32_t icept_cpu_flags[] = { 89 INTERCEPT_EXIT_PG_CORE0, 90 INTERCEPT_EXIT_PG_CORE1, 91 INTERCEPT_EXIT_PG_CORE2, 92 INTERCEPT_EXIT_PG_CORE3 93 }; 94 95 /* set the intercept flags */ 96 for (i = 0; i < ARRAY_SIZE(icept_cpu_flags); i++) { 97 98 /* skip current CPU */ 99 if (i == cpu) 100 continue; 101 102 /* enable power gate exit intercept locks */ 103 flags |= icept_cpu_flags[i]; 104 } 105 106 tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, flags); 107 (void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT); 108 } 109 110 /******************************************************************************* 111 * Revert the ccplex powergate exit locks 112 ******************************************************************************/ 113 void tegra_fc_ccplex_pgexit_unlock(void) 114 { 115 /* clear lock bits, clear pending interrupts */ 116 tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, INTERCEPT_IRQ_PENDING); 117 (void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT); 118 } 119 120 /******************************************************************************* 121 * Powerdn the current CPU 122 ******************************************************************************/ 123 void tegra_fc_cpu_powerdn(uint32_t mpidr) 124 { 125 int cpu = mpidr & MPIDR_CPU_MASK; 126 127 VERBOSE("CPU%d powering down...\n", cpu); 128 tegra_fc_prepare_suspend(cpu, 0); 129 } 130 131 /******************************************************************************* 132 * Suspend the current CPU cluster 133 ******************************************************************************/ 134 void tegra_fc_cluster_idle(uint32_t mpidr) 135 { 136 int cpu = mpidr & MPIDR_CPU_MASK; 137 uint32_t val; 138 139 VERBOSE("Entering cluster idle state...\n"); 140 141 tegra_fc_cc4_ctrl(cpu, 0); 142 143 /* hardware L2 flush is faster for A53 only */ 144 tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, 145 !!MPIDR_AFFLVL1_VAL(mpidr)); 146 147 /* suspend the CPU cluster */ 148 val = FLOWCTRL_PG_CPU_NONCPU << FLOWCTRL_ENABLE_EXT; 149 tegra_fc_prepare_suspend(cpu, val); 150 } 151 152 /******************************************************************************* 153 * Power down the current CPU cluster 154 ******************************************************************************/ 155 void tegra_fc_cluster_powerdn(uint32_t mpidr) 156 { 157 int cpu = mpidr & MPIDR_CPU_MASK; 158 uint32_t val; 159 160 VERBOSE("Entering cluster powerdn state...\n"); 161 162 tegra_fc_cc4_ctrl(cpu, 0); 163 164 /* hardware L2 flush is faster for A53 only */ 165 tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, 166 read_midr() == CORTEX_A53_MIDR); 167 168 /* power down the CPU cluster */ 169 val = FLOWCTRL_TURNOFF_CPURAIL << FLOWCTRL_ENABLE_EXT; 170 tegra_fc_prepare_suspend(cpu, val); 171 } 172 173 /******************************************************************************* 174 * Check if cluster idle or power down state is allowed from this CPU 175 ******************************************************************************/ 176 bool tegra_fc_is_ccx_allowed(void) 177 { 178 unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK; 179 uint32_t val; 180 bool ccx_allowed = true; 181 182 for (i = 0; i < ARRAY_SIZE(flowctrl_offset_cpu_csr); i++) { 183 184 /* skip current CPU */ 185 if (i == cpu) 186 continue; 187 188 /* check if all other CPUs are already halted */ 189 val = mmio_read_32(flowctrl_offset_cpu_csr[i]); 190 if ((val & FLOWCTRL_CSR_HALT_MASK) == 0U) { 191 ccx_allowed = false; 192 } 193 } 194 195 return ccx_allowed; 196 } 197 198 /******************************************************************************* 199 * Suspend the entire SoC 200 ******************************************************************************/ 201 void tegra_fc_soc_powerdn(uint32_t mpidr) 202 { 203 int cpu = mpidr & MPIDR_CPU_MASK; 204 uint32_t val; 205 206 VERBOSE("Entering SoC powerdn state...\n"); 207 208 tegra_fc_cc4_ctrl(cpu, 0); 209 210 tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, 1); 211 212 val = FLOWCTRL_TURNOFF_CPURAIL << FLOWCTRL_ENABLE_EXT; 213 tegra_fc_prepare_suspend(cpu, val); 214 215 /* overwrite HALT register */ 216 tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT); 217 } 218 219 /******************************************************************************* 220 * Power up the CPU 221 ******************************************************************************/ 222 void tegra_fc_cpu_on(int cpu) 223 { 224 tegra_fc_cpu_csr(cpu, FLOWCTRL_CSR_ENABLE); 225 tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT | FLOWCTRL_HALT_SCLK); 226 } 227 228 /******************************************************************************* 229 * Power down the CPU 230 ******************************************************************************/ 231 void tegra_fc_cpu_off(int cpu) 232 { 233 uint32_t val; 234 235 /* 236 * Flow controller powers down the CPU during wfi. The CPU would be 237 * powered on when it receives any interrupt. 238 */ 239 val = FLOWCTRL_CSR_INTR_FLAG | FLOWCTRL_CSR_EVENT_FLAG | 240 FLOWCTRL_CSR_ENABLE | (FLOWCTRL_WAIT_WFI_BITMAP << cpu); 241 tegra_fc_cpu_csr(cpu, val); 242 tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT); 243 tegra_fc_cc4_ctrl(cpu, 0); 244 } 245 246 /******************************************************************************* 247 * Inform the BPMP that we have completed the cluster power up 248 ******************************************************************************/ 249 void tegra_fc_lock_active_cluster(void) 250 { 251 uint32_t val; 252 253 val = tegra_fc_read_32(FLOWCTRL_BPMP_CLUSTER_CONTROL); 254 val |= FLOWCTRL_BPMP_CLUSTER_PWRON_LOCK; 255 tegra_fc_write_32(FLOWCTRL_BPMP_CLUSTER_CONTROL, val); 256 val = tegra_fc_read_32(FLOWCTRL_BPMP_CLUSTER_CONTROL); 257 } 258 259 /******************************************************************************* 260 * Power ON BPMP processor 261 ******************************************************************************/ 262 void tegra_fc_bpmp_on(uint32_t entrypoint) 263 { 264 /* halt BPMP */ 265 tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT); 266 267 /* Assert BPMP reset */ 268 mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST); 269 270 /* Set reset address (stored in PMC_SCRATCH39) */ 271 mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, entrypoint); 272 while (entrypoint != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR)) 273 ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */ 274 275 /* Wait for 2us before de-asserting the reset signal. */ 276 udelay(2); 277 278 /* De-assert BPMP reset */ 279 mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_CLR, CLK_BPMP_RST); 280 281 /* Un-halt BPMP */ 282 tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, 0); 283 } 284 285 /******************************************************************************* 286 * Power OFF BPMP processor 287 ******************************************************************************/ 288 void tegra_fc_bpmp_off(void) 289 { 290 /* halt BPMP */ 291 tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT); 292 293 /* Assert BPMP reset */ 294 mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST); 295 296 /* Clear reset address */ 297 mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, 0); 298 while (0 != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR)) 299 ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */ 300 } 301 302 /******************************************************************************* 303 * Route legacy FIQ to the GICD 304 ******************************************************************************/ 305 void tegra_fc_enable_fiq_to_ccplex_routing(void) 306 { 307 uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL); 308 309 /* set the bit to pass FIQs to the GICD */ 310 tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val | FLOWCTRL_FIQ2CCPLEX_ENABLE); 311 } 312 313 /******************************************************************************* 314 * Disable routing legacy FIQ to the GICD 315 ******************************************************************************/ 316 void tegra_fc_disable_fiq_to_ccplex_routing(void) 317 { 318 uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL); 319 320 /* clear the bit to pass FIQs to the GICD */ 321 tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val & ~FLOWCTRL_FIQ2CCPLEX_ENABLE); 322 } 323