On Tue, Jan 07, 2020 at 12:44:59PM +0100, Claudio Jeker wrote:
> 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.
Picking this up again. Since the second bus causes read timeouts and the
docu mentions that this bus is used for fan and temp control I think it is
better to just not attach the extra busses on these old AMD chipsets.
The additional SB800 busses will only be used if SB800_PMREG_SMB0SELEN
tells us that SMB0SELEN is enabled.
While looking at this I also investigated a bit more into the
PCI_PRODUCT_AMD_HUDSON2_SMB issues. So PCI ID 1022:780b are used by AMD
Bolton and Family 16h model 30h-3fh. AMD Bolton still needs the old layout
while the family 16h chips use the FCH register layout. So merge the if
statements a bit so that AMD Bolton uses the old code path and Family 16h
uses the new.
Last but not least I was informed that we reversed the meaning of
SB800_SMB_HOSTC_SMI (if SB800_SMB_HOSTC bit 1 is set then use IRQ else
SMI). This is visible in the dmesg line of piixpm.
Please test this since I can't test this properly at the moment.
Works for me on
piixpm0 at pci0 dev 20 function 0 "AMD FCH SMBus" rev 0x61: SMI
--
:wq Claudio
Index: piixpm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/piixpm.c,v
retrieving revision 1.41
diff -u -p -r1.41 piixpm.c
--- piixpm.c 9 Jan 2020 14:35:19 -0000 1.41
+++ piixpm.c 21 Jan 2020 01:23:21 -0000
@@ -158,8 +158,13 @@ piixpm_attach(struct device *parent, str
return;
}
+ /*
+ * AMD Bolton matches PCI_PRODUCT_AMD_HUDSON2_SMB but
+ * uses old register layout. Therefor check PCI_REVISION.
+ */
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
- (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON2_SMB ||
+ ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON2_SMB &&
+ PCI_REVISION(pa->pa_class) >= 0x1f) ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_KERNCZ_SMB)) {
bus_space_write_1(sc->sc_iot, ioh, 0,
AMDFCH41_PM_DECODE_EN);
@@ -170,6 +175,9 @@ piixpm_attach(struct device *parent, str
AMDFCH41_PM_DECODE_EN + 1);
val = bus_space_read_1(sc->sc_iot, ioh, 1) << 8;
base = val;
+
+ sc->sc_is_fch = 1;
+ numbusses = 2;
} else {
/* Read "SmBus0En" */
bus_space_write_1(sc->sc_iot, ioh, 0,
@@ -181,6 +189,14 @@ 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_is_sb800 = 1;
+ numbusses = 4;
+ }
}
if (smb0en == 0) {
@@ -190,17 +206,6 @@ piixpm_attach(struct device *parent, str
}
sc->sc_sb800_ioh = ioh;
- if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_KERNCZ_SMB) ||
- (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON2_SMB &&
- PCI_REVISION(pa->pa_class) >= 0x1f)) {
- sc->sc_is_fch = 1;
- numbusses = 2;
- } else {
- sc->sc_is_sb800 = 1;
- numbusses = 4;
- }
/* Map I/O space */
if (base == 0 || bus_space_map(sc->sc_iot, base,
@@ -213,10 +218,10 @@ piixpm_attach(struct device *parent, str
/* 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
+ if (conf & SB800_SMB_HOSTC_INTMASK)
conf = PIIX_SMB_HOSTC_IRQ;
+ else
+ conf = PIIX_SMB_HOSTC_SMI;
} else {
/* Read configuration */
conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC);
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 21 Jan 2020 01:22:49 -0000
@@ -70,11 +70,13 @@
#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_SMB0SELEN_EN 0x01
#define SB800_SMB_HOSTC 0x10 /* I2C bus configuration */
-#define SB800_SMB_HOSTC_SMI (1 << 0) /* SMI */
+#define SB800_SMB_HOSTC_INTMASK 0x1 /* 0: SMI 1: IRQ */
#define SB800_SMB_SIZE 0x14 /* SMBus I/O space size */