2 * This file is part of the coreboot project.
4 * Copyright (C) 2008-2010 Joseph Smith <joe@settoplinux.org>
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.
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.
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
24 #include "lib/debug.c"
27 /*-----------------------------------------------------------------------------
28 Macros and definitions.
29 -----------------------------------------------------------------------------*/
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))
36 #define PRINTK_DEBUG(x...)
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)
46 #define RAM_COMMAND_REFRESH 0x1
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
56 /* DRC[29] - Initialization Complete (IC). */
57 #define RAM_COMMAND_IC 0x1
59 /*-----------------------------------------------------------------------------
60 DIMM-initialization functions.
61 -----------------------------------------------------------------------------*/
63 static void do_ram_command(u32 command)
67 /* Configure the RAM command. */
68 reg32 = pci_read_config32(NORTHBRIDGE, DRC);
69 /* Clear bits 29, 10-8, 6-4. */
71 reg32 |= command << 4;
72 PRINTK_DEBUG(" Sending RAM command 0x%08x", reg32);
73 pci_write_config32(NORTHBRIDGE, DRC, reg32);
76 static void ram_read32(u8 dimm_start, u32 offset)
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);
87 PRINTK_DEBUG(" to 0x%08x\n", base_addr + offset);
88 read32(base_addr + offset);
92 static void initialize_dimm_rows(void)
95 u8 dimm_start, dimm_end;
100 for (row = 0; row < (DIMM_SOCKETS * 2); row++) {
117 dimm_end = pci_read_config8(NORTHBRIDGE, DRB + row);
119 if (dimm_end > dimm_start) {
120 printk(BIOS_DEBUG, "Initializing SDRAM Row %u\n", row);
123 PRINTK_DEBUG(" NOP\n");
124 do_ram_command(RAM_COMMAND_NOP);
125 ram_read32(dimm_start, 0);
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);
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);
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);
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);
155 /* Perform a dummy memory read/write cycle */
156 PRINTK_DEBUG(" Performing dummy read/write\n");
157 ram_read32(dimm_start, 0x55aa55aa);
160 /* Set the start of the next DIMM. */
161 dimm_start = dimm_end;
165 /*-----------------------------------------------------------------------------
166 DIMM-independant configuration functions.
167 -----------------------------------------------------------------------------*/
174 static struct dimm_size spd_get_dimm_size(unsigned device)
177 int i, module_density, dimm_banks;
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);
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) {
191 /* Set to 0 in case it's single sided. */
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)) {
206 /* If not, it's symmetrical */
212 /* SPD byte 31 is the memory size divided by 4 so we
213 * need to muliply by 4 to get the total size.
220 static void set_dram_row_boundaries(void)
222 int i, value, drb1, drb2;
224 for (i = 0; i < DIMM_SOCKETS; i++) {
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);
238 /* - Memory compatibility checks - */
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");
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");
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.
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");
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");
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");
273 /* - End Memory compatibility checks - */
275 /* We need to divide size by 32 to set up the
279 drb1 = sz.side1 / 32;
281 drb2 = sz.side2 / 32;
283 printk(BIOS_DEBUG, "No DIMM found in slot %u\n", i);
285 /* If there's no DIMM in the slot, set value to 0. */
289 /* Set the value for DRAM Row Boundary Registers */
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);
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);
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.
306 value = pci_read_config8(NORTHBRIDGE, DRB + 3);
307 pci_write_config8(NORTHBRIDGE, DRB + 4, value);
308 pci_write_config8(NORTHBRIDGE, DRB + 5, value);
313 static void set_dram_row_attributes(void)
315 int i, dra, col, width, value;
317 for (i = 0; i < DIMM_SOCKETS; i++) {
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);
328 col = spd_read_byte(device, SPD_NUM_COLUMNS);
331 width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
333 /* calculate page size in bits */
334 value = ((1 << col) * width);
336 /* convert to Kilobytes */
337 dra = ((value / 8) >> 10);
339 /* # of banks of DIMM (single or double sided) */
340 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
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 */
352 printk(BIOS_ERR, "Page size not supported\n");
355 } else if (value == 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 */
365 printk(BIOS_ERR, "Page size not supported\n");
369 printk(BIOS_ERR, "# of banks of DIMM not supported\n");
374 PRINTK_DEBUG("No DIMM found in slot %u\n", i);
376 /* If there's no DIMM in the slot, set dra value to 0xFF. */
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);
386 static void set_dram_timing(void)
388 /* Set the value for DRAM Timing Register */
389 /* TODO: Configure the value according to SPD values. */
390 pci_write_config32(NORTHBRIDGE, DRT, 0x00000010);
393 static void set_dram_buffer_strength(void)
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
401 /* Set the value for System Memory Buffer Strength Control Registers */
402 pci_write_config32(NORTHBRIDGE, BUFF_SC, 0xFC9B491B);
405 /*-----------------------------------------------------------------------------
407 -----------------------------------------------------------------------------*/
409 static void sdram_set_registers(void)
411 printk(BIOS_DEBUG, "Setting initial SDRAM registers....\n");
413 /* Calculate the value for DRT DRAM Timing Register */
416 /* Setup System Memory Buffer Strength Control Registers */
417 set_dram_buffer_strength();
419 /* Setup DRAM Row Boundary Registers */
420 set_dram_row_boundaries();
422 /* Setup DRAM Row Attribute Registers */
423 set_dram_row_attributes();
425 printk(BIOS_DEBUG, "Initial SDRAM registers have been set.\n");
428 static void northbridge_set_registers(void)
433 printk(BIOS_DEBUG, "Setting initial Nothbridge registers....\n");
435 /* Set the value for Fixed DRAM Hole Control Register */
436 pci_write_config8(NORTHBRIDGE, FDHC, 0x00);
438 /* Set the value for Programable Attribute Map Registers
439 * Ideally, this should be R/W for as many ranges as possible.
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);
449 /* Set the value for System Management RAM Control Register */
450 pci_write_config8(NORTHBRIDGE, SMRAM, 0x02);
452 /* Set the value for GMCH Control Register #0 */
453 pci_write_config16(NORTHBRIDGE, GCC0, 0xA072);
455 /* Set the value for Aperture Base Configuration Register */
456 pci_write_config32(NORTHBRIDGE, APBASE, 0x00000008);
458 /* Set the value for GMCH Control Register #1 */
459 switch (CONFIG_VIDEO_MB) {
460 case 512: /* 512K of memory */
463 case 1: /* 1M of memory */
466 case 8: /* 8M of memory */
469 default: /* No memory */
470 pci_write_config16(NORTHBRIDGE, GCC1, 0x0002);
474 value = pci_read_config16(NORTHBRIDGE, GCC1);
475 value |= igd_memory << 4;
476 value |= 1; // 64MB aperture
477 pci_write_config16(NORTHBRIDGE, GCC1, value);
479 printk(BIOS_DEBUG, "Initial Northbridge registers have been set.\n");
482 static void sdram_initialize(void)
486 /* Setup Initial SDRAM Registers */
487 sdram_set_registers();
489 /* Wait until power/voltages and clocks are stable (200us). */
492 /* Initialize each row of memory one at a time */
493 initialize_dimm_rows();
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);
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);
507 /* Setup Initial Northbridge Registers */
508 northbridge_set_registers();
510 PRINTK_DEBUG("Northbridge following SDRAM init:\n");