2 * BCM47XX Denali based memory controller initialization
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
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.
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.
18 * $Id: aisdram.S,v 1.26.10.9 2011-01-20 04:28:14 Exp $
27 #include <dmemc_core.h>
28 #include <amemc_core.h>
31 #if defined(NFLASH_SUPPORT)
38 /* Debug macro - write a number to a chipc reg - use it with caution,
39 * it changes k0 and k1 registers.
43 #if defined(IL_BIGENDIAN) && defined(BCMHND74K)
51 #define TRACEINIT(x) \
52 li k0,KSEG1ADDR(0x18000040); \
117 .word DMEMC_TABLE_END
136 .word 127, 0x00000001
137 .word 128, 0x07000300
138 .word 130, 0x00010103
139 .word 131, 0x00000200
140 .word 133, 0x06120000
141 .word 134, 0x06120612
142 .word 135, 0x06120612
143 .word 136, 0x00000612
144 .word 137, 0x00000032
145 .word 140, 0x001f4008
146 .word 141, 0x001f4008
147 .word 142, 0x002ee004
148 .word 143, 0x002ee004
149 .word 146, 0x000f0033
150 .word 147, 0xf4113c17
151 .word 148, 0xf4113c17
152 .word 149, 0x26c00300
153 .word 150, 0x26c00300
154 .word DMEMC_TABLE_END
173 .word 127, 0x00000002
174 .word 128, 0x07000404
175 .word 130, 0x03020304
176 .word 131, 0x00000400
177 .word 133, 0x081b0000
178 .word 134, 0x081b081b
179 .word 135, 0x081b081b
180 .word 136, 0x0000081b
181 .word 137, 0x00400642
182 .word 140, 0x00164008
183 .word 141, 0x00164008
184 .word 142, 0x00236004
185 .word 143, 0x00236004
186 .word 146, 0x000f0133
187 .word 147, 0xf4112c17
188 .word 148, 0xf4112c17
189 .word 149, 0x26c00300
190 .word 150, 0x26c00300
191 .word DMEMC_TABLE_END
193 #if defined(NFLASH_SUPPORT)
195 /* page size mapping */
196 .word 0x200, 0x800, 0x1000, 0x2000
199 /* block size mapping */
200 .word 0x4000, 0x20000, 0x2000, 0x80000, 0x40000, 0, 0, 0
203 /* Register conventions.
204 * Inherited from sisdram.S:
206 * s5 = Relocation factor
210 * s0 = sdram_config + sdram_refresh values
212 * s3 = Controller corerev
213 * s4 = Controller coreid
216 * a2 = dmemc DMP regs
217 * a3 = memory type (sdr,ddr1,ddr2)
228 /* Scan for a Denali DDR controller (a0) */
230 li t0,KSEG1 # t0 = KSEG1
231 or a0,a0,t0 # a0 points to the EROM
234 #if defined(IL_BIGENDIAN) && defined(BCMHND74K)
241 lw t0,0(a0) # t0 = CIA
242 lw t3,4(a0) # t3 = CIB
256 and s4,t0,CIA_CID_MASK
257 srl s4,s4,CIA_CID_SHIFT # s4 has controler coreid
259 beq s4,DMEMC_CORE_ID,founddmemc
262 beq s4,DMEMS_CORE_ID,founddmemc
265 beq s4,AMEMC_CORE_ID,founddmemc
269 addi a0,8 # Skip CIB too
271 /* No DMEMC controller found */
272 noctrl: TRACE(0x415307)
279 /* If we found the controller, but we are already in RAM, there is nothing
280 * to do. This will change if/when we have an AI chip with MIPS and
283 bnez s5,1f # Not running from RAM, go ahead
286 jr t6 # Return with 0 rc.
289 /* We'll cheat a little: memory controllers don't have master ports, so
290 * the EROM entry right after the CIDs is the slave port for the registers
293 #if defined(IL_BIGENDIAN) && defined(BCMHND74K)
302 li t0,KSEG1 # t0 = KSEG1
303 or a1,a1,t0 # a1: dmemc regs
304 /* after that, the first slave wrapper will be its DMP registers */
307 #if defined(IL_BIGENDIAN) && defined(BCMHND74K)
319 addesc: and t1,t0,AD_ST_MASK
320 beq t1,AD_ST_SWRAP,swrap
326 li t0,KSEG1 # t0 = KSEG1
327 or a2,a2,t0 # a2: dmemc DMP regs
329 /* Got our core, reset it */
334 /* Get package option for later */
338 srl s1,t0,CID_PKG_SHIFT # s1 = package opt
340 /* Find out the type of memory from the straps */
341 /* Corerevs 0 & 1 did not have this register, so we have to
342 * check the corerev and use chipstatus for those two.
344 and t3,t3,CIB_REV_MASK
345 srl s3,t3,CIB_REV_SHIFT # s3 = core revision
346 beq s4,DMEMS_CORE_ID,1f
349 /* Go find nvram if the controller is AMEMC. */
350 beq s4,AMEMC_CORE_ID,find_nvram
356 1: /* Not a 4716/47162 (a0?) read the stat register */
359 and a3,t0,t1 # a3 == 4 if ddr2, 2 if ddr1, 1 if sdr.
363 /* Check chipc: chipstatus for the ddr1/ddr2 strapping option */
364 is16x: TRACE(0x41530b)
373 /* Read sdram_config from nvram */
376 li t0,KSEG1ADDR(SI_FLASH2 - NVRAM_SPACE)
381 #if defined(NFLASH_SUPPORT)
382 /* Take care of 5357 NAND boot */
385 bne t4,BCM5357_CHIP_ID,1f
400 /* skip bad blocks and locate nvram */
401 move t1,v0 # block size
406 move a1,v1 # page size
411 move a1,t0 # restore a1
415 li t0,KSEG1ADDR(SI_FLASH1)
418 beq t3,t5,read_config
431 beq t3,t5,read_config
438 #if defined(NFLASH_SUPPORT)
441 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
443 li t4,KSEG1ADDR(SI_FLASH1 + 0x1000)
445 beq t3,t5,read_config
449 li t4,KSEG1ADDR(SI_FLASH1 + 0x400)
451 beq t3,t5,read_config
454 /* No nvram, pick sone defaults */
456 /* assume DDRM16MX16 if ddr1 */
458 bne a3,DM_STAT_DDR1,1f
461 beq s4,DMEMC_CORE_ID,init_dmemc
462 li s0,0x283 # Value for dmemc
464 /* Use DDR1M16MX16 if QT and DDR1M32MX16 otherwise */
465 beq s1,HWSIM_PKG_ID,init_dmemc
466 li s0,0x103 # Value for dmems
469 li s0,0x003 # Value for dmems at 200MHz
471 1: beq a3,DM_STAT_SDR,init_dmemc
472 li s0,0x002 # Value for SDR
474 /* For ddr2, use DDR2M32X16X2 if QT and DDR2M128X16X2 otherwise */
475 beq s1,HWSIM_PKG_ID,init_dmemc
482 /* sdram_config is a 16bit value 12 bytes inside the nvram hdr.
483 * Currently it is defined as:
484 * 10:8 column_size as per control13
485 * 7 reduc i.e. memory is half the width of the controller
492 * 7:0 clk_wr_delay, or clk_wr_delay_0 (for corerev >= 2)
494 * sdram_ncdl: control22
495 * 31:24 clk_dqs_delay, or clk_wr_delay_1 (for corerev >= 2)
501 lw s0,12(t4) # Pick up sdram_config & sdram_refresh
503 /* Determine if it is DMEMC or AMEMC */
504 bne s4,AMEMC_CORE_ID,init_dmemc
505 lw s8,16(t4) # Pick up sdram_ncdl
507 /* Initailize AMEMC */
516 /* Initialize DMEMC/DMEMS */
518 /* For DDR2, init pvt controller */
519 bne a3,DM_STAT_DDR2,init_regs
524 sw t0,DMEMC_PVTGROUPJ(a1)
525 sw zero,DMEMC_PVTGROUPA(a1)
526 sw t0,DMEMC_PVTGROUPA(a1)
528 /* Init the common regs */
532 bal dmemc_init_regs # dmemc_init_regs(a0): Inits from the table @ a0
536 beq a3,DM_STAT_SDR,1f
541 beq a3,DM_STAT_DDR1,1f
546 1: bal dmemc_init_regs
549 /* Fixup differences between dmems & dmemc */
550 fixs: bne s4,DMEMS_CORE_ID,fix2
554 beq a3,DM_STAT_SDR,1f
558 sw t0,DMEMC_CONTROL21(a1)
559 li t0,0x7f000018 # DLL DQS delay for DDR1
560 sw t0,DMEMC_CONTROL22(a1)
562 sw t0,DMEMC_CONTROL23(a1)
563 li t0,0x00320000 # Change MRS data for DDR1
564 sw t0,DMEMC_CONTROL32(a1)
568 1: sw t0,DMEMC_CONTROL52(a1)
570 sw t0,DMEMC_CONTROL53(a1)
572 /* Fixup differences in 47162 */
573 fix2: li t0,CID_ID_MASK
575 bne t0,BCM47162_CHIP_ID,nvover
579 sw t0,DMEMC_CONTROL21(a1)
581 sw t0,DMEMC_CONTROL23(a1)
583 /* Presumaby this is for DDR1 only? */
585 sw t0,DMEMC_CONTROL22(a1)
587 /* Override the dll delays from nvram if provided */
588 nvover: beqz s8,chhalf
591 # Check for dmems (any rev)
592 beq s4,DMEMS_CORE_ID,old_ncdl
600 and t0,t0,s0 # delay_dqs_0
602 lw t1,DMEMC_CONTROL140(a1)
606 sw t0,DMEMC_CONTROL140(a1)
609 and t0,t0,s8 # delay_dqs_1
611 lw t1,DMEMC_CONTROL141(a1)
614 sw t0,DMEMC_CONTROL141(a1)
617 and t0,t0,s0 # clk_wr_delay_0
619 lw t1,DMEMC_CONTROL142(a1)
623 sw t0,DMEMC_CONTROL142(a1)
626 and t0,t0,s8 # clk_wr_delay_1
628 lw t1,DMEMC_CONTROL143(a1)
631 sw t0,DMEMC_CONTROL143(a1)
638 and t0,t0,s0 # delay_dqs_0
640 sw t0,DMEMC_CONTROL21(a1)
642 and t0,t0,s0 # clk_wr_delay
643 sw t0,DMEMC_CONTROL23(a1)
645 sw s8,DMEMC_CONTROL22(a1)
647 /* Check for half-width */
654 /* Set reduc bit if half-wide */
656 lw t0,DMEMC_CONTROL08(a1)
659 sw t0,DMEMC_CONTROL08(a1)
661 /* Check for 8-bank DDRs */
668 /* Change regs for 8-bank DDRs */
670 lw t0,DMEMC_CONTROL05(a1)
673 sw t0,DMEMC_CONTROL05(a1)
675 lw t0,DMEMC_CONTROL19(a1)
678 sw t0,DMEMC_CONTROL19(a1)
680 lw t0,DMEMC_CONTROL24(a1)
685 sw t0,DMEMC_CONTROL24(a1)
687 lw t0,DMEMC_CONTROL34(a1)
692 sw t0,DMEMC_CONTROL34(a1)
694 /* Set the right value for column size and CAS latency */
699 sw t0,DMEMC_CONTROL13(a1)
700 andi t0,s0,7 # Isolate cas
701 beq s4,DMEMS_CORE_ID,setcaslin
705 /* Additional settings required for dmemc rev >= 2 */
708 bne a3,DM_STAT_DDR1,1f
711 1: lw t2,DMEMC_CONTROL128(a1)
714 sw t2,DMEMC_CONTROL128(a1)
716 lw t2,DMEMC_CONTROL137(a1)
719 sw t2,DMEMC_CONTROL137(a1)
720 bne a3,DM_STAT_DDR2,setcaslin
724 lw t2,DMEMC_CONTROL130(a1)
727 sw t2,DMEMC_CONTROL130(a1)
729 lw t2,DMEMC_CONTROL15(a1)
732 sw t2,DMEMC_CONTROL15(a1)
734 /* Set caslat_lin and caslat_lin_gate */
735 lw t2,DMEMC_CONTROL16(a1)
736 /* Take care of fractional CAS latencies for DDR1 */
738 bne a3,DM_STAT_DDR1,1f
743 andi t0,t0,3 # take off half bit
747 addi t1,t0,1 # + 1 => caslin
750 addi t0,t0,-1 # and -1 => caslin_gate
753 sw t2,DMEMC_CONTROL16(a1)
755 /* Finally set bypass mode if needed, but always for quickturn */
756 ckbyp: beq s1,HWSIM_PKG_ID,dobypass
766 beq s4,DMEMS_CORE_ID,1f
773 beq a3,DM_STAT_SDR,2f
777 beq a3,DM_STAT_DDR1,2f
782 2: sw t0,DMEMC_CONTROL25(a1)
783 beq s4,DMEMS_CORE_ID,3f
785 sw t0,DMEMC_CONTROL26(a1)
787 3: lw t0,DMEMC_CONTROL28(a1)
790 sw t0,DMEMC_CONTROL28(a1)
792 4: lw t0,DMEMC_CONTROL29(a1)
797 sw t0,DMEMC_CONTROL29(a1)
799 lw t0,DMEMC_CONTROL05(a1)
802 sw t0,DMEMC_CONTROL05(a1)
804 beq s4,DMEMS_CORE_ID,ckvsim
810 lw t0,DMEMC_CONTROL140(a1)
813 sw t0,DMEMC_CONTROL140(a1)
815 lw t0,DMEMC_CONTROL141(a1)
817 sw t0,DMEMC_CONTROL141(a1)
819 /* For vsim change tinit so sims run faster */
820 ckvsim: bne s1,HDLSIM_PKG_ID,turnon
825 sw t0,DMEMC_CONTROL36(a1)
828 /* We are ready, turn controller on */
830 lw t0,DMEMC_CONTROL09(a1) # Read current control09 reg
831 or t0,t0,DMC09_START # Add start bit
832 sw t0,DMEMC_CONTROL09(a1) # Start the controller
834 beq s4,DMEMS_CORE_ID,2f
840 1: lw t0,DMEMC_CONTROL133(a1) # Poll for INT_INIT_DONE (dmemc >=2)
841 and t1,t0,DM_INT_INIT_DONE
844 /* Bypass mode programming */
845 lw t0,DMEMC_CONTROL05(a1)
850 lw t1,DMEMC_CONTROL144(a1)
852 lw t2,DMEMC_CONTROL140(a1)
857 sw t2,DMEMC_CONTROL140(a1)
859 lw t2,DMEMC_CONTROL142(a1)
868 sw t2,DMEMC_CONTROL142(a1)
870 lw t1,DMEMC_CONTROL145(a1)
872 lw t2,DMEMC_CONTROL141(a1)
877 sw t2,DMEMC_CONTROL141(a1)
879 lw t2,DMEMC_CONTROL143(a1)
888 sw t2,DMEMC_CONTROL143(a1)
890 /* Clear any pending interrupts from dmemc */
891 li t1,DMC132_INTACK_MASK
892 and t0,t0,t1 # t0 = control133 & mask
893 lw t2,DMEMC_CONTROL132(a1)
895 and t2,t1,t2 # t2 = control132 & ~mask
896 or t0,t0,t2 # Or them and ...
897 sw t0,DMEMC_CONTROL132(a1) # Ack all ints
901 2: lw t0,DMEMC_CONTROL24(a1) # Poll for INT_INIT_DONE (dmems & dmemc<2)
902 and t1,t0,DM_INT_INIT_DONE
905 /* Clear any pending interrupts from dmemc */
906 li t1,DMC23_INTACK_MASK
907 and t0,t0,t1 # t0 = control24 & mask
908 lw t2,DMEMC_CONTROL23(a1)
910 and t2,t1,t2 # t2 = control23 & ~mask
911 or t0,t0,t2 # Or them and ...
912 sw t0,DMEMC_CONTROL23(a1) # Ack all ints
917 /* Reset core using DMP regs at (a2) */
919 /* Set reset while enabling the clock */
920 li t9,(SICF_FGC | SICF_CLOCK_EN)
922 sw t9,AI_IOCTRLSET(a2)
923 sw t8,AI_RESETCTRL(a2)
925 /* Read back and delay */
926 lw t8,AI_RESETCTRL(a2)
927 lw t8,AI_RESETCTRL(a2)
928 lw t8,AI_RESETCTRL(a2)
932 sw t8,AI_RESETCTRL(a2)
934 /* Read back and delay */
935 lw t8,AI_RESETCTRL(a2)
936 lw t8,AI_RESETCTRL(a2)
937 lw t8,AI_RESETCTRL(a2)
939 /* Clear Force Gated Clock */
941 sw t9,AI_IOCTRLCLEAR(a2)
943 /* Read back and delay */
951 /* Use table at (a0) to init dmemc regs.
952 * Assumes (a1) points to the regs.
955 beq s4,DMEMS_CORE_ID,loop_regs
964 add a0,a0,s5 # Relocate address
965 li t0,DMEMC_TABLE_END
966 1: lw t1,0(a0) # Pick up reg num
967 bge t1,t3,2f # Return if the reg num >= num of supported regs
969 beq t1,t0,2f # Return if done
972 lw t2,4(a0) # Get reg value
973 sll t1,2 # Reg num * 4 is reg offset
975 #if defined(IL_BIGENDIAN) && defined(BCMHND74K)
978 sw t2,0(t1) # Write reg
987 #if defined(NFLASH_SUPPORT)
989 lw t9,CC_NAND_CONFIG(s2)
993 srl t8,18 # index = (ncf & (0x3 << 20) >> 18)
995 add a0,a0,s5 # Relocate address
1002 srl t8,26 # index = (ncf & (0x7 << 28) >> 26)
1004 add a0,a0,s5 # Relocate address
1012 LEAF(nfl_check_badb)
1016 sw t9,CC_NAND_CMD_ADDR(s2)
1017 lw t9,CC_NAND_CMD_ADDR(s2) # read back
1019 sw t9,CC_NAND_CMD_START(s2)
1020 lw t9,CC_NAND_CMD_START(s2) # read back
1022 li t9,NIST_CTRL_READY
1023 li t8,NIST_FLASH_READY
1025 1: lw t8,CC_NAND_INTFC_STATUS(s2)
1029 /* Check spare valid */
1030 li t9,NIST_SPARE_VALID
1034 /* Check spare byte */
1035 lw t9,CC_NAND_SPARE_RD_0(s2)
1040 /* Read next page */
1043 beq t5,1,check_spare
1054 /* *********************************************************************
1057 * AI version of DDR / memory controller initialization
1059 * This routine deals with DDR23_PHY and PL341 MEMC.
1061 ********************************************************************* */
1062 /* Convenient macro for writing registers (use t0 for base) */
1063 #define ddr_write(offset, value) \
1074 li t0, KSEG1ADDR(AI_DDRPHY_BASE)
1076 #ifndef CFG_QUICKTURN
1082 /* Do recalibration */
1083 beq t5, PVT_MAX_RETRY, 9f
1084 lw t7, DDR23PHY_ZQ_PVT_COMP_CTL(t0)
1085 ddr_write(DDR23PHY_ZQ_PVT_COMP_CTL, 0x04000000);
1087 /* Wait until sample_done == 1 */
1088 lw t1, DDR23PHY_ZQ_PVT_COMP_CTL(t0)
1093 /* Increase total retry count */
1096 /* Check if the result is the same as previous one */
1097 lw t1, DDR23PHY_ZQ_PVT_COMP_CTL(t0)
1101 /* If not, clear matched count */
1105 /* If so, increase matched count; continue if matched count == 3 */
1107 bne t3, PVT_MATCHED_COUNT, 2b
1112 ddr_write(DDR23PHY_PLL_CONFIG, 0x8000000c);
1113 ddr_write(DDR23PHY_PLL_PRE_DIVIDER,
1114 0x00000011 + (PLL_NDIV_INT_VAL << 8));
1115 ddr_write(DDR23PHY_PLL_DIVIDER, 0x02000000);
1116 ddr_write(DDR23PHY_PLL_CONFIG, 0x80000008);
1118 /* Wait for PLL locked */
1120 1: /* Wait until lock == 1 */
1121 lw t1, DDR23PHY_PLL_STATUS(t0)
1126 /* De-assert PLL reset */
1127 ddr_write(DDR23PHY_PLL_CONFIG, 0x80000000);
1128 ddr_write(DDR23PHY_PLL_CONFIG, 0x00000000);
1134 /* calib_once + calib_fast (for all BL) */
1135 ddr_write(DDR23PHY_BL3_VDL_CALIBRATE, 0x00000003);
1136 ddr_write(DDR23PHY_BL2_VDL_CALIBRATE, 0x00000003);
1137 ddr_write(DDR23PHY_BL1_VDL_CALIBRATE, 0x00000003);
1138 ddr_write(DDR23PHY_BL0_VDL_CALIBRATE, 0x00000003);
1141 li t0, KSEG1ADDR(AI_DDRPHY_BASE)
1142 1: /* Wait until calib_idle == 1 and locked for all BL */
1143 lw t1, DDR23PHY_BL3_VDL_STATUS(t0)
1147 lw t1, DDR23PHY_BL2_VDL_STATUS(t0)
1151 lw t1, DDR23PHY_BL1_VDL_STATUS(t0)
1155 lw t1, DDR23PHY_BL0_VDL_STATUS(t0)
1161 lw t1, DDR23PHY_BL0_VDL_STATUS(t0)
1163 andi t2, t1, 0x3f /* VDL step size */
1166 or t2, t2, t1 /* ovr_en */
1169 or t2, t2, t1 /* ovr_force */
1170 sw t2, DDR23PHY_STATIC_VDL_OVERRIDE(t0)
1172 #endif /* !CFG_QUICKTURN */
1175 * Memory controller PL341 initialization
1178 /* De-assert core reset */
1179 move t0, a2 # AMEMC DMP regs
1180 ddr_write(AI_RESETCTRL, 0x00000000)
1182 move t0, a1 # AMEMC regs
1184 #ifdef CFG_DDR_REFRESH_PRD
1186 ddr_write(PL341_refresh_prd, MEMCYCLES_MIN(CFG_DDR_REFRESH_PRD));
1189 #ifdef CFG_DDR_T_MRD
1190 /* MRD time [6:0] */
1191 ddr_write(PL341_t_mrd, MEMCYCLES(CFG_DDR_T_MRD));
1194 #ifdef CFG_DDR_T_RAS
1195 /* ras time [4:0] */
1196 ddr_write(PL341_t_ras, MEMCYCLES(CFG_DDR_T_RAS));
1201 ddr_write(PL341_t_rc, MEMCYCLES(CFG_DDR_T_RC));
1204 #ifdef CFG_DDR_T_RCD
1206 ddr_write(PL341_t_rcd, MEMCYCLES(CFG_DDR_T_RCD));
1209 #ifdef CFG_DDR_T_RFC
1210 /* t_rfc [6:0] schedule_rfc[14:8] */
1211 ddr_write(PL341_t_rfc,
1212 ((MEMCYCLES(CFG_DDR_T_RFC) - 3) << 8) | MEMCYCLES(CFG_DDR_T_RFC));
1217 ddr_write(PL341_t_rp,
1218 ((MEMCYCLES(CFG_DDR_T_RP) - 3) << 8) | MEMCYCLES(CFG_DDR_T_RP));
1221 #ifdef CFG_DDR_T_RRD
1223 ddr_write(PL341_t_rrd, MEMCYCLES(CFG_DDR_T_RRD));
1228 ddr_write(PL341_t_wr, MEMCYCLES(CFG_DDR_T_WR));
1231 #ifdef CFG_DDR_T_WTR
1233 ddr_write(PL341_t_wtr, MEMCYCLES(CFG_DDR_T_WTR));
1238 ddr_write(PL341_t_xp, MEMCYCLES(CFG_DDR_T_XP));
1241 #ifdef CFG_DDR_T_XSR
1243 ddr_write(PL341_t_xsr, MEMCYCLES(CFG_DDR_T_XSR));
1246 #ifdef CFG_DDR_T_ESR
1248 ddr_write(PL341_t_esr, MEMCYCLES(CFG_DDR_T_ESR));
1251 #ifdef CFG_DDR_T_FAW
1253 ddr_write(PL341_t_faw,
1254 ((MEMCYCLES(CFG_DDR_T_FAW) - 3) << 8) | MEMCYCLES(CFG_DDR_T_FAW));
1257 /* Check if sdram_config is nonzero */
1259 bne t1, $0, sdram_mem_cfg
1262 /* sdram_config is 0, configure by code-default values */
1263 /* Figure out if it's a low cost package */
1266 /* Standard package, assume 1024-column, 32-bit, 8-bank DDR */
1267 beq t1, $0, sdram_mem_cfg
1268 li s0, (0x0140 | CFG_DDR_CAS_LATENCY)
1270 /* Low cost package, assume 1024-column, 16-bit, 8-bank DDR */
1271 li s0, (0x01c0 | CFG_DDR_CAS_LATENCY)
1275 * sdram_config[2:0]: CAS latency
1276 * PL341_cas_latency[3:1]: CL range from 2 to 6
1277 * PL341_write_latency[2:0]: CL - 1
1281 sw t2, PL341_cas_latency(a1)
1283 sw t2, PL341_write_latency(a1)
1285 /* PL341_memory_cfg: Rows and Columns */
1286 lw t2, PL341_memory_cfg(a1) # Read PL341_memory_cfg
1289 * sdram_config[10:8]: 0=2048; 1=1024; 2=512; 3=256 columns
1290 * PL341_memory_cfg[2:0]: 1=9-bit; 2=10-bit; 3=11-bit; Others=Reserved.
1292 li t3, ~0x7 # columns(bit2:0)
1293 and t2, t2, t3 # clear column
1294 srl t1, s0, 8 # Column fields from sdram_config s0(bit10:8)
1300 sw t2, PL341_memory_cfg(a1)
1302 /* PL341_memory_cfg2: Bus width and Banks */
1303 lw t2, PL341_memory_cfg2(a1) # Read PL341_memory_cfg2
1305 /* Low cost package is 16-bit bus */
1308 bne t1, $0, 2f # nonzero: low cost package with 16-bit bus
1309 and t2, t2, t3 # Clear bit[7:6] to work in 16-bit mode
1312 * sdram_config[7]: 0 default bus width, 1: reduced width
1313 * PL341_memory_cfg2[7:6]: 00 for 16bit, 01=32bit, 10=64bit, 11=reserved
1316 bne t1, $0, 2f # Work in 16-bit mode
1318 or t2, t2, 0x40 # Set bit[7:6] to 32-bit mode
1321 * sdram_config[6]: 0 for 4 banks, 1 for 8 banks
1322 * PL341_memory_cfg2[5:4]: 00 for 4 banks, 11 for 8 banks
1324 andi t1, s0, 0x40 # Bank configuration
1327 and t2, t2, t3 # Clear bit[5:4] to work in 4-bank mode
1328 or t2, t2, 0x30 # Set bit[5:4] to 11 for 8-bank mode
1330 sw t2, PL341_memory_cfg2(a1);
1332 /* chip0 configuration */
1333 ddr_write(PL341_chip_0_cfg, 0x00000000);
1336 ddr_write(PL341_user_config0, 0x00000003);
1339 * DDR2 chip initialization
1343 ddr_write(PL341_direct_cmd, MCHIP_CMD_NOP);
1345 /* issue precharge all */
1346 ddr_write(PL341_direct_cmd, MCHIP_CMD_PRECHARGE_ALL);
1349 ddr_write(PL341_direct_cmd, MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(2));
1352 ddr_write(PL341_direct_cmd, MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(3));
1355 ddr_write(PL341_direct_cmd,
1356 MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1357 MCHIP_EMR1_DLL_DISABLE(0)
1361 /* Set CAS to external memory devices */
1362 lw t1, PL341_cas_latency(a1) # CAS value in bit3:1
1363 li t2, (MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(0) | \
1364 MCHIP_MR_WRITE_RECOVERY(MEMCYCLES(CFG_DDR_T_WR)) | \
1365 MCHIP_MR_DLL_RESET(1) | MCHIP_MR_BURST_LENGTH)
1366 sll t1, t1, 3 # Shift to bit6:4 for DDR MRS register
1368 sw t2, PL341_direct_cmd(a1)
1370 /* issue precharge all */
1371 ddr_write(PL341_direct_cmd, MCHIP_CMD_PRECHARGE_ALL);
1373 /* auto-refresh 2 times */
1374 ddr_write(PL341_direct_cmd, MCHIP_CMD_AUTO_REFRESH);
1375 ddr_write(PL341_direct_cmd, MCHIP_CMD_AUTO_REFRESH);
1377 /* DLL Reset=0 (Un-Reset DLL) */
1378 and t2, t2, ~MCHIP_MR_DLL_RESET(1)
1379 sw t2, PL341_direct_cmd(a1)
1381 /* DLL Enable & RTT 75ohm */
1382 ddr_write(PL341_direct_cmd,
1383 MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1384 MCHIP_EMR1_DLL_DISABLE(0) | MCHIP_EMR1_RTT_75_OHM |
1385 MCHIP_EMR1_OCD_CALI_EXIT
1389 ddr_write(PL341_direct_cmd,
1390 MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1391 MCHIP_EMR1_DLL_DISABLE(0) | MCHIP_EMR1_RTT_75_OHM |
1392 MCHIP_EMR1_OCD_CALI_DEFAULT
1396 ddr_write(PL341_direct_cmd,
1397 MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1398 MCHIP_EMR1_DLL_DISABLE(0) | MCHIP_EMR1_RTT_75_OHM |
1399 MCHIP_EMR1_OCD_CALI_EXIT
1402 /* set MEMC to GO */
1403 ddr_write(PL341_memc_cmd, 0);