]>
Commit | Line | Data |
---|---|---|
c609719b | 1 | /* |
5fb692ca | 2 | * (C) Copyright 2005-2007 |
5568e613 SR |
3 | * Stefan Roese, DENX Software Engineering, sr@denx.de. |
4 | * | |
62534beb SR |
5 | * (C) Copyright 2006 |
6 | * DAVE Srl <www.dave-tech.it> | |
7 | * | |
de8d5a36 | 8 | * (C) Copyright 2002-2004 |
c609719b WD |
9 | * 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 | |
cf48eb9a | 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c609719b WD |
22 | * 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> | |
62534beb | 33 | #include "sdram.h" |
c821b5f1 | 34 | #include "ecc.h" |
c609719b | 35 | |
c609719b WD |
36 | #ifdef CONFIG_SDRAM_BANK0 |
37 | ||
5fb692ca | 38 | #ifndef CONFIG_440 |
c609719b | 39 | |
6d0f6bcf | 40 | #ifndef CONFIG_SYS_SDRAM_TABLE |
de8d5a36 | 41 | sdram_conf_t mb0cf[] = { |
cf48eb9a WD |
42 | {(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) */ | |
de8d5a36 | 47 | }; |
5568e613 | 48 | #else |
6d0f6bcf | 49 | sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE; |
5568e613 SR |
50 | #endif |
51 | ||
cf48eb9a | 52 | #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) |
c609719b | 53 | |
6d0f6bcf | 54 | #ifdef CONFIG_SYS_SDRAM_CASL |
62534beb SR |
55 | static 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 | } | |
6d0f6bcf | 61 | #endif /* CONFIG_SYS_SDRAM_CASL */ |
62534beb SR |
62 | |
63 | static ulong compute_sdtr1(ulong speed) | |
64 | { | |
6d0f6bcf | 65 | #ifdef CONFIG_SYS_SDRAM_CASL |
cf48eb9a WD |
66 | ulong tmp; |
67 | ulong sdtr1 = 0; | |
68 | ||
69 | /* CASL */ | |
6d0f6bcf | 70 | if (CONFIG_SYS_SDRAM_CASL < 2) |
cf48eb9a WD |
71 | sdtr1 |= (1 << SDRAM0_TR_CASL); |
72 | else | |
6d0f6bcf | 73 | if (CONFIG_SYS_SDRAM_CASL > 4) |
cf48eb9a WD |
74 | sdtr1 |= (3 << SDRAM0_TR_CASL); |
75 | else | |
6d0f6bcf | 76 | sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL); |
cf48eb9a WD |
77 | |
78 | /* PTA */ | |
6d0f6bcf | 79 | tmp = ns2clks(CONFIG_SYS_SDRAM_PTA); |
cf48eb9a WD |
80 | if ((tmp >= 2) && (tmp <= 4)) |
81 | sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA); | |
82 | else | |
83 | sdtr1 |= ((4-1) << SDRAM0_TR_PTA); | |
84 | ||
85 | /* CTP */ | |
6d0f6bcf | 86 | tmp = ns2clks(CONFIG_SYS_SDRAM_CTP); |
cf48eb9a WD |
87 | if ((tmp >= 2) && (tmp <= 4)) |
88 | sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP); | |
89 | else | |
90 | sdtr1 |= ((4-1) << SDRAM0_TR_CTP); | |
91 | ||
92 | /* LDF */ | |
6d0f6bcf | 93 | tmp = ns2clks(CONFIG_SYS_SDRAM_LDF); |
cf48eb9a WD |
94 | if ((tmp >= 2) && (tmp <= 4)) |
95 | sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF); | |
96 | else | |
97 | sdtr1 |= ((2-1) << SDRAM0_TR_LDF); | |
98 | ||
99 | /* RFTA */ | |
6d0f6bcf | 100 | tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA); |
cf48eb9a WD |
101 | if ((tmp >= 4) && (tmp <= 10)) |
102 | sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA); | |
103 | else | |
104 | sdtr1 |= ((10-4) << SDRAM0_TR_RFTA); | |
105 | ||
106 | /* RCD */ | |
6d0f6bcf | 107 | tmp = ns2clks(CONFIG_SYS_SDRAM_RCD); |
cf48eb9a WD |
108 | if ((tmp >= 2) && (tmp <= 4)) |
109 | sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD); | |
110 | else | |
111 | sdtr1 |= ((4-1) << SDRAM0_TR_RCD); | |
112 | ||
113 | return sdtr1; | |
6d0f6bcf | 114 | #else /* CONFIG_SYS_SDRAM_CASL */ |
cf48eb9a WD |
115 | /* |
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 | } | |
6d0f6bcf | 136 | #endif /* CONFIG_SYS_SDRAM_CASL */ |
62534beb SR |
137 | } |
138 | ||
139 | /* refresh is expressed in ms */ | |
140 | static ulong compute_rtr(ulong speed, ulong rows, ulong refresh) | |
141 | { | |
6d0f6bcf | 142 | #ifdef CONFIG_SYS_SDRAM_CASL |
cf48eb9a | 143 | ulong tmp; |
62534beb | 144 | |
cf48eb9a WD |
145 | tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000); |
146 | tmp /= 1000000; | |
62534beb | 147 | |
cf48eb9a | 148 | return ((tmp & 0x00003FF8) << 16); |
6d0f6bcf | 149 | #else /* CONFIG_SYS_SDRAM_CASL */ |
cf48eb9a WD |
150 | if (speed > 100000000) { |
151 | /* | |
152 | * 133 MHz SDRAM | |
153 | */ | |
62534beb | 154 | return 0x07f00000; |
cf48eb9a WD |
155 | } else { |
156 | /* | |
157 | * default: 100 MHz SDRAM | |
158 | */ | |
62534beb | 159 | return 0x05f00000; |
cf48eb9a | 160 | } |
6d0f6bcf | 161 | #endif /* CONFIG_SYS_SDRAM_CASL */ |
62534beb SR |
162 | } |
163 | ||
5568e613 SR |
164 | /* |
165 | * Autodetect onboard SDRAM on 405 platforms | |
166 | */ | |
9973e3c6 | 167 | phys_size_t initdram(int board_type) |
c609719b | 168 | { |
62534beb | 169 | ulong speed; |
c609719b | 170 | ulong sdtr1; |
de8d5a36 | 171 | int i; |
c609719b | 172 | |
cf48eb9a WD |
173 | /* |
174 | * Determine SDRAM speed | |
175 | */ | |
176 | speed = get_bus_freq(0); /* parameter not used on ppc4xx */ | |
62534beb | 177 | |
cf48eb9a WD |
178 | /* |
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); | |
c609719b | 186 | |
de8d5a36 | 187 | for (i=0; i<N_MB0CF; i++) { |
6177445d | 188 | /* |
de8d5a36 | 189 | * Disable memory controller. |
6177445d | 190 | */ |
95b602ba | 191 | mtsdram(SDRAM0_CFG, 0x00000000); |
e5ad56b1 | 192 | |
c609719b | 193 | /* |
de8d5a36 | 194 | * Set MB0CF for bank 0. |
c609719b | 195 | */ |
95b602ba SR |
196 | mtsdram(SDRAM0_B0CR, mb0cf[i].reg); |
197 | mtsdram(SDRAM0_TR, sdtr1); | |
198 | mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64)); | |
e5ad56b1 | 199 | |
de8d5a36 | 200 | udelay(200); |
c609719b | 201 | |
c609719b | 202 | /* |
de8d5a36 SR |
203 | * 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. | |
c609719b | 206 | */ |
95b602ba | 207 | mtsdram(SDRAM0_CFG, 0x80800000); |
c609719b | 208 | |
de8d5a36 | 209 | udelay(10000); |
c609719b | 210 | |
de8d5a36 | 211 | if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) { |
7bf5ecfa SR |
212 | phys_size_t size = mb0cf[i].size; |
213 | ||
de8d5a36 | 214 | /* |
d4024bb7 JO |
215 | * OK, size detected. Enable second bank if |
216 | * defined (assumes same type as bank 0) | |
de8d5a36 | 217 | */ |
d4024bb7 | 218 | #ifdef CONFIG_SDRAM_BANK1 |
95b602ba SR |
219 | mtsdram(SDRAM0_CFG, 0x00000000); |
220 | mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg); | |
221 | mtsdram(SDRAM0_CFG, 0x80800000); | |
d4024bb7 | 222 | udelay(10000); |
779e9751 SR |
223 | |
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) { | |
95b602ba SR |
231 | mtsdram(SDRAM0_B1CR, 0); |
232 | mtsdram(SDRAM0_CFG, 0); | |
7bf5ecfa SR |
233 | } else { |
234 | /* | |
235 | * We have two identical banks, so the size | |
236 | * is twice the bank size | |
237 | */ | |
238 | size = 2 * size; | |
779e9751 | 239 | } |
d4024bb7 | 240 | #endif |
bbeff30c SR |
241 | |
242 | /* | |
243 | * OK, size detected -> all done | |
244 | */ | |
7bf5ecfa | 245 | return size; |
de8d5a36 | 246 | } |
6177445d | 247 | } |
bbeff30c SR |
248 | |
249 | return 0; | |
c609719b WD |
250 | } |
251 | ||
5568e613 SR |
252 | #else /* CONFIG_440 */ |
253 | ||
5fb692ca SR |
254 | /* |
255 | * Define some default values. Those can be overwritten in the | |
256 | * board config file. | |
257 | */ | |
258 | ||
6d0f6bcf | 259 | #ifndef CONFIG_SYS_SDRAM_TABLE |
5fb692ca SR |
260 | sdram_conf_t mb0cf[] = { |
261 | {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */ | |
3943d2ff | 262 | {(128 << 20), 13, 0x000A4001}, /* 128MB mode 3, 13x10(4) */ |
5fb692ca SR |
263 | {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */ |
264 | }; | |
265 | #else | |
6d0f6bcf | 266 | sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE; |
5fb692ca SR |
267 | #endif |
268 | ||
6d0f6bcf JCPV |
269 | #ifndef CONFIG_SYS_SDRAM0_TR0 |
270 | #define CONFIG_SYS_SDRAM0_TR0 0x41094012 | |
5fb692ca SR |
271 | #endif |
272 | ||
3943d2ff DE |
273 | #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 | ||
5fb692ca SR |
285 | #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) |
286 | ||
62534beb SR |
287 | #define NUM_TRIES 64 |
288 | #define NUM_READS 10 | |
289 | ||
290 | static 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 */ | |
95b602ba | 318 | mtsdram(SDRAM0_TR1, (0x80800800 | i)); |
62534beb SR |
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 | ||
5568e613 SR |
361 | /* |
362 | * Autodetect onboard DDR SDRAM on 440 platforms | |
363 | * | |
364 | * NOTE: Some of the hardcoded values are hardware dependant, | |
cf48eb9a WD |
365 | * so this should be extended for other future boards |
366 | * using this routine! | |
5568e613 | 367 | */ |
9973e3c6 | 368 | phys_size_t initdram(int board_type) |
5568e613 SR |
369 | { |
370 | int i; | |
62534beb | 371 | int tr1_bank1; |
5568e613 | 372 | |
5fb692ca SR |
373 | #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ |
374 | defined(CONFIG_440GR) || defined(CONFIG_440SP) | |
899620c2 SR |
375 | /* |
376 | * Soft-reset SDRAM controller. | |
377 | */ | |
d1c3b275 SR |
378 | mtsdr(SDR0_SRST, SDR0_SRST_DMC); |
379 | mtsdr(SDR0_SRST, 0x00000000); | |
899620c2 SR |
380 | #endif |
381 | ||
5568e613 SR |
382 | for (i=0; i<N_MB0CF; i++) { |
383 | /* | |
384 | * Disable memory controller. | |
385 | */ | |
95b602ba | 386 | mtsdram(SDRAM0_CFG0, 0x00000000); |
5568e613 SR |
387 | |
388 | /* | |
389 | * Setup some default | |
390 | */ | |
95b602ba SR |
391 | mtsdram(SDRAM0_UABBA, 0x00000000); /* ubba=0 (default) */ |
392 | mtsdram(SDRAM0_SLIO, 0x00000000); /* rdre=0 wrre=0 rarw=0 */ | |
393 | mtsdram(SDRAM0_DEVOPT, 0x00000000); /* dll=0 ds=0 (normal) */ | |
394 | mtsdram(SDRAM0_WDDCTR, CONFIG_SYS_SDRAM0_WDDCTR); | |
395 | mtsdram(SDRAM0_CLKTR, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */ | |
5568e613 SR |
396 | |
397 | /* | |
398 | * Following for CAS Latency = 2.5 @ 133 MHz PLB | |
399 | */ | |
95b602ba SR |
400 | mtsdram(SDRAM0_B0CR, mb0cf[i].reg); |
401 | mtsdram(SDRAM0_TR0, CONFIG_SYS_SDRAM0_TR0); | |
402 | mtsdram(SDRAM0_TR1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/ | |
403 | mtsdram(SDRAM0_RTR, CONFIG_SYS_SDRAM0_RTR); | |
404 | mtsdram(SDRAM0_CFG1, 0x00000000); /* Self-refresh exit, disable PM*/ | |
5568e613 SR |
405 | udelay(400); /* Delay 200 usecs (min) */ |
406 | ||
407 | /* | |
408 | * Enable the controller, then wait for DCEN to complete | |
409 | */ | |
95b602ba | 410 | mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0); |
5568e613 SR |
411 | udelay(10000); |
412 | ||
413 | if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) { | |
3943d2ff | 414 | phys_size_t size = mb0cf[i].size; |
62534beb SR |
415 | /* |
416 | * Optimize TR1 to current hardware environment | |
417 | */ | |
418 | sdram_tr1_set(0x00000000, &tr1_bank1); | |
95b602ba | 419 | mtsdram(SDRAM0_TR1, (tr1_bank1 | 0x80800800)); |
62534beb | 420 | |
3943d2ff DE |
421 | |
422 | /* | |
423 | * OK, size detected. Enable second bank if | |
424 | * defined (assumes same type as bank 0) | |
425 | */ | |
426 | #ifdef CONFIG_SDRAM_BANK1 | |
95b602ba SR |
427 | mtsdram(SDRAM0_CFG0, 0); |
428 | mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg); | |
429 | mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0); | |
3943d2ff DE |
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) { | |
95b602ba SR |
439 | mtsdram(SDRAM0_CFG0, 0); |
440 | mtsdram(SDRAM0_B1CR, 0); | |
441 | mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0); | |
3943d2ff DE |
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 | ||
62534beb | 452 | #ifdef CONFIG_SDRAM_ECC |
3943d2ff | 453 | ecc_init(0, size); |
62534beb SR |
454 | #endif |
455 | ||
5568e613 SR |
456 | /* |
457 | * OK, size detected -> all done | |
458 | */ | |
3943d2ff | 459 | return size; |
5568e613 SR |
460 | } |
461 | } | |
462 | ||
463 | return 0; /* nothing found ! */ | |
464 | } | |
465 | ||
466 | #endif /* CONFIG_440 */ | |
467 | ||
c609719b | 468 | #endif /* CONFIG_SDRAM_BANK0 */ |