]>
Commit | Line | Data |
---|---|---|
983fda83 WD |
1 | /* |
2 | * (C) Copyright 2004, Freescale, Inc | |
3 | * TsiChung Liew, Tsi-Chung.Liew@freescale.com | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | /* | |
25 | DESCRIPTION | |
26 | Read Dram spd and base on its information to calculate the memory size, | |
27 | characteristics to initialize the dram on MPC8220 | |
28 | */ | |
29 | ||
30 | #include <common.h> | |
31 | #include <mpc8220.h> | |
32 | #include "i2cCore.h" | |
33 | #include "dramSetup.h" | |
34 | ||
d87080b7 WD |
35 | DECLARE_GLOBAL_DATA_PTR; |
36 | ||
6d0f6bcf JCPV |
37 | #define SPD_SIZE CONFIG_SYS_SDRAM_SPD_SIZE |
38 | #define DRAM_SPD (CONFIG_SYS_SDRAM_SPD_I2C_ADDR)<<1 /* on Board SPD eeprom */ | |
39 | #define TOTAL_BANK CONFIG_SYS_SDRAM_TOTAL_BANKS | |
983fda83 WD |
40 | |
41 | int spd_status (volatile i2c8220_t * pi2c, u8 sta_bit, u8 truefalse) | |
42 | { | |
43 | int i; | |
44 | ||
45 | for (i = 0; i < I2C_POLL_COUNT; i++) { | |
46 | if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0)) | |
47 | return (OK); | |
48 | } | |
49 | ||
50 | return (ERROR); | |
51 | } | |
52 | ||
53 | int spd_clear (volatile i2c8220_t * pi2c) | |
54 | { | |
55 | pi2c->adr = 0; | |
56 | pi2c->fdr = 0; | |
57 | pi2c->cr = 0; | |
58 | pi2c->sr = 0; | |
59 | ||
60 | return (OK); | |
61 | } | |
62 | ||
63 | int spd_stop (volatile i2c8220_t * pi2c) | |
64 | { | |
65 | pi2c->cr &= ~I2C_CTL_STA; /* Generate stop signal */ | |
66 | if (spd_status (pi2c, I2C_STA_BB, 0) != OK) | |
67 | return ERROR; | |
68 | ||
69 | return (OK); | |
70 | } | |
71 | ||
72 | int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index) | |
73 | { | |
74 | pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt Bit */ | |
75 | *readb = pi2c->dr; /* Read a byte */ | |
76 | ||
77 | /* | |
78 | Set I2C_CTRL_TXAK will cause Transfer pending and | |
79 | set I2C_CTRL_STA will cause Interrupt pending | |
80 | */ | |
81 | if (*index != 2) { | |
82 | if (spd_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ | |
83 | return ERROR; | |
84 | } | |
85 | ||
86 | if (*index != 1) { | |
87 | if (spd_status (pi2c, I2C_STA_IF, 1) != OK) | |
88 | return ERROR; | |
89 | } | |
90 | ||
91 | return (OK); | |
92 | } | |
93 | ||
94 | int readSpdData (u8 * spdData) | |
95 | { | |
983fda83 WD |
96 | volatile i2c8220_t *pi2cReg; |
97 | volatile pcfg8220_t *pcfg; | |
98 | u8 slvAdr = DRAM_SPD; | |
99 | u8 Tmp; | |
100 | int Length = SPD_SIZE; | |
101 | int i = 0; | |
102 | ||
103 | /* Enable Port Configuration for SDA and SDL signals */ | |
104 | pcfg = (volatile pcfg8220_t *) (MMAP_PCFG); | |
105 | __asm__ ("sync"); | |
6d0f6bcf | 106 | pcfg->pcfg3 &= ~CONFIG_SYS_I2C_PORT3_CONFIG; |
983fda83 WD |
107 | __asm__ ("sync"); |
108 | ||
109 | /* Points the structure to I2c mbar memory offset */ | |
110 | pi2cReg = (volatile i2c8220_t *) (MMAP_I2C); | |
111 | ||
112 | ||
113 | /* Clear FDR, ADR, SR and CR reg */ | |
114 | pi2cReg->adr = 0; | |
115 | pi2cReg->fdr = 0; | |
116 | pi2cReg->cr = 0; | |
117 | pi2cReg->sr = 0; | |
118 | ||
119 | /* Set for fix XLB Bus Frequency */ | |
120 | switch (gd->bus_clk) { | |
121 | case 60000000: | |
122 | pi2cReg->fdr = 0x15; | |
123 | break; | |
124 | case 70000000: | |
125 | pi2cReg->fdr = 0x16; | |
126 | break; | |
127 | case 80000000: | |
128 | pi2cReg->fdr = 0x3a; | |
129 | break; | |
130 | case 90000000: | |
131 | pi2cReg->fdr = 0x17; | |
132 | break; | |
133 | case 100000000: | |
134 | pi2cReg->fdr = 0x3b; | |
135 | break; | |
136 | case 110000000: | |
137 | pi2cReg->fdr = 0x18; | |
138 | break; | |
139 | case 120000000: | |
140 | pi2cReg->fdr = 0x19; | |
141 | break; | |
142 | case 130000000: | |
143 | pi2cReg->fdr = 0x1a; | |
144 | break; | |
145 | } | |
146 | ||
6d0f6bcf | 147 | pi2cReg->adr = CONFIG_SYS_I2C_SLAVE<<1; |
983fda83 WD |
148 | |
149 | pi2cReg->cr = I2C_CTL_EN; /* Set Enable */ | |
150 | ||
151 | /* | |
152 | The I2C bus should be in Idle state. If the bus is busy, | |
153 | clear the STA bit in control register | |
154 | */ | |
155 | if (spd_status (pi2cReg, I2C_STA_BB, 0) != OK) { | |
156 | if ((pi2cReg->cr & I2C_CTL_STA) == I2C_CTL_STA) | |
157 | pi2cReg->cr &= ~I2C_CTL_STA; | |
158 | ||
159 | /* Check again if it is still busy, return error if found */ | |
160 | if (spd_status (pi2cReg, I2C_STA_BB, 1) == OK) | |
161 | return ERROR; | |
162 | } | |
163 | ||
164 | pi2cReg->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack */ | |
165 | pi2cReg->cr |= I2C_CTL_STA; /* Generate start signal */ | |
166 | ||
167 | if (spd_status (pi2cReg, I2C_STA_BB, 1) != OK) | |
168 | return ERROR; | |
169 | ||
170 | ||
171 | /* Write slave address */ | |
172 | pi2cReg->sr &= ~I2C_STA_IF; /* Clear Interrupt */ | |
173 | pi2cReg->dr = slvAdr; /* Write a byte */ | |
174 | ||
175 | if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) { /* Transfer not complete? */ | |
176 | spd_stop (pi2cReg); | |
177 | return ERROR; | |
178 | } | |
179 | ||
180 | if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) { | |
181 | spd_stop (pi2cReg); | |
182 | return ERROR; | |
183 | } | |
184 | ||
185 | ||
186 | /* Issue the offset to start */ | |
187 | pi2cReg->sr &= ~I2C_STA_IF; /* Clear Interrupt */ | |
188 | pi2cReg->dr = 0; /* Write a byte */ | |
189 | ||
190 | if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) { /* Transfer not complete? */ | |
191 | spd_stop (pi2cReg); | |
192 | return ERROR; | |
193 | } | |
194 | ||
195 | if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) { | |
196 | spd_stop (pi2cReg); | |
197 | return ERROR; | |
198 | } | |
199 | ||
200 | ||
201 | /* Set repeat start */ | |
202 | pi2cReg->cr |= I2C_CTL_RSTA; /* Repeat Start */ | |
203 | ||
204 | pi2cReg->sr &= ~I2C_STA_IF; /* Clear Interrupt */ | |
205 | pi2cReg->dr = slvAdr | 1; /* Write a byte */ | |
206 | ||
207 | if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) { /* Transfer not complete? */ | |
208 | spd_stop (pi2cReg); | |
209 | return ERROR; | |
210 | } | |
211 | ||
212 | if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) { | |
213 | spd_stop (pi2cReg); | |
214 | return ERROR; | |
215 | } | |
216 | ||
217 | if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01)) | |
218 | return ERROR; | |
219 | ||
220 | pi2cReg->cr &= ~I2C_CTL_TX; /* Set receive mode */ | |
221 | ||
222 | if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01)) | |
223 | return ERROR; | |
224 | ||
225 | /* Dummy Read */ | |
226 | if (spd_readbyte (pi2cReg, &Tmp, &i) != OK) { | |
227 | spd_stop (pi2cReg); | |
228 | return ERROR; | |
229 | } | |
230 | ||
231 | i = 0; | |
232 | while (Length) { | |
233 | if (Length == 2) | |
234 | pi2cReg->cr |= I2C_CTL_TXAK; | |
235 | ||
236 | if (Length == 1) | |
237 | pi2cReg->cr &= ~I2C_CTL_STA; | |
238 | ||
239 | if (spd_readbyte (pi2cReg, spdData, &Length) != OK) { | |
240 | return spd_stop (pi2cReg); | |
241 | } | |
242 | i++; | |
243 | Length--; | |
244 | spdData++; | |
245 | } | |
246 | ||
247 | /* Stop the service */ | |
248 | spd_stop (pi2cReg); | |
249 | ||
250 | return OK; | |
251 | } | |
252 | ||
253 | int getBankInfo (int bank, draminfo_t * pBank) | |
254 | { | |
255 | int status; | |
256 | int checksum; | |
257 | int count; | |
258 | u8 spdData[SPD_SIZE]; | |
259 | ||
260 | ||
261 | if (bank > 2 || pBank == 0) { | |
262 | /* illegal values */ | |
263 | return (-42); | |
264 | } | |
265 | ||
266 | status = readSpdData (&spdData[0]); | |
267 | if (status < 0) | |
268 | return (-1); | |
269 | ||
270 | /* check the checksum */ | |
271 | for (count = 0, checksum = 0; count < LOC_CHECKSUM; count++) | |
272 | checksum += spdData[count]; | |
273 | ||
274 | checksum = checksum - ((checksum / 256) * 256); | |
275 | ||
276 | if (checksum != spdData[LOC_CHECKSUM]) | |
277 | return (-2); | |
278 | ||
279 | /* Get the memory type */ | |
280 | if (! | |
281 | ((spdData[LOC_TYPE] == TYPE_DDR) | |
282 | || (spdData[LOC_TYPE] == TYPE_SDR))) | |
283 | /* not one of the types we support */ | |
284 | return (-3); | |
285 | ||
286 | pBank->type = spdData[LOC_TYPE]; | |
287 | ||
288 | /* Set logical banks */ | |
289 | pBank->banks = spdData[LOC_LOGICAL_BANKS]; | |
290 | ||
291 | /* Check that we have enough physical banks to cover the bank we are | |
292 | * figuring out. Odd-numbered banks correspond to the second bank | |
293 | * on the device. | |
294 | */ | |
295 | if (bank & 1) { | |
296 | /* Second bank of a "device" */ | |
297 | if (spdData[LOC_PHYS_BANKS] < 2) | |
298 | /* this bank doesn't exist on the "device" */ | |
299 | return (-4); | |
300 | ||
301 | if (spdData[LOC_ROWS] & 0xf0) | |
302 | /* Two asymmetric banks */ | |
303 | pBank->rows = spdData[LOC_ROWS] >> 4; | |
304 | else | |
305 | pBank->rows = spdData[LOC_ROWS]; | |
306 | ||
307 | if (spdData[LOC_COLS] & 0xf0) | |
308 | /* Two asymmetric banks */ | |
309 | pBank->cols = spdData[LOC_COLS] >> 4; | |
310 | else | |
311 | pBank->cols = spdData[LOC_COLS]; | |
312 | } else { | |
313 | /* First bank of a "device" */ | |
314 | pBank->rows = spdData[LOC_ROWS]; | |
315 | pBank->cols = spdData[LOC_COLS]; | |
316 | } | |
317 | ||
318 | pBank->width = spdData[LOC_WIDTH_HIGH] << 8 | spdData[LOC_WIDTH_LOW]; | |
319 | pBank->bursts = spdData[LOC_BURSTS]; | |
320 | pBank->CAS = spdData[LOC_CAS]; | |
321 | pBank->CS = spdData[LOC_CS]; | |
322 | pBank->WE = spdData[LOC_WE]; | |
323 | pBank->Trp = spdData[LOC_Trp]; | |
324 | pBank->Trcd = spdData[LOC_Trcd]; | |
325 | pBank->buffered = spdData[LOC_Buffered] & 1; | |
326 | pBank->refresh = spdData[LOC_REFRESH]; | |
327 | ||
328 | return (0); | |
329 | } | |
330 | ||
331 | ||
332 | /* checkMuxSetting -- given a row/column device geometry, return a mask | |
333 | * of the valid DRAM controller addr_mux settings for | |
334 | * that geometry. | |
335 | * | |
336 | * Arguments: u8 rows: number of row addresses in this device | |
337 | * u8 columns: number of column addresses in this device | |
338 | * | |
339 | * Returns: a mask of the allowed addr_mux settings for this | |
340 | * geometry. Each bit in the mask represents a | |
341 | * possible addr_mux settings (for example, the | |
342 | * (1<<2) bit in the mask represents the 0b10 setting)/ | |
343 | * | |
344 | */ | |
345 | u8 checkMuxSetting (u8 rows, u8 columns) | |
346 | { | |
347 | muxdesc_t *pIdx, *pMux; | |
348 | u8 mask; | |
349 | int lrows, lcolumns; | |
350 | u32 mux[4] = { 0x00080c04, 0x01080d03, 0x02080e02, 0xffffffff }; | |
351 | ||
352 | /* Setup MuxDescriptor in SRAM space */ | |
353 | /* MUXDESC AddressRuns [] = { | |
354 | { 0, 8, 12, 4 }, / setting, columns, rows, extra columns / | |
355 | { 1, 8, 13, 3 }, / setting, columns, rows, extra columns / | |
356 | { 2, 8, 14, 2 }, / setting, columns, rows, extra columns / | |
357 | { 0xff } / list terminator / | |
358 | }; */ | |
359 | ||
360 | pIdx = (muxdesc_t *) & mux[0]; | |
361 | ||
362 | /* Check rows x columns against each possible address mux setting */ | |
363 | for (pMux = pIdx, mask = 0;; pMux++) { | |
364 | lrows = rows; | |
365 | lcolumns = columns; | |
366 | ||
367 | if (pMux->MuxValue == 0xff) | |
368 | break; /* end of list */ | |
369 | ||
370 | /* For a given mux setting, since we want all the memory in a | |
371 | * device to be contiguous, we want the device "use up" the | |
372 | * address lines such that there are no extra column or row | |
373 | * address lines on the device. | |
374 | */ | |
375 | ||
376 | lcolumns -= pMux->Columns; | |
377 | if (lcolumns < 0) | |
378 | /* Not enough columns to get to the rows */ | |
379 | continue; | |
380 | ||
381 | lrows -= pMux->Rows; | |
382 | if (lrows > 0) | |
383 | /* we have extra rows left -- can't do that! */ | |
384 | continue; | |
385 | ||
386 | /* At this point, we either have to have used up all the | |
387 | * rows or we have to have no columns left. | |
388 | */ | |
389 | ||
390 | if (lcolumns != 0 && lrows != 0) | |
391 | /* rows AND columns are left. Bad! */ | |
392 | continue; | |
393 | ||
394 | lcolumns -= pMux->MoreColumns; | |
395 | ||
396 | if (lcolumns <= 0) | |
397 | mask |= (1 << pMux->MuxValue); | |
398 | } | |
399 | ||
400 | return (mask); | |
401 | } | |
402 | ||
403 | ||
404 | u32 dramSetup (void) | |
405 | { | |
983fda83 WD |
406 | draminfo_t DramInfo[TOTAL_BANK]; |
407 | draminfo_t *pDramInfo; | |
408 | u32 size, temp, cfg_value, mode_value, refresh; | |
409 | u8 *ptr; | |
410 | u8 bursts, Trp, Trcd, type, buffered; | |
411 | u8 muxmask, rows, columns; | |
412 | int count, banknum; | |
413 | u32 *prefresh, *pIdx; | |
414 | u32 refrate[8] = { 15625, 3900, 7800, 31300, | |
415 | 62500, 125000, 0xffffffff, 0xffffffff | |
416 | }; | |
417 | volatile sysconf8220_t *sysconf; | |
418 | volatile memctl8220_t *memctl; | |
419 | ||
420 | sysconf = (volatile sysconf8220_t *) MMAP_MBAR; | |
421 | memctl = (volatile memctl8220_t *) MMAP_MEMCTL; | |
422 | ||
423 | /* Set everything in the descriptions to zero */ | |
424 | ptr = (u8 *) & DramInfo[0]; | |
425 | for (count = 0; count < sizeof (DramInfo); count++) | |
426 | *ptr++ = 0; | |
427 | ||
428 | for (banknum = 0; banknum < TOTAL_BANK; banknum++) | |
429 | sysconf->cscfg[banknum]; | |
430 | ||
431 | /* Descriptions of row/column address muxing for various | |
432 | * addr_mux settings. | |
433 | */ | |
434 | ||
435 | pIdx = prefresh = (u32 *) & refrate[0]; | |
436 | ||
437 | /* Get all the info for all three logical banks */ | |
438 | bursts = 0xff; | |
439 | Trp = 0; | |
440 | Trcd = 0; | |
441 | type = 0; | |
442 | buffered = 0xff; | |
443 | refresh = 0xffffffff; | |
444 | muxmask = 0xff; | |
445 | ||
446 | /* Two bank, CS0 and CS1 */ | |
447 | for (banknum = 0, pDramInfo = &DramInfo[0]; | |
448 | banknum < TOTAL_BANK; banknum++, pDramInfo++) { | |
449 | pDramInfo->ordinal = banknum; /* initial sorting */ | |
450 | if (getBankInfo (banknum, pDramInfo) < 0) | |
451 | continue; | |
452 | ||
453 | /* get cumulative parameters of all three banks */ | |
454 | if (type && pDramInfo->type != type) | |
455 | return 0; | |
456 | ||
457 | type = pDramInfo->type; | |
458 | rows = pDramInfo->rows; | |
459 | columns = pDramInfo->cols; | |
460 | ||
461 | /* This chip only supports 13 DRAM memory lines, but some devices | |
462 | * have 14 rows. To deal with this, ignore the 14th address line | |
463 | * by limiting the number of rows (and columns) to 13. This will | |
464 | * mean that for 14-row devices we will only be able to use | |
465 | * half of the memory, but it's better than nothing. | |
466 | */ | |
467 | if (rows > 13) | |
468 | rows = 13; | |
469 | if (columns > 13) | |
470 | columns = 13; | |
471 | ||
472 | pDramInfo->size = | |
473 | ((1 << (rows + columns)) * pDramInfo->width); | |
474 | pDramInfo->size *= pDramInfo->banks; | |
475 | pDramInfo->size >>= 3; | |
476 | ||
477 | /* figure out which addr_mux configurations will support this device */ | |
478 | muxmask &= checkMuxSetting (rows, columns); | |
479 | if (muxmask == 0) | |
480 | return 0; | |
481 | ||
482 | buffered = pDramInfo->buffered; | |
483 | bursts &= pDramInfo->bursts; /* union of all bursts */ | |
484 | if (pDramInfo->Trp > Trp) /* worst case (longest) Trp */ | |
485 | Trp = pDramInfo->Trp; | |
486 | ||
487 | if (pDramInfo->Trcd > Trcd) /* worst case (longest) Trcd */ | |
488 | Trcd = pDramInfo->Trcd; | |
489 | ||
490 | prefresh = pIdx; | |
491 | /* worst case (shortest) Refresh period */ | |
492 | if (refresh > prefresh[pDramInfo->refresh & 7]) | |
493 | refresh = prefresh[pDramInfo->refresh & 7]; | |
494 | ||
495 | } /* for loop */ | |
496 | ||
497 | ||
498 | /* We only allow a burst length of 8! */ | |
499 | if (!(bursts & 8)) | |
500 | bursts = 8; | |
501 | ||
502 | /* Sort the devices. In order to get each chip select region | |
503 | * aligned properly, put the biggest device at the lowest address. | |
504 | * A simple bubble sort will do the trick. | |
505 | */ | |
506 | for (banknum = 0, pDramInfo = &DramInfo[0]; | |
507 | banknum < TOTAL_BANK; banknum++, pDramInfo++) { | |
508 | int i; | |
509 | ||
510 | for (i = 0; i < TOTAL_BANK; i++) { | |
511 | if (pDramInfo->size < DramInfo[i].size && | |
512 | pDramInfo->ordinal < DramInfo[i].ordinal) { | |
513 | /* If the current bank is smaller, but if the ordinal is also | |
514 | * smaller, swap the ordinals | |
515 | */ | |
516 | u8 temp8; | |
517 | ||
518 | temp8 = DramInfo[i].ordinal; | |
519 | DramInfo[i].ordinal = pDramInfo->ordinal; | |
520 | pDramInfo->ordinal = temp8; | |
521 | } | |
522 | } | |
523 | } | |
524 | ||
525 | ||
526 | /* Now figure out the base address for each bank. While | |
527 | * we're at it, figure out how much memory there is. | |
528 | * | |
529 | */ | |
530 | size = 0; | |
531 | for (banknum = 0; banknum < TOTAL_BANK; banknum++) { | |
532 | int i; | |
533 | ||
534 | for (i = 0; i < TOTAL_BANK; i++) { | |
535 | if (DramInfo[i].ordinal == banknum | |
536 | && DramInfo[i].size != 0) { | |
537 | DramInfo[i].base = size; | |
538 | size += DramInfo[i].size; | |
539 | } | |
540 | } | |
541 | } | |
542 | ||
543 | /* Set up the Drive Strength register */ | |
6d0f6bcf | 544 | sysconf->sdramds = CONFIG_SYS_SDRAM_DRIVE_STRENGTH; |
983fda83 WD |
545 | |
546 | /* ********************** Cfg 1 ************************* */ | |
547 | ||
548 | /* Set the single read to read/write/precharge delay */ | |
549 | cfg_value = CFG1_SRD2RWP ((type == TYPE_DDR) ? 7 : 0xb); | |
550 | ||
551 | /* Set the single write to read/write/precharge delay. | |
552 | * This may or may not be correct. The controller spec | |
553 | * says "tWR", but "tWR" does not appear in the SPD. It | |
554 | * always seems to be 15nsec for the class of device we're | |
555 | * using, which turns out to be 2 clock cycles at 133MHz, | |
556 | * so that's what we're going to use. | |
557 | * | |
558 | * HOWEVER, because of a bug in the controller, for DDR | |
559 | * we need to set this to be the same as the value | |
560 | * calculated for bwt2rwp. | |
561 | */ | |
562 | cfg_value |= CFG1_SWT2RWP ((type == TYPE_DDR) ? 7 : 2); | |
563 | ||
564 | /* Set the Read CAS latency. We're going to use a CL of | |
12b43d51 | 565 | * 2.5 for DDR and 2 SDR. |
983fda83 WD |
566 | */ |
567 | cfg_value |= CFG1_RLATENCY ((type == TYPE_DDR) ? 7 : 2); | |
568 | ||
569 | ||
570 | /* Set the Active to Read/Write delay. This depends | |
571 | * on Trcd which is reported as nanoseconds times 4. | |
572 | * We want to calculate Trcd (in nanoseconds) times XLB clock (in Hz) | |
573 | * which gives us a dimensionless quantity. Play games with | |
574 | * the divisions so we don't run out of dynamic ranges. | |
575 | */ | |
576 | /* account for megaherz and the times 4 */ | |
577 | temp = (Trcd * (gd->bus_clk / 1000000)) / 4; | |
578 | ||
579 | /* account for nanoseconds and round up, with a minimum value of 2 */ | |
580 | temp = ((temp + 999) / 1000) - 1; | |
581 | if (temp < 2) | |
582 | temp = 2; | |
583 | ||
584 | cfg_value |= CFG1_ACT2WR (temp); | |
585 | ||
586 | /* Set the precharge to active delay. This depends | |
587 | * on Trp which is reported as nanoseconds times 4. | |
588 | * We want to calculate Trp (in nanoseconds) times XLB clock (in Hz) | |
589 | * which gives us a dimensionless quantity. Play games with | |
590 | * the divisions so we don't run out of dynamic ranges. | |
591 | */ | |
592 | /* account for megaherz and the times 4 */ | |
593 | temp = (Trp * (gd->bus_clk / 1000000)) / 4; | |
594 | ||
595 | /* account for nanoseconds and round up, then subtract 1, with a | |
596 | * minumum value of 1 and a maximum value of 7. | |
597 | */ | |
598 | temp = (((temp + 999) / 1000) - 1) & 7; | |
599 | if (temp < 1) | |
600 | temp = 1; | |
601 | ||
602 | cfg_value |= CFG1_PRE2ACT (temp); | |
603 | ||
604 | /* Set refresh to active delay. This depends | |
605 | * on Trfc which is not reported in the SPD. | |
606 | * We'll use a nominal value of 75nsec which is | |
607 | * what the controller spec uses. | |
608 | */ | |
609 | temp = (75 * (gd->bus_clk / 1000000)); | |
610 | /* account for nanoseconds and round up, then subtract 1 */ | |
611 | cfg_value |= CFG1_REF2ACT (((temp + 999) / 1000) - 1); | |
612 | ||
613 | /* Set the write latency, using the values given in the controller spec */ | |
614 | cfg_value |= CFG1_WLATENCY ((type == TYPE_DDR) ? 3 : 0); | |
615 | memctl->cfg1 = cfg_value; /* cfg 1 */ | |
616 | asm volatile ("sync"); | |
617 | ||
618 | ||
619 | /* ********************** Cfg 2 ************************* */ | |
620 | ||
621 | /* Set the burst read to read/precharge delay */ | |
622 | cfg_value = CFG2_BRD2RP ((type == TYPE_DDR) ? 5 : 8); | |
623 | ||
624 | /* Set the burst write to read/precharge delay. Semi-magic numbers | |
625 | * based on the controller spec recommendations, assuming tWR is | |
626 | * two clock cycles. | |
627 | */ | |
628 | cfg_value |= CFG2_BWT2RWP ((type == TYPE_DDR) ? 7 : 10); | |
629 | ||
630 | /* Set the Burst read to write delay. Semi-magic numbers | |
631 | * based on the DRAM controller documentation. | |
632 | */ | |
633 | cfg_value |= CFG2_BRD2WT ((type == TYPE_DDR) ? 7 : 0xb); | |
634 | ||
635 | /* Set the burst length -- must be 8!! Well, 7, actually, becuase | |
636 | * it's burst lenght minus 1. | |
637 | */ | |
638 | cfg_value |= CFG2_BURSTLEN (7); | |
639 | memctl->cfg2 = cfg_value; /* cfg 2 */ | |
640 | asm volatile ("sync"); | |
641 | ||
642 | ||
643 | /* ********************** mode ************************* */ | |
644 | ||
645 | /* Set enable bit, CKE high/low bits, and the DDR/SDR mode bit, | |
646 | * disable automatic refresh. | |
647 | */ | |
648 | cfg_value = CTL_MODE_ENABLE | CTL_CKE_HIGH | | |
649 | ((type == TYPE_DDR) ? CTL_DDR_MODE : 0); | |
650 | ||
651 | /* Set the address mux based on whichever setting(s) is/are common | |
652 | * to all the devices we have. If there is more than one, choose | |
653 | * one arbitrarily. | |
654 | */ | |
655 | if (muxmask & 0x4) | |
656 | cfg_value |= CTL_ADDRMUX (2); | |
657 | else if (muxmask & 0x2) | |
658 | cfg_value |= CTL_ADDRMUX (1); | |
659 | else | |
660 | cfg_value |= CTL_ADDRMUX (0); | |
661 | ||
662 | /* Set the refresh interval. */ | |
663 | temp = ((refresh * (gd->bus_clk / 1000000)) / (1000 * 64)) - 1; | |
664 | cfg_value |= CTL_REFRESH_INTERVAL (temp); | |
665 | ||
666 | /* Set buffered/non-buffered memory */ | |
667 | if (buffered) | |
668 | cfg_value |= CTL_BUFFERED; | |
669 | ||
670 | memctl->ctrl = cfg_value; /* ctrl */ | |
671 | asm volatile ("sync"); | |
672 | ||
673 | if (type == TYPE_DDR) { | |
674 | /* issue precharge all */ | |
675 | temp = cfg_value | CTL_PRECHARGE_CMD; | |
676 | memctl->ctrl = temp; /* ctrl */ | |
677 | asm volatile ("sync"); | |
678 | } | |
679 | ||
680 | ||
12b43d51 | 681 | /* Set up mode value for CAS latency */ |
6d0f6bcf | 682 | #if (CONFIG_SYS_SDRAM_CAS_LATENCY==5) /* CL=2.5 */ |
12b43d51 WD |
683 | mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) | |
684 | MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2p5) | MODE_CMD); | |
685 | #else | |
983fda83 WD |
686 | mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) | |
687 | MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2) | MODE_CMD); | |
12b43d51 | 688 | #endif |
983fda83 WD |
689 | asm volatile ("sync"); |
690 | ||
691 | /* Write Extended Mode - enable DLL */ | |
692 | if (type == TYPE_DDR) { | |
693 | temp = MODE_EXTENDED | MODE_X_DLL_ENABLE | | |
694 | MODE_X_DS_NORMAL | MODE_CMD; | |
695 | memctl->mode = (temp >> 16); /* mode */ | |
696 | asm volatile ("sync"); | |
697 | ||
12b43d51 | 698 | /* Write Mode - reset DLL, set CAS latency */ |
983fda83 WD |
699 | temp = mode_value | MODE_OPMODE (MODE_OPMODE_RESETDLL); |
700 | memctl->mode = (temp >> 16); /* mode */ | |
701 | asm volatile ("sync"); | |
702 | } | |
703 | ||
704 | /* Program the chip selects. */ | |
705 | for (banknum = 0; banknum < TOTAL_BANK; banknum++) { | |
706 | if (DramInfo[banknum].size != 0) { | |
707 | u32 mask; | |
708 | int i; | |
709 | ||
710 | for (i = 0, mask = 1; i < 32; mask <<= 1, i++) { | |
711 | if (DramInfo[banknum].size & mask) | |
712 | break; | |
713 | } | |
714 | temp = (DramInfo[banknum].base & 0xfff00000) | (i - | |
715 | 1); | |
716 | ||
717 | sysconf->cscfg[banknum] = temp; | |
718 | asm volatile ("sync"); | |
719 | } | |
720 | } | |
721 | ||
722 | /* Wait for DLL lock */ | |
723 | udelay (200); | |
724 | ||
725 | temp = cfg_value | CTL_PRECHARGE_CMD; /* issue precharge all */ | |
726 | memctl->ctrl = temp; /* ctrl */ | |
727 | asm volatile ("sync"); | |
728 | ||
729 | temp = cfg_value | CTL_REFRESH_CMD; /* issue precharge all */ | |
730 | memctl->ctrl = temp; /* ctrl */ | |
731 | asm volatile ("sync"); | |
732 | ||
733 | memctl->ctrl = temp; /* ctrl */ | |
734 | asm volatile ("sync"); | |
735 | ||
736 | /* Write Mode - DLL normal */ | |
737 | temp = mode_value | MODE_OPMODE (MODE_OPMODE_NORMAL); | |
738 | memctl->mode = (temp >> 16); /* mode */ | |
739 | asm volatile ("sync"); | |
740 | ||
741 | /* Enable refresh, enable DQS's (if DDR), and lock the control register */ | |
742 | cfg_value &= ~CTL_MODE_ENABLE; /* lock register */ | |
743 | cfg_value |= CTL_REFRESH_ENABLE; /* enable refresh */ | |
744 | ||
745 | if (type == TYPE_DDR) | |
746 | cfg_value |= CTL_DQSOEN (0xf); /* enable DQS's for DDR */ | |
747 | ||
748 | memctl->ctrl = cfg_value; /* ctrl */ | |
749 | asm volatile ("sync"); | |
750 | ||
751 | return size; | |
752 | } |