Home | History | Annotate | Download | only in aarch64
      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