blob: 2d95bc53c2599aaf2d1268e220e21b162bb58dfc [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
Stefan Roese5fb692c2007-01-18 10:25:34 +01002 * (C) Copyright 2005-2007
Stefan Roese5568e612005-11-22 13:20:42 +01003 * Stefan Roese, DENX Software Engineering, sr@denx.de.
4 *
Stefan Roese62534be2006-03-17 10:28:24 +01005 * (C) Copyright 2006
6 * DAVE Srl <www.dave-tech.it>
7 *
stroesede8d5a32004-07-15 14:41:13 +00008 * (C) Copyright 2002-2004
wdenkc6097192002-11-03 00:24:07 +00009 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
10 *
Wolfgang Denk1a459662013-07-08 09:37:19 +020011 * SPDX-License-Identifier: GPL-2.0+
wdenkc6097192002-11-03 00:24:07 +000012 */
13
14#include <common.h>
Stefan Roeseb36df562010-09-09 19:18:00 +020015#include <asm/ppc4xx.h>
wdenkc6097192002-11-03 00:24:07 +000016#include <asm/processor.h>
Stefan Roese62534be2006-03-17 10:28:24 +010017#include "sdram.h"
Grant Ericksonc821b5f2008-05-22 14:44:14 -070018#include "ecc.h"
wdenkc6097192002-11-03 00:24:07 +000019
wdenkc6097192002-11-03 00:24:07 +000020#ifdef CONFIG_SDRAM_BANK0
21
Stefan Roese5fb692c2007-01-18 10:25:34 +010022#ifndef CONFIG_440
wdenkc6097192002-11-03 00:24:07 +000023
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020024#ifndef CONFIG_SYS_SDRAM_TABLE
stroesede8d5a32004-07-15 14:41:13 +000025sdram_conf_t mb0cf[] = {
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020026 {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
27 {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
28 {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
29 {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
30 {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
stroesede8d5a32004-07-15 14:41:13 +000031};
Stefan Roese5568e612005-11-22 13:20:42 +010032#else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020033sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
Stefan Roese5568e612005-11-22 13:20:42 +010034#endif
35
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020036#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
stroesede8d5a32004-07-15 14:41:13 +000037
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020038#ifdef CONFIG_SYS_SDRAM_CASL
Stefan Roese62534be2006-03-17 10:28:24 +010039static ulong ns2clks(ulong ns)
40{
41 ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
42
43 return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
44}
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020045#endif /* CONFIG_SYS_SDRAM_CASL */
Stefan Roese62534be2006-03-17 10:28:24 +010046
47static ulong compute_sdtr1(ulong speed)
48{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020049#ifdef CONFIG_SYS_SDRAM_CASL
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020050 ulong tmp;
51 ulong sdtr1 = 0;
Stefan Roese62534be2006-03-17 10:28:24 +010052
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020053 /* CASL */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020054 if (CONFIG_SYS_SDRAM_CASL < 2)
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020055 sdtr1 |= (1 << SDRAM0_TR_CASL);
56 else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020057 if (CONFIG_SYS_SDRAM_CASL > 4)
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020058 sdtr1 |= (3 << SDRAM0_TR_CASL);
59 else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020060 sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL);
Stefan Roese62534be2006-03-17 10:28:24 +010061
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020062 /* PTA */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020063 tmp = ns2clks(CONFIG_SYS_SDRAM_PTA);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020064 if ((tmp >= 2) && (tmp <= 4))
65 sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
66 else
67 sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
Stefan Roese62534be2006-03-17 10:28:24 +010068
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020069 /* CTP */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020070 tmp = ns2clks(CONFIG_SYS_SDRAM_CTP);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020071 if ((tmp >= 2) && (tmp <= 4))
72 sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
73 else
74 sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
Stefan Roese62534be2006-03-17 10:28:24 +010075
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020076 /* LDF */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020077 tmp = ns2clks(CONFIG_SYS_SDRAM_LDF);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020078 if ((tmp >= 2) && (tmp <= 4))
79 sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
80 else
81 sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
Stefan Roese62534be2006-03-17 10:28:24 +010082
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020083 /* RFTA */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020084 tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020085 if ((tmp >= 4) && (tmp <= 10))
86 sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
87 else
88 sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
Stefan Roese62534be2006-03-17 10:28:24 +010089
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020090 /* RCD */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020091 tmp = ns2clks(CONFIG_SYS_SDRAM_RCD);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020092 if ((tmp >= 2) && (tmp <= 4))
93 sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
94 else
95 sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
Stefan Roese62534be2006-03-17 10:28:24 +010096
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020097 return sdtr1;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020098#else /* CONFIG_SYS_SDRAM_CASL */
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020099 /*
100 * If no values are configured in the board config file
101 * use the default values, which seem to be ok for most
102 * boards.
103 *
104 * REMARK:
105 * For new board ports we strongly recommend to define the
106 * correct values for the used SDRAM chips in your board
107 * config file (see PPChameleonEVB.h)
108 */
109 if (speed > 100000000) {
110 /*
111 * 133 MHz SDRAM
112 */
113 return 0x01074015;
114 } else {
115 /*
116 * default: 100 MHz SDRAM
117 */
118 return 0x0086400d;
119 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200120#endif /* CONFIG_SYS_SDRAM_CASL */
Stefan Roese62534be2006-03-17 10:28:24 +0100121}
122
123/* refresh is expressed in ms */
124static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
125{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200126#ifdef CONFIG_SYS_SDRAM_CASL
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200127 ulong tmp;
Stefan Roese62534be2006-03-17 10:28:24 +0100128
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200129 tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
130 tmp /= 1000000;
Stefan Roese62534be2006-03-17 10:28:24 +0100131
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200132 return ((tmp & 0x00003FF8) << 16);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200133#else /* CONFIG_SYS_SDRAM_CASL */
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200134 if (speed > 100000000) {
135 /*
136 * 133 MHz SDRAM
137 */
Stefan Roese62534be2006-03-17 10:28:24 +0100138 return 0x07f00000;
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200139 } else {
140 /*
141 * default: 100 MHz SDRAM
142 */
Stefan Roese62534be2006-03-17 10:28:24 +0100143 return 0x05f00000;
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200144 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200145#endif /* CONFIG_SYS_SDRAM_CASL */
Stefan Roese62534be2006-03-17 10:28:24 +0100146}
147
Stefan Roese5568e612005-11-22 13:20:42 +0100148/*
149 * Autodetect onboard SDRAM on 405 platforms
150 */
Becky Bruce9973e3c2008-06-09 16:03:40 -0500151phys_size_t initdram(int board_type)
wdenkc6097192002-11-03 00:24:07 +0000152{
Stefan Roese62534be2006-03-17 10:28:24 +0100153 ulong speed;
wdenkc6097192002-11-03 00:24:07 +0000154 ulong sdtr1;
stroesede8d5a32004-07-15 14:41:13 +0000155 int i;
wdenkc6097192002-11-03 00:24:07 +0000156
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200157 /*
158 * Determine SDRAM speed
159 */
160 speed = get_bus_freq(0); /* parameter not used on ppc4xx */
Stefan Roese62534be2006-03-17 10:28:24 +0100161
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200162 /*
163 * sdtr1 (register SDRAM0_TR) must take into account timings listed
164 * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
165 * account actual SDRAM size. So we can set up sdtr1 according to what
166 * is specified in board configuration file while rtr dependds on SDRAM
167 * size we are assuming before detection.
168 */
169 sdtr1 = compute_sdtr1(speed);
wdenkc6097192002-11-03 00:24:07 +0000170
stroesede8d5a32004-07-15 14:41:13 +0000171 for (i=0; i<N_MB0CF; i++) {
stroese61774452003-02-10 16:26:37 +0000172 /*
stroesede8d5a32004-07-15 14:41:13 +0000173 * Disable memory controller.
stroese61774452003-02-10 16:26:37 +0000174 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200175 mtsdram(SDRAM0_CFG, 0x00000000);
wdenke5ad56b2003-02-11 01:49:43 +0000176
wdenkc6097192002-11-03 00:24:07 +0000177 /*
stroesede8d5a32004-07-15 14:41:13 +0000178 * Set MB0CF for bank 0.
wdenkc6097192002-11-03 00:24:07 +0000179 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200180 mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
181 mtsdram(SDRAM0_TR, sdtr1);
182 mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64));
wdenke5ad56b2003-02-11 01:49:43 +0000183
stroesede8d5a32004-07-15 14:41:13 +0000184 udelay(200);
wdenke5ad56b2003-02-11 01:49:43 +0000185
wdenkc6097192002-11-03 00:24:07 +0000186 /*
stroesede8d5a32004-07-15 14:41:13 +0000187 * Set memory controller options reg, MCOPT1.
188 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
189 * read/prefetch.
wdenkc6097192002-11-03 00:24:07 +0000190 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200191 mtsdram(SDRAM0_CFG, 0x80800000);
stroesede8d5a32004-07-15 14:41:13 +0000192
193 udelay(10000);
194
195 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200196 phys_size_t size = mb0cf[i].size;
197
stroesede8d5a32004-07-15 14:41:13 +0000198 /*
John Otkend4024bb2007-07-26 17:49:11 +0200199 * OK, size detected. Enable second bank if
200 * defined (assumes same type as bank 0)
stroesede8d5a32004-07-15 14:41:13 +0000201 */
John Otkend4024bb2007-07-26 17:49:11 +0200202#ifdef CONFIG_SDRAM_BANK1
Stefan Roese95b602b2009-09-24 13:59:57 +0200203 mtsdram(SDRAM0_CFG, 0x00000000);
204 mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
205 mtsdram(SDRAM0_CFG, 0x80800000);
John Otkend4024bb2007-07-26 17:49:11 +0200206 udelay(10000);
Stefan Roese779e9752007-08-14 14:44:41 +0200207
208 /*
209 * Check if 2nd bank is really available.
210 * If the size not equal to the size of the first
211 * bank, then disable the 2nd bank completely.
212 */
213 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
214 mb0cf[i].size) {
Stefan Roese95b602b2009-09-24 13:59:57 +0200215 mtsdram(SDRAM0_B1CR, 0);
216 mtsdram(SDRAM0_CFG, 0);
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200217 } else {
218 /*
219 * We have two identical banks, so the size
220 * is twice the bank size
221 */
222 size = 2 * size;
Stefan Roese779e9752007-08-14 14:44:41 +0200223 }
John Otkend4024bb2007-07-26 17:49:11 +0200224#endif
Stefan Roesebbeff302008-06-02 17:37:28 +0200225
226 /*
227 * OK, size detected -> all done
228 */
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200229 return size;
stroesede8d5a32004-07-15 14:41:13 +0000230 }
wdenkc6097192002-11-03 00:24:07 +0000231 }
Stefan Roesebbeff302008-06-02 17:37:28 +0200232
233 return 0;
wdenkc6097192002-11-03 00:24:07 +0000234}
235
Stefan Roese5568e612005-11-22 13:20:42 +0100236#else /* CONFIG_440 */
237
Stefan Roese5fb692c2007-01-18 10:25:34 +0100238/*
239 * Define some default values. Those can be overwritten in the
240 * board config file.
241 */
242
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200243#ifndef CONFIG_SYS_SDRAM_TABLE
Stefan Roese5fb692c2007-01-18 10:25:34 +0100244sdram_conf_t mb0cf[] = {
245 {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100246 {(128 << 20), 13, 0x000A4001}, /* 128MB mode 3, 13x10(4) */
Stefan Roese5fb692c2007-01-18 10:25:34 +0100247 {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
248};
249#else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200250sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
Stefan Roese5fb692c2007-01-18 10:25:34 +0100251#endif
252
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200253#ifndef CONFIG_SYS_SDRAM0_TR0
254#define CONFIG_SYS_SDRAM0_TR0 0x41094012
Stefan Roese5fb692c2007-01-18 10:25:34 +0100255#endif
256
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100257#ifndef CONFIG_SYS_SDRAM0_WDDCTR
258#define CONFIG_SYS_SDRAM0_WDDCTR 0x00000000 /* wrcp=0 dcd=0 */
259#endif
260
261#ifndef CONFIG_SYS_SDRAM0_RTR
262#define CONFIG_SYS_SDRAM0_RTR 0x04100000 /* 7.8us @ 133MHz PLB */
263#endif
264
265#ifndef CONFIG_SYS_SDRAM0_CFG0
266#define CONFIG_SYS_SDRAM0_CFG0 0x82000000 /* DCEN=1, PMUD=0, 64-bit */
267#endif
268
Stefan Roese5fb692c2007-01-18 10:25:34 +0100269#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
270
Stefan Roese62534be2006-03-17 10:28:24 +0100271#define NUM_TRIES 64
272#define NUM_READS 10
273
274static void sdram_tr1_set(int ram_address, int* tr1_value)
275{
276 int i;
277 int j, k;
278 volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
279 int first_good = -1, last_bad = 0x1ff;
280
281 unsigned long test[NUM_TRIES] = {
282 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
283 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
284 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
285 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
286 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
287 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
288 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
289 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
290 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
291 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
292 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
293 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
294 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
295 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
296 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
297 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
298
299 /* go through all possible SDRAM0_TR1[RDCT] values */
300 for (i=0; i<=0x1ff; i++) {
301 /* set the current value for TR1 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200302 mtsdram(SDRAM0_TR1, (0x80800800 | i));
Stefan Roese62534be2006-03-17 10:28:24 +0100303
304 /* write values */
305 for (j=0; j<NUM_TRIES; j++) {
306 ram_pointer[j] = test[j];
307
308 /* clear any cache at ram location */
309 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
310 }
311
312 /* read values back */
313 for (j=0; j<NUM_TRIES; j++) {
314 for (k=0; k<NUM_READS; k++) {
315 /* clear any cache at ram location */
316 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
317
318 if (ram_pointer[j] != test[j])
319 break;
320 }
321
322 /* read error */
323 if (k != NUM_READS)
324 break;
325 }
326
327 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
328 if (j == NUM_TRIES) {
329 if (first_good == -1)
330 first_good = i; /* found beginning of window */
331 } else { /* bad read */
332 /* if we have not had a good read then don't care */
333 if (first_good != -1) {
334 /* first failure after a good read */
335 last_bad = i-1;
336 break;
337 }
338 }
339 }
340
341 /* return the current value for TR1 */
342 *tr1_value = (first_good + last_bad) / 2;
343}
344
Stefan Roese5568e612005-11-22 13:20:42 +0100345/*
346 * Autodetect onboard DDR SDRAM on 440 platforms
347 *
348 * NOTE: Some of the hardcoded values are hardware dependant,
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200349 * so this should be extended for other future boards
350 * using this routine!
Stefan Roese5568e612005-11-22 13:20:42 +0100351 */
Becky Bruce9973e3c2008-06-09 16:03:40 -0500352phys_size_t initdram(int board_type)
Stefan Roese5568e612005-11-22 13:20:42 +0100353{
354 int i;
Stefan Roese62534be2006-03-17 10:28:24 +0100355 int tr1_bank1;
Stefan Roese5568e612005-11-22 13:20:42 +0100356
Stefan Roese5fb692c2007-01-18 10:25:34 +0100357#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
358 defined(CONFIG_440GR) || defined(CONFIG_440SP)
Stefan Roese899620c2006-08-15 14:22:35 +0200359 /*
360 * Soft-reset SDRAM controller.
361 */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200362 mtsdr(SDR0_SRST, SDR0_SRST_DMC);
363 mtsdr(SDR0_SRST, 0x00000000);
Stefan Roese899620c2006-08-15 14:22:35 +0200364#endif
365
Stefan Roese5568e612005-11-22 13:20:42 +0100366 for (i=0; i<N_MB0CF; i++) {
367 /*
368 * Disable memory controller.
369 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200370 mtsdram(SDRAM0_CFG0, 0x00000000);
Stefan Roese5568e612005-11-22 13:20:42 +0100371
372 /*
373 * Setup some default
374 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200375 mtsdram(SDRAM0_UABBA, 0x00000000); /* ubba=0 (default) */
376 mtsdram(SDRAM0_SLIO, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
377 mtsdram(SDRAM0_DEVOPT, 0x00000000); /* dll=0 ds=0 (normal) */
378 mtsdram(SDRAM0_WDDCTR, CONFIG_SYS_SDRAM0_WDDCTR);
379 mtsdram(SDRAM0_CLKTR, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
Stefan Roese5568e612005-11-22 13:20:42 +0100380
381 /*
382 * Following for CAS Latency = 2.5 @ 133 MHz PLB
383 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200384 mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
385 mtsdram(SDRAM0_TR0, CONFIG_SYS_SDRAM0_TR0);
386 mtsdram(SDRAM0_TR1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
387 mtsdram(SDRAM0_RTR, CONFIG_SYS_SDRAM0_RTR);
388 mtsdram(SDRAM0_CFG1, 0x00000000); /* Self-refresh exit, disable PM*/
Stefan Roese5568e612005-11-22 13:20:42 +0100389 udelay(400); /* Delay 200 usecs (min) */
390
391 /*
392 * Enable the controller, then wait for DCEN to complete
393 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200394 mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
Stefan Roese5568e612005-11-22 13:20:42 +0100395 udelay(10000);
396
397 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100398 phys_size_t size = mb0cf[i].size;
Stefan Roese5568e612005-11-22 13:20:42 +0100399 /*
Stefan Roese62534be2006-03-17 10:28:24 +0100400 * Optimize TR1 to current hardware environment
401 */
402 sdram_tr1_set(0x00000000, &tr1_bank1);
Stefan Roese95b602b2009-09-24 13:59:57 +0200403 mtsdram(SDRAM0_TR1, (tr1_bank1 | 0x80800800));
Stefan Roese62534be2006-03-17 10:28:24 +0100404
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100405
406 /*
407 * OK, size detected. Enable second bank if
408 * defined (assumes same type as bank 0)
409 */
410#ifdef CONFIG_SDRAM_BANK1
Stefan Roese95b602b2009-09-24 13:59:57 +0200411 mtsdram(SDRAM0_CFG0, 0);
412 mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
413 mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100414 udelay(10000);
415
416 /*
417 * Check if 2nd bank is really available.
418 * If the size not equal to the size of the first
419 * bank, then disable the 2nd bank completely.
420 */
421 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size)
422 != mb0cf[i].size) {
Stefan Roese95b602b2009-09-24 13:59:57 +0200423 mtsdram(SDRAM0_CFG0, 0);
424 mtsdram(SDRAM0_B1CR, 0);
425 mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100426 udelay(10000);
427 } else {
428 /*
429 * We have two identical banks, so the size
430 * is twice the bank size
431 */
432 size = 2 * size;
433 }
434#endif
435
Stefan Roese62534be2006-03-17 10:28:24 +0100436#ifdef CONFIG_SDRAM_ECC
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100437 ecc_init(0, size);
Stefan Roese62534be2006-03-17 10:28:24 +0100438#endif
439
440 /*
Stefan Roese5568e612005-11-22 13:20:42 +0100441 * OK, size detected -> all done
442 */
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100443 return size;
Stefan Roese5568e612005-11-22 13:20:42 +0100444 }
445 }
446
447 return 0; /* nothing found ! */
448}
449
450#endif /* CONFIG_440 */
451
wdenkc6097192002-11-03 00:24:07 +0000452#endif /* CONFIG_SDRAM_BANK0 */