2 * This file is part of the LinuxBIOS project.
4 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sdram_mode.h>
27 /*-----------------------------------------------------------------------------
28 Macros and definitions.
29 -----------------------------------------------------------------------------*/
31 /* Uncomment this to enable debugging output. */
32 // #define DEBUG_RAM_SETUP 1
34 /* Debugging macros. */
35 #if defined(DEBUG_RAM_SETUP)
36 #define PRINT_DEBUG(x) print_debug(x)
37 #define PRINT_DEBUG_HEX8(x) print_debug_hex8(x)
38 #define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
39 #define PRINT_DEBUG_HEX32(x) print_debug_hex32(x)
40 #define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
42 #define PRINT_DEBUG(x)
43 #define PRINT_DEBUG_HEX8(x)
44 #define PRINT_DEBUG_HEX16(x)
45 #define PRINT_DEBUG_HEX32(x)
49 /* DRAMT[7:5] - SDRAM Mode Select (SMS). */
50 #define RAM_COMMAND_SELF_REFRESH 0x0 /* IE disable refresh */
51 #define RAM_COMMAND_NORMAL 0x1 /* Normal refresh, 15.6us/11.7us for 100/133MHz */
52 #define RAM_COMMAND_NORMAL_FR 0x2 /* Fast refresh, 7.8us/5.85us for 100/133MHz */
53 #define RAM_COMMAND_NOP 0x4
54 #define RAM_COMMAND_PRECHARGE 0x5
55 #define RAM_COMMAND_MRS 0x6
56 #define RAM_COMMAND_CBR 0x7
58 /*-----------------------------------------------------------------------------
59 SDRAM configuration functions.
60 -----------------------------------------------------------------------------*/
63 * Send the specified RAM command to all DIMMs.
65 * @param Memory controller
69 static void do_ram_command(const struct mem_controller *ctrl, uint32_t command,
70 uint32_t addr_offset, uint32_t row_offset)
74 /* TODO: Support for multiple DIMMs. */
76 /* Configure the RAM command. */
77 reg = pci_read_config8(ctrl->d0, DRAMT);
78 reg &= 0x1f; /* Clear bits 7-5. */
80 pci_write_config8(ctrl->d0, DRAMT, reg);
82 /* RAM_COMMAND_NORMAL affects only the memory controller and
83 doesn't need to be "sent" to the DIMMs. */
84 /* if (command == RAM_COMMAND_NORMAL) return; */
86 PRINT_DEBUG(" Sending RAM command 0x");
87 PRINT_DEBUG_HEX8(reg);
88 PRINT_DEBUG(" to 0x");
89 PRINT_DEBUG_HEX32(0 + addr_offset); // FIXME
92 /* Read from (DIMM start address + addr_offset). */
93 read32(0 + addr_offset); //first offset is always 0
94 read32(row_offset + addr_offset);
97 /*-----------------------------------------------------------------------------
98 DIMM-independant configuration functions.
99 -----------------------------------------------------------------------------*/
101 static void spd_set_dram_size(const struct mem_controller *ctrl,
104 /* The variables drp and dimm_size have to be ints since all the
105 * SMBus-related functions return ints, and its just easier this way.
107 int i, drp, dimm_size;
111 for (i = 0; i < DIMM_SOCKETS; i++) {
112 /* First check if a DIMM is actually present. */
113 if (smbus_read_byte(ctrl->channel0[i], 2) == 4) {
114 print_debug("Found DIMM in slot ");
118 dimm_size = smbus_read_byte(ctrl->channel0[i], 31);
120 /* WISHLIST: would be nice to display it as decimal? */
121 print_debug("DIMM is 0x");
122 print_debug_hex8(dimm_size * 4);
123 print_debug("MB\r\n");
125 /* The i810 can't handle DIMMs larger than 128MB per
126 * side. This will fail if the DIMM uses a
127 * non-supported DRAM tech, and can't be used until
128 * buffers are done dynamically.
129 * Note: the factory BIOS just dies if it spots this :D
131 if (dimm_size > 32) {
132 print_err("DIMM row sizes larger than 128MB not"
133 "supported on i810\r\n");
135 ("Attempting to treat as 128MB DIMM\r\n");
139 /* Set the row offset, in KBytes (should this be
140 * Kbits?). Note that this offset is the start of the
143 row_offset = (dimm_size * 4 * 1024);
145 /* This is the way I was doing this, it's provided
146 * mainly as an alternative to the "new" way.
151 if (dimm_size == 0x2)
154 else if (dimm_size == 0x4)
157 else if (dimm_size == 0x8)
160 else if (dimm_size == 0x10)
163 else if (dimm_size == 0x20)
166 print_debug("Ram Size not supported\r\n");
169 /* This array is provided in raminit.h, because it got
170 * extremely messy. The above way is cleaner, but
171 * doesn't support any asymetrical/odd configurations.
173 dimm_size = translate_spd_to_i82810[dimm_size];
175 print_debug("After translation, dimm_size is 0x");
176 print_debug_hex8(dimm_size);
179 /* If the DIMM is dual-sided, the DRP value is +2 */
180 /* TODO: Figure out asymetrical configurations. */
181 if ((smbus_read_byte(ctrl->channel0[i], 127) | 0xf) ==
183 print_debug("DIMM is dual-sided\r\n");
187 print_debug("No DIMM found in slot ");
191 /* If there's no DIMM in the slot, set value to 0. */
195 /* Put in dimm_size to reflect the current DIMM. */
196 drp |= dimm_size << (i * 4);
199 print_debug("DRP calculated to 0x");
200 print_debug_hex8(drp);
203 pci_write_config8(ctrl->d0, DRP, drp);
206 static void set_dram_timing(const struct mem_controller *ctrl)
208 /* TODO, for now using default, hopefully safe values. */
209 // pci_write_config8(ctrl->d0, DRAMT, 0x00);
212 static void set_dram_buffer_strength(const struct mem_controller *ctrl)
214 /* TODO: This needs to be set according to the DRAM tech
215 * (x8, x16, or x32). Argh, Intel provides no docs on this!
216 * Currently, it needs to be pulled from the output of
219 pci_write_config16(ctrl->d0, BUFF_SC, 0x77da);
222 /*-----------------------------------------------------------------------------
224 -----------------------------------------------------------------------------*/
229 * @param Memory controller
231 static void sdram_set_registers(const struct mem_controller *ctrl)
236 pci_write_config8(ctrl->d0, GMCHCFG, 0x60);
238 /* PAMR: Programmable Attributes Register
239 * Every pair of bits controls an address range:
240 * 00 = Disabled, all accesses are forwarded to the ICH
246 * 7:6 000F0000 - 000FFFFF
247 * 5:4 000E0000 - 000EFFFF
248 * 3:2 000D0000 - 000DFFFF
249 * 1:0 000C0000 - 000CFFFF
252 /* Ideally, this should be R/W for as many ranges as possible. */
253 pci_write_config8(ctrl->d0, PAM, 0xff);
255 /* Enabling the VGA Framebuffer currently screws up the rest of the boot.
258 /* Enable 1MB framebuffer. */
259 //pci_write_config8(ctrl->d0, SMRAM, 0xC0);
261 //val = pci_read_config16(ctrl->d0, MISSC);
262 /* Preserve reserved bits. */
264 /* Set graphics cache window to 32MB, no power throttling. */
266 //pci_write_config16(ctrl->d0, MISSC, val);
268 //val = pci_read_config8(ctrl->d0, MISSC2);
269 /* Enable graphics palettes and clock gating (not optional!) */
271 //pci_write_config8(ctrl->d0, MISSC2, val);
277 * @param Memory controller
279 static void sdram_set_spd_registers(const struct mem_controller *ctrl)
281 /* spd_set_dram_size() moved into sdram_enable() to prevent having
282 * to pass a variable between here and there.
284 set_dram_buffer_strength(ctrl);
286 set_dram_timing(ctrl);
292 * @param Number of controllers
293 * @param Memory controller
295 static void sdram_enable(int controllers, const struct mem_controller *ctrl)
299 /* Todo: this will currently work with either one dual sided or two
300 * single sided DIMMs. Needs to work with 2 dual sided DIMMs in the
305 spd_set_dram_size(ctrl, row_offset);
308 PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n");
309 do_ram_command(ctrl, RAM_COMMAND_NOP, 0, row_offset);
312 /* 2. Precharge all. Wait tRP. */
313 PRINT_DEBUG("RAM Enable 2: Precharge all\r\n");
314 do_ram_command(ctrl, RAM_COMMAND_PRECHARGE, 0, row_offset);
317 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
318 PRINT_DEBUG("RAM Enable 3: CBR\r\n");
319 do_ram_command(ctrl, RAM_COMMAND_CBR, 0, row_offset);
320 for (i = 0; i < 8; i++) {
326 /* 4. Mode register set. Wait two memory cycles. */
327 PRINT_DEBUG("RAM Enable 4: Mode register set\r\n");
328 do_ram_command(ctrl, RAM_COMMAND_MRS, 0x1d0, row_offset);
331 /* 5. Normal operation (enables refresh) */
332 PRINT_DEBUG("RAM Enable 5: Normal operation\r\n");
333 do_ram_command(ctrl, RAM_COMMAND_NORMAL, 0, row_offset);
336 PRINT_DEBUG("Northbridge following SDRAM init:\r\n");