]> git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/ppc4xx/sdram.c
Merge with git://www.denx.de/git/u-boot.git
[people/ms/u-boot.git] / cpu / ppc4xx / sdram.c
1 /*
2 * (C) Copyright 2005-2007
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
4 *
5 * (C) Copyright 2006
6 * DAVE Srl <www.dave-tech.it>
7 *
8 * (C) Copyright 2002-2004
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
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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>
33 #include "sdram.h"
34
35 #ifdef CONFIG_SDRAM_BANK0
36
37 #ifndef CONFIG_440
38
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) */
46 };
47 #else
48 sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE;
49 #endif
50
51 #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
52
53 #ifdef CFG_SDRAM_CASL
54 static ulong ns2clks(ulong ns)
55 {
56 ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
57
58 return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
59 }
60 #endif /* CFG_SDRAM_CASL */
61
62 static ulong compute_sdtr1(ulong speed)
63 {
64 #ifdef CFG_SDRAM_CASL
65 ulong tmp;
66 ulong sdtr1 = 0;
67
68 /* CASL */
69 if (CFG_SDRAM_CASL < 2)
70 sdtr1 |= (1 << SDRAM0_TR_CASL);
71 else
72 if (CFG_SDRAM_CASL > 4)
73 sdtr1 |= (3 << SDRAM0_TR_CASL);
74 else
75 sdtr1 |= ((CFG_SDRAM_CASL-1) << SDRAM0_TR_CASL);
76
77 /* PTA */
78 tmp = ns2clks(CFG_SDRAM_PTA);
79 if ((tmp >= 2) && (tmp <= 4))
80 sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
81 else
82 sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
83
84 /* CTP */
85 tmp = ns2clks(CFG_SDRAM_CTP);
86 if ((tmp >= 2) && (tmp <= 4))
87 sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
88 else
89 sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
90
91 /* LDF */
92 tmp = ns2clks(CFG_SDRAM_LDF);
93 if ((tmp >= 2) && (tmp <= 4))
94 sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
95 else
96 sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
97
98 /* RFTA */
99 tmp = ns2clks(CFG_SDRAM_RFTA);
100 if ((tmp >= 4) && (tmp <= 10))
101 sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
102 else
103 sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
104
105 /* RCD */
106 tmp = ns2clks(CFG_SDRAM_RCD);
107 if ((tmp >= 2) && (tmp <= 4))
108 sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
109 else
110 sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
111
112 return sdtr1;
113 #else /* CFG_SDRAM_CASL */
114 /*
115 * If no values are configured in the board config file
116 * use the default values, which seem to be ok for most
117 * boards.
118 *
119 * REMARK:
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)
123 */
124 if (speed > 100000000) {
125 /*
126 * 133 MHz SDRAM
127 */
128 return 0x01074015;
129 } else {
130 /*
131 * default: 100 MHz SDRAM
132 */
133 return 0x0086400d;
134 }
135 #endif /* CFG_SDRAM_CASL */
136 }
137
138 /* refresh is expressed in ms */
139 static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
140 {
141 #ifdef CFG_SDRAM_CASL
142 ulong tmp;
143
144 tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
145 tmp /= 1000000;
146
147 return ((tmp & 0x00003FF8) << 16);
148 #else /* CFG_SDRAM_CASL */
149 if (speed > 100000000) {
150 /*
151 * 133 MHz SDRAM
152 */
153 return 0x07f00000;
154 } else {
155 /*
156 * default: 100 MHz SDRAM
157 */
158 return 0x05f00000;
159 }
160 #endif /* CFG_SDRAM_CASL */
161 }
162
163 /*
164 * Autodetect onboard SDRAM on 405 platforms
165 */
166 void sdram_init(void)
167 {
168 ulong speed;
169 ulong sdtr1;
170 int i;
171
172 /*
173 * Determine SDRAM speed
174 */
175 speed = get_bus_freq(0); /* parameter not used on ppc4xx */
176
177 /*
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.
183 */
184 sdtr1 = compute_sdtr1(speed);
185
186 for (i=0; i<N_MB0CF; i++) {
187 /*
188 * Disable memory controller.
189 */
190 mtsdram(mem_mcopt1, 0x00000000);
191
192 /*
193 * Set MB0CF for bank 0.
194 */
195 mtsdram(mem_mb0cf, mb0cf[i].reg);
196 mtsdram(mem_sdtr1, sdtr1);
197 mtsdram(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64));
198
199 udelay(200);
200
201 /*
202 * Set memory controller options reg, MCOPT1.
203 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
204 * read/prefetch.
205 */
206 mtsdram(mem_mcopt1, 0x80800000);
207
208 udelay(10000);
209
210 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
211 /*
212 * OK, size detected. Enable second bank if
213 * defined (assumes same type as bank 0)
214 */
215 #ifdef CONFIG_SDRAM_BANK1
216 u32 b1cr = mb0cf[i].size | mb0cf[i].reg;
217
218 mtsdram(mem_mcopt1, 0x00000000);
219 mtsdram(mem_mb1cf, b1cr); /* SDRAM0_B1CR */
220 mtsdram(mem_mcopt1, 0x80800000);
221 udelay(10000);
222
223 /*
224 * Check if 2nd bank is really available.
225 * If the size not equal to the size of the first
226 * bank, then disable the 2nd bank completely.
227 */
228 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
229 mb0cf[i].size) {
230 mtsdram(mem_mb1cf, 0);
231 mtsdram(mem_mcopt1, 0);
232 }
233 #endif
234 return;
235 }
236 }
237 }
238
239 #else /* CONFIG_440 */
240
241 /*
242 * Define some default values. Those can be overwritten in the
243 * board config file.
244 */
245
246 #ifndef CFG_SDRAM_TABLE
247 sdram_conf_t mb0cf[] = {
248 {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
249 {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
250 };
251 #else
252 sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE;
253 #endif
254
255 #ifndef CFG_SDRAM0_TR0
256 #define CFG_SDRAM0_TR0 0x41094012
257 #endif
258
259 #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
260
261 #define NUM_TRIES 64
262 #define NUM_READS 10
263
264 static void sdram_tr1_set(int ram_address, int* tr1_value)
265 {
266 int i;
267 int j, k;
268 volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
269 int first_good = -1, last_bad = 0x1ff;
270
271 unsigned long test[NUM_TRIES] = {
272 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
273 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
274 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
275 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
276 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
277 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
278 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
279 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
280 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
281 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
282 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
283 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
284 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
285 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
286 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
287 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
288
289 /* go through all possible SDRAM0_TR1[RDCT] values */
290 for (i=0; i<=0x1ff; i++) {
291 /* set the current value for TR1 */
292 mtsdram(mem_tr1, (0x80800800 | i));
293
294 /* write values */
295 for (j=0; j<NUM_TRIES; j++) {
296 ram_pointer[j] = test[j];
297
298 /* clear any cache at ram location */
299 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
300 }
301
302 /* read values back */
303 for (j=0; j<NUM_TRIES; j++) {
304 for (k=0; k<NUM_READS; k++) {
305 /* clear any cache at ram location */
306 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
307
308 if (ram_pointer[j] != test[j])
309 break;
310 }
311
312 /* read error */
313 if (k != NUM_READS)
314 break;
315 }
316
317 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
318 if (j == NUM_TRIES) {
319 if (first_good == -1)
320 first_good = i; /* found beginning of window */
321 } else { /* bad read */
322 /* if we have not had a good read then don't care */
323 if (first_good != -1) {
324 /* first failure after a good read */
325 last_bad = i-1;
326 break;
327 }
328 }
329 }
330
331 /* return the current value for TR1 */
332 *tr1_value = (first_good + last_bad) / 2;
333 }
334
335 #ifdef CONFIG_SDRAM_ECC
336 static void ecc_init(ulong start, ulong size)
337 {
338 ulong current_addr; /* current byte address */
339 ulong end_addr; /* end of memory region */
340 ulong addr_inc; /* address skip between writes */
341 ulong cfg0_reg; /* for restoring ECC state */
342
343 /*
344 * TODO: Enable dcache before running this test (speedup)
345 */
346
347 mfsdram(mem_cfg0, cfg0_reg);
348 mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_GEN);
349
350 /*
351 * look at geometry of SDRAM (data width) to determine whether we
352 * can skip words when writing
353 */
354 if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32)
355 addr_inc = 4;
356 else
357 addr_inc = 8;
358
359 current_addr = start;
360 end_addr = start + size;
361
362 while (current_addr < end_addr) {
363 *((ulong *)current_addr) = 0x00000000;
364 current_addr += addr_inc;
365 }
366
367 /*
368 * TODO: Flush dcache and disable it again
369 */
370
371 /*
372 * Enable ecc checking and parity errors
373 */
374 mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_CHK);
375 }
376 #endif
377
378 /*
379 * Autodetect onboard DDR SDRAM on 440 platforms
380 *
381 * NOTE: Some of the hardcoded values are hardware dependant,
382 * so this should be extended for other future boards
383 * using this routine!
384 */
385 long int initdram(int board_type)
386 {
387 int i;
388 int tr1_bank1;
389
390 #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
391 defined(CONFIG_440GR) || defined(CONFIG_440SP)
392 /*
393 * Soft-reset SDRAM controller.
394 */
395 mtsdr(sdr_srst, SDR0_SRST_DMC);
396 mtsdr(sdr_srst, 0x00000000);
397 #endif
398
399 for (i=0; i<N_MB0CF; i++) {
400 /*
401 * Disable memory controller.
402 */
403 mtsdram(mem_cfg0, 0x00000000);
404
405 /*
406 * Setup some default
407 */
408 mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
409 mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
410 mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
411 mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
412 mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
413
414 /*
415 * Following for CAS Latency = 2.5 @ 133 MHz PLB
416 */
417 mtsdram(mem_b0cr, mb0cf[i].reg);
418 mtsdram(mem_tr0, CFG_SDRAM0_TR0);
419 mtsdram(mem_tr1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
420 mtsdram(mem_rtr, 0x04100000); /* Interval 7.8µs @ 133MHz PLB */
421 mtsdram(mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM*/
422 udelay(400); /* Delay 200 usecs (min) */
423
424 /*
425 * Enable the controller, then wait for DCEN to complete
426 */
427 mtsdram(mem_cfg0, 0x82000000); /* DCEN=1, PMUD=0, 64-bit */
428 udelay(10000);
429
430 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
431 /*
432 * Optimize TR1 to current hardware environment
433 */
434 sdram_tr1_set(0x00000000, &tr1_bank1);
435 mtsdram(mem_tr1, (tr1_bank1 | 0x80800800));
436
437 #ifdef CONFIG_SDRAM_ECC
438 ecc_init(0, mb0cf[i].size);
439 #endif
440
441 /*
442 * OK, size detected -> all done
443 */
444 return mb0cf[i].size;
445 }
446 }
447
448 return 0; /* nothing found ! */
449 }
450
451 #endif /* CONFIG_440 */
452
453 #endif /* CONFIG_SDRAM_BANK0 */