Page MenuHomeFreeBSD

D13654.id37103.diff
No OneTemporary

D13654.id37103.diff

Index: sys/dev/ichiic/ig4_acpi.c
===================================================================
--- sys/dev/ichiic/ig4_acpi.c
+++ sys/dev/ichiic/ig4_acpi.c
@@ -85,6 +85,8 @@
sc = device_get_softc(dev);
sc->dev = dev;
+ /* All the HIDs matched are Atom SOCs. */
+ sc->version = IG4_ATOM;
sc->regs_rid = 0;
sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->regs_rid, RF_ACTIVE);
Index: sys/dev/ichiic/ig4_iic.c
===================================================================
--- sys/dev/ichiic/ig4_iic.c
+++ sys/dev/ichiic/ig4_iic.c
@@ -525,22 +525,39 @@
mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF);
sx_init(&sc->call_lock, "IG4 call lock");
- v = reg_read(sc, IG4_REG_COMP_TYPE);
- v = reg_read(sc, IG4_REG_COMP_PARAM1);
- v = reg_read(sc, IG4_REG_GENERAL);
- if ((v & IG4_GENERAL_SWMODE) == 0) {
- v |= IG4_GENERAL_SWMODE;
- reg_write(sc, IG4_REG_GENERAL, v);
+ if (sc->version == IG4_ATOM) {
+ v = reg_read(sc, IG4_REG_COMP_TYPE);
+ }
+
+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
+ v = reg_read(sc, IG4_REG_COMP_PARAM1);
v = reg_read(sc, IG4_REG_GENERAL);
+ /*
+ * The content of IG4_REG_GENERAL is different for each
+ * controller version.
+ */
+ if (sc->version == IG4_HASWELL &&
+ (v & IG4_GENERAL_SWMODE) == 0) {
+ v |= IG4_GENERAL_SWMODE;
+ reg_write(sc, IG4_REG_GENERAL, v);
+ v = reg_read(sc, IG4_REG_GENERAL);
+ }
}
- v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
- v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
+ if (sc->version == IG4_HASWELL) {
+ v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
+ v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
+ } else if (sc->version == IG4_SKYLAKE) {
+ v = reg_read(sc, IG4_REG_ACTIVE_LTR_VALUE);
+ v = reg_read(sc, IG4_REG_IDLE_LTR_VALUE);
+ }
- v = reg_read(sc, IG4_REG_COMP_VER);
- if (v != IG4_COMP_VER) {
- error = ENXIO;
- goto done;
+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
+ v = reg_read(sc, IG4_REG_COMP_VER);
+ if (v != IG4_COMP_VER) {
+ error = ENXIO;
+ goto done;
+ }
}
v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
@@ -591,8 +608,13 @@
/*
* Don't do this, it blows up the PCI config
*/
- reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
- reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
+ reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_ASSERT_HSW);
+ reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_DEASSERT_HSW);
+ } else if (sc->version = IG4_SKYLAKE) {
+ reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL);
+ reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL);
+ }
#endif
mtx_lock(&sc->io_lock);
@@ -727,14 +749,27 @@
REGDUMP(sc, IG4_REG_DMA_RDLR);
REGDUMP(sc, IG4_REG_SDA_SETUP);
REGDUMP(sc, IG4_REG_ENABLE_STATUS);
- REGDUMP(sc, IG4_REG_COMP_PARAM1);
- REGDUMP(sc, IG4_REG_COMP_VER);
- REGDUMP(sc, IG4_REG_COMP_TYPE);
- REGDUMP(sc, IG4_REG_CLK_PARMS);
- REGDUMP(sc, IG4_REG_RESETS);
- REGDUMP(sc, IG4_REG_GENERAL);
- REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
- REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
+ REGDUMP(sc, IG4_REG_COMP_PARAM1);
+ REGDUMP(sc, IG4_REG_COMP_VER);
+ }
+ if (sc->version == IG4_ATOM) {
+ REGDUMP(sc, IG4_REG_COMP_TYPE);
+ REGDUMP(sc, IG4_REG_CLK_PARMS);
+ }
+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
+ REGDUMP(sc, IG4_REG_RESETS_HSW);
+ REGDUMP(sc, IG4_REG_GENERAL);
+ } else if (sc->version == IG4_SKYLAKE) {
+ REGDUMP(sc, IG4_REG_RESETS_SKL);
+ }
+ if (sc->version == IG4_HASWELL) {
+ REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
+ REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
+ } else if (sc->version == IG4_SKYLAKE) {
+ REGDUMP(sc, IG4_REG_ACTIVE_LTR_VALUE);
+ REGDUMP(sc, IG4_REG_IDLE_LTR_VALUE);
+ }
}
#undef REGDUMP
Index: sys/dev/ichiic/ig4_pci.c
===================================================================
--- sys/dev/ichiic/ig4_pci.c
+++ sys/dev/ichiic/ig4_pci.c
@@ -74,35 +74,75 @@
#define PCI_CHIP_BRASWELL_I2C_5 0x22c58086
#define PCI_CHIP_BRASWELL_I2C_6 0x22c68086
#define PCI_CHIP_BRASWELL_I2C_7 0x22c78086
+#define PCI_CHIP_SKYLAKE_I2C_0 0x9d608086
+#define PCI_CHIP_SKYLAKE_I2C_1 0x9d618086
+#define PCI_CHIP_SKYLAKE_I2C_2 0x9d628086
+#define PCI_CHIP_SKYLAKE_I2C_3 0x9d638086
+#define PCI_CHIP_SKYLAKE_I2C_4 0x9d648086
+#define PCI_CHIP_SKYLAKE_I2C_5 0x9d658086
static int
ig4iic_pci_probe(device_t dev)
{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+
switch(pci_get_devid(dev)) {
case PCI_CHIP_LYNXPT_LP_I2C_1:
device_set_desc(dev, "Intel Lynx Point-LP I2C Controller-1");
+ sc->version = IG4_HASWELL;
break;
case PCI_CHIP_LYNXPT_LP_I2C_2:
device_set_desc(dev, "Intel Lynx Point-LP I2C Controller-2");
+ sc->version = IG4_HASWELL;
break;
case PCI_CHIP_BRASWELL_I2C_1:
device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 1");
+ sc->version = IG4_ATOM;
break;
case PCI_CHIP_BRASWELL_I2C_2:
device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 2");
+ sc->version = IG4_ATOM;
break;
case PCI_CHIP_BRASWELL_I2C_3:
device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 3");
+ sc->version = IG4_ATOM;
break;
case PCI_CHIP_BRASWELL_I2C_5:
device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 5");
+ sc->version = IG4_ATOM;
break;
case PCI_CHIP_BRASWELL_I2C_6:
device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 6");
+ sc->version = IG4_ATOM;
break;
case PCI_CHIP_BRASWELL_I2C_7:
device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 7");
+ sc->version = IG4_ATOM;
break;
+ case PCI_CHIP_SKYLAKE_I2C_0:
+ device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-0");
+ sc->version = IG4_SKYLAKE;
+ break;
+ case PCI_CHIP_SKYLAKE_I2C_1:
+ device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-1");
+ sc->version = IG4_SKYLAKE;
+ break;
+ case PCI_CHIP_SKYLAKE_I2C_2:
+ device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-2");
+ sc->version = IG4_SKYLAKE;
+ break;
+ case PCI_CHIP_SKYLAKE_I2C_3:
+ device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-3");
+ sc->version = IG4_SKYLAKE;
+ break;
+ case PCI_CHIP_SKYLAKE_I2C_4:
+ device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-4");
+ sc->version = IG4_SKYLAKE;
+ break;
+ case PCI_CHIP_SKYLAKE_I2C_5:
+ device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-5");
+ sc->version = IG4_SKYLAKE;
+ break;
default:
return (ENXIO);
}
Index: sys/dev/ichiic/ig4_reg.h
===================================================================
--- sys/dev/ichiic/ig4_reg.h
+++ sys/dev/ichiic/ig4_reg.h
@@ -109,12 +109,21 @@
#define IG4_REG_DMA_RDLR 0x0090 /* RW DMA Receive Data Level */
#define IG4_REG_SDA_SETUP 0x0094 /* RW SDA Setup */
#define IG4_REG_ENABLE_STATUS 0x009C /* RO Enable Status */
+/* Available at least on Atom SoCs and Haswell mobile. */
#define IG4_REG_COMP_PARAM1 0x00F4 /* RO Component Parameter */
#define IG4_REG_COMP_VER 0x00F8 /* RO Component Version */
+/* Available at least on Atom SoCs */
#define IG4_REG_COMP_TYPE 0x00FC /* RO Probe width/endian? (linux) */
+/* Available on Skylake-U/Y and Kaby Lake-U/Y */
+#define IG4_REG_RESETS_SKL 0x0204 /* RW Reset Register */
+#define IG4_REG_ACTIVE_LTR_VALUE 0x0210 /* RW Active LTR Value */
+#define IG4_REG_IDLE_LTR_VALUE 0x0214 /* RW Idle LTR Value */
+/* Available at least on Atom SoCs */
#define IG4_REG_CLK_PARMS 0x0800 /* RW Clock Parameters */
-#define IG4_REG_RESETS 0x0804 /* RW Reset Register */
+/* Available at least on Atom SoCs and Haswell mobile */
+#define IG4_REG_RESETS_HSW 0x0804 /* RW Reset Register */
#define IG4_REG_GENERAL 0x0808 /* RW General Register */
+/* These LTR config registers are at least available on Haswell mobile. */
#define IG4_REG_SW_LTR_VALUE 0x0810 /* RW SW LTR Value */
#define IG4_REG_AUTO_LTR_VALUE 0x0814 /* RW Auto LTR Value */
@@ -566,9 +575,13 @@
* 10 (reserved)
* 11 I2C host controller is in reset.
*/
-#define IG4_RESETS_ASSERT 0x0003
-#define IG4_RESETS_DEASSERT 0x0000
+#define IG4_RESETS_ASSERT_HSW 0x0003
+#define IG4_RESETS_DEASSERT_HSW 0x0000
+/* Skylake-U/Y and Kaby Lake-U/Y have the reset bits inverted */
+#define IG4_RESETS_DEASSERT_SKL 0x0003
+#define IG4_RESETS_ASSERT_SKL 0x0000
+
/*
* GENERAL - (RW) General Reigster 22.2.38
*
Index: sys/dev/ichiic/ig4_var.h
===================================================================
--- sys/dev/ichiic/ig4_var.h
+++ sys/dev/ichiic/ig4_var.h
@@ -47,6 +47,7 @@
#define IG4_RBUFMASK (IG4_RBUFSIZE - 1)
enum ig4_op { IG4_IDLE, IG4_READ, IG4_WRITE };
+enum ig4_vers { IG4_HASWELL, IG4_ATOM, IG4_SKYLAKE };
struct ig4iic_softc {
device_t dev;
@@ -58,6 +59,7 @@
int intr_rid;
void *intr_handle;
int intr_type;
+ enum ig4_vers version;
enum ig4_op op;
int cmd;
int rnext;

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 22, 7:03 PM (12 h, 25 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24063772
Default Alt Text
D13654.id37103.diff (8 KB)

Event Timeline