]>
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 | ||
12b43d51 WD |
35 | #define SPD_SIZE CFG_SDRAM_SPD_SIZE |
36 | #define DRAM_SPD (CFG_SDRAM_SPD_I2C_ADDR)<<1 /* on Board SPD eeprom */ | |
37 | #define TOTAL_BANK CFG_SDRAM_TOTAL_BANKS | |
983fda83 WD |
38 | |
39 | int spd_status (volatile i2c8220_t * pi2c, u8 sta_bit, u8 truefalse) | |
40 | { | |
41 | int i; | |
42 | ||
43 | for (i = 0; i < I2C_POLL_COUNT; i++) { | |
44 | if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0)) | |
45 | return (OK); | |
46 | } | |
47 | ||
48 | return (ERROR); | |
49 | } | |
50 | ||
51 | int spd_clear (volatile i2c8220_t * pi2c) | |
52 | { | |
53 | pi2c->adr = 0; | |
54 | pi2c->fdr = 0; | |
55 | pi2c->cr = 0; | |
56 | pi2c->sr = 0; | |
57 | ||
58 | return (OK); | |
59 | } | |
60 | ||
61 | int spd_stop (volatile i2c8220_t * pi2c) | |
62 | { | |
63 | pi2c->cr &= ~I2C_CTL_STA; /* Generate stop signal */ | |
64 | if (spd_status (pi2c, I2C_STA_BB, 0) != OK) | |
65 | return ERROR; | |
66 | ||
67 | return (OK); | |
68 | } | |
69 | ||
70 | int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index) | |
71 | { | |
72 | pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt Bit */ | |
73 | *readb = pi2c->dr; /* Read a byte */ | |
74 | ||
75 | /* | |
76 | Set I2C_CTRL_TXAK will cause Transfer pending and | |
77 | set I2C_CTRL_STA will cause Interrupt pending | |
78 | */ | |
79 | if (*index != 2) { | |
80 | if (spd_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ | |
81 | return ERROR; | |
82 | } | |
83 | ||
84 | if (*index != 1) { | |
85 | if (spd_status (pi2c, I2C_STA_IF, 1) != OK) | |
86 | return ERROR; | |
87 | } | |
88 | ||
89 | return (OK); | |
90 | } | |
91 | ||
92 | int readSpdData (u8 * spdData) | |
93 | { | |
94 | DECLARE_GLOBAL_DATA_PTR; | |
95 | ||
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"); | |
106 | pcfg->pcfg3 &= ~CFG_I2C_PORT3_CONFIG; | |
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 | ||
12b43d51 | 147 | pi2cReg->adr = CFG_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 | { | |
406 | DECLARE_GLOBAL_DATA_PTR; | |
407 | ||
408 | draminfo_t DramInfo[TOTAL_BANK]; | |
409 | draminfo_t *pDramInfo; | |
410 | u32 size, temp, cfg_value, mode_value, refresh; | |
411 | u8 *ptr; | |
412 | u8 bursts, Trp, Trcd, type, buffered; | |
413 | u8 muxmask, rows, columns; | |
414 | int count, banknum; | |
415 | u32 *prefresh, *pIdx; | |
416 | u32 refrate[8] = { 15625, 3900, 7800, 31300, | |
417 | 62500, 125000, 0xffffffff, 0xffffffff | |
418 | }; | |
419 | volatile sysconf8220_t *sysconf; | |
420 | volatile memctl8220_t *memctl; | |
421 | ||
422 | sysconf = (volatile sysconf8220_t *) MMAP_MBAR; | |
423 | memctl = (volatile memctl8220_t *) MMAP_MEMCTL; | |
424 | ||
425 | /* Set everything in the descriptions to zero */ | |
426 | ptr = (u8 *) & DramInfo[0]; | |
427 | for (count = 0; count < sizeof (DramInfo); count++) | |
428 | *ptr++ = 0; | |
429 | ||
430 | for (banknum = 0; banknum < TOTAL_BANK; banknum++) | |
431 | sysconf->cscfg[banknum]; | |
432 | ||
433 | /* Descriptions of row/column address muxing for various | |
434 | * addr_mux settings. | |
435 | */ | |
436 | ||
437 | pIdx = prefresh = (u32 *) & refrate[0]; | |
438 | ||
439 | /* Get all the info for all three logical banks */ | |
440 | bursts = 0xff; | |
441 | Trp = 0; | |
442 | Trcd = 0; | |
443 | type = 0; | |
444 | buffered = 0xff; | |
445 | refresh = 0xffffffff; | |
446 | muxmask = 0xff; | |
447 | ||
448 | /* Two bank, CS0 and CS1 */ | |
449 | for (banknum = 0, pDramInfo = &DramInfo[0]; | |
450 | banknum < TOTAL_BANK; banknum++, pDramInfo++) { | |
451 | pDramInfo->ordinal = banknum; /* initial sorting */ | |
452 | if (getBankInfo (banknum, pDramInfo) < 0) | |
453 | continue; | |
454 | ||
455 | /* get cumulative parameters of all three banks */ | |
456 | if (type && pDramInfo->type != type) | |
457 | return 0; | |
458 | ||
459 | type = pDramInfo->type; | |
460 | rows = pDramInfo->rows; | |
461 | columns = pDramInfo->cols; | |
462 | ||
463 | /* This chip only supports 13 DRAM memory lines, but some devices | |
464 | * have 14 rows. To deal with this, ignore the 14th address line | |
465 | * by limiting the number of rows (and columns) to 13. This will | |
466 | * mean that for 14-row devices we will only be able to use | |
467 | * half of the memory, but it's better than nothing. | |
468 | */ | |
469 | if (rows > 13) | |
470 | rows = 13; | |
471 | if (columns > 13) | |
472 | columns = 13; | |
473 | ||
474 | pDramInfo->size = | |
475 | ((1 << (rows + columns)) * pDramInfo->width); | |
476 | pDramInfo->size *= pDramInfo->banks; | |
477 | pDramInfo->size >>= 3; | |
478 | ||
479 | /* figure out which addr_mux configurations will support this device */ | |
480 | muxmask &= checkMuxSetting (rows, columns); | |
481 | if (muxmask == 0) | |
482 | return 0; | |
483 | ||
484 | buffered = pDramInfo->buffered; | |
485 | bursts &= pDramInfo->bursts; /* union of all bursts */ | |
486 | if (pDramInfo->Trp > Trp) /* worst case (longest) Trp */ | |
487 | Trp = pDramInfo->Trp; | |
488 | ||
489 | if (pDramInfo->Trcd > Trcd) /* worst case (longest) Trcd */ | |
490 | Trcd = pDramInfo->Trcd; | |
491 | ||
492 | prefresh = pIdx; | |
493 | /* worst case (shortest) Refresh period */ | |
494 | if (refresh > prefresh[pDramInfo->refresh & 7]) | |
495 | refresh = prefresh[pDramInfo->refresh & 7]; | |
496 | ||
497 | } /* for loop */ | |
498 | ||
499 | ||
500 | /* We only allow a burst length of 8! */ | |
501 | if (!(bursts & 8)) | |
502 | bursts = 8; | |
503 | ||
504 | /* Sort the devices. In order to get each chip select region | |
505 | * aligned properly, put the biggest device at the lowest address. | |
506 | * A simple bubble sort will do the trick. | |
507 | */ | |
508 | for (banknum = 0, pDramInfo = &DramInfo[0]; | |
509 | banknum < TOTAL_BANK; banknum++, pDramInfo++) { | |
510 | int i; | |
511 | ||
512 | for (i = 0; i < TOTAL_BANK; i++) { | |
513 | if (pDramInfo->size < DramInfo[i].size && | |
514 | pDramInfo->ordinal < DramInfo[i].ordinal) { | |
515 | /* If the current bank is smaller, but if the ordinal is also | |
516 | * smaller, swap the ordinals | |
517 | */ | |
518 | u8 temp8; | |
519 | ||
520 | temp8 = DramInfo[i].ordinal; | |
521 | DramInfo[i].ordinal = pDramInfo->ordinal; | |
522 | pDramInfo->ordinal = temp8; | |
523 | } | |
524 | } | |
525 | } | |
526 | ||
527 | ||
528 | /* Now figure out the base address for each bank. While | |
529 | * we're at it, figure out how much memory there is. | |
530 | * | |
531 | */ | |
532 | size = 0; | |
533 | for (banknum = 0; banknum < TOTAL_BANK; banknum++) { | |
534 | int i; | |
535 | ||
536 | for (i = 0; i < TOTAL_BANK; i++) { | |
537 | if (DramInfo[i].ordinal == banknum | |
538 | && DramInfo[i].size != 0) { | |
539 | DramInfo[i].base = size; | |
540 | size += DramInfo[i].size; | |
541 | } | |
542 | } | |
543 | } | |
544 | ||
545 | /* Set up the Drive Strength register */ | |
7680c140 | 546 | sysconf->sdramds = CFG_SDRAM_DRIVE_STRENGTH; |
983fda83 WD |
547 | |
548 | /* ********************** Cfg 1 ************************* */ | |
549 | ||
550 | /* Set the single read to read/write/precharge delay */ | |
551 | cfg_value = CFG1_SRD2RWP ((type == TYPE_DDR) ? 7 : 0xb); | |
552 | ||
553 | /* Set the single write to read/write/precharge delay. | |
554 | * This may or may not be correct. The controller spec | |
555 | * says "tWR", but "tWR" does not appear in the SPD. It | |
556 | * always seems to be 15nsec for the class of device we're | |
557 | * using, which turns out to be 2 clock cycles at 133MHz, | |
558 | * so that's what we're going to use. | |
559 | * | |
560 | * HOWEVER, because of a bug in the controller, for DDR | |
561 | * we need to set this to be the same as the value | |
562 | * calculated for bwt2rwp. | |
563 | */ | |
564 | cfg_value |= CFG1_SWT2RWP ((type == TYPE_DDR) ? 7 : 2); | |
565 | ||
566 | /* Set the Read CAS latency. We're going to use a CL of | |
12b43d51 | 567 | * 2.5 for DDR and 2 SDR. |
983fda83 WD |
568 | */ |
569 | cfg_value |= CFG1_RLATENCY ((type == TYPE_DDR) ? 7 : 2); | |
570 | ||
571 | ||
572 | /* Set the Active to Read/Write delay. This depends | |
573 | * on Trcd which is reported as nanoseconds times 4. | |
574 | * We want to calculate Trcd (in nanoseconds) times XLB clock (in Hz) | |
575 | * which gives us a dimensionless quantity. Play games with | |
576 | * the divisions so we don't run out of dynamic ranges. | |
577 | */ | |
578 | /* account for megaherz and the times 4 */ | |
579 | temp = (Trcd * (gd->bus_clk / 1000000)) / 4; | |
580 | ||
581 | /* account for nanoseconds and round up, with a minimum value of 2 */ | |
582 | temp = ((temp + 999) / 1000) - 1; | |
583 | if (temp < 2) | |
584 | temp = 2; | |
585 | ||
586 | cfg_value |= CFG1_ACT2WR (temp); | |
587 | ||
588 | /* Set the precharge to active delay. This depends | |
589 | * on Trp which is reported as nanoseconds times 4. | |
590 | * We want to calculate Trp (in nanoseconds) times XLB clock (in Hz) | |
591 | * which gives us a dimensionless quantity. Play games with | |
592 | * the divisions so we don't run out of dynamic ranges. | |
593 | */ | |
594 | /* account for megaherz and the times 4 */ | |
595 | temp = (Trp * (gd->bus_clk / 1000000)) / 4; | |
596 | ||
597 | /* account for nanoseconds and round up, then subtract 1, with a | |
598 | * minumum value of 1 and a maximum value of 7. | |
599 | */ | |
600 | temp = (((temp + 999) / 1000) - 1) & 7; | |
601 | if (temp < 1) | |
602 | temp = 1; | |
603 | ||
604 | cfg_value |= CFG1_PRE2ACT (temp); | |
605 | ||
606 | /* Set refresh to active delay. This depends | |
607 | * on Trfc which is not reported in the SPD. | |
608 | * We'll use a nominal value of 75nsec which is | |
609 | * what the controller spec uses. | |
610 | */ | |
611 | temp = (75 * (gd->bus_clk / 1000000)); | |
612 | /* account for nanoseconds and round up, then subtract 1 */ | |
613 | cfg_value |= CFG1_REF2ACT (((temp + 999) / 1000) - 1); | |
614 | ||
615 | /* Set the write latency, using the values given in the controller spec */ | |
616 | cfg_value |= CFG1_WLATENCY ((type == TYPE_DDR) ? 3 : 0); | |
617 | memctl->cfg1 = cfg_value; /* cfg 1 */ | |
618 | asm volatile ("sync"); | |
619 | ||
620 | ||
621 | /* ********************** Cfg 2 ************************* */ | |
622 | ||
623 | /* Set the burst read to read/precharge delay */ | |
624 | cfg_value = CFG2_BRD2RP ((type == TYPE_DDR) ? 5 : 8); | |
625 | ||
626 | /* Set the burst write to read/precharge delay. Semi-magic numbers | |
627 | * based on the controller spec recommendations, assuming tWR is | |
628 | * two clock cycles. | |
629 | */ | |
630 | cfg_value |= CFG2_BWT2RWP ((type == TYPE_DDR) ? 7 : 10); | |
631 | ||
632 | /* Set the Burst read to write delay. Semi-magic numbers | |
633 | * based on the DRAM controller documentation. | |
634 | */ | |
635 | cfg_value |= CFG2_BRD2WT ((type == TYPE_DDR) ? 7 : 0xb); | |
636 | ||
637 | /* Set the burst length -- must be 8!! Well, 7, actually, becuase | |
638 | * it's burst lenght minus 1. | |
639 | */ | |
640 | cfg_value |= CFG2_BURSTLEN (7); | |
641 | memctl->cfg2 = cfg_value; /* cfg 2 */ | |
642 | asm volatile ("sync"); | |
643 | ||
644 | ||
645 | /* ********************** mode ************************* */ | |
646 | ||
647 | /* Set enable bit, CKE high/low bits, and the DDR/SDR mode bit, | |
648 | * disable automatic refresh. | |
649 | */ | |
650 | cfg_value = CTL_MODE_ENABLE | CTL_CKE_HIGH | | |
651 | ((type == TYPE_DDR) ? CTL_DDR_MODE : 0); | |
652 | ||
653 | /* Set the address mux based on whichever setting(s) is/are common | |
654 | * to all the devices we have. If there is more than one, choose | |
655 | * one arbitrarily. | |
656 | */ | |
657 | if (muxmask & 0x4) | |
658 | cfg_value |= CTL_ADDRMUX (2); | |
659 | else if (muxmask & 0x2) | |
660 | cfg_value |= CTL_ADDRMUX (1); | |
661 | else | |
662 | cfg_value |= CTL_ADDRMUX (0); | |
663 | ||
664 | /* Set the refresh interval. */ | |
665 | temp = ((refresh * (gd->bus_clk / 1000000)) / (1000 * 64)) - 1; | |
666 | cfg_value |= CTL_REFRESH_INTERVAL (temp); | |
667 | ||
668 | /* Set buffered/non-buffered memory */ | |
669 | if (buffered) | |
670 | cfg_value |= CTL_BUFFERED; | |
671 | ||
672 | memctl->ctrl = cfg_value; /* ctrl */ | |
673 | asm volatile ("sync"); | |
674 | ||
675 | if (type == TYPE_DDR) { | |
676 | /* issue precharge all */ | |
677 | temp = cfg_value | CTL_PRECHARGE_CMD; | |
678 | memctl->ctrl = temp; /* ctrl */ | |
679 | asm volatile ("sync"); | |
680 | } | |
681 | ||
682 | ||
12b43d51 WD |
683 | /* Set up mode value for CAS latency */ |
684 | #if (CFG_SDRAM_CAS_LATENCY==5) /* CL=2.5 */ | |
685 | mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) | | |
686 | MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2p5) | MODE_CMD); | |
687 | #else | |
983fda83 WD |
688 | mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) | |
689 | MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2) | MODE_CMD); | |
12b43d51 | 690 | #endif |
983fda83 WD |
691 | asm volatile ("sync"); |
692 | ||
693 | /* Write Extended Mode - enable DLL */ | |
694 | if (type == TYPE_DDR) { | |
695 | temp = MODE_EXTENDED | MODE_X_DLL_ENABLE | | |
696 | MODE_X_DS_NORMAL | MODE_CMD; | |
697 | memctl->mode = (temp >> 16); /* mode */ | |
698 | asm volatile ("sync"); | |
699 | ||
12b43d51 | 700 | /* Write Mode - reset DLL, set CAS latency */ |
983fda83 WD |
701 | temp = mode_value | MODE_OPMODE (MODE_OPMODE_RESETDLL); |
702 | memctl->mode = (temp >> 16); /* mode */ | |
703 | asm volatile ("sync"); | |
704 | } | |
705 | ||
706 | /* Program the chip selects. */ | |
707 | for (banknum = 0; banknum < TOTAL_BANK; banknum++) { | |
708 | if (DramInfo[banknum].size != 0) { | |
709 | u32 mask; | |
710 | int i; | |
711 | ||
712 | for (i = 0, mask = 1; i < 32; mask <<= 1, i++) { | |
713 | if (DramInfo[banknum].size & mask) | |
714 | break; | |
715 | } | |
716 | temp = (DramInfo[banknum].base & 0xfff00000) | (i - | |
717 | 1); | |
718 | ||
719 | sysconf->cscfg[banknum] = temp; | |
720 | asm volatile ("sync"); | |
721 | } | |
722 | } | |
723 | ||
724 | /* Wait for DLL lock */ | |
725 | udelay (200); | |
726 | ||
727 | temp = cfg_value | CTL_PRECHARGE_CMD; /* issue precharge all */ | |
728 | memctl->ctrl = temp; /* ctrl */ | |
729 | asm volatile ("sync"); | |
730 | ||
731 | temp = cfg_value | CTL_REFRESH_CMD; /* issue precharge all */ | |
732 | memctl->ctrl = temp; /* ctrl */ | |
733 | asm volatile ("sync"); | |
734 | ||
735 | memctl->ctrl = temp; /* ctrl */ | |
736 | asm volatile ("sync"); | |
737 | ||
738 | /* Write Mode - DLL normal */ | |
739 | temp = mode_value | MODE_OPMODE (MODE_OPMODE_NORMAL); | |
740 | memctl->mode = (temp >> 16); /* mode */ | |
741 | asm volatile ("sync"); | |
742 | ||
743 | /* Enable refresh, enable DQS's (if DDR), and lock the control register */ | |
744 | cfg_value &= ~CTL_MODE_ENABLE; /* lock register */ | |
745 | cfg_value |= CTL_REFRESH_ENABLE; /* enable refresh */ | |
746 | ||
747 | if (type == TYPE_DDR) | |
748 | cfg_value |= CTL_DQSOEN (0xf); /* enable DQS's for DDR */ | |
749 | ||
750 | memctl->ctrl = cfg_value; /* ctrl */ | |
751 | asm volatile ("sync"); | |
752 | ||
753 | return size; | |
754 | } |