Module Name: src Committed By: msaitoh Date: Tue Dec 24 03:43:34 UTC 2019
Modified Files: src/sys/dev/pci: piixpm.c piixpmreg.h Log Message: Don't force using SMBUS0SEL register. - Use it depending on USE_SMBUS0SEL bit. - If we use SMBUS0EN_LO register to select the port, update the port select bits only. To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/dev/pci/piixpm.c cvs rdiff -u -r1.9 -r1.10 src/sys/dev/pci/piixpmreg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/piixpm.c diff -u src/sys/dev/pci/piixpm.c:1.58 src/sys/dev/pci/piixpm.c:1.59 --- src/sys/dev/pci/piixpm.c:1.58 Mon Dec 23 23:41:43 2019 +++ src/sys/dev/pci/piixpm.c Tue Dec 24 03:43:34 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: piixpm.c,v 1.58 2019/12/23 23:41:43 msaitoh Exp $ */ +/* $NetBSD: piixpm.c,v 1.59 2019/12/24 03:43:34 msaitoh Exp $ */ /* $OpenBSD: piixpm.c,v 1.39 2013/10/01 20:06:02 sf Exp $ */ /* @@ -22,7 +22,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.58 2019/12/23 23:41:43 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.59 2019/12/24 03:43:34 msaitoh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -86,6 +86,7 @@ struct piixpm_softc { bus_space_handle_t sc_smb_ioh; void * sc_smb_ih; int sc_poll; + bool sc_sb800_selen; /* Use SMBUS0SEL */ pci_chipset_tag_t sc_pc; pcitag_t sc_pcitag; @@ -419,6 +420,8 @@ piixpm_sb800_init(struct piixpm_softc *s val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8; base_addr = val; } else { + uint8_t data; + bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0EN_LO); val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); @@ -433,8 +436,9 @@ piixpm_sb800_init(struct piixpm_softc *s bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SELEN); - bus_space_write_1(iot, ioh, SB800_INDIRECTIO_DATA, - SB800_PM_SMBUS0EN_ENABLE); + data = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); + if ((data & SB800_PM_USE_SMBUS0SEL) != 0) + sc->sc_sb800_selen = true; } sc->sc_sb800_ioh = ioh; @@ -482,10 +486,23 @@ piixpm_i2c_acquire_bus(void *cookie, int bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, SB800_INDIRECTIO_DATA, smbus->sda << 3); } else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) { - bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, - SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); - bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, - SB800_INDIRECTIO_DATA, smbus->sda << 1); + if (sc->sc_sb800_selen) { + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_DATA, + __SHIFTIN(smbus->sda, SB800_PM_SMBUS0_MASK_E)); + } else { + uint8_t data; + + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0EN_LO); + data = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_DATA) & ~SB800_PM_SMBUS0_MASK_C; + data |= __SHIFTIN(smbus->sda, SB800_PM_SMBUS0_MASK_C); + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_DATA, data); + } } return 0; @@ -500,17 +517,29 @@ piixpm_i2c_release_bus(void *cookie, int if (PIIXPM_IS_KERNCZ(sc)) { bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, SB800_INDIRECTIO_INDEX, AMDFCH41_PM_PORT_INDEX); + /* Set to port 0 */ bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, SB800_INDIRECTIO_DATA, 0); } else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) { - /* - * HP Microserver hangs after reboot if not set to SDA0. - * Also add shutdown hook? - */ - bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, - SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); - bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, - SB800_INDIRECTIO_DATA, 0); + if (sc->sc_sb800_selen) { + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); + + /* Set to port 0 */ + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_DATA, 0); + } else { + uint8_t data; + + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0EN_LO); + + /* Set to port 0 */ + data = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_DATA) & ~SB800_PM_SMBUS0_MASK_C; + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, + SB800_INDIRECTIO_DATA, data); + } } } Index: src/sys/dev/pci/piixpmreg.h diff -u src/sys/dev/pci/piixpmreg.h:1.9 src/sys/dev/pci/piixpmreg.h:1.10 --- src/sys/dev/pci/piixpmreg.h:1.9 Mon Dec 23 23:41:43 2019 +++ src/sys/dev/pci/piixpmreg.h Tue Dec 24 03:43:34 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: piixpmreg.h,v 1.9 2019/12/23 23:41:43 msaitoh Exp $ */ +/* $NetBSD: piixpmreg.h,v 1.10 2019/12/24 03:43:34 msaitoh Exp $ */ /* $OpenBSD: piixreg.h,v 1.3 2006/01/03 22:39:03 grange Exp $ */ /*- @@ -116,11 +116,17 @@ #define SB800_PM_SMBUS0EN_LO 0x2c #define SB800_PM_SMBUS0EN_HI 0x2d -#define SB800_PM_SMBUS0SEL 0x2e -#define SB800_PM_SMBUS0SELEN 0x2f - -#define SB800_PM_SMBUS0EN_ENABLE 0x0001 -#define SB800_PM_SMBUS0EN_BADDR 0xffe0 +#define SB800_PM_SMBUS0EN_ENABLE __BIT(0) /* Function enable */ +#define SB800_PM_SMBUS0_MASK_C __BITS(2, 1) /* Port mask (PMIO2C) */ +#define SB800_PM_SMBUS0EN_BADDR __BITS(15, 5) /* Base address */ + +#define SB800_PM_SMBUS0SEL 0x2e +#define SB800_PM_SMBUS0_MASK_E __BITS(2, 1) /* Port mask (PMIO2E) */ +#define SB800_PM_SMBUS0SELEN 0x2f +#define SB800_PM_USE_SMBUS0SEL __BIT(0) /* + * If the bit is set, SMBUS0SEL is + * used to select the port. + */ /* In the SMBus I/O space */ #define SB800_SMB_HOSTC 0x10 /* I2C bus configuration */