Add support for AMD FCH watchdog timers.

MFC after:	2 weeks
This commit is contained in:
mav 2016-03-29 12:19:46 +00:00
parent 13af8fa343
commit 785acb1fd1
2 changed files with 15 additions and 11 deletions

View File

@ -25,12 +25,12 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 7, 2011 .Dd March 29, 2016
.Dt AMDSBWD 4 .Dt AMDSBWD 4
.Os .Os
.Sh NAME .Sh NAME
.Nm amdsbwd .Nm amdsbwd
.Nd device driver for the AMD SB600/SB7xx/SB8xx watchdog timers .Nd device driver for the AMD southbridge watchdog timers
.Sh SYNOPSIS .Sh SYNOPSIS
To compile this driver into the kernel, To compile this driver into the kernel,
place the following line in your place the following line in your
@ -51,7 +51,7 @@ The
driver provides driver provides
.Xr watchdog 4 .Xr watchdog 4
support for the watchdog timers present on support for the watchdog timers present on
AMD SB600, SB7xx and SB8xx southbridges. AMD SB600, SB7xx, SB8xx and SB9xx southbridges and Axx FCHs.
.Sh SEE ALSO .Sh SEE ALSO
.Xr watchdog 4 , .Xr watchdog 4 ,
.Xr watchdog 8 , .Xr watchdog 8 ,

View File

@ -106,6 +106,8 @@ __FBSDID("$FreeBSD$");
/* SB7xx RRG 2.3.1.1, SB600 RRG 2.3.1.1, SB8xx RRG 2.3.1. */ /* SB7xx RRG 2.3.1.1, SB600 RRG 2.3.1.1, SB8xx RRG 2.3.1. */
#define AMDSB_SMBUS_DEVID 0x43851002 #define AMDSB_SMBUS_DEVID 0x43851002
#define AMDSB8_SMBUS_REVID 0x40 #define AMDSB8_SMBUS_REVID 0x40
#define AMDHUDSON_SMBUS_DEVID 0x780b1022
#define AMDKERNCZ_SMBUS_DEVID 0x790b1022
#define amdsbwd_verbose_printf(dev, ...) \ #define amdsbwd_verbose_printf(dev, ...) \
do { \ do { \
@ -279,7 +281,9 @@ amdsbwd_identify(driver_t *driver, device_t parent)
smb_dev = pci_find_bsf(0, 20, 0); smb_dev = pci_find_bsf(0, 20, 0);
if (smb_dev == NULL) if (smb_dev == NULL)
return; return;
if (pci_get_devid(smb_dev) != AMDSB_SMBUS_DEVID) 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)
return; return;
child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "amdsbwd", -1); child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "amdsbwd", -1);
@ -309,10 +313,12 @@ amdsbwd_probe_sb7xx(device_t dev, struct resource *pmres, uint32_t *addr)
*addr <<= 8; *addr <<= 8;
*addr |= pmio_read(pmres, AMDSB_PM_WDT_BASE_MSB - i); *addr |= pmio_read(pmres, AMDSB_PM_WDT_BASE_MSB - i);
} }
*addr &= ~0x07u;
/* Set watchdog timer tick to 1s. */ /* Set watchdog timer tick to 1s. */
val = pmio_read(pmres, AMDSB_PM_WDT_CTRL); val = pmio_read(pmres, AMDSB_PM_WDT_CTRL);
val &= ~AMDSB_WDT_RES_MASK; val &= ~AMDSB_WDT_RES_MASK;
val |= AMDSB_WDT_RES_10MS; val |= AMDSB_WDT_RES_1S;
pmio_write(pmres, AMDSB_PM_WDT_CTRL, val); pmio_write(pmres, AMDSB_PM_WDT_CTRL, val);
/* Enable watchdog device (in stopped state). */ /* Enable watchdog device (in stopped state). */
@ -372,7 +378,7 @@ amdsbwd_probe_sb8xx(device_t dev, struct resource *pmres, uint32_t *addr)
val = pmio_read(pmres, AMDSB8_PM_WDT_EN); 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 = %#02x\n", val);
#endif #endif
device_set_desc(dev, "AMD SB8xx Watchdog Timer"); device_set_desc(dev, "AMD SB8xx/SB9xx/Axx Watchdog Timer");
} }
static int static int
@ -404,7 +410,8 @@ amdsbwd_probe(device_t dev)
smb_dev = pci_find_bsf(0, 20, 0); smb_dev = pci_find_bsf(0, 20, 0);
KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n")); KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID) if (pci_get_devid(smb_dev) == AMDSB_SMBUS_DEVID &&
pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID)
amdsbwd_probe_sb7xx(dev, res, &addr); amdsbwd_probe_sb7xx(dev, res, &addr);
else else
amdsbwd_probe_sb8xx(dev, res, &addr); amdsbwd_probe_sb8xx(dev, res, &addr);
@ -440,10 +447,7 @@ amdsbwd_attach_sb(device_t dev, struct amdsbwd_softc *sc)
smb_dev = pci_find_bsf(0, 20, 0); smb_dev = pci_find_bsf(0, 20, 0);
KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n")); KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID) sc->ms_per_tick = 1000;
sc->ms_per_tick = 10;
else
sc->ms_per_tick = 1000;
sc->res_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY, sc->res_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->rid_ctrl, RF_ACTIVE); &sc->rid_ctrl, RF_ACTIVE);