提交 15fd5686 编写于 作者: B Benjamin Herrenschmidt 提交者: Linus Torvalds

[PATCH] ppc32: Workaround a cache flush issue on sleep

We are experiencing a problem when flushing the CPU caches before sleep
on some laptop models using the 750FX CPU rev 1.X. While I haven't been
able to figure out a proper explanation for what's going on, I do have a
workaround that seem to work reliably and allows those machine to sleep
and wakeup properly again.

I'll re-update that code if/when I ever find exactly what is happening
with those CPU revisions.
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 7da21a02
...@@ -64,27 +64,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -64,27 +64,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
mtspr SPRN_HID0,r4 /* Disable DPM */ mtspr SPRN_HID0,r4 /* Disable DPM */
sync sync
/* disp-flush L1 */ /* Disp-flush L1. We have a weird problem here that I never
li r4,0x4000 * totally figured out. On 750FX, using the ROM for the flush
mtctr r4 * results in a non-working flush. We use that workaround for
* now until I finally understand what's going on. --BenH
*/
/* ROM base by default */
lis r4,0xfff0 lis r4,0xfff0
1: lwzx r0,r0,r4 mfpvr r3
srwi r3,r3,16
cmplwi cr0,r3,0x7000
bne+ 1f
/* RAM base on 750FX */
li r4,0
1: li r4,0x4000
mtctr r4
1: lwz r0,0(r4)
addi r4,r4,32 addi r4,r4,32
bdnz 1b bdnz 1b
sync sync
isync isync
/* disable / invalidate / enable L1 data */ /* Disable / invalidate / enable L1 data */
mfspr r3,SPRN_HID0 mfspr r3,SPRN_HID0
rlwinm r0,r0,0,~HID0_DCE rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
mtspr SPRN_HID0,r3 mtspr SPRN_HID0,r3
sync sync
isync isync
ori r3,r3,HID0_DCE|HID0_DCI ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
sync sync
isync isync
mtspr SPRN_HID0,r3 mtspr SPRN_HID0,r3
xori r3,r3,HID0_DCI xori r3,r3,(HID0_DCI|HID0_ICFI)
mtspr SPRN_HID0,r3 mtspr SPRN_HID0,r3
sync sync
...@@ -110,11 +122,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -110,11 +122,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
lis r4,2 lis r4,2
mtctr r4 mtctr r4
lis r4,0xfff0 lis r4,0xfff0
1: lwzx r0,r0,r4 1: lwz r0,0(r4)
addi r4,r4,32
bdnz 1b
sync
isync
lis r4,2
mtctr r4
lis r4,0xfff0
1: dcbf 0,r4
addi r4,r4,32 addi r4,r4,32
bdnz 1b bdnz 1b
sync sync
isync isync
/* now disable L2 */ /* now disable L2 */
rlwinm r5,r5,0,~L2CR_L2E rlwinm r5,r5,0,~L2CR_L2E
b 2f b 2f
...@@ -135,6 +156,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -135,6 +156,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
mtspr SPRN_L2CR,r4 mtspr SPRN_L2CR,r4
sync sync
isync isync
/* Wait for the invalidation to complete */
1: mfspr r3,SPRN_L2CR
rlwinm. r0,r3,0,31,31
bne 1b
/* Clear L2I */
xoris r4,r4,L2CR_L2I@h xoris r4,r4,L2CR_L2I@h
sync sync
mtspr SPRN_L2CR,r4 mtspr SPRN_L2CR,r4
...@@ -142,14 +170,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -142,14 +170,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
/* now disable the L1 data cache */ /* now disable the L1 data cache */
mfspr r0,SPRN_HID0 mfspr r0,SPRN_HID0
rlwinm r0,r0,0,~HID0_DCE rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
mtspr SPRN_HID0,r0 mtspr SPRN_HID0,r0
sync sync
isync isync
/* Restore HID0[DPM] to whatever it was before */ /* Restore HID0[DPM] to whatever it was before */
sync sync
mtspr SPRN_HID0,r8 mfspr r0,SPRN_HID0
rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
mtspr SPRN_HID0,r0
sync sync
/* restore DR and EE */ /* restore DR and EE */
...@@ -201,7 +231,7 @@ flush_disable_745x: ...@@ -201,7 +231,7 @@ flush_disable_745x:
mtctr r4 mtctr r4
li r4,0 li r4,0
1: 1:
lwzx r0,r0,r4 lwz r0,0(r4)
addi r4,r4,32 /* Go to start of next cache line */ addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b bdnz 1b
isync isync
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册