Corey Osgood wrote: > 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 <[EMAIL PROTECTED]> >
And here's the patch, for real this time! -Corey
Index: src/southbridge/via/vt8237r/vt8237r_ide.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_ide.c (revision 2925) +++ src/southbridge/via/vt8237r/vt8237r_ide.c (working copy) @@ -27,14 +27,6 @@ #include "vt8237r.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 * IRQ14/15 is used for PCI. Therefore no native mode support. Index: src/southbridge/via/vt8237r/vt8237r.h =================================================================== --- src/southbridge/via/vt8237r/vt8237r.h (revision 2925) +++ src/southbridge/via/vt8237r/vt8237r.h (working copy) @@ -30,4 +30,42 @@ #define VT8237R_HPET_ADDR 0xfed00000ULL #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 Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_early_smbus.c (revision 2925) +++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c (working copy) @@ -20,41 +20,21 @@ */ #include <device/pci_ids.h> +#include <spd.h> #include "vt8237r.h" -#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) - +/** + * Print an error, should it occur. If no error, just exit + * + * @param host_status The data returned on the host status register after a + * transaction is processed + * @param loops The number of times a transaction was attempted + */ static void smbus_print_error(u8 host_status, int loops) { /* Check if there actually was an error. */ - if (host_status == 0x00 || host_status == 0x40 || - host_status == 0x42) + if ((host_status == 0x00 || host_status == 0x40 || + host_status == 0x42) && (loops < SMBUS_TIMEOUT)) return; if (loops >= SMBUS_TIMEOUT) @@ -66,11 +46,14 @@ if (host_status & (1 << 2)) print_err("Device error\r\n"); 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)) 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) { int loops; @@ -79,11 +62,14 @@ loops = 0; /* 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; smbus_print_error(inb(SMBHSTSTAT), loops); } +/** + * Reset and take ownership of the smbus + */ static void smbus_reset(void) { outb(HOST_RESET, SMBHSTSTAT); @@ -95,9 +81,15 @@ 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_HEX16(dimm); @@ -131,10 +123,23 @@ /* Probably don't have to do this, but it can't hurt. */ smbus_reset(); - /* Can I just "return inb(SMBHSTDAT0)"? */ + /* We could probably return inb(SMBHSTDAT0), but we'd lose the ability + * to debug the transaction */ return val; } +/** + * This is provided for compatibility, should it be needed + */ +inline u8 spd_read_byte(u32 address, u8 offset) +{ + return smbus_read_byte(address, offset); +} + +/** + * Enable the smbus on vt8237r-based systems + */ + void enable_smbus(void) { device_t dev; @@ -166,3 +171,42 @@ /* Reset the internal pointer. */ inb(SMBHSTCTL); } + +/** + * A fixup for some systems that need time for the smbus to "warm up" + * It reads the ID byte from SMBus, looking for good data from a slot/address + * Exits on either good data or a timeout + * + * @param mem_controller The memory controller and smbus addresses + */ +void smbus_fixup(const struct mem_controller *ctrl) +{ + int i, ram_slots, current_slot = 0; + u8 result = 0; + +#ifdef DIMM_SOCKETS + ram_slots = DIMM_SOCKETS; +#else + ram_slots = sizeof(ctrl->channel0)/sizeof(ctrl->channel0[0]); +#endif + 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, so really the values we look + * for are arbitrary, as long as they're between 1 and 0xfe */ + for(i = 0; (i < SMBUS_TIMEOUT && ((result < SPD_MEMORY_TYPE_SDRAM) || + (result > SPD_MEMORY_TYPE_SDRAM_DDR2))); i++) + { + if (current_slot > ram_slots) j = 0; + result = spd_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"); +}
-- linuxbios mailing list linuxbios@linuxbios.org http://www.linuxbios.org/mailman/listinfo/linuxbios