/*1* Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.2* Dave Liu <[email protected]>3* copy from idle_6xx.S and modify for e500 based processor,4* implement the power_save function in idle.5*6* This program is free software; you can redistribute it and/or7* modify it under the terms of the GNU General Public License8* as published by the Free Software Foundation; either version9* 2 of the License, or (at your option) any later version.10*/1112#include <linux/threads.h>13#include <asm/reg.h>14#include <asm/page.h>15#include <asm/cputable.h>16#include <asm/thread_info.h>17#include <asm/ppc_asm.h>18#include <asm/asm-offsets.h>1920.text2122_GLOBAL(e500_idle)23rlwinm r3,r1,0,0,31-THREAD_SHIFT /* current thread_info */24lwz r4,TI_LOCAL_FLAGS(r3) /* set napping bit */25ori r4,r4,_TLF_NAPPING /* so when we take an exception */26stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */2728/* Check if we can nap or doze, put HID0 mask in r3 */29lis r3,030BEGIN_FTR_SECTION31lis r3,HID0_DOZE@h32END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)3334BEGIN_FTR_SECTION35/* Now check if user enabled NAP mode */36lis r4,powersave_nap@ha37lwz r4,powersave_nap@l(r4)38cmpwi 0,r4,039beq 1f40stwu r1,-16(r1)41mflr r042stw r0,20(r1)43bl flush_dcache_L144lwz r0,20(r1)45addi r1,r1,1646mtlr r047lis r3,HID0_NAP@h48END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)49BEGIN_FTR_SECTION50msync51li r7,L2CSR0_L2FL@l52mtspr SPRN_L2CSR0,r7532:54mfspr r7,SPRN_L2CSR055andi. r4,r7,L2CSR0_L2FL@l56bne 2b57END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP)581:59/* Go to NAP or DOZE now */60mfspr r4,SPRN_HID061rlwinm r4,r4,0,~(HID0_DOZE|HID0_NAP|HID0_SLEEP)62or r4,r4,r363isync64mtspr SPRN_HID0,r465isync6667mfmsr r768oris r7,r7,MSR_WE@h69ori r7,r7,MSR_EE70msync71mtmsr r772isync732: b 2b7475/*76* Return from NAP/DOZE mode, restore some CPU specific registers,77* r2 containing physical address of current.78* r11 points to the exception frame (physical address).79* We have to preserve r10.80*/81_GLOBAL(power_save_ppc32_restore)82lwz r9,_LINK(r11) /* interrupted in e500_idle */83stw r9,_NIP(r11) /* make it do a blr */8485#ifdef CONFIG_SMP86rlwinm r12,r1,0,0,31-THREAD_SHIFT87lwz r11,TI_CPU(r12) /* get cpu number * 4 */88slwi r11,r11,289#else90li r11,091#endif9293b transfer_to_handler_cont949596