]>
Commit | Line | Data |
---|---|---|
f046ccd1 | 1 | /* |
19580e66 | 2 | * (C) Copyright 2006-2007 Freescale Semiconductor, Inc. |
f6eda7f8 | 3 | * |
dc9e499c RJ |
4 | * (C) Copyright 2006 |
5 | * Wolfgang Denk, DENX Software Engineering, [email protected]. | |
cf48eb9a | 6 | * |
5f820439 | 7 | * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. |
f046ccd1 EL |
8 | * (C) Copyright 2003 Motorola Inc. |
9 | * Xianghua Xiao ([email protected]) | |
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 | |
f046ccd1 EL |
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 | ||
81fd52c6 KP |
37 | DECLARE_GLOBAL_DATA_PTR; |
38 | ||
bbea46f7 KP |
39 | void board_add_ram_info(int use_default) |
40 | { | |
41 | volatile immap_t *immap = (immap_t *) CFG_IMMR; | |
42 | volatile ddr83xx_t *ddr = &immap->ddr; | |
81fd52c6 | 43 | char buf[32]; |
bbea46f7 KP |
44 | |
45 | printf(" (DDR%d", ((ddr->sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) | |
46 | >> SDRAM_CFG_SDRAM_TYPE_SHIFT) - 1); | |
47 | ||
48 | if (ddr->sdram_cfg & SDRAM_CFG_32_BE) | |
49 | puts(", 32-bit"); | |
50 | else | |
51 | puts(", 64-bit"); | |
52 | ||
53 | if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) | |
81fd52c6 | 54 | puts(", ECC on"); |
bbea46f7 | 55 | else |
81fd52c6 KP |
56 | puts(", ECC off"); |
57 | ||
58 | printf(", %s MHz)", strmhz(buf, gd->mem_clk)); | |
bbea46f7 KP |
59 | |
60 | #if defined(CFG_LB_SDRAM) && defined(CFG_LBC_SDRAM_SIZE) | |
61 | puts("\nSDRAM: "); | |
62 | print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, " (local bus)"); | |
63 | #endif | |
64 | } | |
65 | ||
f046ccd1 EL |
66 | #ifdef CONFIG_SPD_EEPROM |
67 | ||
f6eda7f8 | 68 | #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) |
f046ccd1 EL |
69 | extern void dma_init(void); |
70 | extern uint dma_check(void); | |
71 | extern int dma_xfer(void *dest, uint count, void *src); | |
72 | #endif | |
73 | ||
f046ccd1 EL |
74 | #ifndef CFG_READ_SPD |
75 | #define CFG_READ_SPD i2c_read | |
76 | #endif | |
77 | ||
f046ccd1 EL |
78 | /* |
79 | * Convert picoseconds into clock cycles (rounding up if needed). | |
80 | */ | |
f046ccd1 EL |
81 | int |
82 | picos_to_clk(int picos) | |
83 | { | |
35cf155c | 84 | unsigned int mem_bus_clk; |
f046ccd1 EL |
85 | int clks; |
86 | ||
35cf155c KP |
87 | mem_bus_clk = gd->mem_clk >> 1; |
88 | clks = picos / (1000000000 / (mem_bus_clk / 1000)); | |
89 | if (picos % (1000000000 / (mem_bus_clk / 1000)) != 0) | |
f6eda7f8 | 90 | clks++; |
f046ccd1 EL |
91 | |
92 | return clks; | |
93 | } | |
94 | ||
4c8d1ecc | 95 | unsigned int banksize(unsigned char row_dens) |
f046ccd1 EL |
96 | { |
97 | return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24; | |
98 | } | |
99 | ||
4c8d1ecc MB |
100 | int read_spd(uint addr) |
101 | { | |
102 | return ((int) addr); | |
103 | } | |
104 | ||
dc9e499c RJ |
105 | #undef SPD_DEBUG |
106 | #ifdef SPD_DEBUG | |
107 | static void spd_debug(spd_eeprom_t *spd) | |
108 | { | |
109 | printf ("\nDIMM type: %-18.18s\n", spd->mpart); | |
110 | printf ("SPD size: %d\n", spd->info_size); | |
111 | printf ("EEPROM size: %d\n", 1 << spd->chip_size); | |
112 | printf ("Memory type: %d\n", spd->mem_type); | |
113 | printf ("Row addr: %d\n", spd->nrow_addr); | |
114 | printf ("Column addr: %d\n", spd->ncol_addr); | |
115 | printf ("# of rows: %d\n", spd->nrows); | |
116 | printf ("Row density: %d\n", spd->row_dens); | |
117 | printf ("# of banks: %d\n", spd->nbanks); | |
118 | printf ("Data width: %d\n", | |
119 | 256 * spd->dataw_msb + spd->dataw_lsb); | |
120 | printf ("Chip width: %d\n", spd->primw); | |
121 | printf ("Refresh rate: %02X\n", spd->refresh); | |
122 | printf ("CAS latencies: %02X\n", spd->cas_lat); | |
123 | printf ("Write latencies: %02X\n", spd->write_lat); | |
124 | printf ("tRP: %d\n", spd->trp); | |
125 | printf ("tRCD: %d\n", spd->trcd); | |
126 | printf ("\n"); | |
127 | } | |
128 | #endif /* SPD_DEBUG */ | |
129 | ||
130 | long int spd_sdram() | |
f046ccd1 | 131 | { |
d239d74b | 132 | volatile immap_t *immap = (immap_t *)CFG_IMMR; |
f6eda7f8 DL |
133 | volatile ddr83xx_t *ddr = &immap->ddr; |
134 | volatile law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; | |
f046ccd1 | 135 | spd_eeprom_t spd; |
d61853cf XX |
136 | unsigned int n_ranks; |
137 | unsigned int odt_rd_cfg, odt_wr_cfg; | |
138 | unsigned char twr_clk, twtr_clk; | |
bbea46f7 | 139 | unsigned int sdram_type; |
f046ccd1 EL |
140 | unsigned int memsize; |
141 | unsigned int law_size; | |
f6eda7f8 | 142 | unsigned char caslat, caslat_ctrl; |
d61853cf XX |
143 | unsigned int trfc, trfc_clk, trfc_low, trfc_high; |
144 | unsigned int trcd_clk, trtp_clk; | |
145 | unsigned char cke_min_clk; | |
146 | unsigned char add_lat, wr_lat; | |
147 | unsigned char wr_data_delay; | |
148 | unsigned char four_act; | |
149 | unsigned char cpo; | |
f6eda7f8 | 150 | unsigned char burstlen; |
d61853cf | 151 | unsigned char odt_cfg, mode_odt_enable; |
f6eda7f8 DL |
152 | unsigned int max_bus_clk; |
153 | unsigned int max_data_rate, effective_data_rate; | |
154 | unsigned int ddrc_clk; | |
155 | unsigned int refresh_clk; | |
d61853cf | 156 | unsigned int sdram_cfg; |
f6eda7f8 | 157 | unsigned int ddrc_ecc_enable; |
d61853cf | 158 | unsigned int pvr = get_pvr(); |
de1d0a69 | 159 | |
dd520bf3 | 160 | /* Read SPD parameters with I2C */ |
f046ccd1 | 161 | CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd)); |
dc9e499c RJ |
162 | #ifdef SPD_DEBUG |
163 | spd_debug(&spd); | |
164 | #endif | |
f6eda7f8 | 165 | /* Check the memory type */ |
d61853cf | 166 | if (spd.mem_type != SPD_MEMTYPE_DDR && spd.mem_type != SPD_MEMTYPE_DDR2) { |
bbea46f7 | 167 | debug("DDR: Module mem type is %02X\n", spd.mem_type); |
f6eda7f8 DL |
168 | return 0; |
169 | } | |
170 | ||
171 | /* Check the number of physical bank */ | |
d61853cf XX |
172 | if (spd.mem_type == SPD_MEMTYPE_DDR) { |
173 | n_ranks = spd.nrows; | |
174 | } else { | |
175 | n_ranks = (spd.nrows & 0x7) + 1; | |
176 | } | |
177 | ||
178 | if (n_ranks > 2) { | |
179 | printf("DDR: The number of physical bank is %02X\n", n_ranks); | |
f046ccd1 EL |
180 | return 0; |
181 | } | |
182 | ||
f6eda7f8 | 183 | /* Check if the number of row of the module is in the range of DDRC */ |
d61853cf | 184 | if (spd.nrow_addr < 12 || spd.nrow_addr > 15) { |
f6eda7f8 DL |
185 | printf("DDR: Row number is out of range of DDRC, row=%02X\n", |
186 | spd.nrow_addr); | |
f046ccd1 EL |
187 | return 0; |
188 | } | |
189 | ||
f6eda7f8 DL |
190 | /* Check if the number of col of the module is in the range of DDRC */ |
191 | if (spd.ncol_addr < 8 || spd.ncol_addr > 11) { | |
192 | printf("DDR: Col number is out of range of DDRC, col=%02X\n", | |
193 | spd.ncol_addr); | |
194 | return 0; | |
195 | } | |
d61853cf XX |
196 | |
197 | #ifdef CFG_DDRCDR_VALUE | |
198 | /* | |
199 | * Adjust DDR II IO voltage biasing. It just makes it work. | |
200 | */ | |
201 | if(spd.mem_type == SPD_MEMTYPE_DDR2) { | |
202 | immap->sysconf.ddrcdr = CFG_DDRCDR_VALUE; | |
203 | } | |
19580e66 | 204 | udelay(50000); |
d61853cf XX |
205 | #endif |
206 | ||
207 | /* | |
208 | * ODT configuration recommendation from DDR Controller Chapter. | |
209 | */ | |
210 | odt_rd_cfg = 0; /* Never assert ODT */ | |
211 | odt_wr_cfg = 0; /* Never assert ODT */ | |
212 | if (spd.mem_type == SPD_MEMTYPE_DDR2) { | |
213 | odt_wr_cfg = 1; /* Assert ODT on writes to CSn */ | |
214 | } | |
215 | ||
dd520bf3 | 216 | /* Setup DDR chip select register */ |
5f820439 DL |
217 | #ifdef CFG_83XX_DDR_USES_CS0 |
218 | ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1; | |
219 | ddr->cs_config[0] = ( 1 << 31 | |
d61853cf XX |
220 | | (odt_rd_cfg << 20) |
221 | | (odt_wr_cfg << 16) | |
5f820439 DL |
222 | | (spd.nrow_addr - 12) << 8 |
223 | | (spd.ncol_addr - 8) ); | |
224 | debug("\n"); | |
225 | debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds); | |
226 | debug("cs0_config = 0x%08x\n",ddr->cs_config[0]); | |
227 | ||
d61853cf | 228 | if (n_ranks == 2) { |
5f820439 DL |
229 | ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8) |
230 | | ((banksize(spd.row_dens) >> 23) - 1) ); | |
231 | ddr->cs_config[1] = ( 1<<31 | |
d61853cf XX |
232 | | (odt_rd_cfg << 20) |
233 | | (odt_wr_cfg << 16) | |
5f820439 DL |
234 | | (spd.nrow_addr-12) << 8 |
235 | | (spd.ncol_addr-8) ); | |
236 | debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds); | |
237 | debug("cs1_config = 0x%08x\n",ddr->cs_config[1]); | |
238 | } | |
239 | ||
240 | #else | |
f046ccd1 EL |
241 | ddr->csbnds[2].csbnds = (banksize(spd.row_dens) >> 24) - 1; |
242 | ddr->cs_config[2] = ( 1 << 31 | |
d61853cf XX |
243 | | (odt_rd_cfg << 20) |
244 | | (odt_wr_cfg << 16) | |
f046ccd1 EL |
245 | | (spd.nrow_addr - 12) << 8 |
246 | | (spd.ncol_addr - 8) ); | |
247 | debug("\n"); | |
248 | debug("cs2_bnds = 0x%08x\n",ddr->csbnds[2].csbnds); | |
249 | debug("cs2_config = 0x%08x\n",ddr->cs_config[2]); | |
de1d0a69 | 250 | |
d61853cf | 251 | if (n_ranks == 2) { |
f046ccd1 EL |
252 | ddr->csbnds[3].csbnds = ( (banksize(spd.row_dens) >> 8) |
253 | | ((banksize(spd.row_dens) >> 23) - 1) ); | |
254 | ddr->cs_config[3] = ( 1<<31 | |
d61853cf XX |
255 | | (odt_rd_cfg << 20) |
256 | | (odt_wr_cfg << 16) | |
f046ccd1 EL |
257 | | (spd.nrow_addr-12) << 8 |
258 | | (spd.ncol_addr-8) ); | |
259 | debug("cs3_bnds = 0x%08x\n",ddr->csbnds[3].csbnds); | |
260 | debug("cs3_config = 0x%08x\n",ddr->cs_config[3]); | |
261 | } | |
2ad6b513 | 262 | #endif |
f046ccd1 | 263 | |
f046ccd1 EL |
264 | /* |
265 | * Figure out memory size in Megabytes. | |
266 | */ | |
d61853cf | 267 | memsize = n_ranks * banksize(spd.row_dens) / 0x100000; |
f046ccd1 EL |
268 | |
269 | /* | |
270 | * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. | |
271 | */ | |
272 | law_size = 19 + __ilog2(memsize); | |
273 | ||
274 | /* | |
275 | * Set up LAWBAR for all of DDR. | |
276 | */ | |
277 | ecm->bar = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff); | |
278 | ecm->ar = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size)); | |
279 | debug("DDR:bar=0x%08x\n", ecm->bar); | |
280 | debug("DDR:ar=0x%08x\n", ecm->ar); | |
281 | ||
282 | /* | |
f6eda7f8 DL |
283 | * Find the largest CAS by locating the highest 1 bit |
284 | * in the spd.cas_lat field. Translate it to a DDR | |
285 | * controller field value: | |
286 | * | |
d61853cf XX |
287 | * CAS Lat DDR I DDR II Ctrl |
288 | * Clocks SPD Bit SPD Bit Value | |
289 | * ------- ------- ------- ----- | |
290 | * 1.0 0 0001 | |
291 | * 1.5 1 0010 | |
292 | * 2.0 2 2 0011 | |
293 | * 2.5 3 0100 | |
294 | * 3.0 4 3 0101 | |
295 | * 3.5 5 0110 | |
296 | * 4.0 6 4 0111 | |
297 | * 4.5 1000 | |
298 | * 5.0 5 1001 | |
f046ccd1 | 299 | */ |
f6eda7f8 | 300 | caslat = __ilog2(spd.cas_lat); |
d61853cf XX |
301 | if ((spd.mem_type == SPD_MEMTYPE_DDR) |
302 | && (caslat > 6)) { | |
303 | printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat); | |
304 | return 0; | |
305 | } else if (spd.mem_type == SPD_MEMTYPE_DDR2 | |
306 | && (caslat < 2 || caslat > 5)) { | |
307 | printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n", | |
308 | spd.cas_lat); | |
f046ccd1 EL |
309 | return 0; |
310 | } | |
d61853cf XX |
311 | debug("DDR: caslat SPD bit is %d\n", caslat); |
312 | ||
f6eda7f8 DL |
313 | max_bus_clk = 1000 *10 / (((spd.clk_cycle & 0xF0) >> 4) * 10 |
314 | + (spd.clk_cycle & 0x0f)); | |
315 | max_data_rate = max_bus_clk * 2; | |
316 | ||
317 | debug("DDR:Module maximum data rate is: %dMhz\n", max_data_rate); | |
318 | ||
35cf155c | 319 | ddrc_clk = gd->mem_clk / 1000000; |
d61853cf | 320 | effective_data_rate = 0; |
f046ccd1 | 321 | |
d61853cf XX |
322 | if (max_data_rate >= 390 && max_data_rate < 460) { /* it is DDR 400 */ |
323 | if (ddrc_clk <= 460 && ddrc_clk > 350) { | |
324 | /* DDR controller clk at 350~460 */ | |
5f820439 DL |
325 | effective_data_rate = 400; /* 5ns */ |
326 | caslat = caslat; | |
327 | } else if (ddrc_clk <= 350 && ddrc_clk > 280) { | |
328 | /* DDR controller clk at 280~350 */ | |
329 | effective_data_rate = 333; /* 6ns */ | |
e857a5bd | 330 | if (spd.clk_cycle2 == 0x60) |
5f820439 | 331 | caslat = caslat - 1; |
e857a5bd | 332 | else |
5f820439 | 333 | caslat = caslat; |
5f820439 DL |
334 | } else if (ddrc_clk <= 280 && ddrc_clk > 230) { |
335 | /* DDR controller clk at 230~280 */ | |
336 | effective_data_rate = 266; /* 7.5ns */ | |
e857a5bd | 337 | if (spd.clk_cycle3 == 0x75) |
5f820439 | 338 | caslat = caslat - 2; |
d61853cf | 339 | else if (spd.clk_cycle2 == 0x75) |
5f820439 | 340 | caslat = caslat - 1; |
e857a5bd | 341 | else |
5f820439 | 342 | caslat = caslat; |
5f820439 DL |
343 | } else if (ddrc_clk <= 230 && ddrc_clk > 90) { |
344 | /* DDR controller clk at 90~230 */ | |
345 | effective_data_rate = 200; /* 10ns */ | |
d61853cf | 346 | if (spd.clk_cycle3 == 0xa0) |
5f820439 | 347 | caslat = caslat - 2; |
d61853cf | 348 | else if (spd.clk_cycle2 == 0xa0) |
5f820439 | 349 | caslat = caslat - 1; |
e857a5bd | 350 | else |
5f820439 | 351 | caslat = caslat; |
5f820439 | 352 | } |
f6eda7f8 DL |
353 | } else if (max_data_rate >= 323) { /* it is DDR 333 */ |
354 | if (ddrc_clk <= 350 && ddrc_clk > 280) { | |
5f820439 | 355 | /* DDR controller clk at 280~350 */ |
f6eda7f8 DL |
356 | effective_data_rate = 333; /* 6ns */ |
357 | caslat = caslat; | |
358 | } else if (ddrc_clk <= 280 && ddrc_clk > 230) { | |
5f820439 DL |
359 | /* DDR controller clk at 230~280 */ |
360 | effective_data_rate = 266; /* 7.5ns */ | |
e857a5bd | 361 | if (spd.clk_cycle2 == 0x75) |
f6eda7f8 | 362 | caslat = caslat - 1; |
e857a5bd | 363 | else |
5f820439 | 364 | caslat = caslat; |
f6eda7f8 | 365 | } else if (ddrc_clk <= 230 && ddrc_clk > 90) { |
5f820439 DL |
366 | /* DDR controller clk at 90~230 */ |
367 | effective_data_rate = 200; /* 10ns */ | |
e857a5bd | 368 | if (spd.clk_cycle3 == 0xa0) |
f6eda7f8 | 369 | caslat = caslat - 2; |
d61853cf | 370 | else if (spd.clk_cycle2 == 0xa0) |
5f820439 | 371 | caslat = caslat - 1; |
e857a5bd | 372 | else |
5f820439 | 373 | caslat = caslat; |
f6eda7f8 DL |
374 | } |
375 | } else if (max_data_rate >= 256) { /* it is DDR 266 */ | |
376 | if (ddrc_clk <= 350 && ddrc_clk > 280) { | |
5f820439 | 377 | /* DDR controller clk at 280~350 */ |
f6eda7f8 DL |
378 | printf("DDR: DDR controller freq is more than " |
379 | "max data rate of the module\n"); | |
380 | return 0; | |
381 | } else if (ddrc_clk <= 280 && ddrc_clk > 230) { | |
5f820439 | 382 | /* DDR controller clk at 230~280 */ |
f6eda7f8 DL |
383 | effective_data_rate = 266; /* 7.5ns */ |
384 | caslat = caslat; | |
385 | } else if (ddrc_clk <= 230 && ddrc_clk > 90) { | |
5f820439 DL |
386 | /* DDR controller clk at 90~230 */ |
387 | effective_data_rate = 200; /* 10ns */ | |
e857a5bd | 388 | if (spd.clk_cycle2 == 0xa0) |
f6eda7f8 | 389 | caslat = caslat - 1; |
f6eda7f8 DL |
390 | } |
391 | } else if (max_data_rate >= 190) { /* it is DDR 200 */ | |
392 | if (ddrc_clk <= 350 && ddrc_clk > 230) { | |
5f820439 | 393 | /* DDR controller clk at 230~350 */ |
f6eda7f8 DL |
394 | printf("DDR: DDR controller freq is more than " |
395 | "max data rate of the module\n"); | |
396 | return 0; | |
397 | } else if (ddrc_clk <= 230 && ddrc_clk > 90) { | |
5f820439 | 398 | /* DDR controller clk at 90~230 */ |
f6eda7f8 DL |
399 | effective_data_rate = 200; /* 10ns */ |
400 | caslat = caslat; | |
401 | } | |
f046ccd1 EL |
402 | } |
403 | ||
5f820439 DL |
404 | debug("DDR:Effective data rate is: %dMhz\n", effective_data_rate); |
405 | debug("DDR:The MSB 1 of CAS Latency is: %d\n", caslat); | |
bed85caf | 406 | |
5f820439 DL |
407 | /* |
408 | * Errata DDR6 work around: input enable 2 cycles earlier. | |
409 | * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2. | |
410 | */ | |
d61853cf XX |
411 | if(PVR_MAJ(pvr) <= 1 && spd.mem_type == SPD_MEMTYPE_DDR){ |
412 | if (caslat == 2) | |
413 | ddr->debug_reg = 0x201c0000; /* CL=2 */ | |
414 | else if (caslat == 3) | |
415 | ddr->debug_reg = 0x202c0000; /* CL=2.5 */ | |
416 | else if (caslat == 4) | |
417 | ddr->debug_reg = 0x202c0000; /* CL=3.0 */ | |
e857a5bd | 418 | |
d61853cf | 419 | __asm__ __volatile__ ("sync"); |
bed85caf | 420 | |
d61853cf XX |
421 | debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg); |
422 | } | |
bed85caf | 423 | |
f046ccd1 | 424 | /* |
d61853cf XX |
425 | * Convert caslat clocks to DDR controller value. |
426 | * Force caslat_ctrl to be DDR Controller field-sized. | |
427 | */ | |
428 | if (spd.mem_type == SPD_MEMTYPE_DDR) { | |
429 | caslat_ctrl = (caslat + 1) & 0x07; | |
430 | } else { | |
431 | caslat_ctrl = (2 * caslat - 1) & 0x0f; | |
432 | } | |
433 | ||
434 | debug("DDR: effective data rate is %d MHz\n", effective_data_rate); | |
435 | debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n", | |
436 | caslat, caslat_ctrl); | |
437 | ||
438 | /* | |
439 | * Timing Config 0. | |
440 | * Avoid writing for DDR I. | |
441 | */ | |
442 | if (spd.mem_type == SPD_MEMTYPE_DDR2) { | |
443 | unsigned char taxpd_clk = 8; /* By the book. */ | |
444 | unsigned char tmrd_clk = 2; /* By the book. */ | |
445 | unsigned char act_pd_exit = 2; /* Empirical? */ | |
446 | unsigned char pre_pd_exit = 6; /* Empirical? */ | |
447 | ||
448 | ddr->timing_cfg_0 = (0 | |
449 | | ((act_pd_exit & 0x7) << 20) /* ACT_PD_EXIT */ | |
450 | | ((pre_pd_exit & 0x7) << 16) /* PRE_PD_EXIT */ | |
451 | | ((taxpd_clk & 0xf) << 8) /* ODT_PD_EXIT */ | |
452 | | ((tmrd_clk & 0xf) << 0) /* MRS_CYC */ | |
453 | ); | |
454 | debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); | |
455 | } | |
456 | ||
457 | /* | |
458 | * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD, | |
459 | * use conservative value. | |
460 | * For DDR II, they are bytes 36 and 37, in quarter nanos. | |
461 | */ | |
462 | ||
463 | if (spd.mem_type == SPD_MEMTYPE_DDR) { | |
464 | twr_clk = 3; /* Clocks */ | |
465 | twtr_clk = 1; /* Clocks */ | |
466 | } else { | |
467 | twr_clk = picos_to_clk(spd.twr * 250); | |
468 | twtr_clk = picos_to_clk(spd.twtr * 250); | |
469 | } | |
470 | ||
471 | /* | |
472 | * Calculate Trfc, in picos. | |
473 | * DDR I: Byte 42 straight up in ns. | |
474 | * DDR II: Byte 40 and 42 swizzled some, in ns. | |
475 | */ | |
476 | if (spd.mem_type == SPD_MEMTYPE_DDR) { | |
477 | trfc = spd.trfc * 1000; /* up to ps */ | |
478 | } else { | |
479 | unsigned int byte40_table_ps[8] = { | |
480 | 0, | |
481 | 250, | |
482 | 330, | |
483 | 500, | |
484 | 660, | |
485 | 750, | |
486 | 0, | |
487 | 0 | |
488 | }; | |
489 | ||
490 | trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000 | |
491 | + byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7]; | |
492 | } | |
493 | trfc_clk = picos_to_clk(trfc); | |
494 | ||
495 | /* | |
496 | * Trcd, Byte 29, from quarter nanos to ps and clocks. | |
f046ccd1 | 497 | */ |
d61853cf XX |
498 | trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7; |
499 | ||
500 | /* | |
501 | * Convert trfc_clk to DDR controller fields. DDR I should | |
502 | * fit in the REFREC field (16-19) of TIMING_CFG_1, but the | |
503 | * 83xx controller has an extended REFREC field of three bits. | |
504 | * The controller automatically adds 8 clocks to this value, | |
505 | * so preadjust it down 8 first before splitting it up. | |
506 | */ | |
507 | trfc_low = (trfc_clk - 8) & 0xf; | |
508 | trfc_high = ((trfc_clk - 8) >> 4) & 0x3; | |
f046ccd1 EL |
509 | |
510 | ddr->timing_cfg_1 = | |
d61853cf XX |
511 | (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) | /* PRETOACT */ |
512 | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) | /* ACTTOPRE */ | |
53677ef1 | 513 | (trcd_clk << 20 ) | /* ACTTORW */ |
d61853cf XX |
514 | (caslat_ctrl << 16 ) | /* CASLAT */ |
515 | (trfc_low << 12 ) | /* REFEC */ | |
516 | ((twr_clk & 0x07) << 8) | /* WRRREC */ | |
517 | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | /* ACTTOACT */ | |
518 | ((twtr_clk & 0x07) << 0) /* WRTORD */ | |
519 | ); | |
520 | ||
521 | /* | |
522 | * Additive Latency | |
523 | * For DDR I, 0. | |
524 | * For DDR II, with ODT enabled, use "a value" less than ACTTORW, | |
525 | * which comes from Trcd, and also note that: | |
526 | * add_lat + caslat must be >= 4 | |
527 | */ | |
528 | add_lat = 0; | |
529 | if (spd.mem_type == SPD_MEMTYPE_DDR2 | |
530 | && (odt_wr_cfg || odt_rd_cfg) | |
531 | && (caslat < 4)) { | |
532 | add_lat = trcd_clk - 1; | |
533 | if ((add_lat + caslat) < 4) { | |
534 | add_lat = 0; | |
535 | } | |
536 | } | |
537 | ||
538 | /* | |
539 | * Write Data Delay | |
540 | * Historically 0x2 == 4/8 clock delay. | |
541 | * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266. | |
542 | */ | |
543 | wr_data_delay = 2; | |
544 | ||
545 | /* | |
546 | * Write Latency | |
547 | * Read to Precharge | |
548 | * Minimum CKE Pulse Width. | |
549 | * Four Activate Window | |
550 | */ | |
551 | if (spd.mem_type == SPD_MEMTYPE_DDR) { | |
552 | /* | |
553 | * This is a lie. It should really be 1, but if it is | |
554 | * set to 1, bits overlap into the old controller's | |
555 | * otherwise unused ACSM field. If we leave it 0, then | |
556 | * the HW will magically treat it as 1 for DDR 1. Oh Yea. | |
557 | */ | |
558 | wr_lat = 0; | |
559 | ||
560 | trtp_clk = 2; /* By the book. */ | |
561 | cke_min_clk = 1; /* By the book. */ | |
562 | four_act = 1; /* By the book. */ | |
563 | ||
564 | } else { | |
565 | wr_lat = caslat - 1; | |
566 | ||
567 | /* Convert SPD value from quarter nanos to picos. */ | |
568 | trtp_clk = picos_to_clk(spd.trtp * 250); | |
f046ccd1 | 569 | |
d61853cf XX |
570 | cke_min_clk = 3; /* By the book. */ |
571 | four_act = picos_to_clk(37500); /* By the book. 1k pages? */ | |
572 | } | |
573 | ||
574 | /* | |
575 | * Empirically set ~MCAS-to-preamble override for DDR 2. | |
576 | * Your milage will vary. | |
577 | */ | |
578 | cpo = 0; | |
579 | if (spd.mem_type == SPD_MEMTYPE_DDR2) { | |
061aad4d DL |
580 | if (effective_data_rate == 266) { |
581 | cpo = 0x4; /* READ_LAT + 1/2 */ | |
582 | } else if (effective_data_rate == 333 || effective_data_rate == 400) { | |
19580e66 | 583 | cpo = 0x7; /* READ_LAT + 5/4 */ |
d61853cf XX |
584 | } else { |
585 | /* Automatic calibration */ | |
586 | cpo = 0x1f; | |
587 | } | |
588 | } | |
589 | ||
590 | ddr->timing_cfg_2 = (0 | |
591 | | ((add_lat & 0x7) << 28) /* ADD_LAT */ | |
592 | | ((cpo & 0x1f) << 23) /* CPO */ | |
593 | | ((wr_lat & 0x7) << 19) /* WR_LAT */ | |
594 | | ((trtp_clk & 0x7) << 13) /* RD_TO_PRE */ | |
595 | | ((wr_data_delay & 0x7) << 10) /* WR_DATA_DELAY */ | |
596 | | ((cke_min_clk & 0x7) << 6) /* CKE_PLS */ | |
597 | | ((four_act & 0x1f) << 0) /* FOUR_ACT */ | |
598 | ); | |
f046ccd1 EL |
599 | |
600 | debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1); | |
601 | debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2); | |
f6eda7f8 DL |
602 | |
603 | /* Check DIMM data bus width */ | |
3f9c542d | 604 | if (spd.dataw_lsb < 64) { |
036575c5 DL |
605 | if (spd.mem_type == SPD_MEMTYPE_DDR) |
606 | burstlen = 0x03; /* 32 bit data bus, burst len is 8 */ | |
49bb5991 | 607 | else |
036575c5 | 608 | burstlen = 0x02; /* 32 bit data bus, burst len is 4 */ |
bbea46f7 | 609 | debug("\n DDR DIMM: data bus width is 32 bit"); |
5f820439 | 610 | } else { |
f6eda7f8 | 611 | burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */ |
bbea46f7 | 612 | debug("\n DDR DIMM: data bus width is 64 bit"); |
f6eda7f8 | 613 | } |
f046ccd1 | 614 | |
f6eda7f8 | 615 | /* Is this an ECC DDR chip? */ |
e857a5bd | 616 | if (spd.config == 0x02) |
bbea46f7 | 617 | debug(" with ECC\n"); |
e857a5bd | 618 | else |
bbea46f7 | 619 | debug(" without ECC\n"); |
f6eda7f8 DL |
620 | |
621 | /* Burst length is always 4 for 64 bit data bus, 8 for 32 bit data bus, | |
622 | Burst type is sequential | |
f046ccd1 | 623 | */ |
d61853cf XX |
624 | if (spd.mem_type == SPD_MEMTYPE_DDR) { |
625 | switch (caslat) { | |
5f820439 DL |
626 | case 1: |
627 | ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */ | |
628 | break; | |
629 | case 2: | |
630 | ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */ | |
631 | break; | |
632 | case 3: | |
633 | ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */ | |
634 | break; | |
635 | case 4: | |
636 | ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */ | |
637 | break; | |
638 | default: | |
639 | printf("DDR:only CL 1.5, 2.0, 2.5, 3.0 is supported\n"); | |
640 | return 0; | |
d61853cf XX |
641 | } |
642 | } else { | |
643 | mode_odt_enable = 0x0; /* Default disabled */ | |
644 | if (odt_wr_cfg || odt_rd_cfg) { | |
645 | /* | |
646 | * Bits 6 and 2 in Extended MRS(1) | |
647 | * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules. | |
648 | * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module. | |
649 | */ | |
650 | mode_odt_enable = 0x40; /* 150 Ohm */ | |
651 | } | |
652 | ||
653 | ddr->sdram_mode = | |
654 | (0 | |
655 | | (1 << (16 + 10)) /* DQS Differential disable */ | |
656 | | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */ | |
657 | | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */ | |
6fbf261f | 658 | | ((twr_clk - 1) << 9) /* Write Recovery Autopre */ |
d61853cf XX |
659 | | (caslat << 4) /* caslat */ |
660 | | (burstlen << 0) /* Burst length */ | |
661 | ); | |
f046ccd1 EL |
662 | } |
663 | debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode); | |
664 | ||
d61853cf XX |
665 | /* |
666 | * Clear EMRS2 and EMRS3. | |
667 | */ | |
668 | ddr->sdram_mode2 = 0; | |
669 | debug("DDR: sdram_mode2 = 0x%08x\n", ddr->sdram_mode2); | |
670 | ||
5f820439 DL |
671 | switch (spd.refresh) { |
672 | case 0x00: | |
673 | case 0x80: | |
674 | refresh_clk = picos_to_clk(15625000); | |
675 | break; | |
676 | case 0x01: | |
677 | case 0x81: | |
678 | refresh_clk = picos_to_clk(3900000); | |
679 | break; | |
680 | case 0x02: | |
681 | case 0x82: | |
682 | refresh_clk = picos_to_clk(7800000); | |
683 | break; | |
684 | case 0x03: | |
685 | case 0x83: | |
686 | refresh_clk = picos_to_clk(31300000); | |
687 | break; | |
688 | case 0x04: | |
689 | case 0x84: | |
690 | refresh_clk = picos_to_clk(62500000); | |
691 | break; | |
692 | case 0x05: | |
693 | case 0x85: | |
694 | refresh_clk = picos_to_clk(125000000); | |
695 | break; | |
696 | default: | |
697 | refresh_clk = 0x512; | |
698 | break; | |
f046ccd1 EL |
699 | } |
700 | ||
701 | /* | |
702 | * Set BSTOPRE to 0x100 for page mode | |
703 | * If auto-charge is used, set BSTOPRE = 0 | |
704 | */ | |
5f820439 | 705 | ddr->sdram_interval = ((refresh_clk & 0x3fff) << 16) | 0x100; |
f046ccd1 EL |
706 | debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval); |
707 | ||
d61853cf XX |
708 | /* |
709 | * SDRAM Cfg 2 | |
710 | */ | |
711 | odt_cfg = 0; | |
19580e66 | 712 | #ifndef CONFIG_NEVER_ASSERT_ODT_TO_CPU |
d61853cf XX |
713 | if (odt_rd_cfg | odt_wr_cfg) { |
714 | odt_cfg = 0x2; /* ODT to IOs during reads */ | |
715 | } | |
19580e66 | 716 | #endif |
d61853cf XX |
717 | if (spd.mem_type == SPD_MEMTYPE_DDR2) { |
718 | ddr->sdram_cfg2 = (0 | |
719 | | (0 << 26) /* True DQS */ | |
720 | | (odt_cfg << 21) /* ODT only read */ | |
721 | | (1 << 12) /* 1 refresh at a time */ | |
722 | ); | |
723 | ||
724 | debug("DDR: sdram_cfg2 = 0x%08x\n", ddr->sdram_cfg2); | |
725 | } | |
726 | ||
91e25769 PG |
727 | #ifdef CFG_DDR_SDRAM_CLK_CNTL /* Optional platform specific value */ |
728 | ddr->sdram_clk_cntl = CFG_DDR_SDRAM_CLK_CNTL; | |
91e25769 | 729 | #endif |
f6eda7f8 | 730 | debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl); |
4c8d1ecc | 731 | |
f046ccd1 EL |
732 | asm("sync;isync"); |
733 | ||
f6eda7f8 | 734 | udelay(600); |
f046ccd1 EL |
735 | |
736 | /* | |
5f820439 DL |
737 | * Figure out the settings for the sdram_cfg register. Build up |
738 | * the value in 'sdram_cfg' before writing since the write into | |
f046ccd1 EL |
739 | * the register will actually enable the memory controller, and all |
740 | * settings must be done before enabling. | |
741 | * | |
742 | * sdram_cfg[0] = 1 (ddr sdram logic enable) | |
743 | * sdram_cfg[1] = 1 (self-refresh-enable) | |
d61853cf XX |
744 | * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM) |
745 | * 010 DDR 1 SDRAM | |
746 | * 011 DDR 2 SDRAM | |
f6eda7f8 DL |
747 | * sdram_cfg[12] = 0 (32_BE =0 , 64 bit bus mode) |
748 | * sdram_cfg[13] = 0 (8_BE =0, 4-beat bursts) | |
f046ccd1 | 749 | */ |
d61853cf | 750 | if (spd.mem_type == SPD_MEMTYPE_DDR) |
bbea46f7 | 751 | sdram_type = SDRAM_CFG_SDRAM_TYPE_DDR1; |
d61853cf | 752 | else |
4cc1cd59 | 753 | sdram_type = SDRAM_CFG_SDRAM_TYPE_DDR2; |
d61853cf XX |
754 | |
755 | sdram_cfg = (0 | |
bbea46f7 KP |
756 | | SDRAM_CFG_MEM_EN /* DDR enable */ |
757 | | SDRAM_CFG_SREN /* Self refresh */ | |
758 | | sdram_type /* SDRAM type */ | |
d61853cf | 759 | ); |
f046ccd1 | 760 | |
f6eda7f8 | 761 | /* sdram_cfg[3] = RD_EN - registered DIMM enable */ |
e857a5bd | 762 | if (spd.mod_attr & 0x02) |
bbea46f7 | 763 | sdram_cfg |= SDRAM_CFG_RD_EN; |
f046ccd1 | 764 | |
f6eda7f8 | 765 | /* The DIMM is 32bit width */ |
3f9c542d | 766 | if (spd.dataw_lsb < 64) { |
036575c5 | 767 | if (spd.mem_type == SPD_MEMTYPE_DDR) |
bbea46f7 | 768 | sdram_cfg |= SDRAM_CFG_32_BE | SDRAM_CFG_8_BE; |
036575c5 | 769 | if (spd.mem_type == SPD_MEMTYPE_DDR2) |
bbea46f7 | 770 | sdram_cfg |= SDRAM_CFG_32_BE; |
036575c5 | 771 | } |
e857a5bd | 772 | |
f6eda7f8 DL |
773 | ddrc_ecc_enable = 0; |
774 | ||
f046ccd1 | 775 | #if defined(CONFIG_DDR_ECC) |
f6eda7f8 | 776 | /* Enable ECC with sdram_cfg[2] */ |
f046ccd1 | 777 | if (spd.config == 0x02) { |
f6eda7f8 DL |
778 | sdram_cfg |= 0x20000000; |
779 | ddrc_ecc_enable = 1; | |
780 | /* disable error detection */ | |
781 | ddr->err_disable = ~ECC_ERROR_ENABLE; | |
782 | /* set single bit error threshold to maximum value, | |
783 | * reset counter to zero */ | |
784 | ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) | | |
5f820439 | 785 | (0 << ECC_ERROR_MAN_SBEC_SHIFT); |
f046ccd1 | 786 | } |
f6eda7f8 DL |
787 | |
788 | debug("DDR:err_disable=0x%08x\n", ddr->err_disable); | |
789 | debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe); | |
f046ccd1 | 790 | #endif |
bbea46f7 | 791 | debug(" DDRC ECC mode: %s\n", ddrc_ecc_enable ? "ON":"OFF"); |
f046ccd1 EL |
792 | |
793 | #if defined(CONFIG_DDR_2T_TIMING) | |
794 | /* | |
795 | * Enable 2T timing by setting sdram_cfg[16]. | |
796 | */ | |
f6eda7f8 | 797 | sdram_cfg |= SDRAM_CFG_2T_EN; |
f046ccd1 | 798 | #endif |
f6eda7f8 DL |
799 | /* Enable controller, and GO! */ |
800 | ddr->sdram_cfg = sdram_cfg; | |
f046ccd1 EL |
801 | asm("sync;isync"); |
802 | udelay(500); | |
803 | ||
804 | debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg); | |
dc9e499c | 805 | return memsize; /*in MBytes*/ |
f046ccd1 | 806 | } |
f046ccd1 EL |
807 | #endif /* CONFIG_SPD_EEPROM */ |
808 | ||
f6eda7f8 | 809 | #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) |
f046ccd1 | 810 | /* |
4c8d1ecc MB |
811 | * Use timebase counter, get_timer() is not availabe |
812 | * at this point of initialization yet. | |
f046ccd1 | 813 | */ |
4c8d1ecc MB |
814 | static __inline__ unsigned long get_tbms (void) |
815 | { | |
816 | unsigned long tbl; | |
817 | unsigned long tbu1, tbu2; | |
818 | unsigned long ms; | |
819 | unsigned long long tmp; | |
820 | ||
821 | ulong tbclk = get_tbclk(); | |
822 | ||
823 | /* get the timebase ticks */ | |
824 | do { | |
825 | asm volatile ("mftbu %0":"=r" (tbu1):); | |
826 | asm volatile ("mftb %0":"=r" (tbl):); | |
827 | asm volatile ("mftbu %0":"=r" (tbu2):); | |
828 | } while (tbu1 != tbu2); | |
829 | ||
830 | /* convert ticks to ms */ | |
831 | tmp = (unsigned long long)(tbu1); | |
832 | tmp = (tmp << 32); | |
833 | tmp += (unsigned long long)(tbl); | |
834 | ms = tmp/(tbclk/1000); | |
835 | ||
836 | return ms; | |
837 | } | |
f046ccd1 | 838 | |
4c8d1ecc MB |
839 | /* |
840 | * Initialize all of memory for ECC, then enable errors. | |
841 | */ | |
cf48eb9a | 842 | /* #define CONFIG_DDR_ECC_INIT_VIA_DMA */ |
4c8d1ecc | 843 | void ddr_enable_ecc(unsigned int dram_size) |
f046ccd1 | 844 | { |
d239d74b | 845 | volatile immap_t *immap = (immap_t *)CFG_IMMR; |
f6eda7f8 | 846 | volatile ddr83xx_t *ddr= &immap->ddr; |
4c8d1ecc | 847 | unsigned long t_start, t_end; |
90f30a71 DL |
848 | register u64 *p; |
849 | register uint size; | |
850 | unsigned int pattern[2]; | |
4c8d1ecc MB |
851 | #if defined(CONFIG_DDR_ECC_INIT_VIA_DMA) |
852 | uint i; | |
853 | #endif | |
4c8d1ecc | 854 | icache_enable(); |
4c8d1ecc | 855 | t_start = get_tbms(); |
90f30a71 DL |
856 | pattern[0] = 0xdeadbeef; |
857 | pattern[1] = 0xdeadbeef; | |
4c8d1ecc MB |
858 | |
859 | #if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA) | |
90f30a71 DL |
860 | debug("ddr init: CPU FP write method\n"); |
861 | size = dram_size; | |
862 | for (p = 0; p < (u64*)(size); p++) { | |
863 | ppcDWstore((u32*)p, pattern); | |
f046ccd1 | 864 | } |
90f30a71 | 865 | __asm__ __volatile__ ("sync"); |
4c8d1ecc | 866 | #else |
90f30a71 DL |
867 | debug("ddr init: DMA method\n"); |
868 | size = 0x2000; | |
869 | for (p = 0; p < (u64*)(size); p++) { | |
870 | ppcDWstore((u32*)p, pattern); | |
4c8d1ecc | 871 | } |
90f30a71 | 872 | __asm__ __volatile__ ("sync"); |
f046ccd1 | 873 | |
90f30a71 DL |
874 | /* Initialise DMA for direct transfer */ |
875 | dma_init(); | |
876 | /* Start DMA to transfer */ | |
5f820439 DL |
877 | dma_xfer((uint *)0x2000, 0x2000, (uint *)0); /* 8K */ |
878 | dma_xfer((uint *)0x4000, 0x4000, (uint *)0); /* 16K */ | |
879 | dma_xfer((uint *)0x8000, 0x8000, (uint *)0); /* 32K */ | |
880 | dma_xfer((uint *)0x10000, 0x10000, (uint *)0); /* 64K */ | |
881 | dma_xfer((uint *)0x20000, 0x20000, (uint *)0); /* 128K */ | |
882 | dma_xfer((uint *)0x40000, 0x40000, (uint *)0); /* 256K */ | |
883 | dma_xfer((uint *)0x80000, 0x80000, (uint *)0); /* 512K */ | |
884 | dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */ | |
885 | dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */ | |
886 | dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */ | |
f046ccd1 EL |
887 | |
888 | for (i = 1; i < dram_size / 0x800000; i++) { | |
889 | dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); | |
890 | } | |
de1d0a69 | 891 | #endif |
f046ccd1 | 892 | |
4c8d1ecc MB |
893 | t_end = get_tbms(); |
894 | icache_disable(); | |
895 | ||
896 | debug("\nREADY!!\n"); | |
897 | debug("ddr init duration: %ld ms\n", t_end - t_start); | |
898 | ||
899 | /* Clear All ECC Errors */ | |
900 | if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME) | |
901 | ddr->err_detect |= ECC_ERROR_DETECT_MME; | |
902 | if ((ddr->err_detect & ECC_ERROR_DETECT_MBE) == ECC_ERROR_DETECT_MBE) | |
903 | ddr->err_detect |= ECC_ERROR_DETECT_MBE; | |
904 | if ((ddr->err_detect & ECC_ERROR_DETECT_SBE) == ECC_ERROR_DETECT_SBE) | |
905 | ddr->err_detect |= ECC_ERROR_DETECT_SBE; | |
906 | if ((ddr->err_detect & ECC_ERROR_DETECT_MSE) == ECC_ERROR_DETECT_MSE) | |
907 | ddr->err_detect |= ECC_ERROR_DETECT_MSE; | |
908 | ||
909 | /* Disable ECC-Interrupts */ | |
910 | ddr->err_int_en &= ECC_ERR_INT_DISABLE; | |
911 | ||
912 | /* Enable errors for ECC */ | |
913 | ddr->err_disable &= ECC_ERROR_ENABLE; | |
914 | ||
915 | __asm__ __volatile__ ("sync"); | |
916 | __asm__ __volatile__ ("isync"); | |
917 | } | |
f046ccd1 | 918 | #endif /* CONFIG_DDR_ECC */ |