1 /*****************************************************************************
2 * (C) Copyright 2004-05; Tundra Semiconductor Corp.
4 * Added automatic detect of SDC settings
5 * Copyright (c) 2005 Freescale Semiconductor, Inc.
6 * Maintainer tie-fei.zang@freescale.com
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 ****************************************************************************/
24 /*----------------------------------------------------------------------------
25 * FILENAME: asm_init.s
27 * Originator: Alex Bounine
30 * Initialization code for the Tundra Tsi108 bridge chip
32 *---------------------------------------------------------------------------*/
37 #include <ppc_asm.tmpl>
39 #include <asm/processor.h>
43 /*===========================================================================
44 * Build Configuration Options
47 /* #define DISABLE_PBM disables usage of PB Master */
48 /* #define SDC_HARDCODED_INIT config SDRAM controller with hardcoded values */
49 /* #define SDC_AUTOPRECH_EN enable SDRAM auto precharge */
51 /* ===========================================================================
52 * Hardcoded SDC settings
55 #ifdef SDC_HARDCODED_INIT
57 /* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */
59 #define VAL_SD_REFRESH (0x61A)
60 #define VAL_SD_TIMING (0x0308336b)
61 #define VAL_SD_D0_CTRL (0x07100021) /* auto-precharge disabled */
62 #define VAL_SD_D0_BAR (0x0FE00000) /* 512MB @ 0x00000000 */
63 #define VAL_SD_D1_CTRL (0x07100021) /* auto-precharge disabled */
64 #define VAL_SD_D1_BAR (0x0FE00200) /* 512MB @ 0x20000000 */
66 #endif /* SDC_HARDCODED_INIT */
68 /*---------------------------------------------------------------------------
71 CPU Address and Data Parity enables.
76 ===========================================================================
79 !!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are
80 expected to work correctly for the CSR space within 32KB range.
82 LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant.
83 These macros are absolutely identical except their names. This difference
84 is provided intentionally for better readable code.
85 -------------------------------------------------------------------------*/
87 #define LOAD_PTR(reg,const32) \
88 addis reg,r0,const32@h; ori reg,reg,const32@l
90 #define LOAD_U32(reg,const32) \
91 addis reg,r0,const32@h; ori reg,reg,const32@l
93 /* LOADMEM initializes a register with the contents of a specified 32-bit memory
94 location, usually a CSR value.*/
96 #define LOAD_MEM(reg,addr32) \
97 addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
99 #ifndef SDC_HARDCODED_INIT
101 /* MHz: 0,0,183,100,133,167,200,233 */
102 .long 0,0, 6, 10, 8, 6, 5, 4 /* nSec */
105 /*===========================================================================
106 board_asm_init() - early initialization function. Coded to be portable to
107 dual-CPU configuration.
108 Checks CPU number and performs board HW initialization if called for CPU0.
110 Registers used: r3,r4,r5,r6,r19,r29
111 ===========================================================================
113 ---------------------------------------------------------------------------
114 NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108
115 and the rest of the board. Current implementation demonstrates two
116 possible ways to identify CPU number:
117 - for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM.
118 - for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108.
119 ---------------------------------------------------------------------------*/
121 .globl board_asm_init
124 mflr r19 /* Save LR to be able return later. */
126 bl icache_enable /* Enable icache to reduce reads from flash. */
128 /* Initialize pointer to Tsi108 register space
129 -------------------------------------------------------------------------*/
131 LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
132 ori r4,r29,TSI108_PB_REG_OFFSET
134 /*-------------------------------------------------------------------------
135 Check Processor Version Number */
138 rlwinm r3,r3,16,16,23 /* get ((Processor Version Number) & 0xFF00) */
140 cmpli 0,0,r3,0x8000 /* MPC74xx */
143 /* ------------------------------------------
144 For MPC744x/5x enable extended BATs[4-7]
145 Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1
150 oris r5, r5, 0x0080 /* Set HID0[HIGH_BAT_EN] bit #8 */
151 ori r5, r5, 0x0380 /* Set SPD,XBSEN,SGE bits #22,23,24 */
156 /* Adding code to disable external interventions in MPX bus mode */
158 oris r3, r3, 0x0100 /* Set the EIDIS bit in MSSCR0: bit 7 */
163 /* Sri: code to enable FP unit */
170 #if(1) /* def CONFIG_DUAL_CPU
171 -------------------------------------------------------------------------
172 For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number.
175 mfspr r3,1014 /* read MSSCR0 */
176 rlwinm. r3,r3,27,31,31 /* get processor ID number */
177 mtspr SPRN_PIR,r3 /* Save CPU ID */
184 /* An alternative method of checking the processor number (in addition
185 to configuration using MSSCR0[ID] bit on MPC74xx).
186 Good for IBM PPC750FX/GX.
189 lwz r3,PB_BUS_MS_SELECT(r4) /* read PB_ID register */
190 rlwinm. r3,r3,24,31,31 /* get processor ID number */
198 #endif /* CONFIG_DUAL_CPU */
200 /* Initialize Tsi108 chip
201 ---------------------------------------------------------------------------
206 /*--------------------------------------------------------------------------
207 Adjust HLP/Flash parameters. By default after reset the HLP port is set
208 to support slow devices. Better performance can be achived when an optimal
209 parameters are used for specific EPROM device.
210 NOTE: This should be performed ASAP for the emulation platform because
211 it has 5MHz HLP clocking.
214 #ifdef CONFIG_TSI108EMU
215 ori r4,r29,TSI108_HLP_REG_OFFSET
216 LOAD_U32(r5,0x434422c0)
217 stw r5,0x08(r4) /* set HLP B0_CTRL0 */
219 LOAD_U32(r5,0xd0012000)
220 stw r5,0x0c(r4) /* set HLP B0_CTRL1 */
224 /* -------------------------------------------------------------------------
225 * Initialize PB interface.
228 ori r4,r29,TSI108_PB_REG_OFFSET
230 #if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE)
231 /* Relocate (if required) Tsi108 registers. Set new value for PB_REG_BAR:
232 * Note we are in the 32-bit address mode.
234 LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* value for PB_REG_BAR: BA + EN*/
235 stw r5,PB_REG_BAR(r4)
239 ori r4,r29,TSI108_PB_REG_OFFSET
242 /* Set PB Slave configuration register */
244 /* LOAD_U32(r5,0x000024C7) value for PB_SCR: TEA enabled,AACK delay = 7 */
245 LOAD_U32(r5,0x00002481) /* value for PB_SCR: TEA enabled,AACK delay = 1 */
246 lwz r3, PB_RSR(r4) /* get PB bus mode */
247 xori r3,r3,0x0001 /* mask PB_BMODE: r3 -> (0 = 60X, 1 = MPX) */
248 rlwimi r5,r3,14,17,17 /* for MPX: set DTI_MODE bit */
252 /* Configure PB Arbiter */
254 lwz r5,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */
255 li r3, 0x00F0 /* ARB_PIPELINE_DEP mask */
257 ori r3,r3,0x1000 /* add PBM_EN to clear (enabled by default) */
259 andc r5,r5,r3 /* Clear the masked bit fields */
260 /* ori r5,r5,0x0040 Set pipeline depth 4
261 ori r5,r5,0x0080 Set pipeline depth 8
262 ori r5,r5,0x0020 !!!avb Testing: set pipeline depth 2 */
264 stw r5,PB_ARB_CTRL(r4)
266 #if (0) /* currently using the default settings for PBM after reset */
267 LOAD_U32(r5,0x) /* value for PB_MCR */
271 LOAD_U32(r5,0x) /* value for PB_MCMD */
276 /* Disable or enable PVT based on processor bus frequency
277 1. Read CG_PWRUP_STATUS register field bits 18,17,16
278 2. See if the value is < or > 133mhz (18:16 = 100)
282 LOAD_U32(r3,0xC0002234)
284 rlwinm r3,r3,16,29,31
289 #ifndef CONFIG_TSI108EMU
290 /* FIXME: Disable PB calibration control for any real Tsi108 board */
291 li r5,0x0101 /* disable calibration control */
292 stw r5,PB_PVT_CTRL2(r4)
296 /*---------------------------------------------------------------------------
297 Initialize SDRAM controller.
298 ----------------------------------------------------------------------------*/
302 #ifndef SDC_HARDCODED_INIT
303 /* get SDC clock prior doing sdram controller autoconfig */
304 ori r4,r29,TSI108_CLK_REG_OFFSET /* r4 - ptr to CG registers */
305 lwz r3, CG_PWRUP_STATUS(r4) /* get CG configuration */
306 rlwinm r3,r3,12,29,31 /* r3 - SD clk */
307 lis r5,sdc_clk_sync@h
308 ori r5,r5,sdc_clk_sync@l
309 /* Sri: At this point check if r3 = 001. If yes,
310 * the memory frequency should be same as the
315 lwz r6, CG_PWRUP_STATUS(r4)
316 rlwinm r6,r6,16,29,31
321 lwzx r9,r5,r3 /* get SD clk rate in nSec */
322 /* ATTN: r9 will be used by SPD routine */
323 #endif /* !SDC_HARDCODED_INIT */
325 ori r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */
327 /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */
330 stw r5,SD_INT_ENABLE(r4) /* Ensure that interrupts are disabled */
331 #ifdef ENABLE_SDRAM_ECC
333 #endif /* ENABLE_SDRAM_ECC */
334 stw r5,SD_ECC_CTRL(r4) /* Enable/Disable ECC */
337 #ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
339 /* First read the CG_PWRUP_STATUS register to get the
340 memory speed from bits 22,21,20 */
342 LOAD_U32(r3,0xC0002234)
344 rlwinm r3,r3,12,29,31
346 /* Now first check for 166, then 200, or default */
351 /* set values for 166 Mhz memory speed */
353 /* Set refresh rate and timing parameters */
354 LOAD_U32(r5,0x00000515)
355 stw r5,SD_REFRESH(r4)
356 LOAD_U32(r5,0x03073368)
360 /* Initialize DIMM0 control and BAR registers */
361 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
362 #ifdef SDC_AUTOPRECH_EN
363 oris r5,r5,0x0001 /* set auto precharge EN bit */
365 stw r5,SD_D0_CTRL(r4)
366 LOAD_U32(r5,VAL_SD_D0_BAR)
370 /* Initialize DIMM1 control and BAR registers
371 * (same as dimm 0, next 512MB, disabled)
373 LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */
374 #ifdef SDC_AUTOPRECH_EN
375 oris r5,r5,0x0001 /* set auto precharge EN bit */
377 stw r5,SD_D1_CTRL(r4)
378 LOAD_U32(r5,VAL_SD_D1_BAR)
387 bne set_default_values
389 /* set values for 200Mhz memory speed */
391 /* Set refresh rate and timing parameters */
392 LOAD_U32(r5,0x0000061a)
393 stw r5,SD_REFRESH(r4)
394 LOAD_U32(r5,0x03083348)
398 /* Initialize DIMM0 control and BAR registers */
399 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
400 #ifdef SDC_AUTOPRECH_EN
401 oris r5,r5,0x0001 /* set auto precharge EN bit */
403 stw r5,SD_D0_CTRL(r4)
404 LOAD_U32(r5,VAL_SD_D0_BAR)
408 /* Initialize DIMM1 control and BAR registers
409 * (same as dimm 0, next 512MB, disabled)
411 LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */
412 #ifdef SDC_AUTOPRECH_EN
413 oris r5,r5,0x0001 /* set auto precharge EN bit */
415 stw r5,SD_D1_CTRL(r4)
416 LOAD_U32(r5,VAL_SD_D1_BAR)
424 /* Set refresh rate and timing parameters */
425 LOAD_U32(r5,VAL_SD_REFRESH)
426 stw r5,SD_REFRESH(r4)
427 LOAD_U32(r5,VAL_SD_TIMING)
431 /* Initialize DIMM0 control and BAR registers */
432 LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
433 #ifdef SDC_AUTOPRECH_EN
434 oris r5,r5,0x0001 /* set auto precharge EN bit */
436 stw r5,SD_D0_CTRL(r4)
437 LOAD_U32(r5,VAL_SD_D0_BAR)
441 /* Initialize DIMM1 control and BAR registers
442 * (same as dimm 0, next 512MB, disabled)
444 LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */
445 #ifdef SDC_AUTOPRECH_EN
446 oris r5,r5,0x0001 /* set auto precharge EN bit */
448 stw r5,SD_D1_CTRL(r4)
449 LOAD_U32(r5,VAL_SD_D1_BAR)
453 #else /* !SDC_HARDCODED_INIT */
455 bl tsi108_sdram_spd /* automatically detect SDC settings */
457 #endif /* SDC_HARDCODED_INIT */
462 LOAD_U32(r5,0x00000030) /* PB_EN + OCN_EN */
464 LOAD_U32(r5,0x00000230) /* PB_EN + OCN_EN + PB/OCN=80/20 */
465 #endif /* DISABLE_PBM */
467 #ifdef CONFIG_TSI108EMU
468 oris r5,r5,0x0010 /* set EMULATION_MODE bit */
475 /* Enable SDRAM access */
477 oris r5,r5,0x8000 /* start SDC: set SD_CTRL[ENABLE] bit */
484 beq wait_init_complete /* wait until SDRAM initialization is complete */
486 /*---------------------------------------------------------------------------
487 Map SDRAM into the processor bus address space
488 ---------------------------------------------------------------------------*/
490 ori r4,r29,TSI108_PB_REG_OFFSET
492 /* Setup BARs associated with direct path PB<->SDRAM */
495 provides a direct path to the main system memory (cacheable SDRAM) */
497 LOAD_U32(r5, 0x00000011) /* BA=0,Size=512MB, ENable, No Addr.Translation */
498 stw r5,PB_SDRAM_BAR1(r4)
501 /* Make sure that PB_SDRAM_BAR1 decoder is set
502 (to allow following immediate read from SDRAM) */
503 lwz r5,PB_SDRAM_BAR1(r4)
507 provides non-cacheable alias (via the direct path) to main system memory.
508 Size = 512MB, ENable, Addr.Translation - ON,
509 BA = 0x0_40000000, TA = 0x0_00000000 */
511 LOAD_U32(r5, 0x40010011)
512 stw r5,PB_SDRAM_BAR2(r4)
515 /* Make sure that PB_SDRAM_BAR2 decoder is set
516 (to allow following immediate read from SDRAM) */
517 lwz r5,PB_SDRAM_BAR2(r4)
523 /* All done. Restore LR and return. */
528 /*===========================================================================
531 This routine enables CPU1 on the dual-processor system.
532 ===========================================================================*/
537 lis r3,Tsi108_Base@ha /* Get Grendel CSR Base Addr */
538 addi r3,r3,Tsi108_Base@l
539 lwz r3,0(r3) /* R3 = CSR Base Addr */
540 ori r4,r3,TSI108_PB_REG_OFFSET
541 lwz r3,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */
542 ori r3,r3,0x0200 /* Set M1_EN bit */
543 stw r3,PB_ARB_CTRL(r4)
548 /*===========================================================================
551 Enable CPU core external interrupt
552 ===========================================================================*/
557 ori r3,r3,0x8000 /* set EE bit */
561 /*===========================================================================
564 Disable CPU core external interrupt
565 ===========================================================================*/
570 li r4,-32768 /* aka "li r4,0x8000" */
571 andc r3,r3,r4 /* clear EE bit */
575 #ifdef ENABLE_SDRAM_ECC
576 /*===========================================================================
580 ===========================================================================*/
584 ori r4,r29,TSI108_SD_REG_OFFSET
585 lwz r3,SD_ECC_CTRL(r4) /* Read SDRAM ECC Control Register */
586 ori r3,r3,0x0001 /* Set ECC_EN bit */
587 stw r3,SD_ECC_CTRL(r4)
590 /*===========================================================================
593 Clears all pending SDRAM ECC errors
594 (normally after SDRAM scrubbing/initialization)
595 ===========================================================================*/
597 .global clear_ECC_err
599 ori r4,r29,TSI108_SD_REG_OFFSET
600 /* lwz r3,SD_INT_STATUS(r4) Read SDRAM ECC Control Register */
601 ori r3,r0,0x0030 /* ECC_UE_INT + ECC_CE_INT bits */
602 stw r3,SD_INT_STATUS(r4)
605 #endif /* ENABLE_SDRAM_ECC */
607 #ifndef SDC_HARDCODED_INIT
609 /********************************************************************
613 #define SD_I2C_CTRL1 (0x400)
614 #define SD_I2C_CTRL2 (0x404)
615 #define SD_I2C_RD_DATA (0x408)
616 #define SD_I2C_WR_DATA (0x40C)
619 * SDRAM SPD Support Macros
622 #define SPD_DIMM0 (0x00000100)
623 #define SPD_DIMM1 (0x00000200) /* SPD_DIMM1 was 0x00000000 */
625 #define SPD_RDIMM (0x01)
626 #define SPD_UDIMM (0x02)
628 #define SPD_CAS_3 0x8
629 #define SPD_CAS_4 0x10
630 #define SPD_CAS_5 0x20
632 #define ERR_NO_DIMM_FOUND (0xdb0)
633 #define ERR_TRAS_FAIL (0xdb1)
634 #define ERR_TRCD_FAIL (0xdb2)
635 #define ERR_TRP_FAIL (0xdb3)
636 #define ERR_TWR_FAIL (0xdb4)
637 #define ERR_UNKNOWN_PART (0xdb5)
638 #define ERR_NRANK_INVALID (0xdb6)
639 #define ERR_DIMM_SIZE (0xdb7)
640 #define ERR_ADDR_MODE (0xdb8)
641 #define ERR_RFRSH_RATE (0xdb9)
642 #define ERR_DIMM_TYPE (0xdba)
643 #define ERR_CL_VALUE (0xdbb)
644 #define ERR_TRFC_FAIL (0xdbc)
646 /* READ_SPD requirements:
647 * byte - byte address in SPD device (0 - 255)
648 * r3 = will return data read from I2C Byte location
649 * r4 - unchanged (SDC base addr)
650 * r5 - clobbered in routine (I2C status)
651 * r10 - number of DDR slot where first SPD device is detected
654 #define READ_SPD(byte_num) \
655 addis r3, 0, byte_num@l;\
658 stw r3, SD_I2C_CTRL1(r4);\
659 li r3, I2C_CNTRL2_START;\
660 stw r3, SD_I2C_CTRL2(r4);\
668 lwz r5, SD_I2C_CTRL2(r4);\
669 rlwinm. r3,r5,0,23,23;\
671 rlwinm. r3,r5,0,3,3;\
672 lwz r3, SD_I2C_RD_DATA(r4)
674 #define SPD_MIN_RFRSH (0x80)
675 #define SPD_MAX_RFRSH (0x85)
677 refresh_rates: /* in nSec */
678 .long 15625 /* Normal (0x80) */
679 .long 3900 /* Reduced 0.25x (0x81) */
680 .long 7800 /* Reduced 0.5x (0x82) */
681 .long 31300 /* Extended 2x (0x83) */
682 .long 62500 /* Extended 4x (0x84) */
683 .long 125000 /* Extended 8x (0x85) */
685 /*===========================================================================
688 * Inittializes SDRAM Controller using DDR2 DIMM Serial Presence Detect data
689 * Uses registers: r4 - SDC base address (not changed)
690 * r9 - SDC clocking period in nSec
691 * Changes registers: r3,r5,r6,r7,r8,r10,r11
692 *==========================================================================*/
697 xor r11,r11,r11 /* DIMM Base Address: starts from 0 */
701 /**************************************
702 * Program Refresh Rate Register
705 READ_SPD(12) /* get Refresh Rate */
707 li r5, ERR_RFRSH_RATE
708 cmpi 0,0,r3,SPD_MIN_RFRSH
710 cmpi 0,0,r3,SPD_MAX_RFRSH
712 addi r3,r3,-SPD_MIN_RFRSH
714 lis r5,refresh_rates@h
715 ori r5,r5,refresh_rates@l
716 lwzx r5,r5,r3 /* get refresh rate in nSec */
717 divwu r5,r5,r9 /* calculate # of SDC clocks */
718 stw r5,SD_REFRESH(r4) /* Set refresh rate */
721 /**************************************
722 * Program SD Timing Register
725 li r7, 0 /* clear r7 prior parameter collection */
727 READ_SPD(20) /* get DIMM type: Registered or Unbuffered */
730 cmpi 0,0,r3,SPD_UDIMM
732 cmpi 0,0,r3,SPD_RDIMM
734 oris r7,r7,0x1000 /* set SD_TIMING[DIMM_TYPE] bit */
737 READ_SPD(18) /* Get CAS Latency */
740 andi. r6,r3,SPD_CAS_3
745 andi. r6,r3,SPD_CAS_4
750 andi. r6,r3,SPD_CAS_5
756 READ_SPD(30) /* Get tRAS */
765 cmpi 0,0,r6,0x0F /* max supported value */
767 rlwimi r7,r6,16,12,15
769 READ_SPD(29) /* Get tRCD */
771 rlwinm r3,r3,30,2,31/* right shift tRCD by 2 bits as per DDR2 spec */
779 cmpi 0,0,r6,0x07 /* max supported value */
781 rlwimi r7,r6,12,17,19
783 READ_SPD(27) /* Get tRP value */
785 rlwinm r3,r3,30,2,31 /* right shift tRP by 2 bits as per DDR2 spec */
793 cmpi 0,0,r6,0x07 /* max supported value */
797 READ_SPD(36) /* Get tWR value */
799 rlwinm r3,r3,30,2,31 /* right shift tWR by 2 bits as per DDR2 spec */
806 addi r6,r6,-1 /* Tsi108 SDC always gives one extra clock */
808 cmpi 0,0,r6,0x07 /* max supported value */
812 READ_SPD(42) /* Get tRFC */
815 /* Tsi108 spec: tRFC=(tRFC + 1)/2 */
817 rlwinm. r3,r3,31,1,31 /* divide by 2 */
825 cmpi 0,0,r6,0x1F /* max supported value */
832 /*=====================================================================
833 * The following two registers are set on per-DIMM basis.
834 * The SD_REFRESH and SD_TIMING settings are common for both DIMMS
835 *=====================================================================
840 /*****************************************
841 * Program SDRAM DIMM Control Register
844 li r7, 0 /* clear r7 prior parameter collection */
846 READ_SPD(13) /* Get Primary SDRAM Width */
848 cmpi 0,0,r3,4 /* Check for 4-bit SDRAM */
850 oris r7,r7,0x0010 /* Set MEM_WIDTH bit */
853 READ_SPD(17) /* Get Number of banks on SDRAM device */
855 /* Grendel only distinguish betw. 4 or 8-bank memory parts */
856 li r5,ERR_UNKNOWN_PART /* non-supported memory part */
864 READ_SPD(5) /* Get # of Ranks */
866 li r5,ERR_NRANK_INVALID
867 andi. r6,r3,0x7 /* Use bits [2..0] only */
874 READ_SPD(4) /* Get # of Column Addresses */
877 andi. r3,r3,0x0f /* cut off reserved bits */
882 addi r6,r3,-8 /* calculate ADDR_MODE parameter */
883 rlwimi r7,r6,4,24,27 /* set ADDR_MODE field */
886 #ifdef SDC_AUTOPRECH_EN
887 oris r7,r7,0x0001 /* set auto precharge EN bit */
889 ori r7,r7,1 /* set ENABLE bit */
890 cmpi 0,0,r10,SPD_DIMM0
892 stw r7,SD_D0_CTRL(r4)
896 stw r7,SD_D1_CTRL(r4)
900 /********************************************
901 * Program SDRAM DIMMx Base Address Register
905 READ_SPD(5) /* get # of Ranks */
909 READ_SPD(31) /* Read DIMM rank density */
911 rlwinm r5,r3,27,29,31
913 or r5,r6,r5 /* r5 = Normalized Rank Density byte */
914 lis r8, 0x0080 /* 128MB >> 4 */
915 mullw r8,r8,r5 /* r8 = (rank_size >> 4) */
916 mullw r8,r8,r7 /* r8 = (DIMM_size >> 4) */
919 or r7,r7,r11 /* set ADDR field */
920 rlwinm r8,r8,12,20,31
921 add r11,r11,r8 /* set Base Addr for next DIMM */
923 cmpi 0,0,r10,SPD_DIMM0
939 cmpi 0,0,r10,SPD_DIMM1
949 err_hung: /* hang here for debugging */
954 #endif /* !SDC_HARDCODED_INIT */