amdsbwd: add support for FCH in family 16h models 30h-3Fh processors
Requested by: Mike Tancsa <mike@sentex.net> Tested by: Mike Tancsa <mike@sentex.net> MFC after: 1 week
This commit is contained in:
parent
4c90f11b3c
commit
9626ccde7f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305535
@ -108,6 +108,21 @@ __FBSDID("$FreeBSD$");
|
||||
#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 { \
|
||||
@ -295,8 +310,8 @@ amdsbwd_identify(driver_t *driver, device_t parent)
|
||||
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);
|
||||
@ -336,8 +351,8 @@ amdsbwd_probe_sb7xx(device_t dev, struct resource *pmres, uint32_t *addr)
|
||||
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);
|
||||
@ -363,7 +378,7 @@ amdsbwd_probe_sb8xx(device_t dev, struct resource *pmres, uint32_t *addr)
|
||||
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
|
||||
|
||||
/*
|
||||
@ -376,11 +391,56 @@ amdsbwd_probe_sb8xx(device_t dev, struct resource *pmres, uint32_t *addr)
|
||||
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/SB9xx/Axx Watchdog Timer");
|
||||
}
|
||||
|
||||
static void
|
||||
amdsbwd_probe_fch_16h_3xh(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) {
|
||||
/* Fixed offset for the watchdog within ACPI MMIO range. */
|
||||
amdsbwd_verbose_printf(dev, "ACPI MMIO range is enabled\n");
|
||||
*addr = AMDFCH16H3XH_WDT_ADDR1;
|
||||
} 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);
|
||||
#ifdef AMDSBWD_DEBUG
|
||||
val = pmio_read(pmres, AMDFCH16H3XH_PM_WDT_EN);
|
||||
device_printf(dev, "AMDFCH16H3XH_PM_WDT_EN value = %#04x\n",
|
||||
val);
|
||||
#endif
|
||||
|
||||
/* Special fixed MMIO range for the watchdog. */
|
||||
*addr = AMDFCH16H3XH_WDT_ADDR2;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
#ifdef AMDSBWD_DEBUG
|
||||
val = pmio_read(pmres, AMDFCH16H3XH_PM_WDT_CTRL);
|
||||
amdsbwd_verbose_printf(dev, "AMDFCH16H3XH_PM_WDT_CTRL value = %#04x\n",
|
||||
val);
|
||||
#endif
|
||||
device_set_desc(dev, "AMD FCH Rev 42h+ Watchdog Timer");
|
||||
}
|
||||
|
||||
static int
|
||||
amdsbwd_probe(device_t dev)
|
||||
{
|
||||
@ -389,6 +449,8 @@ amdsbwd_probe(device_t dev)
|
||||
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)
|
||||
@ -410,11 +472,15 @@ amdsbwd_probe(device_t dev)
|
||||
|
||||
smb_dev = pci_find_bsf(0, 20, 0);
|
||||
KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
|
||||
if (pci_get_devid(smb_dev) == AMDSB_SMBUS_DEVID &&
|
||||
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
|
||||
else if (devid == AMDSB_SMBUS_DEVID || devid == AMDKERNCZ_SMBUS_DEVID ||
|
||||
(devid == AMDHUDSON_SMBUS_DEVID && revid < 0x42))
|
||||
amdsbwd_probe_sb8xx(dev, res, &addr);
|
||||
else
|
||||
amdsbwd_probe_fch_16h_3xh(dev, res, &addr);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
|
||||
bus_delete_resource(dev, SYS_RES_IOPORT, rid);
|
||||
@ -439,14 +505,11 @@ amdsbwd_probe(device_t dev)
|
||||
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"));
|
||||
sc->ms_per_tick = 1000;
|
||||
|
||||
sc->res_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
|
Loading…
Reference in New Issue
Block a user