1/*  *********************************************************************
2    *  SB1250 Board Support Package
3    *
4    *  L1 Cache initialization			File: sb1250_l1cache.S
5    *
6    *  This module contains code to initialize the L1 cache.
7    *
8    *  Note: all the routines in this module rely on registers only,
9    *        since DRAM may not be active yet.
10    *
11    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
12    *
13    *********************************************************************
14    *
15    *  Copyright 2000,2001,2002,2003
16    *  Broadcom Corporation. All rights reserved.
17    *
18    *  This software is furnished under license and may be used and
19    *  copied only in accordance with the following terms and
20    *  conditions.  Subject to these conditions, you may download,
21    *  copy, install, use, modify and distribute modified or unmodified
22    *  copies of this software in source and/or binary form.  No title
23    *  or ownership is transferred hereby.
24    *
25    *  1) Any source code used, modified or distributed must reproduce
26    *     and retain this copyright notice and list of conditions
27    *     as they appear in the source file.
28    *
29    *  2) No right is granted to use any trade name, trademark, or
30    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
31    *     name may not be used to endorse or promote products derived
32    *     from this software without the prior written permission of
33    *     Broadcom Corporation.
34    *
35    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47    *     THE POSSIBILITY OF SUCH DAMAGE.
48    ********************************************************************* */
49
50#include "sbmips.h"
51#include "mipsmacros.h"
52#include "sb1250_defs.h"
53#include "sb1250_regs.h"
54#include "sb1250_scd.h"
55#include "sb1250_wid.h"
56
57/*
58 * This lets us override the WID by poking values into our PromICE
59 */
60#ifdef _MAGICWID_
61#undef A_SCD_SYSTEM_REVISION
62#define A_SCD_SYSTEM_REVISION 0x1FC00508
63#endif
64
65		.text
66
67		.set	mips64
68
69
70/*  *********************************************************************
71    *  Macros
72    ********************************************************************* */
73
74#define L1CACHE_NUMWAYS	4
75#define L1CACHE_NUMIDX  256
76#define L1CACHE_LINESIZE 32
77#define L1CACHE_IDXHIGH (L1CACHE_LINESIZE*L1CACHE_NUMWAYS*L1CACHE_NUMIDX)
78
79#define L1CACHEOP(cachename,op) ((cachename) | ((op) << 2))
80
81#define L1C_OP_IDXINVAL     0
82#define L1C_OP_IDXLOADTAG   1
83#define L1C_OP_IDXSTORETAG  2
84#define L1C_OP_IMPLRSVD     3
85#define L1C_OP_HITINVAL     4
86#define L1C_OP_FILL         5
87#define L1C_OP_HITWRITEBACK 6
88#define L1C_OP_FETCHLOCK    7
89
90#define L1C_I		    0
91#define L1C_D		    1
92
93/*
94 * CP0 C0_TAGHI values for cache freezing/way elimination
95 */
96
97#define L1C_LRU_FREEZE0	    (1<<22)|(3<<20)|(2<<18)|(1<<16)|(0<<14)	/* 3,2,1,0[F] */
98#define L1C_LRU_FREEZE1	    (1<<22)|(3<<20)|(2<<18)|(0<<16)|(1<<14)	/* 3,2,0,1[F] */
99#define L1C_LRU_FREEZE2	    (1<<22)|(3<<20)|(0<<18)|(1<<16)|(2<<14)	/* 3,0,1,2[F] */
100#define L1C_LRU_FREEZE3	    (1<<22)|(2<<20)|(1<<18)|(0<<16)|(3<<14)	/* 2,1,0,3[F] */
101
102#define L1C_LRU_REMOVE0	    (1<<22)|(3<<20)|(2<<18)|(1<<16)|(3<<14)	/* 3,2,1,3 */
103#define L1C_LRU_REMOVE1	    (1<<22)|(3<<20)|(2<<18)|(0<<16)|(2<<14)	/* 3,2,0,2 */
104#define L1C_LRU_REMOVE2	    (1<<22)|(3<<20)|(0<<18)|(1<<16)|(1<<14)	/* 3,0,1,1 */
105#define L1C_LRU_REMOVE3	    (1<<22)|(2<<20)|(1<<18)|(0<<16)|(0<<14)	/* 2,1,0,0 */
106
107/*
108 * Macro to test bin numbers
109 */
110
111#define HAZARD ssnop ;  ssnop ;  ssnop ;  ssnop ;  ssnop ;  ssnop ;  ssnop
112
113#define IF_BIN(binreg,binmask,label) \
114	.set noat ; \
115	andi AT,binreg,binmask ; \
116	bne  AT,zero,label ; \
117	.set at
118
119#define IF_CPU1(label) \
120	.set noat ; \
121	mfc0 AT,C0_PRID ; \
122	srl  AT,AT,25 ; \
123	andi AT,AT,7 ; \
124	bne  AT,zero,label ; \
125	.set at
126
127/*  *********************************************************************
128    *  SB1250_L1CACHE_DISABLETABLE
129    *
130    *  This table maps the bits in the diagnostic result
131    *  register (part of WID) to which ways we want to enable/remove
132    *  from the L1.
133    *
134    *  The format of the table is:
135    *
136    *       X DD II
137    *
138    *  Where X is one for 1/4 (way indicated is the GOOD way)
139    *  or    X is zero for 3/4 (way indicated is the BAD way)
140    *
141    *  and
142    *
143    *  DD is the way number for the DCache
144    *  II is the way number for the ICache
145    *
146    *  there are 32 64-bit entries in this table.
147    ********************************************************************* */
148
149#define L1DISTBL(d,i)  (d),(i)
150
151sb1250_l1cache_disabletable:
152
153	.word	L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE0)
154	.word	L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE1)
155	.word	L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE2)
156	.word	L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE3)
157
158	.word	L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE0)
159	.word	L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE1)
160	.word	L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE2)
161	.word	L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE3)
162
163	.word	L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE0)
164	.word	L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE1)
165	.word	L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE2)
166	.word	L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE3)
167
168	.word	L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE0)
169	.word	L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE1)
170	.word	L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE2)
171	.word	L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE3)
172
173	.word	L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE0)
174	.word	L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE1)
175	.word	L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE2)
176	.word	L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE3)
177
178	.word	L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE0)
179	.word	L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE1)
180	.word	L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE2)
181	.word	L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE3)
182
183	.word	L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE0)
184	.word	L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE1)
185	.word	L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE2)
186	.word	L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE3)
187
188	.word	L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE0)
189	.word	L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE1)
190	.word	L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE2)
191	.word	L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE3)
192
193
194
195
196/*  *********************************************************************
197    *  SB1250_L1CACHE_INIT()
198    *
199    *  Initialize the L1 Cache tags to be "invalid"
200    *
201    *  Input parameters:
202    *  	   nothing
203    *
204    *  Return value:
205    *  	   nothing
206    *
207    *  Registers used:
208    *  	   t0,t1,t2,t3
209    ********************************************************************* */
210
211
212LEAF(sb1250_l1cache_init)
213
214	/*
215	 * Test to see if we're running on a pre-production part with
216	 * a defective L1 cache.  We store information in the SCD
217	 * SYSTEM_REVISION register that identifies what is
218	 * going on.
219	 */
220
221	/*
222	 * First, check the part number
223	 */
224
225		li	t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
226
227		ld	t1,0(t0)			/* get SYSTEM_REVISION */
228
229		dsrl	t1,t1,S_SYS_PART
230		andi	t1,t1,(M_SYS_PART >> S_SYS_PART)
231
232		beq	t1,0x1250,sb1250_l1cache_check_rev /* Go if real 1250 */
233		beq	t1,0x1150,sb1250_l1cache_check_rev /* or 1250 in uni-cpu mode */
234		b	sb1250_l1cache_init_good	/* otherwise not a 1250, no WID check */
235
236 	/*
237	 * Now, check the revision.  Anything earlier than step A3
238	 * does not need this check. Pass 3 does not need this check also.
239	 *
240	 * Exception: Step A6 parts return 0x04 in their revision field.
241	 * These parts can can be verified as A6 by having a nonzero WID.
242	 */
243
244sb1250_l1cache_check_rev:
245		ld	t1,0(t0)			/* get the SYSTEM_REVISION again */
246		dsrl	t1,t1,S_SYS_REVISION
247		andi	t1,t1,(M_SYS_REVISION >> S_SYS_REVISION)
248		beq	t1,0x04,sb1250_l1cache_check_wid
249		blt	t1,0x05,sb1250_l1cache_init_good
250		bge	t1,0x20,sb1250_l1cache_init_good
251
252	/*
253	 * Okay, we really need to check the WID now.  If the WID is
254	 * not programmed at all, assume the part is good.
255	 * (yes, this includes the wafer/lot bits)
256	 */
257
258sb1250_l1cache_check_wid:
259		ld	t1,0(t0)			/* Get the WID bits back */
260		dsrl	t1,t1,S_SYS_WID			/* wafer ID to bits 0..31 */
261		li	t2,(M_SYS_WID >> S_SYS_WID)
262		and	t1,t1,t2
263
264		WID_UNCONVOLUTE(t1,t2,t3,t4)
265
266		beq	t1,zero,sb1250_l1cache_init_good
267
268	/*
269         * Get the bin number from the WID.  This tells us many things.
270	 * For the L1 cache we need to know which ways to use,
271	 * and this is determined by what we put in the tag registers.
272	 */
273
274		dmtc0	zero,C0_TAGLO			/* assume all is good. */
275		dmtc0	zero,C0_TAGHI
276		dmtc0	zero,C0_TAGLO,2
277		dmtc0	zero,C0_TAGHI,2
278
279		andi	t0,t1,M_WID_BIN			/* bin # into T0 */
280		li	t2,1				/* make a bitmask */
281		sll	t0,t2,t0			/* put '1' in correct place */
282
283	/*
284	 * t0 now contains a single bit set corresponding to the bin number
285	 * that this chip belongs to.
286	 * for example, if it is in bin 4, then the value is 1<<4
287	 */
288
289	/*
290	 * Check for the case of a fully operational cache.
291	 */
292
293		IF_BIN(t0,M_WID_BIN_FID,sb1250_l1cache_init_good)
294
295	/*
296	 * Now compute an index into the table using the WID bits and
297	 * the "3/4" value from the bin number.
298	 */
299
300		li	t1,PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
301		ld	t1,0(t1)			/* get SYSTEM_REVISION */
302		dsrl	t1,t1,S_SYS_WID			/* get WID bits */
303
304		WID_UNCONVOLUTE(t1,t2,t3,t4)
305
306		IF_CPU1(sb1250_l1init_cpu1)
307
308		li	t2,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
309		ld	t2,0(t2)
310		dli	t3,M_SYS_UNICPU1
311		and	t2,t3			/* T2 nonzero if UNICPU1 */
312		bne	t2,zero,sb1250_l1init_cpu1
313
314
315sb1250_l1init_cpu0:
316		li	t2,S_WID_CPU0
317		b	sb1250_l1init_cont
318
319sb1250_l1init_cpu1:
320		li	t2,S_WID_CPU1
321
322
323sb1250_l1init_cont:
324		dsrl	t1,t1,t2			/* move CPU way bits into posn */
325		andi	t1,t1,(M_WID_CPUX_L1I|M_WID_CPUX_L1D) /* keep only way bits */
326
327
328		IF_BIN(t0,M_WID_BIN_3ID,1f)
329		ori	t1,t1,0x10			/* 1/4 bit set */
3301:
331
332	/*
333	 * Okay, now t1 is the index into the table.
334	 * Look up the I and D way disable values from the table and store
335	 * them in the TAGHI and TAGHI,2 registers.
336	 */
337		sll	t1,3				/* make 64-bit offset */
338
339		move	t3,ra
340		LOADREL(t2,sb1250_l1cache_disabletable)
341                or      t2,K1BASE
342		move	ra,t3
343		add	t2,t2,t1			/* t2 points at our table entry */
344
345		lw	t1,0(t2)			/* DCache disable mask */
346		dmtc0	t1,C0_TAGHI,2
347		lw	t1,4(t2)			/* ICache disable mask */
348		dmtc0	t1,C0_TAGHI
349
350	/*
351	 * Go ahead and initialize the cache now, using the
352	 * values programmed into the TAGHI registers.
353	 *
354	 * T0 is _still_ our bitmask from the bin register.  We will
355	 * need that later.
356	 */
357
358
359		li	t2,K1BASE
360#ifdef _FASTINIT_
361		li	t3,L1CACHE_LINESIZE*8			/* only 8 indicies now */
362#else
363		li	t3,L1CACHE_IDXHIGH
364#endif
365
366		add     t1,t2,t3
3671:		cache   L1CACHEOP(L1C_I,L1C_OP_IDXSTORETAG),0(t2)
368		addu    t2,L1CACHE_LINESIZE
369		bne     t1,t2,1b
370
371		li	t2,K1BASE
372		add     t1,t2,t3
3731:		cache   L1CACHEOP(L1C_D,L1C_OP_IDXSTORETAG),0(t2)
374		addu    t2,L1CACHE_LINESIZE
375		bne     t1,t2,1b
376
377
378	/*
379	 * Set the defeature register if we're doing the 1/4 case.
380	 * If we're here, at least _something_ is wrong.
381	 */
382
383		IF_BIN(t0,M_WID_BIN_3ID,2f)
384
385	/*
386	 * In the 1/4 case, we'll always freeze the D cache.
387	 * We might not freeze the I cache, though.
388	 */
389
390		li	t2,(1<<10)			/* Freeze D */
391		mfc0	t1,$23,2			/* start with current value */
392
393		IF_BIN(t0,M_WID_BIN_FI,1f)		/* If I cache is ok, no freeze */
394		li      t3,(1<<28)
395		or      t2,t2,t3			/* also freeze I */
3961:
397		or	t1,t1,t2			/* Merge in new bits */
398		HAZARD
399		mtc0	t1,$23,2			/* Write back to defeature register */
400		HAZARD
401
4022:
403	/*
404	 * Done, if you can believe it!
405	 */
406
407		j	ra
408
409/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
410
411	/*
412	 * This part of the routine handles a fully operational L1
413	 * cache.
414	 */
415
416sb1250_l1cache_init_good:
417
418		dmtc0	zero,C0_TAGLO
419		dmtc0	zero,C0_TAGHI
420
421		li	t2,K1BASE
422#ifdef _FASTINIT_
423		li	t3,L1CACHE_LINESIZE*8			/* only 8 indicies now */
424#else
425		li	t3,L1CACHE_IDXHIGH
426#endif
427
428		add     t0,t2,t3
429		.align	4
4301:		cache   L1CACHEOP(L1C_I,L1C_OP_IDXSTORETAG),0(t2)
431		addu    t2,L1CACHE_LINESIZE
432		bne     t0,t2,1b
433
434		dmtc0	zero,C0_TAGLO,2
435		dmtc0	zero,C0_TAGHI,2
436
437		li	t2,K1BASE
438		add     t0,t2,t3
439		.align	4
4401:		cache   L1CACHEOP(L1C_D,L1C_OP_IDXSTORETAG),0(t2)
441		addu    t2,L1CACHE_LINESIZE
442		bne     t0,t2,1b
443
444		j	ra
445
446END(sb1250_l1cache_init)
447
448
449#if CFG_VAPI
450
451LEAF(sb1250_reset_defeature)
452
453	/*
454	 * Test to see if we're running on a pre-production part with
455	 * a defective L1 cache.  We store information in the SCD
456	 * SYSTEM_REVISION register that identifies what is
457	 * going on.
458	 */
459
460	/*
461	 * First, check the part number
462	 */
463
464		li	t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
465		ld	t1,0(t0)			/* get SYSTEM_REVISION */
466
467		dsrl	t1,t1,S_SYS_PART
468		andi	t1,t1,(M_SYS_PART >> S_SYS_PART)
469
470		beq	t1,0x1250,1f			/* Go if real 1250 */
471		beq	t1,0x1150,1f			/* or 1250 in uni-cpu mode */
472		b	sb1250_no_defeature	/* otherwise not a 1250, no WID check */
473
474 	/*
475	 * Now, check the revision.  Anything earlier than step A3
476	 * does not need this check.
477	 *
478	 * Exception: Step A6 parts return 0x04 in their revision field.
479	 * These parts can can be verified as A6 by having a nonzero WID.
480	 */
481
4821:		ld	t1,0(t0)			/* get the SYSTEM_REVISION again */
483		dsrl	t1,t1,S_SYS_REVISION
484		andi	t1,t1,(M_SYS_REVISION >> S_SYS_REVISION)
485		beq	t1,0x04,1f
486		blt	t1,0x05,sb1250_no_defeature
487
488	/*
489	 * Okay, we really need to check the WID now.  If the WID is
490	 * not programmed at all, assume the part is good.
491	 * (yes, this includes the wafer/lot bits)
492	 */
493
4941:		ld	t1,0(t0)			/* Get the WID bits back */
495		dsrl	t1,t1,S_SYS_WID			/* wafer ID to bits 0..31 */
496		li	t2,(M_SYS_WID >> S_SYS_WID)
497		and	t1,t1,t2
498
499		WID_UNCONVOLUTE(t1,t2,t3,t4)
500
501		beq	t1,zero,sb1250_no_defeature
502
503	/*
504         * Get the bin number from the WID.  This tells us many things.
505	 * For the L1 cache we need to know which ways to use,
506	 * and this is determined by what we put in the tag registers.
507	 */
508
509		andi	t0,t1,M_WID_BIN			/* bin # into T0 */
510		li	t2,1				/* make a bitmask */
511		sll	t0,t2,t0			/* put '1' in correct place */
512
513	/*
514	 * Set the defeature register if we're doing the 1/4 case.
515	 * If we're here, at least _something_ is wrong.
516	 * The 3/4 and full cache cases don't need defeaturing.
517	 */
518
519		IF_BIN(t0,(M_WID_BIN_3ID | M_WID_BIN_FID),sb1250_no_defeature)
520
521	/*
522	 * In the 1/4 case, we'll always freeze the D cache.
523	 * We might not freeze the I cache, though.
524	 */
525
526		li	t2,(1<<10)			/* Freeze D */
527		mfc0	t1,$23,2			/* start with current value */
528
529		IF_BIN(t0,M_WID_BIN_FI,1f)		/* If I cache is ok, no freeze */
530		li      t3,(1<<28)
531		or      t2,t2,t3			/* also freeze I */
5321:
533		or	t1,t1,t2			/* Merge in new bits */
534		HAZARD
535		mtc0	t1,$23,2			/* Write back to defeature register */
536		HAZARD
537
538sb1250_no_defeature:
539
540		j	ra
541
542END(sb1250_reset_defeature)
543
544#endif
545
546
547/*  *********************************************************************
548    *  SB1250_L1CACHE_INVAL_I()
549    *
550    *  Invalidate the L1 ICache
551    *
552    *  Input parameters:
553    *  	   nothing
554    *
555    *  Return value:
556    *  	   nothing
557    *
558    *  Registers used:
559    *  	   t0,t1,t2,t3
560    ********************************************************************* */
561
562
563LEAF(sb1250_l1cache_inval_i)
564
565
566		li	t2,K1BASE
567		li	t3,L1CACHE_IDXHIGH
568
569		add     t0,t2,t3
570		.align	4
5711:		cache   L1CACHEOP(L1C_I,L1C_OP_IDXINVAL),0(t2)
572		addu    t2,L1CACHE_LINESIZE
573		bne     t0,t2,1b
574
575		j	ra
576
577END(sb1250_l1cache_inval_i)
578
579
580/*  *********************************************************************
581    *  SB1250_L1CACHE_FLUSH_D()
582    *
583    *  Flush the entire L1 DCache (write dirty lines back to memory)
584    *
585    *  Input parameters:
586    *  	   nothing
587    *
588    *  Return value:
589    *  	   nothing
590    *
591    *  Registers used:
592    *  	   t0,t1,t2,t3
593    ********************************************************************* */
594
595
596LEAF(sb1250_l1cache_flush_d)
597
598		li	t2,K1BASE
599		li	t3,L1CACHE_IDXHIGH
600
601		li	t2,K1BASE
602		add     t0,t2,t3
603		.align	4
6041:		cache   L1CACHEOP(L1C_D,L1C_OP_IDXINVAL),0(t2)
605		addu    t2,L1CACHE_LINESIZE
606		bne     t0,t2,1b
607
608		sync
609		sync				/* pass1 issue. */
610
611		j	ra
612
613END(sb1250_l1cache_flush_d)
614
615
616/*  *********************************************************************
617    *  End
618    ********************************************************************* */
619
620