> Date: Thu, 19 May 2011 19:09:36 -0400 > From: Brynet <bry...@gmail.com> > > Here it is a again with the magic relocated to piixreg.h. > > To clarify, if you have: > piixpm0 at pci0 dev 20 function 0 "ATI SBx00 SMBus" > > Then check if the revision is >= 0x40, which is the relevant southbridge. > > If it works, you'll see pretty stuff like this:: > spdmem0 at iic addr 0x50: 2GB DDR3 SDRAM PC3-10600 SO-DIMM > ..
Had a look at the chipset docs, and it took me some time to figure out how AMD had hidden these registers away. So I wrote a somewhat less cryptic comment that explains the code a bit better. I also noticed that there is a register that indicates whether SMI is enabled or not. So here's a cleaned up diff. Does this still work for you? Index: piixpm.c =================================================================== RCS file: /cvs/src/sys/dev/pci/piixpm.c,v retrieving revision 1.35 diff -u -p -r1.35 piixpm.c --- piixpm.c 9 Apr 2011 04:33:40 -0000 1.35 +++ piixpm.c 21 May 2011 20:29:19 -0000 @@ -114,28 +114,80 @@ piixpm_attach(struct device *parent, str { struct piixpm_softc *sc = (struct piixpm_softc *)self; struct pci_attach_args *pa = aux; - struct i2cbus_attach_args iba; - pcireg_t base, conf; + bus_space_handle_t ioh; + u_int16_t smb0en; + bus_addr_t base; + pcireg_t conf; pci_intr_handle_t ih; const char *intrstr = NULL; + struct i2cbus_attach_args iba; - /* Read configuration */ - conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); - DPRINTF((": conf 0x%08x", conf)); - - if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { - printf(": SMBus disabled\n"); - return; - } - - /* Map I/O space */ sc->sc_iot = pa->pa_iot; - base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; - if (PCI_MAPREG_IO_ADDR(base) == 0 || - bus_space_map(sc->sc_iot, PCI_MAPREG_IO_ADDR(base), - PIIX_SMB_SIZE, 0, &sc->sc_ioh)) { - printf(": can't map i/o space\n"); - return; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SBX00_SMB && + PCI_REVISION(pa->pa_class) >= 0x40) { + /* + * On the AMD SB800, the SMBus I/O registers are well + * hidden. We need to look at the "SMBus0En" Power + * Management register to find out where they live. + * We use indirect IO access through the index/data + * pair at 0xcd6/0xcd7 to access "SMBus0En". Since + * the index/data pair may be needed by other drivers, + * we only map them for the duration that we actually + * need them. + */ + if (bus_space_map(sc->sc_iot, SB800_PMREG_BASE, + SB800_PMREG_SIZE, 0, &ioh) != 0) { + printf(": can't map i/o space\n"); + return; + } + + /* Read "SmBus0En" */ + bus_space_write_1(sc->sc_iot, ioh, 0, SB800_PMREG_SMB0EN); + smb0en = bus_space_read_1(sc->sc_iot, ioh, 1); + bus_space_write_1(sc->sc_iot, ioh, 0, SB800_PMREG_SMB0EN + 1); + smb0en |= (bus_space_read_1(sc->sc_iot, ioh, 1) << 8); + + bus_space_unmap(sc->sc_iot, ioh, SB800_PMREG_SIZE); + + if ((smb0en & SB800_SMB0EN_EN) == 0) { + printf(": SMBus disabled\n"); + return; + } + + /* Map I/O space */ + base = smb0en & SB800_SMB0EN_BASE_MASK; + if (base == 0 || bus_space_map(sc->sc_iot, base, + SB800_SMB_SIZE, 0, &sc->sc_ioh)) { + printf(": can't map i/o space"); + return; + } + + /* Read configuration */ + conf = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SB800_SMB_HOSTC); + if (conf & SB800_SMB_HOSTC_SMI) + conf = PIIX_SMB_HOSTC_SMI; + else + conf = PIIX_SMB_HOSTC_IRQ; + } else { + /* Read configuration */ + conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); + DPRINTF((": conf 0x%08x", conf)); + + if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { + printf(": SMBus disabled\n"); + return; + } + + /* Map I/O space */ + base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & + PIIX_SMB_BASE_MASK; + if (base == 0 || bus_space_map(sc->sc_iot, base, + PIIX_SMB_SIZE, 0, &sc->sc_ioh)) { + printf(": can't map i/o space\n"); + return; + } } sc->sc_poll = 1; Index: piixreg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/piixreg.h,v retrieving revision 1.3 diff -u -p -r1.3 piixreg.h --- piixreg.h 3 Jan 2006 22:39:03 -0000 1.3 +++ piixreg.h 21 May 2011 20:29:19 -0000 @@ -29,6 +29,7 @@ /* PCI configuration registers */ #define PIIX_SMB_BASE 0x90 /* SMBus base address */ +#define PIIX_SMB_BASE_MASK 0xfffe #define PIIX_SMB_HOSTC 0xd0 /* SMBus host configuration */ #define PIIX_SMB_HOSTC_HSTEN (1 << 16) /* enable host controller */ #define PIIX_SMB_HOSTC_SMI (0 << 17) /* SMI */ @@ -63,5 +64,17 @@ #define PIIX_SMB_SC_ALERTEN (1 << 3) /* enable SMBALERT# */ #define PIIX_SMB_SIZE 0x10 /* SMBus I/O space size */ + +/* AMD SB800 configuration registers */ +#define SB800_PMREG_BASE 0xcd6 +#define SB800_PMREG_SIZE 2 /* index/data pair */ +#define SB800_PMREG_SMB0EN 0x2c /* 16-bit register */ +#define SB800_SMB0EN_EN 0x0001 +#define SB800_SMB0EN_BASE_MASK 0xffe0 + +#define SB800_SMB_HOSTC 0x10 /* I2C bus configuration */ +#define SB800_SMB_HOSTC_SMI (1 << 0) /* SMI */ + +#define SB800_SMB_SIZE 0x14 /* SMBus I/O space size */ #endif /* !_DEV_PCI_PIIXREG_H_ */