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