This patch allows support for multiple so-dimms, single or double sided.
[coreboot.git] / src / northbridge / intel / i82830 / raminit.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  *
20  */
21
22 #include <spd.h>
23 #include <sdram_mode.h>
24 #include <delay.h>
25 #include "debug.c"
26 #include "i82830.h"
27
28 /*-----------------------------------------------------------------------------
29 Macros and definitions.
30 -----------------------------------------------------------------------------*/
31
32 /* Uncomment this to enable debugging output. */
33 /* #define DEBUG_RAM_SETUP 1 */
34
35 /* Debugging macros. */
36 #if defined(DEBUG_RAM_SETUP)
37 #define PRINT_DEBUG(x)          print_debug(x)
38 #define PRINT_DEBUG_HEX8(x)     print_debug_hex8(x)
39 #define PRINT_DEBUG_HEX16(x)    print_debug_hex16(x)
40 #define PRINT_DEBUG_HEX32(x)    print_debug_hex32(x)
41 #define DUMPNORTH()             dump_pci_device(PCI_DEV(0, 0, 0))
42 #else
43 #define PRINT_DEBUG(x)
44 #define PRINT_DEBUG_HEX8(x)
45 #define PRINT_DEBUG_HEX16(x)
46 #define PRINT_DEBUG_HEX32(x)
47 #define DUMPNORTH()
48 #endif
49
50 /* DRC[10:8] - Refresh Mode Select (RMS).
51  * 0x0 for Refresh Disabled (Self Refresh)
52  * 0x1 for Refresh interval 15.6 us for 133MHz
53  * 0x2 for Refresh interval 7.8 us for 133MHz
54  * 0x7 /* Refresh interval 128 Clocks. (Fast Refresh Mode)
55  */
56 #define RAM_COMMAND_REFRESH             0x1
57
58 /* DRC[6:4] - SDRAM Mode Select (SMS). */
59 #define RAM_COMMAND_SELF_REFRESH        0x0
60 #define RAM_COMMAND_NOP                 0x1
61 #define RAM_COMMAND_PRECHARGE           0x2
62 #define RAM_COMMAND_MRS                 0x3
63 #define RAM_COMMAND_CBR                 0x6
64 #define RAM_COMMAND_NORMAL              0x7
65
66 /* DRC[29] - Initialization Complete (IC). */
67 #define RAM_COMMAND_IC                  0x1
68
69 /*-----------------------------------------------------------------------------
70 SDRAM configuration functions.
71 -----------------------------------------------------------------------------*/
72
73 /* Send the specified RAM command to all DIMMs. */
74
75 static void do_ram_command(const struct mem_controller *ctrl, uint32_t command,
76                            uint32_t addr_offset)
77 {
78         int i;
79         uint8_t dimm_start, dimm_end;
80         uint32_t reg32;
81
82         /* Configure the RAM command. */
83         reg32 = pci_read_config32(ctrl->d0, DRC);
84         /* Clear bits 29, 10-8, 6-4. */
85         reg32 &= 0xdffff88f;
86         reg32 |= command << 4;
87         pci_write_config32(ctrl->d0, DRC, reg32);
88
89         /* Send the ram command to each row of memory.
90          * (DIMM_SOCKETS * 2) is the maximum number of rows possible.
91          * Note: Each DRB defines the upper boundary address of 
92          * each SDRAM row in 32-MB granularity.
93          */
94         dimm_start = 0;
95
96         for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
97                 dimm_end = pci_read_config8(ctrl->d0, DRB + i);
98                 if (dimm_end > dimm_start) {
99                         PRINT_DEBUG("    Sending RAM command 0x");
100                         PRINT_DEBUG_HEX32(reg32);
101                         PRINT_DEBUG(" to 0x");
102                         PRINT_DEBUG_HEX32((dimm_start * 32 * 1024 * 1024) + addr_offset);
103                         PRINT_DEBUG("\r\n");
104                         read32((dimm_start * 32 * 1024 * 1024) + addr_offset);
105                 }
106                 /* Set the start of the next DIMM. */
107                 dimm_start = dimm_end;
108         }
109 }
110
111 /*-----------------------------------------------------------------------------
112 DIMM-independant configuration functions.
113 -----------------------------------------------------------------------------*/
114
115 struct dimm_size {
116         unsigned long side1;
117         unsigned long side2;
118 };
119
120 static struct dimm_size spd_get_dimm_size(unsigned device)
121 {
122         struct dimm_size sz;
123         int i, module_density, dimm_banks;
124         sz.side1 = 0;
125         module_density = spd_read_byte(device, 31);
126         dimm_banks = spd_read_byte(device, 5);
127
128         /* Find the size of side1. */
129         /* Find the larger value. The larger value is always side1. */
130         for (i = 512; i >= 0; i >>= 1) {
131                 if ((module_density & i) == i) {
132                         sz.side1 = i;
133                         break;
134                 }
135         }
136
137         /* Set to 0 in case it's single sided. */
138         sz.side2 = 0;
139
140         /* Test if it's a dual-sided DIMM. */
141         if (dimm_banks > 1) {
142                 /* Test to see if there's a second value, if so it's asymmetrical. */
143                 if (module_density != i) {
144                         /* Find the second value, picking up where we left off. */
145                         /* i >>= 1 done initially to make sure we don't get the same value again. */
146                         for (i >>= 1; i >= 0; i >>= 1) {
147                                 if (module_density == (sz.side1 | i)) {
148                                         sz.side2 = i;
149                                         break;
150                                 }
151                         }
152                         /* If not, it's symmetrical */
153                 } else {
154                         sz.side2 = sz.side1;
155                 }
156         }
157
158         /* SPD byte 31 is the memory size divided by 4 so we
159          * need to muliply by 4 to get the total size.
160          */
161         sz.side1 *= 4;
162         sz.side2 *= 4;
163         return sz;
164 }
165
166 static void spd_set_dram_size(const struct mem_controller *ctrl)
167 {
168         int i, value, drb1, drb2;
169
170         for (i = 0; i < DIMM_SOCKETS; i++) {
171                 struct dimm_size sz;
172                 unsigned device;
173                 device = ctrl->channel0[i];
174                 drb1 = 0;
175                 drb2 = 0;
176
177                 /* First check if a DIMM is actually present. */
178                 if (spd_read_byte(device, 2) == 0x4) {
179                         print_debug("Found DIMM in slot ");
180                         print_debug_hex8(i);
181                         print_debug("\r\n");
182
183                         sz = spd_get_dimm_size(device);
184
185                         /* WISHLIST: would be nice to display it as decimal? */
186                         print_debug("DIMM is 0x");
187                         print_debug_hex16(sz.side1);
188                         print_debug(" on side 1\r\n");
189                         print_debug("DIMM is 0x");
190                         print_debug_hex16(sz.side2);
191                         print_debug(" on side 2\r\n");
192
193                         /* Test for PC133 (i82830 only supports PC133) */
194                         /* PC133 SPD9 - cycle time is always 75 */
195                         if (spd_read_byte(device, 9) != 0x75) {
196                                 print_err("SPD9 DIMM Is Not PC133 Compatable\r\n");
197                                 die("HALT\r\n");
198                         }
199                         /* PC133 SPD10 - access time is always 54 */
200                         if (spd_read_byte(device, 10) != 0x54) {
201                                 print_err("SPD10 DIMM Is Not PC133 Compatable\r\n");
202                                 die("HALT\r\n");
203                         }
204
205                         /* The i82830 only supports a symmetrical dual-sided dimms
206                          * and can't handle DIMMs smaller than 32MB per
207                          * side or larger than 256MB per side.
208                          */
209                         if ((sz.side2 != 0) && (sz.side1 != sz.side2)) {
210                                 print_err("This northbridge only supports\r\n");
211                                 print_err("symmetrical dual-sided DIMMs\r\n");
212                                 print_err("booting as a single-sided DIMM\r\n");
213                                 sz.side2 = 0;
214                         }
215                         if ((sz.side1 < 32)) {
216                                 print_err("DIMMs smaller than 32MB per side\r\n");
217                                 print_err("are not supported on this northbridge\r\n");
218                                 die("HALT\r\n");
219                         }
220
221                         if ((sz.side1 > 256)) {
222                                 print_err
223                                     ("DIMMs larger than 256MB per side\r\n");
224                                 print_err
225                                     ("are not supported on this northbridge\r\n");
226                                 die("HALT\r\n");
227                         }
228
229                         /* We need to divide size by 32 to set up the
230                          * DRB registers.
231                          */
232                         if (sz.side1)
233                                 drb1 = sz.side1 / 32;
234                         if (sz.side2)
235                                 drb2 = sz.side2 / 32;
236                 } else {
237                         PRINT_DEBUG("No DIMM found in slot ");
238                         PRINT_DEBUG_HEX8(i);
239                         PRINT_DEBUG("\r\n");
240
241                         /* If there's no DIMM in the slot, set value to 0. */
242                         drb1 = 0;
243                         drb2 = 0;
244                 }
245                 /* Set the value for DRAM Row Boundary Registers */
246                 if (i == 0) {
247                         pci_write_config8(ctrl->d0, DRB, drb1);
248                         pci_write_config8(ctrl->d0, DRB + 1, drb1 + drb2);
249                         PRINT_DEBUG("DRB 0x");
250                         PRINT_DEBUG_HEX8(DRB);
251                         PRINT_DEBUG(" has been set to 0x");
252                         PRINT_DEBUG_HEX8(drb1);
253                         PRINT_DEBUG("\r\n");
254                         PRINT_DEBUG("DRB1 0x");
255                         PRINT_DEBUG_HEX8(DRB + 1);
256                         PRINT_DEBUG(" has been set to 0x");
257                         PRINT_DEBUG_HEX8(drb1 + drb2);
258                         PRINT_DEBUG("\r\n");
259                 } else if (i == 1) {
260                         value = pci_read_config8(ctrl->d0, DRB + 1);
261                         pci_write_config8(ctrl->d0, DRB + 2, value + drb1);
262                         pci_write_config8(ctrl->d0, DRB + 3,
263                                           value + drb1 + drb2);
264                         PRINT_DEBUG("DRB2 0x");
265                         PRINT_DEBUG_HEX8(DRB + 2);
266                         PRINT_DEBUG(" has been set to 0x");
267                         PRINT_DEBUG_HEX8(value + drb1);
268                         PRINT_DEBUG("\r\n");
269                         PRINT_DEBUG("DRB3 0x");
270                         PRINT_DEBUG_HEX8(DRB + 3);
271                         PRINT_DEBUG(" has been set to 0x");
272                         PRINT_DEBUG_HEX8(value + drb1 + drb2);
273                         PRINT_DEBUG("\r\n");
274
275                         /* We need to set the highest DRB value to 0x64 and 0x65.
276                          * These are supposed to be "Reserved" but memory will
277                          * not initialize properly if we don't.
278                          */
279                         value = pci_read_config8(ctrl->d0, DRB + 3);
280                         pci_write_config8(ctrl->d0, DRB + 4, value);
281                         pci_write_config8(ctrl->d0, DRB + 5, value);
282                 }
283         }
284 }
285
286 static void set_dram_row_attributes(const struct mem_controller *ctrl)
287 {
288         int i, dra, col, width, value;
289
290         for (i = 0; i < DIMM_SOCKETS; i++) {
291                 unsigned device;
292                 device = ctrl->channel0[i];
293
294                 /* First check if a DIMM is actually present. */
295                 if (spd_read_byte(device, 2) == 0x4) {
296                         print_debug("Found DIMM in slot ");
297                         print_debug_hex8(i);
298                         print_debug(", setting DRA...\r\n");
299
300                         dra = 0x00;
301
302                         /* columns */
303                         col = spd_read_byte(device, 4);
304
305                         /* data width */
306                         width = spd_read_byte(device, 6);
307
308                         /* calculate page size in bits */
309                         value = ((1 << col) * width);
310
311                         /* convert to Kilobytes */
312                         dra = ((value / 8) >> 10);
313
314                         /* # of banks of DIMM (single or double sided) */
315                         value = spd_read_byte(device, 5);
316
317                         if (value == 1) {
318                                 if (dra == 2) {
319                                         dra = 0xF0; /* 2KB */
320                                 } else if (dra == 4) {
321                                         dra = 0xF1; /* 4KB */
322                                 } else if (dra == 8) {
323                                         dra = 0xF2; /* 8KB */
324                                 } else if (dra == 16) {
325                                         dra = 0xF3; /* 16KB */
326                                 } else {
327                                         print_err("Page size not supported\r\n");
328                                         die("HALT\r\n");
329                                 }
330                         } else if (value == 2) {
331                                 if (dra == 2) {
332                                         dra = 0x00; /* 2KB */
333                                 } else if (dra == 4) {
334                                         dra = 0x11; /* 4KB */
335                                 } else if (dra == 8) {
336                                         dra = 0x22; /* 8KB */
337                                 } else if (dra == 16) {
338                                         dra = 0x33; /* 16KB */
339                                 } else {
340                                         print_err("Page size not supported\r\n");
341                                         die("HALT\r\n");
342                                 }
343                         } else {
344                                 print_err("# of banks of DIMM not supported\r\n");
345                                 die("HALT\r\n");
346                         }
347
348                 } else {
349                         PRINT_DEBUG("No DIMM found in slot ");
350                         PRINT_DEBUG_HEX8(i);
351                         PRINT_DEBUG(", setting DRA to 0xFF\r\n");
352
353                         /* If there's no DIMM in the slot, set dra value to 0xFF. */
354                         dra = 0xFF;
355                 }
356
357                 /* Set the value for DRAM Row Attribute Registers */
358                 pci_write_config8(ctrl->d0, DRA + i, dra);
359                 PRINT_DEBUG("DRA 0x");
360                 PRINT_DEBUG_HEX8(DRA + i);
361                 PRINT_DEBUG(" has been set to 0x");
362                 PRINT_DEBUG_HEX8(dra);
363                 PRINT_DEBUG("\r\n");
364         }
365 }
366
367 static void set_dram_timing(const struct mem_controller *ctrl)
368 {
369         /* Set the value for DRAM Timing Register */
370         /* TODO: Configure the value according to SPD values. */
371         pci_write_config32(ctrl->d0, DRT, 0x00000010);
372 }
373
374 static void set_dram_buffer_strength(const struct mem_controller *ctrl)
375 {
376         /* TODO: This needs to be set according to the DRAM tech
377          * (x8, x16, or x32). Argh, Intel provides no docs on this!
378          * Currently, it needs to be pulled from the output of
379          * lspci -xxx Rx92
380          */
381
382         /* Set the value for System Memory Buffer Strength Control Registers */
383         pci_write_config32(ctrl->d0, BUFF_SC, 0xFC9B491B);
384 }
385
386 /*-----------------------------------------------------------------------------
387 Public interface.
388 -----------------------------------------------------------------------------*/
389
390 static void sdram_set_registers(const struct mem_controller *ctrl)
391 {
392         uint16_t value;
393         int igd_memory = 0;
394
395         PRINT_DEBUG("Setting initial registers....\r\n");
396
397         /* Set the value for GMCH Control Register #0 */
398         pci_write_config16(ctrl->d0, GCC0, 0xA072);
399
400         /* Set the value for GMCH Control Register #1 */
401         switch (CONFIG_VIDEO_MB) {
402         case 512: /* 512K of memory */
403                 igd_memory = 0x2;
404                 break;
405         case 1: /* 1M of memory */
406                 igd_memory = 0x3;
407                 break;
408         case 8: /* 8M of memory */
409                 igd_memory = 0x4;
410                 break;
411         default: /* No memory */
412                 pci_write_config16(ctrl->d0, GCC1, 0x0002);
413                 igd_memory = 0x0;
414         }
415
416         value = pci_read_config16(ctrl->d0, GCC1);
417         value |= igd_memory << 4;
418         pci_write_config16(ctrl->d0, GCC1, value);
419
420         /* Set the value for Aperture Base Configuration Register */
421         pci_write_config32(ctrl->d0, APBASE, 0x00000008);
422
423         /* Set the value for Register Range Base Address Register */
424         pci_write_config32(ctrl->d0, RRBAR, 0x00000000);
425
426         /* Set the value for Fixed DRAM Hole Control Register */
427         pci_write_config8(ctrl->d0, FDHC, 0x00);
428
429         /* Set the value for Programable Attribute Map Registers
430          * Ideally, this should be R/W for as many ranges as possible.
431          */
432         pci_write_config8(ctrl->d0, PAM0, 0x30);
433         pci_write_config8(ctrl->d0, PAM1, 0x33);
434         pci_write_config8(ctrl->d0, PAM2, 0x33);
435         pci_write_config8(ctrl->d0, PAM3, 0x33);
436         pci_write_config8(ctrl->d0, PAM4, 0x33);
437         pci_write_config8(ctrl->d0, PAM5, 0x33);
438         pci_write_config8(ctrl->d0, PAM6, 0x33);
439
440         /* Set the value for DRAM Throttling Control Register */
441         pci_write_config32(ctrl->d0, DTC, 0x00000000);
442
443         /* Set the value for System Management RAM Control Register */
444         pci_write_config8(ctrl->d0, SMRAM, 0x02);
445
446         /* Set the value for Extended System Management RAM Control Register */
447         pci_write_config8(ctrl->d0, ESMRAMC, 0x38);
448
449         PRINT_DEBUG("Initial registers have been set.\r\n");
450 }
451
452 static void sdram_set_spd_registers(const struct mem_controller *ctrl)
453 {
454         spd_set_dram_size(ctrl);
455         set_dram_row_attributes(ctrl);
456         set_dram_timing(ctrl);
457         set_dram_buffer_strength(ctrl);
458 }
459
460 static void sdram_enable(int controllers, const struct mem_controller *ctrl)
461 {
462         int i;
463         uint32_t reg32;
464
465         /* 0. Wait until power/voltages and clocks are stable (200us). */
466         udelay(200);
467
468         /* 1. Apply NOP. */
469         PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n");
470         do_ram_command(ctrl, RAM_COMMAND_NOP, 0);
471         udelay(200);
472
473         /* 2. Precharge all. Wait tRP. */
474         PRINT_DEBUG("RAM Enable 2: Precharge all\r\n");
475         do_ram_command(ctrl, RAM_COMMAND_PRECHARGE, 0);
476         udelay(1);
477
478         /* 3. Perform 8 refresh cycles. Wait tRC each time. */
479         PRINT_DEBUG("RAM Enable 3: CBR\r\n");
480         for (i = 0; i < 8; i++) {
481                 do_ram_command(ctrl, RAM_COMMAND_CBR, 0);
482                 udelay(1);
483         }
484
485         /* 4. Mode register set. Wait two memory cycles. */
486         /* TODO: Set offset according to DRT values */
487         PRINT_DEBUG("RAM Enable 4: Mode register set\r\n");
488         do_ram_command(ctrl, RAM_COMMAND_MRS, 0x1d0);
489         udelay(2);
490
491         /* 5. Normal operation (enables refresh) */
492         PRINT_DEBUG("RAM Enable 5: Normal operation\r\n");
493         do_ram_command(ctrl, RAM_COMMAND_NORMAL, 0);
494         udelay(1);
495
496         /* 6. Enable refresh and Set initialization complete. */
497         PRINT_DEBUG("RAM Enable 6: Enable Refresh and IC\r\n");
498         reg32 = pci_read_config32(ctrl->d0, DRC);
499         reg32 |= ((RAM_COMMAND_REFRESH << 8) | (RAM_COMMAND_IC << 29));
500         pci_write_config32(ctrl->d0, DRC, reg32);
501
502         PRINT_DEBUG("Northbridge following SDRAM init:\r\n");
503         DUMPNORTH();
504 }