Author: cozzie Date: 2007-11-03 19:45:42 +0100 (Sat, 03 Nov 2007) New Revision: 2937
Modified: trunk/LinuxBIOSv2/src/include/spd.h trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r.h trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_early_smbus.c trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_ide.c Log: 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
Modified: trunk/LinuxBIOSv2/src/include/spd.h =================================================================== --- trunk/LinuxBIOSv2/src/include/spd.h 2007-11-03 12:50:26 UTC (rev 2936) +++ trunk/LinuxBIOSv2/src/include/spd.h 2007-11-03 18:45:42 UTC (rev 2937) @@ -105,6 +105,7 @@ #define SPD_MEMORY_TYPE_SGRAM_DDR 6 #define SPD_MEMORY_TYPE_SDRAM_DDR 7 #define SPD_MEMORY_TYPE_SDRAM_DDR2 8 +#define SPD_MEMORY_TYPE_SDRAM_DDR3 0xb
/* SPD_MODULE_VOLTAGE values. */ #define SPD_VOLTAGE_TTL 0 /* 5.0 Volt/TTL */
Modified: trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r.h =================================================================== --- trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r.h 2007-11-03 12:50:26 UTC (rev 2936) +++ trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r.h 2007-11-03 18:45:42 UTC (rev 2937) @@ -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
Modified: trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2007-11-03 12:50:26 UTC (rev 2936) +++ trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2007-11-03 18:45:42 UTC (rev 2937) @@ -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,12 @@ /* Probably don't have to do this, but it can't hurt. */ smbus_reset();
- /* Can I just "return inb(SMBHSTDAT0)"? */ return val; }
+/** + * Enable the smbus on vt8237r-based systems + */ void enable_smbus(void) { device_t dev; @@ -166,3 +160,45 @@ /* Reset the internal pointer. */ 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"); +}
Modified: trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_ide.c =================================================================== --- trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_ide.c 2007-11-03 12:50:26 UTC (rev 2936) +++ trunk/LinuxBIOSv2/src/southbridge/via/vt8237r/vt8237r_ide.c 2007-11-03 18:45:42 UTC (rev 2937) @@ -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.