]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/ppc4xx/sdram.c
Coding Style cleanup: remove trailing white space
[karo-tx-uboot.git] / arch / powerpc / 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  * SPDX-License-Identifier:     GPL-2.0+
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
25 sdram_conf_t mb0cf[] = {
26         {(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)    */
31 };
32 #else
33 sdram_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
39 static 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 /* CONFIG_SYS_SDRAM_CASL */
46
47 static ulong compute_sdtr1(ulong speed)
48 {
49 #ifdef CONFIG_SYS_SDRAM_CASL
50         ulong tmp;
51         ulong sdtr1 = 0;
52
53         /* CASL */
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         /* PTA */
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         /* CTP */
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         /* LDF */
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         /* RFTA */
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         /* RCD */
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 /* CONFIG_SYS_SDRAM_CASL */
99         /*
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         }
120 #endif /* CONFIG_SYS_SDRAM_CASL */
121 }
122
123 /* refresh is expressed in ms */
124 static 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 /* CONFIG_SYS_SDRAM_CASL */
134         if (speed > 100000000) {
135                 /*
136                  * 133 MHz SDRAM
137                  */
138                 return 0x07f00000;
139         } else {
140                 /*
141                  * default: 100 MHz SDRAM
142                  */
143                 return 0x05f00000;
144         }
145 #endif /* CONFIG_SYS_SDRAM_CASL */
146 }
147
148 /*
149  * Autodetect onboard SDRAM on 405 platforms
150  */
151 phys_size_t initdram(int board_type)
152 {
153         ulong speed;
154         ulong sdtr1;
155         int i;
156
157         /*
158          * Determine SDRAM speed
159          */
160         speed = get_bus_freq(0); /* parameter not used on ppc4xx */
161
162         /*
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);
170
171         for (i=0; i<N_MB0CF; i++) {
172                 /*
173                  * Disable memory controller.
174                  */
175                 mtsdram(SDRAM0_CFG, 0x00000000);
176
177                 /*
178                  * Set MB0CF for bank 0.
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                  * 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.
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                          * OK, size detected.  Enable second bank if
200                          * defined (assumes same type as bank 0)
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                          * 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) {
215                                 mtsdram(SDRAM0_B1CR, 0);
216                                 mtsdram(SDRAM0_CFG, 0);
217                         } else {
218                                 /*
219                                  * We have two identical banks, so the size
220                                  * is twice the bank size
221                                  */
222                                 size = 2 * size;
223                         }
224 #endif
225
226                         /*
227                          * OK, size detected -> all done
228                          */
229                         return size;
230                 }
231         }
232
233         return 0;
234 }
235
236 #else /* CONFIG_440 */
237
238 /*
239  * Define some default values. Those can be overwritten in the
240  * board config file.
241  */
242
243 #ifndef CONFIG_SYS_SDRAM_TABLE
244 sdram_conf_t mb0cf[] = {
245         {(256 << 20), 13, 0x000C4001},  /* 256MB mode 3, 13x10(4)       */
246         {(128 << 20), 13, 0x000A4001},  /* 128MB mode 3, 13x10(4)       */
247         {(64 << 20),  12, 0x00082001}   /* 64MB mode 2, 12x9(4)         */
248 };
249 #else
250 sdram_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  /* 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
269 #define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
270
271 #define NUM_TRIES 64
272 #define NUM_READS 10
273
274 static 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 */
302                 mtsdram(SDRAM0_TR1, (0x80800800 | i));
303
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
345 /*
346  * Autodetect onboard DDR SDRAM on 440 platforms
347  *
348  * NOTE: Some of the hardcoded values are hardware dependant,
349  *       so this should be extended for other future boards
350  *       using this routine!
351  */
352 phys_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          * Soft-reset SDRAM controller.
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                  * Disable memory controller.
369                  */
370                 mtsdram(SDRAM0_CFG0, 0x00000000);
371
372                 /*
373                  * Setup some default
374                  */
375                 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 */
380
381                 /*
382                  * Following for CAS Latency = 2.5 @ 133 MHz PLB
383                  */
384                 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*/
389                 udelay(400);                    /* Delay 200 usecs (min)        */
390
391                 /*
392                  * Enable the controller, then wait for DCEN to complete
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                          * Optimize TR1 to current hardware environment
401                          */
402                         sdram_tr1_set(0x00000000, &tr1_bank1);
403                         mtsdram(SDRAM0_TR1, (tr1_bank1 | 0x80800800));
404
405
406                         /*
407                          * OK, size detected.  Enable second bank if
408                          * defined (assumes same type as bank 0)
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                          * 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) {
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                                  * We have two identical banks, so the size
430                                  * is twice the bank size
431                                  */
432                                 size = 2 * size;
433                         }
434 #endif
435
436 #ifdef CONFIG_SDRAM_ECC
437                         ecc_init(0, size);
438 #endif
439
440                         /*
441                          * OK, size detected -> all done
442                          */
443                         return size;
444                 }
445         }
446
447         return 0;                               /* nothing found !              */
448 }
449
450 #endif /* CONFIG_440 */
451
452 #endif /* CONFIG_SDRAM_BANK0 */