1 /******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
4 * This program and the accompanying materials
5 * are made available under the terms of the BSD License
6 * which accompanies this distribution, and is available at
7 * http://www.opensource.org/licenses/bsd-license.php
10 * IBM Corporation - initial implementation
11 *****************************************************************************/
21 *******************************************************************************
25 //#define U4_SHOW_REGS
27 int io_getchar(char *);
32 static const uint32_t VER = 2;
33 static const uint32_t SUBVER = 1;
37 *******************************************************************************
39 // bit shifting in Motorola/IBM bit enumeration format (yaks...)
40 #define IBIT( nr ) ( (uint32_t) 0x80000000 >> (nr) )
41 #define BIT( nr ) ( (uint32_t) 0x1 << (nr) )
44 * macros to detect the current board layout
46 #define IS_MAUI ( ( load8_ci( 0xf4000682 ) >> 4 ) == 0 )
47 #define IS_BIMINI ( ( load8_ci( 0xf4000682 ) >> 4 ) == 1 )
48 #define IS_KAUAI ( ( load8_ci( 0xf4000682 ) >> 4 ) == 2 )
52 *******************************************************************************
58 #define U4_BASE_ADDR ((uint64_t) 0xf8000000 )
59 #define u4reg( reg ) (U4_BASE_ADDR + (uint64_t) (reg))
64 #define I2C_MODE_R u4reg(0x1000)
65 #define I2C_CTRL_R u4reg(0x1010)
66 #define I2C_STAT_R u4reg(0x1020)
67 #define I2C_ISR_R u4reg(0x1030)
68 #define I2C_ADDR_R u4reg(0x1050)
69 #define I2C_SUBA_R u4reg(0x1060)
70 #define I2C_DATA_R u4reg(0x1070)
73 * clock control registers & needed bits/masks
75 #define ClkCntl_R u4reg(0x0800)
76 #define PLL2Cntl_R u4reg(0x0860)
79 * clock control bits & masks
81 #define CLK_DDR_CLK_MSK (IBIT(11) | IBIT(12) | IBIT(13))
84 * memory controller registers
86 #define RASTimer0_R u4reg(0x2030)
87 #define RASTimer1_R u4reg(0x2040)
88 #define CASTimer0_R u4reg(0x2050)
89 #define CASTimer1_R u4reg(0x2060)
90 #define MemRfshCntl_R u4reg(0x2070)
91 #define MemProgCntl_R u4reg(0x20b0)
92 #define Dm0Cnfg_R u4reg(0x2200)
93 #define Dm1Cnfg_R u4reg(0x2210)
94 #define Dm2Cnfg_R u4reg(0x2220)
95 #define Dm3Cnfg_R u4reg(0x2230)
96 #define MemWrQCnfg_R u4reg(0x2270)
97 #define MemArbWt_R u4reg(0x2280)
98 #define UsrCnfg_R u4reg(0x2290)
99 #define MemRdQCnfg_R u4reg(0x22a0)
100 #define MemQArb_R u4reg(0x22b0)
101 #define MemRWArb_R u4reg(0x22c0)
102 #define MemBusCnfg_R u4reg(0x22d0)
103 #define MemBusCnfg2_R u4reg(0x22e0)
104 #define ODTCntl_R u4reg(0x23a0)
105 #define MemModeCntl_R u4reg(0x2500)
106 #define MemPhyModeCntl_R u4reg(0x2880)
107 #define CKDelayL_R u4reg(0x2890)
108 #define CKDelayU_R u4reg(0x28a0)
109 #define IOPadCntl_R u4reg(0x29a0)
110 #define ByteWrClkDelC0B00_R u4reg(0x2800)
111 #define ByteWrClkDelC0B01_R u4reg(0x2810)
112 #define ByteWrClkDelC0B02_R u4reg(0x2820)
113 #define ByteWrClkDelC0B03_R u4reg(0x2830)
114 #define ByteWrClkDelC0B04_R u4reg(0x2900)
115 #define ByteWrClkDelC0B05_R u4reg(0x2910)
116 #define ByteWrClkDelC0B06_R u4reg(0x2920)
117 #define ByteWrClkDelC0B07_R u4reg(0x2930)
118 #define ByteWrClkDelC0B16_R u4reg(0x2980)
119 #define ByteWrClkDelC0B08_R u4reg(0x2a00)
120 #define ByteWrClkDelC0B09_R u4reg(0x2a10)
121 #define ByteWrClkDelC0B10_R u4reg(0x2a20)
122 #define ByteWrClkDelC0B11_R u4reg(0x2a30)
123 #define ByteWrClkDelC0B12_R u4reg(0x2b00)
124 #define ByteWrClkDelC0B13_R u4reg(0x2b10)
125 #define ByteWrClkDelC0B14_R u4reg(0x2b20)
126 #define ByteWrClkDelC0B15_R u4reg(0x2b30)
127 #define ByteWrClkDelC0B17_R u4reg(0x2b80)
128 #define ReadStrobeDelC0B00_R u4reg(0x2840)
129 #define ReadStrobeDelC0B01_R u4reg(0x2850)
130 #define ReadStrobeDelC0B02_R u4reg(0x2860)
131 #define ReadStrobeDelC0B03_R u4reg(0x2870)
132 #define ReadStrobeDelC0B04_R u4reg(0x2940)
133 #define ReadStrobeDelC0B05_R u4reg(0x2950)
134 #define ReadStrobeDelC0B06_R u4reg(0x2960)
135 #define ReadStrobeDelC0B07_R u4reg(0x2970)
136 #define ReadStrobeDelC0B16_R u4reg(0x2990)
137 #define ReadStrobeDelC0B08_R u4reg(0x2a40)
138 #define ReadStrobeDelC0B09_R u4reg(0x2a50)
139 #define ReadStrobeDelC0B10_R u4reg(0x2a60)
140 #define ReadStrobeDelC0B11_R u4reg(0x2a70)
141 #define ReadStrobeDelC0B12_R u4reg(0x2b40)
142 #define ReadStrobeDelC0B13_R u4reg(0x2b50)
143 #define ReadStrobeDelC0B14_R u4reg(0x2b60)
144 #define ReadStrobeDelC0B15_R u4reg(0x2b70)
145 #define ReadStrobeDelC0B17_R u4reg(0x2b90)
146 #define MemInit00_R u4reg(0x2100)
147 #define MemInit01_R u4reg(0x2110)
148 #define MemInit02_R u4reg(0x2120)
149 #define MemInit03_R u4reg(0x2130)
150 #define MemInit04_R u4reg(0x2140)
151 #define MemInit05_R u4reg(0x2150)
152 #define MemInit06_R u4reg(0x2160)
153 #define MemInit07_R u4reg(0x2170)
154 #define MemInit08_R u4reg(0x2180)
155 #define MemInit09_R u4reg(0x2190)
156 #define MemInit10_R u4reg(0x21a0)
157 #define MemInit11_R u4reg(0x21b0)
158 #define MemInit12_R u4reg(0x21c0)
159 #define MemInit13_R u4reg(0x21d0)
160 #define MemInit14_R u4reg(0x21e0)
161 #define MemInit15_R u4reg(0x21f0)
162 #define CalConf0_R u4reg(0x29b0)
163 #define CalConf1_R u4reg(0x29c0)
164 #define MeasStatusC0_R u4reg(0x28f0)
165 #define MeasStatusC1_R u4reg(0x29f0)
166 #define MeasStatusC2_R u4reg(0x2af0)
167 #define MeasStatusC3_R u4reg(0x2bf0)
168 #define CalC0_R u4reg(0x28e0)
169 #define CalC1_R u4reg(0x29e0)
170 #define CalC2_R u4reg(0x2ae0)
171 #define CalC3_R u4reg(0x2be0)
172 #define RstLdEnVerniersC0_R u4reg(0x28d0)
173 #define RstLdEnVerniersC1_R u4reg(0x29d0)
174 #define RstLdEnVerniersC2_R u4reg(0x2ad0)
175 #define RstLdEnVerniersC3_R u4reg(0x2bd0)
176 #define ExtMuxVernier0_R u4reg(0x28b0)
177 #define ExtMuxVernier1_R u4reg(0x28c0)
178 #define OCDCalCmd_R u4reg(0x2300)
179 #define OCDCalCntl_R u4reg(0x2310)
180 #define MCCR_R u4reg(0x2440)
181 #define MSRSR_R u4reg(0x2410)
182 #define MSRER_R u4reg(0x2420)
183 #define MSPR_R u4reg(0x2430)
184 #define MSCR_R u4reg(0x2400)
185 #define MEAR0_R u4reg(0x2460)
186 #define MEAR1_R u4reg(0x2470)
187 #define MESR_R u4reg(0x2480)
188 #define MRSRegCntl_R u4reg(0x20c0)
189 #define EMRSRegCntl_R u4reg(0x20d0)
190 #define APIMemRdCfg_R u4reg(0x30090)
191 #define APIExcp_R u4reg(0x300a0)
194 * common return values
198 #define RET_ACERR_CE -1
199 #define RET_ACERR_UEWT -2
200 #define RET_ACERR_UE -3
203 * 'DIMM slot populated' indicator
210 #define SPD_BUF_SIZE 0x40
213 * maximum number of DIMM banks & DIMM groups
216 #define NUM_BANKS ( NUM_SLOTS / 2 )
217 #define MAX_DGROUPS ( NUM_SLOTS / 2 )
218 #define SLOT_ADJ() ( ( IS_MAUI ) ? NUM_SLOTS / 4 : NUM_SLOTS / 2 )
221 * values needed for auto calibration
223 #define MAX_DRANKS NUM_SLOTS
228 * maximum number of supported CAS latencies
233 * min/max supported CL values by U4
241 #define DIMM_TYPE_MSK BIT(0)
242 #define DIMM_ORG_x4 BIT(0)
243 #define DIMM_ORG_x8 BIT(1)
244 #define DIMM_ORG_x16 BIT(2)
245 #define DIMM_ORG_MIXx8x16 BIT(30)
246 #define DIMM_ORG_UNKNOWN 0
247 #define DIMM_WIDTH 72
248 #define DIMM_BURSTLEN_4 BIT(2)
253 #define L2_CACHE_SIZE (uint32_t) 0x100000
258 #define IMMEDIATE_SCRUB IBIT(0)
259 #define IMMEDIATE_SCRUB_WITH_FILL ( IBIT(0) | IBIT(1) )
260 #define BACKGROUND_SCRUB ( IBIT(1) | ( 0x29 << 16 ) )
263 * I2C starting slave addresses of the DIMM banks
265 #define I2C_START 0x50
268 * Index to the speed dependend DIMM settings
279 * number of read/write strobes of the U4
281 #define NUM_STROBES 18
284 * 2GB hole definition
286 static const uint64_t _2GB = (uint64_t) 0x80000000;
290 *******************************************************************************
297 uint32_t m_pop_u32; // set if bank is populated
298 uint32_t m_bank_u32; // bank number
299 uint32_t m_clmsk_u32; // mask of supported CAS latencies
300 uint32_t m_clcnt_u32; // number of supporetd CAS latencies
301 uint32_t m_clval_pu32[NUM_CL]; // values of supporeted CAS latencies
302 uint32_t m_speed_pu32[NUM_CL]; // speed (Mhz) at CAS latency of same index
303 uint32_t m_size_u32; // chip size in Mb
304 uint32_t m_rank_u32; // # of ranks, total size = chip size*rank
305 uint32_t m_orgmsk_u32; // data organisation (x4, x8, x16) (mask)
306 uint32_t m_orgval_u32; // data organisation (value)
307 uint32_t m_width_u32; // data width
308 uint32_t m_ecc_u32; // set if ecc
309 uint32_t m_type_u32; // rdimm or udimm
310 uint32_t m_burst_u32; // supported burst lengths
311 uint32_t m_bankcnt_u32; // number of banks
314 * the following timing values are all in 1/100ns
316 uint32_t m_tCK_pu32[NUM_CL];
330 * DIMM group definition
334 uint32_t m_size_u32; // group size in MB
335 uint32_t m_start_u32; // in 128Mb granularity
336 uint32_t m_end_u32; // in 128Mb granularity
337 uint32_t m_ss_u32; // single sided/double sided
338 uint32_t m_csmode_u32; // selected CS mode for this group
339 uint32_t m_add2g_u32;
340 uint32_t m_sub2g_u32;
341 uint32_t m_memmd_u32; // selected mem mode for this group
342 uint32_t m_dcnt_u32; // number of DIMMs in group
343 dimm_t *m_dptr[NUM_SLOTS];
347 * auto calibration result structure
351 uint32_t m_MemBusCnfg_u32;
352 uint32_t m_MemBusCnfg2_u32;
353 uint32_t m_RstLdEnVerniers_pu32[4];
357 * ECC error structure
362 uint32_t m_uecnt_u32; // number of uncorrectable errors
363 uint32_t m_cecnt_u32; // number of correctable errors
364 uint32_t m_rank_u32; // erroneous rank
365 uint32_t m_col_u32; // erroneous column
366 uint32_t m_row_u32; // erroneous row
367 uint32_t m_bank_u32; // erroneous bank
371 * U4 register setup structure
376 * external MUX delays
384 * default Wr/Rd Queue & Arbiter register settings
392 * misc fixed register values
396 uint32_t MemPhyModeCntl;
404 uint32_t ByteWrClkDel[NUM_STROBES];
405 uint32_t ReadStrobeDel[NUM_STROBES];
410 *******************************************************************************
412 static dimm_t m_dimm[NUM_SLOTS];
413 static dimm_t m_gendimm;
414 static uint32_t m_dcnt_u32;
415 static dimm_t *m_dptr[NUM_SLOTS];
416 static uint32_t m_bankoff_u32;
417 static uint32_t m_bankpop_u32[NUM_BANKS];
418 static uint32_t m_dclidx_u32;
419 static uint32_t m_dgrcnt_u32;
420 static dgroup_t m_dgroup[MAX_DGROUPS];
421 static dgroup_t *m_dgrptr[MAX_DGROUPS];
422 static uint64_t m_memsize_u64; // memsize in bytes
426 *******************************************************************************
431 static uint8_t bar[] =
432 { '|', '/', '-', '\\', 0 };
433 static uint32_t idx = 0;
435 printf( "\b%c", bar[idx] );
437 if( bar[++idx] == 0 ) {
444 or32_ci( uint64_t r, uint32_t m )
454 and32_ci( uint64_t r, uint32_t m )
464 dly( uint64_t volatile f_wait_u64 ) \
466 while( f_wait_u64 ) {
472 * local i2c access functions
480 * clear out all pending int's and wait
481 * for the stop condition to occur
484 l_stat_u32 = load32_ci( I2C_ISR_R );
485 store32_ci( I2C_ISR_R, l_stat_u32 );
486 } while( ( l_stat_u32 & IBIT(29) ) == 0 );
491 i2c_read( uint32_t f_addr_u32, uint32_t f_suba_u32, uint8_t *f_buf_pu08, uint32_t f_len_u32 )
494 int32_t l_ret_i32 = 1;
499 if( ( f_addr_u32 > (uint32_t) 0x7f ) ||
500 ( f_suba_u32 > (uint32_t) 0xff ) ||
501 ( f_len_u32 == (uint32_t) 0x00 ) ) {
506 * set I2C Interface to combined mode
508 store32_ci( I2C_MODE_R, IBIT(28) | IBIT(29) );
511 * set address, subaddress & read mode
513 store32_ci( I2C_ADDR_R, ( f_addr_u32 << 1 ) | (uint32_t) 0x1 );
514 store32_ci( I2C_SUBA_R, f_suba_u32 );
517 * start address transmission phase
519 store32_ci( I2C_CTRL_R, IBIT(30) );
522 * wait for address transmission to finish
525 l_val_u32 = load32_ci( I2C_ISR_R );
526 } while( ( l_val_u32 & IBIT(30) ) == 0 );
531 if( ( load32_ci( I2C_STAT_R ) & IBIT(30) ) == 0 ) {
536 store32_ci( I2C_CTRL_R, IBIT(31) );
538 store32_ci( I2C_ISR_R, IBIT(30) );
544 while( l_ret_i32 > 0 ) {
545 l_val_u32 = load32_ci( I2C_ISR_R );
547 if( ( l_val_u32 & IBIT(31) ) != 0 ) {
549 *f_buf_pu08 = ( uint8_t ) load32_ci( I2C_DATA_R );
555 * continue when there is more data to read or
558 if( f_len_u32 != 0 ) {
560 store32_ci( I2C_CTRL_R, IBIT(31) );
562 store32_ci( I2C_ISR_R, IBIT(31) );
565 store32_ci( I2C_CTRL_R, 0 );
570 } else if( ( l_val_u32 & IBIT(29) ) != 0 ) {
571 // early stop condition
584 i2c_get_slot( uint32_t i2c_addr )
588 slot = ( i2c_addr - I2C_START ) / 2;
590 if( ( i2c_addr & 0x1 ) != 0 ) {
598 * 'serial presence detect' interpretation functions
601 ddr2_get_dimm_rank( uint8_t *f_spd_pu08 )
603 static const int RANK_IDX = (int) 5;
605 return (uint32_t) ( f_spd_pu08[RANK_IDX] & 0x3 ) + 1;
609 ddr2_get_dimm_size( uint8_t *f_spd_pu08 )
611 static const int SIZE_IDX = (int) 31;
615 l_smsk_u08 = ( f_spd_pu08[SIZE_IDX] << 3 ) |
616 ( f_spd_pu08[SIZE_IDX] >> 5 );
618 for( i = 0; ( ( l_smsk_u08 & ( (uint8_t) 0x1 << i ) ) == 0 ) ; i++ );
620 return (uint32_t) 0x80 << i;
624 ddr2_get_dimm_type( uint8_t *f_spd_pu08 )
626 static const int TYPE_IDX = (int) 20;
628 return (uint32_t) f_spd_pu08[TYPE_IDX] & DIMM_TYPE_MSK;
632 ddr2_get_dimm_org( uint8_t *f_spd_pu08, uint32_t /*out*/ *f_omsk_pu32 )
634 static const int ORG_IDX = (int) 13;
635 uint32_t l_ret_u32 = (uint32_t) f_spd_pu08[ORG_IDX];
637 if( l_ret_u32 == 4 ) {
638 *f_omsk_pu32 = DIMM_ORG_x4;
639 } else if( l_ret_u32 == 8 ) {
640 *f_omsk_pu32 = DIMM_ORG_x8;
641 *f_omsk_pu32 |= DIMM_ORG_MIXx8x16;
642 } else if( l_ret_u32 == 16 ) {
643 *f_omsk_pu32 = DIMM_ORG_x16;
644 *f_omsk_pu32 |= DIMM_ORG_MIXx8x16;
646 *f_omsk_pu32 = DIMM_ORG_UNKNOWN;
647 l_ret_u32 = (uint32_t) ~0;
654 ddr2_get_dimm_width( uint8_t *f_spd_pu08 )
656 static const int WIDTH_IDX = (int) 6;
658 return (uint32_t) f_spd_pu08[WIDTH_IDX];
662 ddr2_get_dimm_ecc( uint8_t *f_spd_pu08 )
664 static const int ECC_IDX = (int) 11;
666 return ( f_spd_pu08[ECC_IDX] & BIT(1) ) != 0;
670 ddr2_get_dimm_burstlen( uint8_t *f_spd_pu08 )
672 static const int BURST_IDX = (int) 16;
674 return (uint32_t) f_spd_pu08[BURST_IDX];
678 ddr2_get_dimm_speed( dimm_t *f_dimm, uint8_t *f_spd_pu08 )
680 static const int SPEED_IDX[] = { 25, 23, 9 };
681 static const uint32_t NS[] = { 25, 33, 66, 75 };
683 uint32_t l_dspeed_u32;
687 for( i = NUM_CL - f_dimm->m_clcnt_u32; i < NUM_CL; i++ ) {
688 l_tmp_u08 = f_spd_pu08[SPEED_IDX[i]];
689 l_dspeed_u32 = (uint32_t) ( l_tmp_u08 >> 4 ) * 100;
690 l_tmp_u08 &= (uint8_t) 0xf;
692 if( l_tmp_u08 >= (uint8_t) 10 ) {
693 l_dspeed_u32 += NS[l_tmp_u08 - 10];
695 l_dspeed_u32 += (uint32_t) l_tmp_u08 * 10;
698 f_dimm->m_tCK_pu32[idx] = l_dspeed_u32;
699 f_dimm->m_speed_pu32[idx] = (uint32_t) 2000000 / l_dspeed_u32;
700 f_dimm->m_speed_pu32[idx] += (uint32_t) 5;
701 f_dimm->m_speed_pu32[idx] /= (uint32_t) 10;
708 ddr2_get_dimm_timings( dimm_t *f_dimm, uint8_t *f_spd_pu08 )
710 static const uint32_t NS[] = { 00, 25, 33, 50, 66, 75, 00, 00 };
711 static const uint32_t USMUL = (uint32_t) 390625;
712 static const int tREF_IDX = (int) 12;
713 static const int tRP_IDX = (int) 27;
714 static const int tRRD_IDX = (int) 28;
715 static const int tRCD_IDX = (int) 29;
716 static const int tRAS_IDX = (int) 30;
717 static const int tWR_IDX = (int) 36;
718 static const int tWTR_IDX = (int) 37;
719 static const int tRTP_IDX = (int) 38;
720 static const int tRC_IDX = (int) 41; // & 40
721 static const int tRFC_IDX = (int) 42; // & 40
725 f_dimm->m_tRP_u32 = (uint32_t) f_spd_pu08[tRP_IDX] * 25;
726 f_dimm->m_tRRD_u32 = (uint32_t) f_spd_pu08[tRRD_IDX] * 25;
727 f_dimm->m_tRCD_u32 = (uint32_t) f_spd_pu08[tRCD_IDX] * 25;
728 f_dimm->m_tWR_u32 = (uint32_t) f_spd_pu08[tWR_IDX] * 25;
729 f_dimm->m_tWTR_u32 = (uint32_t) f_spd_pu08[tWTR_IDX] * 25;
730 f_dimm->m_tRTP_u32 = (uint32_t) f_spd_pu08[tRTP_IDX] * 25;
731 f_dimm->m_tRAS_u32 = (uint32_t) f_spd_pu08[tRAS_IDX] * 100;
733 l_tmp_u32 = (uint32_t) ( f_spd_pu08[tRC_IDX - 1] >> 4 );
734 l_tmp_u32 &= (uint32_t) 0x7;
735 f_dimm->m_tRC_u32 = (uint32_t) f_spd_pu08[tRC_IDX] * 100 +
738 l_tmp_u32 = (uint32_t) f_spd_pu08[tRFC_IDX - 2];
739 l_tmp_u32 &= (uint32_t) 0xf;
740 f_dimm->m_tRFC_u32 = (uint32_t) 256 * ( l_tmp_u32 & (uint32_t) 0x1 );
741 f_dimm->m_tRFC_u32 += (uint32_t) f_spd_pu08[tRFC_IDX];
742 f_dimm->m_tRFC_u32 *= 100;
744 f_dimm->m_tRFC_u32 += NS[l_tmp_u32];
746 l_tmp_u32 = (uint32_t) f_spd_pu08[tREF_IDX];
747 l_tmp_u32 &= (uint32_t) 0x7f;
749 if( l_tmp_u32 == 0 ) {
750 l_tmp_u32 = (uint32_t) 2;
751 } else if( l_tmp_u32 <= (uint32_t) 2 ) {
755 f_dimm->m_tREF_u32 = ( l_tmp_u32 + 1 ) * USMUL;
759 ddr2_get_banks( uint8_t *f_spd_pu08 )
761 static const int BANK_IDX = (int) 17;
763 return (uint32_t) f_spd_pu08[BANK_IDX];
767 ddr2_get_cl_mask( uint8_t *f_spd_pu08 )
769 static const int CL_IDX = (int) 18;
771 return (uint32_t) f_spd_pu08[CL_IDX];
775 ddr2_get_cl( dimm_t *f_dimm )
777 uint32_t l_clcnt_u32 = 0;
780 for( i = 0; ( i < 8 ) && ( l_clcnt_u32 < NUM_CL ) ; i++ ) {
782 if( ( f_dimm->m_clmsk_u32 & ( (uint32_t) 0x1 << i ) ) != 0 ) {
783 f_dimm->m_clval_pu32[l_clcnt_u32] = i;
789 f_dimm->m_clcnt_u32 = l_clcnt_u32;
793 ddr2_cl2speed( dimm_t *f_dimm, uint32_t f_cl_u32, uint32_t *f_tCK_pu32 )
797 for(i = 0; (i < NUM_CL) && (f_dimm->m_clval_pu32[i] != f_cl_u32); i++);
800 return (uint32_t) ~0;
803 *f_tCK_pu32 = f_dimm->m_tCK_pu32[i];
805 return f_dimm->m_speed_pu32[i];
809 ddr2_setupDIMM( dimm_t *f_dimm, uint32_t f_bank_u32, uint8_t *f_spd_pu08 )
811 f_dimm->m_pop_u32 = SL_POP;
812 f_dimm->m_bank_u32 = f_bank_u32;
813 f_dimm->m_size_u32 = ddr2_get_dimm_size( f_spd_pu08 );
814 f_dimm->m_rank_u32 = ddr2_get_dimm_rank( f_spd_pu08 );
815 f_dimm->m_type_u32 = ddr2_get_dimm_type( f_spd_pu08 );
816 f_dimm->m_orgval_u32 = ddr2_get_dimm_org( f_spd_pu08, &f_dimm->m_orgmsk_u32 );
817 f_dimm->m_width_u32 = ddr2_get_dimm_width( f_spd_pu08 );
818 f_dimm->m_ecc_u32 = ddr2_get_dimm_ecc( f_spd_pu08 );
819 f_dimm->m_burst_u32 = ddr2_get_dimm_burstlen( f_spd_pu08 );
820 f_dimm->m_clmsk_u32 = ddr2_get_cl_mask( f_spd_pu08 );
821 f_dimm->m_bankcnt_u32 = ddr2_get_banks( f_spd_pu08 );
823 ddr2_get_cl( f_dimm );
824 ddr2_get_dimm_speed( f_dimm, f_spd_pu08 );
825 ddr2_get_dimm_timings( f_dimm, f_spd_pu08 );
829 ddr2_checkSPD( uint8_t *f_spd_pu08 )
834 for( i = 0; i < SPD_BUF_SIZE - 1; i++ ) {
835 crc += f_spd_pu08[i];
838 if( crc != f_spd_pu08[i] ) {
846 ddr2_readSPDs( void )
848 static const uint32_t MAX_SPD_FAIL = 3;
849 uint8_t l_spdbuf_pu08[SPD_BUF_SIZE];
850 uint32_t l_bankfail_u32 = 0;
851 uint32_t l_spdfail_u32 = 0;
852 int32_t l_i2c_i32 = RET_OK;
853 int32_t l_spd_i32 = RET_OK;
854 int32_t ret = RET_OK;
858 * read spd's and detect populated slots
860 for( i = 0; i < NUM_SLOTS; i++ ) {
862 * indicate slot as empty
864 m_dimm[i].m_pop_u32 = 0;
867 * check whether bank is switched off
869 if( ( m_bankoff_u32 & ( 0x1 << ( i / 2 ) ) ) != 0 ) {
878 * reset SPD fail counter
880 l_spdfail_u32 = MAX_SPD_FAIL;
883 while( l_spdfail_u32 != 0 ) {
884 l_i2c_i32 = i2c_read( I2C_START + i, 0x0, l_spdbuf_pu08, SPD_BUF_SIZE );
886 if( l_i2c_i32 == RET_OK ) {
887 l_spd_i32 = ddr2_checkSPD( l_spdbuf_pu08 );
889 if( l_spd_i32 == RET_OK ) {
901 if( l_spd_i32 != RET_OK ) {
903 printf( "\r\n [ERROR -> SPD read failure in slot %u]",
904 i2c_get_slot( I2C_START + i ) );
907 l_bankfail_u32 |= ( 0x1 << ( i / 2 ) );
909 } else if( l_i2c_i32 == RET_OK ) {
913 ddr2_setupDIMM( &m_dimm[i], i / 2, l_spdbuf_pu08 );
915 m_dptr[m_dcnt_u32] = &m_dimm[i];
921 if( ret != RET_OK ) {
922 m_bankoff_u32 |= l_bankfail_u32;
932 ddr2_setupDIMMcfg( void )
940 * check wether on board DIMM slot population is valid
944 for( i = 0; i < NUM_SLOTS; i += 2 ) {
946 switch( m_dimm[i].m_pop_u32 + m_dimm[i+1].m_pop_u32 ) {
948 m_bankpop_u32[i/2] = 0;
953 m_bankpop_u32[i/2] = !0;
960 printf( "\r\n [ERROR -> only 1 DIMM installed in bank %u]", i/2 );
981 printf( "\r\n [ERROR -> no (functional) memory installed]\r\n" );
987 * check DIMM compatibility
988 * configuration is 128 bit data/128 bit bus
989 * -all DIMMs must be organized as x4
990 * -all DIMMs must be 72 bit wide with ECC
991 * -all DIMMs must be registered DIMMs (RDIMMs)
992 * -paired DIMMs must have the same # of ranks, size & organization
996 * check DIMM ranks & sizes
999 for( i = 0; i < NUM_SLOTS; i += 2 ) {
1001 if( ( m_bankpop_u32[i/2] != 0 ) &&
1002 ( ( m_dimm[i].m_rank_u32 != m_dimm[i+1].m_rank_u32 ) ||
1003 ( m_dimm[i].m_size_u32 != m_dimm[i+1].m_size_u32 ) ) ) {
1005 printf( "\r\n [ERROR -> installed DIMMs in bank %u have different ranks/sizes]", i/2 );
1023 * check valid DIMM organisation (must be x4)
1026 for( i = 0; i < m_dcnt_u32; i++ ) {
1028 if( ( m_dptr[i]->m_orgmsk_u32 & DIMM_ORG_x4 ) == 0 ) {
1030 printf( "\r\n [ERROR -> wrong DIMM organisation in bank %u]",
1031 m_dptr[i]->m_bank_u32 );
1049 for( i = 0; i < m_dcnt_u32; i++ ) {
1050 e &= m_dptr[i]->m_type_u32;
1058 printf( "\r\n [ERROR -> installed DIMMs are of different type]\r\n" );
1064 * setup generic dimm
1066 m_gendimm.m_type_u32 = e;
1069 * check valid width, ecc & burst length
1072 for( i = 0; i < m_dcnt_u32; i++ ) {
1074 if( m_dptr[i]->m_width_u32 != DIMM_WIDTH ) {
1076 printf( "\r\n [ERROR -> invalid DIMM width in bank %u]",
1077 m_dptr[i]->m_bank_u32 );
1082 if( m_dptr[i]->m_ecc_u32 == 0 ) {
1084 printf( "\r\n [ERROR -> DIMM(s) do not support ECC in bank %u]",
1085 m_dptr[i]->m_bank_u32 );
1090 if( ( m_dptr[i]->m_burst_u32 & DIMM_BURSTLEN_4 ) == 0 ) {
1092 printf( "\r\n [ERROR -> DIMM(s) have invalid burst length in bank %u]",
1093 m_dptr[i]->m_bank_u32 );
1111 * setup generic dimm
1113 m_gendimm.m_width_u32 = m_dptr[0]->m_width_u32;
1114 m_gendimm.m_ecc_u32 = m_dptr[0]->m_ecc_u32;
1115 m_gendimm.m_burst_u32 = m_dptr[0]->m_burst_u32;
1120 m_gendimm.m_pop_u32 = SL_POP;
1123 * setup timing parameters
1127 * find smallest common CL value
1129 l_tmp_u32 = (uint32_t) ~0;
1130 for( i = 0; i < m_dcnt_u32; i++ ) {
1131 l_tmp_u32 &= m_dptr[i]->m_clmsk_u32;
1134 m_gendimm.m_clmsk_u32 = l_tmp_u32;
1135 ddr2_get_cl( &m_gendimm );
1138 * find fastest common DIMM speed for all common CL values
1140 for( i = 0; i < m_gendimm.m_clcnt_u32; i++ ) {
1141 m_gendimm.m_speed_pu32[i] = (uint32_t) ~0;
1143 for( j = 0; j < m_dcnt_u32; j++ ) {
1145 ddr2_cl2speed( m_dptr[j],
1146 m_gendimm.m_clval_pu32[i],
1149 if( m_gendimm.m_speed_pu32[i] > l_tmp0_u32 ) {
1150 m_gendimm.m_speed_pu32[i] = l_tmp0_u32;
1151 m_gendimm.m_tCK_pu32[i] = l_tmp1_u32;
1159 * check wether cl values are supported by U4
1161 for( i = 0; i < m_gendimm.m_clcnt_u32; i++ ) {
1163 if( ( m_gendimm.m_clval_pu32[i] >= U4_MIN_CL ) &&
1164 ( m_gendimm.m_clval_pu32[i] <= U4_MAX_CL ) ) {
1170 if( i == m_gendimm.m_clcnt_u32 ) {
1172 printf( "\r\n [ERROR -> DIMM's CL values not supported]\r\n" );
1178 * choose cl/speed values to use: prefer speed over CL
1179 * i holds smallest supported cl value of u4 already
1182 while( i < m_gendimm.m_clcnt_u32 ) {
1184 if( l_tmp_u32 < m_gendimm.m_speed_pu32[i] ) {
1185 l_tmp_u32 = m_gendimm.m_speed_pu32[i];
1193 * choose largest number of banks
1195 m_gendimm.m_bankcnt_u32 = 0;
1197 for( i = 0; i < m_dcnt_u32; i++ ) {
1199 if( m_gendimm.m_bankcnt_u32 < m_dptr[i]->m_bankcnt_u32 ) {
1200 m_gendimm.m_bankcnt_u32 = m_dptr[i]->m_bankcnt_u32;
1206 * setup fastest possible timing parameters for all DIMMs
1208 m_gendimm.m_tRP_u32 = 0;
1209 m_gendimm.m_tRRD_u32 = 0;
1210 m_gendimm.m_tRCD_u32 = 0;
1211 m_gendimm.m_tWR_u32 = 0;
1212 m_gendimm.m_tWTR_u32 = 0;
1213 m_gendimm.m_tRTP_u32 = 0;
1214 m_gendimm.m_tRAS_u32 = 0;
1215 m_gendimm.m_tRC_u32 = 0;
1216 m_gendimm.m_tRFC_u32 = 0;
1217 m_gendimm.m_tREF_u32 = (uint32_t) ~0;
1219 for( i = 0; i < m_dcnt_u32; i++ ) {
1221 if( m_gendimm.m_tRP_u32 < m_dptr[i]->m_tRP_u32 ) {
1222 m_gendimm.m_tRP_u32 = m_dptr[i]->m_tRP_u32;
1225 if( m_gendimm.m_tRRD_u32 < m_dptr[i]->m_tRRD_u32 ) {
1226 m_gendimm.m_tRRD_u32 = m_dptr[i]->m_tRRD_u32;
1229 if( m_gendimm.m_tRCD_u32 < m_dptr[i]->m_tRCD_u32 ) {
1230 m_gendimm.m_tRCD_u32 = m_dptr[i]->m_tRCD_u32;
1233 if( m_gendimm.m_tWR_u32 < m_dptr[i]->m_tWR_u32 ) {
1234 m_gendimm.m_tWR_u32 = m_dptr[i]->m_tWR_u32;
1237 if( m_gendimm.m_tWTR_u32 < m_dptr[i]->m_tWTR_u32 ) {
1238 m_gendimm.m_tWTR_u32 = m_dptr[i]->m_tWTR_u32;
1241 if( m_gendimm.m_tRTP_u32 < m_dptr[i]->m_tRTP_u32 ) {
1242 m_gendimm.m_tRTP_u32 = m_dptr[i]->m_tRTP_u32;
1245 if( m_gendimm.m_tRAS_u32 < m_dptr[i]->m_tRAS_u32 ) {
1246 m_gendimm.m_tRAS_u32 = m_dptr[i]->m_tRAS_u32;
1249 if( m_gendimm.m_tRC_u32 < m_dptr[i]->m_tRC_u32 ) {
1250 m_gendimm.m_tRC_u32 = m_dptr[i]->m_tRC_u32;
1253 if( m_gendimm.m_tRFC_u32 < m_dptr[i]->m_tRFC_u32 ) {
1254 m_gendimm.m_tRFC_u32 = m_dptr[i]->m_tRFC_u32;
1257 if( m_gendimm.m_tREF_u32 > m_dptr[i]->m_tREF_u32 ) {
1258 m_gendimm.m_tREF_u32 = m_dptr[i]->m_tREF_u32;
1267 u4_group2dimmsDS( dimm_t *f_dimm0, dimm_t *f_dimm1 )
1269 dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
1272 * known conditions at this point:
1273 * -at least 2 slots are populated
1274 * -the 2 DIMMs are equal
1275 * -DIMMs are double sided (2 ranks)
1278 * 1 group of 2 ranks (2 ranks/2 DIMMs)
1279 * -> CS mode 1 (one double sided DIMM pair)
1281 l_dgr->m_size_u32 = 2 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
1282 l_dgr->m_ss_u32 = 0;
1283 l_dgr->m_csmode_u32 = 1;
1284 l_dgr->m_dcnt_u32 = 2;
1285 l_dgr->m_dptr[0] = f_dimm0;
1286 l_dgr->m_dptr[1] = f_dimm1;
1292 u4_group2dimmsSS( dimm_t *f_dimm0, dimm_t *f_dimm1 )
1294 dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
1297 * known conditions at this point:
1298 * -at least 2 slots are populated
1299 * -the 2 DIMMs are equal
1300 * -DIMMs are single sided (1 rank)
1303 * 1 group of 1 rank (1 rank/2 DIMMs)
1304 * -> CS mode 0 (one single sided DIMM pair)
1306 l_dgr->m_size_u32 = 2 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
1307 l_dgr->m_ss_u32 = 1;
1308 l_dgr->m_csmode_u32 = 0;
1309 l_dgr->m_dcnt_u32 = 2;
1310 l_dgr->m_dptr[0] = f_dimm0;
1311 l_dgr->m_dptr[1] = f_dimm1;
1317 u4_group4dimmsDS( dimm_t *f_dimm0, dimm_t *f_dimm1,
1318 dimm_t *f_dimm2, dimm_t *f_dimm3 )
1320 dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
1323 * known conditions at this point:
1324 * -4 slots are populated
1325 * -all 4 DIMMs are equal
1326 * -DIMMs are double sided (2 ranks)
1329 * 1 group of 4 ranks (2 ranks/2 DIMMs)
1330 * -> CS mode 2 (two double sided DIMM pairs)
1332 l_dgr->m_size_u32 = 4 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
1333 l_dgr->m_ss_u32 = 0;
1334 l_dgr->m_csmode_u32 = 2;
1335 l_dgr->m_dcnt_u32 = 4;
1336 l_dgr->m_dptr[0] = f_dimm0;
1337 l_dgr->m_dptr[1] = f_dimm1;
1338 l_dgr->m_dptr[2] = f_dimm2;
1339 l_dgr->m_dptr[3] = f_dimm3;
1345 u4_group4dimmsSS( dimm_t *f_dimm0, dimm_t *f_dimm1,
1346 dimm_t *f_dimm2, dimm_t *f_dimm3 )
1348 dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
1351 * known conditions at this point:
1352 * -4 slots are populated
1353 * -all 4 DIMMs are equal
1354 * -DIMMs are single sided (1 rank)
1357 * 1 group of 2 ranks (1 rank/2 DIMMs)
1358 * -> CS mode 1 (two single sided DIMM pairs)
1360 l_dgr->m_size_u32 = 4 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
1361 l_dgr->m_ss_u32 = 1;
1362 l_dgr->m_csmode_u32 = 1;
1363 l_dgr->m_dcnt_u32 = 4;
1364 l_dgr->m_dptr[0] = f_dimm0;
1365 l_dgr->m_dptr[1] = f_dimm1;
1366 l_dgr->m_dptr[2] = f_dimm2;
1367 l_dgr->m_dptr[3] = f_dimm3;
1373 u4_group8dimmsDS( dimm_t *f_dimm0, dimm_t *f_dimm1,
1374 dimm_t *f_dimm2, dimm_t *f_dimm3,
1375 dimm_t *f_dimm4, dimm_t *f_dimm5,
1376 dimm_t *f_dimm6, dimm_t *f_dimm7 )
1378 dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
1381 * known conditions at this point:
1382 * -8 slots are populated
1383 * -all 8 DIMMs are equal
1384 * -DIMMs are double sided (2 ranks)
1387 * 1 group of 8 ranks (2 ranks/2 DIMMs)
1388 * -> CS mode 3 (four double sided DIMM pairs)
1390 l_dgr->m_size_u32 = 8 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
1391 l_dgr->m_ss_u32 = 0;
1392 l_dgr->m_csmode_u32 = 3;
1393 l_dgr->m_dcnt_u32 = 8;
1394 l_dgr->m_dptr[0] = f_dimm0;
1395 l_dgr->m_dptr[1] = f_dimm1;
1396 l_dgr->m_dptr[2] = f_dimm2;
1397 l_dgr->m_dptr[3] = f_dimm3;
1398 l_dgr->m_dptr[4] = f_dimm4;
1399 l_dgr->m_dptr[5] = f_dimm5;
1400 l_dgr->m_dptr[6] = f_dimm6;
1401 l_dgr->m_dptr[7] = f_dimm7;
1407 u4_group8dimmsSS( dimm_t *f_dimm0, dimm_t *f_dimm1,
1408 dimm_t *f_dimm2, dimm_t *f_dimm3,
1409 dimm_t *f_dimm4, dimm_t *f_dimm5,
1410 dimm_t *f_dimm6, dimm_t *f_dimm7 )
1412 dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
1415 * known conditions at this point:
1416 * -8 slots are populated
1417 * -all 8 DIMMs are equal
1418 * -DIMMs are single sided (1 rank)
1421 * 1 group of 4 ranks (1 rank/2 DIMMs)
1422 * -> CS mode 2 (four single sided DIMM pairs)
1424 l_dgr->m_size_u32 = 8 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
1425 l_dgr->m_ss_u32 = 1;
1426 l_dgr->m_csmode_u32 = 2;
1427 l_dgr->m_dcnt_u32 = 8;
1428 l_dgr->m_dptr[0] = f_dimm0;
1429 l_dgr->m_dptr[1] = f_dimm1;
1430 l_dgr->m_dptr[2] = f_dimm2;
1431 l_dgr->m_dptr[3] = f_dimm3;
1432 l_dgr->m_dptr[4] = f_dimm4;
1433 l_dgr->m_dptr[5] = f_dimm5;
1434 l_dgr->m_dptr[6] = f_dimm6;
1435 l_dgr->m_dptr[7] = f_dimm7;
1441 u4_Dcmp( dimm_t *f_dimm0, dimm_t *f_dimm1 )
1444 if( ( f_dimm0->m_size_u32 == f_dimm1->m_size_u32 ) &&
1445 ( f_dimm0->m_rank_u32 == f_dimm1->m_rank_u32 ) ) {
1453 u4_group1banks( uint32_t *bidx )
1455 uint32_t didx = 2 * bidx[0];
1458 * known conditions at this point:
1459 * -either DIMMs 0 & 4 or
1462 * DIMMs 3 & 7 are populated
1463 * -3 (bimini)/1 (maui) pair of slots is empty
1464 * -installed DIMMs are equal
1468 * double/single sided setup
1470 if( m_dimm[didx].m_rank_u32 == 1 ) {
1471 u4_group2dimmsSS( &m_dimm[didx], &m_dimm[didx+1] );
1473 u4_group2dimmsDS( &m_dimm[didx], &m_dimm[didx+1] );
1479 u4_group2banks( uint32_t *bidx )
1481 uint32_t didx0 = 2 * bidx[0];
1482 uint32_t didx1 = 2 * bidx[1];
1485 * known conditions at this point:
1486 * -4 slots are populated
1490 * check wether DIMM banks may be grouped
1492 if( ( ( ( bidx[0] + bidx[1] ) & 0x1 ) != 0 ) &&
1493 ( u4_Dcmp( &m_dimm[didx0], &m_dimm[didx1] ) == 0 ) ) {
1495 * double/single sided setup
1496 * NOTE: at this point all DIMMs have the same amount
1497 * of ranks, therefore only the # of ranks on DIMM 0 is checked
1499 if( m_dimm[didx0].m_rank_u32 == 1 ) {
1500 u4_group4dimmsSS( &m_dimm[didx0], &m_dimm[didx0+1],
1501 &m_dimm[didx1], &m_dimm[didx1+1]);
1503 u4_group4dimmsDS( &m_dimm[didx0], &m_dimm[didx0+1],
1504 &m_dimm[didx1], &m_dimm[didx1+1]);
1508 u4_group1banks( &bidx[0] );
1509 u4_group1banks( &bidx[1] );
1515 u4_group3banks( uint32_t *bidx )
1518 if( ( bidx[0] == 0 ) && ( bidx[1] == 1 ) ) {
1519 u4_group2banks( &bidx[0] );
1520 u4_group1banks( &bidx[2] );
1521 } else if( ( bidx[1] == 2 ) && ( bidx[2] == 3 ) ) {
1522 u4_group2banks( &bidx[1] );
1523 u4_group1banks( &bidx[0] );
1529 u4_group4banks( uint32_t *bidx )
1531 uint32_t didx0 = 2 * bidx[0];
1532 uint32_t didx1 = 2 * bidx[1];
1533 uint32_t didx2 = 2 * bidx[2];
1534 uint32_t didx3 = 2 * bidx[3];
1536 if( ( u4_Dcmp( &m_dimm[didx0], &m_dimm[didx1] ) == RET_OK ) &&
1537 ( u4_Dcmp( &m_dimm[didx2], &m_dimm[didx3] ) == RET_OK ) &&
1538 ( u4_Dcmp( &m_dimm[didx0], &m_dimm[didx2] ) == RET_OK ) ) {
1540 if( m_dimm[didx0].m_rank_u32 == 1 ) {
1541 u4_group8dimmsSS( &m_dimm[didx0], &m_dimm[didx0+1],
1542 &m_dimm[didx1], &m_dimm[didx1+1],
1543 &m_dimm[didx2], &m_dimm[didx2+1],
1544 &m_dimm[didx3], &m_dimm[didx3+1] );
1546 u4_group8dimmsDS( &m_dimm[didx0], &m_dimm[didx0+1],
1547 &m_dimm[didx1], &m_dimm[didx1+1],
1548 &m_dimm[didx2], &m_dimm[didx2+1],
1549 &m_dimm[didx3], &m_dimm[didx3+1] );
1553 u4_group2banks( &bidx[0] );
1554 u4_group2banks( &bidx[2] );
1560 u4_sortDIMMgroups( void )
1565 * setup global group pointers
1567 for( i = 0; i < m_dgrcnt_u32; i++ ) {
1568 m_dgrptr[i] = &m_dgroup[i];
1572 * use a simple bubble sort to sort groups by size (descending)
1574 for( i = 0; i < ( m_dgrcnt_u32 - 1 ); i++ ) {
1576 for( j = i + 1; j < m_dgrcnt_u32; j++ ) {
1578 if( m_dgrptr[i]->m_size_u32 < m_dgrptr[j]->m_size_u32 ) {
1581 l_sgr = m_dgrptr[i];
1582 m_dgrptr[i] = m_dgrptr[j];
1583 m_dgrptr[j] = l_sgr;
1593 u4_calcDIMMcnfg( void )
1595 static const uint32_t _2GB = (uint32_t) 0x00800;
1596 static const uint32_t _4GB = (uint32_t) 0x01000;
1597 static const uint32_t _64GB = (uint32_t) 0x10000;
1598 uint32_t l_start_u32 = (uint32_t) 0;
1599 uint32_t l_end_u32 = (uint32_t) 0;
1600 uint32_t l_add2g_u32 = (uint32_t) 1;
1601 uint32_t l_sub2g_u32 = (uint32_t) 1;
1605 * setup DIMM group parameters
1607 for( i = 0; i < m_dgrcnt_u32; i++ ) {
1608 l_end_u32 = l_start_u32 + m_dgrptr[i]->m_size_u32;
1610 if( m_dgrptr[i]->m_size_u32 > _2GB ) {
1612 if( l_end_u32 < _64GB ) {
1613 l_add2g_u32 = ( l_end_u32 >> 11 );
1618 if( l_start_u32 == 0 ) {
1621 l_sub2g_u32 = ( l_start_u32 >> 11 );
1624 } else if( l_add2g_u32 != 1 ) {
1625 l_start_u32 += _2GB;
1632 * save values for the group
1634 m_dgrptr[i]->m_start_u32 = ( l_start_u32 >> 7 ); // = /128
1635 m_dgrptr[i]->m_end_u32 = ( l_end_u32 >> 7 );
1636 m_dgrptr[i]->m_add2g_u32 = l_add2g_u32;
1637 m_dgrptr[i]->m_sub2g_u32 = l_sub2g_u32;
1640 * continue with next group
1642 if( l_end_u32 != _2GB ) {
1643 l_start_u32 = l_end_u32;
1653 u4_calcDIMMmemmode( void )
1655 static const uint32_t MAX_ORG = (uint32_t) 0x10;
1656 static const uint32_t MIN_BASE = (uint32_t) 0x80;
1657 static const uint32_t MAX_MODE = (uint32_t) 0x10;
1658 static const uint32_t MODE_ADD = (uint32_t) 0x04;
1660 uint32_t l_modeoffs_u32;
1661 uint32_t l_sizebase_u32;
1662 int32_t ret = RET_OK;
1666 * loop through all DIMM groups and calculate memmode setting
1668 for( i = 0; i < m_dgrcnt_u32; i++ ) {
1669 l_dptr = m_dgrptr[i]->m_dptr[0]; // all dimms in one group are equal!
1671 l_modeoffs_u32 = MAX_ORG / l_dptr->m_orgval_u32;
1672 l_modeoffs_u32 /= (uint32_t) 2;
1673 l_sizebase_u32 = ( MIN_BASE << l_modeoffs_u32 );
1676 while( ( l_sizebase_u32 != l_dptr->m_size_u32 ) &&
1677 ( j < MAX_MODE ) ) {
1678 l_sizebase_u32 <<= 1;
1679 j += (uint32_t) MODE_ADD;
1683 if( j >= MAX_MODE ) {
1686 printf( "\r\n [ERROR -> unsupported memory type in bank(s)" );
1689 for( k = 0; k < m_dgrptr[i]->m_dcnt_u32; k++ ) {
1690 b = m_dgrptr[i]->m_dptr[k]->m_bank_u32;
1692 if( ( l & ( 1 << b ) ) == 0 ) {
1704 m_dgrptr[i]->m_memmd_u32 = l_modeoffs_u32 + j;
1713 u4_setupDIMMgroups( void )
1715 static const uint64_t _1MB = (uint64_t) 0x100000;
1716 uint32_t l_bcnt_u32;
1717 uint32_t l_bidx_u32[NUM_BANKS];
1721 * calculate number of populated banks
1722 * IMPORTANT: array must be in ascending order!
1725 for( i = 0; i < NUM_BANKS; i++ ) {
1727 if( m_bankpop_u32[i] != 0 ) {
1728 l_bidx_u32[l_bcnt_u32] = i;
1734 switch( l_bcnt_u32 ) {
1735 case 4: u4_group4banks( &l_bidx_u32[0] ); break;
1736 case 3: u4_group3banks( &l_bidx_u32[0] ); break;
1737 case 2: u4_group2banks( &l_bidx_u32[0] ); break;
1738 case 1: u4_group1banks( &l_bidx_u32[0] ); break;
1742 * sort DIMM groups by size (descending)
1744 u4_sortDIMMgroups();
1747 * calculate overall memory size in bytes
1748 * (group size is in MB)
1751 for( i = 0; i < m_dgrcnt_u32; i++ ) {
1752 m_memsize_u64 += (uint64_t) m_dgrptr[i]->m_size_u32 * _1MB;
1758 u4_setup_core_clock( void )
1760 static const uint32_t MCLK = (uint32_t) 266;
1761 static const uint32_t CDIV = (uint32_t) 66;
1762 static const uint32_t CMAX = (uint32_t) 7;
1763 static const uint32_t MERR = (uint32_t) 10;
1764 uint32_t volatile l_cclk_u32;
1765 uint32_t volatile l_pll2_u32;
1769 printf( " [core clock reset: ]" );
1773 * calculate speed value
1775 s = m_gendimm.m_speed_pu32[m_dclidx_u32];
1780 * insert new core clock value
1782 l_cclk_u32 = load32_ci( ClkCntl_R );
1783 l_cclk_u32 &= ~CLK_DDR_CLK_MSK;
1784 l_cclk_u32 |= ( s << 18 );
1790 printf( "\b\b\b\bERR\r\n" );
1798 store32_ci( ClkCntl_R, l_cclk_u32 );
1800 or32_ci( PLL2Cntl_R, IBIT(0) );
1804 * wait for reset to finish
1807 l_pll2_u32 = load32_ci( PLL2Cntl_R );
1808 } while( ( l_pll2_u32 & IBIT(0) ) != 0 );
1811 * wait for stable PLL
1815 l_pll2_u32 = ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
1817 for( i = 0; i < 4; i++ ) {
1818 l_pll2_u32 &= ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
1819 l_pll2_u32 &= ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
1820 l_pll2_u32 &= ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
1824 } while( ( l_pll2_u32 == 0 ) && ( s++ < MERR ) );
1828 printf( "\b\b\b\bERR\r\n" );
1834 printf( "\b\b\bOK\r\n" );
1841 u4_auto_calib_init( void )
1843 static const uint32_t SEQ[] = {
1844 0xb1000000, 0xd1000000, 0xd1000000, 0xd1000000,
1845 0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000,
1846 0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000,
1847 0xd1000000, 0xd1000000, 0xd1000400, 0x00000000,
1853 for( i = MemInit00_R, j = 0; i <= MemInit15_R; i += 0x10, j++ ) {
1854 store32_ci( i, SEQ[j] );
1861 u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 )
1863 static const uint32_t MemProgCntl_V = (uint32_t) 0x80000500;
1864 static const uint32_t CalConf0_V = (uint32_t) 0x0000aa10;
1865 uint32_t l_MemProgCntl_u32;
1866 uint32_t l_CalConf0_u32;
1867 uint32_t l_MeasStat_u32;
1868 uint32_t l_CalC_u32;
1869 uint64_t MeasStat_R;
1875 if( f_BLane_u32 < 4 ) {
1876 MeasStat_R = MeasStatusC0_R;
1878 VerC_R = RstLdEnVerniersC0_R;
1879 } else if( f_BLane_u32 < 8 ) {
1881 MeasStat_R = MeasStatusC1_R;
1883 VerC_R = RstLdEnVerniersC1_R;
1884 } else if( f_BLane_u32 < 12 ) {
1886 MeasStat_R = MeasStatusC2_R;
1888 VerC_R = RstLdEnVerniersC2_R;
1889 } else if( f_BLane_u32 == 16 ) {
1891 MeasStat_R = MeasStatusC1_R;
1893 VerC_R = RstLdEnVerniersC1_R;
1894 } else if( f_BLane_u32 == 17 ) {
1896 MeasStat_R = MeasStatusC3_R;
1898 VerC_R = RstLdEnVerniersC3_R;
1901 MeasStat_R = MeasStatusC3_R;
1903 VerC_R = RstLdEnVerniersC3_R;
1906 shft = (uint32_t) 28 - ( f_BLane_u32 * 4 );
1909 * start auto calibration logic & wait for completion
1911 or32_ci( MeasStat_R, IBIT(0) );
1914 l_MeasStat_u32 = load32_ci( MeasStat_R );
1915 } while( ( l_MeasStat_u32 & IBIT(0) ) == 1 );
1917 l_CalConf0_u32 = CalConf0_V;
1918 store32_ci( CalConf0_R, l_CalConf0_u32 );
1920 for( v = 0x000; v < (uint32_t) 0x100; v++ ) {
1921 store32_ci( VerC_R, ( v << 24 ) | ( v << 16 ) );
1923 l_MemProgCntl_u32 = MemProgCntl_V;
1924 l_MemProgCntl_u32 |=
1925 ( (uint32_t) 0x00800000 >> f_Rank_u32 );
1926 store32_ci( MemProgCntl_R, l_MemProgCntl_u32 );
1929 l_MemProgCntl_u32 = load32_ci( MemProgCntl_R );
1930 } while( ( l_MemProgCntl_u32 & IBIT(1) ) == 0 );
1932 l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) &
1935 if( l_CalC_u32 != (uint32_t) 0xa ) {
1942 if( v == (uint32_t) 0x100 ) {
1951 u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 )
1953 static const uint32_t MemProgCntl_V = (uint32_t) 0x80000f00;
1954 static const uint32_t CalConf0_V = (uint32_t) 0x0000ac10;
1955 uint32_t l_MemProgCntl_u32;
1956 uint32_t l_CalConf0_u32;
1957 uint32_t l_MeasStat_u32;
1958 uint32_t l_CalC_u32;
1959 uint64_t MeasStat_R;
1965 if( f_BLane_u32 < 4 ) {
1966 MeasStat_R = MeasStatusC0_R;
1968 VerC_R = RstLdEnVerniersC0_R;
1969 } else if( f_BLane_u32 < 8 ) {
1971 MeasStat_R = MeasStatusC1_R;
1973 VerC_R = RstLdEnVerniersC1_R;
1974 } else if( f_BLane_u32 < 12 ) {
1976 MeasStat_R = MeasStatusC2_R;
1978 VerC_R = RstLdEnVerniersC2_R;
1979 } else if( f_BLane_u32 == 16 ) {
1981 MeasStat_R = MeasStatusC1_R;
1983 VerC_R = RstLdEnVerniersC1_R;
1984 } else if( f_BLane_u32 == 17 ) {
1986 MeasStat_R = MeasStatusC3_R;
1988 VerC_R = RstLdEnVerniersC3_R;
1991 MeasStat_R = MeasStatusC3_R;
1993 VerC_R = RstLdEnVerniersC3_R;
1996 shft = (uint32_t) 28 - ( f_BLane_u32 * 4 );
1999 * start auto calibration logic & wait for completion
2001 or32_ci( MeasStat_R, IBIT(0) );
2004 l_MeasStat_u32 = load32_ci( MeasStat_R );
2005 } while( ( l_MeasStat_u32 & IBIT(0) ) == 1 );
2007 l_CalConf0_u32 = CalConf0_V;
2008 l_CalConf0_u32 |= ( f_BLane_u32 << 5 );
2009 store32_ci( CalConf0_R, l_CalConf0_u32 );
2011 for( v = 0x000; v < (uint32_t) 0x100; v++ ) {
2012 store32_ci( VerC_R, ( v << 24 ) | ( v << 16 ) );
2014 l_MemProgCntl_u32 = MemProgCntl_V;
2015 l_MemProgCntl_u32 |=
2016 ( (uint32_t) 0x00800000 >> f_Rank_u32 );
2017 store32_ci( MemProgCntl_R, l_MemProgCntl_u32 );
2020 l_MemProgCntl_u32 = load32_ci( MemProgCntl_R );
2021 } while( ( l_MemProgCntl_u32 & IBIT(1) ) == 0 );
2023 l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) &
2026 if( l_CalC_u32 != (uint32_t) 0xa ) {
2033 if( v == (uint32_t) 0x100 ) {
2041 u4_RMDF_Rank( uint32_t f_Rank_u32,
2042 uint32_t *f_Buf_pu32 )
2044 int32_t l_Err_pi32 = 0;
2047 for( b = 0; ( b < MAX_BLANE ) && ( l_Err_pi32 == 0 ); b++ ) {
2048 f_Buf_pu32[b] = u4_RMDF_BLane( f_Rank_u32, b );
2050 if( f_Buf_pu32[b] == (uint32_t) ~0 ) {
2053 } else if( f_Buf_pu32[b] == (uint32_t) ~1 ) {
2054 f_Buf_pu32[b] = (uint32_t) 0xff;
2064 u4_auto_calib_MemBus( auto_calib_t *f_ac_pt )
2066 uint32_t RdMacDly, RdMacCnt;
2067 uint32_t ResMuxDly, ResMuxCnt;
2069 uint32_t l_Buf_pu32[MAX_DRANKS][MAX_BLANE];
2070 uint32_t l_Rnk_pu32[MAX_DRANKS];
2077 * read starting delays out of the MemBus register
2079 RdMacDly = ( load32_ci( MemBusCnfg_R ) >> 28 ) & 0xf;
2080 ResMuxDly = ( load32_ci( MemBusCnfg_R ) >> 24 ) & 0xf;
2083 * initialize ranks as not populated
2085 for( r = 0; r < MAX_DRANKS; r++ ) {
2090 * run through every possible delays of
2091 * RdMacDly, ResMuxDly & RdPipeDly until
2092 * the first working configuration is found
2096 and32_ci( MemBusCnfg2_R, ~0x3 );
2097 or32_ci( MemBusCnfg2_R, RdPipeDly );
2099 RdMacCnt = RdMacDly;
2100 ResMuxCnt = ResMuxDly;
2103 * RdMacDly >= ResMuxDly
2106 and32_ci( MemBusCnfg_R, ( 1 << 24 ) - 1 );
2107 or32_ci( MemBusCnfg_R, ( RdMacCnt << 28 ) |
2108 ( ResMuxCnt << 24 ) );
2109 and32_ci( MemBusCnfg2_R, ( 1 << 28 ) - 1 );
2110 or32_ci( MemBusCnfg2_R, ( RdMacCnt << 28 ) );
2113 * check the current value for every installed
2114 * DIMM on each side for every bytelane
2118 ( n < NUM_SLOTS ) &&
2122 if( m_dimm[n].m_pop_u32 ) {
2124 * run through all 18 bytelanes of every rank
2127 ( r < n + m_dimm[n].m_rank_u32 ) &&
2134 &l_Buf_pu32[r][0] );
2142 * decrementation before exit is wanted!
2146 } while( ( ResMuxCnt > 0 ) &&
2147 ( l_Err_i32 != 0 ) );
2149 if( l_Err_i32 != 0 ) {
2153 } while( ( RdPipeDly < 4 ) &&
2154 ( l_Err_i32 != 0 ) );
2157 * if l_Err_pi32 == 0 the auto calibration passed ok
2159 if( l_Err_i32 != 0 ) {
2164 * insert delay values into return struct
2166 and32_ci( MemBusCnfg_R, ( 1 << 24 ) - 1 );
2167 or32_ci( MemBusCnfg_R, ( RdMacCnt << 28 ) |
2168 ( ResMuxCnt << 24 ) );
2169 and32_ci( MemBusCnfg2_R, ( ( 1 << 28 ) - 1 ) & ~0x3 );
2170 or32_ci( MemBusCnfg2_R, ( RdMacCnt << 28 ) | RdPipeDly );
2172 f_ac_pt->m_MemBusCnfg_u32 = load32_ci( MemBusCnfg_R );
2173 f_ac_pt->m_MemBusCnfg2_u32 = load32_ci( MemBusCnfg2_R );
2176 * calculate the average vernier setting for the
2177 * bytelanes which share one vernier
2179 for( b = 0; b < MAX_BLANE - 2; b += 2 ) {
2183 for( r = 0; r < MAX_DRANKS; r++ ) {
2185 * calculation is done or populated ranks only
2187 if( l_Rnk_pu32[r] != 0 ) {
2189 * calculate average value
2191 l_Ver_u32 += l_Buf_pu32[r][b];
2192 l_Ver_u32 += l_Buf_pu32[r][b+1];
2196 l_Ver_u32 += l_Buf_pu32[r][16];
2198 } else if( b == 12 ) {
2199 l_Ver_u32 += l_Buf_pu32[r][17];
2208 * average the values
2213 * set appropriate vernier register for
2214 * the current bytelane
2217 if( ( b & (uint32_t) 0x3 ) == 0 ) {
2219 f_ac_pt->m_RstLdEnVerniers_pu32[bidx] = l_Ver_u32;
2222 f_ac_pt->m_RstLdEnVerniers_pu32[bidx] |= l_Ver_u32;
2231 u4_auto_calib( auto_calib_t *f_ac_pt )
2233 uint32_t l_MemBusCnfg_S;
2234 uint32_t l_MemBusCnfg2_S;
2235 uint32_t l_RstLdEnVerniers_S[4];
2239 * save manipulated registers
2241 l_MemBusCnfg_S = load32_ci( MemBusCnfg_R );
2242 l_MemBusCnfg2_S = load32_ci( MemBusCnfg2_R );
2243 l_RstLdEnVerniers_S[0] = load32_ci( RstLdEnVerniersC0_R );
2244 l_RstLdEnVerniers_S[1] = load32_ci( RstLdEnVerniersC1_R );
2245 l_RstLdEnVerniers_S[2] = load32_ci( RstLdEnVerniersC2_R );
2246 l_RstLdEnVerniers_S[3] = load32_ci( RstLdEnVerniersC3_R );
2248 u4_auto_calib_init();
2249 l_Ret_i32 = u4_auto_calib_MemBus( f_ac_pt );
2252 * restore manipulated registers
2254 store32_ci( MemBusCnfg_R, l_MemBusCnfg_S );
2255 store32_ci( MemBusCnfg2_R, l_MemBusCnfg2_S );
2256 store32_ci( RstLdEnVerniersC0_R, l_RstLdEnVerniers_S[0] );
2257 store32_ci( RstLdEnVerniersC1_R, l_RstLdEnVerniers_S[1] );
2258 store32_ci( RstLdEnVerniersC2_R, l_RstLdEnVerniers_S[2] );
2259 store32_ci( RstLdEnVerniersC3_R, l_RstLdEnVerniers_S[3] );
2265 u4_checkeccerr( eccerror_t *f_ecc_pt )
2268 int32_t ret = RET_OK;
2270 l_val_u32 = load32_ci( MESR_R );
2273 if( ( l_val_u32 & (uint32_t) 0x7 ) != 0 ) {
2275 if( ( l_val_u32 & (uint32_t) 0x4 ) != 0 ) {
2278 } else if( ( l_val_u32 & (uint32_t) 0x1 ) != 0 ) {
2280 ret = RET_ACERR_UEWT;
2288 f_ecc_pt->m_err_i32 = ret;
2290 l_val_u32 = load32_ci( MEAR1_R );
2291 f_ecc_pt->m_uecnt_u32 = ( ( l_val_u32 >> 24 ) & (uint32_t) 0xff );
2292 f_ecc_pt->m_cecnt_u32 = ( ( l_val_u32 >> 16 ) & (uint32_t) 0xff );
2294 l_val_u32 = load32_ci( MEAR0_R );
2295 f_ecc_pt->m_rank_u32 = ( ( l_val_u32 >> 29 ) & (uint32_t) 0x7 );
2296 f_ecc_pt->m_col_u32 = ( ( l_val_u32 >> 18 ) & (uint32_t) 0x7ff );
2297 f_ecc_pt->m_row_u32 = ( ( l_val_u32 >> 0 ) & (uint32_t) 0x7fff );
2298 f_ecc_pt->m_bank_u32 = ( ( l_val_u32 >> 15 ) & (uint32_t) 0x7 );
2304 u4_CalcScrubEnd( void )
2306 uint64_t l_scrend_u64 = m_memsize_u64;
2309 * check for memory hole at 2GB
2311 if( l_scrend_u64 > _2GB ) {
2312 l_scrend_u64 += _2GB;
2315 l_scrend_u64 -= 0x40;
2316 l_scrend_u64 /= 0x10;
2318 return( (uint32_t) l_scrend_u64 );
2322 u4_Scrub( uint32_t f_scrub_u32, uint32_t f_pattern_u32, eccerror_t *f_eccerr_pt )
2328 * setup scrub parameters
2330 store32_ci( MSCR_R, 0 ); // stop scrub
2331 store32_ci( MSRSR_R, 0x0 ); // set start
2332 store32_ci( MSRER_R, u4_CalcScrubEnd() ); // set end
2333 store32_ci( MSPR_R, f_pattern_u32 ); // set pattern
2336 * clear out ECC error registers
2338 store32_ci( MEAR0_R, 0x0 );
2339 store32_ci( MEAR1_R, 0x0 );
2340 store32_ci( MESR_R, 0x0 );
2345 store32_ci( MSCR_R, f_scrub_u32 );
2347 if( f_scrub_u32 != BACKGROUND_SCRUB ) {
2349 * wait for scrub to complete
2354 i = load32_ci( MSCR_R );
2355 } while( ( i & f_scrub_u32 ) != 0 );
2357 ret = u4_checkeccerr( f_eccerr_pt );
2366 u4_InitialScrub( void )
2368 eccerror_t l_eccerr_st[2];
2369 int32_t l_err_i32[2] = { 0, 0 };
2371 l_err_i32[0] = u4_Scrub( IMMEDIATE_SCRUB_WITH_FILL, 0x0, &l_eccerr_st[0] );
2373 if( l_err_i32[0] >= -1 /*CE*/ ) {
2374 l_err_i32[1] = u4_Scrub( IMMEDIATE_SCRUB, 0x0, &l_eccerr_st[1] );
2377 if( l_err_i32[0] < l_err_i32[1] ) {
2378 return l_eccerr_st[0];
2380 return l_eccerr_st[1];
2386 * RND: calculates Timer cycles from the given frequency
2387 * divided by the clock frequency. Values are rounded
2388 * up to the nearest integer value if the division is not even.
2390 #define RND( tXXX ) ( ( ( tXXX ) + tCK - 1 ) / tCK )
2393 u4_MemInitSequence( uint32_t tRP, uint32_t tWR, uint32_t tRFC, uint32_t CL,
2394 uint32_t tCK, uint32_t TD )
2397 * DIMM init sequence
2399 static const uint32_t INI_SEQ[] = {
2400 0xa0000400, 0x80020000, 0x80030000, 0x80010404,
2401 0x8000100a, 0xa0000400, 0x90000000, 0x90000000,
2402 0x8ff0100a, 0x80010784, 0x80010404, 0x00000000,
2403 0x00000000, 0x00000000, 0x00000000, 0x00000000
2406 uint32_t l_MemInit_u32;
2410 for( r = MemInit00_R, i = 0; r <= MemInit15_R; r += 0x10, i++ ) {
2411 l_MemInit_u32 = INI_SEQ[i];
2416 l_MemInit_u32 |= ( ( RND( tRP ) - TD ) << 20 );
2420 store32_ci( EMRSRegCntl_R, l_MemInit_u32 &
2421 (uint32_t) 0xffff );
2425 l_MemInit_u32 |= IBIT(23);
2428 l_MemInit_u32 |= ( ( RND( tWR ) - 1 ) << 9 );
2429 l_MemInit_u32 |= ( CL << 4 );
2431 store32_ci( MRSRegCntl_R, l_MemInit_u32 &
2432 (uint32_t) 0xffff );
2437 l_MemInit_u32 |= ( ( RND( tRFC ) - TD ) << 20 );
2443 store32_ci( r, l_MemInit_u32 );
2446 printf( "\r\nMemInit%02d (0x%04X): 0x%08X", i, (uint16_t) r, l_MemInit_u32 );
2453 * Kick off memory init sequence & wait for completion
2455 store32_ci( MemProgCntl_R, IBIT(0) );
2458 i = load32_ci( MemProgCntl_R );
2459 } while( ( i & IBIT(1) ) == 0 );
2464 * static DIMM configuartion settings
2466 static reg_statics_t reg_statics_maui[NUM_SPEED_IDX] = {
2473 .MemRdQCnfg = 0x20020820,
2474 .MemWrQCnfg = 0x40041040,
2475 .MemQArb = 0x00000000,
2476 .MemRWArb = 0x30413cc0,
2478 .ODTCntl = 0x60000000,
2479 .IOPadCntl = 0x001a4000,
2480 .MemPhyModeCntl = 0x00000000,
2481 .OCDCalCntl = 0x00000000,
2482 .OCDCalCmd = 0x00000000,
2484 .CKDelayL = 0x34000000,
2485 .CKDelayU = 0x34000000,
2487 .MemBusCnfg = 0x00000050 |
2488 ( ( MAX_RMD << 28 ) |
2489 ( ( MAX_RMD - 2 ) << 24 ) ),
2495 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2496 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2497 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2498 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2499 0x00000000, 0x00000000
2502 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2503 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2504 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2505 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2506 0x00000000, 0x00000000
2516 .MemRdQCnfg = 0x20020820,
2517 .MemWrQCnfg = 0x40041040,
2518 .MemQArb = 0x00000000,
2519 .MemRWArb = 0x30413cc0,
2521 .ODTCntl = 0x60000000,
2522 .IOPadCntl = 0x001a4000,
2523 .MemPhyModeCntl = 0x00000000,
2524 .OCDCalCntl = 0x00000000,
2525 .OCDCalCmd = 0x00000000,
2527 .CKDelayL = 0x18000000,
2528 .CKDelayU = 0x18000000,
2530 .MemBusCnfg = 0x00002070 |
2531 ( ( MAX_RMD << 28 ) |
2532 ( ( MAX_RMD - 3 ) << 24 ) ),
2539 0x12000000, 0x12000000, 0x12000000 , 0x12000000,
2540 0x12000000, 0x12000000, 0x12000000 , 0x12000000,
2541 0x12000000, 0x12000000, 0x12000000 , 0x12000000,
2542 0x12000000, 0x12000000, 0x12000000 , 0x12000000,
2543 0x12000000, 0x12000000
2546 0x00000000, 0x00000000, 0x00000000 , 0x00000000,
2547 0x00000000, 0x00000000, 0x00000000 , 0x00000000,
2548 0x00000000, 0x00000000, 0x00000000 , 0x00000000,
2549 0x00000000, 0x00000000, 0x00000000 , 0x00000000,
2550 0x00000000, 0x00000000
2560 .MemRdQCnfg = 0x20020820,
2561 .MemWrQCnfg = 0x40041040,
2562 .MemQArb = 0x00000000,
2563 .MemRWArb = 0x30413cc0,
2565 .ODTCntl = 0x60000000,
2566 .IOPadCntl = 0x001a4000,
2567 .MemPhyModeCntl = 0x00000000,
2568 .OCDCalCntl = 0x00000000,
2569 .OCDCalCmd = 0x00000000,
2571 .CKDelayL = 0x0a000000,
2572 .CKDelayU = 0x0a000000,
2574 .MemBusCnfg = 0x000040a0 |
2575 ( ( MAX_RMD << 28 ) |
2576 ( ( MAX_RMD - 3 ) << 24 ) ),
2583 0x12000000, 0x12000000, 0x12000000, 0x12000000,
2584 0x12000000, 0x12000000, 0x12000000, 0x12000000,
2585 0x12000000, 0x12000000, 0x12000000, 0x12000000,
2586 0x12000000, 0x12000000, 0x12000000, 0x12000000,
2587 0x12000000, 0x12000000
2589 0x31000000, 0x31000000, 0x31000000, 0x31000000,
2590 0x31000000, 0x31000000, 0x31000000, 0x31000000,
2591 0x31000000, 0x31000000, 0x31000000, 0x31000000,
2592 0x31000000, 0x31000000, 0x31000000, 0x31000000,
2593 0x31000000, 0x31000000
2597 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2598 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2599 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2600 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2601 0x00000000, 0x00000000
2607 static reg_statics_t reg_statics_bimini[NUM_SPEED_IDX] = {
2614 .MemRdQCnfg = 0x20020820,
2615 .MemWrQCnfg = 0x40041040,
2616 .MemQArb = 0x00000000,
2617 .MemRWArb = 0x30413cc0,
2619 .ODTCntl = 0x40000000,
2620 .IOPadCntl = 0x001a4000,
2621 .MemPhyModeCntl = 0x00000000,
2622 .OCDCalCntl = 0x00000000,
2623 .OCDCalCmd = 0x00000000,
2625 .CKDelayL = 0x00000000,
2626 .CKDelayU = 0x28000000,
2628 .MemBusCnfg = 0x00552070 |
2629 ( ( MAX_RMD << 28 ) |
2630 ( ( MAX_RMD - 2 ) << 24 ) ),
2636 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2637 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2638 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2639 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2640 0x00000000, 0x00000000
2643 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2644 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2645 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2646 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2647 0x00000000, 0x00000000
2657 .MemRdQCnfg = 0x20020820,
2658 .MemWrQCnfg = 0x40041040,
2659 .MemQArb = 0x00000000,
2660 .MemRWArb = 0x30413cc0,
2662 .ODTCntl = 0x40000000,
2663 .IOPadCntl = 0x001a4000,
2664 .MemPhyModeCntl = 0x00000000,
2665 .OCDCalCntl = 0x00000000,
2666 .OCDCalCmd = 0x00000000,
2668 .CKDelayL = 0x00000000,
2669 .CKDelayU = 0x20000000,
2671 .MemBusCnfg = 0x00644190 |
2672 ( ( MAX_RMD << 28 ) |
2673 ( ( MAX_RMD - 3 ) << 24 ) ),
2679 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2680 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2681 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2682 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2683 0x14000000, 0x14000000
2686 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2687 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2688 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2689 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2690 0x00000000, 0x00000000
2700 .MemRdQCnfg = 0x20020820,
2701 .MemWrQCnfg = 0x40041040,
2702 .MemQArb = 0x00000000,
2703 .MemRWArb = 0x30413cc0,
2705 .ODTCntl = 0x40000000,
2706 .IOPadCntl = 0x001a4000,
2707 .MemPhyModeCntl = 0x00000000,
2708 .OCDCalCntl = 0x00000000,
2709 .OCDCalCmd = 0x00000000,
2711 .CKDelayL = 0x00000000,
2712 .CKDelayU = 0x00000000,
2714 .MemBusCnfg = 0x00666270 |
2715 ( ( MAX_RMD << 28 ) |
2716 ( ( MAX_RMD - 3 ) << 24 ) ),
2722 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2723 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2724 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2725 0x14000000, 0x14000000, 0x14000000, 0x14000000,
2726 0x14000000, 0x14000000
2729 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2730 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2731 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2732 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2733 0x00000000, 0x00000000
2739 static reg_statics_t reg_statics_kauai[NUM_SPEED_IDX] = {
2753 .MemPhyModeCntl = 0,
2766 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2767 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2768 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2769 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2770 0x00000000, 0x00000000
2773 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2774 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2775 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2776 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2777 0x00000000, 0x00000000
2794 .MemPhyModeCntl = 0,
2807 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2808 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2809 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2810 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2811 0x00000000, 0x00000000
2814 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2815 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2816 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2817 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2818 0x00000000, 0x00000000
2835 .MemPhyModeCntl = 0,
2848 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2849 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2850 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2851 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2852 0x00000000, 0x00000000
2855 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2856 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2857 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2858 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2859 0x00000000, 0x00000000
2866 u4_start( eccerror_t *f_ecc_pt )
2869 * maximum runs for auto calibration
2871 static const uint32_t MAX_ACERR = (uint32_t) 5;
2874 * fixed u4/DIMM timer/timing values for calculation
2876 static const uint32_t TD = (uint32_t) 2; // u4 delay cycles for loading a timer
2877 static const uint32_t AL = (uint32_t) 0; // additional latency (fix)
2878 static const uint32_t BL = (uint32_t) 4; // burst length (fix)
2880 uint32_t SPEED = m_gendimm.m_speed_pu32[m_dclidx_u32];
2881 uint32_t CL = m_gendimm.m_clval_pu32[m_dclidx_u32];
2882 uint32_t RL = AL + CL;
2883 uint32_t WL = RL - 1;
2884 uint32_t tCK = m_gendimm.m_tCK_pu32[m_dclidx_u32];
2885 uint32_t tRAS = m_gendimm.m_tRAS_u32;
2886 uint32_t tRTP = m_gendimm.m_tRTP_u32;
2887 uint32_t tRP = m_gendimm.m_tRP_u32;
2888 uint32_t tWR = m_gendimm.m_tWR_u32;
2889 uint32_t tRRD = m_gendimm.m_tRRD_u32;
2890 uint32_t tRC = m_gendimm.m_tRC_u32;
2891 uint32_t tRCD = m_gendimm.m_tRCD_u32;
2892 uint32_t tWTR = m_gendimm.m_tWTR_u32;
2893 uint32_t tRFC = m_gendimm.m_tRFC_u32;
2894 uint32_t tREF = m_gendimm.m_tREF_u32;
2896 reg_statics_t *rst = 0;
2898 uint32_t l_RAS0_u32;
2899 uint32_t l_RAS1_u32;
2900 uint32_t l_CAS0_u32;
2901 uint32_t l_CAS1_u32;
2902 uint32_t l_MemRfshCntl_u32;
2903 uint32_t l_UsrCnfg_u32;
2904 uint32_t l_DmCnfg_u32;
2906 uint32_t l_MemArbWt_u32;
2907 uint32_t l_MemRWArb_u32;
2908 uint32_t l_MemBusCnfg_u32;
2910 auto_calib_t l_ac_st;
2912 uint32_t l_acerr_i32;
2914 uint32_t i, j, t0, t1;
2917 * set index for different 400/533/667 Mhz setup
2931 printf( "\r\n-> DIMM speed of %03u not supported\r\n",
2932 m_gendimm.m_speed_pu32[m_dclidx_u32] );
2940 * setup pointer to the static register settings
2943 rst = ®_statics_maui[sidx];
2944 } else if( IS_BIMINI ) {
2945 rst = ®_statics_bimini[sidx];
2946 } else if( IS_KAUAI ) {
2947 rst = ®_statics_kauai[sidx];
2951 * Switch off Fast Path by default for all DIMMs
2952 * running with more than 400Mhz
2954 if( SPEED == 400 ) {
2955 or32_ci( APIMemRdCfg_R, IBIT(30) );
2957 printf( " [fastpath : ON]\r\n" );
2960 and32_ci( APIMemRdCfg_R, ~IBIT(30) );
2962 printf( " [fastpath : OFF]\r\n" );
2968 printf( " [register setup : ]" );
2972 * setup RAS/CAS timers2
2973 * NOTE: subtract TD from all values because of the delay
2974 * caused by reloading timers (see spec)
2980 // TiAtP = RND(tRAS) -> RAS0[0:4]
2981 l_RAS0_u32 = ( ( RND( tRAS ) - TD ) << 27 );
2982 // TiRtP = AL + BL/2 - 2 + RND(tRTP) -> RAS01[5:9]
2983 l_RAS0_u32 |= ( ( AL + BL/2 - 2 + RND( tRTP ) - TD ) << 22 );
2984 // TiWtP = WL + BL/2 + RND(tWR) -> RAS0[10:14]
2985 l_RAS0_u32 |= ( ( WL + BL/2 + RND( tWR ) - TD ) << 17 );
2986 // TiPtA = RND(tRP) -> RAS0[15:19]
2987 l_RAS0_u32 |= ( ( RND( tRP ) - TD ) << 12 );
2988 // TiPAtA = RND(tRP) or
2989 // RND(tRP) + 1 for 8 bank devices -> RAS0[20:24]
2990 if( m_gendimm.m_bankcnt_u32 <= 4 ) {
2991 l_RAS0_u32 |= ( ( RND( tRP ) - TD ) << 7 );
2993 l_RAS0_u32 |= ( ( RND( tRP ) + 1 - TD ) << 7 );
2999 // TiRAPtA = AL + BL/2 - 2 + RND(tRTP + tRP) -> RAS1[0:4]
3000 l_RAS1_u32 = ( ( AL + BL/2 - 2 + RND( tRTP + tRP ) - TD ) << 27 );
3001 // TiWAPtA = CL + AL + BL/2 - 1 + RND(tWR + tRP) -> RAS1[5:9]
3002 l_RAS1_u32 |= ( ( CL + AL + BL/2 - 1 + RND( tWR + tRP ) - TD ) << 22 );
3003 // TiAtARk = tRRD -> RAS1[10:14]
3004 l_RAS1_u32 |= ( ( RND( tRRD ) - TD ) << 17 );
3005 // TiAtABk = tRC -> RAS1[15:19]
3006 l_RAS1_u32 |= ( ( RND( tRC ) - TD ) << 12 );
3007 // TiAtRW = tRCD -> RAS1[20:24]
3008 l_RAS1_u32 |= ( ( RND( tRCD ) - TD ) << 7 );
3009 // TiSAtARk Win = 4 * tRRD + 2 -> RAS1[25:29]
3010 l_RAS1_u32 |= ( ( RND( 4 * tRRD ) + 2 - TD ) << 2 );
3015 // TiRtRRk = BL/2 -> CAS0[0:4]
3016 l_CAS0_u32 = ( ( BL/2 - TD ) << 27 );
3017 // TiRtRDm = BL/2 + 1 -> CAS0[5:9]
3018 l_CAS0_u32 |= ( ( BL/2 + 1 - TD ) << 22 );
3019 // TiRtRSy = BL/2 + RRMux -> CAS0[10:14]
3020 l_CAS0_u32 |= ( ( BL/2 + rst->RRMux - TD ) << 17 );
3021 // TiWtRRk = CL - 1 + BL/2 + tWTR ->CAS0[15:19]
3022 l_CAS0_u32 |= ( ( CL - 1 + BL/2 + RND( tWTR ) - TD ) << 12 );
3023 // TiWtRDm = BL/2 + 1 -> CAS0[20:24]
3024 l_CAS0_u32 |= ( ( BL/2 + 1 - TD ) << 7 );
3025 // TiWtRSy = BL/2 + WRMux -> CAS0[25:29]
3026 l_CAS0_u32 |= ( ( BL/2 + rst->WRMux - TD ) << 2 );
3031 // TiWtWRk = BL/2 -> CAS1[0:4]
3032 l_CAS1_u32 = ( ( BL/2 - TD ) << 27 );
3033 // TiWtWDm = BL/2 + 1 -> CAS1[5:9]
3034 l_CAS1_u32 |= ( ( BL/2 + 1 - TD ) << 22 );
3035 // TiWtWSy = BL/2 + WWMux -> CAS1[10:14]
3036 l_CAS1_u32 |= ( ( BL/2 + rst->WWMux - TD ) << 17 );
3037 // TiRtWRk = BL/2 + 2 -> CAS1[15:19]
3038 l_CAS1_u32 |= ( ( BL/2 + 2 + rst->CAS1Dly0 - TD ) << 12 );
3039 // TiRtWDm = BL/2 + 2 -> CAS1[20:24]
3040 l_CAS1_u32 |= ( ( BL/2 + 2 + rst->CAS1Dly1 - TD ) << 7 );
3041 // TiRtWSy = BL/2 + RWMux + 1 -> CAS1[25:29]
3042 l_CAS1_u32 |= ( ( BL/2 + rst->RWMux + 1 - TD ) << 2 );
3044 store32_ci( RASTimer0_R, l_RAS0_u32 );
3045 store32_ci( RASTimer1_R, l_RAS1_u32 );
3046 store32_ci( CASTimer0_R, l_CAS0_u32 );
3047 store32_ci( CASTimer1_R, l_CAS1_u32 );
3050 * Mem Refresh Control register
3052 l_MemRfshCntl_u32 = ( ( ( tREF / tCK ) / 16 ) << 23 );
3053 l_MemRfshCntl_u32 |= ( ( RND( tRFC ) - TD ) << 8 );
3054 store32_ci( MemRfshCntl_R, l_MemRfshCntl_u32 );
3057 * setup DmXCnfg registers
3059 store32_ci( Dm0Cnfg_R, (uint32_t) 0x0 );
3060 store32_ci( Dm1Cnfg_R, (uint32_t) 0x0 );
3061 store32_ci( Dm2Cnfg_R, (uint32_t) 0x0 );
3062 store32_ci( Dm3Cnfg_R, (uint32_t) 0x0 );
3065 * create DmCnfg & UsrCnfg values out of group data
3068 for( i = 0; i < m_dgrcnt_u32; i++ ) {
3069 l_DmCnfg_u32 = ( m_dgrptr[i]->m_add2g_u32 << 27 );
3070 l_DmCnfg_u32 |= ( m_dgrptr[i]->m_sub2g_u32 << 19 );
3071 l_DmCnfg_u32 |= ( m_dgrptr[i]->m_memmd_u32 << 12 );
3072 l_DmCnfg_u32 |= ( m_dgrptr[i]->m_start_u32 << 3 );
3073 l_DmCnfg_u32 |= ( m_dgrptr[i]->m_ss_u32 << 1 );
3074 l_DmCnfg_u32 |= IBIT(31); // enable bit
3077 * write value into DmXCnfg registers
3079 for( j = 0; j < m_dgrptr[i]->m_dcnt_u32; j++ ) {
3080 t0 = m_dgrptr[i]->m_dptr[j]->m_bank_u32;
3081 t1 = Dm0Cnfg_R + 0x10 * t0;
3083 if( load32_ci( t1 ) == 0 ) {
3084 store32_ci( t1, l_DmCnfg_u32 );
3086 ( m_dgrptr[i]->m_csmode_u32 << ( 30 - 2 * t0 ) );
3094 * setup UsrCnfg register
3095 *- cs mode is selected above
3096 *- Interleave on L2 cache line
3097 *- Usually closed page policy
3099 l_UsrCnfg_u32 |= IBIT(8); // interleave on L2 cache line
3100 l_UsrCnfg_u32 &= ~IBIT(9); // usually closed
3101 l_UsrCnfg_u32 |= IBIT(10);
3102 store32_ci( UsrCnfg_R, l_UsrCnfg_u32 );
3105 * Memory Arbiter Weight Register
3107 // CohWt -> MemAWt[0:1]
3108 l_MemArbWt_u32 = ( (uint32_t) 1 << 30 );
3109 // NCohWt -> MemAWt[2:3]
3110 l_MemArbWt_u32 |= ( (uint32_t) 1 << 28 );
3111 // ScrbWt -> MemAWt[4:5]
3112 l_MemArbWt_u32 |= ( (uint32_t) 0 << 26 );
3113 store32_ci( MemArbWt_R, l_MemArbWt_u32 );
3116 * misc fixed register setup
3118 store32_ci( ODTCntl_R, rst->ODTCntl );
3119 store32_ci( IOPadCntl_R, rst->IOPadCntl );
3120 store32_ci( MemPhyModeCntl_R, rst->MemPhyModeCntl );
3121 store32_ci( OCDCalCntl_R, rst->OCDCalCntl );
3122 store32_ci( OCDCalCmd_R, rst->OCDCalCmd );
3125 * CK Delay registers
3127 store32_ci( CKDelayL_R, rst->CKDelayL );
3128 store32_ci( CKDelayU_R, rst->CKDelayU );
3131 * read/write strobe delays
3133 store32_ci( ByteWrClkDelC0B00_R, rst->ByteWrClkDel[ 0] );
3134 store32_ci( ByteWrClkDelC0B01_R, rst->ByteWrClkDel[ 1] );
3135 store32_ci( ByteWrClkDelC0B02_R, rst->ByteWrClkDel[ 2] );
3136 store32_ci( ByteWrClkDelC0B03_R, rst->ByteWrClkDel[ 3] );
3137 store32_ci( ByteWrClkDelC0B04_R, rst->ByteWrClkDel[ 4] );
3138 store32_ci( ByteWrClkDelC0B05_R, rst->ByteWrClkDel[ 5] );
3139 store32_ci( ByteWrClkDelC0B06_R, rst->ByteWrClkDel[ 6] );
3140 store32_ci( ByteWrClkDelC0B07_R, rst->ByteWrClkDel[ 7] );
3141 store32_ci( ByteWrClkDelC0B16_R, rst->ByteWrClkDel[16] );
3142 store32_ci( ByteWrClkDelC0B08_R, rst->ByteWrClkDel[ 8] );
3143 store32_ci( ByteWrClkDelC0B09_R, rst->ByteWrClkDel[ 9] );
3144 store32_ci( ByteWrClkDelC0B10_R, rst->ByteWrClkDel[10] );
3145 store32_ci( ByteWrClkDelC0B11_R, rst->ByteWrClkDel[11] );
3146 store32_ci( ByteWrClkDelC0B12_R, rst->ByteWrClkDel[12] );
3147 store32_ci( ByteWrClkDelC0B13_R, rst->ByteWrClkDel[13] );
3148 store32_ci( ByteWrClkDelC0B14_R, rst->ByteWrClkDel[14] );
3149 store32_ci( ByteWrClkDelC0B15_R, rst->ByteWrClkDel[15] );
3150 store32_ci( ByteWrClkDelC0B17_R, rst->ByteWrClkDel[17] );
3151 store32_ci( ReadStrobeDelC0B00_R, rst->ReadStrobeDel[ 0] );
3152 store32_ci( ReadStrobeDelC0B01_R, rst->ReadStrobeDel[ 1] );
3153 store32_ci( ReadStrobeDelC0B02_R, rst->ReadStrobeDel[ 2] );
3154 store32_ci( ReadStrobeDelC0B03_R, rst->ReadStrobeDel[ 3] );
3155 store32_ci( ReadStrobeDelC0B04_R, rst->ReadStrobeDel[ 4] );
3156 store32_ci( ReadStrobeDelC0B05_R, rst->ReadStrobeDel[ 5] );
3157 store32_ci( ReadStrobeDelC0B06_R, rst->ReadStrobeDel[ 6] );
3158 store32_ci( ReadStrobeDelC0B07_R, rst->ReadStrobeDel[ 7] );
3159 store32_ci( ReadStrobeDelC0B16_R, rst->ReadStrobeDel[16] );
3160 store32_ci( ReadStrobeDelC0B08_R, rst->ReadStrobeDel[ 8] );
3161 store32_ci( ReadStrobeDelC0B09_R, rst->ReadStrobeDel[ 9] );
3162 store32_ci( ReadStrobeDelC0B10_R, rst->ReadStrobeDel[10] );
3163 store32_ci( ReadStrobeDelC0B11_R, rst->ReadStrobeDel[11] );
3164 store32_ci( ReadStrobeDelC0B12_R, rst->ReadStrobeDel[12] );
3165 store32_ci( ReadStrobeDelC0B13_R, rst->ReadStrobeDel[13] );
3166 store32_ci( ReadStrobeDelC0B14_R, rst->ReadStrobeDel[14] );
3167 store32_ci( ReadStrobeDelC0B15_R, rst->ReadStrobeDel[15] );
3168 store32_ci( ReadStrobeDelC0B17_R, rst->ReadStrobeDel[17] );
3171 * Mem Bus Configuration
3172 * initial setup used in auto calibration
3173 * final values will be written after
3174 * auto calibration has finished
3176 l_MemBusCnfg_u32 = rst->MemBusCnfg;
3178 /* values calculation has been dropped, static values are used instead
3179 // WdbRqDly = 2 * (CL - 3) (registered DIMMs) -> MBC[16:19]
3180 l_MemBusCnfg_u32 += ( ( 2 * ( CL - 3 ) ) << 12 );
3181 // RdOEOnDly = 0 (typically)
3182 l_MemBusCnfg_u32 += ( ( 0 ) << 8 );
3183 // RdOEOffDly = (2 * CL) - 4 -> MBC[24:27]
3184 // NOTE: formula is not working, changed to:
3185 // RdOEOffDly = (2 * CL) - 1
3186 l_MemBusCnfg_u32 += ( ( ( 2 * CL ) - 1 ) << 4 );
3189 store32_ci( MemBusCnfg_R, l_MemBusCnfg_u32 );
3190 store32_ci( MemBusCnfg2_R, rst->MemBusCnfg & (uint32_t) 0xf0000000 );
3193 * reset verniers registers
3195 store32_ci( RstLdEnVerniersC0_R, 0x0 );
3196 store32_ci( RstLdEnVerniersC1_R, 0x0 );
3197 store32_ci( RstLdEnVerniersC2_R, 0x0 );
3198 store32_ci( RstLdEnVerniersC3_R, 0x0 );
3199 store32_ci( ExtMuxVernier0_R, 0x0 );
3200 store32_ci( ExtMuxVernier1_R, 0x0 );
3203 * Queue Configuration
3205 store32_ci( MemRdQCnfg_R, rst->MemRdQCnfg );
3206 store32_ci( MemWrQCnfg_R, rst->MemWrQCnfg );
3207 store32_ci( MemQArb_R, rst->MemQArb );
3208 store32_ci( MemRWArb_R, rst->MemRWArb );
3211 printf( "\b\b\bOK\r\n" );
3215 * start up clocks & wait for pll2 to stabilize
3218 printf( " [start DDR clock : ]" );
3221 store32_ci( MemModeCntl_R, IBIT(0) | IBIT(8) );
3225 printf( "\b\b\bOK\r\n" );
3230 * memory initialization sequence
3233 printf( " [memory init : ]" );
3235 u4_MemInitSequence( tRP, tWR, tRFC, CL, tCK, TD );
3237 printf( "\b\b\bOK\r\n" );
3241 * start ECC before auto calibration to enable ECC bytelane
3243 store32_ci( MCCR_R, IBIT(0) );
3247 * start up auto calibration
3250 printf( " [auto calibration: ]\b" );
3254 * start auto calibration
3260 l_ac_i32 = u4_auto_calib( &l_ac_st );
3262 if( l_ac_i32 != 0 ) {
3267 } while( ( l_ac_i32 != 0 ) &&
3268 ( l_acerr_i32 <= MAX_ACERR ) );
3270 if( l_acerr_i32 > MAX_ACERR ) {
3272 printf( "\b\b\bERR\r\n" );
3278 * insert auto calibration results
3280 store32_ci( MemBusCnfg_R, l_ac_st.m_MemBusCnfg_u32 );
3281 store32_ci( MemBusCnfg2_R, l_ac_st.m_MemBusCnfg2_u32 );
3282 store32_ci( RstLdEnVerniersC0_R, l_ac_st.m_RstLdEnVerniers_pu32[0] );
3283 store32_ci( RstLdEnVerniersC1_R, l_ac_st.m_RstLdEnVerniers_pu32[1] );
3284 store32_ci( RstLdEnVerniersC2_R, l_ac_st.m_RstLdEnVerniers_pu32[2] );
3285 store32_ci( RstLdEnVerniersC3_R, l_ac_st.m_RstLdEnVerniers_pu32[3] );
3288 * insert final timing value into MemRWArb
3290 l_MemRWArb_u32 = ( ( l_ac_st.m_MemBusCnfg_u32 >> 28 /*RdMacDel*/) + 1 );
3291 l_MemRWArb_u32 *= 10; // needed for rounding
3292 l_MemRWArb_u32 /= 2; // due to spec
3293 l_MemRWArb_u32 += 9; // round up
3294 l_MemRWArb_u32 /= 10; // value is rounded now
3295 l_MemRWArb_u32 = l_MemRWArb_u32 + 6 - WL - TD;
3296 l_MemRWArb_u32 |= rst->MemRWArb;
3297 store32_ci( MemRWArb_R, l_MemRWArb_u32 );
3303 * do initial scrubbing
3305 *f_ecc_pt = u4_InitialScrub();
3307 switch( f_ecc_pt->m_err_i32 ) {
3310 printf( "\b\bOK\r\n" );
3315 case RET_ACERR_CE: {
3317 printf( "\b\b\b\bWEAK][correctable errors during scrub (%u)]\r\n",
3318 f_ecc_pt->m_cecnt_u32 );
3323 case RET_ACERR_UEWT:
3324 case RET_ACERR_UE: {
3326 printf( "\b\b\bERR][uncorrectable errors during scrub (%u)]\r\n",
3327 f_ecc_pt->m_uecnt_u32 );
3329 return RET_ACERR_UE;
3335 * start continuous background scrub
3338 printf( " [background scrub: ]" );
3341 u4_Scrub( BACKGROUND_SCRUB, 0, NULL );
3344 printf( "\b\b\bOK\r\n" );
3348 * finally clear API Exception register
3351 load32_ci( APIExcp_R );
3360 u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags)
3364 static const uint64_t _2GB = (uint64_t) 0x80000000;
3365 static const uint64_t _start = (uint64_t) 0x08000000; // 128Mb
3366 static const uint64_t _bsize = (uint64_t) 0x08000000; // 128MB
3367 static const uint64_t _line = (uint64_t) 128;
3368 static const uint64_t _256MB = (uint64_t) 0x10000000;
3370 static const uint64_t PATTERN[] = {
3371 0x9090909090909090, 0x0020002000200020,
3372 0x0c0c0c0c0c0c0c0c, 0x8080808080808080,
3373 0x1004010004001041, 0x0000000000000000
3376 uint64_t mend = (uint64_t) 0x200000000;//m_memsize_u64;
3377 uint64_t numblocks = ( mend - _start ) / _bsize; // 128Mb blocks
3378 uint64_t numlines = _bsize / _line;
3379 uint64_t tstate = 0;
3395 printf( "\n\nU4 memory test" );
3396 printf( "\n--------------" );
3399 * mask out UEC & CEC
3401 or32_ci( MCCR_R, IBIT(6) | IBIT(7) );
3403 while( PATTERN[pidx] ) {
3408 printf( "\npattern fill 0x%08X%08X: ", (uint32_t) (PATTERN[pidx] >> 32), (uint32_t) PATTERN[pidx] );
3411 * first switch lines, then blocks. This way the CPU
3412 * is not able to cache data
3414 for( line = 0, dcnt = 0; line < numlines; line++ ) {
3416 for( block = 0; block < numblocks; block++ ) {
3418 for( i = 0; i < _line; i += 8 ) {
3420 ( block * _bsize ) +
3424 if( addr >= _2GB ) {
3428 *( (uint64_t *) addr ) = PATTERN[pidx];
3431 * print out a dot every 256Mb
3434 if( dcnt == _256MB ) {
3438 if( io_getchar( &c ) ) {
3450 check = PATTERN[pidx];
3462 one = ( ( check & 0x1 ) != 0 );
3465 check |= 0x8000000000000000;
3468 printf( "\nrotate right 0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
3471 * first switch lines, then blocks. This way the CPU
3472 * is not able to cache data
3474 for( line = 0, dcnt = 0; line < numlines; line++ ) {
3476 for( block = 0; block < numblocks; block++ ) {
3478 for( i = 0; i < _line; i += 8 ) {
3480 ( block * _bsize ) +
3484 if( addr >= _2GB ) {
3488 *( (uint64_t *) addr ) >>= 1;
3491 *( (uint64_t *) addr ) |=
3492 (uint64_t) 0x8000000000000000;
3496 * print out a dot every 256Mb
3499 if( dcnt == _256MB ) {
3503 if( io_getchar( &c ) ) {
3535 check ^= (uint64_t) ~0;
3537 printf( "\ninverting 0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
3540 * first switch lines, then blocks. This way the CPU
3541 * is not able to cache data
3543 for( line = 0, dcnt = 0; line < numlines; line++ ) {
3545 for( block = 0; block < numblocks; block++ ) {
3547 for( i = 0; i < _line; i += 8 ) {
3549 ( block * _bsize ) +
3553 if( addr >= _2GB ) {
3557 *( (uint64_t *) addr ) ^= (uint64_t) ~0;
3560 * print out a dot every 256Mb
3563 if( dcnt == _256MB ) {
3567 if( io_getchar( &c ) ) {
3589 one = ( ( check & 0x8000000000000000 ) != 0 );
3595 printf( "\nrotate left 0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
3598 * first switch lines, then blocks. This way the CPU
3599 * is not able to cache data
3601 for( line = 0, dcnt = 0; line < numlines; line++ ) {
3603 for( block = 0; block < numblocks; block++ ) {
3605 for( i = 0; i < _line; i += 8 ) {
3607 ( block * _bsize ) +
3611 if( addr >= _2GB ) {
3615 *( (uint64_t *) addr ) <<= 1;
3618 *( (uint64_t *) addr ) |=
3623 * print out a dot every 256Mb
3626 if( dcnt == _256MB ) {
3630 if( io_getchar( &c ) ) {
3663 printf( "\nmultiply 0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
3666 * first switch lines, then blocks. This way the CPU
3667 * is not able to cache data
3669 for( line = 0, dcnt = 0; line < numlines; line++ ) {
3671 for( block = 0; block < numblocks; block++ ) {
3673 for( i = 0; i < _line; i += 8 ) {
3675 ( block * _bsize ) +
3679 if( addr >= _2GB ) {
3683 *( (uint64_t *) addr ) *= ~( *( (uint64_t *) addr ) );
3686 * print out a dot every 256Mb
3689 if( dcnt == _256MB ) {
3693 if( io_getchar( &c ) ) {
3719 printf( "\nchecking : " );
3721 for( line = 0, dcnt = 0; line < numlines; line++ ) {
3723 for( block = 0; block < numblocks; block++ ) {
3725 for( i = 0; i < _line; i += 8 ) {
3727 ( block * _bsize ) +
3731 if( addr >= _2GB ) {
3735 err = ( *( (uint64_t *) addr ) != check );
3742 * print out a dot every 256Mb
3745 if( dcnt == _256MB ) {
3754 if( io_getchar( &c ) ) {
3766 err = (uint64_t) load32_ci( MEAR1_R );
3767 uerr += ( err >> 24 ) & (uint64_t) 0xff;
3768 cerr += ( err >> 16 ) & (uint64_t) 0xff;
3770 printf( " (UE: %02llX, CE: %02llX)", ( err >> 24 ) & (uint64_t) 0xff, ( err >> 16 ) & (uint64_t) 0xff );
3781 printf( "\n\nmemory test results" );
3782 printf( "\n-------------------" );
3783 printf( "\nuncorrectable errors: %u", (uint32_t) uerr );
3784 printf( "\ncorrectable errors : %u", (uint32_t) cerr );
3785 printf( "\nread/write errors : %u\n", (uint32_t) merr );
3787 and32_ci( MCCR_R, ~( IBIT(6) | IBIT(7) ) );
3793 u4_dump(uint8_t argCnt, char *pArgs[], uint64_t flags)
3795 printf( "\r\n*** u4 register dump ***\r\n\n" );
3796 printf( "register (offset): value\r\n" );
3797 printf( "----------------------------------\r\n" );
3798 printf( "Clock Control (0x%04X): 0x%08X\r\n", (uint16_t) ClkCntl_R, load32_ci( ClkCntl_R ) );
3799 printf( "PLL2 Control (0x%04X): 0x%08X\r\n", (uint16_t) PLL2Cntl_R, load32_ci( PLL2Cntl_R ) );
3800 printf( "MemModeCntl (0x%04X): 0x%08X\r\n", (uint16_t) MemModeCntl_R, load32_ci( MemModeCntl_R ) );
3801 printf( "RASTimer0 (0x%04X): 0x%08X\r\n", (uint16_t) RASTimer0_R, load32_ci( RASTimer0_R ) );
3802 printf( "RASTimer1 (0x%04X): 0x%08X\r\n", (uint16_t) RASTimer1_R, load32_ci( RASTimer1_R ) );
3803 printf( "CASTimer0 (0x%04X): 0x%08X\r\n", (uint16_t) CASTimer0_R, load32_ci( CASTimer0_R ) );
3804 printf( "CASTimer1 (0x%04X): 0x%08X\r\n", (uint16_t) CASTimer1_R, load32_ci( CASTimer1_R ) );
3805 printf( "MemRfshCntl (0x%04X): 0x%08X\r\n", (uint16_t) MemRfshCntl_R, load32_ci( MemRfshCntl_R ) );
3806 printf( "Dm0Cnfg (0x%04X): 0x%08X\r\n", (uint16_t) Dm0Cnfg_R, load32_ci( Dm0Cnfg_R ) );
3807 printf( "Dm1Cnfg (0x%04X): 0x%08X\r\n", (uint16_t) Dm1Cnfg_R, load32_ci( Dm1Cnfg_R ) );
3808 printf( "Dm2Cnfg (0x%04X): 0x%08X\r\n", (uint16_t) Dm2Cnfg_R, load32_ci( Dm2Cnfg_R ) );
3809 printf( "Dm3Cnfg (0x%04X): 0x%08X\r\n", (uint16_t) Dm3Cnfg_R, load32_ci( Dm3Cnfg_R ) );
3810 printf( "UsrCnfg (0x%04X): 0x%08X\r\n", (uint16_t) UsrCnfg_R, load32_ci( UsrCnfg_R ) );
3811 printf( "MemArbWt (0x%04X): 0x%08X\r\n", (uint16_t) MemArbWt_R, load32_ci( MemArbWt_R ) );
3812 printf( "ODTCntl (0x%04X): 0x%08X\r\n", (uint16_t) ODTCntl_R, load32_ci( ODTCntl_R ) );
3813 printf( "IOPadCntl (0x%04X): 0x%08X\r\n", (uint16_t) IOPadCntl_R, load32_ci( IOPadCntl_R ) );
3814 printf( "MemPhyMode (0x%04X): 0x%08X\r\n", (uint16_t) MemPhyModeCntl_R, load32_ci( MemPhyModeCntl_R ) );
3815 printf( "OCDCalCntl (0x%04X): 0x%08X\r\n", (uint16_t) OCDCalCntl_R, load32_ci( OCDCalCntl_R ) );
3816 printf( "OCDCalCmd (0x%04X): 0x%08X\r\n", (uint16_t) OCDCalCmd_R, load32_ci( OCDCalCmd_R ) );
3817 printf( "CKDelayL (0x%04X): 0x%08X\r\n", (uint16_t) CKDelayL_R, load32_ci( CKDelayL_R ) );
3818 printf( "CKDelayH (0x%04X): 0x%08X\r\n", (uint16_t) CKDelayU_R, load32_ci( CKDelayU_R ) );
3819 printf( "MemBusCnfg (0x%04X): 0x%08X\r\n", (uint16_t) MemBusCnfg_R, load32_ci( MemBusCnfg_R ) );
3820 printf( "MemBusCnfg2 (0x%04X): 0x%08X\r\n", (uint16_t) MemBusCnfg2_R, load32_ci( MemBusCnfg2_R ) );
3821 printf( "MemRdQCnfg (0x%04X): 0x%08X\r\n", (uint16_t) MemRdQCnfg_R, load32_ci( MemRdQCnfg_R ) );
3822 printf( "MemWrQCnfg (0x%04X): 0x%08X\r\n", (uint16_t) MemWrQCnfg_R, load32_ci( MemWrQCnfg_R ) );
3823 printf( "MemQArb (0x%04X): 0x%08X\r\n", (uint16_t) MemQArb_R, load32_ci( MemQArb_R ) );
3824 printf( "MemRWArb (0x%04X): 0x%08X\r\n", (uint16_t) MemRWArb_R, load32_ci( MemRWArb_R ) );
3825 printf( "ByteWrClkDel (0x%04X): 0x%08X\r\n", (uint16_t) ByteWrClkDelC0B00_R, load32_ci( ByteWrClkDelC0B00_R ) );
3826 printf( "ReadStrobeDel (0x%04X): 0x%08X\r\n", (uint16_t) ReadStrobeDelC0B00_R, load32_ci( ReadStrobeDelC0B00_R ) );
3827 printf( "RstLdEnVerC0 (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC0_R, load32_ci( RstLdEnVerniersC0_R ) );
3828 printf( "RstLdEnVerC1 (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC1_R, load32_ci( RstLdEnVerniersC1_R ) );
3829 printf( "RstLdEnVerC2 (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC2_R, load32_ci( RstLdEnVerniersC2_R ) );
3830 printf( "RstLdEnVerC3 (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC3_R, load32_ci( RstLdEnVerniersC3_R ) );
3831 printf( "APIMemRdCfg (0x%04X): 0x%08X\r\n", (uint16_t) APIMemRdCfg_R, load32_ci( APIMemRdCfg_R ) );
3832 printf( "scrub start (0x%04X): 0x%08X\r\n", (uint16_t) MSRSR_R, load32_ci( MSRSR_R ) );
3833 printf( "scrub end (0x%04X): 0x%08X\r\n", (uint16_t) MSRER_R, load32_ci( MSRER_R ) );
3838 u4_memBegin( eccerror_t *f_ecc_pt )
3844 printf( "U4 DDR2 memory controller setup V%u.%u\r\n",
3846 printf( "------------------------------------\r\n" );
3847 printf( "> detected board : " );
3851 } else if( IS_BIMINI ) {
3853 } else if( IS_KAUAI ) {
3856 printf( "unknown!" );
3863 * initialize variables
3870 for( i = 0; i < NUM_SLOTS; i++ ) {
3872 memset( ( void * ) &m_dimm[i], 0, sizeof( dimm_t ) );
3875 for( i = 0; i < MAX_DGROUPS; i++ ) {
3877 memset( ( void * ) &m_dgroup[i], 0, sizeof( dimm_t ) );
3881 * start configuration
3884 printf( "\r\n> detected DIMM configuration : " );
3887 i = ddr2_readSPDs();
3891 printf( "\r\n-------------------------------------------------------------" );
3892 printf( "\r\n switching off memory bank(s) due to SPD integrity failure" );
3893 printf( "\r\n-------------------------------------------------------------\r\n" );
3897 } while( i != RET_OK );
3900 * check DIMM configuration
3902 if( ddr2_setupDIMMcfg() != RET_OK ) {
3904 printf( "> initialization failure.\r\n" );
3910 * create DIMM groups
3912 u4_setupDIMMgroups();
3915 * start configuration of u4
3919 if( u4_calcDIMMmemmode() != RET_OK ) {
3921 printf( "> initialization failure.\r\n" );
3927 printf( "%uMb @ %uMhz, CL %u\r\n",
3928 (uint32_t) ( m_memsize_u64 / 0x100000 ),
3929 m_gendimm.m_speed_pu32[m_dclidx_u32],
3930 m_gendimm.m_clval_pu32[m_dclidx_u32] );
3932 printf( "> initializing memory :\r\n" );
3935 if( u4_setup_core_clock() != RET_OK ) {
3937 printf( "> initialization failure.\r\n" );
3942 i = u4_start( f_ecc_pt );
3945 printf( "> initialization failure.\r\n" );
3951 printf( " [flush cache : ]" );
3954 flush_cache( 0x0, L2_CACHE_SIZE );
3957 printf( "\b\b\bOK\r\n" );
3958 printf( "> initialization complete.\r\n" );
3970 static int32_t scrubstarted = 0;
3972 u4_scrubStart(uint8_t argCnt, char *pArgs[], uint64_t flags )
3977 * setup scrub parameters
3979 store32_ci( MSCR_R, 0 ); // stop scrub
3980 store32_ci( MSRSR_R, 0x0 ); // set start
3981 store32_ci( MSRER_R, 0x1c ); // set end
3982 store32_ci( MSPR_R, 0x0 ); // set pattern
3985 * clear out ECC error registers
3987 store32_ci( MEAR0_R, 0x0 );
3988 store32_ci( MEAR1_R, 0x0 );
3989 store32_ci( MESR_R, 0x0 );
3994 store32_ci( MSCR_R, IBIT(1) );
3995 printf( "\r\nscrub started\r\n" );
4001 u4_scrubEnd(uint8_t argCnt, char *pArgs[], uint64_t flags )
4003 store32_ci( MSCR_R, 0 ); // stop scrub
4005 printf( "\r\nscrub stopped\r\n" );
4011 u4_memwr(uint8_t argCnt, char *pArgs[], uint64_t flags )
4016 for( i = 0; i < 0x200; i += 4 ) {
4018 if( ( i & 0xf ) == 0 ) {
4031 static uint32_t l_isInit_u32 = 0;
4036 * do not initialize memory more than once
4038 if( l_isInit_u32 ) {
4040 printf( "\r\n\nmemory already initialized\r\n" );
4048 * enable all DIMM banks on first run
4053 ret = u4_memBegin( &l_ecc_t );
4055 if( ret < RET_ERR ) {
4056 uint32_t l_bank_u32 = l_ecc_t.m_rank_u32 / 2;
4057 printf( "\r\n-----------------------------------------------------" );
4058 printf( "\r\n switching off memory bank %u due to memory failure", l_bank_u32 );
4059 printf( "\r\n-----------------------------------------------------" );
4060 m_bankoff_u32 |= ( 1 << l_bank_u32 );
4063 } while( ret < RET_ERR );