Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Oct 2016 18:51:04 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r306815 - in stable/10: share/man/man4 sys/dev/amdsbwd sys/pci
Message-ID:  <201610071851.u97Ip48p063321@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Fri Oct  7 18:51:04 2016
New Revision: 306815
URL: https://svnweb.freebsd.org/changeset/base/306815

Log:
  MFC r306218,306290: amdsbwd, intpm: unify bits specific to AMD chipsets

Added:
  stable/10/sys/dev/amdsbwd/amd_chipset.h
     - copied, changed from r306218, head/sys/dev/amdsbwd/amd_chipset.h
Modified:
  stable/10/share/man/man4/intpm.4
  stable/10/sys/dev/amdsbwd/amdsbwd.c
  stable/10/sys/pci/intpm.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/share/man/man4/intpm.4
==============================================================================
--- stable/10/share/man/man4/intpm.4	Fri Oct  7 18:50:50 2016	(r306814)
+++ stable/10/share/man/man4/intpm.4	Fri Oct  7 18:51:04 2016	(r306815)
@@ -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 ,

Copied and modified: stable/10/sys/dev/amdsbwd/amd_chipset.h (from r306218, head/sys/dev/amdsbwd/amd_chipset.h)
==============================================================================
--- head/sys/dev/amdsbwd/amd_chipset.h	Thu Sep 22 21:34:35 2016	(r306218, copy source)
+++ stable/10/sys/dev/amdsbwd/amd_chipset.h	Fri Oct  7 18:51:04 2016	(r306815)
@@ -36,18 +36,23 @@
  * 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
+ * - several types of southbridges and FCHs:
+ *   o SB8x0, SB9x0 southbridges where the SMBus controller device has a PCI
+ *     Device ID of 0x43851002 and a revision greater than or equal to 0x40
+ *   o FCHs where the controller has an ID of 0x780b1022 and a revision less
+ *     than 0x41 (various revisions of "Hudson" and "Bolton")
+ *   o FCHs where the controller has an ID of 0x790b1022 and a revision less
+ *     than 0x49
+ * - several types of southbridges and FCHs:
+ *   o FCHs where the SMBus controller device has a PCI Device ID of 0x780b1022
+ *     and a revision greater than or equal to 0x41 (integrated into "Mullins"
+ *     processors, code named "ML")
+ *   o FCHs where the controller has an ID of 0x790b1022 and a revision greater
+ *     than or equal to 0x49 (integrated into "Carrizo" processors, code named
+ *     "KERNCZ" or "CZ")
+ *
  * 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.
  */
 
 /*

Modified: stable/10/sys/dev/amdsbwd/amdsbwd.c
==============================================================================
--- stable/10/sys/dev/amdsbwd/amdsbwd.c	Fri Oct  7 18:50:50 2016	(r306814)
+++ stable/10/sys/dev/amdsbwd/amdsbwd.c	Fri Oct  7 18:51:04 2016	(r306815)
@@ -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: stable/10/sys/pci/intpm.c
==============================================================================
--- stable/10/sys/pci/intpm.c	Fri Oct  7 18:50:50 2016	(r306814)
+++ stable/10/sys/pci/intpm.c	Fri Oct  7 18:51:04 2016	(r306815)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include <pci/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;
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610071851.u97Ip48p063321>