2 * (C) Copyright 2005-2007
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>
35 #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]))
54 static ulong ns2clks(ulong ns)
56 ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
58 return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
60 #endif /* CFG_SDRAM_CASL */
62 static ulong compute_sdtr1(ulong speed)
69 if (CFG_SDRAM_CASL < 2)
70 sdtr1 |= (1 << SDRAM0_TR_CASL);
72 if (CFG_SDRAM_CASL > 4)
73 sdtr1 |= (3 << SDRAM0_TR_CASL);
75 sdtr1 |= ((CFG_SDRAM_CASL-1) << SDRAM0_TR_CASL);
78 tmp = ns2clks(CFG_SDRAM_PTA);
79 if ((tmp >= 2) && (tmp <= 4))
80 sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
82 sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
85 tmp = ns2clks(CFG_SDRAM_CTP);
86 if ((tmp >= 2) && (tmp <= 4))
87 sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
89 sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
92 tmp = ns2clks(CFG_SDRAM_LDF);
93 if ((tmp >= 2) && (tmp <= 4))
94 sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
96 sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
99 tmp = ns2clks(CFG_SDRAM_RFTA);
100 if ((tmp >= 4) && (tmp <= 10))
101 sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
103 sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
106 tmp = ns2clks(CFG_SDRAM_RCD);
107 if ((tmp >= 2) && (tmp <= 4))
108 sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
110 sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
113 #else /* CFG_SDRAM_CASL */
115 * If no values are configured in the board config file
116 * use the default values, which seem to be ok for most
120 * For new board ports we strongly recommend to define the
121 * correct values for the used SDRAM chips in your board
122 * config file (see PPChameleonEVB.h)
124 if (speed > 100000000) {
131 * default: 100 MHz SDRAM
135 #endif /* CFG_SDRAM_CASL */
138 /* refresh is expressed in ms */
139 static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
141 #ifdef CFG_SDRAM_CASL
144 tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
147 return ((tmp & 0x00003FF8) << 16);
148 #else /* CFG_SDRAM_CASL */
149 if (speed > 100000000) {
156 * default: 100 MHz SDRAM
160 #endif /* CFG_SDRAM_CASL */
164 * Autodetect onboard SDRAM on 405 platforms
166 void sdram_init(void)
173 * Determine SDRAM speed
175 speed = get_bus_freq(0); /* parameter not used on ppc4xx */
178 * sdtr1 (register SDRAM0_TR) must take into account timings listed
179 * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
180 * account actual SDRAM size. So we can set up sdtr1 according to what
181 * is specified in board configuration file while rtr dependds on SDRAM
182 * size we are assuming before detection.
184 sdtr1 = compute_sdtr1(speed);
186 for (i=0; i<N_MB0CF; i++) {
188 * Disable memory controller.
190 mtsdram0(mem_mcopt1, 0x00000000);
193 * Set MB0CF for bank 0.
195 mtsdram0(mem_mb0cf, mb0cf[i].reg);
196 mtsdram0(mem_sdtr1, sdtr1);
197 mtsdram0(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64));
202 * Set memory controller options reg, MCOPT1.
203 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
206 mtsdram0(mem_mcopt1, 0x80800000);
210 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
212 * OK, size detected. Enable second bank if
213 * defined (assumes same type as bank 0)
215 #ifdef CONFIG_SDRAM_BANK1
216 u32 b1cr = mb0cf[i].size | mb0cf[i].reg;
218 mtsdram0(mem_mcopt1, 0x00000000);
219 mtsdram0(mem_mb1cf, b1cr); /* SDRAM0_B1CR */
220 mtsdram0(mem_mcopt1, 0x80800000);
228 #else /* CONFIG_440 */
231 * Define some default values. Those can be overwritten in the
235 #ifndef CFG_SDRAM_TABLE
236 sdram_conf_t mb0cf[] = {
237 {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
238 {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
241 sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE;
244 #ifndef CFG_SDRAM0_TR0
245 #define CFG_SDRAM0_TR0 0x41094012
248 #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
253 static void sdram_tr1_set(int ram_address, int* tr1_value)
257 volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
258 int first_good = -1, last_bad = 0x1ff;
260 unsigned long test[NUM_TRIES] = {
261 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
262 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
263 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
264 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
265 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
266 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
267 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
268 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
269 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
270 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
271 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
272 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
273 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
274 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
275 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
276 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
278 /* go through all possible SDRAM0_TR1[RDCT] values */
279 for (i=0; i<=0x1ff; i++) {
280 /* set the current value for TR1 */
281 mtsdram(mem_tr1, (0x80800800 | i));
284 for (j=0; j<NUM_TRIES; j++) {
285 ram_pointer[j] = test[j];
287 /* clear any cache at ram location */
288 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
291 /* read values back */
292 for (j=0; j<NUM_TRIES; j++) {
293 for (k=0; k<NUM_READS; k++) {
294 /* clear any cache at ram location */
295 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
297 if (ram_pointer[j] != test[j])
306 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
307 if (j == NUM_TRIES) {
308 if (first_good == -1)
309 first_good = i; /* found beginning of window */
310 } else { /* bad read */
311 /* if we have not had a good read then don't care */
312 if (first_good != -1) {
313 /* first failure after a good read */
320 /* return the current value for TR1 */
321 *tr1_value = (first_good + last_bad) / 2;
324 #ifdef CONFIG_SDRAM_ECC
325 static void ecc_init(ulong start, ulong size)
327 ulong current_addr; /* current byte address */
328 ulong end_addr; /* end of memory region */
329 ulong addr_inc; /* address skip between writes */
330 ulong cfg0_reg; /* for restoring ECC state */
333 * TODO: Enable dcache before running this test (speedup)
336 mfsdram(mem_cfg0, cfg0_reg);
337 mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_GEN);
340 * look at geometry of SDRAM (data width) to determine whether we
341 * can skip words when writing
343 if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32)
348 current_addr = start;
349 end_addr = start + size;
351 while (current_addr < end_addr) {
352 *((ulong *)current_addr) = 0x00000000;
353 current_addr += addr_inc;
357 * TODO: Flush dcache and disable it again
361 * Enable ecc checking and parity errors
363 mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_CHK);
368 * Autodetect onboard DDR SDRAM on 440 platforms
370 * NOTE: Some of the hardcoded values are hardware dependant,
371 * so this should be extended for other future boards
372 * using this routine!
374 long int initdram(int board_type)
379 #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
380 defined(CONFIG_440GR) || defined(CONFIG_440SP)
382 * Soft-reset SDRAM controller.
384 mtsdr(sdr_srst, SDR0_SRST_DMC);
385 mtsdr(sdr_srst, 0x00000000);
388 for (i=0; i<N_MB0CF; i++) {
390 * Disable memory controller.
392 mtsdram(mem_cfg0, 0x00000000);
397 mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
398 mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
399 mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
400 mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
401 mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
404 * Following for CAS Latency = 2.5 @ 133 MHz PLB
406 mtsdram(mem_b0cr, mb0cf[i].reg);
407 mtsdram(mem_tr0, CFG_SDRAM0_TR0);
408 mtsdram(mem_tr1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
409 mtsdram(mem_rtr, 0x04100000); /* Interval 7.8µs @ 133MHz PLB */
410 mtsdram(mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM*/
411 udelay(400); /* Delay 200 usecs (min) */
414 * Enable the controller, then wait for DCEN to complete
416 mtsdram(mem_cfg0, 0x82000000); /* DCEN=1, PMUD=0, 64-bit */
419 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
421 * Optimize TR1 to current hardware environment
423 sdram_tr1_set(0x00000000, &tr1_bank1);
424 mtsdram(mem_tr1, (tr1_bank1 | 0x80800800));
426 #ifdef CONFIG_SDRAM_ECC
427 ecc_init(0, mb0cf[i].size);
431 * OK, size detected -> all done
433 return mb0cf[i].size;
437 return 0; /* nothing found ! */
440 #endif /* CONFIG_440 */
442 #endif /* CONFIG_SDRAM_BANK0 */