2 * BK Id: %F% %I% %G% %U% %#%
5 * This file contains the power_save function for 6xx & 7xxx CPUs
6 * rewritten in assembler
8 * Warning ! This code assumes that if your machine has a 750fx
9 * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
10 * if this is not the case some additional changes will have to
11 * be done to check a runtime var (a bit like powersave-nap)
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version.
19 #include <linux/config.h>
20 #include <linux/threads.h>
21 #include <asm/processor.h>
23 #include <asm/cputable.h>
24 #include <asm/ppc_asm.h>
32 * Init idle, called at early CPU setup time from head.S for each CPU
33 * Make sure no rest of NAP mode remains in HID0, save default
34 * values for some CPU specific registers. Called with r24
35 * containing CPU number and r3 reloc offset
41 rlwinm r4,r4,0,10,8 /* Clear NAP */
44 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
51 addis r6,r5, nap_save_msscr0@ha
52 stw r4,nap_save_msscr0@l(r6)
53 END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
56 addis r6,r5,nap_save_hid1@ha
57 stw r4,nap_save_hid1@l(r6)
58 END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
62 * Here is the power_save_6xx function. This could eventually be
63 * split into several functions & changing the function pointer
64 * depending on the various features.
68 /* Check if we can nap or doze, put HID0 mask in r3
73 END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
75 /* We must dynamically check for the NAP feature as it
76 * can be cleared by CPU init after the fixups are done
78 lis r4,cur_cpu_spec@ha
79 lwz r4,cur_cpu_spec@l(r4)
80 lwz r4,CPU_SPEC_FEATURES(r4)
81 andi. r0,r4,CPU_FTR_CAN_NAP
83 /* Now check if user or arch enabled NAP mode */
84 lis r4,powersave_nap@ha
85 lwz r4,powersave_nap@l(r4)
90 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
99 /* Check current->need_resched */
100 lwz r4,NEED_RESCHED(r2)
103 mtmsr r7 /* out of line this ? */
106 /* Some pre-nap cleanups needed on some CPUs */
107 andis. r0,r3,HID0_NAP@h
110 /* Disable L2 prefetch on some 745x and try to ensure
111 * L2 prefetch engines are idle. As explained by errata
112 * text, we can't be sure they are, we just hope very hard
113 * that well be enough (sic !). At least I noticed Apple
114 * doesn't even bother doing the dcbf's here...
127 END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
129 lis r6,nap_enter_count@ha
130 lwz r4,nap_enter_count@l(r6)
132 stw r4,nap_enter_count@l(r6)
136 /* Go to low speed mode on some 750FX */
137 lis r4,powersave_lowspeed@ha
138 lwz r4,powersave_lowspeed@l(r4)
145 END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
147 /* Go to NAP or DOZE now */
149 lis r5,(HID0_NAP|HID0_SLEEP)@h
151 oris r5,r5,HID0_DOZE@h
152 END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
156 oris r4,r4,HID0_DPM@h /* that should be done once for all */
157 END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
162 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
163 ori r7,r7,MSR_EE /* Could be ommited (already set) */
168 .globl power_save_6xx_ret
175 * Return from NAP/DOZE mode, restore some CPU specific registers,
176 * we are called with DR/IR still off and r2 containing physical
177 * address of current.
179 .globl power_save_6xx_restore
180 power_save_6xx_restore:
182 rlwinm. r22,r22,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */
183 cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
185 rlwinm r22,r22,0,9,7 /* Clear DOZE */
186 END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
191 lis r22,(nap_return_count-KERNELBASE)@ha
192 lwz r24,nap_return_count@l(r22)
194 stw r24,nap_return_count@l(r22)
198 lwz r24,PROCESSOR(r2)
200 /* Todo make sure all these are in the same page
201 * and load r22 (@ha part + CPU offset) only once
205 addis r22,r24,(nap_save_msscr0-KERNELBASE)@ha
206 lwz r22,nap_save_msscr0@l(r22)
207 mtspr SPRN_MSSCR0, r22
211 END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
213 addis r22,r24,(nap_save_hid1-KERNELBASE)@ha
214 lwz r22,nap_save_hid1@l(r22)
216 END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
217 b transfer_to_handler_cont
221 .globl nap_save_msscr0
230 .globl nap_enter_count
233 .globl nap_return_count