1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu#include <asm_macros.S> 8*91f16700Schasinglulu#include <assert_macros.S> 9*91f16700Schasinglulu#include <lib/psci/psci.h> 10*91f16700Schasinglulu#include <platform_def.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu .globl psci_do_pwrdown_cache_maintenance 13*91f16700Schasinglulu .globl psci_do_pwrup_cache_maintenance 14*91f16700Schasinglulu .globl psci_power_down_wfi 15*91f16700Schasinglulu 16*91f16700Schasinglulu/* ----------------------------------------------------------------------- 17*91f16700Schasinglulu * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 18*91f16700Schasinglulu * 19*91f16700Schasinglulu * This function performs cache maintenance for the specified power 20*91f16700Schasinglulu * level. The levels of cache affected are determined by the power 21*91f16700Schasinglulu * level which is passed as the argument i.e. level 0 results 22*91f16700Schasinglulu * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 23*91f16700Schasinglulu * for a higher power level. 24*91f16700Schasinglulu * 25*91f16700Schasinglulu * Additionally, this function also ensures that stack memory is correctly 26*91f16700Schasinglulu * flushed out to avoid coherency issues due to a change in its memory 27*91f16700Schasinglulu * attributes after the data cache is disabled. 28*91f16700Schasinglulu * ----------------------------------------------------------------------- 29*91f16700Schasinglulu */ 30*91f16700Schasinglulufunc psci_do_pwrdown_cache_maintenance 31*91f16700Schasinglulu stp x29, x30, [sp,#-16]! 32*91f16700Schasinglulu stp x19, x20, [sp,#-16]! 33*91f16700Schasinglulu 34*91f16700Schasinglulu /* --------------------------------------------- 35*91f16700Schasinglulu * Invoke CPU-specific power down operations for 36*91f16700Schasinglulu * the appropriate level 37*91f16700Schasinglulu * --------------------------------------------- 38*91f16700Schasinglulu */ 39*91f16700Schasinglulu bl prepare_cpu_pwr_dwn 40*91f16700Schasinglulu 41*91f16700Schasinglulu /* --------------------------------------------- 42*91f16700Schasinglulu * Do stack maintenance by flushing the used 43*91f16700Schasinglulu * stack to the main memory and invalidating the 44*91f16700Schasinglulu * remainder. 45*91f16700Schasinglulu * --------------------------------------------- 46*91f16700Schasinglulu */ 47*91f16700Schasinglulu bl plat_get_my_stack 48*91f16700Schasinglulu 49*91f16700Schasinglulu /* --------------------------------------------- 50*91f16700Schasinglulu * Calculate and store the size of the used 51*91f16700Schasinglulu * stack memory in x1. 52*91f16700Schasinglulu * --------------------------------------------- 53*91f16700Schasinglulu */ 54*91f16700Schasinglulu mov x19, x0 55*91f16700Schasinglulu mov x1, sp 56*91f16700Schasinglulu sub x1, x0, x1 57*91f16700Schasinglulu mov x0, sp 58*91f16700Schasinglulu bl flush_dcache_range 59*91f16700Schasinglulu 60*91f16700Schasinglulu /* --------------------------------------------- 61*91f16700Schasinglulu * Calculate and store the size of the unused 62*91f16700Schasinglulu * stack memory in x1. Calculate and store the 63*91f16700Schasinglulu * stack base address in x0. 64*91f16700Schasinglulu * --------------------------------------------- 65*91f16700Schasinglulu */ 66*91f16700Schasinglulu sub x0, x19, #PLATFORM_STACK_SIZE 67*91f16700Schasinglulu sub x1, sp, x0 68*91f16700Schasinglulu bl inv_dcache_range 69*91f16700Schasinglulu 70*91f16700Schasinglulu ldp x19, x20, [sp], #16 71*91f16700Schasinglulu ldp x29, x30, [sp], #16 72*91f16700Schasinglulu ret 73*91f16700Schasingluluendfunc psci_do_pwrdown_cache_maintenance 74*91f16700Schasinglulu 75*91f16700Schasinglulu 76*91f16700Schasinglulu/* ----------------------------------------------------------------------- 77*91f16700Schasinglulu * void psci_do_pwrup_cache_maintenance(void); 78*91f16700Schasinglulu * 79*91f16700Schasinglulu * This function performs cache maintenance after this cpu is powered up. 80*91f16700Schasinglulu * Currently, this involves managing the used stack memory before turning 81*91f16700Schasinglulu * on the data cache. 82*91f16700Schasinglulu * ----------------------------------------------------------------------- 83*91f16700Schasinglulu */ 84*91f16700Schasinglulufunc psci_do_pwrup_cache_maintenance 85*91f16700Schasinglulu stp x29, x30, [sp,#-16]! 86*91f16700Schasinglulu 87*91f16700Schasinglulu /* --------------------------------------------- 88*91f16700Schasinglulu * Ensure any inflight stack writes have made it 89*91f16700Schasinglulu * to main memory. 90*91f16700Schasinglulu * --------------------------------------------- 91*91f16700Schasinglulu */ 92*91f16700Schasinglulu dmb st 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* --------------------------------------------- 95*91f16700Schasinglulu * Calculate and store the size of the used 96*91f16700Schasinglulu * stack memory in x1. Calculate and store the 97*91f16700Schasinglulu * stack base address in x0. 98*91f16700Schasinglulu * --------------------------------------------- 99*91f16700Schasinglulu */ 100*91f16700Schasinglulu bl plat_get_my_stack 101*91f16700Schasinglulu mov x1, sp 102*91f16700Schasinglulu sub x1, x0, x1 103*91f16700Schasinglulu mov x0, sp 104*91f16700Schasinglulu bl inv_dcache_range 105*91f16700Schasinglulu 106*91f16700Schasinglulu /* --------------------------------------------- 107*91f16700Schasinglulu * Enable the data cache. 108*91f16700Schasinglulu * --------------------------------------------- 109*91f16700Schasinglulu */ 110*91f16700Schasinglulu mrs x0, sctlr_el3 111*91f16700Schasinglulu orr x0, x0, #SCTLR_C_BIT 112*91f16700Schasinglulu msr sctlr_el3, x0 113*91f16700Schasinglulu isb 114*91f16700Schasinglulu 115*91f16700Schasinglulu ldp x29, x30, [sp], #16 116*91f16700Schasinglulu ret 117*91f16700Schasingluluendfunc psci_do_pwrup_cache_maintenance 118*91f16700Schasinglulu 119*91f16700Schasinglulu/* ----------------------------------------------------------------------- 120*91f16700Schasinglulu * void psci_power_down_wfi(void); 121*91f16700Schasinglulu * This function is called to indicate to the power controller that it 122*91f16700Schasinglulu * is safe to power down this cpu. It should not exit the wfi and will 123*91f16700Schasinglulu * be released from reset upon power up. 124*91f16700Schasinglulu * ----------------------------------------------------------------------- 125*91f16700Schasinglulu */ 126*91f16700Schasinglulufunc psci_power_down_wfi 127*91f16700Schasinglulu#if ERRATA_A510_2684597 128*91f16700Schasinglulu bl apply_cpu_pwr_dwn_errata 129*91f16700Schasinglulu#endif 130*91f16700Schasinglulu dsb sy // ensure write buffer empty 131*91f16700Schasinglulu1: 132*91f16700Schasinglulu wfi 133*91f16700Schasinglulu b 1b 134*91f16700Schasingluluendfunc psci_power_down_wfi 135