1 /* 2 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <arch.h> 31 #include <asm_macros.S> 32 #include <assert_macros.S> 33 #include <bl_common.h> 34 #include <cortex_a57.h> 35 #include <cpu_macros.S> 36 #include <plat_macros.S> 37 38 /* --------------------------------------------- 39 * Disable L1 data cache and unified L2 cache 40 * --------------------------------------------- 41 */ 42 func cortex_a57_disable_dcache 43 mrs x1, sctlr_el3 44 bic x1, x1, #SCTLR_C_BIT 45 msr sctlr_el3, x1 46 isb 47 ret 48 49 /* --------------------------------------------- 50 * Disable all types of L2 prefetches. 51 * --------------------------------------------- 52 */ 53 func cortex_a57_disable_l2_prefetch 54 mrs x0, CPUECTLR_EL1 55 orr x0, x0, #CPUECTLR_DIS_TWD_ACC_PFTCH_BIT 56 mov x1, #CPUECTLR_L2_IPFTCH_DIST_MASK 57 orr x1, x1, #CPUECTLR_L2_DPFTCH_DIST_MASK 58 bic x0, x0, x1 59 msr CPUECTLR_EL1, x0 60 isb 61 dsb ish 62 ret 63 64 /* --------------------------------------------- 65 * Disable intra-cluster coherency 66 * --------------------------------------------- 67 */ 68 func cortex_a57_disable_smp 69 mrs x0, CPUECTLR_EL1 70 bic x0, x0, #CPUECTLR_SMP_BIT 71 msr CPUECTLR_EL1, x0 72 ret 73 74 /* --------------------------------------------- 75 * Disable debug interfaces 76 * --------------------------------------------- 77 */ 78 func cortex_a57_disable_ext_debug 79 mov x0, #1 80 msr osdlr_el1, x0 81 isb 82 dsb sy 83 ret 84 85 /* -------------------------------------------------- 86 * Errata Workaround for Cortex A57 Errata #806969. 87 * This applies only to revision r0p0 of Cortex A57. 88 * Inputs: 89 * x0: variant[4:7] and revision[0:3] of current cpu. 90 * Clobbers : x0 - x5 91 * -------------------------------------------------- 92 */ 93 func errata_a57_806969_wa 94 /* 95 * Compare x0 against revision r0p0 96 */ 97 cbz x0, apply_806969 98 #if DEBUG 99 b print_revision_warning 100 #else 101 ret 102 #endif 103 apply_806969: 104 /* 105 * Test if errata has already been applied in an earlier 106 * invocation of the reset handler and does not need to 107 * be applied again. 108 */ 109 mrs x1, CPUACTLR_EL1 110 tst x1, #CPUACTLR_NO_ALLOC_WBWA 111 b.ne skip_806969 112 orr x1, x1, #CPUACTLR_NO_ALLOC_WBWA 113 msr CPUACTLR_EL1, x1 114 skip_806969: 115 ret 116 117 118 /* --------------------------------------------------- 119 * Errata Workaround for Cortex A57 Errata #813420. 120 * This applies only to revision r0p0 of Cortex A57. 121 * Inputs: 122 * x0: variant[4:7] and revision[0:3] of current cpu. 123 * Clobbers : x0 - x5 124 * --------------------------------------------------- 125 */ 126 func errata_a57_813420_wa 127 /* 128 * Compare x0 against revision r0p0 129 */ 130 cbz x0, apply_813420 131 #if DEBUG 132 b print_revision_warning 133 #else 134 ret 135 #endif 136 apply_813420: 137 /* 138 * Test if errata has already been applied in an earlier 139 * invocation of the reset handler and does not need to 140 * be applied again. 141 */ 142 mrs x1, CPUACTLR_EL1 143 tst x1, #CPUACTLR_DCC_AS_DCCI 144 b.ne skip_813420 145 orr x1, x1, #CPUACTLR_DCC_AS_DCCI 146 msr CPUACTLR_EL1, x1 147 skip_813420: 148 ret 149 150 /* ------------------------------------------------- 151 * The CPU Ops reset function for Cortex-A57. 152 * Clobbers: x0-x5, x15, x19, x30 153 * ------------------------------------------------- 154 */ 155 func cortex_a57_reset_func 156 mov x19, x30 157 mrs x0, midr_el1 158 159 /* 160 * Extract the variant[20:23] and revision[0:3] from x0 161 * and pack it in x15[0:7] as variant[4:7] and revision[0:3]. 162 * First extract x0[16:23] to x15[0:7] and zero fill the rest. 163 * Then extract x0[0:3] into x15[0:3] retaining other bits. 164 */ 165 ubfx x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS) 166 bfxil x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS 167 168 #if ERRATA_A57_806969 169 mov x0, x15 170 bl errata_a57_806969_wa 171 #endif 172 173 #if ERRATA_A57_813420 174 mov x0, x15 175 bl errata_a57_813420_wa 176 #endif 177 178 /* --------------------------------------------- 179 * As a bare minimum enable the SMP bit if it is 180 * not already set. 181 * --------------------------------------------- 182 */ 183 mrs x0, CPUECTLR_EL1 184 tst x0, #CPUECTLR_SMP_BIT 185 b.ne skip_smp_setup 186 orr x0, x0, #CPUECTLR_SMP_BIT 187 msr CPUECTLR_EL1, x0 188 skip_smp_setup: 189 isb 190 ret x19 191 192 /* ---------------------------------------------------- 193 * The CPU Ops core power down function for Cortex-A57. 194 * ---------------------------------------------------- 195 */ 196 func cortex_a57_core_pwr_dwn 197 mov x18, x30 198 199 /* --------------------------------------------- 200 * Turn off caches. 201 * --------------------------------------------- 202 */ 203 bl cortex_a57_disable_dcache 204 205 /* --------------------------------------------- 206 * Disable the L2 prefetches. 207 * --------------------------------------------- 208 */ 209 bl cortex_a57_disable_l2_prefetch 210 211 /* --------------------------------------------- 212 * Flush L1 caches. 213 * --------------------------------------------- 214 */ 215 mov x0, #DCCISW 216 bl dcsw_op_level1 217 218 /* --------------------------------------------- 219 * Come out of intra cluster coherency 220 * --------------------------------------------- 221 */ 222 bl cortex_a57_disable_smp 223 224 /* --------------------------------------------- 225 * Force the debug interfaces to be quiescent 226 * --------------------------------------------- 227 */ 228 mov x30, x18 229 b cortex_a57_disable_ext_debug 230 231 /* ------------------------------------------------------- 232 * The CPU Ops cluster power down function for Cortex-A57. 233 * ------------------------------------------------------- 234 */ 235 func cortex_a57_cluster_pwr_dwn 236 mov x18, x30 237 238 /* --------------------------------------------- 239 * Turn off caches. 240 * --------------------------------------------- 241 */ 242 bl cortex_a57_disable_dcache 243 244 /* --------------------------------------------- 245 * Disable the L2 prefetches. 246 * --------------------------------------------- 247 */ 248 bl cortex_a57_disable_l2_prefetch 249 250 #if !SKIP_A57_L1_FLUSH_PWR_DWN 251 /* ------------------------------------------------- 252 * Flush the L1 caches. 253 * ------------------------------------------------- 254 */ 255 mov x0, #DCCISW 256 bl dcsw_op_level1 257 #endif 258 /* --------------------------------------------- 259 * Disable the optional ACP. 260 * --------------------------------------------- 261 */ 262 bl plat_disable_acp 263 264 /* ------------------------------------------------- 265 * Flush the L2 caches. 266 * ------------------------------------------------- 267 */ 268 mov x0, #DCCISW 269 bl dcsw_op_level2 270 271 /* --------------------------------------------- 272 * Come out of intra cluster coherency 273 * --------------------------------------------- 274 */ 275 bl cortex_a57_disable_smp 276 277 /* --------------------------------------------- 278 * Force the debug interfaces to be quiescent 279 * --------------------------------------------- 280 */ 281 mov x30, x18 282 b cortex_a57_disable_ext_debug 283 284 /* --------------------------------------------- 285 * This function provides cortex_a57 specific 286 * register information for crash reporting. 287 * It needs to return with x6 pointing to 288 * a list of register names in ascii and 289 * x8 - x15 having values of registers to be 290 * reported. 291 * --------------------------------------------- 292 */ 293 .section .rodata.cortex_a57_regs, "aS" 294 cortex_a57_regs: /* The ascii list of register names to be reported */ 295 .asciz "cpuectlr_el1", "" 296 297 func cortex_a57_cpu_reg_dump 298 adr x6, cortex_a57_regs 299 mrs x8, CPUECTLR_EL1 300 ret 301 302 303 declare_cpu_ops cortex_a57, CORTEX_A57_MIDR 304