Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
0004  * Dave Liu <daveliu@freescale.com>
0005  * copy from idle_6xx.S and modify for e500 based processor,
0006  * implement the power_save function in idle.
0007  */
0008 
0009 #include <linux/threads.h>
0010 #include <asm/reg.h>
0011 #include <asm/page.h>
0012 #include <asm/cputable.h>
0013 #include <asm/thread_info.h>
0014 #include <asm/ppc_asm.h>
0015 #include <asm/asm-offsets.h>
0016 #include <asm/feature-fixups.h>
0017 
0018     .text
0019 
0020 _GLOBAL(e500_idle)
0021     lwz r4,TI_LOCAL_FLAGS(r2)   /* set napping bit */
0022     ori r4,r4,_TLF_NAPPING  /* so when we take an exception */
0023     stw r4,TI_LOCAL_FLAGS(r2)   /* it will return to our caller */
0024 
0025 #ifdef CONFIG_PPC_E500MC
0026     wrteei  1
0027 1:  wait
0028 
0029     /*
0030      * Guard against spurious wakeups (e.g. from a hypervisor) --
0031      * any real interrupt will cause us to return to LR due to
0032      * _TLF_NAPPING.
0033      */
0034     b   1b
0035 #else
0036     /* Check if we can nap or doze, put HID0 mask in r3 */
0037     lis r3,0
0038 BEGIN_FTR_SECTION
0039     lis r3,HID0_DOZE@h
0040 END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
0041 
0042 BEGIN_FTR_SECTION
0043     /* Now check if user enabled NAP mode */
0044     lis r4,powersave_nap@ha
0045     lwz r4,powersave_nap@l(r4)
0046     cmpwi   0,r4,0
0047     beq 1f
0048     stwu    r1,-16(r1)
0049     mflr    r0
0050     stw r0,20(r1)
0051     bl  flush_dcache_L1
0052     lwz r0,20(r1)
0053     addi    r1,r1,16
0054     mtlr    r0
0055     lis r3,HID0_NAP@h
0056 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
0057 1:
0058     /* Go to NAP or DOZE now */
0059     mfspr   r4,SPRN_HID0
0060     rlwinm  r4,r4,0,~(HID0_DOZE|HID0_NAP|HID0_SLEEP)
0061     or  r4,r4,r3
0062     isync
0063     mtspr   SPRN_HID0,r4
0064     isync
0065 
0066     mfmsr   r7
0067     oris    r7,r7,MSR_WE@h
0068     ori r7,r7,MSR_EE
0069     msync
0070     mtmsr   r7
0071     isync
0072 2:  b   2b
0073 #endif /* !E500MC */
0074 
0075 /*
0076  * Return from NAP/DOZE mode, restore some CPU specific registers,
0077  * r2 containing address of current.
0078  * r11 points to the exception frame.
0079  * We have to preserve r10.
0080  */
0081 _GLOBAL(power_save_ppc32_restore)
0082     lwz r9,_LINK(r11)       /* interrupted in e500_idle */
0083     stw r9,_NIP(r11)        /* make it do a blr */
0084     blr
0085 _ASM_NOKPROBE_SYMBOL(power_save_ppc32_restore)