Browse Source

i2c: piix4: Add support for AMD ML and CZ SMBus changes

The locations of SMBus register base address and enablement bit are changed
from AMD ML, which need this patch to be supported.

Signed-off-by: Shane Huang <shane.huang@amd.com>
Reviewed-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Cc: stable@vger.kernel.org
Shane Huang 11 years ago
parent
commit
032f708bc4
3 changed files with 25 additions and 6 deletions
  1. 1 1
      Documentation/i2c/busses/i2c-piix4
  2. 1 0
      drivers/i2c/busses/Kconfig
  3. 23 5
      drivers/i2c/busses/i2c-piix4.c

+ 1 - 1
Documentation/i2c/busses/i2c-piix4

@@ -13,7 +13,7 @@ Supported adapters:
   * AMD SP5100 (SB700 derivative found on some server mainboards)
   * AMD SP5100 (SB700 derivative found on some server mainboards)
     Datasheet: Publicly available at the AMD website
     Datasheet: Publicly available at the AMD website
     http://support.amd.com/us/Embedded_TechDocs/44413.pdf
     http://support.amd.com/us/Embedded_TechDocs/44413.pdf
-  * AMD Hudson-2, CZ
+  * AMD Hudson-2, ML, CZ
     Datasheet: Not publicly available
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
     Datasheet: Publicly available at the SMSC website http://www.smsc.com

+ 1 - 0
drivers/i2c/busses/Kconfig

@@ -152,6 +152,7 @@ config I2C_PIIX4
 	    ATI SB700/SP5100
 	    ATI SB700/SP5100
 	    ATI SB800
 	    ATI SB800
 	    AMD Hudson-2
 	    AMD Hudson-2
+	    AMD ML
 	    AMD CZ
 	    AMD CZ
 	    Serverworks OSB4
 	    Serverworks OSB4
 	    Serverworks CSB5
 	    Serverworks CSB5

+ 23 - 5
drivers/i2c/busses/i2c-piix4.c

@@ -22,7 +22,7 @@
 	Intel PIIX4, 440MX
 	Intel PIIX4, 440MX
 	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
 	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
 	ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
 	ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
-	AMD Hudson-2, CZ
+	AMD Hudson-2, ML, CZ
 	SMSC Victory66
 	SMSC Victory66
 
 
    Note: we assume there can only be one device, with one or more
    Note: we assume there can only be one device, with one or more
@@ -235,7 +235,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 {
 {
 	unsigned short piix4_smba;
 	unsigned short piix4_smba;
 	unsigned short smba_idx = 0xcd6;
 	unsigned short smba_idx = 0xcd6;
-	u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en;
+	u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status;
+	u8 i2ccfg, i2ccfg_offset = 0x10;
 
 
 	/* SB800 and later SMBus does not support forcing address */
 	/* SB800 and later SMBus does not support forcing address */
 	if (force || force_addr) {
 	if (force || force_addr) {
@@ -245,7 +246,15 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 	}
 	}
 
 
 	/* Determine the address of the SMBus areas */
 	/* Determine the address of the SMBus areas */
-	smb_en = (aux) ? 0x28 : 0x2c;
+	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
+	     PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
+	     PIIX4_dev->revision >= 0x41) ||
+	    (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
+	     PIIX4_dev->device == 0x790b &&
+	     PIIX4_dev->revision >= 0x49))
+		smb_en = 0x00;
+	else
+		smb_en = (aux) ? 0x28 : 0x2c;
 
 
 	if (!request_region(smba_idx, 2, "smba_idx")) {
 	if (!request_region(smba_idx, 2, "smba_idx")) {
 		dev_err(&PIIX4_dev->dev, "SMBus base address index region "
 		dev_err(&PIIX4_dev->dev, "SMBus base address index region "
@@ -258,13 +267,22 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 	smba_en_hi = inb_p(smba_idx + 1);
 	smba_en_hi = inb_p(smba_idx + 1);
 	release_region(smba_idx, 2);
 	release_region(smba_idx, 2);
 
 
-	if ((smba_en_lo & 1) == 0) {
+	if (!smb_en) {
+		smb_en_status = smba_en_lo & 0x10;
+		piix4_smba = smba_en_hi << 8;
+		if (aux)
+			piix4_smba |= 0x20;
+	} else {
+		smb_en_status = smba_en_lo & 0x01;
+		piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
+	}
+
+	if (!smb_en_status) {
 		dev_err(&PIIX4_dev->dev,
 		dev_err(&PIIX4_dev->dev,
 			"Host SMBus controller not enabled!\n");
 			"Host SMBus controller not enabled!\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
 		return -ENODEV;
 		return -ENODEV;