powerpc: Move l2cr.S over to arch/powerpc
No functional changes, but call it l2cr_6xx.S since it is specific to 6xx-family (including G3/750 and G4/74xx) processors. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
@@ -34,7 +34,7 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o
|
||||
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
|
||||
obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
|
||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
obj-$(CONFIG_6xx) += idle_6xx.o
|
||||
obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o
|
||||
|
||||
ifeq ($(CONFIG_PPC_MERGE),y)
|
||||
|
||||
|
471
arch/powerpc/kernel/l2cr_6xx.S
Normal file
471
arch/powerpc/kernel/l2cr_6xx.S
Normal file
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
L2CR functions
|
||||
Copyright <EFBFBD> 1997-1998 by PowerLogix R & D, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
Thur, Dec. 12, 1998.
|
||||
- First public release, contributed by PowerLogix.
|
||||
***********
|
||||
Sat, Aug. 7, 1999.
|
||||
- Terry: Made sure code disabled interrupts before running. (Previously
|
||||
it was assumed interrupts were already disabled).
|
||||
- Terry: Updated for tentative G4 support. 4MB of memory is now flushed
|
||||
instead of 2MB. (Prob. only 3 is necessary).
|
||||
- Terry: Updated for workaround to HID0[DPM] processor bug
|
||||
during global invalidates.
|
||||
***********
|
||||
Thu, July 13, 2000.
|
||||
- Terry: Added isync to correct for an errata.
|
||||
|
||||
22 August 2001.
|
||||
- DanM: Finally added the 7450 patch I've had for the past
|
||||
several months. The L2CR is similar, but I'm going
|
||||
to assume the user of this functions knows what they
|
||||
are doing.
|
||||
|
||||
Author: Terry Greeniaus (tgree@phys.ualberta.ca)
|
||||
Please e-mail updates to this file to me, thanks!
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/ppc_asm.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/* Usage:
|
||||
|
||||
When setting the L2CR register, you must do a few special
|
||||
things. If you are enabling the cache, you must perform a
|
||||
global invalidate. If you are disabling the cache, you must
|
||||
flush the cache contents first. This routine takes care of
|
||||
doing these things. When first enabling the cache, make sure
|
||||
you pass in the L2CR you want, as well as passing in the
|
||||
global invalidate bit set. A global invalidate will only be
|
||||
performed if the L2I bit is set in applyThis. When enabling
|
||||
the cache, you should also set the L2E bit in applyThis. If
|
||||
you want to modify the L2CR contents after the cache has been
|
||||
enabled, the recommended procedure is to first call
|
||||
__setL2CR(0) to disable the cache and then call it again with
|
||||
the new values for L2CR. Examples:
|
||||
|
||||
_setL2CR(0) - disables the cache
|
||||
_setL2CR(0xB3A04000) - enables my G3 upgrade card:
|
||||
- L2E set to turn on the cache
|
||||
- L2SIZ set to 1MB
|
||||
- L2CLK set to 1:1
|
||||
- L2RAM set to pipelined synchronous late-write
|
||||
- L2I set to perform a global invalidation
|
||||
- L2OH set to 0.5 nS
|
||||
- L2DF set because this upgrade card
|
||||
requires it
|
||||
|
||||
A similar call should work for your card. You need to know
|
||||
the correct setting for your card and then place them in the
|
||||
fields I have outlined above. Other fields support optional
|
||||
features, such as L2DO which caches only data, or L2TS which
|
||||
causes cache pushes from the L1 cache to go to the L2 cache
|
||||
instead of to main memory.
|
||||
|
||||
IMPORTANT:
|
||||
Starting with the 7450, the bits in this register have moved
|
||||
or behave differently. The Enable, Parity Enable, Size,
|
||||
and L2 Invalidate are the only bits that have not moved.
|
||||
The size is read-only for these processors with internal L2
|
||||
cache, and the invalidate is a control as well as status.
|
||||
-- Dan
|
||||
|
||||
*/
|
||||
/*
|
||||
* Summary: this procedure ignores the L2I bit in the value passed in,
|
||||
* flushes the cache if it was already enabled, always invalidates the
|
||||
* cache, then enables the cache if the L2E bit is set in the value
|
||||
* passed in.
|
||||
* -- paulus.
|
||||
*/
|
||||
_GLOBAL(_set_L2CR)
|
||||
/* Make sure this is a 750 or 7400 chip */
|
||||
BEGIN_FTR_SECTION
|
||||
li r3,-1
|
||||
blr
|
||||
END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
|
||||
|
||||
mflr r9
|
||||
|
||||
/* Stop DST streams */
|
||||
BEGIN_FTR_SECTION
|
||||
DSSALL
|
||||
sync
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||
|
||||
/* Turn off interrupts and data relocation. */
|
||||
mfmsr r7 /* Save MSR in r7 */
|
||||
rlwinm r4,r7,0,17,15
|
||||
rlwinm r4,r4,0,28,26 /* Turn off DR bit */
|
||||
sync
|
||||
mtmsr r4
|
||||
isync
|
||||
|
||||
/* Before we perform the global invalidation, we must disable dynamic
|
||||
* power management via HID0[DPM] to work around a processor bug where
|
||||
* DPM can possibly interfere with the state machine in the processor
|
||||
* that invalidates the L2 cache tags.
|
||||
*/
|
||||
mfspr r8,SPRN_HID0 /* Save HID0 in r8 */
|
||||
rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
|
||||
sync
|
||||
mtspr SPRN_HID0,r4 /* Disable DPM */
|
||||
sync
|
||||
|
||||
/* Get the current enable bit of the L2CR into r4 */
|
||||
mfspr r4,SPRN_L2CR
|
||||
|
||||
/* Tweak some bits */
|
||||
rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
|
||||
rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
|
||||
rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
|
||||
|
||||
/* Check to see if we need to flush */
|
||||
rlwinm. r4,r4,0,0,0
|
||||
beq 2f
|
||||
|
||||
/* Flush the cache. First, read the first 4MB of memory (physical) to
|
||||
* put new data in the cache. (Actually we only need
|
||||
* the size of the L2 cache plus the size of the L1 cache, but 4MB will
|
||||
* cover everything just to be safe).
|
||||
*/
|
||||
|
||||
/**** Might be a good idea to set L2DO here - to prevent instructions
|
||||
from getting into the cache. But since we invalidate
|
||||
the next time we enable the cache it doesn't really matter.
|
||||
Don't do this unless you accomodate all processor variations.
|
||||
The bit moved on the 7450.....
|
||||
****/
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
/* Disable L2 prefetch on some 745x and try to ensure
|
||||
* L2 prefetch engines are idle. As explained by errata
|
||||
* text, we can't be sure they are, we just hope very hard
|
||||
* that well be enough (sic !). At least I noticed Apple
|
||||
* doesn't even bother doing the dcbf's here...
|
||||
*/
|
||||
mfspr r4,SPRN_MSSCR0
|
||||
rlwinm r4,r4,0,0,29
|
||||
sync
|
||||
mtspr SPRN_MSSCR0,r4
|
||||
sync
|
||||
isync
|
||||
lis r4,KERNELBASE@h
|
||||
dcbf 0,r4
|
||||
dcbf 0,r4
|
||||
dcbf 0,r4
|
||||
dcbf 0,r4
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
|
||||
|
||||
/* TODO: use HW flush assist when available */
|
||||
|
||||
lis r4,0x0002
|
||||
mtctr r4
|
||||
li r4,0
|
||||
1:
|
||||
lwzx r0,r0,r4
|
||||
addi r4,r4,32 /* Go to start of next cache line */
|
||||
bdnz 1b
|
||||
isync
|
||||
|
||||
/* Now, flush the first 4MB of memory */
|
||||
lis r4,0x0002
|
||||
mtctr r4
|
||||
li r4,0
|
||||
sync
|
||||
1:
|
||||
dcbf 0,r4
|
||||
addi r4,r4,32 /* Go to start of next cache line */
|
||||
bdnz 1b
|
||||
|
||||
2:
|
||||
/* Set up the L2CR configuration bits (and switch L2 off) */
|
||||
/* CPU errata: Make sure the mtspr below is already in the
|
||||
* L1 icache
|
||||
*/
|
||||
b 20f
|
||||
.balign L1_CACHE_BYTES
|
||||
22:
|
||||
sync
|
||||
mtspr SPRN_L2CR,r3
|
||||
sync
|
||||
b 23f
|
||||
20:
|
||||
b 21f
|
||||
21: sync
|
||||
isync
|
||||
b 22b
|
||||
|
||||
23:
|
||||
/* Perform a global invalidation */
|
||||
oris r3,r3,0x0020
|
||||
sync
|
||||
mtspr SPRN_L2CR,r3
|
||||
sync
|
||||
isync /* For errata */
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
/* On the 7450, we wait for the L2I bit to clear......
|
||||
*/
|
||||
10: mfspr r3,SPRN_L2CR
|
||||
andis. r4,r3,0x0020
|
||||
bne 10b
|
||||
b 11f
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
|
||||
|
||||
/* Wait for the invalidation to complete */
|
||||
3: mfspr r3,SPRN_L2CR
|
||||
rlwinm. r4,r3,0,31,31
|
||||
bne 3b
|
||||
|
||||
11: rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */
|
||||
sync
|
||||
mtspr SPRN_L2CR,r3
|
||||
sync
|
||||
|
||||
/* See if we need to enable the cache */
|
||||
cmplwi r5,0
|
||||
beq 4f
|
||||
|
||||
/* Enable the cache */
|
||||
oris r3,r3,0x8000
|
||||
mtspr SPRN_L2CR,r3
|
||||
sync
|
||||
|
||||
/* Enable L2 HW prefetch on 744x/745x */
|
||||
BEGIN_FTR_SECTION
|
||||
mfspr r3,SPRN_MSSCR0
|
||||
ori r3,r3,3
|
||||
sync
|
||||
mtspr SPRN_MSSCR0,r3
|
||||
sync
|
||||
isync
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
|
||||
4:
|
||||
|
||||
/* Restore HID0[DPM] to whatever it was before */
|
||||
sync
|
||||
mtspr 1008,r8
|
||||
sync
|
||||
|
||||
/* Restore MSR (restores EE and DR bits to original state) */
|
||||
SYNC
|
||||
mtmsr r7
|
||||
isync
|
||||
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
_GLOBAL(_get_L2CR)
|
||||
/* Return the L2CR contents */
|
||||
li r3,0
|
||||
BEGIN_FTR_SECTION
|
||||
mfspr r3,SPRN_L2CR
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* Here is a similar routine for dealing with the L3 cache
|
||||
* on the 745x family of chips
|
||||
*/
|
||||
|
||||
_GLOBAL(_set_L3CR)
|
||||
/* Make sure this is a 745x chip */
|
||||
BEGIN_FTR_SECTION
|
||||
li r3,-1
|
||||
blr
|
||||
END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
|
||||
|
||||
/* Turn off interrupts and data relocation. */
|
||||
mfmsr r7 /* Save MSR in r7 */
|
||||
rlwinm r4,r7,0,17,15
|
||||
rlwinm r4,r4,0,28,26 /* Turn off DR bit */
|
||||
sync
|
||||
mtmsr r4
|
||||
isync
|
||||
|
||||
/* Stop DST streams */
|
||||
DSSALL
|
||||
sync
|
||||
|
||||
/* Get the current enable bit of the L3CR into r4 */
|
||||
mfspr r4,SPRN_L3CR
|
||||
|
||||
/* Tweak some bits */
|
||||
rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
|
||||
rlwinm r3,r3,0,22,20 /* Turn off the invalidate bit */
|
||||
rlwinm r3,r3,0,2,31 /* Turn off the enable & PE bits */
|
||||
rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
|
||||
/* Check to see if we need to flush */
|
||||
rlwinm. r4,r4,0,0,0
|
||||
beq 2f
|
||||
|
||||
/* Flush the cache.
|
||||
*/
|
||||
|
||||
/* TODO: use HW flush assist */
|
||||
|
||||
lis r4,0x0008
|
||||
mtctr r4
|
||||
li r4,0
|
||||
1:
|
||||
lwzx r0,r0,r4
|
||||
dcbf 0,r4
|
||||
addi r4,r4,32 /* Go to start of next cache line */
|
||||
bdnz 1b
|
||||
|
||||
2:
|
||||
/* Set up the L3CR configuration bits (and switch L3 off) */
|
||||
sync
|
||||
mtspr SPRN_L3CR,r3
|
||||
sync
|
||||
|
||||
oris r3,r3,L3CR_L3RES@h /* Set reserved bit 5 */
|
||||
mtspr SPRN_L3CR,r3
|
||||
sync
|
||||
oris r3,r3,L3CR_L3CLKEN@h /* Set clken */
|
||||
mtspr SPRN_L3CR,r3
|
||||
sync
|
||||
|
||||
/* Wait for stabilize */
|
||||
li r0,256
|
||||
mtctr r0
|
||||
1: bdnz 1b
|
||||
|
||||
/* Perform a global invalidation */
|
||||
ori r3,r3,0x0400
|
||||
sync
|
||||
mtspr SPRN_L3CR,r3
|
||||
sync
|
||||
isync
|
||||
|
||||
/* We wait for the L3I bit to clear...... */
|
||||
10: mfspr r3,SPRN_L3CR
|
||||
andi. r4,r3,0x0400
|
||||
bne 10b
|
||||
|
||||
/* Clear CLKEN */
|
||||
rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
|
||||
mtspr SPRN_L3CR,r3
|
||||
sync
|
||||
|
||||
/* Wait for stabilize */
|
||||
li r0,256
|
||||
mtctr r0
|
||||
1: bdnz 1b
|
||||
|
||||
/* See if we need to enable the cache */
|
||||
cmplwi r5,0
|
||||
beq 4f
|
||||
|
||||
/* Enable the cache */
|
||||
oris r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
|
||||
mtspr SPRN_L3CR,r3
|
||||
sync
|
||||
|
||||
/* Wait for stabilize */
|
||||
li r0,256
|
||||
mtctr r0
|
||||
1: bdnz 1b
|
||||
|
||||
/* Restore MSR (restores EE and DR bits to original state) */
|
||||
4: SYNC
|
||||
mtmsr r7
|
||||
isync
|
||||
blr
|
||||
|
||||
_GLOBAL(_get_L3CR)
|
||||
/* Return the L3CR contents */
|
||||
li r3,0
|
||||
BEGIN_FTR_SECTION
|
||||
mfspr r3,SPRN_L3CR
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
|
||||
blr
|
||||
|
||||
/* --- End of PowerLogix code ---
|
||||
*/
|
||||
|
||||
|
||||
/* flush_disable_L1() - Flush and disable L1 cache
|
||||
*
|
||||
* clobbers r0, r3, ctr, cr0
|
||||
* Must be called with interrupts disabled and MMU enabled.
|
||||
*/
|
||||
_GLOBAL(__flush_disable_L1)
|
||||
/* Stop pending alitvec streams and memory accesses */
|
||||
BEGIN_FTR_SECTION
|
||||
DSSALL
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||
sync
|
||||
|
||||
/* Load counter to 0x4000 cache lines (512k) and
|
||||
* load cache with datas
|
||||
*/
|
||||
li r3,0x4000 /* 512kB / 32B */
|
||||
mtctr r3
|
||||
lis r3,KERNELBASE@h
|
||||
1:
|
||||
lwz r0,0(r3)
|
||||
addi r3,r3,0x0020 /* Go to start of next cache line */
|
||||
bdnz 1b
|
||||
isync
|
||||
sync
|
||||
|
||||
/* Now flush those cache lines */
|
||||
li r3,0x4000 /* 512kB / 32B */
|
||||
mtctr r3
|
||||
lis r3,KERNELBASE@h
|
||||
1:
|
||||
dcbf 0,r3
|
||||
addi r3,r3,0x0020 /* Go to start of next cache line */
|
||||
bdnz 1b
|
||||
sync
|
||||
|
||||
/* We can now disable the L1 cache (HID0:DCE, HID0:ICE) */
|
||||
mfspr r3,SPRN_HID0
|
||||
rlwinm r3,r3,0,18,15
|
||||
mtspr SPRN_HID0,r3
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
/* inval_enable_L1 - Invalidate and enable L1 cache
|
||||
*
|
||||
* Assumes L1 is already disabled and MSR:EE is off
|
||||
*
|
||||
* clobbers r3
|
||||
*/
|
||||
_GLOBAL(__inval_enable_L1)
|
||||
/* Enable and then Flash inval the instruction & data cache */
|
||||
mfspr r3,SPRN_HID0
|
||||
ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
|
||||
sync
|
||||
isync
|
||||
mtspr SPRN_HID0,r3
|
||||
xori r3,r3, HID0_ICFI|HID0_DCI
|
||||
mtspr SPRN_HID0,r3
|
||||
sync
|
||||
|
||||
blr
|
||||
|
||||
|
Reference in New Issue
Block a user