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 */ 42func 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 */ 53func 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 */ 68func 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 */ 78func 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 * -------------------------------------------------- 91 */ 92func errata_a57_806969_wa 93 /* 94 * Compare x0 against revision r0p0 95 */ 96 cbz x0, apply_806969 97#if DEBUG 98 b print_revision_warning 99#else 100 ret 101#endif 102apply_806969: 103 /* 104 * Test if errata has already been applied in an earlier 105 * invocation of the reset handler and does not need to 106 * be applied again. 107 */ 108 mrs x1, CPUACTLR_EL1 109 tst x1, #CPUACTLR_NO_ALLOC_WBWA 110 b.ne skip_806969 111 orr x1, x1, #CPUACTLR_NO_ALLOC_WBWA 112 msr CPUACTLR_EL1, x1 113skip_806969: 114 ret 115 116 117 /* --------------------------------------------------- 118 * Errata Workaround for Cortex A57 Errata #813420. 119 * This applies only to revision r0p0 of Cortex A57. 120 * Inputs: 121 * x0: variant[4:7] and revision[0:3] of current cpu. 122 * --------------------------------------------------- 123 */ 124func errata_a57_813420_wa 125 /* 126 * Compare x0 against revision r0p0 127 */ 128 cbz x0, apply_813420 129#if DEBUG 130 b print_revision_warning 131#else 132 ret 133#endif 134apply_813420: 135 /* 136 * Test if errata has already been applied in an earlier 137 * invocation of the reset handler and does not need to 138 * be applied again. 139 */ 140 mrs x1, CPUACTLR_EL1 141 tst x1, #CPUACTLR_DCC_AS_DCCI 142 b.ne skip_813420 143 orr x1, x1, #CPUACTLR_DCC_AS_DCCI 144 msr CPUACTLR_EL1, x1 145skip_813420: 146 ret 147 148 /* ------------------------------------------------- 149 * The CPU Ops reset function for Cortex-A57. 150 * ------------------------------------------------- 151 */ 152func cortex_a57_reset_func 153 mov x19, x30 154 mrs x0, midr_el1 155 156 /* 157 * Extract the variant[20:23] and revision[0:3] from x0 158 * and pack it in x20[0:7] as variant[4:7] and revision[0:3]. 159 * First extract x0[16:23] to x20[0:7] and zero fill the rest. 160 * Then extract x0[0:3] into x20[0:3] retaining other bits. 161 */ 162 ubfx x20, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS) 163 bfxil x20, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS 164 165#if ERRATA_A57_806969 166 mov x0, x20 167 bl errata_a57_806969_wa 168#endif 169 170#if ERRATA_A57_813420 171 mov x0, x20 172 bl errata_a57_813420_wa 173#endif 174 175 /* --------------------------------------------- 176 * As a bare minimum enable the SMP bit if it is 177 * not already set. 178 * --------------------------------------------- 179 */ 180 mrs x0, CPUECTLR_EL1 181 tst x0, #CPUECTLR_SMP_BIT 182 b.ne skip_smp_setup 183 orr x0, x0, #CPUECTLR_SMP_BIT 184 msr CPUECTLR_EL1, x0 185skip_smp_setup: 186 isb 187 ret x19 188 189 /* ---------------------------------------------------- 190 * The CPU Ops core power down function for Cortex-A57. 191 * ---------------------------------------------------- 192 */ 193func cortex_a57_core_pwr_dwn 194 mov x18, x30 195 196 /* --------------------------------------------- 197 * Turn off caches. 198 * --------------------------------------------- 199 */ 200 bl cortex_a57_disable_dcache 201 202 /* --------------------------------------------- 203 * Disable the L2 prefetches. 204 * --------------------------------------------- 205 */ 206 bl cortex_a57_disable_l2_prefetch 207 208 /* --------------------------------------------- 209 * Flush L1 caches. 210 * --------------------------------------------- 211 */ 212 mov x0, #DCCISW 213 bl dcsw_op_level1 214 215 /* --------------------------------------------- 216 * Come out of intra cluster coherency 217 * --------------------------------------------- 218 */ 219 bl cortex_a57_disable_smp 220 221 /* --------------------------------------------- 222 * Force the debug interfaces to be quiescent 223 * --------------------------------------------- 224 */ 225 mov x30, x18 226 b cortex_a57_disable_ext_debug 227 228 /* ------------------------------------------------------- 229 * The CPU Ops cluster power down function for Cortex-A57. 230 * ------------------------------------------------------- 231 */ 232func cortex_a57_cluster_pwr_dwn 233 mov x18, x30 234 235 /* --------------------------------------------- 236 * Turn off caches. 237 * --------------------------------------------- 238 */ 239 bl cortex_a57_disable_dcache 240 241 /* --------------------------------------------- 242 * Disable the L2 prefetches. 243 * --------------------------------------------- 244 */ 245 bl cortex_a57_disable_l2_prefetch 246 247#if !SKIP_A57_L1_FLUSH_PWR_DWN 248 /* ------------------------------------------------- 249 * Flush the L1 caches. 250 * ------------------------------------------------- 251 */ 252 mov x0, #DCCISW 253 bl dcsw_op_level1 254#endif 255 /* --------------------------------------------- 256 * Disable the optional ACP. 257 * --------------------------------------------- 258 */ 259 bl plat_disable_acp 260 261 /* ------------------------------------------------- 262 * Flush the L2 caches. 263 * ------------------------------------------------- 264 */ 265 mov x0, #DCCISW 266 bl dcsw_op_level2 267 268 /* --------------------------------------------- 269 * Come out of intra cluster coherency 270 * --------------------------------------------- 271 */ 272 bl cortex_a57_disable_smp 273 274 /* --------------------------------------------- 275 * Force the debug interfaces to be quiescent 276 * --------------------------------------------- 277 */ 278 mov x30, x18 279 b cortex_a57_disable_ext_debug 280 281 /* --------------------------------------------- 282 * This function provides cortex_a57 specific 283 * register information for crash reporting. 284 * It needs to return with x6 pointing to 285 * a list of register names in ascii and 286 * x8 - x15 having values of registers to be 287 * reported. 288 * --------------------------------------------- 289 */ 290.section .rodata.cortex_a57_regs, "aS" 291cortex_a57_regs: /* The ascii list of register names to be reported */ 292 .asciz "cpuectlr_el1", "" 293 294func cortex_a57_cpu_reg_dump 295 adr x6, cortex_a57_regs 296 mrs x8, CPUECTLR_EL1 297 ret 298 299 300declare_cpu_ops cortex_a57, CORTEX_A57_MIDR 301