1727e5238SSoby Mathew/* 2727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3727e5238SSoby Mathew * 4727e5238SSoby Mathew * Redistribution and use in source and binary forms, with or without 5727e5238SSoby Mathew * modification, are permitted provided that the following conditions are met: 6727e5238SSoby Mathew * 7727e5238SSoby Mathew * Redistributions of source code must retain the above copyright notice, this 8727e5238SSoby Mathew * list of conditions and the following disclaimer. 9727e5238SSoby Mathew * 10727e5238SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 11727e5238SSoby Mathew * this list of conditions and the following disclaimer in the documentation 12727e5238SSoby Mathew * and/or other materials provided with the distribution. 13727e5238SSoby Mathew * 14727e5238SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 15727e5238SSoby Mathew * to endorse or promote products derived from this software without specific 16727e5238SSoby Mathew * prior written permission. 17727e5238SSoby Mathew * 18727e5238SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19727e5238SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20727e5238SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21727e5238SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22727e5238SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23727e5238SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24727e5238SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25727e5238SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26727e5238SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27727e5238SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28727e5238SSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 29727e5238SSoby Mathew */ 30727e5238SSoby Mathew 31727e5238SSoby Mathew#include <asm_macros.S> 32727e5238SSoby Mathew#include <platform_def.h> 33727e5238SSoby Mathew#include <psci.h> 34727e5238SSoby Mathew 35727e5238SSoby Mathew .globl psci_do_pwrdown_cache_maintenance 36727e5238SSoby Mathew .globl psci_do_pwrup_cache_maintenance 37727e5238SSoby Mathew .globl psci_power_down_wfi 38727e5238SSoby Mathew 39727e5238SSoby Mathew/* ----------------------------------------------------------------------- 40727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 41727e5238SSoby Mathew * 42727e5238SSoby Mathew * This function performs cache maintenance for the specified power 43727e5238SSoby Mathew * level. The levels of cache affected are determined by the power 44727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results 45727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 46727e5238SSoby Mathew * for a higher power level. 47727e5238SSoby Mathew * 48727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly 49727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory 50727e5238SSoby Mathew * attributes after the data cache is disabled. 51727e5238SSoby Mathew * ----------------------------------------------------------------------- 52727e5238SSoby Mathew */ 53727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance 54727e5238SSoby Mathew push {r4, lr} 55727e5238SSoby Mathew 56727e5238SSoby Mathew /* ---------------------------------------------- 57727e5238SSoby Mathew * Turn OFF cache and do stack maintenance 58727e5238SSoby Mathew * prior to cpu operations . This sequence is 59727e5238SSoby Mathew * different from AArch64 because in AArch32 the 60727e5238SSoby Mathew * assembler routines for cpu operations utilize 61727e5238SSoby Mathew * the stack whereas in AArch64 it doesn't. 62727e5238SSoby Mathew * ---------------------------------------------- 63727e5238SSoby Mathew */ 64727e5238SSoby Mathew mov r4, r0 65727e5238SSoby Mathew bl do_stack_maintenance 66727e5238SSoby Mathew 67727e5238SSoby Mathew /* --------------------------------------------- 68727e5238SSoby Mathew * Determine how many levels of cache will be 69727e5238SSoby Mathew * subject to cache maintenance. Power level 70727e5238SSoby Mathew * 0 implies that only the cpu is being powered 71727e5238SSoby Mathew * down. Only the L1 data cache needs to be 72727e5238SSoby Mathew * flushed to the PoU in this case. For a higher 73727e5238SSoby Mathew * power level we are assuming that a flush 74727e5238SSoby Mathew * of L1 data and L2 unified cache is enough. 75727e5238SSoby Mathew * This information should be provided by the 76727e5238SSoby Mathew * platform. 77727e5238SSoby Mathew * --------------------------------------------- 78727e5238SSoby Mathew */ 79727e5238SSoby Mathew cmp r4, #PSCI_CPU_PWR_LVL 80727e5238SSoby Mathew pop {r4,lr} 81727e5238SSoby Mathew 82727e5238SSoby Mathew beq prepare_core_pwr_dwn 83727e5238SSoby Mathew b prepare_cluster_pwr_dwn 84727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance 85727e5238SSoby Mathew 86727e5238SSoby Mathew 87727e5238SSoby Mathew/* ----------------------------------------------------------------------- 88727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void); 89727e5238SSoby Mathew * 90727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up. 91727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning 92727e5238SSoby Mathew * on the data cache. 93727e5238SSoby Mathew * ----------------------------------------------------------------------- 94727e5238SSoby Mathew */ 95727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance 96*9f3ee61cSSoby Mathew /* r12 is pushed to meet the 8 byte stack alignment requirement */ 97*9f3ee61cSSoby Mathew push {r12, lr} 98727e5238SSoby Mathew 99727e5238SSoby Mathew /* --------------------------------------------- 100727e5238SSoby Mathew * Ensure any inflight stack writes have made it 101727e5238SSoby Mathew * to main memory. 102727e5238SSoby Mathew * --------------------------------------------- 103727e5238SSoby Mathew */ 104727e5238SSoby Mathew dmb st 105727e5238SSoby Mathew 106727e5238SSoby Mathew /* --------------------------------------------- 107727e5238SSoby Mathew * Calculate and store the size of the used 108727e5238SSoby Mathew * stack memory in r1. Calculate and store the 109727e5238SSoby Mathew * stack base address in r0. 110727e5238SSoby Mathew * --------------------------------------------- 111727e5238SSoby Mathew */ 112727e5238SSoby Mathew bl plat_get_my_stack 113727e5238SSoby Mathew mov r1, sp 114727e5238SSoby Mathew sub r1, r0, r1 115727e5238SSoby Mathew mov r0, sp 116727e5238SSoby Mathew bl inv_dcache_range 117727e5238SSoby Mathew 118727e5238SSoby Mathew /* --------------------------------------------- 119727e5238SSoby Mathew * Enable the data cache. 120727e5238SSoby Mathew * --------------------------------------------- 121727e5238SSoby Mathew */ 122727e5238SSoby Mathew ldcopr r0, SCTLR 123727e5238SSoby Mathew orr r0, r0, #SCTLR_C_BIT 124727e5238SSoby Mathew stcopr r0, SCTLR 125727e5238SSoby Mathew isb 126727e5238SSoby Mathew 127*9f3ee61cSSoby Mathew pop {r12, pc} 128727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance 129727e5238SSoby Mathew 130727e5238SSoby Mathew /* --------------------------------------------- 131727e5238SSoby Mathew * void do_stack_maintenance(void) 132727e5238SSoby Mathew * Do stack maintenance by flushing the used 133727e5238SSoby Mathew * stack to the main memory and invalidating the 134727e5238SSoby Mathew * remainder. 135727e5238SSoby Mathew * --------------------------------------------- 136727e5238SSoby Mathew */ 137727e5238SSoby Mathewfunc do_stack_maintenance 138727e5238SSoby Mathew push {r4, lr} 139727e5238SSoby Mathew bl plat_get_my_stack 140727e5238SSoby Mathew 141727e5238SSoby Mathew /* Turn off the D-cache */ 142727e5238SSoby Mathew ldcopr r1, SCTLR 143727e5238SSoby Mathew bic r1, #SCTLR_C_BIT 144727e5238SSoby Mathew stcopr r1, SCTLR 145727e5238SSoby Mathew isb 146727e5238SSoby Mathew 147727e5238SSoby Mathew /* --------------------------------------------- 148727e5238SSoby Mathew * Calculate and store the size of the used 149727e5238SSoby Mathew * stack memory in r1. 150727e5238SSoby Mathew * --------------------------------------------- 151727e5238SSoby Mathew */ 152727e5238SSoby Mathew mov r4, r0 153727e5238SSoby Mathew mov r1, sp 154727e5238SSoby Mathew sub r1, r0, r1 155727e5238SSoby Mathew mov r0, sp 156727e5238SSoby Mathew bl flush_dcache_range 157727e5238SSoby Mathew 158727e5238SSoby Mathew /* --------------------------------------------- 159727e5238SSoby Mathew * Calculate and store the size of the unused 160727e5238SSoby Mathew * stack memory in r1. Calculate and store the 161727e5238SSoby Mathew * stack base address in r0. 162727e5238SSoby Mathew * --------------------------------------------- 163727e5238SSoby Mathew */ 164727e5238SSoby Mathew sub r0, r4, #PLATFORM_STACK_SIZE 165727e5238SSoby Mathew sub r1, sp, r0 166727e5238SSoby Mathew bl inv_dcache_range 167727e5238SSoby Mathew 168727e5238SSoby Mathew pop {r4, pc} 169727e5238SSoby Mathewendfunc do_stack_maintenance 170727e5238SSoby Mathew 171727e5238SSoby Mathew/* ----------------------------------------------------------------------- 172727e5238SSoby Mathew * This function is called to indicate to the power controller that it 173727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will 174727e5238SSoby Mathew * be released from reset upon power up. 175727e5238SSoby Mathew * ----------------------------------------------------------------------- 176727e5238SSoby Mathew */ 177727e5238SSoby Mathewfunc psci_power_down_wfi 178727e5238SSoby Mathew dsb sy // ensure write buffer empty 179727e5238SSoby Mathew wfi 180727e5238SSoby Mathew bl plat_panic_handler 181727e5238SSoby Mathewendfunc psci_power_down_wfi 182