Some timing in here, but we don't set; it breaks.
[coreboot.git] / src / northbridge / via / vt8601 / raminit.c
1 #include <cpu/p6/mtrr.h>
2 #include "raminit.h"
3
4 /*
5 This software and ancillary information (herein called SOFTWARE )
6 called LinuxBIOS          is made available under the terms described
7 here.  The SOFTWARE has been approved for release with associated
8 LA-CC Number 00-34   .  Unless otherwise indicated, this SOFTWARE has
9 been authored by an employee or employees of the University of
10 California, operator of the Los Alamos National Laboratory under
11 Contract No. W-7405-ENG-36 with the U.S. Department of Energy.  The
12 U.S. Government has rights to use, reproduce, and distribute this
13 SOFTWARE.  The public may copy, distribute, prepare derivative works
14 and publicly display this SOFTWARE without charge, provided that this
15 Notice and any statement of authorship are reproduced on all copies.
16 Neither the Government nor the University makes any warranty, express 
17 or implied, or assumes any liability or responsibility for the use of
18 this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
19 such modified SOFTWARE should be clearly marked, so as not to confuse
20 it with the version available from LANL.
21  */
22 /* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
23  * rminnich@lanl.gov
24  */
25 /*
26  * 11/26/02 - kevinh@ispiri.com - The existing comments implied that
27  * this didn't work yet.  Therefore, I've updated it so that it works
28  * correctly - at least on my VIA epia motherboard.  64MB DIMM in slot 0.
29  */
30
31 /* Added automatic detection of first equipped bank and its MA mapping type.
32  * (Rest of configuration is done in C)
33  * 5/19/03 by SONE Takeshi <ts1@tsn.or.jp>
34  */
35 /* converted to C 9/2003 Ron Minnich */
36
37 /* Set to 1 if your DIMMs are PC133 Note that I'm assuming CPU's FSB
38  * frequency is 133MHz. If your CPU runs at another bus speed, you
39  * might need to change some of register values.
40  */
41 #ifndef DIMM_PC133
42 #define DIMM_PC133 0
43 #endif
44
45 // Set to 1 if your DIMMs are CL=2
46 #ifndef DIMM_CL2
47 #define DIMM_CL2 0
48 #endif
49
50 void dimms_read(unsigned long x) {
51   uint8_t c;
52   unsigned long eax; 
53   volatile unsigned long y;
54   eax =  x;
55   for(c = 0; c < 6; c++) {
56     
57     print_err("dimms_read: ");
58     print_err_hex32(eax);
59     print_err("\r\n");
60     y = * (volatile unsigned long *) eax;
61     eax += 0x10000000;
62   }
63 }
64
65 void dimms_write(int x) {
66   uint8_t c;
67   unsigned long eax = x;
68   for(c = 0; c < 6; c++) {
69     print_err("dimms_write: ");
70     print_err_hex32(eax);
71     print_err("\r\n");
72     *(volatile unsigned long *) eax = 0;
73     eax += 0x10000000;
74   }
75 }
76
77
78
79 #ifdef DEBUG_SETNORTHB
80 void setnorthb(device_t north, uint8_t reg, uint8_t val) {
81   print_err("setnorth: reg ");
82     print_err_hex8(reg);
83   print_err(" to ");
84   print_err_hex8(val);
85   print_err("\r\n");
86   pci_write_config8(north, reg, val);
87 }
88 #else
89 #define setnorthb pci_write_config8
90 #endif
91
92 void
93 dumpnorth(device_t north) {
94   uint8_t r, c;
95   for(r = 0; r < 256; r += 16) {
96     print_err_hex8(r);
97     print_err(":");
98     for(c = 0; c < 16; c++) {
99       print_err_hex8(pci_read_config8(north, r+c));
100       print_err(" ");
101     }
102     print_err("\r\n");
103   }
104 }
105 static void sdram_set_registers(const struct mem_controller *ctrl) {
106   static const uint16_t raminit_ma_reg_table[] = {
107     /* Values for MA type register to try */
108     0x0000, 0x8088, 0xe0ee,
109     0xffff // end mark
110   };
111   static const unsigned char ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
112                                         0x56, 0x57};
113
114   device_t north = (device_t) 0;
115   uint8_t c, r;
116
117   print_err("vt8601 init starting\n");
118   north = pci_locate_device(PCI_ID(0x1106, 0x8601), 0);
119   north = 0;
120   print_err_hex32(north);
121   print_err(" is the north\n");
122   print_err_hex16(pci_read_config16(north, 0));
123   print_err(" ");
124   print_err_hex16(pci_read_config16(north, 2));
125   print_err("\r\n");
126
127   /* All we are doing now is setting initial known-good values that will
128    * be revised later as we read SPD
129    */   
130   // memory clk enable. We are not using ECC
131   pci_write_config8(north,0x78, 0x01);
132   print_err_hex8(pci_read_config8(north, 0x78));
133   // dram control, see the book. 
134 #if DIMM_PC133
135   pci_write_config8(north,0x68, 0x52);
136 #else
137   pci_write_config8(north,0x68, 0x42);
138 #endif
139   // dram control, see the book. 
140   pci_write_config8(north,0x6B, 0x0c);
141   // Initial setting, 256MB in each bank, will be rewritten later.
142   pci_write_config8(north,0x5A, 0x20);
143   print_err_hex8(pci_read_config8(north, 0x5a));
144   pci_write_config8(north,0x5B, 0x40);
145   pci_write_config8(north,0x5C, 0x60);
146   pci_write_config8(north,0x5D, 0x80);
147   pci_write_config8(north,0x5E, 0xA0);
148   pci_write_config8(north,0x5F, 0xC0);
149   // It seems we have to take care of these 2 registers as if 
150   // they are bank 6 and 7.
151   pci_write_config8(north,0x56, 0xC0);
152   pci_write_config8(north,0x57, 0xC0);
153
154   // SDRAM in all banks
155   pci_write_config8(north,0x60, 0x3F);
156   // DRAM timing. I'm suspicious of this
157   // This is for all banks, 64 is 0,1.  65 is 2,3. 66 is 4,5.
158   // ras precharge 4T, RAS pulse 5T
159   // cas2 is 0xd6, cas3 is 0xe6
160   // we're also backing off write pulse width to 2T, so result is 0xee
161 #if DIMM_CL2
162   pci_write_config8(north,0x64, 0xd4);
163   pci_write_config8(north,0x65, 0xd4);
164   pci_write_config8(north,0x66, 0xd4);
165 #else // CL=3
166   pci_write_config8(north,0x64, 0xe4);
167   pci_write_config8(north,0x65, 0xe4);
168   pci_write_config8(north,0x66, 0xe4);
169 #endif
170
171   // dram frequency select.
172   // enable 4K pages for 64M dram. 
173 #if DIMM_PC133
174   pci_write_config8(north,0x69, 0x3c);
175 #else
176   pci_write_config8(north,0x69, 0xac);
177 #endif
178
179   /* IMPORTANT -- disable refresh counter */
180   // refresh counter, disabled.
181   pci_write_config8(north,0x6A, 0x00);
182
183
184   // clkenable configuration. kevinh FIXME - add precharge
185   pci_write_config8(north,0x6C, 0x00);
186   // dram read latch delay of 1 ns, MD drive 8 mA,
187   // high drive strength on MA[2:       13], we#, cas#, ras#
188   // As per Cindy Lee, set to 0x37, not 0x57
189   pci_write_config8(north,0x6D, 0x7f);
190
191   /* Initialize all banks at once */
192
193 }
194
195 /* slot is the dram slot. Base is the *8M base. */
196 static unsigned char 
197 do_module_size(unsigned char slot) { /*, unsigned char base) */
198   static const unsigned char log2[256] = {[1] = 0, [2] = 1, [4] = 2, [8] = 3,
199                              [16]=4, [32]=5, [64]=6, 
200                              [128]=7};
201   static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
202                                         0x56, 0x57};
203   device_t north = 0;
204   /* for all the DRAMS, see if they are there and get the size of each
205    * module. This is just a very early first cut at sizing.
206    */
207   /* we may run out of registers ... */
208   unsigned char width, banks, rows, cols, reg;
209   unsigned char value = 0;
210   unsigned char module = 0xa1 | (slot << 1);
211     /* is the module there? if byte 2 is not 4, then we'll assume it 
212      * is useless. 
213      */
214   if (smbus_read_byte(module, 2) != 4)
215     goto done;
216
217   //print_err_hex8(slot);
218   //    print_err(" is SDRAM\n");
219     width = smbus_read_byte(module, 6) | (smbus_read_byte(module,7)<<0);
220     banks = smbus_read_byte(module, 17);
221     /* we're going to assume symmetric banks. Sorry. */
222     cols = smbus_read_byte(module, 4)  & 0xf;
223     rows = smbus_read_byte(module, 3)  & 0xf;
224     /* grand total. You have rows+cols addressing, * times of banks, times
225      * width of data in bytes*/
226     /* do this in terms of address bits. Then subtract 23 from it. 
227      * That might do it.
228      */
229     value = cols + rows + log2[banks] + log2[width];
230     value -= 23;
231     /* now subtract 3 more bits as these are 8-bit bytes */
232     value -= 3;
233     //    print_err_hex8(value);
234     //    print_err(" is the # bits for this bank\n");
235     /* now put that size into the correct register */
236     value = (1 << value);
237  done:
238     reg = ramregs[slot];
239
240     //    print_err_hex8(value); print_err(" would go into ");
241     //    print_err_hex8(ramregs[reg]); print_err("\n");
242     //    pci_write_config8(north, ramregs[reg], value);
243     return value;
244 }
245
246 static void sdram_set_spd_registers(const struct mem_controller *ctrl) {
247   #define T133 7
248   unsigned char Trp = 1, Tras = 1, casl = 2, val;
249   unsigned char timing = 0xe4;
250   /* read Trp */
251   val = smbus_read_byte(0xa0, 27);
252   if (val < 2*T133)
253     Trp = 1;
254   val = smbus_read_byte(0xa0, 30);
255   if (val < 5*T133)
256     Tras = 0;
257   val = smbus_read_byte(0xa0, 18);
258   if (val < 8)
259     casl = 1;
260   if (val < 4)
261     casl = 0;
262
263   val = (Trp << 7) | (Tras << 6) | (casl << 4) | 4;
264
265   print_err_hex8(val); print_err(" is the computed timing\n");
266   /* don't set it. Experience shows that this screwy chipset should just
267    * be run with the most conservative timing.
268    * pci_write_config8(0, 0x64, val);
269    */
270 }
271
272 static void sdram_enable(int controllers, const struct mem_controller *ctrl) {
273   unsigned char i;
274   static const uint16_t raminit_ma_reg_table[] = {
275     /* Values for MA type register to try */
276     0x0000, 0x8088, 0xe0ee,
277     0xffff // end mark
278   };
279   static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
280                                         0x56, 0x57};
281
282   device_t north = 0;
283   uint8_t c, r, base;
284   /* begin to initialize*/
285   // I forget why we need this, but we do
286   dimms_write(0xa55a5aa5);
287
288   /* set NOP*/
289   pci_write_config8(north,0x6C, 0x01);
290   print_err("NOP\r\n");
291   /* wait 200us*/
292   // You need to do the memory reference. That causes the nop cycle. 
293   dimms_read(0);
294   udelay(400);
295   print_err("PRECHARGE\r\n");
296   /* set precharge */
297   pci_write_config8(north,0x6C, 0x02);
298   print_err("DUMMY READS\r\n");
299   /* dummy reads*/
300   dimms_read(0);
301   udelay(200);
302   print_err("CBR\r\n");
303   /* set CBR*/
304   pci_write_config8(north,0x6C, 0x04);
305         
306   /* do 8 reads and wait >100us between each - from via*/
307   dimms_read(0);
308   udelay(200);
309   dimms_read(0);
310   udelay(200);
311   dimms_read(0);
312   udelay(200);
313   dimms_read(0);
314   udelay(200);
315   dimms_read(0);
316   udelay(200);
317   dimms_read(0);
318   udelay(200);
319   dimms_read(0);
320   udelay(200);
321   dimms_read(0);
322   udelay(200);
323   print_err("MRS\r\n");
324   /* set MRS*/
325   pci_write_config8(north,0x6c, 0x03);
326 #if DIMM_CL2
327   dimms_read(0x150);
328 #else // CL=3
329   dimms_read(0x1d0);
330 #endif
331   udelay(200);
332   print_err("NORMAL\r\n");
333   /* set to normal mode */
334   pci_write_config8(north,0x6C, 0x08);
335
336   dimms_write(0x55aa55aa);
337   dimms_read(0);
338   udelay(200);
339   print_err("set ref. rate\r\n");
340   // Set the refresh rate. 
341 #if DIMM_PC133
342   pci_write_config8(north,0x6A, 0x86);
343 #else
344   pci_write_config8(north,0x6A, 0x65);
345 #endif
346   print_err("enable multi-page open\r\n");
347   // enable multi-page open
348   pci_write_config8(north,0x6B, 0x0d);
349
350   /* Begin auto-detection
351    * Find the first bank with DIMM equipped. */
352
353   /* Maximum possible memory in bank 0, none in other banks.
354    * Starting from bank 0, we fill 0 in these registers
355    * until memory is found. */
356   pci_write_config8(north,0x5A, 0xff);
357   pci_write_config8(north,0x5B, 0xff);
358   pci_write_config8(north,0x5C, 0xff);
359   pci_write_config8(north,0x5D, 0xff);
360   pci_write_config8(north,0x5E, 0xff);
361   pci_write_config8(north,0x5F, 0xff);
362   pci_write_config8(north,0x56, 0xff);
363   pci_write_config8(north,0x57, 0xff);
364   dumpnorth(north);
365   print_err("MA\r\n");
366   for(c = 0; c < 8; c++) {
367     /* Write different values to 0 and 8, then read from 0.
368      * If values of address 0 match, we have something there. */
369     print_err("write to 0\r\n");
370     *(volatile unsigned long *) 0 = 0x12345678;
371
372     /* LEAVE THIS HERE. IT IS ESSENTIAL. OTHERWISE BUFFERING
373      * WILL FOOL YOU!
374      */
375     print_err("write to 8\r\n");
376     *(volatile unsigned long *) 8 = 0x87654321;
377
378     if (*(volatile unsigned long *) 0 != 0x12345678) {
379       print_err("no memory in this bank\r\n");
380       /* No memory in this bank. Tell it to the bridge. */
381       pci_write_config8(north,ramregs[c], 0);
382     } 
383     /* found something */
384     {
385       uint8_t best = 0;
386
387       /* Detect MA mapping type of the bank. */
388
389       for(r = 0; r < 3; r++) {
390         volatile unsigned long esi = 0;
391         volatile unsigned long eax = 0;
392         pci_write_config8(north,0x58, raminit_ma_reg_table[r]);
393
394         * (volatile unsigned long *) eax = 0;
395         print_err(" done write to eax\r\n");
396         // Write to addresses with only one address bit
397         // on, from 0x80000000 to 0x00000008 (lower 3 bits
398         // are ignored, assuming 64-bit bus).  Then what
399         // is read at address 0 is the value written to
400         // the lowest address where it gets
401         // wrap-around. That address is either the size of
402         // the bank, or a missing bit due to incorrect MA
403         // mapping.
404         eax = 0x80000000;
405         while (eax !=  4) {
406           * (volatile unsigned long *) eax = eax;
407           //print_err_hex32(eax);
408           outb(eax&0xff, 0x80);
409           eax >>= 1;
410         }
411         print_err(" done read to eax\r\n");
412         eax = * (unsigned long *)0;
413         /* oh boy ... what is this. 
414            movl 0, %eax
415            cmpl %eax, %esi
416            jnc 3f
417         */
418         print_err("eax and esi: ");
419         print_err_hex32(eax); print_err(" ");
420         print_err_hex32(esi); print_err("\r\n");
421
422         if (eax > esi) { /* ??*/
423                       
424           // This is the current best MA mapping.
425           // Save the address and its MA mapping value.
426           best = r;
427           esi = eax;
428         }
429       }
430                   
431       pci_write_config8(north,0x58, raminit_ma_reg_table[best]);
432       print_err("enabled first bank of ram ... ma is ");
433       print_err_hex8(pci_read_config8(north, 0x58));
434       print_err("\r\n");
435     }
436   }
437   base = 0;
438   /* runs out of variable space. */
439   /* this is unrolled and constants used as much as possible to help
440    * us not run out of registers.
441    * we'll run out of code space instead :-)
442    */
443   //  for(i = 0; i < 8; i++)
444   base = do_module_size(0); /*, base);*/
445   pci_write_config8(north, ramregs[0], base);
446   base = do_module_size(1); /*, base);*/
447   base += pci_read_config8(north, ramregs[0]);
448   pci_write_config8(north, ramregs[1], base);
449   /* runs out of code space. */
450   for(i = 0; i < 8; i++){
451     pci_write_config8(north, ramregs[i], base);
452     /*
453     pci_write_config8(north, ramregs[3], base);
454     pci_write_config8(north, ramregs[4], base);
455     pci_write_config8(north, ramregs[5], base);
456     pci_write_config8(north, ramregs[6], base);
457     pci_write_config8(north, ramregs[7], base);
458     */
459   }
460   /*
461   base = do_module_size(0xa0, base);
462   base = do_module_size(0xa0, base);
463   base = do_module_size(0xa0, base);
464   base = do_module_size(0xa0, base);
465   base = do_module_size(0xa0, base);
466   base = do_module_size(0xa0, base);*/
467   print_err("vt8601 done\n");
468   dumpnorth(north);
469   udelay(1000);
470 }