[Midnightbsd-cvs] src [10116] trunk/sys/dev/amdsbwd: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 20:12:27 EDT 2018


Revision: 10116
          http://svnweb.midnightbsd.org/src/?rev=10116
Author:   laffer1
Date:     2018-05-27 20:12:27 -0400 (Sun, 27 May 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/sys/dev/amdsbwd/amdsbwd.c

Added Paths:
-----------
    trunk/sys/dev/amdsbwd/amd_chipset.h

Added: trunk/sys/dev/amdsbwd/amd_chipset.h
===================================================================
--- trunk/sys/dev/amdsbwd/amd_chipset.h	                        (rev 0)
+++ trunk/sys/dev/amdsbwd/amd_chipset.h	2018-05-28 00:12:27 UTC (rev 10116)
@@ -0,0 +1,148 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2016 Andriy Gapon <avg at 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: stable/10/sys/dev/amdsbwd/amd_chipset.h 306817 2016-10-07 18:53:28Z avg $
+ */
+
+/*
+ * 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
+ * - 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 variants of "Hudson" and "Bolton" as well as FCHs
+ *     integrated into processors, e.g. "Kabini")
+ *   o FCHs where the controller has an ID of 0x790b1022 and a revision less
+ *     than 0x49
+ * - several types of 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.
+ */
+
+/*
+ * 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 15h Models 60h-6Fh 3.26.6.1,
+ * BKDG for Family 15h Models 70h-7Fh 3.26.6.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
+


Property changes on: trunk/sys/dev/amdsbwd/amd_chipset.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/amdsbwd/amdsbwd.c
===================================================================
--- trunk/sys/dev/amdsbwd/amdsbwd.c	2018-05-28 00:11:41 UTC (rev 10115)
+++ trunk/sys/dev/amdsbwd/amdsbwd.c	2018-05-28 00:12:27 UTC (rev 10116)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Andriy Gapon <avg at FreeBSD.org>
  * All rights reserved.
@@ -45,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD: src/sys/dev/amdsbwd/amdsbwd.c,v 1.1 2011/10/20 04:39:31 laffer1 Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/amdsbwd/amdsbwd.c 328845 2018-02-04 13:58:29Z avg $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -59,38 +60,13 @@
 #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,11 +77,6 @@
 #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	amdsbwd_verbose_printf(dev, ...)	\
 	do {						\
@@ -139,7 +110,7 @@
 #if 0
 	DEVMETHOD(device_shutdown,	amdsbwd_detach),
 #endif
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t	amdsbwd_devclass;
@@ -238,21 +209,30 @@
 amdsbwd_event(void *arg, unsigned int cmd, int *error)
 {
 	struct amdsbwd_softc *sc = arg;
-	unsigned int timeout;
+	uint64_t timeout;
 
-	/* convert from power-of-two-ns to WDT ticks */
-	cmd &= WD_INTERVAL;
-	if (cmd < WD_TO_1SEC)
-		cmd = 0;
-	if (cmd) {
-		timeout = ((uint64_t)1 << (cmd - WD_TO_1MS)) / sc->ms_per_tick;
+	if (cmd != 0) {
+		timeout = 0;
+		cmd &= WD_INTERVAL;
+		if (cmd >= WD_TO_1MS) {
+			timeout = (uint64_t)1 << (cmd - WD_TO_1MS);
+			timeout = timeout / sc->ms_per_tick;
+		}
+		/* For a too short timeout use 1 tick. */
+		if (timeout == 0)
+			timeout = 1;
+		/* For a too long timeout stop the timer. */
 		if (timeout > sc->max_ticks)
-			timeout = sc->max_ticks;
-		if (timeout != sc->timeout) {
+			timeout = 0;
+	} else {
+		timeout = 0;
+	}
+
+	if (timeout != 0) {
+		if (timeout != sc->timeout)
 			amdsbwd_tmr_set(sc, timeout);
-			if (!sc->active)
-				amdsbwd_tmr_enable(sc);
-		}
+		if (!sc->active)
+			amdsbwd_tmr_enable(sc);
 		amdsbwd_tmr_reload(sc);
 		*error = 0;
 	} else {
@@ -279,7 +259,9 @@
 	smb_dev = pci_find_bsf(0, 20, 0);
 	if (smb_dev == NULL)
 		return;
-	if (pci_get_devid(smb_dev) != AMDSB_SMBUS_DEVID)
+	if (pci_get_devid(smb_dev) != AMDSB_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);
@@ -291,8 +273,8 @@
 static void
 amdsbwd_probe_sb7xx(device_t dev, struct resource *pmres, uint32_t *addr)
 {
-	uint32_t	val;
-	int		i;
+	uint8_t	val;
+	int	i;
 
 	/* Report cause of previous reset for user's convenience. */
 	val = pmio_read(pmres, AMDSB_PM_RESET_STATUS0);
@@ -309,10 +291,12 @@
 		*addr <<= 8;
 		*addr |= pmio_read(pmres, AMDSB_PM_WDT_BASE_MSB - i);
 	}
+	*addr &= ~0x07u;
+
 	/* Set watchdog timer tick to 1s. */
 	val = pmio_read(pmres, AMDSB_PM_WDT_CTRL);
 	val &= ~AMDSB_WDT_RES_MASK;
-	val |= AMDSB_WDT_RES_10MS;
+	val |= AMDSB_WDT_RES_1S;
 	pmio_write(pmres, AMDSB_PM_WDT_CTRL, val);
 
 	/* Enable watchdog device (in stopped state). */
@@ -330,8 +314,8 @@
 static void
 amdsbwd_probe_sb8xx(device_t dev, struct resource *pmres, uint32_t *addr)
 {
-	uint32_t	val;
-	int		i;
+	uint8_t	val;
+	int	i;
 
 	/* Report cause of previous reset for user's convenience. */
 	val = pmio_read(pmres, AMDSB8_PM_RESET_STATUS0);
@@ -357,7 +341,7 @@
 	pmio_write(pmres, AMDSB8_PM_WDT_CTRL, val);
 #ifdef AMDSBWD_DEBUG
 	val = pmio_read(pmres, AMDSB8_PM_WDT_CTRL);
-	amdsbwd_verbose_printf(dev, "AMDSB8_PM_WDT_CTRL value = %#02x\n", val);
+	amdsbwd_verbose_printf(dev, "AMDSB8_PM_WDT_CTRL value = %#04x\n", val);
 #endif
 
 	/*
@@ -370,11 +354,56 @@
 	pmio_write(pmres, AMDSB8_PM_WDT_EN, val);
 #ifdef AMDSBWD_DEBUG
 	val = pmio_read(pmres, AMDSB8_PM_WDT_EN);
-	device_printf(dev, "AMDSB8_PM_WDT_EN value = %#02x\n", val);
+	device_printf(dev, "AMDSB8_PM_WDT_EN value = %#04x\n", val);
 #endif
-	device_set_desc(dev, "AMD SB8xx Watchdog Timer");
+	device_set_desc(dev, "AMD SB8xx/SB9xx/Axx Watchdog Timer");
 }
 
+static void
+amdsbwd_probe_fch41(device_t dev, struct resource *pmres, uint32_t *addr)
+{
+	uint8_t	val;
+
+	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 = AMDFCH41_MMIO_ADDR + AMDFCH41_MMIO_WDT_OFF;
+	} else {
+		/*
+		 * Enable decoding of watchdog MMIO address.
+		 */
+		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, AMDFCH41_PM_DECODE_EN0);
+		device_printf(dev, "AMDFCH41_PM_DECODE_EN0 value = %#04x\n",
+		    val);
+#endif
+
+		/* Special fixed MMIO range for the watchdog. */
+		*addr = AMDFCH41_WDT_FIXED_ADDR;
+	}
+
+	/*
+	 * Set watchdog timer tick to 1s and
+	 * enable the watchdog device (in stopped state).
+	 */
+	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, AMDFCH41_PM_DECODE_EN3);
+	amdsbwd_verbose_printf(dev, "AMDFCH41_PM_DECODE_EN3 value = %#04x\n",
+	    val);
+#endif
+	device_set_desc(dev, "AMD FCH Rev 41h+ Watchdog Timer");
+}
+
 static int
 amdsbwd_probe(device_t dev)
 {
@@ -383,6 +412,8 @@
 	uint32_t		addr;
 	int			rid;
 	int			rc;
+	uint32_t		devid;
+	uint8_t			revid;
 
 	/* Do not claim some ISA PnP device by accident. */
 	if (isa_get_logicalid(dev) != 0)
@@ -395,8 +426,8 @@
 		return (ENXIO);
 	}
 	rid = 0;
-	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul,
-	    AMDSB_PMIO_WIDTH, RF_ACTIVE | RF_SHAREABLE);
+	res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
 	if (res == NULL) {
 		device_printf(dev, "bus_alloc_resource for IO failed\n");
 		return (ENXIO);
@@ -404,10 +435,16 @@
 
 	smb_dev = pci_find_bsf(0, 20, 0);
 	KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
-	if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID)
+	devid = pci_get_devid(smb_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 == AMDFCH_SMBUS_DEVID && revid < AMDFCH41_SMBUS_REVID) ||
+	    (devid == AMDCZ_SMBUS_DEVID  && revid < AMDCZ49_SMBUS_REVID))
+		amdsbwd_probe_sb8xx(dev, res, &addr);
 	else
-		amdsbwd_probe_sb8xx(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);
@@ -432,18 +469,12 @@
 static int
 amdsbwd_attach_sb(device_t dev, struct amdsbwd_softc *sc)
 {
-	device_t	smb_dev;
 
 	sc->max_ticks = UINT16_MAX;
 	sc->rid_ctrl = 0;
 	sc->rid_count = 1;
 
-	smb_dev = pci_find_bsf(0, 20, 0);
-	KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
-	if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID)
-		sc->ms_per_tick = 10;
-	else
-		sc->ms_per_tick = 1000;
+	sc->ms_per_tick = 1000;
 
 	sc->res_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
 	    &sc->rid_ctrl, RF_ACTIVE);



More information about the Midnightbsd-cvs mailing list