This patch is some small changes to the vt8237r to prepare it for

the Jetway J7F2 patch that should be coming soon, and also moves most
defines into vt8237r.h. I've changed some of the values from u32 to u8,
because that's all they should ever need to be. Also includes
doxygenized comments!

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



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2937 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Corey Osgood 2007-11-03 18:45:42 +00:00
parent e6409f218c
commit 02b2365f02
4 changed files with 110 additions and 43 deletions

View File

@ -105,6 +105,7 @@
#define SPD_MEMORY_TYPE_SGRAM_DDR 6 #define SPD_MEMORY_TYPE_SGRAM_DDR 6
#define SPD_MEMORY_TYPE_SDRAM_DDR 7 #define SPD_MEMORY_TYPE_SDRAM_DDR 7
#define SPD_MEMORY_TYPE_SDRAM_DDR2 8 #define SPD_MEMORY_TYPE_SDRAM_DDR2 8
#define SPD_MEMORY_TYPE_SDRAM_DDR3 0xb
/* SPD_MODULE_VOLTAGE values. */ /* SPD_MODULE_VOLTAGE values. */
#define SPD_VOLTAGE_TTL 0 /* 5.0 Volt/TTL */ #define SPD_VOLTAGE_TTL 0 /* 5.0 Volt/TTL */

View File

@ -30,4 +30,42 @@
#define VT8237R_HPET_ADDR 0xfed00000ULL #define VT8237R_HPET_ADDR 0xfed00000ULL
#define VT8237R_APIC_BASE 0xfec00000ULL #define VT8237R_APIC_BASE 0xfec00000ULL
/* IDE specific defines */
#define IDE_CS 0x40
#define IDE_CONF_I 0x41
#define IDE_CONF_II 0x42
#define IDE_CONF_FIFO 0x43
#define IDE_MISC_I 0x44
#define IDE_MISC_II 0x45
#define IDE_UDMA 0x50
/* SMBus specific */
#define VT8237R_POWER_WELL 0x94
#define VT8237R_SMBUS_IO_BASE_REG 0xd0
#define VT8237R_SMBUS_HOST_CONF 0xd2
#define SMBHSTSTAT (VT8237R_SMBUS_IO_BASE + 0x0)
#define SMBSLVSTAT (VT8237R_SMBUS_IO_BASE + 0x1)
#define SMBHSTCTL (VT8237R_SMBUS_IO_BASE + 0x2)
#define SMBHSTCMD (VT8237R_SMBUS_IO_BASE + 0x3)
#define SMBXMITADD (VT8237R_SMBUS_IO_BASE + 0x4)
#define SMBHSTDAT0 (VT8237R_SMBUS_IO_BASE + 0x5)
#define HOST_RESET 0xff
/* 1 in the 0 bit of SMBHSTADD states to READ. */
#define READ_CMD 0x01
#define SMBUS_TIMEOUT (100 * 1000 * 10)
#define I2C_TRANS_CMD 0x40
#define CLOCK_SLAVE_ADDRESS 0x69
#if DEBUG_SMBUS == 1
#define PRINT_DEBUG(x) print_debug(x)
#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
#else
#define PRINT_DEBUG(x)
#define PRINT_DEBUG_HEX16(x)
#endif
#define SMBUS_DELAY() inb(0x80)
#endif #endif

View File

@ -20,41 +20,21 @@
*/ */
#include <device/pci_ids.h> #include <device/pci_ids.h>
#include <spd.h>
#include "vt8237r.h" #include "vt8237r.h"
#define VT8237R_POWER_WELL 0x94 /**
#define VT8237R_SMBUS_IO_BASE_REG 0xd0 * Print an error, should it occur. If no error, just exit.
#define VT8237R_SMBUS_HOST_CONF 0xd2 *
* @param host_status The data returned on the host status register after a
#define SMBHSTSTAT (VT8237R_SMBUS_IO_BASE + 0x0) * transaction is processed.
#define SMBSLVSTAT (VT8237R_SMBUS_IO_BASE + 0x1) * @param loops The number of times a transaction was attempted.
#define SMBHSTCTL (VT8237R_SMBUS_IO_BASE + 0x2) */
#define SMBHSTCMD (VT8237R_SMBUS_IO_BASE + 0x3)
#define SMBXMITADD (VT8237R_SMBUS_IO_BASE + 0x4)
#define SMBHSTDAT0 (VT8237R_SMBUS_IO_BASE + 0x5)
#define HOST_RESET 0xff
/* 1 in the 0 bit of SMBHSTADD states to READ. */
#define READ_CMD 0x01
#define SMBUS_TIMEOUT (100 * 1000 * 10)
#define I2C_TRANS_CMD 0x40
#define CLOCK_SLAVE_ADDRESS 0x69
#if DEBUG_SMBUS == 1
#define PRINT_DEBUG(x) print_debug(x)
#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
#else
#define PRINT_DEBUG(x)
#define PRINT_DEBUG_HEX16(x)
#endif
#define SMBUS_DELAY() inb(0x80)
static void smbus_print_error(u8 host_status, int loops) static void smbus_print_error(u8 host_status, int loops)
{ {
/* Check if there actually was an error. */ /* Check if there actually was an error. */
if (host_status == 0x00 || host_status == 0x40 || if ((host_status == 0x00 || host_status == 0x40 ||
host_status == 0x42) host_status == 0x42) && (loops < SMBUS_TIMEOUT))
return; return;
if (loops >= SMBUS_TIMEOUT) if (loops >= SMBUS_TIMEOUT)
@ -66,11 +46,14 @@ static void smbus_print_error(u8 host_status, int loops)
if (host_status & (1 << 2)) if (host_status & (1 << 2))
print_err("Device error\r\n"); print_err("Device error\r\n");
if (host_status & (1 << 1)) if (host_status & (1 << 1))
print_err("Interrupt/SMI# was Successful Completion\r\n"); print_debug("Interrupt/SMI# Completed Successfully\r\n");
if (host_status & (1 << 0)) if (host_status & (1 << 0))
print_err("Host busy\r\n"); print_err("Host busy\r\n");
} }
/**
* Wait for the smbus to become ready to process the next transaction
*/
static void smbus_wait_until_ready(void) static void smbus_wait_until_ready(void)
{ {
int loops; int loops;
@ -79,11 +62,14 @@ static void smbus_wait_until_ready(void)
loops = 0; loops = 0;
/* Yes, this is a mess, but it's the easiest way to do it. */ /* Yes, this is a mess, but it's the easiest way to do it. */
while ((inb(SMBHSTSTAT) & 1) == 1 && loops <= SMBUS_TIMEOUT) while ((inb(SMBHSTSTAT) & 1) == 1 && loops < SMBUS_TIMEOUT)
++loops; ++loops;
smbus_print_error(inb(SMBHSTSTAT), loops); smbus_print_error(inb(SMBHSTSTAT), loops);
} }
/**
* Reset and take ownership of the smbus
*/
static void smbus_reset(void) static void smbus_reset(void)
{ {
outb(HOST_RESET, SMBHSTSTAT); outb(HOST_RESET, SMBHSTSTAT);
@ -95,9 +81,15 @@ static void smbus_reset(void)
PRINT_DEBUG("\r\n"); PRINT_DEBUG("\r\n");
} }
u8 smbus_read_byte(u32 dimm, u32 offset) /**
* Read a byte from the smbus
*
* @param dimm The address location of the dimm on the smbus
* @param offset The offset the data is located at
*/
u8 smbus_read_byte(u8 dimm, u8 offset)
{ {
u32 val; u8 val;
PRINT_DEBUG("DIMM "); PRINT_DEBUG("DIMM ");
PRINT_DEBUG_HEX16(dimm); PRINT_DEBUG_HEX16(dimm);
@ -131,10 +123,12 @@ u8 smbus_read_byte(u32 dimm, u32 offset)
/* Probably don't have to do this, but it can't hurt. */ /* Probably don't have to do this, but it can't hurt. */
smbus_reset(); smbus_reset();
/* Can I just "return inb(SMBHSTDAT0)"? */
return val; return val;
} }
/**
* Enable the smbus on vt8237r-based systems
*/
void enable_smbus(void) void enable_smbus(void)
{ {
device_t dev; device_t dev;
@ -166,3 +160,45 @@ void enable_smbus(void)
/* Reset the internal pointer. */ /* Reset the internal pointer. */
inb(SMBHSTCTL); inb(SMBHSTCTL);
} }
/**
* A fixup for some systems that need time for the smbus to "warm up". This is
* needed on some vt823x based systems, where the smbus spurts out bad data for
* a short time after power on. This has been seen on the Via Epia-series and
* Jetway J7F2-series. It reads the ID byte from SMBus, looking for
* known-good data from a slot/address. Exits on either good data or a timeout.
*
* This should probably go into some global file, but one would need to be
* created just for it. If some other chip needs/wants it, we can worry about it
* then.
*
* @param ctrl The memory controller and smbus addresses
*/
void smbus_fixup(const struct mem_controller *ctrl)
{
int i, ram_slots, current_slot = 0;
u8 result = 0;
ram_slots = ARRAY_SIZE(ctrl->channel0);
if (!ram_slots) {
print_err("smbus_fixup thinks there are no ram slots!\r\n");
return;
}
PRINT_DEBUG("Waiting for smbus to warm up");
/* Bad SPD data should be either 0 or 0xff, but YMMV. So we look for the
* ID bytes of SDRAM, DDR, DDR2, and DDR3 (and anything in between).
* vt8237r has only been seen on DDR and DDR2 based systems, so far */
for(i = 0; (i < SMBUS_TIMEOUT && ((result < SPD_MEMORY_TYPE_SDRAM) ||
(result > SPD_MEMORY_TYPE_SDRAM_DDR3))); i++)
{
if (current_slot > ram_slots) current_slot = 0;
result = smbus_read_byte(ctrl->channel0[current_slot],
SPD_MEMORY_TYPE);
current_slot++;
PRINT_DEBUG(".");
}
if (i >= SMBUS_TIMEOUT) print_err("SMBus timed out while warming up\r\n");
else PRINT_DEBUG("Done\r\n");
}

View File

@ -27,14 +27,6 @@
#include "vt8237r.h" #include "vt8237r.h"
#include "chip.h" #include "chip.h"
#define IDE_CS 0x40
#define IDE_CONF_I 0x41
#define IDE_CONF_II 0x42
#define IDE_CONF_FIFO 0x43
#define IDE_MISC_I 0x44
#define IDE_MISC_II 0x45
#define IDE_UDMA 0x50
/** /**
* No native mode. Interrupts from unconnected HDDs might occur if * No native mode. Interrupts from unconnected HDDs might occur if
* IRQ14/15 is used for PCI. Therefore no native mode support. * IRQ14/15 is used for PCI. Therefore no native mode support.