*/
_GLOBAL(flush_disable_caches)
+#ifndef CONFIG_6xx
+ blr
+#else
BEGIN_FTR_SECTION
b flush_disable_745x
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
/* Stop DPM */
- mfspr r8,SPRN_HID0 /* Save HID0 in r8 */
+ mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
sync
mtspr SPRN_HID0,r4 /* Disable DPM */
sync
- /* disp-flush L1 */
- li r4,0x4000
- mtctr r4
+ /* Disp-flush L1. We have a weird problem here that I never
+ * totally figured out. On 750FX, using the ROM for the flush
+ * 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
-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
bdnz 1b
sync
isync
- /* disable / invalidate / enable L1 data */
+ /* Disable / invalidate / enable L1 data */
mfspr r3,SPRN_HID0
- rlwinm r0,r0,0,~HID0_DCE
+ rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
mtspr SPRN_HID0,r3
sync
isync
- ori r3,r3,HID0_DCE|HID0_DCI
+ ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
sync
isync
mtspr SPRN_HID0,r3
- xori r3,r3,HID0_DCI
+ xori r3,r3,(HID0_DCI|HID0_ICFI)
mtspr SPRN_HID0,r3
sync
/* Get the current enable bit of the L2CR into r4 */
- mfspr r5,L2CR
+ mfspr r5,SPRN_L2CR
/* Set to data-only (pre-745x bit) */
oris r3,r5,L2CR_L2DO@h
b 2f
/* When disabling L2, code must be in L1 */
.balign 32
-1: mtspr L2CR,r3
+1: mtspr SPRN_L2CR,r3
3: sync
isync
b 1f
lis r4,2
mtctr r4
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
+ bdnz 1b
+ sync
+ isync
+
/* now disable L2 */
rlwinm r5,r5,0,~L2CR_L2E
b 2f
/* When disabling L2, code must be in L1 */
.balign 32
-1: mtspr L2CR,r5
+1: mtspr SPRN_L2CR,r5
3: sync
isync
b 1f
isync
/* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
oris r4,r5,L2CR_L2I@h
- mtspr L2CR,r4
+ mtspr SPRN_L2CR,r4
sync
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
sync
- mtspr L2CR,r4
+ mtspr SPRN_L2CR,r4
sync
/* now disable the L1 data cache */
- mfspr r0,HID0
- rlwinm r0,r0,0,~HID0_DCE
- mtspr HID0,r0
+ mfspr r0,SPRN_HID0
+ rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
+ mtspr SPRN_HID0,r0
sync
isync
/* Restore HID0[DPM] to whatever it was before */
sync
- mtspr SPRN_HID0,r8
+ mfspr r0,SPRN_HID0
+ rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
+ mtspr SPRN_HID0,r0
sync
/* restore DR and EE */
mtctr r4
li r4,0
1:
- lwzx r0,r0,r4
+ lwz r0,0(r4)
addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b
isync
isync
/* Flush the L2 cache using the hardware assist */
- mfspr r3,L2CR
+ mfspr r3,SPRN_L2CR
cmpwi r3,0 /* check if it is enabled first */
bge 4f
oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
b 2f
/* When disabling/locking L2, code must be in L1 */
.balign 32
-1: mtspr L2CR,r0 /* lock the L2 cache */
+1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
3: sync
isync
b 1f
isync
ori r0,r3,L2CR_L2HWF_745x
sync
- mtspr L2CR,r0 /* set the hardware flush bit */
-3: mfspr r0,L2CR /* wait for it to go to 0 */
+ mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
+3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
andi. r0,r0,L2CR_L2HWF_745x
bne 3b
sync
b 2f
/* When disabling L2, code must be in L1 */
.balign 32
-1: mtspr L2CR,r3 /* disable the L2 cache */
+1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
3: sync
isync
b 1f
1: sync
isync
oris r4,r3,L2CR_L2I@h
- mtspr L2CR,r4
+ mtspr SPRN_L2CR,r4
sync
isync
-1: mfspr r4,L2CR
+1: mfspr r4,SPRN_L2CR
andis. r0,r4,L2CR_L2I@h
bne 1b
sync
BEGIN_FTR_SECTION
/* Flush the L3 cache using the hardware assist */
-4: mfspr r3,L3CR
+4: mfspr r3,SPRN_L3CR
cmpwi r3,0 /* check if it is enabled */
bge 6f
oris r0,r3,L3CR_L3IO@h
ori r0,r0,L3CR_L3DO
sync
- mtspr L3CR,r0 /* lock the L3 cache */
+ mtspr SPRN_L3CR,r0 /* lock the L3 cache */
sync
isync
ori r0,r0,L3CR_L3HWF
sync
- mtspr L3CR,r0 /* set the hardware flush bit */
-5: mfspr r0,L3CR /* wait for it to go to zero */
+ mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
+5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
andi. r0,r0,L3CR_L3HWF
bne 5b
rlwinm r3,r3,0,~L3CR_L3E
sync
- mtspr L3CR,r3 /* disable the L3 cache */
+ mtspr SPRN_L3CR,r3 /* disable the L3 cache */
sync
ori r4,r3,L3CR_L3I
mtspr SPRN_L3CR,r4
sync
END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
-6: mfspr r0,HID0 /* now disable the L1 data cache */
+6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
rlwinm r0,r0,0,~HID0_DCE
- mtspr HID0,r0
+ mtspr SPRN_HID0,r0
sync
isync
mtmsr r11 /* restore DR and EE */
isync
blr
+#endif /* CONFIG_6xx */