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

Reply via email to