]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc83xx/spd_sdram.c
Add support for ECC DDR initialization on MPC83xx.
[karo-tx-uboot.git] / cpu / mpc83xx / spd_sdram.c
1 /*
2  * Copyright 2004 Freescale Semiconductor.
3  * (C) Copyright 2003 Motorola Inc.
4  * Xianghua Xiao (X.Xiao@motorola.com)
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  *
24  * Change log:
25  *
26  * 20050101: Eran Liberty (liberty@freescale.com)
27  *           Initial file creating (porting from 85XX & 8260)
28  */
29
30 #include <common.h>
31 #include <asm/processor.h>
32 #include <i2c.h>
33 #include <spd.h>
34 #include <asm/mmu.h>
35 #include <spd_sdram.h>
36
37 #ifdef CONFIG_SPD_EEPROM
38
39 #if defined(CONFIG_DDR_ECC)
40 extern void dma_init(void);
41 extern uint dma_check(void);
42 extern int dma_xfer(void *dest, uint count, void *src);
43 #endif
44
45 #ifndef CFG_READ_SPD
46 #define CFG_READ_SPD    i2c_read
47 #endif
48
49 /*
50  * Convert picoseconds into clock cycles (rounding up if needed).
51  */
52
53 int
54 picos_to_clk(int picos)
55 {
56         int clks;
57
58         clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
59         if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
60         clks++;
61         }
62
63         return clks;
64 }
65
66 unsigned int banksize(unsigned char row_dens)
67 {
68         return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
69 }
70
71 int read_spd(uint addr)
72 {
73         return ((int) addr);
74 }
75
76 long int spd_sdram(int(read_spd)(uint addr))
77 {
78         volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
79         volatile ddr8349_t *ddr = &immap->ddr;
80         volatile law8349_t *ecm = &immap->sysconf.ddrlaw[0];
81         spd_eeprom_t spd;
82         unsigned tmp, tmp1;
83         unsigned int memsize;
84         unsigned int law_size;
85         unsigned char caslat;
86         unsigned int trfc, trfc_clk, trfc_low;
87
88 #warning Current spd_sdram does not fit its usage... adjust implementation or API...
89
90         CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
91         
92         if (spd.nrows > 2) {
93                 puts("DDR:Only two chip selects are supported on ADS.\n");
94                 return 0;
95         }
96
97         if (spd.nrow_addr < 12
98             || spd.nrow_addr > 14
99             || spd.ncol_addr < 8
100             || spd.ncol_addr > 11) {
101                 puts("DDR:Row or Col number unsupported.\n");
102                 return 0;
103         }
104
105         ddr->csbnds[2].csbnds = (banksize(spd.row_dens) >> 24) - 1;
106         ddr->cs_config[2] = ( 1 << 31
107                             | (spd.nrow_addr - 12) << 8
108                             | (spd.ncol_addr - 8) );
109         debug("\n");
110         debug("cs2_bnds = 0x%08x\n",ddr->csbnds[2].csbnds);
111         debug("cs2_config = 0x%08x\n",ddr->cs_config[2]);
112
113         if (spd.nrows == 2) {
114                 ddr->csbnds[3].csbnds = ( (banksize(spd.row_dens) >> 8)
115                                   | ((banksize(spd.row_dens) >> 23) - 1) );
116                 ddr->cs_config[3] = ( 1<<31
117                                     | (spd.nrow_addr-12) << 8
118                                     | (spd.ncol_addr-8) );
119                 debug("cs3_bnds = 0x%08x\n",ddr->csbnds[3].csbnds);
120                 debug("cs3_config = 0x%08x\n",ddr->cs_config[3]);
121         }
122
123         if (spd.mem_type != 0x07) {
124                 puts("No DDR module found!\n");
125                 return 0;
126         }
127
128         /*
129          * Figure out memory size in Megabytes.
130          */
131         memsize = spd.nrows * banksize(spd.row_dens) / 0x100000;
132
133         /*
134          * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23.
135          */
136         law_size = 19 + __ilog2(memsize);
137
138         /*
139          * Set up LAWBAR for all of DDR.
140          */
141         ecm->bar = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
142         ecm->ar  = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size));
143         debug("DDR:bar=0x%08x\n", ecm->bar);
144         debug("DDR:ar=0x%08x\n", ecm->ar);
145
146         /*
147          * find the largest CAS
148          */
149         if(spd.cas_lat & 0x40) {
150                 caslat = 7;
151         } else if (spd.cas_lat & 0x20) {
152                 caslat = 6;
153         } else if (spd.cas_lat & 0x10) {
154                 caslat = 5;
155         } else if (spd.cas_lat & 0x08) {
156                 caslat = 4;
157         } else if (spd.cas_lat & 0x04) {
158                 caslat = 3;
159         } else if (spd.cas_lat & 0x02) {
160                 caslat = 2;
161         } else if (spd.cas_lat & 0x01) {
162                 caslat = 1;
163         } else {
164                 puts("DDR:no valid CAS Latency information.\n");
165                 return 0;
166         }
167
168         tmp = 20000 / (((spd.clk_cycle & 0xF0) >> 4) * 10
169                        + (spd.clk_cycle & 0x0f));
170         debug("DDR:Module maximum data rate is: %dMhz\n", tmp);
171
172         tmp1 = get_bus_freq(0) / 1000000;
173         if (tmp1 < 230 && tmp1 >= 90 && tmp >= 230) {
174                 /* 90~230 range, treated as DDR 200 */
175                 if (spd.clk_cycle3 == 0xa0)
176                         caslat -= 2;
177                 else if(spd.clk_cycle2 == 0xa0)
178                         caslat--;
179         } else if (tmp1 < 280 && tmp1 >= 230 && tmp >= 280) {
180                 /* 230-280 range, treated as DDR 266 */
181                 if (spd.clk_cycle3 == 0x75)
182                         caslat -= 2;
183                 else if (spd.clk_cycle2 == 0x75)
184                         caslat--;
185         } else if (tmp1 < 350 && tmp1 >= 280 && tmp >= 350) {
186                 /* 280~350 range, treated as DDR 333 */
187                 if (spd.clk_cycle3 == 0x60)
188                         caslat -= 2;
189                 else if (spd.clk_cycle2 == 0x60)
190                         caslat--;
191         } else if (tmp1 < 90 || tmp1 >= 350) {
192                 /* DDR rate out-of-range */
193                 puts("DDR:platform frequency is not fit for DDR rate\n");
194                 return 0;
195         }
196
197         /*
198          * note: caslat must also be programmed into ddr->sdram_mode
199          * register.
200          *
201          * note: WRREC(Twr) and WRTORD(Twtr) are not in SPD,
202          * use conservative value here.
203          */
204         trfc = spd.trfc * 1000;         /* up to ps */
205         trfc_clk = picos_to_clk(trfc);
206         trfc_low = (trfc_clk - 8) & 0xf;
207
208         ddr->timing_cfg_1 =
209             (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |
210              ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) |
211              ((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) |
212              ((caslat & 0x07) << 16 ) |
213              (trfc_low << 12 ) |
214              ( 0x300 ) |
215              ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1);
216
217         ddr->timing_cfg_2 = 0x00000800;
218
219         debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1);
220         debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
221
222         /*
223          * Only DDR I is supported
224          * DDR I and II have different mode-register-set definition
225          */
226
227         /* burst length is always 4 */
228         switch(caslat) {
229         case 2:
230                 ddr->sdram_mode = 0x52; /* 1.5 */
231                 break;
232         case 3:
233                 ddr->sdram_mode = 0x22; /* 2.0 */
234                 break;
235         case 4:
236                 ddr->sdram_mode = 0x62; /* 2.5 */
237                 break;
238         case 5:
239                 ddr->sdram_mode = 0x32; /* 3.0 */
240                 break;
241         default:
242                 puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n");
243                 return 0;
244         }
245         debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);
246
247         switch(spd.refresh) {
248         case 0x00:
249         case 0x80:
250                 tmp = picos_to_clk(15625000);
251                 break;
252         case 0x01:
253         case 0x81:
254                 tmp = picos_to_clk(3900000);
255                 break;
256         case 0x02:
257         case 0x82:
258                 tmp = picos_to_clk(7800000);
259                 break;
260         case 0x03:
261         case 0x83:
262                 tmp = picos_to_clk(31300000);
263                 break;
264         case 0x04:
265         case 0x84:
266                 tmp = picos_to_clk(62500000);
267                 break;
268         case 0x05:
269         case 0x85:
270                 tmp = picos_to_clk(125000000);
271                 break;
272         default:
273                 tmp = 0x512;
274                 break;
275         }
276
277         /*
278          * Set BSTOPRE to 0x100 for page mode
279          * If auto-charge is used, set BSTOPRE = 0
280          */
281         ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100;
282         debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval);
283
284         /*
285          * Is this an ECC DDR chip?
286          */
287 #if defined(CONFIG_DDR_ECC)
288         if (spd.config == 0x02) {
289                 /* disable error detection */
290                 ddr->err_disable = ~ECC_ERROR_ENABLE;
291
292                 /* set single bit error threshold to maximum value,
293                  * reset counter to zero */
294                 ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) |
295                         (0 << ECC_ERROR_MAN_SBEC_SHIFT);
296         }
297         debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
298         debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
299 #endif
300         asm("sync;isync");
301
302         udelay(500);
303
304         /*
305          * SS_EN=1,
306          * CLK_ADJST = 2-MCK/MCK_B, is lauched 1/2 of one SDRAM
307          * clock cycle after address/command
308          */
309         /*ddr->sdram_clk_cntl = 0x82000000;*/
310         ddr->sdram_clk_cntl = (DDR_SDRAM_CLK_CNTL_SS_EN|DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05);
311
312         /*
313          * Figure out the settings for the sdram_cfg register.  Build up
314          * the entire register in 'tmp' before writing since the write into
315          * the register will actually enable the memory controller, and all
316          * settings must be done before enabling.
317          *
318          * sdram_cfg[0]   = 1 (ddr sdram logic enable)
319          * sdram_cfg[1]   = 1 (self-refresh-enable)
320          * sdram_cfg[6:7] = 2 (SDRAM type = DDR SDRAM)
321          */
322         tmp = 0xc2000000;
323
324         /*
325          * sdram_cfg[3] = RD_EN - registered DIMM enable
326          *   A value of 0x26 indicates micron registered DIMMS (micron.com)
327          */
328         if (spd.mod_attr == 0x26) {
329                 tmp |= 0x10000000;
330         }
331
332 #if defined(CONFIG_DDR_ECC)
333         /*
334          * If the user wanted ECC (enabled via sdram_cfg[2])
335          */
336         if (spd.config == 0x02) {
337                 tmp |= SDRAM_CFG_ECC_EN;
338         }
339 #endif
340
341 #if defined(CONFIG_DDR_2T_TIMING)
342         /*
343          * Enable 2T timing by setting sdram_cfg[16].
344          */
345         tmp |= SDRAM_CFG_2T_EN;
346 #endif
347
348         ddr->sdram_cfg = tmp;
349         asm("sync;isync");
350         udelay(500);
351
352         debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
353
354         return memsize;/*in MBytes*/
355 }
356 #endif /* CONFIG_SPD_EEPROM */
357
358
359 #if defined(CONFIG_DDR_ECC)
360 /*
361  * Use timebase counter, get_timer() is not availabe
362  * at this point of initialization yet.
363  */
364 static __inline__ unsigned long get_tbms (void)
365 {
366         unsigned long tbl;
367         unsigned long tbu1, tbu2;
368         unsigned long ms;
369         unsigned long long tmp;
370
371         ulong tbclk = get_tbclk();
372
373         /* get the timebase ticks */
374         do {
375                 asm volatile ("mftbu %0":"=r" (tbu1):);
376                 asm volatile ("mftb %0":"=r" (tbl):);
377                 asm volatile ("mftbu %0":"=r" (tbu2):);
378         } while (tbu1 != tbu2);
379
380         /* convert ticks to ms */
381         tmp = (unsigned long long)(tbu1);
382         tmp = (tmp << 32);
383         tmp += (unsigned long long)(tbl);
384         ms = tmp/(tbclk/1000);
385
386         return ms;
387 }
388
389 /*
390  * Initialize all of memory for ECC, then enable errors.
391  */
392 //#define CONFIG_DDR_ECC_INIT_VIA_DMA
393 void ddr_enable_ecc(unsigned int dram_size)
394 {
395         uint *p;
396         volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
397         volatile ddr8349_t *ddr = &immap->ddr;
398         unsigned long t_start, t_end;
399 #if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
400         uint i;
401 #endif
402
403         debug("Initialize a Cachline in DRAM\n");
404         icache_enable();
405
406 #if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
407         /* Initialise DMA for direct Transfers */
408         dma_init();
409 #endif
410
411         t_start = get_tbms();
412
413 #if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
414         debug("DDR init: Cache flush method\n");
415         for (p = 0; p < (uint *)(dram_size); p++) {
416                 if (((unsigned int)p & 0x1f) == 0) {
417                         ppcDcbz((unsigned long) p);
418                 }
419
420                 /* write pattern to cache and flush */
421                 *p = (unsigned int)0xdeadbeef;
422
423                 if (((unsigned int)p & 0x1c) == 0x1c) {
424                         ppcDcbf((unsigned long) p);
425                 }
426         }
427 #else
428         printf("DDR init: DMA method\n");
429         for (p = 0; p < (uint *)(8 * 1024); p++) {
430                 /* zero one data cache line */
431                 if (((unsigned int)p & 0x1f) == 0) {
432                         ppcDcbz((unsigned long)p);
433                 }
434
435                 /* write pattern to it and flush */
436                 *p = (unsigned int)0xdeadbeef;
437
438                 if (((unsigned int)p & 0x1c) == 0x1c) {
439                         ppcDcbf((unsigned long)p);
440                 }
441         }
442
443         /* 8K */
444         dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
445         /* 16K */
446         dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
447         /* 32K */
448         dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
449         /* 64K */
450         dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
451         /* 128k */
452         dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
453         /* 256k */
454         dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
455         /* 512k */
456         dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
457         /* 1M */
458         dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
459         /* 2M */
460         dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
461         /* 4M */
462         dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
463
464         for (i = 1; i < dram_size / 0x800000; i++) {
465                 dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
466         }
467 #endif
468
469         t_end = get_tbms();
470         icache_disable();
471
472         debug("\nREADY!!\n");
473         debug("ddr init duration: %ld ms\n", t_end - t_start);
474
475         /* Clear All ECC Errors */
476         if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME)
477                 ddr->err_detect |= ECC_ERROR_DETECT_MME;
478         if ((ddr->err_detect & ECC_ERROR_DETECT_MBE) == ECC_ERROR_DETECT_MBE)
479                 ddr->err_detect |= ECC_ERROR_DETECT_MBE;
480         if ((ddr->err_detect & ECC_ERROR_DETECT_SBE) == ECC_ERROR_DETECT_SBE)
481                 ddr->err_detect |= ECC_ERROR_DETECT_SBE;
482         if ((ddr->err_detect & ECC_ERROR_DETECT_MSE) == ECC_ERROR_DETECT_MSE)
483                 ddr->err_detect |= ECC_ERROR_DETECT_MSE;
484
485         /* Disable ECC-Interrupts */
486         ddr->err_int_en &= ECC_ERR_INT_DISABLE;
487
488         /* Enable errors for ECC */
489         ddr->err_disable &= ECC_ERROR_ENABLE;
490
491         __asm__ __volatile__ ("sync");
492         __asm__ __volatile__ ("isync");
493 }
494 #endif  /* CONFIG_DDR_ECC */