1/*  *********************************************************************
2    *  BM1280/BCM1480 Board Support Package
3    *
4    *  L2 Cache initialization			File: bcm1480_l2cache.S
5    *
6    *  This module contains code to initialize the L2 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
12    *
13    *********************************************************************
14    *
15    *  Copyright 2000,2001,2002,2003,2004
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 "cpu_config.h"
52#include "mipsmacros.h"
53#include "bcm1480_regs.h"
54#include "bcm1480_l2c.h"
55#include "bcm1480_mc.h"
56#include "bcm1480_scd.h"
57
58		.text
59		.set mips64
60
61
62/*  *********************************************************************
63    *  Macros
64    ********************************************************************* */
65
66#define CACHE_LINE_SIZE	  32
67
68/*  *********************************************************************
69    *  BCM1480_L2CACHE_INIT()
70    *
71    *  Initialize the L2 Cache tags to be "invalid"
72    *
73    *  Input parameters:
74    *  	   nothing
75    *
76    *  Return value:
77    *  	   nothing
78    *
79    *  Registers used:
80    *  	   t0,t1,t2
81    ********************************************************************* */
82
83
84LEAF(bcm1480_l2cache_init)
85_bcm1480_l2cache_init:
86
87#ifdef _BIGSUR_
88       /*
89        * This is a special hack just for the BCM1480 bringup board
90	* (customers, don't use this!).  For testing we can hold the
91	* L2 cache in reset, but the BCM1480 does not provide a way to
92	* test for that at runtime.  We will use the least significant
93	* config bit for this purpose.
94	*/
95		li	t0, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
96		ld	t0, 0(t0)
97		and	t0, t0, (1<<S_BCM1480_SYS_CONFIG)
98		beq	zero, t0, 1f
99		jr	ra
1001:
101#endif
102
103	# Save the old status register, and set the KX bit.
104
105		mfc0	t2,C0_SR
106		or	t1,t2,M_SR_KX
107		mtc0	t1,C0_SR
108		HAZARD
109
110	# Start the index at the base of the cache management
111	# area, but leave the address bit for "Valid" zero.
112	# Note that the management tags are at 00_D000_0000,
113	# which cannot be expressed with the PHYS_TO_K1 macro,
114	# so we will need to use a 64-bit address to get to it.
115
116		dli	t0,PHYS_TO_XKSEG_UNCACHED(A_BCM1480_L2C_MGMT_TAG_BASE)
117
118	# Loop through each entry and each way
119
120#ifdef _FASTINIT_
121		li	t1,16
122#else
123		li	t1,BCM1480_L2C_ENTRIES_PER_WAY*BCM1480_L2C_NUM_WAYS
124#endif
125
126
127	# Write a zero to the cache management register at each
128	# address.
129
130		.align 4
1311:		sd	zero,0(t0)
132		sd	zero,CACHE_LINE_SIZE(t0)
133		sd	zero,2*CACHE_LINE_SIZE(t0)
134		sd	zero,3*CACHE_LINE_SIZE(t0)
135		daddu	t0,(4*CACHE_LINE_SIZE) # size of a cache line
136		subu	t1,4
137		bne	t1,0,1b
138
139#ifdef _BCM1480_PASS1_WORKAROUNDS_
140	# S0 Erratum SOC-9: Doing a mgmt access to way 7 stops random
141	# replacement from working correctly.  To work around this
142	# we simply zero a line in another way again.  (This won't
143	# negatively impact operation on other revs, so we don't
144	# conditionalize it at run-time.)
145
146		dli	t0,PHYS_TO_XKSEG_UNCACHED(A_BCM1480_L2C_MGMT_TAG_BASE)
147		sd	zero,0(t0)
148#endif
149
150	#
151	# Restore old KX bit setting
152	#
153
154		mtc0	t2,C0_SR
155		HAZARD
156
157		j	ra		# return to caller
158
159END(bcm1480_l2cache_init)
160
161
162/*  *********************************************************************
163    *  BCM1480_L2CACHE_DISABLE()
164    *
165    *  Convert the entire L2 Cache into static memory, for use by
166    *  the bootstrap loader.  Actually, it only removes seven of the
167    *  ways, since you must leave at least one way active at all
168    *  times.
169    *
170    *  Input parameters:
171    *  	   nothing
172    *
173    *  Return value:
174    *  	   nothing
175    *
176    *  Registers used:
177    *  	   t0,t1
178    ********************************************************************* */
179
180
181LEAF(bcm1480_l2cache_disable)
182
183#ifdef _BIGSUR_
184	# Do nothing (return immediately) if L2 has been disabled via JTAG.
185	# See comments in bcm1480_l2cache_init.
186
187		li	t0, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
188		ld	t0, 0(t0)
189		and	t0, t0, (1<<S_BCM1480_SYS_CONFIG)
190		beq	zero, t0, 1f
191		jr	ra
1921:
193#endif
194
195	# Save the old status register, and set the KX bit.
196	# Configure the L2 cache as SRAM (all ways disabled except one)
197	# Do a memory reference at the "way_disable" address
198	# to switch it off.
199	# Warning: do NOT try to configure all of the ways off - you
200	# must leave at least one way active!  This code leaves
201	# way #7 active and gives ways 0..6 to the program.
202
203		li	t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_LO(0x0))
204		sd	zero,(t0)
205		li	t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_HI(0x8))
206		sd	zero,(t0)
207
208	# Use the result of the load to stall the pipe here.
209	# Ref sec 5.4.2
210	# XXX is this necessary for global enable/disable operations?
211
212		ld	t0,(t0)
213		addu	t0,t0,t0
214
215	# Re-write all the tags
216
217		b	_bcm1480_l2cache_init
218
219END(bcm1480_l2cache_disable)
220
221
222/*  *********************************************************************
223    *  BCM1480_L2CACHE_ENABLE()
224    *
225    *  Convert the L2 Cache memory into the actual L2 cache, enabling
226    *  the cache for future memory accesses.
227    *
228    *  Input parameters:
229    *  	   nothing
230    *
231    *  Return value:
232    *  	   nothing
233    *
234    *  Registers used:
235    *  	   t0,t1
236    ********************************************************************* */
237
238LEAF(bcm1480_l2cache_enable)
239
240#ifdef _BIGSUR_
241	# Do nothing (return immediately) if L2 has been disabled via JTAG.
242	# See comments in bcm1480_l2cache_init.
243
244		li	t0, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
245		ld	t0, 0(t0)
246		and	t0, t0, (1<<S_BCM1480_SYS_CONFIG)
247		beq	zero, t0, 1f
248		jr	ra
2491:
250#endif
251
252	# Save the old status register, and set the KX bit.
253	# Configure the L2 cache as Cache (all ways enabled)
254	# Do a memory reference at the "way_disable" address
255	# to switch it on.
256
257		li	t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_LO(0xF))
258		sd	zero,(t0)
259		li	t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_HI(0xF))
260		sd	zero,(t0)
261
262	# Use the result of the load to stall the pipe here.
263	# Ref sec 5.4.2
264	# XXX is this necessary for global enable/disable operations?
265
266		ld	t0,(t0)
267		addu	t0,t0,t0
268
269	# Re-write all the tags
270
271		b	_bcm1480_l2cache_init
272
273END(bcm1480_l2cache_enable)
274
275
276/*  *********************************************************************
277    *  BCM1480_L2CACHE_FLUSH()
278    *
279    *  Flush the entire L2 cache.  All dirty lines are written back
280    *  out to memory.
281    *
282    *  Input parameters:
283    *  	   nothing
284    *
285    *  Return value:
286    *  	   nothing
287    *
288    *  Registers used:
289    *      t0,t1,t2,t3,t4: scratch
290    *      t5: saved SR
291    *      t6: MC initial state information
292    ********************************************************************* */
293
294
295LEAF(bcm1480_l2cache_flush)
296
297#ifdef _BIGSUR_
298	# Do nothing (return immediately) if L2 has been disabled via JTAG.
299
300		li	t0, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
301		ld	t0, 0(t0)
302		and	t0, t0, (1<<S_BCM1480_SYS_CONFIG)
303		beq	zero, t0, 1f
304		jr	ra
3051:
306#endif
307
308	# Save the old status register, and set the KX bit.
309
310		mfc0	t5,C0_SR
311		or	t0,t5,M_SR_KX
312		mtc0	t0,C0_SR
313		HAZARD
314
315	#
316	# Set the BERR_DISABLE bits in the memory controller.  We're
317	# going to do cacheable reads where there is no memory.
318	# Also, turn off ECC.  We may be reading garbage, so we don't
319	# want ECC errors.
320	#
321
322		move	t6, zero
323
324		# disable buserrs in global config, and put a bit
325		# into t6 to indicate whether we actually changed the
326		# value.
327		la	t0, PHYS_TO_K1(A_BCM1480_MC_GLB_CONFIG)
328		dli	t1, M_BCM1480_MC_BERR_DISABLE
329		ld	t2, 0(t0)
330		or	t3, t1, t2
331		beq	t2, t3, 1f
332		ori	t6, t6, 1
333		sd	t3, 0(t0)
3341:
335
336		# disable ECC errors in each channel, and put bits
337		# into t6 to indicate whether we actually changed the
338		# channels.
339		la	t0, PHYS_TO_K1(A_BCM1480_MC_BASE(0))
340		li	t4, 4
3412:
342		dli	t1, M_BCM1480_MC_ECC_DISABLE
343		ld	t2, (R_BCM1480_MC_DRAMMODE)(t0)
344		or	t3, t1, t2
345		sll	t6, t6, 1
346		beq	t2, t3, 3f
347		ori	t6, t6, 1
348		sd	t3, (R_BCM1480_MC_DRAMMODE)(t0)
3493:
350		daddiu	t0, t0, BCM1480_MC_REGISTER_SPACING
351		daddiu	t4, t4, -1
352		bnez	t4, 2b
353
354		sync
355
356		# t6 now contains:
357		# bit 4: buserr needs clr
358		# bit 3: chan 0 ecc disable needs clear
359		# bit 2: chan 1 ecc disable needs clear
360		# ...
361
362	# Flush all of the lines in the cache
363	#
364	# We use the following algorithm, for each way and index of
365	# the cache:
366	#
367	# * do a management mode access to select a victim way.
368	#
369	# * do a cacheable read of an address not in the cache.
370	#
371	# The index used in the second read, in the selected victim way,
372	# will be replaced with the data from the cacheable read.
373	#
374	# We use PAs starting at 0F_0000_0000 (in the middle
375	# of the memory expansion area) for the cacheable reads.
376	# They'll return garbage data, but we're just going to
377	# invalidate afterward.
378	#
379	# Note that if the cacheable read is done to an address that
380	# is present in the cache, the victim way will *not* be ejected
381	# (since there's no need to victimize it).
382
383		dli	t0, PHYS_TO_XKPHYS(K_CALG_UNCACHED,
384					   (A_BCM1480_L2C_MGMT_TAG_BASE
385					    | V_BCM1480_L2C_MGMT_ECC_DIAG(1)))
386		dli	t1, PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, 0x0f00000000)
387		li	t2, (BCM1480_L2C_ENTRIES_PER_WAY \
388			     * BCM1480_L2C_NUM_WAYS * CACHE_LINE_SIZE)
389
3901:
391		daddiu	t2, -CACHE_LINE_SIZE
392
393		# Select the line to be victimized, and wait for the
394		# read data to return.
395		or	t3, t0, t2
396		ld	t3, 0(t3)
397		daddu	t3, t3, zero
398
399		# Read the high-memory flush address for this line, and
400		# wait for the read data to return.
401		or	t3, t1, t2
402		ld	t3, 0(t3)
403		daddu	t3, t3, zero
404
405		bnez	t2, 1b
406
407
408	#
409	# Now, invalidate the entire cache.  Of course, we could just
410	# reinit the lines we flushed, but this routine is mucking
411	# the entire cache anyway, so it doesn't matter.
412	#
413
414
415		dli	t0,PHYS_TO_XKSEG_UNCACHED(A_BCM1480_L2C_MGMT_TAG_BASE)
416		li	t1,BCM1480_L2C_ENTRIES_PER_WAY*BCM1480_L2C_NUM_WAYS
417
418	# Write a zero to the cache management register at each
419	# address.
420
4211:		sd	zero,0(t0)
422		sd	zero,CACHE_LINE_SIZE(t0)
423		sd	zero,2*CACHE_LINE_SIZE(t0)
424		sd	zero,3*CACHE_LINE_SIZE(t0)
425		daddu	t0,(4*CACHE_LINE_SIZE) # size of a cache line
426		subu	t1,4
427		bne	t1,0,1b
428
429#ifdef _BCM1480_PASS1_WORKAROUNDS_
430	# S0 Erratum SOC-9: Doing a mgmt access to way 7 stops random
431	# replacement from working correctly.  To work around this
432	# we simply zero a line in another way again.  (This won't
433	# negatively impact operation on other revs, so we don't
434	# conditionalize it at run-time.)
435		dli	t0,PHYS_TO_XKSEG_UNCACHED(A_BCM1480_L2C_MGMT_TAG_BASE)
436		sd	zero,0(t0)
437#endif
438
439	#
440	# Restore the old MC register values and turn the bus errors back on.
441	#
442
443		# t6 contains:
444		# bit 4: buserr needs clr
445		# bit 3: chan 0 ecc disable needs clear
446		# bit 2: chan 1 ecc disable needs clear
447		# ...
448		# so we work backwards to restore state.
449
450		# re-enable ECC errors in each channel as appropriate
451		# based on the values in t6.
452		la	t0, PHYS_TO_K1(A_BCM1480_MC_BASE(3))
453		li	t4, 4
4541:		andi	t1, t6, 1
455		beqz	t1, 2f
456		dli	t1, M_BCM1480_MC_ECC_DISABLE
457		ld	t2, (R_BCM1480_MC_DRAMMODE)(t0)
458		xor	t3, t1, t2
459		sd	t3, (R_BCM1480_MC_DRAMMODE)(t0)
4602:		srl	t6, t6, 1
461		daddiu	t0, t0, -BCM1480_MC_REGISTER_SPACING
462		daddiu	t4, t4, -1
463		bnez	t4, 1b
464
465		# re-enable ECC errors in global config as appropriate
466		# based on the value in t6.
467		andi	t1, t6, 1
468		beqz	t1, 3f
469		la	t0, PHYS_TO_K1(A_BCM1480_MC_GLB_CONFIG)
470		dli	t1, M_BCM1480_MC_BERR_DISABLE
471		ld	t2, 0(t0)
472		xor	t3, t1, t2
473		sd	t3, 0(t0)
4743:
475
476		sync
477
478
479	#
480	# Restore old KX bit setting
481	#
482
483		mtc0	t5,C0_SR
484		HAZARD
485
486		j	ra		# return to caller
487
488END(bcm1480_l2cache_flush)
489
490
491
492
493/*  *********************************************************************
494    *  End
495    ********************************************************************* */
496