Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-38
[coreboot.git] / src / southbridge / via / vt8231 / vt8231_early_smbus.c
index dbb6e213ae39b075a79247259712f8faea591c00..056c4b5b117c6820e8770e9c887a56897d6ffaf6 100644 (file)
 #define SMBTRNSADD 0x9
 #define SMBSLVDATA 0xa
 #define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL  0xf
+#define SMBUS_PIN_CTL  0xf 
 
 /* Define register settings */
 #define HOST_RESET 0xff
-#define DIMM_BASE 0xa0         // 1010000 is base for DIMM in SMBus
-#define READ_CMD  0x01         // 1 in the 0 bit of SMBHSTADD states to READ
+#define DIMM_BASE 0xa0        // 1010000 is base for DIMM in SMBus
+#define READ_CMD  0x01        // 1 in the 0 bit of SMBHSTADD states to READ
 
 
 #define SMBUS_TIMEOUT (100*1000*10)
@@ -27,28 +27,29 @@ static void enable_smbus(void)
        device_t dev;
        unsigned char c;
        /* Power management controller */
-       dev = pci_locate_device(PCI_ID(0x1106, 0x8235), 0);
-
+       dev = pci_locate_device(PCI_ID(0x1106,0x8235), 0);
+       
        if (dev == PCI_DEV_INVALID) {
                die("SMBUS controller not found\r\n");
        }
+       
        // set IO base address to SMBUS_IO_BASE
-       pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
-
+       pci_write_config32(dev, 0x90, SMBUS_IO_BASE|1);
+       
        // Enable SMBus 
        c = pci_read_config8(dev, 0xd2);
        c |= 5;
        pci_write_config8(dev, 0xd2, c);
-
+       
        /* make it work for I/O ...
         */
-       dev = pci_locate_device(PCI_ID(0x1106, 0x8231), 0);
+       dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
        c = pci_read_config8(dev, 4);
        c |= 1;
        pci_write_config8(dev, 4, c);
        print_debug_hex8(c);
        print_debug(" is the comm register\r\n");
-
+       
        print_debug("SMBus controller enabled\r\n");
 }
 
@@ -60,51 +61,52 @@ static inline void smbus_delay(void)
 
 static int smbus_wait_until_active(void)
 {
-       unsigned long loops;
-       loops = SMBUS_TIMEOUT;
-       do {
-               unsigned char val;
-               smbus_delay();
-               val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-               if ((val & 1)) {
-                       break;
-               }
-       } while (--loops);
-       return loops ? 0 : -4;
+        unsigned long loops;
+        loops = SMBUS_TIMEOUT;
+        do {
+                unsigned char val;
+                smbus_delay();
+                val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+                if ((val & 1)) {
+                        break;
+                }
+        } while(--loops);
+        return loops?0:-4;
 }
 
 static int smbus_wait_until_ready(void)
 {
-       unsigned long loops;
-       loops = SMBUS_TIMEOUT;
-       do {
-               unsigned char val;
-               smbus_delay();
-               val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-               if ((val & 1) == 0) {
-                       break;
-               }
-               if (loops == (SMBUS_TIMEOUT / 2)) {
-                       outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-               }
-       } while (--loops);
-       return loops ? 0 : -2;
+        unsigned long loops;
+        loops = SMBUS_TIMEOUT;
+        do {
+                unsigned char val;
+                smbus_delay();
+                val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+                if ((val & 1) == 0) {
+                        break;
+                }
+                if(loops == (SMBUS_TIMEOUT / 2)) {
+                        outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
+                                SMBUS_IO_BASE + SMBHSTSTAT);
+                }
+        } while(--loops);
+        return loops?0:-2;
 }
 
 static int smbus_wait_until_done(void)
 {
-       unsigned long loops;
-       loops = SMBUS_TIMEOUT;
-       do {
-               unsigned char val;
-               smbus_delay();
-
-               val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-               if ((val & 1) == 0) {
-                       break;
-               }
-       } while (--loops);
-       return loops ? 0 : -3;
+        unsigned long loops;
+        loops = SMBUS_TIMEOUT;
+        do {
+                unsigned char val;
+                smbus_delay();
+
+                val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+                if ( (val & 1) == 0) {
+                        break;
+                }
+        } while(--loops);
+        return loops?0:-3;
 }
 
 void smbus_reset(void)
@@ -113,13 +115,13 @@ void smbus_reset(void)
        outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
        outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
        outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
-
+       
        smbus_wait_until_ready();
        print_debug("After reset status ");
-       print_debug_hex8(inb(SMBUS_IO_BASE + SMBHSTSTAT));
+       print_debug_hex8( inb(SMBUS_IO_BASE + SMBHSTSTAT));
        print_debug("\r\n");
 }
-
+  
 static void smbus_print_error(unsigned char host_status_register)
 {
 
@@ -150,95 +152,96 @@ static void smbus_print_error(unsigned char host_status_register)
  */
 static int smbus_read_byte(unsigned device, unsigned address)
 {
-       unsigned char global_control_register;
-       unsigned char global_status_register;
-       unsigned char byte;
-
-       if (smbus_wait_until_ready() < 0) {
-               outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-               if (smbus_wait_until_ready() < 0) {
-                       return -2;
-               }
-       }
-
-       /* setup transaction */
-       /* disable interrupts */
-       outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
-       /* set the device I'm talking too */
-       outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
-       /* set the command/address... */
-       outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-       /* set up for a byte data read */
-       outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
-
-       /* clear any lingering errors, so the transaction will run */
-       outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
-       /* clear the data byte... */
-       outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
-       /* start a byte read, with interrupts disabled */
-       outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
-       /* poll for it to start */
-       if (smbus_wait_until_active() < 0) {
-               return -4;
-       }
-
-       /* poll for transaction completion */
-       if (smbus_wait_until_done() < 0) {
-               return -3;
-       }
+        unsigned char global_control_register;
+        unsigned char global_status_register;
+        unsigned char byte;
+
+        if (smbus_wait_until_ready() < 0) {
+          outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+          if ( smbus_wait_until_ready() < 0 ) {
+              return -2;
+          }
+        }
+
+        /* setup transaction */
+        /* disable interrupts */
+        outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
+        /* set the device I'm talking too */
+        outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+        /* set the command/address... */
+        outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+        /* set up for a byte data read */
+        outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2<<2), SMBUS_IO_BASE + SMBHSTCTL);
+
+        /* clear any lingering errors, so the transaction will run */
+        outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+        /* clear the data byte...*/
+        outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+        /* start a byte read, with interrupts disabled */
+        outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+        /* poll for it to start */
+        if (smbus_wait_until_active() < 0) {
+                return -4;
+        }
+
+        /* poll for transaction completion */
+        if (smbus_wait_until_done() < 0) {
+                return -3;
+        }
 
        /* Ignore the Host Busy & Command Complete ? */
-       global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~((1 << 1) | (1 << 0));
+        global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~((1<<1)|(1<<0));
 
-       /* read results of transaction */
-       byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+        /* read results of transaction */
+        byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
 
-       if (global_status_register != 0) {
-               return -1;
-       }
-       return byte;
+        if (global_status_register != 0) {
+                return -1;
+        }
+        return byte;
 }
 
 #if 0
 /* SMBus routines borrowed from VIA's Trident Driver */
 /* this works, so I am not going to touch it for now -- rgm */
-static unsigned char smbus_read_byte(unsigned char devAdr, unsigned char bIndex)
+static unsigned char smbus_read_byte(unsigned char devAdr, 
+                               unsigned char bIndex) 
 {
        unsigned int i;
-       unsigned char bData;
-       unsigned char sts = 0;
-
+       unsigned char  bData;
+       unsigned char  sts = 0;
+       
        /* clear host status */
        outb(0xff, SMBUS_IO_BASE);
-
+       
        /* check SMBUS ready */
-       for (i = 0; i < SMBUS_TIMEOUT; i++)
-               if ((inb(SMBUS_IO_BASE) & 0x01) == 0)
+       for ( i = 0; i < SMBUS_TIMEOUT; i++ )
+               if ( (inb(SMBUS_IO_BASE) & 0x01) == 0 )
                        break;
 
        /* set host command */
-       outb(bIndex, SMBUS_IO_BASE + 3);
-
+       outb(bIndex, SMBUS_IO_BASE+3);
+       
        /* set slave address */
-       outb(devAdr | 0x01, SMBUS_IO_BASE + 4);
-
+       outb(devAdr | 0x01, SMBUS_IO_BASE+4);
+       
        /* start */
-       outb(0x48, SMBUS_IO_BASE + 2);
-
+       outb(0x48, SMBUS_IO_BASE+2);
+       
        /* SMBUS Wait Ready */
-       for (i = 0; i < SMBUS_TIMEOUT; i++)
-               if (((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0)
+       for ( i = 0; i < SMBUS_TIMEOUT; i++ )
+               if ( ((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0 )
                        break;
        if ((sts & ~3) != 0) {
                smbus_print_error(sts);
                return 0;
        }
-       bData = inb(SMBUS_IO_BASE + 5);
-
+       bData=inb(SMBUS_IO_BASE+5);
+       
        return bData;
-
+       
 }
 #endif
 /* for reference, here is the fancier version which we will use at some 
@@ -249,11 +252,11 @@ int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
 {
        unsigned char host_status_register;
        unsigned char byte;
-
+       
        reset();
-
+       
        smbus_wait_until_ready();
-
+       
        /* setup transaction */
        /* disable interrupts */
        outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
@@ -262,32 +265,35 @@ int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
        /* set the command/address... */
        outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
        /* set up for a byte data read */
-       outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
-
+       outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
+               SMBUS_IO_BASE + SMBHSTCTL);
+       
        /* clear any lingering errors, so the transaction will run */
        outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
-       /* clear the data byte... */
+       
+       /* clear the data byte...*/
        outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
+       
        /* start the command */
-       outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
-
+       outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
+               SMBUS_IO_BASE + SMBHSTCTL);
+       
        /* poll for transaction completion */
        smbus_wait_until_done();
-
+       
        host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
+       
        /* Ignore the In Use Status... */
        host_status_register &= ~(1 << 6);
-
+       
        /* read results of transaction */
        byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
        smbus_print_error(byte);
-
+       
        *result = byte;
        return host_status_register != 0x02;
 }
 
 
 #endif
+