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

View File

@ -37,19 +37,11 @@
#include "southbridge/intel/i82801xx/i82801xx_early_smbus.c" #include "southbridge/intel/i82801xx/i82801xx_early_smbus.c"
#include "pc80/udelay_io.c" #include "pc80/udelay_io.c"
#include "northbridge/intel/i82810/raminit.c" #include "northbridge/intel/i82810/raminit.c"
#include "sdram/generic_sdram.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
static void main(unsigned long bist) static void main(unsigned long bist)
{ {
static const struct mem_controller memctrl[] = {
{
.d0 = PCI_DEV(0, 0, 0),
.channel0 = {0x50, 0x51},
}
};
if (bist == 0) if (bist == 0)
early_mtrr_init(); early_mtrr_init();
@ -66,7 +58,10 @@ static void main(unsigned long bist)
enable_smbus(); enable_smbus();
report_bist_failure(bist); 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); */ /* 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; int i;
print_debug("\r\n"); print_debug("\r\n");
for(i = 0; i < 4; i++) { for(i = 0; i < DIMM_SOCKETS; i++) {
unsigned device; unsigned device;
device = ctrl->channel0[i]; device = DIMM_SPD_BASE + i;
if (device) { if (device) {
int j; int j;
print_debug("dimm: "); print_debug("dimm: ");

View File

@ -62,22 +62,21 @@ SDRAM configuration functions.
/** /**
* Send the specified RAM command to all DIMMs. * Send the specified RAM command to all DIMMs.
* *
* @param Memory controller
* @param TODO * @param TODO
* @param TODO * @param TODO
*/ */
static void do_ram_command(const struct mem_controller *ctrl, uint32_t command, static void do_ram_command(uint32_t command, uint32_t addr_offset,
uint32_t addr_offset, uint32_t row_offset) uint32_t row_offset)
{ {
uint8_t reg; uint8_t reg;
/* TODO: Support for multiple DIMMs. */ /* TODO: Support for multiple DIMMs. */
/* Configure the RAM command. */ /* 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 &= 0x1f; /* Clear bits 7-5. */
reg |= command << 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 /* RAM_COMMAND_NORMAL affects only the memory controller and
doesn't need to be "sent" to the DIMMs. */ 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). * Set DRP - DRAM Row Population Register (Device 0).
*/ */
static void spd_set_dram_size(const struct mem_controller *ctrl, static void spd_set_dram_size(uint32_t row_offset)
uint32_t row_offset)
{ {
/* The variables drp and dimm_size have to be ints since all the /* The variables drp and dimm_size have to be ints since all the
* SMBus-related functions return ints, and its just easier this way. * 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++) { for (i = 0; i < DIMM_SOCKETS; i++) {
/* First check if a DIMM is actually present. */ /* 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("Found DIMM in slot ");
print_debug_hex8(i); print_debug_hex8(i);
print_debug("\r\n"); 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? */ /* WISHLIST: would be nice to display it as decimal? */
print_debug("DIMM is 0x"); 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 */ /* If the DIMM is dual-sided, the DRP value is +2 */
/* TODO: Figure out asymetrical configurations. */ /* 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) { 0xff) {
print_debug("DIMM is dual-sided\r\n"); print_debug("DIMM is dual-sided\r\n");
dimm_size += 2; dimm_size += 2;
@ -203,13 +201,13 @@ static void spd_set_dram_size(const struct mem_controller *ctrl,
print_debug_hex8(drp); print_debug_hex8(drp);
print_debug("\r\n"); 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. */ /* 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 * 0x4445 384MB 0xfd 128MB single-sided 256MB dual-sided
* 0x0001 512MB 0xff 256MB dual-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. * TODO.
*
* @param Memory controller
*/ */
static void sdram_set_registers(const struct mem_controller *ctrl) static void sdram_set_registers(void)
{ {
unsigned long val; unsigned long val;
/* TODO */ /* TODO */
pci_write_config8(ctrl->d0, GMCHCFG, 0x60); pci_write_config8(PCI_DEV(0, 0, 0), GMCHCFG, 0x60);
/* PAMR: Programmable Attributes Register /* PAMR: Programmable Attributes Register
* Every pair of bits controls an address range: * 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. */ /* 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. /* Enabling the VGA Framebuffer currently screws up the rest of the boot.
* Disable for now */ * Disable for now */
/* Enable 1MB framebuffer. */ /* 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. */ /* Preserve reserved bits. */
//val &= 0xff06; //val &= 0xff06;
/* Set graphics cache window to 32MB, no power throttling. */ /* Set graphics cache window to 32MB, no power throttling. */
//val |= 0x0001; //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!) */ /* Enable graphics palettes and clock gating (not optional!) */
//val |= 0x06; //val |= 0x06;
//pci_write_config8(ctrl->d0, MISSC2, val); //pci_write_config8(PCI_DEV(0, 0, 0), MISSC2, val);
} }
/** /**
* TODO. * 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 /* spd_set_dram_size() moved into sdram_enable() to prevent having
* to pass a variable between here and there. * 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. * 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; int i;
@ -327,21 +318,21 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
*/ */
uint32_t row_offset; uint32_t row_offset;
spd_set_dram_size(ctrl, row_offset); spd_set_dram_size(row_offset);
/* 1. Apply NOP. */ /* 1. Apply NOP. */
PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n"); 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); udelay(200);
/* 2. Precharge all. Wait tRP. */ /* 2. Precharge all. Wait tRP. */
PRINT_DEBUG("RAM Enable 2: Precharge all\r\n"); 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); udelay(1);
/* 3. Perform 8 refresh cycles. Wait tRC each time. */ /* 3. Perform 8 refresh cycles. Wait tRC each time. */
PRINT_DEBUG("RAM Enable 3: CBR\r\n"); 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++) { for (i = 0; i < 8; i++) {
read32(0); read32(0);
read32(row_offset); 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. */ /* 4. Mode register set. Wait two memory cycles. */
PRINT_DEBUG("RAM Enable 4: Mode register set\r\n"); 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); udelay(2);
/* 5. Normal operation (enables refresh) */ /* 5. Normal operation (enables refresh) */
PRINT_DEBUG("RAM Enable 5: Normal operation\r\n"); 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); udelay(1);
PRINT_DEBUG("Northbridge following SDRAM init:\r\n"); PRINT_DEBUG("Northbridge following SDRAM init:\r\n");

View File

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