aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/i440lx/raminit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/intel/i440lx/raminit.c')
-rw-r--r--src/northbridge/intel/i440lx/raminit.c453
1 files changed, 0 insertions, 453 deletions
diff --git a/src/northbridge/intel/i440lx/raminit.c b/src/northbridge/intel/i440lx/raminit.c
deleted file mode 100644
index fc19d9163d..0000000000
--- a/src/northbridge/intel/i440lx/raminit.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2008 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <spd.h>
-#include <delay.h>
-#include <stdlib.h>
-#include "i440lx.h"
-
-/*-----------------------------------------------------------------------------
-Macros and definitions.
------------------------------------------------------------------------------*/
-
-/* Uncomment this to enable debugging output. */
-
-/* Debugging macros. */
-#if CONFIG_DEBUG_RAM_SETUP
-#define PRINT_DEBUG(x) printk(BIOS_DEBUG, x)
-#define PRINT_DEBUG_HEX8(x) printk(BIOS_DEBUG, "%02x", x)
-#define PRINT_DEBUG_HEX16(x) printk(BIOS_DEBUG, "%04x", x)
-#define PRINT_DEBUG_HEX32(x) printk(BIOS_DEBUG, "%08x", x)
-#define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
-#else
-#define PRINT_DEBUG(x)
-#define PRINT_DEBUG_HEX8(x)
-#define PRINT_DEBUG_HEX16(x)
-#define PRINT_DEBUG_HEX32(x)
-#define DUMPNORTH()
-#endif
-
-#define NB PCI_DEV(0, 0, 0)
-
-/* DRAMXC[7:5] - DRAM extended control register (SMS). */
-#define RAM_COMMAND_NORMAL 0x0
-#define RAM_COMMAND_NOP 0x1 // (NOPCE)
-#define RAM_COMMAND_PRECHARGE 0x2 // ABPCE
-#define RAM_COMMAND_MRS 0x3 // MRSCE
-#define RAM_COMMAND_CBR 0x4 // CBRC
-// rest are reserved
-
-/* Table format: register, bitmask, value. */
-static const long register_values[] = {
- // ~0x02 == bit 9
- // 0x04 == bit 10
- // BASE is 0x8A but we dont want bit 9 or 10 have ENABLED so 0x8C
- PACCFG + 1, 0x38, 0x8c,
-
- DBC, 0x00, 0xC3,
-
- DRT, 0x00, 0xFF,
- DRT+1, 0x00, 0xFF,
-
- DRAMC, 0x00, 0x00, /* disable refresh for now. */
- DRAMT, 0x00, 0x00,
-
- PAM0, 0x00, 0x30, // everything is a mem
- PAM1, 0x00, 0x33,
- PAM2, 0x00, 0x33,
- PAM3, 0x00, 0x33,
- PAM4, 0x00, 0x33,
- PAM5, 0x00, 0x33,
- PAM6, 0x00, 0x33,
-
- /* Set the DRBs to zero for now, this will be fixed later. */
- DRB0, 0x00, 0x00,
- DRB1, 0x00, 0x00,
- DRB2, 0x00, 0x00,
- DRB3, 0x00, 0x00,
- DRB4, 0x00, 0x00,
- DRB5, 0x00, 0x00,
- DRB6, 0x00, 0x00,
- DRB7, 0x00, 0x00,
-
- /* No memory holes. */
- FDHC, 0x00, 0x00,
-};
-
-/*-----------------------------------------------------------------------------
-SDRAM configuration functions.
------------------------------------------------------------------------------*/
-
-/**
- * Send the specified RAM command to all DIMMs.
- *
- * @param command The RAM command to send to the DIMM(s).
- */
-static void do_ram_command(u32 command)
-{
- int i, caslatency;
- u8 dimm_start, dimm_end;
- u16 reg16;
- u32 addr, addr_offset;
-
- /* Configure the RAM command. */
- reg16 = pci_read_config16(NB, DRAMXC);
- reg16 &= 0xff1f; /* Clear bits 7-5. */
- reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
- pci_write_config16(NB, DRAMXC, reg16);
-
- /*
- * RAM_COMMAND_NORMAL affects only the memory controller and
- * doesn't need to be "sent" to the DIMMs.
- */
- if (command == RAM_COMMAND_NORMAL)
- return;
-
- /* Send the RAM command to each row of memory. */
- dimm_start = 0;
- for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
- addr_offset = 0;
- caslatency = 3; /* TODO: Dynamically get CAS latency later. */
-
- /* before translation it is
- *
- * M[02:00] Burst Length
- * M[03:03] Burst Type
- * M[06:04] Cas Latency
- * 000 - Reserved
- * 001 - Reserved
- * 010 - CAS 2
- * 011 - CAS 3
- * 100 - Reserved
- * 101 - Reserved
- * 110 - Reserved
- * 111 - Reserved
- * M[08:07] Op Mode
- * Must Be 00b (Defined mode)
- * M[09:09] Write Burst Mode
- * 0 - Programmed burst length
- * 1 - Single location access
- * M[11:10] Reserved
- * write 0 to ensure compatibility with....
- */
-
- /* seems constructed value will be right shifted by 3 bit, thus constructed value
- * must be left shifted by 3
- * so possible formula is (caslatency <<4)|(burst_type << 1)|(burst length)
- * then << 3 shift to compensate shift in Memory Controller
- */
- if (command == RAM_COMMAND_MRS) {
- if (caslatency == 3)
- addr_offset = 0x1d0;
- if (caslatency == 2)
- addr_offset = 0x150;
- }
-
- dimm_end = pci_read_config8(NB, DRB + i);
-
- addr = (dimm_start * 8 * 1024 * 1024) + addr_offset;
- if (dimm_end > dimm_start) {
-#if 0
- PRINT_DEBUG(" Sending RAM command 0x");
- PRINT_DEBUG_HEX16(reg16);
- PRINT_DEBUG(" to 0x");
- PRINT_DEBUG_HEX32(addr);
- PRINT_DEBUG("\n");
-#endif
-
- read32(addr);
- }
-
- /* Set the start of the next DIMM. */
- dimm_start = dimm_end;
- }
-}
-
-/*-----------------------------------------------------------------------------
-DIMM-independant configuration functions.
------------------------------------------------------------------------------*/
-
-static void spd_enable_refresh(void)
-{
- uint8_t reg;
-
- reg = pci_read_config8(NB, DRAMC);
-
- /* this chipset offer only two choices regarding refresh
- * refresh disabled, or refresh normal
- */
-
- pci_write_config8(NB, DRAMC, reg | 0x01);
- reg = pci_read_config8(NB, DRAMC);
-
- PRINT_DEBUG("spd_enable_refresh: dramc = 0x");
- PRINT_DEBUG_HEX8(reg);
- PRINT_DEBUG("\n");
-}
-
-/*-----------------------------------------------------------------------------
-Public interface.
------------------------------------------------------------------------------*/
-
-static void northbridge_init(void)
-{
- uint32_t reg32;
-
- reg32 = pci_read_config32(NB, APBASE);
- reg32 &= 0xe8000000U;
- pci_write_config32(NB, APBASE, reg32);
-
-#if CONFIG_DEBUG_RAM_SETUP
- /*
- * apbase dont get set still, no idea what i have doing wrong yet,
- * i am almost sure that somehow i set it by mistake once, but can't
- * repeat that.
- */
- reg32 = pci_read_config32(NB, APBASE);
- PRINT_DEBUG("APBASE ");
- PRINT_DEBUG_HEX32(reg32);
- PRINT_DEBUG("\n");
-#endif
-}
-
-
-/**
- * This routine sets RAM controller inside northbridge to known state
- *
- */
-static void sdram_set_registers(void)
-{
- int i, max;
-
- /* nice banner with FSB shown? do we have
- * any standart policy about such things?
- */
-#if 0
- uint16_t reg16;
- reg16 = pci_read_config16(NB, PACCFG);
- printk(BIOS_DEBUG, "i82443LX Host Freq: 6%C MHz\n", (reg16 & 0x4000) ? '0' : '6');
-#endif
-
- PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
- DUMPNORTH();
-
- northbridge_init();
-
- max = ARRAY_SIZE(register_values);
-
- /* Set registers as specified in the register_values[] array. */
- for (i = 0; i < max; i += 3) {
- uint8_t reg,tmp;
- reg = pci_read_config8(NB, register_values[i]);
- reg &= register_values[i + 1];
- reg |= register_values[i + 2] & ~(register_values[i + 1]);
- pci_write_config8(NB, register_values[i], reg);
-
- /*
- * i am not sure if that is needed, but was usefull
- * for me to confirm what got written
- */
-#if CONFIG_DEBUG_RAM_SETUP
- PRINT_DEBUG(" Set register 0x");
- PRINT_DEBUG_HEX8(register_values[i]);
- PRINT_DEBUG(" to 0x");
- PRINT_DEBUG_HEX8(reg);
- tmp = pci_read_config8(NB, register_values[i]);
- PRINT_DEBUG(" readed 0x");
- PRINT_DEBUG_HEX8(tmp);
- if (tmp == reg) {
- PRINT_DEBUG(" OK ");
- } else {
- PRINT_DEBUG(" FAIL ");
- }
- PRINT_DEBUG("\n");
-#endif
- }
-
- PRINT_DEBUG("Northbridge atexit sdram set registers\n");
- DUMPNORTH();
-}
-
-
-static void sdram_set_spd_registers(void)
-{
- int i;
- u16 memsize = 0;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- uint16_t ds = 0; // dimm size
- int j;
- /* this code skips second bank on each socket (no idea how to fix it now)
- */
-
- PRINT_DEBUG("DIMM");
- PRINT_DEBUG_HEX8(i);
- PRINT_DEBUG(" rows: ");
- PRINT_DEBUG_HEX8(spd_read_byte(DIMM0 + i, SPD_NUM_DIMM_BANKS) & 0xFF);
- PRINT_DEBUG(" rowsize: ");
- PRINT_DEBUG_HEX8(spd_read_byte(DIMM0 + i, SPD_DENSITY_OF_EACH_ROW_ON_MODULE) & 0xFF);
- PRINT_DEBUG(" modulesize: ");
-
- j = spd_read_byte(DIMM0 + i, SPD_NUM_DIMM_BANKS);
- if (j < 0)
- j = 0;
- else
- ds = j;
-
- j = spd_read_byte(DIMM0 + i, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
-
- if (j < 0)
- j = 0;
- else
- ds = ds * (j >> 1); // convert from 4MB to 8MB units in place
-
-
- /* This is more or less crude hack
- * allowing to run this target under qemu (even if that is not really
- * same hardware emulated),
- * probably some kconfig expert option should be added to enable/disable
- * this nicelly
- */
-#if 0
- if (ds == 0 && memsize == 0)
- ds = 0x8;
-#endif
-
-
- // todo: support for bank with not equal sizes as per jedec standart?
-
- /*
- * because density is reported in units of 4Mbyte
- * and rows in device are just value,
- * and for setting registers we need value in 8Mbyte units
- */
-
- PRINT_DEBUG_HEX16(ds);
- PRINT_DEBUG("\n");
-
- memsize += ds;
-
- pci_write_config8(NB, DRB + (2*i), memsize);
- pci_write_config8(NB, DRB + (2*i) + 1, memsize);
- if (ds > 0) {
- /* i have no idea why pci_read_config16 not work for
- * me correctly here
- */
- ds = pci_read_config8(NB, DRT+1);
- ds <<=8;
- ds |= pci_read_config8(NB, DRT);
-
- PRINT_DEBUG("DRT ");
- PRINT_DEBUG_HEX16(ds);
-
- ds &= ~(0x01 << (4 * i));
-
- PRINT_DEBUG(" ");
- PRINT_DEBUG_HEX16(ds);
- PRINT_DEBUG("\n");
-
- /*
- * modify DRT register if current row isn't empty
- * code assume its SDRAM plugged (should check if its sdram or EDO,
- * edo would have 0x00 as constand instead 0x10 for SDRAM
- * also this code is buggy because ignores second row of each dimm socket
- */
-
- /* and as above write_config16 not work here too)
- * pci_write_config16(NB, DRT, j);
- */
-
- pci_write_config8(NB, DRT+1, ds >> 8);
- pci_write_config8(NB, DRT, ds & 0xFF);
- }
- }
-
-#if 0
- PRINT_DEBUG("Mem: 0x");
- PRINT_DEBUG_HEX16(memsize * 8);
- PRINT_DEBUG(" MB\n");
-
- if (memsize == 0) {
- /* maybe we should use some nice die/hlt sequence with printing on console
- * that no memory found, get lost, i can't run?
- * maybe such event_handler can be commonly defined routine to decrease
- * code duplication?
- */
- PRINT_DEBUG("No memory detected via SPD\n");
- PRINT_DEBUG("Reverting to hardcoded 64M single side dimm in first bank\n");
- }
-#endif
-
- /* Set DRAMC. Don't enable refresh for now. */
- pci_write_config8(NB, DRAMC, 0x00);
-
- /* Cas latency 3, and other shouldbe properly from spd too */
- pci_write_config8(NB, DRAMT, 0xAC);
-
- /* TODO? */
- pci_write_config8(NB, PCI_LATENCY_TIMER, 0x40);
-
- // set drive strength
- pci_write_config32(NB, MBSC, 0x00000000);
-}
-
-static void sdram_enable(void)
-{
- int i;
-
- /* 0. Wait until power/voltages and clocks are stable (200us). */
- udelay(200);
-
- /* 1. Apply NOP. Wait 200 clock cycles (clock might be 60 or 66 MHz). */
- PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
- do_ram_command(RAM_COMMAND_NOP);
- udelay(200);
-
- /* 2. Precharge all. Wait tRP. */
- PRINT_DEBUG("RAM Enable 2: Precharge all\n");
- do_ram_command(RAM_COMMAND_PRECHARGE);
- udelay(1);
-
- /* 3. Perform 8 refresh cycles. Wait tRC each time. */
- PRINT_DEBUG("RAM Enable 3: CBR\n");
- for (i = 0; i < 8; i++) {
- do_ram_command(RAM_COMMAND_CBR);
- udelay(1);
- }
-
- /* 4. Mode register set. Wait two memory cycles. */
- PRINT_DEBUG("RAM Enable 4: Mode register set\n");
- do_ram_command(RAM_COMMAND_MRS);
- udelay(2);
-
- /* 5. Normal operation. */
- PRINT_DEBUG("RAM Enable 5: Normal operation\n");
- do_ram_command(RAM_COMMAND_NORMAL);
- udelay(1);
-
- /* 6. Finally enable refresh. */
- PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
- pci_write_config8(NB, DRAMC, 0x01);
- spd_enable_refresh();
- udelay(1);
-
- PRINT_DEBUG("Northbridge following SDRAM init:\n");
-}