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