1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <common.h>
15#include <asm/ppc4xx.h>
16#include <asm/processor.h>
17#include "sdram.h"
18#include "ecc.h"
19
20#ifdef CONFIG_SDRAM_BANK0
21
22#ifndef CONFIG_440
23
24#ifndef CONFIG_SYS_SDRAM_TABLE
25sdram_conf_t mb0cf[] = {
26 {(128 << 20), 13, 0x000A4001},
27 {(64 << 20), 13, 0x00084001},
28 {(32 << 20), 12, 0x00062001},
29 {(16 << 20), 12, 0x00046001},
30 {(4 << 20), 11, 0x00008001},
31};
32#else
33sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
34#endif
35
36#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
37
38#ifdef CONFIG_SYS_SDRAM_CASL
39static 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}
45#endif
46
47static ulong compute_sdtr1(ulong speed)
48{
49#ifdef CONFIG_SYS_SDRAM_CASL
50 ulong tmp;
51 ulong sdtr1 = 0;
52
53
54 if (CONFIG_SYS_SDRAM_CASL < 2)
55 sdtr1 |= (1 << SDRAM0_TR_CASL);
56 else
57 if (CONFIG_SYS_SDRAM_CASL > 4)
58 sdtr1 |= (3 << SDRAM0_TR_CASL);
59 else
60 sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL);
61
62
63 tmp = ns2clks(CONFIG_SYS_SDRAM_PTA);
64 if ((tmp >= 2) && (tmp <= 4))
65 sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
66 else
67 sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
68
69
70 tmp = ns2clks(CONFIG_SYS_SDRAM_CTP);
71 if ((tmp >= 2) && (tmp <= 4))
72 sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
73 else
74 sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
75
76
77 tmp = ns2clks(CONFIG_SYS_SDRAM_LDF);
78 if ((tmp >= 2) && (tmp <= 4))
79 sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
80 else
81 sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
82
83
84 tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA);
85 if ((tmp >= 4) && (tmp <= 10))
86 sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
87 else
88 sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
89
90
91 tmp = ns2clks(CONFIG_SYS_SDRAM_RCD);
92 if ((tmp >= 2) && (tmp <= 4))
93 sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
94 else
95 sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
96
97 return sdtr1;
98#else
99
100
101
102
103
104
105
106
107
108
109 if (speed > 100000000) {
110
111
112
113 return 0x01074015;
114 } else {
115
116
117
118 return 0x0086400d;
119 }
120#endif
121}
122
123
124static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
125{
126#ifdef CONFIG_SYS_SDRAM_CASL
127 ulong tmp;
128
129 tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
130 tmp /= 1000000;
131
132 return ((tmp & 0x00003FF8) << 16);
133#else
134 if (speed > 100000000) {
135
136
137
138 return 0x07f00000;
139 } else {
140
141
142
143 return 0x05f00000;
144 }
145#endif
146}
147
148
149
150
151phys_size_t initdram(int board_type)
152{
153 ulong speed;
154 ulong sdtr1;
155 int i;
156
157
158
159
160 speed = get_bus_freq(0);
161
162
163
164
165
166
167
168
169 sdtr1 = compute_sdtr1(speed);
170
171 for (i=0; i<N_MB0CF; i++) {
172
173
174
175 mtsdram(SDRAM0_CFG, 0x00000000);
176
177
178
179
180 mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
181 mtsdram(SDRAM0_TR, sdtr1);
182 mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64));
183
184 udelay(200);
185
186
187
188
189
190
191 mtsdram(SDRAM0_CFG, 0x80800000);
192
193 udelay(10000);
194
195 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
196 phys_size_t size = mb0cf[i].size;
197
198
199
200
201
202#ifdef CONFIG_SDRAM_BANK1
203 mtsdram(SDRAM0_CFG, 0x00000000);
204 mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
205 mtsdram(SDRAM0_CFG, 0x80800000);
206 udelay(10000);
207
208
209
210
211
212
213 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
214 mb0cf[i].size) {
215 mtsdram(SDRAM0_B1CR, 0);
216 mtsdram(SDRAM0_CFG, 0);
217 } else {
218
219
220
221
222 size = 2 * size;
223 }
224#endif
225
226
227
228
229 return size;
230 }
231 }
232
233 return 0;
234}
235
236#else
237
238
239
240
241
242
243#ifndef CONFIG_SYS_SDRAM_TABLE
244sdram_conf_t mb0cf[] = {
245 {(256 << 20), 13, 0x000C4001},
246 {(128 << 20), 13, 0x000A4001},
247 {(64 << 20), 12, 0x00082001}
248};
249#else
250sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
251#endif
252
253#ifndef CONFIG_SYS_SDRAM0_TR0
254#define CONFIG_SYS_SDRAM0_TR0 0x41094012
255#endif
256
257#ifndef CONFIG_SYS_SDRAM0_WDDCTR
258#define CONFIG_SYS_SDRAM0_WDDCTR 0x00000000
259#endif
260
261#ifndef CONFIG_SYS_SDRAM0_RTR
262#define CONFIG_SYS_SDRAM0_RTR 0x04100000
263#endif
264
265#ifndef CONFIG_SYS_SDRAM0_CFG0
266#define CONFIG_SYS_SDRAM0_CFG0 0x82000000
267#endif
268
269#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
270
271#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
300 for (i=0; i<=0x1ff; i++) {
301
302 mtsdram(SDRAM0_TR1, (0x80800800 | i));
303
304
305 for (j=0; j<NUM_TRIES; j++) {
306 ram_pointer[j] = test[j];
307
308
309 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
310 }
311
312
313 for (j=0; j<NUM_TRIES; j++) {
314 for (k=0; k<NUM_READS; k++) {
315
316 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
317
318 if (ram_pointer[j] != test[j])
319 break;
320 }
321
322
323 if (k != NUM_READS)
324 break;
325 }
326
327
328 if (j == NUM_TRIES) {
329 if (first_good == -1)
330 first_good = i;
331 } else {
332
333 if (first_good != -1) {
334
335 last_bad = i-1;
336 break;
337 }
338 }
339 }
340
341
342 *tr1_value = (first_good + last_bad) / 2;
343}
344
345
346
347
348
349
350
351
352phys_size_t initdram(int board_type)
353{
354 int i;
355 int tr1_bank1;
356
357#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
358 defined(CONFIG_440GR) || defined(CONFIG_440SP)
359
360
361
362 mtsdr(SDR0_SRST, SDR0_SRST_DMC);
363 mtsdr(SDR0_SRST, 0x00000000);
364#endif
365
366 for (i=0; i<N_MB0CF; i++) {
367
368
369
370 mtsdram(SDRAM0_CFG0, 0x00000000);
371
372
373
374
375 mtsdram(SDRAM0_UABBA, 0x00000000);
376 mtsdram(SDRAM0_SLIO, 0x00000000);
377 mtsdram(SDRAM0_DEVOPT, 0x00000000);
378 mtsdram(SDRAM0_WDDCTR, CONFIG_SYS_SDRAM0_WDDCTR);
379 mtsdram(SDRAM0_CLKTR, 0x40000000);
380
381
382
383
384 mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
385 mtsdram(SDRAM0_TR0, CONFIG_SYS_SDRAM0_TR0);
386 mtsdram(SDRAM0_TR1, 0x80800800);
387 mtsdram(SDRAM0_RTR, CONFIG_SYS_SDRAM0_RTR);
388 mtsdram(SDRAM0_CFG1, 0x00000000);
389 udelay(400);
390
391
392
393
394 mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
395 udelay(10000);
396
397 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
398 phys_size_t size = mb0cf[i].size;
399
400
401
402 sdram_tr1_set(0x00000000, &tr1_bank1);
403 mtsdram(SDRAM0_TR1, (tr1_bank1 | 0x80800800));
404
405
406
407
408
409
410#ifdef CONFIG_SDRAM_BANK1
411 mtsdram(SDRAM0_CFG0, 0);
412 mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
413 mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
414 udelay(10000);
415
416
417
418
419
420
421 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size)
422 != mb0cf[i].size) {
423 mtsdram(SDRAM0_CFG0, 0);
424 mtsdram(SDRAM0_B1CR, 0);
425 mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
426 udelay(10000);
427 } else {
428
429
430
431
432 size = 2 * size;
433 }
434#endif
435
436#ifdef CONFIG_SDRAM_ECC
437 ecc_init(0, size);
438#endif
439
440
441
442
443 return size;
444 }
445 }
446
447 return 0;
448}
449
450#endif
451
452#endif
453