blob: 5a3336e3c8a16457024ec6301b56386cfdeffe99 [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 *
11 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
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.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wdenkc6097192002-11-03 00:24:07 +000022 * GNU General Public License for more details.
23 *
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,
27 * MA 02111-1307 USA
28 */
29
30#include <common.h>
31#include <ppc4xx.h>
32#include <asm/processor.h>
Stefan Roese62534be2006-03-17 10:28:24 +010033#include "sdram.h"
Grant Ericksonc821b5f2008-05-22 14:44:14 -070034#include "ecc.h"
wdenkc6097192002-11-03 00:24:07 +000035
wdenkc6097192002-11-03 00:24:07 +000036#ifdef CONFIG_SDRAM_BANK0
37
Stefan Roese5fb692c2007-01-18 10:25:34 +010038#ifndef CONFIG_440
wdenkc6097192002-11-03 00:24:07 +000039
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020040#ifndef CONFIG_SYS_SDRAM_TABLE
stroesede8d5a32004-07-15 14:41:13 +000041sdram_conf_t mb0cf[] = {
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020042 {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
43 {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
44 {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
45 {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
46 {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
stroesede8d5a32004-07-15 14:41:13 +000047};
Stefan Roese5568e612005-11-22 13:20:42 +010048#else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020049sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
Stefan Roese5568e612005-11-22 13:20:42 +010050#endif
51
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020052#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
stroesede8d5a32004-07-15 14:41:13 +000053
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020054#ifdef CONFIG_SYS_SDRAM_CASL
Stefan Roese62534be2006-03-17 10:28:24 +010055static ulong ns2clks(ulong ns)
56{
57 ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
58
59 return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
60}
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020061#endif /* CONFIG_SYS_SDRAM_CASL */
Stefan Roese62534be2006-03-17 10:28:24 +010062
63static ulong compute_sdtr1(ulong speed)
64{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020065#ifdef CONFIG_SYS_SDRAM_CASL
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020066 ulong tmp;
67 ulong sdtr1 = 0;
Stefan Roese62534be2006-03-17 10:28:24 +010068
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020069 /* CASL */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020070 if (CONFIG_SYS_SDRAM_CASL < 2)
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020071 sdtr1 |= (1 << SDRAM0_TR_CASL);
72 else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020073 if (CONFIG_SYS_SDRAM_CASL > 4)
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020074 sdtr1 |= (3 << SDRAM0_TR_CASL);
75 else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020076 sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL);
Stefan Roese62534be2006-03-17 10:28:24 +010077
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020078 /* PTA */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020079 tmp = ns2clks(CONFIG_SYS_SDRAM_PTA);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020080 if ((tmp >= 2) && (tmp <= 4))
81 sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
82 else
83 sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
Stefan Roese62534be2006-03-17 10:28:24 +010084
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020085 /* CTP */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020086 tmp = ns2clks(CONFIG_SYS_SDRAM_CTP);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020087 if ((tmp >= 2) && (tmp <= 4))
88 sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
89 else
90 sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
Stefan Roese62534be2006-03-17 10:28:24 +010091
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020092 /* LDF */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020093 tmp = ns2clks(CONFIG_SYS_SDRAM_LDF);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020094 if ((tmp >= 2) && (tmp <= 4))
95 sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
96 else
97 sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
Stefan Roese62534be2006-03-17 10:28:24 +010098
Wolfgang Denkcf48eb92006-04-16 10:51:58 +020099 /* RFTA */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200100 tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200101 if ((tmp >= 4) && (tmp <= 10))
102 sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
103 else
104 sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
Stefan Roese62534be2006-03-17 10:28:24 +0100105
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200106 /* RCD */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200107 tmp = ns2clks(CONFIG_SYS_SDRAM_RCD);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200108 if ((tmp >= 2) && (tmp <= 4))
109 sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
110 else
111 sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
Stefan Roese62534be2006-03-17 10:28:24 +0100112
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200113 return sdtr1;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200114#else /* CONFIG_SYS_SDRAM_CASL */
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200115 /*
116 * If no values are configured in the board config file
117 * use the default values, which seem to be ok for most
118 * boards.
119 *
120 * REMARK:
121 * For new board ports we strongly recommend to define the
122 * correct values for the used SDRAM chips in your board
123 * config file (see PPChameleonEVB.h)
124 */
125 if (speed > 100000000) {
126 /*
127 * 133 MHz SDRAM
128 */
129 return 0x01074015;
130 } else {
131 /*
132 * default: 100 MHz SDRAM
133 */
134 return 0x0086400d;
135 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200136#endif /* CONFIG_SYS_SDRAM_CASL */
Stefan Roese62534be2006-03-17 10:28:24 +0100137}
138
139/* refresh is expressed in ms */
140static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
141{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200142#ifdef CONFIG_SYS_SDRAM_CASL
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200143 ulong tmp;
Stefan Roese62534be2006-03-17 10:28:24 +0100144
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200145 tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
146 tmp /= 1000000;
Stefan Roese62534be2006-03-17 10:28:24 +0100147
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200148 return ((tmp & 0x00003FF8) << 16);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200149#else /* CONFIG_SYS_SDRAM_CASL */
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200150 if (speed > 100000000) {
151 /*
152 * 133 MHz SDRAM
153 */
Stefan Roese62534be2006-03-17 10:28:24 +0100154 return 0x07f00000;
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200155 } else {
156 /*
157 * default: 100 MHz SDRAM
158 */
Stefan Roese62534be2006-03-17 10:28:24 +0100159 return 0x05f00000;
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200160 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200161#endif /* CONFIG_SYS_SDRAM_CASL */
Stefan Roese62534be2006-03-17 10:28:24 +0100162}
163
Stefan Roese5568e612005-11-22 13:20:42 +0100164/*
165 * Autodetect onboard SDRAM on 405 platforms
166 */
Becky Bruce9973e3c2008-06-09 16:03:40 -0500167phys_size_t initdram(int board_type)
wdenkc6097192002-11-03 00:24:07 +0000168{
Stefan Roese62534be2006-03-17 10:28:24 +0100169 ulong speed;
wdenkc6097192002-11-03 00:24:07 +0000170 ulong sdtr1;
stroesede8d5a32004-07-15 14:41:13 +0000171 int i;
wdenkc6097192002-11-03 00:24:07 +0000172
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200173 /*
174 * Determine SDRAM speed
175 */
176 speed = get_bus_freq(0); /* parameter not used on ppc4xx */
Stefan Roese62534be2006-03-17 10:28:24 +0100177
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200178 /*
179 * sdtr1 (register SDRAM0_TR) must take into account timings listed
180 * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
181 * account actual SDRAM size. So we can set up sdtr1 according to what
182 * is specified in board configuration file while rtr dependds on SDRAM
183 * size we are assuming before detection.
184 */
185 sdtr1 = compute_sdtr1(speed);
wdenkc6097192002-11-03 00:24:07 +0000186
stroesede8d5a32004-07-15 14:41:13 +0000187 for (i=0; i<N_MB0CF; i++) {
stroese61774452003-02-10 16:26:37 +0000188 /*
stroesede8d5a32004-07-15 14:41:13 +0000189 * Disable memory controller.
stroese61774452003-02-10 16:26:37 +0000190 */
Stefan Roese779e9752007-08-14 14:44:41 +0200191 mtsdram(mem_mcopt1, 0x00000000);
wdenke5ad56b2003-02-11 01:49:43 +0000192
wdenkc6097192002-11-03 00:24:07 +0000193 /*
stroesede8d5a32004-07-15 14:41:13 +0000194 * Set MB0CF for bank 0.
wdenkc6097192002-11-03 00:24:07 +0000195 */
Stefan Roese779e9752007-08-14 14:44:41 +0200196 mtsdram(mem_mb0cf, mb0cf[i].reg);
197 mtsdram(mem_sdtr1, sdtr1);
198 mtsdram(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64));
wdenke5ad56b2003-02-11 01:49:43 +0000199
stroesede8d5a32004-07-15 14:41:13 +0000200 udelay(200);
wdenke5ad56b2003-02-11 01:49:43 +0000201
wdenkc6097192002-11-03 00:24:07 +0000202 /*
stroesede8d5a32004-07-15 14:41:13 +0000203 * Set memory controller options reg, MCOPT1.
204 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
205 * read/prefetch.
wdenkc6097192002-11-03 00:24:07 +0000206 */
Stefan Roese779e9752007-08-14 14:44:41 +0200207 mtsdram(mem_mcopt1, 0x80800000);
stroesede8d5a32004-07-15 14:41:13 +0000208
209 udelay(10000);
210
211 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200212 phys_size_t size = mb0cf[i].size;
213
stroesede8d5a32004-07-15 14:41:13 +0000214 /*
John Otkend4024bb2007-07-26 17:49:11 +0200215 * OK, size detected. Enable second bank if
216 * defined (assumes same type as bank 0)
stroesede8d5a32004-07-15 14:41:13 +0000217 */
John Otkend4024bb2007-07-26 17:49:11 +0200218#ifdef CONFIG_SDRAM_BANK1
Stefan Roese779e9752007-08-14 14:44:41 +0200219 mtsdram(mem_mcopt1, 0x00000000);
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200220 mtsdram(mem_mb1cf, mb0cf[i].size | mb0cf[i].reg);
Stefan Roese779e9752007-08-14 14:44:41 +0200221 mtsdram(mem_mcopt1, 0x80800000);
John Otkend4024bb2007-07-26 17:49:11 +0200222 udelay(10000);
Stefan Roese779e9752007-08-14 14:44:41 +0200223
224 /*
225 * Check if 2nd bank is really available.
226 * If the size not equal to the size of the first
227 * bank, then disable the 2nd bank completely.
228 */
229 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
230 mb0cf[i].size) {
231 mtsdram(mem_mb1cf, 0);
232 mtsdram(mem_mcopt1, 0);
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200233 } else {
234 /*
235 * We have two identical banks, so the size
236 * is twice the bank size
237 */
238 size = 2 * size;
Stefan Roese779e9752007-08-14 14:44:41 +0200239 }
John Otkend4024bb2007-07-26 17:49:11 +0200240#endif
Stefan Roesebbeff302008-06-02 17:37:28 +0200241
242 /*
243 * OK, size detected -> all done
244 */
Stefan Roese7bf5ecf2008-09-10 16:53:47 +0200245 return size;
stroesede8d5a32004-07-15 14:41:13 +0000246 }
wdenkc6097192002-11-03 00:24:07 +0000247 }
Stefan Roesebbeff302008-06-02 17:37:28 +0200248
249 return 0;
wdenkc6097192002-11-03 00:24:07 +0000250}
251
Stefan Roese5568e612005-11-22 13:20:42 +0100252#else /* CONFIG_440 */
253
Stefan Roese5fb692c2007-01-18 10:25:34 +0100254/*
255 * Define some default values. Those can be overwritten in the
256 * board config file.
257 */
258
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200259#ifndef CONFIG_SYS_SDRAM_TABLE
Stefan Roese5fb692c2007-01-18 10:25:34 +0100260sdram_conf_t mb0cf[] = {
261 {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100262 {(128 << 20), 13, 0x000A4001}, /* 128MB mode 3, 13x10(4) */
Stefan Roese5fb692c2007-01-18 10:25:34 +0100263 {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
264};
265#else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200266sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
Stefan Roese5fb692c2007-01-18 10:25:34 +0100267#endif
268
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200269#ifndef CONFIG_SYS_SDRAM0_TR0
270#define CONFIG_SYS_SDRAM0_TR0 0x41094012
Stefan Roese5fb692c2007-01-18 10:25:34 +0100271#endif
272
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100273#ifndef CONFIG_SYS_SDRAM0_WDDCTR
274#define CONFIG_SYS_SDRAM0_WDDCTR 0x00000000 /* wrcp=0 dcd=0 */
275#endif
276
277#ifndef CONFIG_SYS_SDRAM0_RTR
278#define CONFIG_SYS_SDRAM0_RTR 0x04100000 /* 7.8us @ 133MHz PLB */
279#endif
280
281#ifndef CONFIG_SYS_SDRAM0_CFG0
282#define CONFIG_SYS_SDRAM0_CFG0 0x82000000 /* DCEN=1, PMUD=0, 64-bit */
283#endif
284
Stefan Roese5fb692c2007-01-18 10:25:34 +0100285#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
286
Stefan Roese62534be2006-03-17 10:28:24 +0100287#define NUM_TRIES 64
288#define NUM_READS 10
289
290static void sdram_tr1_set(int ram_address, int* tr1_value)
291{
292 int i;
293 int j, k;
294 volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
295 int first_good = -1, last_bad = 0x1ff;
296
297 unsigned long test[NUM_TRIES] = {
298 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
299 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
300 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
301 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
302 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
303 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
304 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
305 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
306 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
307 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
308 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
309 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
310 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
311 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
312 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
313 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
314
315 /* go through all possible SDRAM0_TR1[RDCT] values */
316 for (i=0; i<=0x1ff; i++) {
317 /* set the current value for TR1 */
318 mtsdram(mem_tr1, (0x80800800 | i));
319
320 /* write values */
321 for (j=0; j<NUM_TRIES; j++) {
322 ram_pointer[j] = test[j];
323
324 /* clear any cache at ram location */
325 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
326 }
327
328 /* read values back */
329 for (j=0; j<NUM_TRIES; j++) {
330 for (k=0; k<NUM_READS; k++) {
331 /* clear any cache at ram location */
332 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
333
334 if (ram_pointer[j] != test[j])
335 break;
336 }
337
338 /* read error */
339 if (k != NUM_READS)
340 break;
341 }
342
343 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
344 if (j == NUM_TRIES) {
345 if (first_good == -1)
346 first_good = i; /* found beginning of window */
347 } else { /* bad read */
348 /* if we have not had a good read then don't care */
349 if (first_good != -1) {
350 /* first failure after a good read */
351 last_bad = i-1;
352 break;
353 }
354 }
355 }
356
357 /* return the current value for TR1 */
358 *tr1_value = (first_good + last_bad) / 2;
359}
360
Stefan Roese5568e612005-11-22 13:20:42 +0100361/*
362 * Autodetect onboard DDR SDRAM on 440 platforms
363 *
364 * NOTE: Some of the hardcoded values are hardware dependant,
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200365 * so this should be extended for other future boards
366 * using this routine!
Stefan Roese5568e612005-11-22 13:20:42 +0100367 */
Becky Bruce9973e3c2008-06-09 16:03:40 -0500368phys_size_t initdram(int board_type)
Stefan Roese5568e612005-11-22 13:20:42 +0100369{
370 int i;
Stefan Roese62534be2006-03-17 10:28:24 +0100371 int tr1_bank1;
Stefan Roese5568e612005-11-22 13:20:42 +0100372
Stefan Roese5fb692c2007-01-18 10:25:34 +0100373#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
374 defined(CONFIG_440GR) || defined(CONFIG_440SP)
Stefan Roese899620c2006-08-15 14:22:35 +0200375 /*
376 * Soft-reset SDRAM controller.
377 */
Stefan Roese297a6582009-09-09 16:25:29 +0200378 mtsdr(SDR0_SRST, SDR0_SRST_DMC);
379 mtsdr(SDR0_SRST, 0x00000000);
Stefan Roese899620c2006-08-15 14:22:35 +0200380#endif
381
Stefan Roese5568e612005-11-22 13:20:42 +0100382 for (i=0; i<N_MB0CF; i++) {
383 /*
384 * Disable memory controller.
385 */
386 mtsdram(mem_cfg0, 0x00000000);
387
388 /*
389 * Setup some default
390 */
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200391 mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
392 mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
Stefan Roese5568e612005-11-22 13:20:42 +0100393 mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100394 mtsdram(mem_wddctr, CONFIG_SYS_SDRAM0_WDDCTR);
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200395 mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
Stefan Roese5568e612005-11-22 13:20:42 +0100396
397 /*
398 * Following for CAS Latency = 2.5 @ 133 MHz PLB
399 */
400 mtsdram(mem_b0cr, mb0cf[i].reg);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200401 mtsdram(mem_tr0, CONFIG_SYS_SDRAM0_TR0);
Stefan Roese5568e612005-11-22 13:20:42 +0100402 mtsdram(mem_tr1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100403 mtsdram(mem_rtr, CONFIG_SYS_SDRAM0_RTR);
Stefan Roese5568e612005-11-22 13:20:42 +0100404 mtsdram(mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM*/
405 udelay(400); /* Delay 200 usecs (min) */
406
407 /*
408 * Enable the controller, then wait for DCEN to complete
409 */
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100410 mtsdram(mem_cfg0, CONFIG_SYS_SDRAM0_CFG0);
Stefan Roese5568e612005-11-22 13:20:42 +0100411 udelay(10000);
412
413 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100414 phys_size_t size = mb0cf[i].size;
Stefan Roese5568e612005-11-22 13:20:42 +0100415 /*
Stefan Roese62534be2006-03-17 10:28:24 +0100416 * Optimize TR1 to current hardware environment
417 */
418 sdram_tr1_set(0x00000000, &tr1_bank1);
419 mtsdram(mem_tr1, (tr1_bank1 | 0x80800800));
420
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100421
422 /*
423 * OK, size detected. Enable second bank if
424 * defined (assumes same type as bank 0)
425 */
426#ifdef CONFIG_SDRAM_BANK1
427 mtsdram(mem_cfg0, 0);
428 mtsdram(mem_b1cr, mb0cf[i].size | mb0cf[i].reg);
429 mtsdram(mem_cfg0, CONFIG_SYS_SDRAM0_CFG0);
430 udelay(10000);
431
432 /*
433 * Check if 2nd bank is really available.
434 * If the size not equal to the size of the first
435 * bank, then disable the 2nd bank completely.
436 */
437 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size)
438 != mb0cf[i].size) {
439 mtsdram(mem_cfg0, 0);
440 mtsdram(mem_b1cr, 0);
441 mtsdram(mem_cfg0, CONFIG_SYS_SDRAM0_CFG0);
442 udelay(10000);
443 } else {
444 /*
445 * We have two identical banks, so the size
446 * is twice the bank size
447 */
448 size = 2 * size;
449 }
450#endif
451
Stefan Roese62534be2006-03-17 10:28:24 +0100452#ifdef CONFIG_SDRAM_ECC
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100453 ecc_init(0, size);
Stefan Roese62534be2006-03-17 10:28:24 +0100454#endif
455
456 /*
Stefan Roese5568e612005-11-22 13:20:42 +0100457 * OK, size detected -> all done
458 */
Dirk Eibach3943d2f2008-12-09 11:00:07 +0100459 return size;
Stefan Roese5568e612005-11-22 13:20:42 +0100460 }
461 }
462
463 return 0; /* nothing found ! */
464}
465
466#endif /* CONFIG_440 */
467
wdenkc6097192002-11-03 00:24:07 +0000468#endif /* CONFIG_SDRAM_BANK0 */