1*6556fd1aSChristophe Leroy/* SPDX-License-Identifier: GPL-2.0-or-later */ 2*6556fd1aSChristophe Leroy/* 3*6556fd1aSChristophe Leroy * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. 4*6556fd1aSChristophe Leroy * Dave Liu <daveliu@freescale.com> 5*6556fd1aSChristophe Leroy * copy from idle_6xx.S and modify for e500 based processor, 6*6556fd1aSChristophe Leroy * implement the power_save function in idle. 7*6556fd1aSChristophe Leroy */ 8*6556fd1aSChristophe Leroy 9*6556fd1aSChristophe Leroy#include <linux/threads.h> 10*6556fd1aSChristophe Leroy#include <asm/reg.h> 11*6556fd1aSChristophe Leroy#include <asm/page.h> 12*6556fd1aSChristophe Leroy#include <asm/cputable.h> 13*6556fd1aSChristophe Leroy#include <asm/thread_info.h> 14*6556fd1aSChristophe Leroy#include <asm/ppc_asm.h> 15*6556fd1aSChristophe Leroy#include <asm/asm-offsets.h> 16*6556fd1aSChristophe Leroy#include <asm/feature-fixups.h> 17*6556fd1aSChristophe Leroy 18*6556fd1aSChristophe Leroy .text 19*6556fd1aSChristophe Leroy 20*6556fd1aSChristophe Leroy_GLOBAL(e500_idle) 21*6556fd1aSChristophe Leroy lwz r4,TI_LOCAL_FLAGS(r2) /* set napping bit */ 22*6556fd1aSChristophe Leroy ori r4,r4,_TLF_NAPPING /* so when we take an exception */ 23*6556fd1aSChristophe Leroy stw r4,TI_LOCAL_FLAGS(r2) /* it will return to our caller */ 24*6556fd1aSChristophe Leroy 25*6556fd1aSChristophe Leroy#ifdef CONFIG_PPC_E500MC 26*6556fd1aSChristophe Leroy wrteei 1 27*6556fd1aSChristophe Leroy1: wait 28*6556fd1aSChristophe Leroy 29*6556fd1aSChristophe Leroy /* 30*6556fd1aSChristophe Leroy * Guard against spurious wakeups (e.g. from a hypervisor) -- 31*6556fd1aSChristophe Leroy * any real interrupt will cause us to return to LR due to 32*6556fd1aSChristophe Leroy * _TLF_NAPPING. 33*6556fd1aSChristophe Leroy */ 34*6556fd1aSChristophe Leroy b 1b 35*6556fd1aSChristophe Leroy#else 36*6556fd1aSChristophe Leroy /* Check if we can nap or doze, put HID0 mask in r3 */ 37*6556fd1aSChristophe Leroy lis r3,0 38*6556fd1aSChristophe LeroyBEGIN_FTR_SECTION 39*6556fd1aSChristophe Leroy lis r3,HID0_DOZE@h 40*6556fd1aSChristophe LeroyEND_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) 41*6556fd1aSChristophe Leroy 42*6556fd1aSChristophe LeroyBEGIN_FTR_SECTION 43*6556fd1aSChristophe Leroy /* Now check if user enabled NAP mode */ 44*6556fd1aSChristophe Leroy lis r4,powersave_nap@ha 45*6556fd1aSChristophe Leroy lwz r4,powersave_nap@l(r4) 46*6556fd1aSChristophe Leroy cmpwi 0,r4,0 47*6556fd1aSChristophe Leroy beq 1f 48*6556fd1aSChristophe Leroy stwu r1,-16(r1) 49*6556fd1aSChristophe Leroy mflr r0 50*6556fd1aSChristophe Leroy stw r0,20(r1) 51*6556fd1aSChristophe Leroy bl flush_dcache_L1 52*6556fd1aSChristophe Leroy lwz r0,20(r1) 53*6556fd1aSChristophe Leroy addi r1,r1,16 54*6556fd1aSChristophe Leroy mtlr r0 55*6556fd1aSChristophe Leroy lis r3,HID0_NAP@h 56*6556fd1aSChristophe LeroyEND_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) 57*6556fd1aSChristophe Leroy1: 58*6556fd1aSChristophe Leroy /* Go to NAP or DOZE now */ 59*6556fd1aSChristophe Leroy mfspr r4,SPRN_HID0 60*6556fd1aSChristophe Leroy rlwinm r4,r4,0,~(HID0_DOZE|HID0_NAP|HID0_SLEEP) 61*6556fd1aSChristophe Leroy or r4,r4,r3 62*6556fd1aSChristophe Leroy isync 63*6556fd1aSChristophe Leroy mtspr SPRN_HID0,r4 64*6556fd1aSChristophe Leroy isync 65*6556fd1aSChristophe Leroy 66*6556fd1aSChristophe Leroy mfmsr r7 67*6556fd1aSChristophe Leroy oris r7,r7,MSR_WE@h 68*6556fd1aSChristophe Leroy ori r7,r7,MSR_EE 69*6556fd1aSChristophe Leroy msync 70*6556fd1aSChristophe Leroy mtmsr r7 71*6556fd1aSChristophe Leroy isync 72*6556fd1aSChristophe Leroy2: b 2b 73*6556fd1aSChristophe Leroy#endif /* !E500MC */ 74*6556fd1aSChristophe Leroy 75*6556fd1aSChristophe Leroy/* 76*6556fd1aSChristophe Leroy * Return from NAP/DOZE mode, restore some CPU specific registers, 77*6556fd1aSChristophe Leroy * r2 containing address of current. 78*6556fd1aSChristophe Leroy * r11 points to the exception frame. 79*6556fd1aSChristophe Leroy * We have to preserve r10. 80*6556fd1aSChristophe Leroy */ 81*6556fd1aSChristophe Leroy_GLOBAL(power_save_ppc32_restore) 82*6556fd1aSChristophe Leroy lwz r9,_LINK(r11) /* interrupted in e500_idle */ 83*6556fd1aSChristophe Leroy stw r9,_NIP(r11) /* make it do a blr */ 84*6556fd1aSChristophe Leroy blr 85*6556fd1aSChristophe Leroy_ASM_NOKPROBE_SYMBOL(power_save_ppc32_restore) 86