2 * (C) Copyright 2005-2006
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
6 * DAVE Srl <www.dave-tech.it>
8 * (C) Copyright 2002-2004
9 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
11 * See file CREDITS for list of people who contributed to this
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 #include <asm/processor.h>
36 #ifdef CONFIG_SDRAM_BANK0
39 #ifndef CFG_SDRAM_TABLE
40 sdram_conf_t mb0cf
[] = {
41 {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
42 {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
43 {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
44 {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
45 {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
48 sdram_conf_t mb0cf
[] = CFG_SDRAM_TABLE
;
51 #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
57 static ulong
ns2clks(ulong ns
)
59 ulong bus_period_x_10
= ONE_BILLION
/ (get_bus_freq(0) / 10);
61 return ((ns
* 10) + bus_period_x_10
) / bus_period_x_10
;
63 #endif /* CFG_SDRAM_CASL */
65 static ulong
compute_sdtr1(ulong speed
)
72 if (CFG_SDRAM_CASL
< 2)
73 sdtr1
|= (1 << SDRAM0_TR_CASL
);
75 if (CFG_SDRAM_CASL
> 4)
76 sdtr1
|= (3 << SDRAM0_TR_CASL
);
78 sdtr1
|= ((CFG_SDRAM_CASL
-1) << SDRAM0_TR_CASL
);
81 tmp
= ns2clks(CFG_SDRAM_PTA
);
82 if ((tmp
>= 2) && (tmp
<= 4))
83 sdtr1
|= ((tmp
-1) << SDRAM0_TR_PTA
);
85 sdtr1
|= ((4-1) << SDRAM0_TR_PTA
);
88 tmp
= ns2clks(CFG_SDRAM_CTP
);
89 if ((tmp
>= 2) && (tmp
<= 4))
90 sdtr1
|= ((tmp
-1) << SDRAM0_TR_CTP
);
92 sdtr1
|= ((4-1) << SDRAM0_TR_CTP
);
95 tmp
= ns2clks(CFG_SDRAM_LDF
);
96 if ((tmp
>= 2) && (tmp
<= 4))
97 sdtr1
|= ((tmp
-1) << SDRAM0_TR_LDF
);
99 sdtr1
|= ((2-1) << SDRAM0_TR_LDF
);
102 tmp
= ns2clks(CFG_SDRAM_RFTA
);
103 if ((tmp
>= 4) && (tmp
<= 10))
104 sdtr1
|= ((tmp
-4) << SDRAM0_TR_RFTA
);
106 sdtr1
|= ((10-4) << SDRAM0_TR_RFTA
);
109 tmp
= ns2clks(CFG_SDRAM_RCD
);
110 if ((tmp
>= 2) && (tmp
<= 4))
111 sdtr1
|= ((tmp
-1) << SDRAM0_TR_RCD
);
113 sdtr1
|= ((4-1) << SDRAM0_TR_RCD
);
116 #else /* CFG_SDRAM_CASL */
118 * If no values are configured in the board config file
119 * use the default values, which seem to be ok for most
123 * For new board ports we strongly recommend to define the
124 * correct values for the used SDRAM chips in your board
125 * config file (see PPChameleonEVB.h)
127 if (speed
> 100000000) {
134 * default: 100 MHz SDRAM
138 #endif /* CFG_SDRAM_CASL */
141 /* refresh is expressed in ms */
142 static ulong
compute_rtr(ulong speed
, ulong rows
, ulong refresh
)
144 #ifdef CFG_SDRAM_CASL
147 tmp
= ((refresh
*1000*1000) / (1 << rows
)) * (speed
/ 1000);
150 return ((tmp
& 0x00003FF8) << 16);
151 #else /* CFG_SDRAM_CASL */
152 if (speed
> 100000000) {
159 * default: 100 MHz SDRAM
163 #endif /* CFG_SDRAM_CASL */
167 * Autodetect onboard SDRAM on 405 platforms
169 void sdram_init(void)
176 * Determine SDRAM speed
178 speed
= get_bus_freq(0); /* parameter not used on ppc4xx */
181 * sdtr1 (register SDRAM0_TR) must take into account timings listed
182 * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
183 * account actual SDRAM size. So we can set up sdtr1 according to what
184 * is specified in board configuration file while rtr dependds on SDRAM
185 * size we are assuming before detection.
187 sdtr1
= compute_sdtr1(speed
);
189 for (i
=0; i
<N_MB0CF
; i
++) {
191 * Disable memory controller.
193 mtsdram0(mem_mcopt1
, 0x00000000);
196 * Set MB0CF for bank 0.
198 mtsdram0(mem_mb0cf
, mb0cf
[i
].reg
);
199 mtsdram0(mem_sdtr1
, sdtr1
);
200 mtsdram0(mem_rtr
, compute_rtr(speed
, mb0cf
[i
].rows
, 64));
205 * Set memory controller options reg, MCOPT1.
206 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
209 mtsdram0(mem_mcopt1
, 0x80800000);
213 if (get_ram_size(0, mb0cf
[i
].size
) == mb0cf
[i
].size
) {
215 * OK, size detected -> all done
222 #else /* CONFIG_440 */
227 static void sdram_tr1_set(int ram_address
, int* tr1_value
)
231 volatile unsigned int* ram_pointer
= (unsigned int *)ram_address
;
232 int first_good
= -1, last_bad
= 0x1ff;
234 unsigned long test
[NUM_TRIES
] = {
235 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
236 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
237 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
238 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
239 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
240 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
241 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
242 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
243 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
244 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
245 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
246 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
247 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
248 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
249 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
250 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
252 /* go through all possible SDRAM0_TR1[RDCT] values */
253 for (i
=0; i
<=0x1ff; i
++) {
254 /* set the current value for TR1 */
255 mtsdram(mem_tr1
, (0x80800800 | i
));
258 for (j
=0; j
<NUM_TRIES
; j
++) {
259 ram_pointer
[j
] = test
[j
];
261 /* clear any cache at ram location */
262 __asm__("dcbf 0,%0": :"r" (&ram_pointer
[j
]));
265 /* read values back */
266 for (j
=0; j
<NUM_TRIES
; j
++) {
267 for (k
=0; k
<NUM_READS
; k
++) {
268 /* clear any cache at ram location */
269 __asm__("dcbf 0,%0": :"r" (&ram_pointer
[j
]));
271 if (ram_pointer
[j
] != test
[j
])
280 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
281 if (j
== NUM_TRIES
) {
282 if (first_good
== -1)
283 first_good
= i
; /* found beginning of window */
284 } else { /* bad read */
285 /* if we have not had a good read then don't care */
286 if (first_good
!= -1) {
287 /* first failure after a good read */
294 /* return the current value for TR1 */
295 *tr1_value
= (first_good
+ last_bad
) / 2;
299 #ifdef CONFIG_SDRAM_ECC
300 static void ecc_init(ulong start
, ulong size
)
302 ulong current_addr
; /* current byte address */
303 ulong end_addr
; /* end of memory region */
304 ulong addr_inc
; /* address skip between writes */
305 ulong cfg0_reg
; /* for restoring ECC state */
308 * TODO: Enable dcache before running this test (speedup)
311 mfsdram(mem_cfg0
, cfg0_reg
);
312 mtsdram(mem_cfg0
, (cfg0_reg
& ~SDRAM_CFG0_MEMCHK
) | SDRAM_CFG0_MEMCHK_GEN
);
315 * look at geometry of SDRAM (data width) to determine whether we
316 * can skip words when writing
318 if ((cfg0_reg
& SDRAM_CFG0_DRAMWDTH
) == SDRAM_CFG0_DRAMWDTH_32
)
323 current_addr
= start
;
324 end_addr
= start
+ size
;
326 while (current_addr
< end_addr
) {
327 *((ulong
*)current_addr
) = 0x00000000;
328 current_addr
+= addr_inc
;
332 * TODO: Flush dcache and disable it again
336 * Enable ecc checking and parity errors
338 mtsdram(mem_cfg0
, (cfg0_reg
& ~SDRAM_CFG0_MEMCHK
) | SDRAM_CFG0_MEMCHK_CHK
);
343 * Autodetect onboard DDR SDRAM on 440 platforms
345 * NOTE: Some of the hardcoded values are hardware dependant,
346 * so this should be extended for other future boards
347 * using this routine!
349 long int initdram(int board_type
)
354 for (i
=0; i
<N_MB0CF
; i
++) {
356 * Disable memory controller.
358 mtsdram(mem_cfg0
, 0x00000000);
363 mtsdram(mem_uabba
, 0x00000000); /* ubba=0 (default) */
364 mtsdram(mem_slio
, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
365 mtsdram(mem_devopt
, 0x00000000); /* dll=0 ds=0 (normal) */
366 mtsdram(mem_wddctr
, 0x00000000); /* wrcp=0 dcd=0 */
367 mtsdram(mem_clktr
, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
370 * Following for CAS Latency = 2.5 @ 133 MHz PLB
372 mtsdram(mem_b0cr
, mb0cf
[i
].reg
);
373 mtsdram(mem_tr0
, 0x41094012);
374 mtsdram(mem_tr1
, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
375 mtsdram(mem_rtr
, 0x7e000000); /* Interval 15.20µs @ 133MHz PLB*/
376 mtsdram(mem_cfg1
, 0x00000000); /* Self-refresh exit, disable PM*/
377 udelay(400); /* Delay 200 usecs (min) */
380 * Enable the controller, then wait for DCEN to complete
382 mtsdram(mem_cfg0
, 0x82000000); /* DCEN=1, PMUD=0, 64-bit */
385 if (get_ram_size(0, mb0cf
[i
].size
) == mb0cf
[i
].size
) {
387 * Optimize TR1 to current hardware environment
389 sdram_tr1_set(0x00000000, &tr1_bank1
);
390 mtsdram(mem_tr1
, (tr1_bank1
| 0x80800800));
392 #ifdef CONFIG_SDRAM_ECC
393 ecc_init(0, mb0cf
[i
].size
);
397 * OK, size detected -> all done
399 return mb0cf
[i
].size
;
403 return 0; /* nothing found ! */
406 #endif /* CONFIG_440 */
408 #endif /* CONFIG_SDRAM_BANK0 */