xref: /linux/arch/powerpc/kernel/l2cr_6xx.S (revision 4116941b7a703f8c770998bb3a59966608cb5bb2)
1/*
2	L2CR functions
3	Copyright © 1997-1998 by PowerLogix R & D, Inc.
4
5	This program is free software; you can redistribute it and/or modify
6	it under the terms of the GNU General Public License as published by
7	the Free Software Foundation; either version 2 of the License, or
8	(at your option) any later version.
9
10	This program is distributed in the hope that it will be useful,
11	but WITHOUT ANY WARRANTY; without even the implied warranty of
12	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13	GNU General Public License for more details.
14
15	You should have received a copy of the GNU General Public License
16	along with this program; if not, write to the Free Software
17	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19/*
20	Thur, Dec. 12, 1998.
21	- First public release, contributed by PowerLogix.
22	***********
23	Sat, Aug. 7, 1999.
24	- Terry: Made sure code disabled interrupts before running. (Previously
25			it was assumed interrupts were already disabled).
26	- Terry: Updated for tentative G4 support.  4MB of memory is now flushed
27			instead of 2MB.  (Prob. only 3 is necessary).
28	- Terry: Updated for workaround to HID0[DPM] processor bug
29			during global invalidates.
30	***********
31	Thu, July 13, 2000.
32	- Terry: Added isync to correct for an errata.
33
34	22 August 2001.
35	- DanM: Finally added the 7450 patch I've had for the past
36		several months.  The L2CR is similar, but I'm going
37		to assume the user of this functions knows what they
38		are doing.
39
40	Author:	Terry Greeniaus (tgree@phys.ualberta.ca)
41	Please e-mail updates to this file to me, thanks!
42*/
43#include <asm/processor.h>
44#include <asm/cputable.h>
45#include <asm/ppc_asm.h>
46#include <asm/cache.h>
47#include <asm/page.h>
48#include <asm/feature-fixups.h>
49
50/* Usage:
51
52	When setting the L2CR register, you must do a few special
53	things.  If you are enabling the cache, you must perform a
54	global invalidate.  If you are disabling the cache, you must
55	flush the cache contents first.  This routine takes care of
56	doing these things.  When first enabling the cache, make sure
57	you pass in the L2CR you want, as well as passing in the
58	global invalidate bit set.  A global invalidate will only be
59	performed if the L2I bit is set in applyThis.  When enabling
60	the cache, you should also set the L2E bit in applyThis.  If
61	you want to modify the L2CR contents after the cache has been
62	enabled, the recommended procedure is to first call
63	__setL2CR(0) to disable the cache and then call it again with
64	the new values for L2CR.  Examples:
65
66	_setL2CR(0)		- disables the cache
67	_setL2CR(0xB3A04000)	- enables my G3 upgrade card:
68				- L2E set to turn on the cache
69				- L2SIZ set to 1MB
70				- L2CLK set to 1:1
71				- L2RAM set to pipelined synchronous late-write
72				- L2I set to perform a global invalidation
73				- L2OH set to 0.5 nS
74				- L2DF set because this upgrade card
75				  requires it
76
77	A similar call should work for your card.  You need to know
78	the correct setting for your card and then place them in the
79	fields I have outlined above.  Other fields support optional
80	features, such as L2DO which caches only data, or L2TS which
81	causes cache pushes from the L1 cache to go to the L2 cache
82	instead of to main memory.
83
84IMPORTANT:
85	Starting with the 7450, the bits in this register have moved
86	or behave differently.  The Enable, Parity Enable, Size,
87	and L2 Invalidate are the only bits that have not moved.
88	The size is read-only for these processors with internal L2
89	cache, and the invalidate is a control as well as status.
90		-- Dan
91
92*/
93/*
94 * Summary: this procedure ignores the L2I bit in the value passed in,
95 * flushes the cache if it was already enabled, always invalidates the
96 * cache, then enables the cache if the L2E bit is set in the value
97 * passed in.
98 *   -- paulus.
99 */
100_GLOBAL(_set_L2CR)
101	/* Make sure this is a 750 or 7400 chip */
102BEGIN_FTR_SECTION
103	li	r3,-1
104	blr
105END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
106
107	mflr	r9
108
109	/* Stop DST streams */
110BEGIN_FTR_SECTION
111	DSSALL
112	sync
113END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
114
115	/* Turn off interrupts and data relocation. */
116	mfmsr	r7		/* Save MSR in r7 */
117	rlwinm	r4,r7,0,17,15
118	rlwinm	r4,r4,0,28,26	/* Turn off DR bit */
119	sync
120	mtmsr	r4
121	isync
122
123	/* Before we perform the global invalidation, we must disable dynamic
124	 * power management via HID0[DPM] to work around a processor bug where
125	 * DPM can possibly interfere with the state machine in the processor
126	 * that invalidates the L2 cache tags.
127	 */
128	mfspr	r8,SPRN_HID0		/* Save HID0 in r8 */
129	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
130	sync
131	mtspr	SPRN_HID0,r4		/* Disable DPM */
132	sync
133
134	/* Get the current enable bit of the L2CR into r4 */
135	mfspr	r4,SPRN_L2CR
136
137	/* Tweak some bits */
138	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
139	rlwinm	r3,r3,0,11,9		/* Turn off the invalidate bit */
140	rlwinm	r3,r3,0,1,31		/* Turn off the enable bit */
141
142	/* Check to see if we need to flush */
143	rlwinm.	r4,r4,0,0,0
144	beq	2f
145
146	/* Flush the cache. First, read the first 4MB of memory (physical) to
147	 * put new data in the cache.  (Actually we only need
148	 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
149	 * cover everything just to be safe).
150	 */
151
152	 /**** Might be a good idea to set L2DO here - to prevent instructions
153	       from getting into the cache.  But since we invalidate
154	       the next time we enable the cache it doesn't really matter.
155	       Don't do this unless you accommodate all processor variations.
156	       The bit moved on the 7450.....
157	  ****/
158
159BEGIN_FTR_SECTION
160	/* Disable L2 prefetch on some 745x and try to ensure
161	 * L2 prefetch engines are idle. As explained by errata
162	 * text, we can't be sure they are, we just hope very hard
163	 * that well be enough (sic !). At least I noticed Apple
164	 * doesn't even bother doing the dcbf's here...
165	 */
166	mfspr	r4,SPRN_MSSCR0
167	rlwinm	r4,r4,0,0,29
168	sync
169	mtspr	SPRN_MSSCR0,r4
170	sync
171	isync
172	lis	r4,KERNELBASE@h
173	dcbf	0,r4
174	dcbf	0,r4
175	dcbf	0,r4
176	dcbf	0,r4
177END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
178
179	/* TODO: use HW flush assist when available */
180
181	lis	r4,0x0002
182	mtctr	r4
183	li	r4,0
1841:
185	lwzx	r0,0,r4
186	addi	r4,r4,32		/* Go to start of next cache line */
187	bdnz	1b
188	isync
189
190	/* Now, flush the first 4MB of memory */
191	lis	r4,0x0002
192	mtctr	r4
193	li	r4,0
194	sync
1951:
196	dcbf	0,r4
197	addi	r4,r4,32		/* Go to start of next cache line */
198	bdnz	1b
199
2002:
201	/* Set up the L2CR configuration bits (and switch L2 off) */
202	/* CPU errata: Make sure the mtspr below is already in the
203	 * L1 icache
204	 */
205	b	20f
206	.balign	L1_CACHE_BYTES
20722:
208	sync
209	mtspr	SPRN_L2CR,r3
210	sync
211	b	23f
21220:
213	b	21f
21421:	sync
215	isync
216	b	22b
217
21823:
219	/* Perform a global invalidation */
220	oris	r3,r3,0x0020
221	sync
222	mtspr	SPRN_L2CR,r3
223	sync
224	isync				/* For errata */
225
226BEGIN_FTR_SECTION
227	/* On the 7450, we wait for the L2I bit to clear......
228	*/
22910:	mfspr	r3,SPRN_L2CR
230	andis.	r4,r3,0x0020
231	bne	10b
232	b	11f
233END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
234
235	/* Wait for the invalidation to complete */
2363:	mfspr	r3,SPRN_L2CR
237	rlwinm.	r4,r3,0,31,31
238	bne	3b
239
24011:	rlwinm	r3,r3,0,11,9		/* Turn off the L2I bit */
241	sync
242	mtspr	SPRN_L2CR,r3
243	sync
244
245	/* See if we need to enable the cache */
246	cmplwi	r5,0
247	beq	4f
248
249	/* Enable the cache */
250	oris	r3,r3,0x8000
251	mtspr	SPRN_L2CR,r3
252	sync
253
254	/* Enable L2 HW prefetch on 744x/745x */
255BEGIN_FTR_SECTION
256	mfspr	r3,SPRN_MSSCR0
257	ori	r3,r3,3
258	sync
259	mtspr	SPRN_MSSCR0,r3
260	sync
261	isync
262END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
2634:
264
265	/* Restore HID0[DPM] to whatever it was before */
266	sync
267	mtspr	1008,r8
268	sync
269
270	/* Restore MSR (restores EE and DR bits to original state) */
271	SYNC
272	mtmsr	r7
273	isync
274
275	mtlr	r9
276	blr
277
278_GLOBAL(_get_L2CR)
279	/* Return the L2CR contents */
280	li	r3,0
281BEGIN_FTR_SECTION
282	mfspr	r3,SPRN_L2CR
283END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
284	blr
285
286
287/*
288 * Here is a similar routine for dealing with the L3 cache
289 * on the 745x family of chips
290 */
291
292_GLOBAL(_set_L3CR)
293	/* Make sure this is a 745x chip */
294BEGIN_FTR_SECTION
295	li	r3,-1
296	blr
297END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
298
299	/* Turn off interrupts and data relocation. */
300	mfmsr	r7		/* Save MSR in r7 */
301	rlwinm	r4,r7,0,17,15
302	rlwinm	r4,r4,0,28,26	/* Turn off DR bit */
303	sync
304	mtmsr	r4
305	isync
306
307	/* Stop DST streams */
308	DSSALL
309	sync
310
311	/* Get the current enable bit of the L3CR into r4 */
312	mfspr	r4,SPRN_L3CR
313
314	/* Tweak some bits */
315	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
316	rlwinm	r3,r3,0,22,20		/* Turn off the invalidate bit */
317	rlwinm	r3,r3,0,2,31		/* Turn off the enable & PE bits */
318	rlwinm	r3,r3,0,5,3		/* Turn off the clken bit */
319	/* Check to see if we need to flush */
320	rlwinm.	r4,r4,0,0,0
321	beq	2f
322
323	/* Flush the cache.
324	 */
325
326	/* TODO: use HW flush assist */
327
328	lis	r4,0x0008
329	mtctr	r4
330	li	r4,0
3311:
332	lwzx	r0,0,r4
333	dcbf	0,r4
334	addi	r4,r4,32		/* Go to start of next cache line */
335	bdnz	1b
336
3372:
338	/* Set up the L3CR configuration bits (and switch L3 off) */
339	sync
340	mtspr	SPRN_L3CR,r3
341	sync
342
343	oris	r3,r3,L3CR_L3RES@h		/* Set reserved bit 5 */
344	mtspr	SPRN_L3CR,r3
345	sync
346	oris	r3,r3,L3CR_L3CLKEN@h		/* Set clken */
347	mtspr	SPRN_L3CR,r3
348	sync
349
350	/* Wait for stabilize */
351	li	r0,256
352	mtctr	r0
3531:	bdnz	1b
354
355	/* Perform a global invalidation */
356	ori	r3,r3,0x0400
357	sync
358	mtspr	SPRN_L3CR,r3
359	sync
360	isync
361
362	/* We wait for the L3I bit to clear...... */
36310:	mfspr	r3,SPRN_L3CR
364	andi.	r4,r3,0x0400
365	bne	10b
366
367	/* Clear CLKEN */
368	rlwinm	r3,r3,0,5,3		/* Turn off the clken bit */
369	mtspr	SPRN_L3CR,r3
370	sync
371
372	/* Wait for stabilize */
373	li	r0,256
374	mtctr	r0
3751:	bdnz	1b
376
377	/* See if we need to enable the cache */
378	cmplwi	r5,0
379	beq	4f
380
381	/* Enable the cache */
382	oris	r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
383	mtspr	SPRN_L3CR,r3
384	sync
385
386	/* Wait for stabilize */
387	li	r0,256
388	mtctr	r0
3891:	bdnz	1b
390
391	/* Restore MSR (restores EE and DR bits to original state) */
3924:	SYNC
393	mtmsr	r7
394	isync
395	blr
396
397_GLOBAL(_get_L3CR)
398	/* Return the L3CR contents */
399	li	r3,0
400BEGIN_FTR_SECTION
401	mfspr	r3,SPRN_L3CR
402END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
403	blr
404
405/* --- End of PowerLogix code ---
406 */
407
408
409/* flush_disable_L1()	- Flush and disable L1 cache
410 *
411 * clobbers r0, r3, ctr, cr0
412 * Must be called with interrupts disabled and MMU enabled.
413 */
414_GLOBAL(__flush_disable_L1)
415	/* Stop pending alitvec streams and memory accesses */
416BEGIN_FTR_SECTION
417	DSSALL
418END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
419 	sync
420
421	/* Load counter to 0x4000 cache lines (512k) and
422	 * load cache with datas
423	 */
424	li	r3,0x4000	/* 512kB / 32B */
425	mtctr	r3
426	lis	r3,KERNELBASE@h
4271:
428	lwz	r0,0(r3)
429	addi	r3,r3,0x0020	/* Go to start of next cache line */
430	bdnz	1b
431	isync
432	sync
433
434	/* Now flush those cache lines */
435	li	r3,0x4000	/* 512kB / 32B */
436	mtctr	r3
437	lis	r3,KERNELBASE@h
4381:
439	dcbf	0,r3
440	addi	r3,r3,0x0020	/* Go to start of next cache line */
441	bdnz	1b
442	sync
443
444	/* We can now disable the L1 cache (HID0:DCE, HID0:ICE) */
445	mfspr	r3,SPRN_HID0
446	rlwinm	r3,r3,0,18,15
447	mtspr	SPRN_HID0,r3
448	sync
449	isync
450 	blr
451
452/* inval_enable_L1	- Invalidate and enable L1 cache
453 *
454 * Assumes L1 is already disabled and MSR:EE is off
455 *
456 * clobbers r3
457 */
458_GLOBAL(__inval_enable_L1)
459	/* Enable and then Flash inval the instruction & data cache */
460	mfspr	r3,SPRN_HID0
461	ori	r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
462	sync
463	isync
464	mtspr	SPRN_HID0,r3
465	xori	r3,r3, HID0_ICFI|HID0_DCI
466	mtspr	SPRN_HID0,r3
467	sync
468
469 	blr
470
471
472