On Tue, Jan 07, 2020 at 09:27:50AM +0100, Claudio Jeker wrote:
> In -current I added support for the additional I2C busses on piixpm(4)
> now I noticed that on my old AMD system the I2C bus seems to either
> connect all those 4 busses together (or there is a bug in the driver).
Looks like this is indeed a problem with the driver.
With the following diff I now get:
piixpm0 at pci0 dev 20 function 0 "ATI SBx00 SMBus" rev 0x41: polling
iic0 at piixpm0
sdtemp0 at iic0 addr 0x18: stts2002
sdtemp1 at iic0 addr 0x19: stts2002
sdtemp2 at iic0 addr 0x1a: stts2002
sdtemp3 at iic0 addr 0x1b: stts2002
spdmem0 at iic0 addr 0x50: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
spdmem1 at iic0 addr 0x51: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
spdmem2 at iic0 addr 0x52: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
spdmem3 at iic0 addr 0x53: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
iic1 at piixpm0
piixpm0: exec: op 1, addr 0x18, cmdlen 1, len 0, flags 0x08: timeout, status 0x1
<BUSY>
iic2 at piixpm0
iic3 at piixpm0
Not sure what is up with the timeout on iic @ addr 0x18. If that is seen
on more systems it may be better to only use the primary bus on SB800
devices that don't support SB800_PMREG_SMB0SEL.
Please test and report back.
--
:wq Claudio
Index: piixpm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/piixpm.c,v
retrieving revision 1.40
diff -u -p -r1.40 piixpm.c
--- piixpm.c 16 Dec 2019 21:39:40 -0000 1.40
+++ piixpm.c 7 Jan 2020 11:19:09 -0000
@@ -60,6 +60,7 @@ struct piixpm_softc {
int sc_poll;
int sc_is_sb800;
int sc_is_fch;
+ int sc_sb800_selen;
struct piixpm_smbus sc_busses[4];
struct i2c_controller sc_i2c_tag[4];
@@ -181,6 +182,12 @@ piixpm_attach(struct device *parent, str
val |= (bus_space_read_1(sc->sc_iot, ioh, 1) << 8);
smb0en = val & SB800_SMB0EN_EN;
base = val & SB800_SMB0EN_BASE_MASK;
+
+ bus_space_write_1(sc->sc_iot, ioh, 0,
+ SB800_PMREG_SMB0SELEN);
+ val = bus_space_read_1(sc->sc_iot, ioh, 1);
+ if (val & SB800_SMB0SELEN_EN)
+ sc->sc_sb800_selen = 1;
}
if (smb0en == 0) {
@@ -296,11 +303,20 @@ piixpm_i2c_acquire_bus(void *cookie, int
AMDFCH41_PM_PORT_INDEX);
bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1,
smbus->sb_bus << 3);
- } else if (sc->sc_is_sb800) {
+ } else if (sc->sc_is_sb800 && sc->sc_sb800_selen) {
bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 0,
SB800_PMREG_SMB0SEL);
bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1,
smbus->sb_bus << 1);
+ } else if (sc->sc_is_sb800) {
+ uint8_t val;
+
+ bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 0,
+ SB800_PMREG_SMB0EN);
+ val = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh, 1) &
+ ~SB800_SMB0EN_PORT_MASK;
+ val |= smbus->sb_bus << 1;
+ bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1, val);
}
return (0);
@@ -317,11 +333,20 @@ piixpm_i2c_release_bus(void *cookie, int
AMDFCH41_PM_PORT_INDEX);
bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1,
0);
- } else if (sc->sc_is_sb800) {
+ } else if (sc->sc_is_sb800 && sc->sc_sb800_selen) {
bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 0,
SB800_PMREG_SMB0SEL);
bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1,
0);
+ } else if (sc->sc_is_sb800) {
+ uint8_t val;
+
+ bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 0,
+ SB800_PMREG_SMB0EN);
+ val = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh, 1) &
+ ~SB800_SMB0EN_PORT_MASK;
+ val |= 0;
+ bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1, val);
}
if (cold || sc->sc_poll || (flags & I2C_F_POLL))
Index: piixreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/piixreg.h,v
retrieving revision 1.5
diff -u -p -r1.5 piixreg.h
--- piixreg.h 16 Dec 2019 21:39:40 -0000 1.5
+++ piixreg.h 7 Jan 2020 11:12:29 -0000
@@ -70,8 +70,11 @@
#define SB800_PMREG_SIZE 2 /* index/data pair */
#define SB800_PMREG_SMB0EN 0x2c /* 16-bit register */
#define SB800_PMREG_SMB0SEL 0x2e /* bus selection */
+#define SB800_PMREG_SMB0SELEN 0x2f /* bus selection enable */
#define SB800_SMB0EN_EN 0x0001
#define SB800_SMB0EN_BASE_MASK 0xffe0
+#define SB800_SMB0EN_PORT_MASK 0x06
+#define SB800_SMB0SELEN_EN 0x01
#define SB800_SMB_HOSTC 0x10 /* I2C bus configuration */
#define SB800_SMB_HOSTC_SMI (1 << 0) /* SMI */