svn mv src/northbridge/intel/E7520 src/northbridge/intel/e7520
[coreboot.git] / src / northbridge / intel / e7520 / raminit.c
1 #include <cpu/x86/mem.h>
2 #include <cpu/x86/mtrr.h>
3 #include <cpu/x86/cache.h>
4 #include "raminit.h"
5 #include "e7520.h"
6
7 #define BAR 0x40000000
8
9 static void sdram_set_registers(const struct mem_controller *ctrl)
10 {
11         static const unsigned int register_values[] = {
12
13                 /* CKDIS 0x8c disable clocks */
14         PCI_ADDR(0, 0x00, 0, CKDIS), 0xffff0000, 0x0000ffff,
15
16                 /* 0x9c Device present and extended RAM control 
17                  * DEVPRES is very touchy, hard code the initialization
18                  * of PCI-E ports here.
19                  */
20         PCI_ADDR(0, 0x00, 0, DEVPRES), 0x00000000, 0x07020801 | DEVPRES_CONFIG,
21
22                 /* 0xc8 Remap RAM base and limit off */ 
23         PCI_ADDR(0, 0x00, 0, REMAPLIMIT), 0x00000000, 0x03df0000,
24
25                 /* ??? */
26         PCI_ADDR(0, 0x00, 0, 0xd8), 0x00000000, 0xb5930000,
27         PCI_ADDR(0, 0x00, 0, 0xe8), 0x00000000, 0x00004a2a,
28
29                 /* 0x50 scrub */
30         PCI_ADDR(0, 0x00, 0, MCHCFG0), 0xfce0ffff, 0x00006000, /* 6000 */
31
32                 /* 0x58 0x5c PAM */
33         PCI_ADDR(0, 0x00, 0, PAM-1), 0xcccccc7f, 0x33333000,
34         PCI_ADDR(0, 0x00, 0, PAM+3), 0xcccccccc, 0x33333333,
35
36                 /* 0xf4 */
37         PCI_ADDR(0, 0x00, 0, DEVPRES1), 0xffbffff, (1<<22)|(6<<2) | DEVPRES1_CONFIG,
38
39                 /* 0x14 */
40         PCI_ADDR(0, 0x00, 0, IURBASE), 0x00000fff, BAR |0,  
41         };
42         int i;
43         int max;
44
45         max = sizeof(register_values)/sizeof(register_values[0]);
46         for(i = 0; i < max; i += 3) {
47                 device_t dev;
48                 unsigned where;
49                 unsigned long reg;
50                 dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x00, 0) + ctrl->f0;
51                 where = register_values[i] & 0xff;
52                 reg = pci_read_config32(dev, where);
53                 reg &= register_values[i+1];
54                 reg |= register_values[i+2];
55                 pci_write_config32(dev, where, reg);
56         }
57         print_spew("done.\r\n");
58 }
59
60
61
62 struct dimm_size {
63         unsigned long side1;
64         unsigned long side2;
65 };
66
67 static struct dimm_size spd_get_dimm_size(unsigned device)
68 {
69         /* Calculate the log base 2 size of a DIMM in bits */
70         struct dimm_size sz;
71         int value, low, ddr2;
72         sz.side1 = 0;
73         sz.side2 = 0;
74
75         /* test for ddr2 */
76         ddr2=0;
77         value = spd_read_byte(device, 2);       /* type */
78         if (value < 0) goto hw_err;
79         if (value == 8) ddr2 = 1;
80
81         /* Note it might be easier to use byte 31 here, it has the DIMM size as
82          * a multiple of 4MB.  The way we do it now we can size both
83          * sides of an assymetric dimm.
84          */
85         value = spd_read_byte(device, 3);       /* rows */
86         if (value < 0) goto hw_err;
87         if ((value & 0xf) == 0) goto val_err;
88         sz.side1 += value & 0xf;
89
90         value = spd_read_byte(device, 4);       /* columns */
91         if (value < 0) goto hw_err;
92         if ((value & 0xf) == 0) goto val_err;
93         sz.side1 += value & 0xf;
94
95         value = spd_read_byte(device, 17);      /* banks */
96         if (value < 0) goto hw_err;
97         if ((value & 0xff) == 0) goto val_err;
98         sz.side1 += log2(value & 0xff);
99
100         /* Get the module data width and convert it to a power of two */
101         value = spd_read_byte(device, 7);       /* (high byte) */
102         if (value < 0) goto hw_err;
103         value &= 0xff;
104         value <<= 8;
105         
106         low = spd_read_byte(device, 6); /* (low byte) */
107         if (low < 0) goto hw_err;
108         value = value | (low & 0xff);
109         if ((value != 72) && (value != 64)) goto val_err;
110         sz.side1 += log2(value);
111
112         /* side 2 */
113         value = spd_read_byte(device, 5);       /* number of physical banks */
114
115         if (value < 0) goto hw_err;
116         value &= 7;
117         if(ddr2) value++;
118         if (value == 1) goto out;
119         if (value != 2) goto val_err;
120
121         /* Start with the symmetrical case */
122         sz.side2 = sz.side1;
123
124         value = spd_read_byte(device, 3);       /* rows */
125         if (value < 0) goto hw_err;
126         if ((value & 0xf0) == 0) goto out;      /* If symmetrical we are done */
127         sz.side2 -= (value & 0x0f);             /* Subtract out rows on side 1 */
128         sz.side2 += ((value >> 4) & 0x0f);      /* Add in rows on side 2 */
129
130         value = spd_read_byte(device, 4);       /* columns */
131         if (value < 0) goto hw_err;
132         if ((value & 0xff) == 0) goto val_err;
133         sz.side2 -= (value & 0x0f);             /* Subtract out columns on side 1 */
134         sz.side2 += ((value >> 4) & 0x0f);      /* Add in columsn on side 2 */
135         goto out;
136
137  val_err:
138         die("Bad SPD value\r\n");
139         /* If an hw_error occurs report that I have no memory */
140 hw_err:
141         sz.side1 = 0;
142         sz.side2 = 0;
143  out:
144         return sz;
145
146 }
147
148 static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
149 {
150         int i;
151         int cum;
152         
153         for(i = cum = 0; i < DIMM_SOCKETS; i++) {
154                 struct dimm_size sz;
155                 if (dimm_mask & (1 << i)) {
156                         sz = spd_get_dimm_size(ctrl->channel0[i]);
157                         if (sz.side1 < 29) {
158                                 return -1; /* Report SPD error */
159                         }
160                         /* convert bits to multiples of 64MB */
161                         sz.side1 -= 29;
162                         cum += (1 << sz.side1);
163                         /* DRB = 0x60 */
164                         pci_write_config8(ctrl->f0, DRB + (i*2), cum);
165                         if( sz.side2 > 28) {
166                                 sz.side2 -= 29;
167                                 cum += (1 << sz.side2);
168                         }
169                         pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
170                 }
171                 else {
172                         pci_write_config8(ctrl->f0, DRB + (i*2), cum);
173                         pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
174                 }
175         }
176         /* set TOM top of memory 0xcc */
177         pci_write_config16(ctrl->f0, TOM, cum);
178         /* set TOLM top of low memory */
179         if(cum > 0x18) {
180                 cum = 0x18;
181         }
182         cum <<= 11;
183         /* 0xc4 TOLM */
184         pci_write_config16(ctrl->f0, TOLM, cum);
185         return 0;
186 }
187
188
189 static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
190 {
191         unsigned dimm_mask;
192         int i;
193         dimm_mask = 0;
194         for(i = 0; i < DIMM_SOCKETS; i++) {
195                 int byte;
196                 unsigned device;
197                 device = ctrl->channel0[i];
198                 if (device) {
199                         byte = spd_read_byte(device, 2);  /* Type */
200                         if ((byte == 7) || (byte == 8)) {
201                                 dimm_mask |= (1 << i);
202                         }
203                 }
204                 device = ctrl->channel1[i];
205                 if (device) {
206                         byte = spd_read_byte(device, 2);
207                         if ((byte == 7) || (byte == 8)) {
208                                 dimm_mask |= (1 << (i + DIMM_SOCKETS));
209                         }
210                 }
211         }
212         return dimm_mask;
213 }
214
215
216 static int spd_set_row_attributes(const struct mem_controller *ctrl, 
217                 long dimm_mask)
218 {
219
220         int value;
221         int reg;
222         int dra;
223         int cnt;
224
225         dra = 0;
226         for(cnt=0; cnt < 4; cnt++) {
227                 if (!(dimm_mask & (1 << cnt))) {
228                         continue;
229                 }
230                 reg =0;
231                 value = spd_read_byte(ctrl->channel0[cnt], 3);  /* rows */
232                 if (value < 0) goto hw_err;
233                 if ((value & 0xf) == 0) goto val_err;
234                 reg += value & 0xf;
235
236                 value = spd_read_byte(ctrl->channel0[cnt], 4);  /* columns */
237                 if (value < 0) goto hw_err;
238                 if ((value & 0xf) == 0) goto val_err;
239                 reg += value & 0xf;
240
241                 value = spd_read_byte(ctrl->channel0[cnt], 17); /* banks */
242                 if (value < 0) goto hw_err;
243                 if ((value & 0xff) == 0) goto val_err;
244                 reg += log2(value & 0xff);
245
246                 /* Get the device width and convert it to a power of two */
247                 value = spd_read_byte(ctrl->channel0[cnt], 13); 
248                 if (value < 0) goto hw_err;
249                 value = log2(value & 0xff);
250                 reg += value;
251                 if(reg < 27) goto hw_err;
252                 reg -= 27;
253                 reg += (value << 2);
254         
255                 dra += reg << (cnt*8);
256                 value = spd_read_byte(ctrl->channel0[cnt], 5);
257                 if (value & 2)
258                         dra += reg << ((cnt*8)+4);      
259         }
260
261         /* 0x70 DRA */
262         pci_write_config32(ctrl->f0, DRA, dra); 
263         goto out;
264
265  val_err:
266         die("Bad SPD value\r\n");
267         /* If an hw_error occurs report that I have no memory */
268 hw_err:
269         dra = 0;
270  out:
271         return dra;
272
273 }
274
275
276 static int spd_set_drt_attributes(const struct mem_controller *ctrl, 
277                 long dimm_mask, uint32_t drc)
278 {
279         int value;
280         int reg;
281         uint32_t drt;
282         int cnt;
283         int first_dimm;
284         int cas_latency=0;
285         int latency;
286         uint32_t index = 0;
287         uint32_t index2 = 0;
288         static const unsigned char cycle_time[3] = {0x75,0x60,0x50}; 
289         static const int latency_indicies[] = { 26, 23, 9 };
290
291         /* 0x78 DRT */
292         drt = pci_read_config32(ctrl->f0, DRT);
293         drt &= 3;  /* save bits 1:0 */
294         
295         for(first_dimm = 0; first_dimm < 4; first_dimm++) {
296                 if (dimm_mask & (1 << first_dimm)) 
297                         break;
298         }
299         
300         /* get dimm type */
301         value = spd_read_byte(ctrl->channel0[first_dimm], 2);
302         if(value == 8) {
303                 drt |= (3<<5); /* back to bark write turn around & cycle add */
304         }       
305
306         drt |= (3<<18);  /* Trasmax */
307
308         for(cnt=0; cnt < 4; cnt++) {
309                 if (!(dimm_mask & (1 << cnt))) {
310                         continue;
311                 }
312                 reg = spd_read_byte(ctrl->channel0[cnt], 18); /* CAS Latency */
313                 /* Compute the lowest cas latency supported */
314                 latency = log2(reg) -2;
315         
316                 /* Loop through and find a fast clock with a low latency */
317                 for(index = 0; index < 3; index++, latency++) {
318                         if ((latency < 2) || (latency > 4) ||
319                                 (!(reg & (1 << latency)))) {
320                                 continue;
321                         }
322                         value = spd_read_byte(ctrl->channel0[cnt], 
323                                         latency_indicies[index]);
324           
325                         if(value <= cycle_time[drc&3]) {
326                                 if( latency > cas_latency) {
327                                         cas_latency = latency;
328                                 }
329                                 break;
330                         }       
331                 }
332         }
333         index = (cas_latency-2);
334         if((index)==0) cas_latency = 20;
335         else if((index)==1) cas_latency = 25;
336         else cas_latency = 30;
337
338         for(cnt=0;cnt<4;cnt++) {
339                 if (!(dimm_mask & (1 << cnt))) {
340                         continue;
341                 }
342                 reg = spd_read_byte(ctrl->channel0[cnt], 27)&0x0ff;
343                 if(((index>>8)&0x0ff)<reg) {
344                         index &= ~(0x0ff << 8);
345                         index |= (reg << 8);
346                 }
347                 reg = spd_read_byte(ctrl->channel0[cnt], 28)&0x0ff;
348                 if(((index>>16)&0x0ff)<reg) {
349                         index &= ~(0x0ff << 16);
350                         index |= (reg<<16);
351                 }
352                 reg = spd_read_byte(ctrl->channel0[cnt], 29)&0x0ff;
353                 if(((index2>>0)&0x0ff)<reg) {
354                         index2 &= ~(0x0ff << 0);
355                         index2 |= (reg<<0);
356                 }
357                 reg = spd_read_byte(ctrl->channel0[cnt], 41)&0x0ff;
358                 if(((index2>>8)&0x0ff)<reg) {
359                         index2 &= ~(0x0ff << 8);
360                         index2 |= (reg<<8);
361                 }
362                 reg = spd_read_byte(ctrl->channel0[cnt], 42)&0x0ff;
363                 if(((index2>>16)&0x0ff)<reg) {
364                         index2 &= ~(0x0ff << 16);
365                         index2 |= (reg<<16);
366                 }
367         }
368
369         /* get dimm speed */
370         value = cycle_time[drc&3];
371         if(value <= 0x50) {  /* 200 MHz */
372                 if((index&7) > 2) {
373                         drt |= (2<<2);  /* CAS latency 4 */
374                         cas_latency = 40;
375                 } else {
376                         drt |= (1<<2);  /* CAS latency 3 */
377                         cas_latency = 30;
378                 }
379                 if((index&0x0ff00)<=0x03c00) {
380                         drt |= (1<<8);  /* Trp RAS Precharg */
381                 } else {
382                         drt |= (2<<8);  /* Trp RAS Precharg */
383                 }
384                 
385                 /* Trcd RAS to CAS delay */
386                 if((index2&0x0ff)<=0x03c) {
387                         drt |= (0<<10);
388                 } else {
389                         drt |= (1<<10);
390                 }
391
392                 /* Tdal Write auto precharge recovery delay */
393                 drt |= (1<<12);
394         
395                 /* Trc TRS min */
396                 if((index2&0x0ff00)<=0x03700)
397                         drt |= (0<<14);
398                 else if((index2&0xff00)<=0x03c00)
399                         drt |= (1<<14);
400                 else
401                         drt |= (2<<14); /* spd 41 */
402                 
403                 drt |= (2<<16);  /* Twr not defined for DDR docs say use 2 */
404                 
405                 /* Trrd Row Delay */
406                 if((index&0x0ff0000)<=0x0140000) {
407                         drt |= (0<<20);
408                 } else if((index&0x0ff0000)<=0x0280000) {
409                         drt |= (1<<20);
410                 } else if((index&0x0ff0000)<=0x03c0000) {
411                         drt |= (2<<20);
412                 } else {
413                         drt |= (3<<20);
414                 }
415                 
416                 /* Trfc Auto refresh cycle time */
417                 if((index2&0x0ff0000)<=0x04b0000) {
418                         drt |= (0<<22);
419                 } else if((index2&0x0ff0000)<=0x0690000) {
420                         drt |= (1<<22);
421                 } else {
422                         drt |= (2<<22);
423                 }
424                 /* Docs say use 55 for all 200Mhz */
425                 drt |= (0x055<<24);
426         }
427         else if(value <= 0x60) { /* 167 Mhz */
428                 /* according to new documentation CAS latency is 00
429                  * for bits 3:2 for all 167 Mhz 
430                 drt |= ((index&3)<<2); */  /* set CAS latency */
431                 if((index&0x0ff00)<=0x03000) {
432                         drt |= (1<<8);  /* Trp RAS Precharg */
433                 } else {
434                         drt |= (2<<8);  /* Trp RAS Precharg */
435                 }
436                 
437                 /* Trcd RAS to CAS delay */
438                 if((index2&0x0ff)<=0x030) {
439                         drt |= (0<<10);
440                 } else {
441                         drt |= (1<<10);
442                 }
443
444                 /* Tdal Write auto precharge recovery delay */
445                 drt |= (2<<12); 
446                 
447                 /* Trc TRS min */
448                 drt |= (2<<14); /* spd 41, but only one choice */
449                 
450                 drt |= (2<<16);  /* Twr not defined for DDR docs say 2 */
451                 
452                 /* Trrd Row Delay */
453                 if((index&0x0ff0000)<=0x0180000) {
454                         drt |= (0<<20);
455                 } else if((index&0x0ff0000)<=0x0300000) {
456                         drt |= (1<<20);
457                 } else {
458                         drt |= (2<<20);
459                 }
460                 
461                 /* Trfc Auto refresh cycle time */
462                 if((index2&0x0ff0000)<=0x0480000) {
463                         drt |= (0<<22);
464                 } else if((index2&0x0ff0000)<=0x0780000) {
465                         drt |= (2<<22);
466                 } else {
467                         drt |= (2<<22);
468                 }
469                 /* Docs state to use 99 for all 167 Mhz */
470                 drt |= (0x099<<24);
471         }
472         else if(value <= 0x75) { /* 133 Mhz */
473                 drt |= ((index&3)<<2);  /* set CAS latency */
474                 if((index&0x0ff00)<=0x03c00) {
475                         drt |= (1<<8);  /* Trp RAS Precharg */
476                 } else {
477                         drt |= (2<<8);  /* Trp RAS Precharg */
478                 }
479
480                 /* Trcd RAS to CAS delay */
481                 if((index2&0x0ff)<=0x03c) {
482                         drt |= (0<<10);
483                 } else {
484                         drt |= (1<<10);
485                 }
486
487                 /* Tdal Write auto precharge recovery delay */
488                 drt |= (1<<12); 
489                 
490                 /* Trc TRS min */
491                 drt |= (2<<14); /* spd 41, but only one choice */
492                 
493                 drt |= (1<<16);  /* Twr not defined for DDR docs say 1 */
494                 
495                 /* Trrd Row Delay */
496                 if((index&0x0ff0000)<=0x01e0000) {
497                         drt |= (0<<20);
498                 } else if((index&0x0ff0000)<=0x03c0000) {
499                         drt |= (1<<20);
500                 } else {
501                         drt |= (2<<20);
502                 }
503                 
504                 /* Trfc Auto refresh cycle time */
505                 if((index2&0x0ff0000)<=0x04b0000) {
506                         drt |= (0<<22);
507                 } else if((index2&0x0ff0000)<=0x0780000) {
508                         drt |= (2<<22);
509                 } else {
510                         drt |= (2<<22);
511                 }
512                 
513                 /* Based on CAS latency */
514                 if(index&7)
515                         drt |= (0x099<<24);
516                 else
517                         drt |= (0x055<<24);
518                 
519         }
520         else {
521                 die("Invalid SPD 9 bus speed.\r\n");
522         }
523
524         /* 0x78 DRT */
525         pci_write_config32(ctrl->f0, DRT, drt);
526
527         return(cas_latency);
528 }
529
530 static int spd_set_dram_controller_mode(const struct mem_controller *ctrl, 
531                 long dimm_mask)
532 {
533         int value;
534         int reg;
535         int drc;
536         int cnt;
537         msr_t msr;
538         unsigned char dram_type = 0xff;
539         unsigned char ecc = 0xff;
540         unsigned char rate = 62;
541         static const unsigned char spd_rates[6] = {15,3,7,7,62,62}; 
542         static const unsigned char drc_rates[5] = {0,15,7,62,3};
543         static const unsigned char fsb_conversion[4] = {3,1,3,2};
544
545         /* 0x7c DRC */
546         drc = pci_read_config32(ctrl->f0, DRC); 
547         for(cnt=0; cnt < 4; cnt++) {
548                 if (!(dimm_mask & (1 << cnt))) {
549                         continue;
550                 }
551                 value = spd_read_byte(ctrl->channel0[cnt], 11); /* ECC */
552                 reg = spd_read_byte(ctrl->channel0[cnt], 2); /* Type */
553                 if (value == 2) {    /* RAM is ECC capable */
554                         if (reg == 8) {
555                                 if ( ecc == 0xff ) {
556                                         ecc = 2;
557                                 }
558                                 else if (ecc == 1) {
559                                         die("ERROR - Mixed DDR & DDR2 RAM\r\n");
560                                 }
561                         } 
562                         else if ( reg == 7 ) {
563                                 if ( ecc == 0xff) {
564                                         ecc = 1;
565                                 }
566                                 else if ( ecc > 1 ) {
567                                         die("ERROR - Mixed DDR & DDR2 RAM\r\n");
568                                 }
569                         }       
570                         else {
571                                 die("ERROR - RAM not DDR\r\n");
572                         }
573                 }
574                 else {
575                         die("ERROR - Non ECC memory dimm\r\n");
576                 }
577
578                 value = spd_read_byte(ctrl->channel0[cnt], 12); /*refresh rate*/
579                 value &= 0x0f;    /* clip self refresh bit */
580                 if (value > 5) goto hw_err;
581                 if (rate > spd_rates[value])
582                         rate = spd_rates[value];
583
584                 value = spd_read_byte(ctrl->channel0[cnt], 9);  /* cycle time */
585                 if (value > 0x75) goto hw_err;
586                 if (value <= 0x50) {
587                         if (dram_type >= 2) {
588                                 if (reg == 8) { /*speed is good, is this ddr2?*/
589                                         dram_type = 2;
590                                 } else { /* not ddr2 so use ddr333 */
591                                         dram_type = 1;
592                                 }
593                         }
594                 }
595                 else if (value <= 0x60) {
596                         if (dram_type >= 1)  dram_type = 1;
597                 }
598                 else dram_type = 0; /* ddr266 */
599
600         }
601         ecc = 2;
602         if (read_option(CMOS_VSTART_ECC_memory,CMOS_VLEN_ECC_memory,1) == 0) {
603                 ecc = 0;  /* ECC off in CMOS so disable it */
604                 print_debug("ECC off\r\n");
605         }
606         else {
607                 print_debug("ECC on\r\n");
608         }
609         drc &= ~(3 << 20); /* clear the ecc bits */
610         drc |= (ecc << 20);  /* or in the calculated ecc bits */
611         for ( cnt = 1; cnt < 5; cnt++)
612                 if (drc_rates[cnt] == rate)
613                         break;
614         if (cnt < 5) {
615                 drc &= ~(7 << 8);  /* clear the rate bits */
616                 drc |= (cnt << 8);
617         }
618
619         if (reg == 8) { /* independant clocks */
620                 drc |= (1 << 4);
621         }
622
623         drc |= (1 << 26); /* set the overlap bit - the factory BIOS does */
624         drc |= (1 << 27); /* set DED retry enable - the factory BIOS does */
625         /* front side bus */
626         msr = rdmsr(0x2c);
627         value = msr.lo >> 16;
628         value &= 0x03;
629         drc &= ~(3 << 2); /* set the front side bus */
630         drc |= (fsb_conversion[value] << 2);
631         drc &= ~(3 << 0); /* set the dram type */
632         drc |= (dram_type << 0);
633                 
634         goto out;
635
636  val_err:
637         die("Bad SPD value\r\n");
638         /* If an hw_error occurs report that I have no memory */
639 hw_err:
640         drc = 0;
641  out:
642         return drc;
643 }
644
645 static void sdram_set_spd_registers(const struct mem_controller *ctrl) 
646 {
647         long dimm_mask;
648
649         /* Test if we can read the spd and if ram is ddr or ddr2 */
650         dimm_mask = spd_detect_dimms(ctrl);
651         if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
652                 print_err("No memory for this cpu\r\n");
653                 return;
654         }
655         return;
656 }
657
658 static void do_delay(void)
659 {
660         int i;
661         unsigned char b;
662         for(i=0;i<16;i++)
663                 b=inb(0x80);
664 }       
665
666 static void pll_setup(uint32_t drc)
667 {
668         unsigned pins;
669         if(drc&3) { /* DDR 333 or DDR 400 */
670                 if((drc&0x0c) == 0x0c) { /* FSB 200 */
671                         pins = 2 | 1;
672                 }
673                 else if((drc&0x0c) == 0x08) {   /* FSB 167 */
674                         pins = 0 | 1;
675                 }
676                 else if(drc&1){  /* FSB 133 DDR 333 */
677                         pins = 2 | 1;
678                 }
679                 else { /* FSB 133 DDR 400 */
680                         pins = 0 | 1;
681                 }
682         }
683         else { /* DDR 266 */
684                 if((drc&0x08) == 0x08) { /* FSB 200 or 167 */
685                         pins = 0 | 0;
686                 }
687                 else { /* FSB 133 */
688                         pins = 0 | 1;
689                 }
690         }
691         mainboard_set_e7520_pll(pins);
692         return;
693 }       
694
695 #define TIMEOUT_LOOPS 300000
696
697 #define DCALCSR  0x100
698 #define DCALADDR 0x104
699 #define DCALDATA 0x108
700
701 static void set_on_dimm_termination_enable(const struct mem_controller *ctrl)
702 {
703         unsigned char c1,c2;
704         unsigned int dimm,i;
705         unsigned int data32;
706         unsigned int t4;
707  
708         /* Set up northbridge values */
709         /* ODT enable */
710         pci_write_config32(ctrl->f0, 0x88, 0xf0000180);
711         /* Figure out which slots are Empty, Single, or Double sided */
712         for(i=0,t4=0,c2=0;i<8;i+=2) {
713                 c1 = pci_read_config8(ctrl->f0, DRB+i);
714                 if(c1 == c2) continue;
715                 c2 = pci_read_config8(ctrl->f0, DRB+1+i);
716                 if(c1 == c2)
717                         t4 |= (1 << (i*4));
718                 else
719                         t4 |= (2 << (i*4));
720         }
721         for(i=0;i<1;i++) {
722             if((t4&0x0f) == 1) {
723                 if( ((t4>>8)&0x0f) == 0 ) {
724                         data32 = 0x00000010; /* EEES */ 
725                         break;
726                 }
727                 if ( ((t4>>16)&0x0f) == 0 ) { 
728                         data32 = 0x00003132; /* EESS */
729                         break;
730                 }
731                 if ( ((t4>>24)&0x0f)  == 0 ) {
732                         data32 = 0x00335566; /* ESSS */
733                         break;
734                 }
735                 data32 = 0x77bbddee; /* SSSS */
736                 break;
737             }
738             if((t4&0x0f) == 2) {
739                 if( ((t4>>8)&0x0f) == 0 ) {
740                         data32 = 0x00003132; /* EEED */ 
741                         break;
742                 }
743                 if ( ((t4>>8)&0x0f) == 2 ) {
744                         data32 = 0xb373ecdc; /* EEDD */
745                         break;
746                 }
747                 if ( ((t4>>16)&0x0f) == 0 ) {
748                         data32 = 0x00b3a898; /* EESD */
749                         break;
750                 }
751                 data32 = 0x777becdc; /* ESSD */
752                 break;
753             }
754             die("Error - First dimm slot empty\r\n");
755         }
756
757         print_debug("ODT Value = ");
758         print_debug_hex32(data32);
759         print_debug("\r\n");
760
761         pci_write_config32(ctrl->f0, 0xb0, data32);
762
763         for(dimm=0;dimm<8;dimm+=1) {
764
765                 write32(BAR+DCALADDR, 0x0b840001);
766                 write32(BAR+DCALCSR, 0x83000003 | (dimm << 20));
767                 
768                 for(i=0;i<1001;i++) {
769                         data32 = read32(BAR+DCALCSR);
770                         if(!(data32 & (1<<31)))
771                                 break;
772                 }
773         }
774 }       
775 static void set_receive_enable(const struct mem_controller *ctrl)
776 {
777         unsigned int i;
778         unsigned int cnt;
779         uint32_t recena=0;
780         uint32_t recenb=0;
781
782         {       
783         unsigned int dimm;
784         unsigned int edge;
785         int32_t data32;
786         uint32_t data32_dram;
787         uint32_t dcal_data32_0;
788         uint32_t dcal_data32_1;
789         uint32_t dcal_data32_2;
790         uint32_t dcal_data32_3;
791         uint32_t work32l;
792         uint32_t work32h;
793         uint32_t data32r;
794         int32_t recen;
795         for(dimm=0;dimm<8;dimm+=1) {
796
797                 if(!(dimm&1)) {
798                         write32(BAR+DCALDATA+(17*4), 0x04020000);
799                         write32(BAR+DCALCSR, 0x83800004 | (dimm << 20));
800                 
801                         for(i=0;i<1001;i++) {
802                                 data32 = read32(BAR+DCALCSR);
803                                 if(!(data32 & (1<<31)))
804                                         break;
805                         }
806                         if(i>=1000)
807                                 continue;
808                 
809                         dcal_data32_0 = read32(BAR+DCALDATA + 0);
810                         dcal_data32_1 = read32(BAR+DCALDATA + 4);
811                         dcal_data32_2 = read32(BAR+DCALDATA + 8);
812                         dcal_data32_3 = read32(BAR+DCALDATA + 12);
813                 }
814                 else {
815                         dcal_data32_0 = read32(BAR+DCALDATA + 16);
816                         dcal_data32_1 = read32(BAR+DCALDATA + 20);
817                         dcal_data32_2 = read32(BAR+DCALDATA + 24);
818                         dcal_data32_3 = read32(BAR+DCALDATA + 28);
819                 }
820
821                 /* check if bank is installed */
822                 if((dcal_data32_0 == 0) && (dcal_data32_2 == 0))
823                         continue;
824                 /* Calculate the timing value */
825                 {
826                 unsigned int bit;
827                 for(i=0,edge=0,bit=63,cnt=31,data32r=0,
828                         work32l=dcal_data32_1,work32h=dcal_data32_3;
829                                 (i<4) && bit; i++) {
830                         for(;;bit--,cnt--) {
831                                 if(work32l & (1<<cnt))
832                                         break;
833                                 if(!cnt) {
834                                         work32l = dcal_data32_0;
835                                         work32h = dcal_data32_2;
836                                         cnt = 32;
837                                 }
838                                 if(!bit) break;
839                         }
840                         for(;;bit--,cnt--) {
841                                 if(!(work32l & (1<<cnt)))
842                                         break;
843                                 if(!cnt) {
844                                         work32l = dcal_data32_0;
845                                         work32h = dcal_data32_2;
846                                         cnt = 32;
847                                 }
848                                 if(!bit) break;
849                         }
850                         if(!bit) {
851                                 break;
852                         }
853                         data32 = ((bit%8) << 1);
854                         if(work32h & (1<<cnt))
855                                 data32 += 1;
856                         if(data32 < 4) {
857                                 if(!edge) {
858                                         edge = 1;
859                                 }
860                                 else {
861                                         if(edge != 1) {
862                                                 data32 = 0x0f;
863                                         }
864                                 }
865                         }
866                         if(data32 > 12) {
867                                 if(!edge) {
868                                         edge = 2;
869                                 }
870                                 else {
871                                         if(edge != 2) {
872                                                 data32 = 0x00;
873                                         }
874                                 }
875                         }
876                         data32r += data32;
877                 }
878                 }
879                 work32l = dcal_data32_0;
880                 work32h = dcal_data32_2;
881                 recen = data32r;
882                 recen += 3;
883                 recen = recen>>2;
884                 for(cnt=5;cnt<24;) {
885                         for(;;cnt++)
886                                 if(!(work32l & (1<<cnt)))
887                                         break;
888                         for(;;cnt++) {
889                                 if(work32l & (1<<cnt))
890                                         break;
891                         }
892                         data32 = (((cnt-1)%8)<<1);
893                         if(work32h & (1<<(cnt-1))) {
894                                 data32++;
895                         }
896                         /* test for frame edge cross overs */
897                         if((edge == 1) && (data32 > 12) && 
898                             (((recen+16)-data32) < 3)) {
899                                 data32 = 0;
900                                 cnt += 2;
901                         }
902                         if((edge == 2) && (data32 < 4) &&
903                             ((recen - data32) > 12))  {
904                                 data32 = 0x0f;
905                                 cnt -= 2;
906                         }
907                         if(((recen+3) >= data32) && ((recen-3) <= data32))
908                                 break;
909                 }
910                 cnt--;
911                 cnt /= 8;
912                 cnt--;
913                 if(recen&1)
914                         recen+=2;
915                 recen >>= 1;
916                 recen += (cnt*8);
917                 recen+=2;      /* this is not in the spec, but matches
918                                  the factory output, and has less failure */
919                 recen <<= (dimm/2) * 8;
920                 if(!(dimm&1)) {
921                         recena |= recen;
922                 }
923                 else {
924                         recenb |= recen;
925                 }
926         }
927         }
928         /* Check for Eratta problem */
929         for(i=cnt=0;i<32;i+=8) {
930                 if (((recena>>i)&0x0f)>7) {
931                         cnt+= 0x101;
932                 }
933                 else {
934                         if((recena>>i)&0x0f) {
935                                 cnt++;
936                         }
937                 }
938         }
939         if(cnt&0x0f00) {
940                 cnt = (cnt&0x0f) - (cnt>>16);
941                 if(cnt>1) {
942                         for(i=0;i<32;i+=8) {
943                                 if(((recena>>i)&0x0f)>7) {
944                                         recena &= ~(0x0f<<i);
945                                         recena |= (7<<i);
946                                 }
947                         }
948                 }
949                 else {
950                         for(i=0;i<32;i+=8) {
951                                 if(((recena>>i)&0x0f)<8) {
952                                         recena &= ~(0x0f<<i);
953                                         recena |= (8<<i);
954                                 }
955                         }
956                 }
957         }
958         for(i=cnt=0;i<32;i+=8) {
959                 if (((recenb>>i)&0x0f)>7) {
960                         cnt+= 0x101;
961                 }
962                 else {
963                         if((recenb>>i)&0x0f) {
964                                 cnt++;
965                         }
966                 }
967         }
968         if(cnt & 0x0f00) {
969                 cnt = (cnt&0x0f) - (cnt>>16);
970                 if(cnt>1) {
971                         for(i=0;i<32;i+=8) {
972                                 if(((recenb>>i)&0x0f)>7) {
973                                         recenb &= ~(0x0f<<i);
974                                         recenb |= (7<<i);
975                                 }
976                         }
977                 }
978                 else {
979                         for(i=0;i<32;i+=8) {
980                                 if(((recenb>>8)&0x0f)<8) {
981                                         recenb &= ~(0x0f<<i);
982                                         recenb |= (8<<i);
983                                 }
984                         }
985                 }
986         }
987
988         print_debug("Receive enable A = ");
989         print_debug_hex32(recena);
990         print_debug(",  Receive enable B = ");
991         print_debug_hex32(recenb);
992         print_debug("\r\n");
993
994         /* clear out the calibration area */
995         write32(BAR+DCALDATA+(16*4), 0x00000000);
996         write32(BAR+DCALDATA+(17*4), 0x00000000);
997         write32(BAR+DCALDATA+(18*4), 0x00000000);
998         write32(BAR+DCALDATA+(19*4), 0x00000000);
999
1000         /* No command */
1001         write32(BAR+DCALCSR, 0x0000000f);
1002
1003         write32(BAR+0x150, recena);
1004         write32(BAR+0x154, recenb);
1005 }
1006
1007
1008 static void sdram_enable(int controllers, const struct mem_controller *ctrl)
1009 {
1010         int i;
1011         int cs;
1012         int cnt;
1013         int cas_latency;
1014         long mask;
1015         uint32_t drc;
1016         uint32_t data32;
1017         uint32_t mode_reg;
1018         uint32_t *iptr;
1019         volatile unsigned long *iptrv;
1020         msr_t msr;
1021         uint32_t scratch;
1022         uint8_t byte;
1023         uint16_t data16;
1024         static const struct {
1025                 uint32_t clkgr[4];
1026         } gearing [] = {
1027                 /* FSB 133 DIMM 266 */
1028         {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
1029                 /* FSB 133 DIMM 333 */
1030         {{ 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1031                 /* FSB 133 DIMM 400 */
1032         {{ 0x00000120, 0x00000000, 0x00000032, 0x00000010}},
1033                 /* FSB 167 DIMM 266 */
1034         {{ 0x00005432, 0x00001000, 0x00004325, 0x00000000}},
1035                 /* FSB 167 DIMM 333 */
1036         {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
1037                 /* FSB 167 DIMM 400 */
1038         {{ 0x00154320, 0x00000000, 0x00065432, 0x00010000}},
1039                 /* FSB 200 DIMM 266 */
1040         {{ 0x00000032, 0x00000010, 0x00000120, 0x00000000}},
1041                 /* FSB 200 DIMM 333 */
1042         {{ 0x00065432, 0x00010000, 0x00154320, 0x00000000}},
1043                 /* FSB 200 DIMM 400 */
1044         {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
1045         };
1046         
1047         static const uint32_t dqs_data[] = {
1048                 0xffffffff, 0xffffffff, 0x000000ff, 
1049                 0xffffffff, 0xffffffff, 0x000000ff, 
1050                 0xffffffff, 0xffffffff, 0x000000ff,
1051                 0xffffffff, 0xffffffff, 0x000000ff,
1052                 0xffffffff, 0xffffffff, 0x000000ff, 
1053                 0xffffffff, 0xffffffff, 0x000000ff, 
1054                 0xffffffff, 0xffffffff, 0x000000ff, 
1055                 0xffffffff, 0xffffffff, 0x000000ff};
1056
1057         mask = spd_detect_dimms(ctrl);
1058         print_debug("Starting SDRAM Enable\r\n");
1059
1060         /* 0x80 */
1061 #ifdef DIMM_MAP_LOGICAL
1062         pci_write_config32(ctrl->f0, DRM,
1063                 0x00210000 | DIMM_MAP_LOGICAL);
1064 #else
1065         pci_write_config32(ctrl->f0, DRM, 0x00211248);
1066 #endif
1067         /* set dram type and Front Side Bus freq. */
1068         drc = spd_set_dram_controller_mode(ctrl, mask);
1069         if( drc == 0) {
1070                 die("Error calculating DRC\r\n");
1071         }
1072         pll_setup(drc);
1073         data32 = drc & ~(3 << 20);  /* clear ECC mode */
1074         data32 = data32 & ~(7 << 8);  /* clear refresh rates */
1075         data32 = data32 | (1 << 5);  /* temp turn off of ODT */
1076         /* Set gearing, then dram controller mode */
1077         /* drc bits 1:0 = DIMM speed, bits 3:2 = FSB speed */
1078         for(iptr = gearing[(drc&3)+((((drc>>2)&3)-1)*3)].clkgr,cnt=0;
1079                         cnt<4;cnt++) {
1080                 pci_write_config32(ctrl->f0, 0xa0+(cnt*4), iptr[cnt]);
1081         }
1082         /* 0x7c DRC */
1083         pci_write_config32(ctrl->f0, DRC, data32);
1084         
1085                 /* turn the clocks on */
1086         /* 0x8c CKDIS */
1087         pci_write_config16(ctrl->f0, CKDIS, 0x0000);
1088         
1089                 /* 0x9a DDRCSR Take subsystem out of idle */
1090         data16 = pci_read_config16(ctrl->f0, DDRCSR);
1091         data16 &= ~(7 << 12);
1092         data16 |= (3 << 12);   /* use dual channel lock step */
1093         pci_write_config16(ctrl->f0, DDRCSR, data16);
1094         
1095                 /* program row size DRB */
1096         spd_set_ram_size(ctrl, mask);
1097
1098                 /* program page size DRA */
1099         spd_set_row_attributes(ctrl, mask);
1100
1101                 /* program DRT timing values */ 
1102         cas_latency = spd_set_drt_attributes(ctrl, mask, drc);
1103
1104         for(i=0;i<8;i++) { /* loop throught each dimm to test for row */
1105                 print_debug("DIMM ");
1106                 print_debug_hex8(i);
1107                 print_debug("\r\n");
1108                 /* Apply NOP */
1109                 do_delay();
1110                 
1111                 write32(BAR + 0x100, (0x03000000 | (i<<20)));
1112
1113                 write32(BAR+0x100, (0x83000000 | (i<<20)));
1114
1115                 data32 = read32(BAR+DCALCSR);
1116                 while(data32 & 0x80000000)
1117                         data32 = read32(BAR+DCALCSR);
1118
1119         }
1120         
1121         /* Apply NOP */
1122         do_delay();
1123
1124         for(cs=0;cs<8;cs++) {   
1125                 write32(BAR + DCALCSR, (0x83000000 | (cs<<20))); 
1126                 data32 = read32(BAR+DCALCSR);
1127                 while(data32 & 0x80000000)
1128                         data32 = read32(BAR+DCALCSR);
1129         }
1130
1131         /* Precharg all banks */
1132         do_delay();
1133         for(cs=0;cs<8;cs++) {   
1134                 if ((drc & 3) == 2) /* DDR2  */
1135                         write32(BAR+DCALADDR, 0x04000000);
1136                 else   /* DDR1  */
1137                         write32(BAR+DCALADDR, 0x00000000);
1138                 write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
1139                 data32 = read32(BAR+DCALCSR);
1140                 while(data32 & 0x80000000)
1141                         data32 = read32(BAR+DCALCSR);
1142         }
1143                 
1144         /* EMRS dll's enabled */
1145         do_delay();
1146         for(cs=0;cs<8;cs++) {   
1147                 if ((drc & 3) == 2) /* DDR2  */
1148                         /* fixme hard code AL additive latency */
1149                         write32(BAR+DCALADDR, 0x0b940001);
1150                 else   /* DDR1  */
1151                         write32(BAR+DCALADDR, 0x00000001);
1152                 write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
1153                 data32 = read32(BAR+DCALCSR);
1154                 while(data32 & 0x80000000)
1155                         data32 = read32(BAR+DCALCSR);
1156         }
1157         /* MRS reset dll's */
1158         do_delay();
1159         if ((drc & 3) == 2) {  /* DDR2  */
1160                 if(cas_latency == 30)
1161                         mode_reg = 0x053a0000;
1162                 else
1163                         mode_reg = 0x054a0000;
1164         }
1165         else {  /* DDR1  */
1166                 if(cas_latency == 20)
1167                         mode_reg = 0x012a0000;
1168                 else  /*  CAS Latency 2.5 */
1169                         mode_reg = 0x016a0000;
1170         }
1171         for(cs=0;cs<8;cs++) {   
1172                 write32(BAR+DCALADDR, mode_reg);
1173                 write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
1174                 data32 = read32(BAR+DCALCSR);
1175                 while(data32 & 0x80000000)
1176                         data32 = read32(BAR+DCALCSR);
1177         }
1178
1179         /* Precharg all banks */
1180         do_delay();
1181         do_delay();
1182         do_delay();
1183         for(cs=0;cs<8;cs++) {   
1184                 if ((drc & 3) == 2) /* DDR2  */
1185                         write32(BAR+DCALADDR, 0x04000000);
1186                 else   /* DDR1  */
1187                         write32(BAR+DCALADDR, 0x00000000);
1188                 write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
1189                 data32 = read32(BAR+DCALCSR);
1190                 while(data32 & 0x80000000)
1191                         data32 = read32(BAR+DCALCSR);
1192         }
1193         
1194         /* Do 2 refreshes */
1195         do_delay();
1196         for(cs=0;cs<8;cs++) {   
1197                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1198                 data32 = read32(BAR+DCALCSR);
1199                 while(data32 & 0x80000000)
1200                         data32 = read32(BAR+DCALCSR);
1201         }
1202         do_delay();
1203         for(cs=0;cs<8;cs++) {   
1204                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1205                 data32 = read32(BAR+DCALCSR);
1206                 while(data32 & 0x80000000)
1207                         data32 = read32(BAR+DCALCSR);
1208         }
1209         do_delay();
1210         /* for good luck do 6 more */
1211         for(cs=0;cs<8;cs++) {   
1212                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1213         }
1214         do_delay();
1215         for(cs=0;cs<8;cs++) {   
1216                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1217         }
1218         do_delay();
1219         for(cs=0;cs<8;cs++) {   
1220                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1221         }
1222         do_delay();
1223         for(cs=0;cs<8;cs++) {   
1224                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1225         }
1226         do_delay();
1227         for(cs=0;cs<8;cs++) {   
1228                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1229         }
1230         do_delay();
1231         for(cs=0;cs<8;cs++) {   
1232                 write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
1233         }
1234         do_delay();
1235         /* MRS reset dll's normal */
1236         do_delay();
1237         for(cs=0;cs<8;cs++) {   
1238                 write32(BAR+DCALADDR, (mode_reg & ~(1<<24)));
1239                 write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
1240                 data32 = read32(BAR+DCALCSR);
1241                 while(data32 & 0x80000000)
1242                         data32 = read32(BAR+DCALCSR);
1243         }
1244
1245         /* Do only if DDR2  EMRS dll's enabled */
1246         if ((drc & 3) == 2) { /* DDR2  */
1247                 do_delay();
1248                 for(cs=0;cs<8;cs++) {
1249                         write32(BAR+DCALADDR, (0x0b940001));
1250                         write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
1251                         data32 = read32(BAR+DCALCSR);
1252                         while(data32 & 0x80000000)
1253                                 data32 = read32(BAR+DCALCSR);
1254                 }
1255         }
1256
1257         do_delay();
1258         /* No command */
1259         write32(BAR+DCALCSR, 0x0000000f);
1260
1261         /* DDR1 This is test code to copy some codes in the factory setup */
1262         
1263         write32(BAR, 0x00100000);
1264
1265         if ((drc & 3) == 2) { /* DDR2  */
1266         /* enable on dimm termination */
1267                 set_on_dimm_termination_enable(ctrl);
1268         }
1269         else { /* ddr */
1270                 pci_write_config32(ctrl->f0, 0x88, 0xa0000000 );
1271         }
1272
1273         /* receive enable calibration */
1274         set_receive_enable(ctrl);
1275         
1276         /* DQS */
1277         pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); 
1278         for(i = 0, cnt = (BAR+0x200); i < 24; i++, cnt+=4) {
1279                 write32(cnt, dqs_data[i]);
1280         }
1281         pci_write_config32(ctrl->f0, 0x94, 0x3904a100 );
1282
1283         /* Enable refresh */
1284         /* 0x7c DRC */
1285         data32 = drc & ~(3 << 20);  /* clear ECC mode */
1286         pci_write_config32(ctrl->f0, DRC, data32);      
1287         write32(BAR+DCALCSR, 0x0008000f);
1288
1289         /* clear memory and init ECC */
1290         print_debug("Clearing memory\r\n");
1291         for(i=0;i<64;i+=4) {
1292                 write32(BAR+DCALDATA+i, 0x00000000);
1293         }
1294         
1295         for(cs=0;cs<8;cs++) {
1296                 write32(BAR+DCALCSR, (0x830831d8 | (cs<<20)));
1297                 data32 = read32(BAR+DCALCSR);
1298                 while(data32 & 0x80000000)
1299                         data32 = read32(BAR+DCALCSR);
1300         }
1301
1302         /* Bring memory subsystem on line */
1303         data32 = pci_read_config32(ctrl->f0, 0x98);
1304         data32 |= (1 << 31);
1305         pci_write_config32(ctrl->f0, 0x98, data32);
1306         /* wait for completion */
1307         print_debug("Waiting for mem complete\r\n");
1308         while(1) {
1309                 data32 = pci_read_config32(ctrl->f0, 0x98);
1310                 if( (data32 & (1<<31)) == 0)
1311                         break;
1312         }
1313         print_debug("Done\r\n");
1314         
1315         /* Set initialization complete */
1316         /* 0x7c DRC */
1317         drc |= (1 << 29);
1318         data32 = drc & ~(3 << 20);  /* clear ECC mode */
1319         pci_write_config32(ctrl->f0, DRC, data32);      
1320
1321         /* Set the ecc mode */
1322         pci_write_config32(ctrl->f0, DRC, drc); 
1323
1324         /* Enable memory scrubbing */
1325         /* 0x52 MCHSCRB */      
1326         data16 = pci_read_config16(ctrl->f0, MCHSCRB);
1327         data16 &= ~0x0f;
1328         data16 |= ((2 << 2) | (2 << 0));
1329         pci_write_config16(ctrl->f0, MCHSCRB, data16);  
1330
1331         /* The memory is now setup, use it */
1332         cache_lbmem(MTRR_TYPE_WRBACK);
1333 }