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