1/* 2 * BCM47XX Sonics SiliconBackplane SDRAM/MEMC core initialization 3 * 4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: sbsdram.S,v 1.45 2008/11/14 17:51:32 Exp $ 19 */ 20 21#include <hndsoc.h> 22#include <sbmemc.h> 23#include <sbsocram.h> 24#include <sbchipc.h> 25#include <bcmdevs.h> 26#include <bcmnvram.h> 27 28#include <mipsinc.h> 29 30/* #define DEBUG_SBSDRAM 1 */ 31#ifdef DEBUG_SBSDRAM 32 /* Trace function 33 * Write to prog space so we can see it in 34 * the Logic Analizer 35 */ 36#define LATRACEINIT \ 37 li k0,0xb8000120; \ 38 li k1,0x11; \ 39 sw k1,0(k0); \ 40 li k1,0x01020108; \ 41 sw k1,4(k0); \ 42 li k0,0xbb000000 43 44#define LATRACE(num, reg) \ 45 sw reg,((num & 0xff) << 4)(k0) 46 47#else 48#define LATRACEINIT 49#define LATRACE(num, reg) 50#endif /* DEBUG_SBSDRAM */ 51/* Debug macro - write a number to a chipc reg - use it with caution, 52 * it changes k0 and k1 registers. 53 */ 54#define TRACEINIT(x) 55#define TRACE(x) 56#define TRACE2(x) 57 58/* 59 * Register usage within this file: 60 * 61 * top ncdlsearch test_mem Xdr_do_init sb_reset_core 62 * v0: retval retval 63 * v1: corerev - - corerev - 64 * a0: coreptr coreptr - coreptr coreptr 65 * a1: x x x sdr/ddr flag 66 * a2: NVRAM x x 67 * a3: x 68 * t0: - - config 69 * t1: - - mode 70 * t2: - wr/strm off wr/strm 71 * t3: - rd/strd rd/strd 72 * t4: - g/clkd g/clkd 73 * t5: x 74 * t6: retaddr - - - 75 * t7: - - retaddr - 76 * s0: pass_count - - 77 * s1: wrsum/clkdsum - - 78 * s2: rdsum/pass_countmax - - 79 * s3: gsum/strmmax - - 80 * s4: wrlim/stdmmax - - 81 * s5: rdlim/clkdmax - - 82 * s6: glim/clkdlim - - 83 * s7: dll - - 84 * t8: - - x tmp 85 * t9: - - x retaddr 86 * k0: trace trace trace - - 87 * k1: trace trace trace - - 88 * gp: PRESERVED 89 * sp: 90 * s8: - step - - 91 * ra: 92 */ 93 94 95 .text 96 .set mips32 97 98 LEAF(sb_draminit) 99 .set noreorder 100 101 LATRACEINIT 102 TRACEINIT(0x425300) 103 104 /* Save return address */ 105 move t6,ra 106 107 /* Scan for a memory controller */ 108 move a0,s2 1091: lw v1,(SBCONFIGOFF + SBIDHIGH)(a0) 110 and a1,v1,SBIDH_CC_MASK 111 srl a1,a1,SBIDH_CC_SHIFT 112 beq a1,MEMC_CORE_ID,foundctrl 113 nop 114 beq a1,SOCRAM_CORE_ID,foundctrl 115 nop 116 addu a0,SI_CORE_SIZE 117 bne a1,(SBIDH_CC_MASK >> SBIDH_CC_SHIFT),1b 118 nop 119 120 /* No memory controller */ 121 li v0,-1 122 jr t6 123 nop 124 125foundctrl: 126 TRACE(0x425301) 127 /* If we are already in RAM, just go and size it */ 128 bal 1f 129 nop 1301: li t0,PHYSADDR_MASK 131 and t0,t0,ra 132 li t1,SI_FLASH1 133 blt t0,t1,memprio_szmem 134 nop 135 136 /* For socram we don't need any nvram parms, just do a core reset */ 137socram_init: 138 bne a1,SOCRAM_CORE_ID,read_nvram 139 nop 140 TRACE(0x425302) 141 bal sb_core_reset 142 li a2,0 143 /* and size memory */ 144 b memprio_szmem 145 nop 146 147read_nvram: 148 TRACE(0x425303) 149 /* Find NVRAM (a2) */ 150 /* 1: Isolate memc's corerev in v1 */ 151 and t2,v1,SBIDH_RCE_MASK 152 srl t2,t2,SBIDH_RCE_SHIFT 153 and v1,v1,SBIDH_RC_MASK 154 or v1,t2 155 156 /* 1.5: 5365a0 lies about its revision, it is really 1 */ 157 bnez v1,1f 158 nop 159 160 TRACE(0x425304) 161 li t0,KSEG1ADDR(SI_ENUM_BASE) # Is there a chipcommon core? 162 lw t1,CC_CHIPID(t0) # Get chipid 163 andi t1,CID_ID_MASK # Check chipid 164 bne t1,BCM5365_CHIP_ID,1f 165 nop 166 li v1,1 167 168 /* 2: find_nvram, use the 32MB window */ 1691: li t2,KSEG1ADDR(SI_FLASH2 - NVRAM_SPACE) 170 li t4,SI_FLASH2_SZ 171 li t3,FLASH_MIN 172 li t0,NVRAM_MAGIC 173 1742: add a2,t2,t3 175 lw t1,0(a2) 176 beq t0,t1,read_parms 177 nop 178 179 TRACE(0x425306) 180 sll t3,t3,1 181 ble t3,t4,2b 182 nop 183 184 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ 185 li a2,KSEG1ADDR(SI_FLASH1 + 0x1000) 186 lw t1,0(a2) 187 beq t0,t1,read_parms 188 nop 189 190 TRACE(0x425307) 191 li a2,KSEG1ADDR(SI_FLASH1 + 0x400) 192 lw t1,0(a2) 193 beq t0,t1,read_parms 194 nop 195 196 TRACE(0x425308) 197 b memc_init # No NVRAM 198 li a2, 0 199 200read_parms: 201 /* Get SDRAM parameters (t0, t1, t2) from NVRAM (a2) */ 202 TRACE(0x425309) 203 lw t0,8(a2) # SDRAM init 204 srl t0,16 205 lw t2,12(a2) 206 andi t1,t2,0xffff # SDRAM config 207 srl t2,16 # SDRAM refresh 208 lw t3,16(a2) # SDRAM ncdl 209 210memc_init: 211 /* Initialize memc core */ 212 TRACE(0x425309) 213 bnez a2,1f # Already have the parms in 214 nop # t0, t1, t2, t3 215 216 /* No nvram parms: assume DDRM16MX16X2 */ 217 218 li t0,MEMC_DDR_INIT 219 li t1,MEMC_DDR_MODE 220 li t3,MEMC_DDR1_NCDL # If rev1 (4712): 221 beq v1,1,1f 222 nop 223 # rev0, 2: 224 li t3,MEMC_DDR_NCDL 225 2261: 227 andi a3,t0,MEMC_CONFIG_DDR # Is it ddr or sdr? 228 TRACE(0x42530a) 229 beqz a3,memc_sdr_init 230 nop 231 232 /* Initialize DDR SDRAM */ 233memc_ddr_init: 234 beqz t3,ddr_find_ncdl # Do we have ncdl values? (0s) 235 nop 236 237 li t4,-1 # or ffs 238 bne t3,t4,break_ddr_ncdl 239 nop 240 241ddr_find_ncdl: 242 TRACE(0x42530b) 243 244/* Register usage */ 245#define pass_count s0 246#define wrsum s1 247#define rdsum s2 248#define gsum s3 249#define wrlim s4 250#define rdlim s5 251#define glim s6 252#define dll s7 253#define step s8 254#define wr t2 255#define rd t3 256#define g t4 257 258 /* Initialize counter & accumulators */ 259 move pass_count,zero 260 move wrsum,zero 261 move rdsum,zero 262 move gsum,zero 263 264 /* Initialize with default values */ 265 li wr,5 266 li rd,5 267 bal ddr_do_init 268 li g,10 269 270 /* Read dll value */ 271 lw dll,MEMC_NCDLCTL(a0) 272 LATRACE(0xc, dll) 273 andi dll,dll,0xfe 274 srl dll,dll,1 275 beqz dll,memprio_szmem /* If zero, leave the default values */ 276 nop 277 278 move wrlim,dll /* dll value is lim for wr, rd and g */ 279 move rdlim,dll 280 move glim,dll 281 LATRACE(0xd, wrlim) 282 LATRACE(0xe, rdlim) 283 LATRACE(0xf, glim) 284 285 addi step,dll,15 /* step = (dll + 16 - 1) / 16 */ 286 srl step,step,4 287 LATRACE(0x10, step) 288 289 sub wr,zero,dll /* Negate dll as initial value */ 290 move rd,wr 291 move g,wr 292 293 /* Inner loop: call ddr_do_init to re-initialize and the test mem */ 294loop: 295 LATRACE(0x11, wr) 296 LATRACE(0x12, rd) 297 LATRACE(0x13, g) 298 bal ddr_do_init 299 nop 300 301 bal test_mem 302 nop 303 304 LATRACE(0x14, v0) 305 beqz v0,nextg 306 nop 307 308 /* Memory is ok */ 309 310 addi pass_count,1 311 add wrsum,wrsum,wr 312 add rdsum,rdsum,rd 313 add gsum,gsum,g 314 LATRACE(0x15, pass_count) 315 LATRACE(0x16, wrsum) 316 LATRACE(0x17, rdsum) 317 LATRACE(0x18, gsum) 318 319 bne wr,dll,1f 320 nop 321 sll wrlim,dll,1 322 LATRACE(0x19, wrlim) 3231: 324 325 bne rd,dll,2f 326 nop 327 sll rdlim,dll,1 328 LATRACE(0x1a, rdlim) 3292: 330 331 bne g,dll,nextg 332 nop 333 sll glim,dll,1 334 LATRACE(0x1b, glim) 335 336nextg: 337 add g,g,step 338 ble g,glim,loop 339 nop 340 sub g,zero,dll 341 move glim,dll 342 LATRACE(0x1c, g) 343 344 /* nextrd: */ 345 add rd,rd,step 346 ble rd,rdlim,loop 347 nop 348 sub rd,zero,dll 349 move rdlim,dll 350 LATRACE(0x1d, rd) 351 352 /* nextwr: */ 353 add wr,wr,step 354 ble wr,wrlim,loop 355 nop 356 357 /* All done, calculate average values and program them */ 358 359 LATRACE(0x1e, pass_count) 360 LATRACE(0x1f, wrsum) 361 LATRACE(0x20, rdsum) 362 LATRACE(0x21, gsum) 363 beqz pass_count,1f 364 nop 365 366 div zero,wrsum,pass_count 367 mflo wr 368 369 div zero,rdsum,pass_count 370 mflo rd 371 372 div zero,gsum,pass_count 373 mflo g 374 375 b ddr_got_ncdl 376 nop 377 378 /* No passing values, panic! (use defaults) */ 3791: 380 li t3,MEMC_DDR1_NCDL # If rev1: 381 beq v1,1,2f 382 nop 383 # rev0, 2: 384 li t3,MEMC_DDR_NCDL 3852: 386 387break_ddr_ncdl: 388 TRACE(0x425322) 389 andi t4,t3,0xff # t4: g 390 srl t2,t3,16 # t2: wr 391 andi t2,t2,0xff 392 srl t3,t3,8 # t3: rd 393 andi t3,t3,0xff 394 395ddr_got_ncdl: 396 LATRACE(0x23, wr) 397 LATRACE(0x24, rd) 398 LATRACE(0x25, g) 399 bal ddr_do_init 400 nop 401 402 b memprio_szmem 403 nop 404 405memc_sdr_init: 406 beqz t3,sdr_find_ncdl # Do we have ncdl values? 407 nop 408 409 li t4,-1 410 bne t3,t4,break_sdr_ncdl 411 nop 412 413sdr_find_ncdl: 414 TRACE(0x425326) 415 416/* Register usage */ 417#define pass_count s0 418#define clkdsum s1 419#define pass_countmax s2 420#define strmmax s3 421#define strdmax s4 422#define clkdmax s5 423#define clkdlim s6 424#define strm t2 425#define strd t3 426#define clkd t4 427 428#define STRMLIM 4 429#define STRDLIM 16 430#define CLKDLIM 128 431#define CLKDLIM_IC 256 432 433 /* Initialize counter & saved values */ 434 move pass_countmax,zero 435 move strmmax,zero 436 move strdmax,zero 437 li clkdlim,CLKDLIM 438 439 and strm,t0,0x2000 /* Test for internal clock (Using strm as a temp) */ 440 beqz strm,strmloop 441 nop 442 443 li clkdlim,CLKDLIM_IC 444 445 move strm,zero /* strm loop */ 446strmloop: 447 move strd,zero 448strdloop: 449 move pass_count,zero 450 move clkdsum,zero 451 move clkd,zero 452 453 /* Inner loop: call sdr_do_init to re-initialize and the test mem */ 454clkdloop: 455 LATRACE(0x27, strm) 456 LATRACE(0x28, strd) 457 LATRACE(0x29, clkd) 458 bal sdr_do_init 459 nop 460 461 bal test_mem 462 nop 463 464 LATRACE(0x2a, v0) 465 beqz v0,failclkd 466 nop 467 468 /* Memory is ok */ 469 470 addi pass_count,1 471 add clkdsum,clkdsum,clkd 472 LATRACE(0x2b, pass_count) 473 LATRACE(0x2c, clkdsum) 474 b nextclkd 475 nop 476 477failclkd: 478 bnez pass_count,clkdout # End of passing range, leave clkd loop 479 nop 480 481nextclkd: 482 addi clkd,clkd,1 483 blt clkd,clkdlim,clkdloop 484 nop 485 486clkdout: 487 /* If no passing values, skip to next strm */ 488 beqz pass_count,nextstrm 489 nop 490 491 /* If this is a new max, Save the values */ 492 ble pass_count,pass_countmax,nextstrd 493 nop 494 495 move pass_countmax,pass_count 496 div zero,clkdsum,pass_count 497 mflo clkdmax 498 move strdmax,strd 499 move strmmax,strm 500 LATRACE(0x2d, pass_count) 501 LATRACE(0x2e, clkdmax) 502 LATRACE(0x2f, strdmax) 503 LATRACE(0x30, strmmax) 504 505nextstrd: 506 addi strd,strd,1 507 blt strd,STRDLIM,strdloop 508 nop 509 510nextstrm: 511 addi strm,strm,1 512 blt strm,STRMLIM,strmloop 513 nop 514 515 /* All done, program the new ncdl values */ 516 517 LATRACE(0x31, pass_count) 518 LATRACE(0x32, clkdmax) 519 LATRACE(0x33, strdmax) 520 LATRACE(0x34, strmmax) 521 522 beqz pass_countmax,1f 523 nop 524 525 move clkd,clkdmax 526 move strd,strdmax 527 move strm,strmmax 528 b sdr_got_ncdl 529 nop 530 531 /* No passing values, panic! (use defaults) */ 5321: 533 li t3,MEMC_SDR1_NCDL # If rev1: 534 beq v1,1,2f 535 nop 536 # rev0, 2: 537 li t3,MEMC_SDR_NCDL 5382: 539 540break_sdr_ncdl: 541 TRACE(0x425335) 542 andi t4,t3,0xff # t4: cd 543 srl t2,t3,16 # t2: sm 544 andi t2,t2,3 # sm is 2 bits only 545 srl t3,t3,8 # t3: sd 546 andi t3,t3,0xf # sd is 4 bits 547 548sdr_got_ncdl: 549 bal sdr_do_init 550 nop 551 552 /* Change the memory priority inversion counter value */ 553 /* If an SOCRAM, determine memory size and return */ 554memprio_szmem: 555 TRACE(0x425337) 556 557#ifdef APPLE 558 lw t0, MEMC_PRIORINV(a0) 559 li t1, 0xFFFF0000 560 and t0, t0, t1 561 ori t0, t0, 0x1 562 sw t0, MEMC_PRIORINV(a0) 563#else 564 li t0,KSEG1ADDR(SI_ENUM_BASE) # is there a chipcommon core? 565 lw t1,(SBCONFIGOFF + SBIDHIGH)(t0) 566 and t1,t1,SBIDH_CC_MASK 567 srl t1,t1,SBIDH_CC_SHIFT 568 bne t1,CC_CORE_ID,0f 569 nop 570 lw t1,CC_CHIPID(t0) # is this BCM4785 chip? 571 and t1,t1,CID_ID_MASK 572 bne t1,BCM4785_CHIP_ID,0f 573 nop 574 lw t0,MEMC_PRIORINV(a0) # change PriorInvTim to 2 575 and t0,t0,0xFFFF0000 576 ori t0,t0,0x02 577 sw t0,MEMC_PRIORINV(a0) 578#endif 5790: TRACE(0x425338) 580 lw t0,(SBCONFIGOFF + SBIDHIGH)(a0) 581 and t1,t0,SBIDH_CC_MASK 582 srl t1,t1,SBIDH_CC_SHIFT 583 beq t1,SOCRAM_CORE_ID,1f 584 nop 585 jr t6 586 li v0,0 587 588 /* The socram core tells us how much memory there is */ 5891: TRACE(0x425339) 590 lw t1,SR_COREINFO(a0) 591 and t0,t0,SBIDH_RC_MASK /* Find corerev */ 592 beq t0,zero,crev0 593 594 /* Its corerev >= 1 */ 595 and t2,t1,SRCI_SRNB_MASK /* Find number of blocks */ 596 srl t2,t2,SRCI_SRNB_SHIFT 597 and t1,t1,SRCI_SRBSZ_MASK /* Find block size */ 598 addi t1,t1,SR_BSZ_BASE 599 li t0,1 600 sll t0,t0,t1 601 mul v0,t0,t2 602 jr t6 603 nop 604 605crev0: 606 and t1,t1,SRCI_MS0_MASK 607 add t1,t1,SR_MS0_BASE 608 li v0,1 609 sll v0,v0,t1 610 jr t6 611 nop 612 613 /* 614 * Test memory 615 * 616 * Uses arg in t2(wr/sd), t3(rd/sm) and t4(g/clkd) 617 * Returns success (1) or failure (0) in v0 618 * Uses a1, a2, a3 & t5 619 */ 620test_mem: 621 /* Use t4 to generate a semi-random address in the second KB */ 622 li a1,KSEG1 623 addi a2,t4,255 624 sll a2,a2,2 625 add a1,a1,a2 626 627 /* First set: 0 & its negation */ 628 li a2,0 629 sw a2,0(a1) 630 not a3,a2 631 sw a3,4(a1) 632 nop 633 lw t5,0(a1) 634 bne a2,t5,bad_mem 635 nop 636 637 lw t5,4(a1) 638 bne a3,t5,bad_mem 639 nop 640 641 /* Second set: 0xaaaaaaaa & its negation */ 642 li a2,0xaaaaaaaa 643 sw a2,0(a1) 644 not a3,a2 645 sw a3,4(a1) 646 nop 647 lw t5,0(a1) 648 bne a2,t5,bad_mem 649 nop 650 651 lw t5,4(a1) 652 bne a3,t5,bad_mem 653 nop 654 655 /* Third set: 0x12345678 & its negation */ 656 li a2,0x12345678 657 sw a2,0(a1) 658 not a3,a2 659 sw a3,4(a1) 660 nop 661 lw t5,0(a1) 662 bne a2,t5,bad_mem 663 nop 664 665 lw t5,4(a1) 666 bne a3,t5,bad_mem 667 nop 668 669 /* Fourth set: the ncdl & its negation */ 670 sll a2,t2,8 671 or a2,t3 672 sll a2,a2,8 673 or a2,t4 674 sw a2,0(a1) 675 not a3,a2 676 sw a3,4(a1) 677 nop 678 lw t5,0(a1) 679 bne a2,t5,bad_mem 680 nop 681 682 lw t5,4(a1) 683 bne a3,t5,bad_mem 684 nop 685 686 /* Fifth set: the CPU count register & its negation */ 687 mfc0 a2,$9 688 sw a2,0(a1) 689 not a3,a2 690 sw a3,4(a1) 691 nop 692 lw t5,0(a1) 693 bne a2,t5,bad_mem 694 nop 695 696 lw t5,4(a1) 697 bne a3,t5,bad_mem 698 nop 699 700 jr ra 701 li v0,1 702 703bad_mem: 704 jr ra 705 li v0,0 706 707 708 /* Do an init of the memc core for ddr 709 * a0: memc core pointer 710 * t0: memc config value 711 * t1: memc mode value 712 * t2: memc wr ncdl value 713 * t3: memc rd ncdl value 714 * t4: memc g ncdl value 715 * 716 * Uses a1, a2, t7, t8, t9 (here and by calling sb_core_reset) 717 */ 718ddr_do_init: 719 TRACE(0x42533a) 720 721 /* Save return address */ 722 move t7,ra 723 724 bal sb_core_reset 725 li a1,0 726 727 li a1,MEMC_CONFIG_INIT 728 or a1,a1,t0 729 lui a2, 0x8 # set DQMGate for memc rev 4 or more 730 or a1, a1, a2 731 sw a1,MEMC_CONFIG(a0) 732 733 li a1,MEMC_DRAMTIM25_INIT # Assume CAS latency of 2.5 734 andi t8,t1,0xf0 # Find out the CAS latency 735 bne t8,0x20,1f 736 nop 737 li a1,MEMC_DRAMTIM2_INIT # CAS latency is 2 7381: 739 sw a1,MEMC_DRAMTIM(a0) 740 741#ifndef BCM_ATE 742 li t8,KSEG1ADDR(SI_ENUM_BASE) # Get package options 743 lw a1,CC_CHIPID(t8) # Get chipid 744 li t9,CID_PKG_MASK # Check package options 745 and a1,a1,t9 746 srl a1,a1,CID_PKG_SHIFT 747 addi t8,SBCONFIGOFF # Get corerev for chipcommon 748 lw a2,SBIDHIGH(t8) 749 li t8,SBIDH_RCE_MASK 750 and t8,t8,a2 751 srl t8,SBIDH_RCE_SHIFT 752 li t9,SBIDH_RC_MASK 753 and t9,t9,a2 754 or t8,t8,t9 755 bge t8,10,1f # If ccrev is >= 10 use 4bit pkg opt 756 nop 757 ori a1,8 # else add a bit to the 3bit field 7581: 759 beq a1,HDLSIM_PKG_ID,hdlsim # Special case for hdl sim: 760 nop 761 762 li t8,KSEG1ADDR(SI_ENUM_BASE) # Get chipid again 763 lw a2,CC_CHIPID(t8) 764 li t9,BCM5350_CHIP_ID # 5350 ChipID 765 li t8,CID_ID_MASK 766 and t8,t8,a2 767 bne t8,t9,notsim # if not 5350keep going 768 nop 769 770 bne a1,(8 | HDLSIM5350_PKG_ID),notsim # If 5350, is it (3/4-bit) vsim? 771 nop 772#endif /* !BCM_ATE */ 773 774hdlsim: 775 li a1,MEMC_RDNCDLCOR_SIMINIT # Fixed 0xf6 rdncdl and no inits 776 sw a1,MEMC_RDNCDLCOR(a0) # of wrncdl, dqsgate and miscdly. 777 778#ifndef BCM_ATE 779 b simskip 780 nop 781 782notsim: andi t8,t3,0xff 783 sll a1,t8,8 # Replicate rd ncdl 4 times 784 or a1,a1,t8 785 sll t8,a1,16 786 or t8,t8,a1 787 li a1,MEMC_RDNCDLCOR_INIT 788 or a1,a1,t8 789 sw a1,MEMC_RDNCDLCOR(a0) 790 791 li a1,MEMC_1_WRNCDLCOR_INIT # If rev1: 792 beq v1,1,1f 793 nop 794 # rev0, 2 795 li a1,MEMC_WRNCDLCOR_INIT 7961: 797 andi t8,t2,0xff 798 or a1,a1,t8 799 sw a1,MEMC_WRNCDLCOR(a0) 800 801 li a1,MEMC_DQSGATENCDL_INIT 802 andi t8,t4,0xff 803 or a1,a1,t8 804 sw a1,MEMC_DQSGATENCDL(a0) 805 806 li a1,MEMC_1_MISCDLYCTL_INIT # If rev1: 807 beq v1,1,2f 808 nop 809 # rev0,2 810 li a1,MEMC_MISCDLYCTL_INIT 8112: 812 sw a1,MEMC_MISCDLYCTL(a0) 813#endif /* !BCM_ATE */ 814 815simskip: 816 li a1,MEMC_NCDLCTL_INIT 817 sw a1,MEMC_NCDLCTL(a0) 818 819 li a1,MEMC_CONTROL_INIT0 820 sw a1,MEMC_CONTROL(a0) 821 822 li a1,MEMC_CONTROL_INIT1 823 sw a1,MEMC_CONTROL(a0) 824 825 li a1,MEMC_MODEBUF_INIT0 826 sw a1,MEMC_MODEBUF(a0) 827 828 li a1,MEMC_CONTROL_INIT2 829 sw a1,MEMC_CONTROL(a0) 830 831 li a1,MEMC_MODEBUF_INIT1 832 or a1,a1,t1 833 sw a1,MEMC_MODEBUF(a0) 834 835 li a1,MEMC_CONTROL_INIT3 836 sw a1,MEMC_CONTROL(a0) 837 838 li a1,MEMC_CONTROL_INIT4 839 sw a1,MEMC_CONTROL(a0) 840 841 li a1,MEMC_CONTROL_INIT5 842 sw a1,MEMC_CONTROL(a0) 843 lw a1,MEMC_CONTROL(a0) 844 lw a1,MEMC_CONTROL(a0) 845 lw a1,MEMC_CONTROL(a0) 846 847 li a1,MEMC_CONTROL_INIT5 848 sw a1,MEMC_CONTROL(a0) 849 lw a1,MEMC_CONTROL(a0) 850 lw a1,MEMC_CONTROL(a0) 851 lw a1,MEMC_CONTROL(a0) 852 853 li a1,MEMC_REFRESH_INIT 854 sw a1,MEMC_REFRESH(a0) 855 856 li a1,MEMC_MODEBUF_INIT2 857 or a1,a1,t1 858 sw a1,MEMC_MODEBUF(a0) 859 860 li a1,MEMC_CONTROL_INIT6 861 sw a1,MEMC_CONTROL(a0) 862 863 li a1,MEMC_CONTROL_INIT7 864 sw a1,MEMC_CONTROL(a0) 865 866 /* Wait for SDRAM controller to refresh. 867 * We want 8uS delay. 868 */ 869 li t8,50 8701: lw a1,(SBCONFIGOFF + SBIDLOW)(a0) 871 lw a1,(SBCONFIGOFF + SBIDHIGH)(a0) 872 873 bnez t8,1b 874 subu t8,1 875 876 jr t7 877 nop 878 879 /* Do an init of the memc core for sdr 880 * a0: memc core pointer 881 * t0: memc config value 882 * t1: memc mode value 883 * t2: memc strobe mode ncdl value 884 * t3: memc strobe delay ncdl value 885 * t4: memc clock delay ncdl value 886 * 887 * Uses a1, t7, t8, t9 (here and by calling sb_core_reset) 888 */ 889sdr_do_init: 890 TRACE(0x42533b) 891 892 /* Save return address */ 893 move t7,ra 894 895 bal sb_core_reset 896 li a1,0x40 897 898 /* Initialize for SDR SDRAM */ 899 li a1,MEMC_SD_CONFIG_INIT 900 or a1,a1,t0 901 sw a1,MEMC_CONFIG(a0) 902 903 li a1,MEMC_SD_DRAMTIM3_INIT # Assume CAS latency of 3 904 andi t8,t1,0xf0 # Find out the CAS latency 905 bne t8,0x20,1f 906 nop 907 li a1,MEMC_SD_DRAMTIM2_INIT # CAS latency is 2 9081: 909 sw a1,MEMC_DRAMTIM(a0) 910 911 andi t8,t4,0xff 912 ble t8,MEMC_CD_THRESHOLD,1f # if (cd <= MEMC_CD_THRESHOLD) rd = cd 913 nop 914 915 li t8,MEMC_CD_THRESHOLD # else rd = MEMC_CD_THRESHOLD 916 9171: # t8 is now rd 918 sll a1,t8,8 # .. replicate it 4 times 919 or a1,a1,t8 920 sll t8,a1,16 921 or t8,t8,a1 922 li a1,MEMC_SD_RDNCDLCOR_INIT 923 or a1,a1,t8 924 sw a1,MEMC_RDNCDLCOR(a0) 925 926 li a1,MEMC_SD1_WRNCDLCOR_INIT # rev1 927 beq v1,1,1f 928 nop 929 930 li a1,MEMC_SD_WRNCDLCOR_INIT # rev0, 2 9311: 932 li t8,0 933 ble t4,MEMC_CD_THRESHOLD,2f # if (cd <= MEMC_CD_THRESHOLD) wr = 0 934 nop 935 936 andi t8,t4,0xff # else wr = cd - MEMC_CD_THRESHOLD 937 sub t8,t8,MEMC_CD_THRESHOLD 938 andi t8,t8,0xff 939 9402: # t8 is now wr, a0 is extra bits 941 or a1,a1,t8 942 sw a1,MEMC_WRNCDLCOR(a0) 943 944 andi t8,t2,3 945 sll a1,t8,28 946 andi t8,t3,0xf 947 sll t8,t8,24 948 or t8,t8,a1 949 li a1,MEMC_SD1_MISCDLYCTL_INIT 950 beq v1,1,3f # If rev1: 951 nop 952 # rev0, 2: 953 li a1,MEMC_SD_MISCDLYCTL_INIT 9543: 955 or a1,a1,t8 956 sw a1,MEMC_MISCDLYCTL(a0) 957 958 li a1,MEMC_SD_CONTROL_INIT0 959 sw a1,MEMC_CONTROL(a0) 960 961 li a1,MEMC_SD_CONTROL_INIT1 962 sw a1,MEMC_CONTROL(a0) 963 964 li a1,MEMC_SD_CONTROL_INIT2 965 sw a1,MEMC_CONTROL(a0) 966 lw a1,MEMC_CONTROL(a0) 967 lw a1,MEMC_CONTROL(a0) 968 lw a1,MEMC_CONTROL(a0) 969 970 li a1,MEMC_SD_CONTROL_INIT2 971 sw a1,MEMC_CONTROL(a0) 972 lw a1,MEMC_CONTROL(a0) 973 lw a1,MEMC_CONTROL(a0) 974 lw a1,MEMC_CONTROL(a0) 975 976 li a1,MEMC_SD_CONTROL_INIT2 977 sw a1,MEMC_CONTROL(a0) 978 lw a1,MEMC_CONTROL(a0) 979 lw a1,MEMC_CONTROL(a0) 980 lw a1,MEMC_CONTROL(a0) 981 982 li a1,MEMC_SD_REFRESH_INIT 983 sw a1,MEMC_REFRESH(a0) 984 985 li a1,MEMC_SD_MODEBUF_INIT 986 or a1,a1,t1 987 sw a1,MEMC_MODEBUF(a0) 988 989 li a1,MEMC_SD_CONTROL_INIT3 990 sw a1,MEMC_CONTROL(a0) 991 992 li a1,MEMC_SD_CONTROL_INIT4 993 sw a1,MEMC_CONTROL(a0) 994 995 li t8,50 9961: lw a1,(SBCONFIGOFF + SBIDLOW)(a0) 997 lw a1,(SBCONFIGOFF + SBIDHIGH)(a0) 998 bnez t8,1b 999 subu t8,1 1000 1001 jr t7 1002 nop 1003 1004 1005 /* Special sb_core_reset that makes sure the first time 1006 * clock is enabled, address line 6 is in the state specified 1007 * by a1. 1008 * 1009 * a0: Core pointer 1010 * a1: 0x40 if a6 needs to be 1, 0 otherwise 1011 * uses t8, t9 1012 */ 1013 1014 .align 6 1015 1016sb_core_reset: 1017 1018 /* Save return address */ 1019 move t9,ra 1020 1021 /* run uncached */ 1022 bal kseg1_switch 1023 nop 1024 1025 /* Figure out our address */ 1026 bal h0 1027 nop 1028h0: add t8,ra,24 # This is (h1 - h0) 1029 andi t8,t8,0x40 1030 bne t8,a1,alt_core_reset 1031 nop 1032 1033 /* Set reset while enabling the clock */ 1034 li t8,(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET) 1035h1: sw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1036 b cont 1037 nop 1038 1039 /* Now pad to 0x40: We want (h2 - h1) == 0x40 and there 1040 * are 5 instructions inbetween them. 1041 */ 1042 .space (0x40 - 20) 1043 1044alt_core_reset: 1045 /* Set reset while enabling the clock */ 1046 li t8,(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET) 1047h2: sw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1048 1049cont: 1050 /* Read back and delay */ 1051 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1052 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1053 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1054 1055 /* Clear reset */ 1056 li t8,((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) 1057 sw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1058 1059 /* Read back and delay */ 1060 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1061 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1062 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1063 1064 /* Leave clock enabled */ 1065 li t8,(SICF_CLOCK_EN << SBTML_SICF_SHIFT) 1066 sw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1067 1068 /* Read back and delay */ 1069 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1070 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1071 lw t8,(SBCONFIGOFF + SBTMSTATELOW)(a0) 1072 1073 jr t9 1074 nop 1075 1076 1077kseg1_switch: 1078 and ra,ra,PHYSADDR_MASK 1079 or ra,ra,KSEG1 1080 jr ra 1081 nop 1082 1083 .set reorder 1084 END(sb_draminit) 1085