2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2008 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.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
27 /*-----------------------------------------------------------------------------
28 Macros and definitions.
29 -----------------------------------------------------------------------------*/
31 /* Uncomment this to enable debugging output. */
33 /* Debugging macros. */
34 #if CONFIG_DEBUG_RAM_SETUP
35 #define PRINT_DEBUG(x) print_debug(x)
36 #define PRINT_DEBUG_HEX8(x) print_debug_hex8(x)
37 #define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
38 #define PRINT_DEBUG_HEX32(x) print_debug_hex32(x)
39 #define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
41 #define PRINT_DEBUG(x)
42 #define PRINT_DEBUG_HEX8(x)
43 #define PRINT_DEBUG_HEX16(x)
44 #define PRINT_DEBUG_HEX32(x)
48 #define NB PCI_DEV(0, 0, 0)
50 /* DRAMXC[7:5] - DRAM extended control register (SMS). */
51 #define RAM_COMMAND_NORMAL 0x0
52 #define RAM_COMMAND_NOP 0x1 // (NOPCE)
53 #define RAM_COMMAND_PRECHARGE 0x2 // ABPCE
54 #define RAM_COMMAND_MRS 0x3 // MRSCE
55 #define RAM_COMMAND_CBR 0x4 // CBRC
58 /* Table format: register, bitmask, value. */
59 static const long register_values[] = {
62 // BASE is 0x8A but we dont want bit 9 or 10 have ENABLED so 0x8C
63 PACCFG + 1, 0x38, 0x8c,
70 DRAMC, 0x00, 0x00, /* disable refresh for now. */
73 PAM0, 0x00, 0x30, // everything is a mem
81 /* Set the DRBs to zero for now, this will be fixed later. */
91 /* No memory holes. */
95 /*-----------------------------------------------------------------------------
96 SDRAM configuration functions.
97 -----------------------------------------------------------------------------*/
100 * Send the specified RAM command to all DIMMs.
102 * @param command The RAM command to send to the DIMM(s).
104 static void do_ram_command(u32 command)
107 u8 dimm_start, dimm_end;
109 u32 addr, addr_offset;
111 /* Configure the RAM command. */
112 reg16 = pci_read_config16(NB, DRAMXC);
113 reg16 &= 0xff1f; /* Clear bits 7-5. */
114 reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
115 pci_write_config16(NB, DRAMXC, reg16);
118 * RAM_COMMAND_NORMAL affects only the memory controller and
119 * doesn't need to be "sent" to the DIMMs.
121 if (command == RAM_COMMAND_NORMAL)
124 /* Send the RAM command to each row of memory. */
126 for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
128 caslatency = 3; /* TODO: Dynamically get CAS latency later. */
130 /* before translation it is
132 * M[02:00] Burst Length
133 * M[03:03] Burst Type
134 * M[06:04] Cas Latency
144 * Must Be 00b (Defined mode)
145 * M[09:09] Write Burst Mode
146 * 0 - Programmed burst length
147 * 1 - Single location access
149 * write 0 to ensure compatibility with....
152 /* seems constructed value will be right shifted by 3 bit, thus constructed value
153 * must be left shifted by 3
154 * so possible formula is (caslatency <<4)|(burst_type << 1)|(burst length)
155 * then << 3 shift to compensate shift in Memory Controller
157 if (command == RAM_COMMAND_MRS) {
164 dimm_end = pci_read_config8(NB, DRB + i);
166 addr = (dimm_start * 8 * 1024 * 1024) + addr_offset;
167 if (dimm_end > dimm_start) {
169 PRINT_DEBUG(" Sending RAM command 0x");
170 PRINT_DEBUG_HEX16(reg16);
171 PRINT_DEBUG(" to 0x");
172 PRINT_DEBUG_HEX32(addr);
179 /* Set the start of the next DIMM. */
180 dimm_start = dimm_end;
184 /*-----------------------------------------------------------------------------
185 DIMM-independant configuration functions.
186 -----------------------------------------------------------------------------*/
188 static void spd_enable_refresh(void)
192 reg = pci_read_config8(NB, DRAMC);
194 /* this chipset offer only two choices regarding refresh
195 * refresh disabled, or refresh normal
198 pci_write_config8(NB, DRAMC, reg | 0x01);
199 reg = pci_read_config8(NB, DRAMC);
201 PRINT_DEBUG("spd_enable_refresh: dramc = 0x");
202 PRINT_DEBUG_HEX8(reg);
206 /*-----------------------------------------------------------------------------
208 -----------------------------------------------------------------------------*/
210 static void northbridge_init(void)
214 reg32 = pci_read_config32(NB, APBASE);
215 reg32 &= 0xe8000000U;
216 pci_write_config32(NB, APBASE, reg32);
218 #if CONFIG_DEBUG_RAM_SETUP
220 * apbase dont get set still, no idea what i have doing wrong yet,
221 * i am almost sure that somehow i set it by mistake once, but can't
224 reg32 = pci_read_config32(NB, APBASE);
225 PRINT_DEBUG("APBASE ");
226 PRINT_DEBUG_HEX32(reg32);
233 * This routine sets RAM controller inside northbridge to known state
236 static void sdram_set_registers(void)
240 /* nice banner with FSB shown? do we have
241 * any standart policy about such things?
245 reg16 = pci_read_config16(NB, PACCFG);
246 printk(BIOS_DEBUG, "i82443LX Host Freq: 6%C MHz\n", (reg16 & 0x4000) ? '0' : '6');
249 PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
254 max = ARRAY_SIZE(register_values);
256 /* Set registers as specified in the register_values[] array. */
257 for (i = 0; i < max; i += 3) {
259 reg = pci_read_config8(NB, register_values[i]);
260 reg &= register_values[i + 1];
261 reg |= register_values[i + 2] & ~(register_values[i + 1]);
262 pci_write_config8(NB, register_values[i], reg);
265 * i am not sure if that is needed, but was usefull
266 * for me to confirm what got written
268 #if CONFIG_DEBUG_RAM_SETUP
269 PRINT_DEBUG(" Set register 0x");
270 PRINT_DEBUG_HEX8(register_values[i]);
271 PRINT_DEBUG(" to 0x");
272 PRINT_DEBUG_HEX8(reg);
273 tmp = pci_read_config8(NB, register_values[i]);
274 PRINT_DEBUG(" readed 0x");
275 PRINT_DEBUG_HEX8(tmp);
279 PRINT_DEBUG(" FAIL ");
285 PRINT_DEBUG("Northbridge atexit sdram set registers\n");
290 static void sdram_set_spd_registers(void)
295 for (i = 0; i < DIMM_SOCKETS; i++) {
296 uint16_t ds = 0; // dimm size
298 /* this code skips second bank on each socket (no idea how to fix it now)
303 PRINT_DEBUG(" rows: ");
304 PRINT_DEBUG_HEX8(spd_read_byte(DIMM0 + i, SPD_NUM_DIMM_BANKS) & 0xFF);
305 PRINT_DEBUG(" rowsize: ");
306 PRINT_DEBUG_HEX8(spd_read_byte(DIMM0 + i, SPD_DENSITY_OF_EACH_ROW_ON_MODULE) & 0xFF);
307 PRINT_DEBUG(" modulesize: ");
309 j = spd_read_byte(DIMM0 + i, SPD_NUM_DIMM_BANKS);
315 j = spd_read_byte(DIMM0 + i, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
320 ds = ds * (j >> 1); // convert from 4MB to 8MB units in place
323 /* This is more or less crude hack
324 * allowing to run this target under qemu (even if that is not really
325 * same hardware emulated),
326 * probably some kconfig expert option should be added to enable/disable
330 if (ds == 0 && memsize == 0)
335 // todo: support for bank with not equal sizes as per jedec standart?
338 * because density is reported in units of 4Mbyte
339 * and rows in device are just value,
340 * and for setting registers we need value in 8Mbyte units
343 PRINT_DEBUG_HEX16(ds);
348 pci_write_config8(NB, DRB + (2*i), memsize);
349 pci_write_config8(NB, DRB + (2*i) + 1, memsize);
351 /* i have no idea why pci_read_config16 not work for
354 ds = pci_read_config8(NB, DRT+1);
356 ds |= pci_read_config8(NB, DRT);
359 PRINT_DEBUG_HEX16(ds);
361 ds &= ~(0x01 << (4 * i));
364 PRINT_DEBUG_HEX16(ds);
368 * modify DRT register if current row isn't empty
369 * code assume its SDRAM plugged (should check if its sdram or EDO,
370 * edo would have 0x00 as constand instead 0x10 for SDRAM
371 * also this code is buggy because ignores second row of each dimm socket
374 /* and as above write_config16 not work here too)
375 * pci_write_config16(NB, DRT, j);
378 pci_write_config8(NB, DRT+1, ds >> 8);
379 pci_write_config8(NB, DRT, ds & 0xFF);
384 PRINT_DEBUG("Mem: 0x");
385 PRINT_DEBUG_HEX16(memsize * 8);
386 PRINT_DEBUG(" MB\n");
389 /* maybe we should use some nice die/hlt sequence with printing on console
390 * that no memory found, get lost, i can't run?
391 * maybe such event_handler can be commonly defined routine to decrease
394 PRINT_DEBUG("No memory detected via SPD\n");
395 PRINT_DEBUG("Reverting to hardcoded 64M single side dimm in first bank\n");
399 /* Set DRAMC. Don't enable refresh for now. */
400 pci_write_config8(NB, DRAMC, 0x00);
402 /* Cas latency 3, and other shouldbe properly from spd too */
403 pci_write_config8(NB, DRAMT, 0xAC);
406 pci_write_config8(NB, PCI_LATENCY_TIMER, 0x40);
408 // set drive strength
409 pci_write_config32(NB, MBSC, 0x00000000);
412 static void sdram_enable(void)
416 /* 0. Wait until power/voltages and clocks are stable (200us). */
419 /* 1. Apply NOP. Wait 200 clock cycles (clock might be 60 or 66 Mhz). */
420 PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
421 do_ram_command(RAM_COMMAND_NOP);
424 /* 2. Precharge all. Wait tRP. */
425 PRINT_DEBUG("RAM Enable 2: Precharge all\n");
426 do_ram_command(RAM_COMMAND_PRECHARGE);
429 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
430 PRINT_DEBUG("RAM Enable 3: CBR\n");
431 for (i = 0; i < 8; i++) {
432 do_ram_command(RAM_COMMAND_CBR);
436 /* 4. Mode register set. Wait two memory cycles. */
437 PRINT_DEBUG("RAM Enable 4: Mode register set\n");
438 do_ram_command(RAM_COMMAND_MRS);
441 /* 5. Normal operation. */
442 PRINT_DEBUG("RAM Enable 5: Normal operation\n");
443 do_ram_command(RAM_COMMAND_NORMAL);
446 /* 6. Finally enable refresh. */
447 PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
448 pci_write_config8(NB, DRAMC, 0x01);
449 spd_enable_refresh();
452 PRINT_DEBUG("Northbridge following SDRAM init:\n");