Author: avg
Date: Thu Sep 22 21:34:35 2016
New Revision: 306218
URL: https://svnweb.freebsd.org/changeset/base/306218

Log:
  amdsbwd, intpm: unify bits specific to AMD chipsets (FCHs, southbridges)
  
  AMD chipsets have proprietary mechanisms for dicovering resources.
  Those resources are not discoverable via plug-and-play mechanisms
  like PCI configuration registers or ACPI.
  For this reason a chipset-specific knowledge of proprietary registers
  is required.
  
  At present there are two FreeBSD drivers that require the proprietary
  resource discovery.  One is amdsbwd which is a driver for the watchdog
  timer in the AMD chipsets.  The other is intpm SMBus driver when it
  attaches to the newer AMD chipsets where the resources of the SMBus HBA
  are not described in the regular PCI way.
  
  In both cases the resources are discovered by accessing AMD PMIO space.
  Thus, many definitions are shared between the two drivers.
  This change puts those defintions into a common header file.
  
  As an added benefit, intpm driver now supports newest FCHs built into
  AMD processors of Family 15h, models 70h-7Fh and Family 16h, models
  30h-3Fh.
  
  Reviewed by:  kib
  MFC after:    1 week
  Differential Revision: https://reviews.freebsd.org/D8004

Added:
  head/sys/dev/amdsbwd/amd_chipset.h   (contents, props changed)
Modified:
  head/share/man/man4/intpm.4
  head/sys/dev/amdsbwd/amdsbwd.c
  head/sys/dev/intpm/intpm.c

Modified: head/share/man/man4/intpm.4
==============================================================================
--- head/share/man/man4/intpm.4 Thu Sep 22 21:23:28 2016        (r306217)
+++ head/share/man/man4/intpm.4 Thu Sep 22 21:34:35 2016        (r306218)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 20, 2016
+.Dd September 22, 2016
 .Dt INTPM 4
 .Os
 .Sh NAME
@@ -59,7 +59,9 @@ AMD SB600/7x0/8x0/9x0 southbridges
 .It
 AMD Axx/Hudson/Bolton FCHs
 .It
-AMD FCH integrated into Family 16h Models 00h-0Fh Processors
+AMD FCH integrated into Family 15h Models 60h-6Fh, 70h-7Fh Processors
+.It
+AMD FCH integrated into Family 16h Models 00h-0Fh, 30h-3Fh Processors
 .El
 .Sh SEE ALSO
 .Xr amdpm 4 ,

Added: head/sys/dev/amdsbwd/amd_chipset.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/dev/amdsbwd/amd_chipset.h  Thu Sep 22 21:34:35 2016        
(r306218)
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2016 Andriy Gapon <a...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The following registers, bits and magic values are defined in Register
+ * Reference Guide documents for SB600, SB7x0, SB8x0, SB9x0 southbridges and
+ * various versions of Fusion Controller Hubs (FCHs).  FCHs integrated into
+ * CPUs are documented in BIOS and Kernel Development Guide documents for
+ * the corresponding processor families.
+ *
+ * At present there are three classes of supported chipsets:
+ * - SB600 and S7x0 southbridges where the SMBus controller device has
+ *   a PCI Device ID of 0x43851002 and a revision less than 0x40
+ * - SB8x0, SB9x0 southbridges and FCHs where the SMBus controller device has
+ *   a PCI Device ID of 0x43851002 and a revision greater than or equal to 0x40
+ *   or the controller has an ID of 0x780b1022 and a revision less than 0x41
+ * - FCHs where the SMBus controller device has a PCI Device ID of 0x780b1022
+ *   and a revision greater than or equal to 0x41
+ * The register definitions are compatible within the classes and may be
+ * incompatible accross them.
+ * So far there is no public documentation for "KERNCZ" FCH where the SMBus
+ * controller has a PCI ID of 0x790b1022.  Based on some code in Linux it is
+ * assumed that revisions less than 0x49 are compatible with the SB8x0 class
+ * and revisions greater than or equal to 0x49 are compatible with the class
+ * of FCHs with 0x41+ revisions.
+ */
+
+/*
+ * IO registers for accessing the PMIO space.
+ * See SB7xx RRG 2.3.3.1.1, for instance.
+ */
+#define        AMDSB_PMIO_INDEX                0xcd6
+#define        AMDSB_PMIO_DATA                 (PMIO_INDEX + 1)
+#define        AMDSB_PMIO_WIDTH                2
+
+/*
+ * SB7x0 and compatible registers in the PMIO space.
+ * See SB7xx RRG 2.3.3.2.
+ */
+#define        AMDSB_PM_RESET_STATUS0          0x44
+#define        AMDSB_PM_RESET_STATUS1          0x45
+#define                AMDSB_WD_RST_STS        0x02
+#define        AMDSB_PM_WDT_CTRL               0x69
+#define                AMDSB_WDT_DISABLE       0x01
+#define                AMDSB_WDT_RES_MASK      (0x02 | 0x04)
+#define                AMDSB_WDT_RES_32US      0x00
+#define                AMDSB_WDT_RES_10MS      0x02
+#define                AMDSB_WDT_RES_100MS     0x04
+#define                AMDSB_WDT_RES_1S        0x06
+#define        AMDSB_PM_WDT_BASE_LSB           0x6c
+#define        AMDSB_PM_WDT_BASE_MSB           0x6f
+
+/*
+ * SB8x0 and compatible registers in the PMIO space.
+ * See SB8xx RRG 2.3.3, for instance.
+ */
+#define        AMDSB8_PM_SMBUS_EN              0x2c
+#define                AMDSB8_SMBUS_EN         0x01
+#define                AMDSB8_SMBUS_ADDR_MASK  0xffe0u
+#define        AMDSB8_PM_WDT_EN                0x48
+#define                AMDSB8_WDT_DEC_EN       0x01
+#define                AMDSB8_WDT_DISABLE      0x02
+#define        AMDSB8_PM_WDT_CTRL              0x4c
+#define                AMDSB8_WDT_32KHZ        0x00
+#define                AMDSB8_WDT_1HZ          0x03
+#define                AMDSB8_WDT_RES_MASK     0x03
+#define        AMDSB8_PM_RESET_STATUS0         0xc0
+#define        AMDSB8_PM_RESET_STATUS1         0xc1
+#define                AMDSB8_WD_RST_STS       0x20
+
+/*
+ * Newer FCH registers in the PMIO space.
+ * See BKDG for Family 16h Models 30h-3Fh 3.26.13 PMx00 and PMx04.
+ */
+#define AMDFCH41_PM_DECODE_EN0         0x00
+#define                AMDFCH41_SMBUS_EN       0x10
+#define                AMDFCH41_WDT_EN         0x80
+#define AMDFCH41_PM_DECODE_EN1         0x01
+#define        AMDFCH41_PM_DECODE_EN3          0x03
+#define                AMDFCH41_WDT_RES_MASK   0x03
+#define                AMDFCH41_WDT_RES_32US   0x00
+#define                AMDFCH41_WDT_RES_10MS   0x01
+#define                AMDFCH41_WDT_RES_100MS  0x02
+#define                AMDFCH41_WDT_RES_1S     0x03
+#define                AMDFCH41_WDT_EN_MASK    0x0c
+#define                AMDFCH41_WDT_ENABLE     0x00
+#define        AMDFCH41_PM_ISA_CTRL            0x04
+#define                AMDFCH41_MMIO_EN        0x02
+
+/*
+ * Fixed MMIO addresses for accessing Watchdog and SMBus registers.
+ * See BKDG for Family 16h Models 30h-3Fh 3.26.13 PMx00 and PMx04.
+ */
+#define        AMDFCH41_WDT_FIXED_ADDR         0xfeb00000u
+#define        AMDFCH41_MMIO_ADDR              0xfed80000u
+#define AMDFCH41_MMIO_SMBUS_OFF                0x0a00
+#define AMDFCH41_MMIO_WDT_OFF          0x0b00
+
+/*
+ * PCI Device IDs and revisions.
+ * SB600 RRG 2.3.1.1,
+ * SB7xx RRG 2.3.1.1,
+ * SB8xx RRG 2.3.1,
+ * BKDG for Family 16h Models 00h-0Fh 3.26.7.1,
+ * BKDG for Family 16h Models 30h-3Fh 3.26.7.1.
+ * Also, see i2c-piix4 aka piix4_smbus Linux driver.
+ */
+#define        AMDSB_SMBUS_DEVID               0x43851002
+#define        AMDSB8_SMBUS_REVID              0x40
+#define        AMDFCH_SMBUS_DEVID              0x780b1022
+#define        AMDFCH41_SMBUS_REVID            0x41
+#define        AMDCZ_SMBUS_DEVID               0x790b1022
+#define        AMDCZ49_SMBUS_REVID             0x49
+

Modified: head/sys/dev/amdsbwd/amdsbwd.c
==============================================================================
--- head/sys/dev/amdsbwd/amdsbwd.c      Thu Sep 22 21:23:28 2016        
(r306217)
+++ head/sys/dev/amdsbwd/amdsbwd.c      Thu Sep 22 21:34:35 2016        
(r306218)
@@ -59,38 +59,13 @@ __FBSDID("$FreeBSD$");
 #include <sys/watchdog.h>
 
 #include <dev/pci/pcivar.h>
+#include <dev/amdsbwd/amd_chipset.h>
 #include <isa/isavar.h>
 
-/* SB7xx RRG 2.3.3.1.1. */
-#define        AMDSB_PMIO_INDEX                0xcd6
-#define        AMDSB_PMIO_DATA                 (PMIO_INDEX + 1)
-#define        AMDSB_PMIO_WIDTH                2
-/* SB7xx RRG 2.3.3.2. */
-#define        AMDSB_PM_RESET_STATUS0          0x44
-#define        AMDSB_PM_RESET_STATUS1          0x45
-#define                AMDSB_WD_RST_STS        0x02
-/* SB7xx RRG 2.3.3.2, RPR 2.36. */
-#define        AMDSB_PM_WDT_CTRL               0x69
-#define                AMDSB_WDT_DISABLE       0x01
-#define                AMDSB_WDT_RES_MASK      (0x02 | 0x04)
-#define                AMDSB_WDT_RES_32US      0x00
-#define                AMDSB_WDT_RES_10MS      0x02
-#define                AMDSB_WDT_RES_100MS     0x04
-#define                AMDSB_WDT_RES_1S        0x06
-#define        AMDSB_PM_WDT_BASE_LSB           0x6c
-#define        AMDSB_PM_WDT_BASE_MSB           0x6f
-/* SB8xx RRG 2.3.3. */
-#define        AMDSB8_PM_WDT_EN                0x48
-#define                AMDSB8_WDT_DEC_EN       0x01
-#define                AMDSB8_WDT_DISABLE      0x02
-#define        AMDSB8_PM_WDT_CTRL              0x4c
-#define                AMDSB8_WDT_32KHZ        0x00
-#define                AMDSB8_WDT_1HZ          0x03
-#define                AMDSB8_WDT_RES_MASK     0x03
-#define        AMDSB8_PM_RESET_STATUS0         0xC0
-#define        AMDSB8_PM_RESET_STATUS1         0xC1
-#define                AMDSB8_WD_RST_STS       0x20
-/* SB7xx RRG 2.3.4, WDRT. */
+/*
+ * Registers in the Watchdog IO space.
+ * See SB7xx RRG 2.3.4, WDRT.
+ */
 #define        AMDSB_WD_CTRL                   0x00
 #define                AMDSB_WD_RUN            0x01
 #define                AMDSB_WD_FIRED          0x02
@@ -101,28 +76,6 @@ __FBSDID("$FreeBSD$");
 #define        AMDSB_WD_COUNT                  0x04
 #define                AMDSB_WD_COUNT_MASK     0xffff
 #define        AMDSB_WDIO_REG_WIDTH            4
-/* WDRT */
-#define        MAXCOUNT_MIN_VALUE              511
-/* SB7xx RRG 2.3.1.1, SB600 RRG 2.3.1.1, SB8xx RRG 2.3.1.  */
-#define        AMDSB_SMBUS_DEVID               0x43851002
-#define        AMDSB8_SMBUS_REVID              0x40
-#define        AMDHUDSON_SMBUS_DEVID           0x780b1022
-#define        AMDKERNCZ_SMBUS_DEVID           0x790b1022
-/* BKDG Family 16h Models 30h - 3Fh */
-#define AMDFCH16H3XH_PM_WDT_EN         0x00
-#define                AMDFCH_WDT_DEC_EN       0x80
-#define        AMDFCH16H3XH_PM_WDT_CTRL        0x03
-#define                AMDFCH_WDT_RES_MASK     0x03
-#define                AMDFCH_WDT_RES_32US     0x00
-#define                AMDFCH_WDT_RES_10MS     0x01
-#define                AMDFCH_WDT_RES_100MS    0x02
-#define                AMDFCH_WDT_RES_1S       0x03
-#define                AMDFCH_WDT_ENABLE_MASK  0x0c
-#define                AMDFCH_WDT_ENABLE       0x00
-#define        AMDFCH16H3XH_PM_MMIO_CTRL       0x04
-#define                AMDFCH_WDT_MMIO_EN      0x02
-#define        AMDFCH16H3XH_WDT_ADDR1          0xfed80b00u
-#define        AMDFCH16H3XH_WDT_ADDR2          0xfeb00000u
 
 #define        amdsbwd_verbose_printf(dev, ...)        \
        do {                                            \
@@ -297,8 +250,8 @@ amdsbwd_identify(driver_t *driver, devic
        if (smb_dev == NULL)
                return;
        if (pci_get_devid(smb_dev) != AMDSB_SMBUS_DEVID &&
-           pci_get_devid(smb_dev) != AMDHUDSON_SMBUS_DEVID &&
-           pci_get_devid(smb_dev) != AMDKERNCZ_SMBUS_DEVID)
+           pci_get_devid(smb_dev) != AMDFCH_SMBUS_DEVID &&
+           pci_get_devid(smb_dev) != AMDCZ_SMBUS_DEVID)
                return;
 
        child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "amdsbwd", -1);
@@ -397,48 +350,48 @@ amdsbwd_probe_sb8xx(device_t dev, struct
 }
 
 static void
-amdsbwd_probe_fch_16h_3xh(device_t dev, struct resource *pmres, uint32_t *addr)
+amdsbwd_probe_fch41(device_t dev, struct resource *pmres, uint32_t *addr)
 {
        uint8_t val;
 
-       val = pmio_read(pmres, AMDFCH16H3XH_PM_MMIO_CTRL);
-       if ((val & AMDFCH_WDT_MMIO_EN) != 0) {
+       val = pmio_read(pmres, AMDFCH41_PM_ISA_CTRL);
+       if ((val & AMDFCH41_MMIO_EN) != 0) {
                /* Fixed offset for the watchdog within ACPI MMIO range. */
                amdsbwd_verbose_printf(dev, "ACPI MMIO range is enabled\n");
-               *addr = AMDFCH16H3XH_WDT_ADDR1;
+               *addr = AMDFCH41_MMIO_ADDR + AMDFCH41_MMIO_WDT_OFF;
        } else {
                /*
                 * Enable decoding of watchdog MMIO address.
                 */
-               val = pmio_read(pmres, AMDFCH16H3XH_PM_WDT_EN);
-               val |= AMDFCH_WDT_DEC_EN;
-               pmio_write(pmres, AMDFCH16H3XH_PM_WDT_EN, val);
+               val = pmio_read(pmres, AMDFCH41_PM_DECODE_EN0);
+               val |= AMDFCH41_WDT_EN;
+               pmio_write(pmres, AMDFCH41_PM_DECODE_EN0, val);
 #ifdef AMDSBWD_DEBUG
-               val = pmio_read(pmres, AMDFCH16H3XH_PM_WDT_EN);
-               device_printf(dev, "AMDFCH16H3XH_PM_WDT_EN value = %#04x\n",
+               val = pmio_read(pmres, AMDFCH41_PM_DECODE_EN0);
+               device_printf(dev, "AMDFCH41_PM_DECODE_EN0 value = %#04x\n",
                    val);
 #endif
 
                /* Special fixed MMIO range for the watchdog. */
-               *addr = AMDFCH16H3XH_WDT_ADDR2;
+               *addr = AMDFCH41_WDT_FIXED_ADDR;
        }
 
        /*
         * Set watchdog timer tick to 1s and
         * enable the watchdog device (in stopped state).
         */
-       val = pmio_read(pmres, AMDFCH16H3XH_PM_WDT_CTRL);
-       val &= ~AMDFCH_WDT_RES_MASK;
-       val |= AMDFCH_WDT_RES_1S;
-       val &= ~AMDFCH_WDT_ENABLE_MASK;
-       val |= AMDFCH_WDT_ENABLE;
-       pmio_write(pmres, AMDFCH16H3XH_PM_WDT_CTRL, val);
+       val = pmio_read(pmres, AMDFCH41_PM_DECODE_EN3);
+       val &= ~AMDFCH41_WDT_RES_MASK;
+       val |= AMDFCH41_WDT_RES_1S;
+       val &= ~AMDFCH41_WDT_EN_MASK;
+       val |= AMDFCH41_WDT_ENABLE;
+       pmio_write(pmres, AMDFCH41_PM_DECODE_EN3, val);
 #ifdef AMDSBWD_DEBUG
-       val = pmio_read(pmres, AMDFCH16H3XH_PM_WDT_CTRL);
-       amdsbwd_verbose_printf(dev, "AMDFCH16H3XH_PM_WDT_CTRL value = %#04x\n",
+       val = pmio_read(pmres, AMDFCH41_PM_DECODE_EN3);
+       amdsbwd_verbose_printf(dev, "AMDFCH41_PM_DECODE_EN3 value = %#04x\n",
            val);
 #endif
-       device_set_desc(dev, "AMD FCH Rev 42h+ Watchdog Timer");
+       device_set_desc(dev, "AMD FCH Rev 41h+ Watchdog Timer");
 }
 
 static int
@@ -476,11 +429,12 @@ amdsbwd_probe(device_t dev)
        revid = pci_get_revid(smb_dev);
        if (devid == AMDSB_SMBUS_DEVID && revid < AMDSB8_SMBUS_REVID)
                amdsbwd_probe_sb7xx(dev, res, &addr);
-       else if (devid == AMDSB_SMBUS_DEVID || devid == AMDKERNCZ_SMBUS_DEVID ||
-           (devid == AMDHUDSON_SMBUS_DEVID && revid < 0x42))
+       else if (devid == AMDSB_SMBUS_DEVID ||
+           (devid == AMDFCH_SMBUS_DEVID && revid < AMDFCH41_SMBUS_REVID) ||
+           (devid == AMDCZ_SMBUS_DEVID  && revid < AMDCZ49_SMBUS_REVID))
                amdsbwd_probe_sb8xx(dev, res, &addr);
        else
-               amdsbwd_probe_fch_16h_3xh(dev, res, &addr);
+               amdsbwd_probe_fch41(dev, res, &addr);
 
        bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
        bus_delete_resource(dev, SYS_RES_IOPORT, rid);

Modified: head/sys/dev/intpm/intpm.c
==============================================================================
--- head/sys/dev/intpm/intpm.c  Thu Sep 22 21:23:28 2016        (r306217)
+++ head/sys/dev/intpm/intpm.c  Thu Sep 22 21:34:35 2016        (r306218)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include <dev/intpm/intpmreg.h>
+#include <dev/amdsbwd/amd_chipset.h>
 
 #include "opt_intpm.h"
 
@@ -103,12 +104,11 @@ intsmb_probe(device_t dev)
        case 0x43721002:
                device_set_desc(dev, "ATI IXP400 SMBus Controller");
                break;
-       case 0x43851002:
+       case AMDSB_SMBUS_DEVID:
                device_set_desc(dev, "AMD SB600/7xx/8xx/9xx SMBus Controller");
                break;
-       case 0x780b1022:        /* AMD FCH */
-               if (pci_get_revid(dev) < 0x40)
-                       return (ENXIO);
+       case AMDFCH_SMBUS_DEVID:        /* AMD FCH */
+       case AMDCZ_SMBUS_DEVID:         /* AMD Carizzo FCH */
                device_set_desc(dev, "AMD FCH SMBus Controller");
                break;
        default:
@@ -119,7 +119,7 @@ intsmb_probe(device_t dev)
 }
 
 static uint8_t
-sb8xx_pmio_read(struct resource *res, uint8_t reg)
+amd_pmio_read(struct resource *res, uint8_t reg)
 {
        bus_write_1(res, 0, reg);       /* Index */
        return (bus_read_1(res, 1));    /* Data */
@@ -128,27 +128,18 @@ sb8xx_pmio_read(struct resource *res, ui
 static int
 sb8xx_attach(device_t dev)
 {
-       static const int        AMDSB_PMIO_INDEX = 0xcd6;
-       static const int        AMDSB_PMIO_WIDTH = 2;
-       static const int        AMDSB8_SMBUS_ADDR = 0x2c;
-       static const int                AMDSB8_SMBUS_EN = 0x01;
-       static const int                AMDSB8_SMBUS_ADDR_MASK = ~0x1fu;
        static const int        AMDSB_SMBIO_WIDTH = 0x14;
-       static const int        AMDSB_SMBUS_CFG = 0x10;
-       static const int                AMDSB_SMBUS_IRQ = 0x01;
-       static const int                AMDSB_SMBUS_REV_MASK = ~0x0fu;
-       static const int                AMDSB_SMBUS_REV_SHIFT = 4;
-       static const int        AMDSB_IO_RID = 0;
-
        struct intsmb_softc     *sc;
        struct resource         *res;
+       uint32_t                devid;
+       uint8_t                 revid;
        uint16_t                addr;
-       uint8_t                 cfg;
        int                     rid;
        int                     rc;
+       bool                    enabled;
 
        sc = device_get_softc(dev);
-       rid = AMDSB_IO_RID;
+       rid = 0;
        rc = bus_set_resource(dev, SYS_RES_IOPORT, rid, AMDSB_PMIO_INDEX,
            AMDSB_PMIO_WIDTH);
        if (rc != 0) {
@@ -156,26 +147,38 @@ sb8xx_attach(device_t dev)
                return (ENXIO);
        }
        res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
-           RF_ACTIVE | RF_SHAREABLE);
+           RF_ACTIVE);
        if (res == NULL) {
                device_printf(dev, "bus_alloc_resource for PM IO failed\n");
                return (ENXIO);
        }
 
-       addr = sb8xx_pmio_read(res, AMDSB8_SMBUS_ADDR + 1);
-       addr <<= 8;
-       addr |= sb8xx_pmio_read(res, AMDSB8_SMBUS_ADDR);
+       devid = pci_get_devid(dev);
+       revid = pci_get_revid(dev);
+       if (devid == AMDSB_SMBUS_DEVID ||
+           (devid == AMDFCH_SMBUS_DEVID && revid < AMDFCH41_SMBUS_REVID) ||
+           (devid == AMDCZ_SMBUS_DEVID  && revid < AMDCZ49_SMBUS_REVID)) {
+               addr = amd_pmio_read(res, AMDSB8_PM_SMBUS_EN + 1);
+               addr <<= 8;
+               addr |= amd_pmio_read(res, AMDSB8_PM_SMBUS_EN);
+               enabled = (addr & AMDSB8_SMBUS_EN) != 0;
+               addr &= AMDSB8_SMBUS_ADDR_MASK;
+       } else {
+               addr = amd_pmio_read(res, AMDFCH41_PM_DECODE_EN0);
+               enabled = (addr & AMDFCH41_SMBUS_EN) != 0;
+               addr = amd_pmio_read(res, AMDFCH41_PM_DECODE_EN1);
+               addr <<= 8;
+       }
 
        bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
        bus_delete_resource(dev, SYS_RES_IOPORT, rid);
 
-       if ((addr & AMDSB8_SMBUS_EN) == 0) {
-               device_printf(dev, "SB8xx SMBus not enabled\n");
+       if (!enabled) {
+               device_printf(dev, "SB8xx/SB9xx/FCH SMBus not enabled\n");
                return (ENXIO);
        }
 
-       addr &= AMDSB8_SMBUS_ADDR_MASK;
-       sc->io_rid = AMDSB_IO_RID;
+       sc->io_rid = 0;
        rc = bus_set_resource(dev, SYS_RES_IOPORT, sc->io_rid, addr,
            AMDSB_SMBIO_WIDTH);
        if (rc != 0) {
@@ -187,15 +190,8 @@ sb8xx_attach(device_t dev)
                return (ENXIO);
        }
        sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid,
-           RF_ACTIVE | RF_SHAREABLE);
-       cfg = bus_read_1(sc->io_res, AMDSB_SMBUS_CFG);
-
+           RF_ACTIVE);
        sc->poll = 1;
-       device_printf(dev, "intr %s disabled ",
-           (cfg & AMDSB_SMBUS_IRQ) != 0 ? "IRQ" : "SMI");
-       printf("revision %d\n",
-           (cfg & AMDSB_SMBUS_REV_MASK) >> AMDSB_SMBUS_REV_SHIFT);
-
        return (0);
 }
 
@@ -237,11 +233,12 @@ intsmb_attach(device_t dev)
                sc->cfg_irq9 = 1;
                break;
 #endif
-       case 0x43851002:
-               if (pci_get_revid(dev) >= 0x40)
+       case AMDSB_SMBUS_DEVID:
+               if (pci_get_revid(dev) >= AMDSB8_SMBUS_REVID)
                        sc->sb8xx = 1;
                break;
-       case 0x780b1022:
+       case AMDFCH_SMBUS_DEVID:
+       case AMDCZ_SMBUS_DEVID:
                sc->sb8xx = 1;
                break;
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to