Get rid of the unnecessary indirection by 'struct mem_controller' for the

Intel 810 chipset (and all boards using it). This isn't required for this
chipset as there's only one memory controller.

This also helps a lot with romcc register usage, you should see the dreaded
"too few registers" less often.

Build-tested with all three boards using the Intel 810 chipset.

Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de>
Acked-by: Corey Osgood <corey.osgood@gmail.com>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3764 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Uwe Hermann 2008-11-20 23:18:10 +00:00
parent 76c6c95c1e
commit 4cf5ecf39d
6 changed files with 49 additions and 82 deletions

View File

@ -48,17 +48,9 @@ static inline int spd_read_byte(unsigned int device, unsigned int address)
#include "northbridge/intel/i82810/raminit.c"
/* #include "northbridge/intel/i82810/debug.c" */
#include "sdram/generic_sdram.c"
static void main(unsigned long bist)
{
static const struct mem_controller memctrl[] = {
{
.d0 = PCI_DEV(0, 0, 0),
.channel0 = {0x50, 0x51},
}
};
if (bist == 0)
early_mtrr_init();
@ -67,7 +59,9 @@ static void main(unsigned long bist)
console_init();
report_bist_failure(bist);
enable_smbus();
/* dump_spd_registers(&memctrl[0]); */
sdram_initialize(ARRAY_SIZE(memctrl), memctrl);
/* dump_spd_registers(); */
sdram_set_registers();
sdram_set_spd_registers();
sdram_enable();
/* ram_check(0, 640 * 1024); */
}

View File

@ -52,17 +52,9 @@ void udelay(int usecs)
#include "northbridge/intel/i82810/raminit.c"
#include "northbridge/intel/i82810/debug.c"
#include "sdram/generic_sdram.c"
static void main(unsigned long bist)
{
static const struct mem_controller memctrl[] = {
{
.d0 = PCI_DEV(0, 0, 0),
.channel0 = {0x50, 0x51},
}
};
if (bist == 0)
early_mtrr_init();
@ -75,14 +67,11 @@ static void main(unsigned long bist)
/* Halt if there was a built in self test failure. */
report_bist_failure(bist);
/* dump_spd_registers(&memctrl[0]); */
/* dump_spd_registers(); */
/* sdram_initialize() runs out of registers. */
/* sdram_initialize(ARRAY_SIZE(memctrl), memctrl); */
sdram_set_registers(memctrl);
sdram_set_spd_registers(memctrl);
sdram_enable(0, memctrl);
sdram_set_registers();
sdram_set_spd_registers();
sdram_enable();
/* Check RAM. */
/* ram_check(0, 640 * 1024); */

View File

@ -37,19 +37,11 @@
#include "southbridge/intel/i82801xx/i82801xx_early_smbus.c"
#include "pc80/udelay_io.c"
#include "northbridge/intel/i82810/raminit.c"
#include "sdram/generic_sdram.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
static void main(unsigned long bist)
{
static const struct mem_controller memctrl[] = {
{
.d0 = PCI_DEV(0, 0, 0),
.channel0 = {0x50, 0x51},
}
};
if (bist == 0)
early_mtrr_init();
@ -66,7 +58,10 @@ static void main(unsigned long bist)
enable_smbus();
report_bist_failure(bist);
/* dump_spd_registers(&memctrl[0]); */
sdram_initialize(ARRAY_SIZE(memctrl), memctrl);
/* dump_spd_registers(); */
sdram_set_registers();
sdram_set_spd_registers();
sdram_enable();
/* ram_check(0, 640 * 1024); */
}

View File

@ -1,11 +1,11 @@
static void dump_spd_registers(const struct mem_controller *ctrl)
static void dump_spd_registers(void)
{
int i;
print_debug("\r\n");
for(i = 0; i < 4; i++) {
for(i = 0; i < DIMM_SOCKETS; i++) {
unsigned device;
device = ctrl->channel0[i];
device = DIMM_SPD_BASE + i;
if (device) {
int j;
print_debug("dimm: ");

View File

@ -62,22 +62,21 @@ SDRAM configuration functions.
/**
* Send the specified RAM command to all DIMMs.
*
* @param Memory controller
* @param TODO
* @param TODO
*/
static void do_ram_command(const struct mem_controller *ctrl, uint32_t command,
uint32_t addr_offset, uint32_t row_offset)
static void do_ram_command(uint32_t command, uint32_t addr_offset,
uint32_t row_offset)
{
uint8_t reg;
/* TODO: Support for multiple DIMMs. */
/* Configure the RAM command. */
reg = pci_read_config8(ctrl->d0, DRAMT);
reg = pci_read_config8(PCI_DEV(0, 0, 0), DRAMT);
reg &= 0x1f; /* Clear bits 7-5. */
reg |= command << 5;
pci_write_config8(ctrl->d0, DRAMT, reg);
pci_write_config8(PCI_DEV(0, 0, 0), DRAMT, reg);
/* RAM_COMMAND_NORMAL affects only the memory controller and
doesn't need to be "sent" to the DIMMs. */
@ -101,8 +100,7 @@ DIMM-independant configuration functions.
/*
* Set DRP - DRAM Row Population Register (Device 0).
*/
static void spd_set_dram_size(const struct mem_controller *ctrl,
uint32_t row_offset)
static void spd_set_dram_size(uint32_t row_offset)
{
/* The variables drp and dimm_size have to be ints since all the
* SMBus-related functions return ints, and its just easier this way.
@ -113,12 +111,12 @@ static void spd_set_dram_size(const struct mem_controller *ctrl,
for (i = 0; i < DIMM_SOCKETS; i++) {
/* First check if a DIMM is actually present. */
if (smbus_read_byte(ctrl->channel0[i], 2) == 4) {
if (smbus_read_byte(DIMM_SPD_BASE + i, 2) == 4) {
print_debug("Found DIMM in slot ");
print_debug_hex8(i);
print_debug("\r\n");
dimm_size = smbus_read_byte(ctrl->channel0[i], 31);
dimm_size = smbus_read_byte(DIMM_SPD_BASE + i, 31);
/* WISHLIST: would be nice to display it as decimal? */
print_debug("DIMM is 0x");
@ -181,7 +179,7 @@ static void spd_set_dram_size(const struct mem_controller *ctrl,
/* If the DIMM is dual-sided, the DRP value is +2 */
/* TODO: Figure out asymetrical configurations. */
if ((smbus_read_byte(ctrl->channel0[i], 127) | 0xf) ==
if ((smbus_read_byte(DIMM_SPD_BASE + i, 127) | 0xf) ==
0xff) {
print_debug("DIMM is dual-sided\r\n");
dimm_size += 2;
@ -203,13 +201,13 @@ static void spd_set_dram_size(const struct mem_controller *ctrl,
print_debug_hex8(drp);
print_debug("\r\n");
pci_write_config8(ctrl->d0, DRP, drp);
pci_write_config8(PCI_DEV(0, 0, 0), DRP, drp);
}
static void set_dram_timing(const struct mem_controller *ctrl)
static void set_dram_timing(void)
{
/* TODO, for now using default, hopefully safe values. */
// pci_write_config8(ctrl->d0, DRAMT, 0x00);
// pci_write_config8(PCI_DEV(0, 0, 0), DRAMT, 0x00);
}
/*
@ -239,9 +237,9 @@ static void set_dram_timing(const struct mem_controller *ctrl)
* 0x4445 384MB 0xfd 128MB single-sided 256MB dual-sided
* 0x0001 512MB 0xff 256MB dual-sided 256MB dual-sided
*/
static void set_dram_buffer_strength(const struct mem_controller *ctrl)
static void set_dram_buffer_strength(void)
{
pci_write_config16(ctrl->d0, BUFF_SC, 0x77da);
pci_write_config16(PCI_DEV(0, 0, 0), BUFF_SC, 0x77da);
}
/*-----------------------------------------------------------------------------
@ -250,15 +248,13 @@ Public interface.
/**
* TODO.
*
* @param Memory controller
*/
static void sdram_set_registers(const struct mem_controller *ctrl)
static void sdram_set_registers(void)
{
unsigned long val;
/* TODO */
pci_write_config8(ctrl->d0, GMCHCFG, 0x60);
pci_write_config8(PCI_DEV(0, 0, 0), GMCHCFG, 0x60);
/* PAMR: Programmable Attributes Register
* Every pair of bits controls an address range:
@ -275,49 +271,44 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
*/
/* Ideally, this should be R/W for as many ranges as possible. */
pci_write_config8(ctrl->d0, PAM, 0xff);
pci_write_config8(PCI_DEV(0, 0, 0), PAM, 0xff);
/* Enabling the VGA Framebuffer currently screws up the rest of the boot.
* Disable for now */
/* Enable 1MB framebuffer. */
//pci_write_config8(ctrl->d0, SMRAM, 0xC0);
//pci_write_config8(PCI_DEV(0, 0, 0), SMRAM, 0xC0);
//val = pci_read_config16(ctrl->d0, MISSC);
//val = pci_read_config16(PCI_DEV(0, 0, 0), MISSC);
/* Preserve reserved bits. */
//val &= 0xff06;
/* Set graphics cache window to 32MB, no power throttling. */
//val |= 0x0001;
//pci_write_config16(ctrl->d0, MISSC, val);
//pci_write_config16(PCI_DEV(0, 0, 0), MISSC, val);
//val = pci_read_config8(ctrl->d0, MISSC2);
//val = pci_read_config8(PCI_DEV(0, 0, 0), MISSC2);
/* Enable graphics palettes and clock gating (not optional!) */
//val |= 0x06;
//pci_write_config8(ctrl->d0, MISSC2, val);
//pci_write_config8(PCI_DEV(0, 0, 0), MISSC2, val);
}
/**
* TODO.
*
* @param Memory controller
*/
static void sdram_set_spd_registers(const struct mem_controller *ctrl)
static void sdram_set_spd_registers(void)
{
/* spd_set_dram_size() moved into sdram_enable() to prevent having
* to pass a variable between here and there.
*/
set_dram_buffer_strength(ctrl);
set_dram_buffer_strength();
set_dram_timing(ctrl);
set_dram_timing();
}
/**
* Enable SDRAM.
*
* @param Number of controllers
* @param Memory controller
*/
static void sdram_enable(int controllers, const struct mem_controller *ctrl)
static void sdram_enable(void)
{
int i;
@ -327,21 +318,21 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
*/
uint32_t row_offset;
spd_set_dram_size(ctrl, row_offset);
spd_set_dram_size(row_offset);
/* 1. Apply NOP. */
PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n");
do_ram_command(ctrl, RAM_COMMAND_NOP, 0, row_offset);
do_ram_command(RAM_COMMAND_NOP, 0, row_offset);
udelay(200);
/* 2. Precharge all. Wait tRP. */
PRINT_DEBUG("RAM Enable 2: Precharge all\r\n");
do_ram_command(ctrl, RAM_COMMAND_PRECHARGE, 0, row_offset);
do_ram_command(RAM_COMMAND_PRECHARGE, 0, row_offset);
udelay(1);
/* 3. Perform 8 refresh cycles. Wait tRC each time. */
PRINT_DEBUG("RAM Enable 3: CBR\r\n");
do_ram_command(ctrl, RAM_COMMAND_CBR, 0, row_offset);
do_ram_command(RAM_COMMAND_CBR, 0, row_offset);
for (i = 0; i < 8; i++) {
read32(0);
read32(row_offset);
@ -350,12 +341,12 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
/* 4. Mode register set. Wait two memory cycles. */
PRINT_DEBUG("RAM Enable 4: Mode register set\r\n");
do_ram_command(ctrl, RAM_COMMAND_MRS, 0x1d0, row_offset);
do_ram_command(RAM_COMMAND_MRS, 0x1d0, row_offset);
udelay(2);
/* 5. Normal operation (enables refresh) */
PRINT_DEBUG("RAM Enable 5: Normal operation\r\n");
do_ram_command(ctrl, RAM_COMMAND_NORMAL, 0, row_offset);
do_ram_command(RAM_COMMAND_NORMAL, 0, row_offset);
udelay(1);
PRINT_DEBUG("Northbridge following SDRAM init:\r\n");

View File

@ -24,10 +24,8 @@
/* The 82810 supports max. 2 dual-sided DIMMs. */
#define DIMM_SOCKETS 2
struct mem_controller {
device_t d0;
uint16_t channel0[DIMM_SOCKETS];
};
/* DIMM0 is at 0x50, DIMM1 is at 0x51. */
#define DIMM_SPD_BASE 0x50
/* The following table has been bumped over to this header to avoid clutter in
* raminit.c. It's used to translate the value read from SPD Byte 31 to a value