svn commit: r339029 - stable/11/sys/dev/ichiic

Oleksandr Tymoshenko gonzo at FreeBSD.org
Sun Sep 30 23:14:08 UTC 2018


Author: gonzo
Date: Sun Sep 30 23:14:07 2018
New Revision: 339029
URL: https://svnweb.freebsd.org/changeset/base/339029

Log:
  MFC r336050-r336051, r336142, r336326, r337719
  
  r336050:
  ig4(4): add support for Apollo Lake I2C controllers
  
  Add PCI ids for I2C controllers on Apollo Lake platform. Also convert
  switch/case probe logic into a table.
  
  Reviewed by:	avg
  Differential Revision:	https://reviews.freebsd.org/D16120
  
  r336051:
  ig4(4): Fix Apollo lake entries platform identifier
  
  Identify Apollo Lake controllers as IG4_APL and not as a IG4_SKYLAKE
  
  Reported by:	rpokala@
  
  r336142:
  ig4(4): add devmatch(8) PNP info
  
  Now that we have all devices ids in a table add MODULE_PNP_INFO macro
  to let devmatch autoload module
  
  r336326:
  Remove MODULE_PNP_INFO for ig4(4) driver
  
  ig4(4) does not support suspend/resume but present on the hardware where
  such functionality is critical, like laptops. Remove PNP info to avoid
  breaking suspend/resume on the systems where ig4(4) load is not explicitly
  requested by the user.
  
  PR:             229791
  Reported by:    Ali Abdallah
  
  r337719:
  [ig4] Fix initialization sequence for newer ig4 chips
  
  Newer chips may require assert/deassert after power down for proper
  startup. Check respective flag in DEVIDLE_CTRL and perform operation
  if neccesssary.
  
  PR:		221777
  Submitted by:	marc.priggemeyer at gmail.com
  Obtained from:	DragonFly BSD
  Tested on:	Thinkpad T470

Modified:
  stable/11/sys/dev/ichiic/ig4_iic.c
  stable/11/sys/dev/ichiic/ig4_pci.c
  stable/11/sys/dev/ichiic/ig4_reg.h
  stable/11/sys/dev/ichiic/ig4_var.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/ichiic/ig4_iic.c
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_iic.c	Sun Sep 30 21:54:02 2018	(r339028)
+++ stable/11/sys/dev/ichiic/ig4_iic.c	Sun Sep 30 23:14:07 2018	(r339029)
@@ -525,6 +525,16 @@ ig4iic_attach(ig4iic_softc_t *sc)
 	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_DEVIDLE_CTRL);
+	if (sc->version == IG4_SKYLAKE && (v & IG4_RESTORE_REQUIRED) ) {
+		reg_write(sc, IG4_REG_DEVIDLE_CTRL, IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED);
+		reg_write(sc, IG4_REG_DEVIDLE_CTRL, 0);
+
+		reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL);
+		reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL);
+		DELAY(1000);
+	}
+
 	if (sc->version == IG4_ATOM)
 		v = reg_read(sc, IG4_REG_COMP_TYPE);
 	

Modified: stable/11/sys/dev/ichiic/ig4_pci.c
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_pci.c	Sun Sep 30 21:54:02 2018	(r339028)
+++ stable/11/sys/dev/ichiic/ig4_pci.c	Sun Sep 30 23:14:07 2018	(r339029)
@@ -80,73 +80,62 @@ static int ig4iic_pci_detach(device_t dev);
 #define PCI_CHIP_SKYLAKE_I2C_3		0x9d638086
 #define PCI_CHIP_SKYLAKE_I2C_4		0x9d648086
 #define PCI_CHIP_SKYLAKE_I2C_5		0x9d658086
+#define PCI_CHIP_APL_I2C_0		0x5aac8086
+#define PCI_CHIP_APL_I2C_1		0x5aae8086
+#define PCI_CHIP_APL_I2C_2		0x5ab08086
+#define PCI_CHIP_APL_I2C_3		0x5ab28086
+#define PCI_CHIP_APL_I2C_4		0x5ab48086
+#define PCI_CHIP_APL_I2C_5		0x5ab68086
+#define PCI_CHIP_APL_I2C_6		0x5ab88086
+#define PCI_CHIP_APL_I2C_7		0x5aba8086
 
+struct ig4iic_pci_device {
+	uint32_t	devid;
+	const char	*desc;
+	enum ig4_vers	version;
+};
+
+static struct ig4iic_pci_device ig4iic_pci_devices[] = {
+	{ PCI_CHIP_LYNXPT_LP_I2C_1, "Intel Lynx Point-LP I2C Controller-1", IG4_HASWELL},
+	{ PCI_CHIP_LYNXPT_LP_I2C_2, "Intel Lynx Point-LP I2C Controller-2", IG4_HASWELL},
+	{ PCI_CHIP_BRASWELL_I2C_1, "Intel Braswell Serial I/O I2C Port 1", IG4_ATOM},
+	{ PCI_CHIP_BRASWELL_I2C_2, "Intel Braswell Serial I/O I2C Port 2", IG4_ATOM},
+	{ PCI_CHIP_BRASWELL_I2C_3, "Intel Braswell Serial I/O I2C Port 3", IG4_ATOM},
+	{ PCI_CHIP_BRASWELL_I2C_5, "Intel Braswell Serial I/O I2C Port 5", IG4_ATOM},
+	{ PCI_CHIP_BRASWELL_I2C_6, "Intel Braswell Serial I/O I2C Port 6", IG4_ATOM},
+	{ PCI_CHIP_BRASWELL_I2C_7, "Intel Braswell Serial I/O I2C Port 7", IG4_ATOM},
+	{ PCI_CHIP_SKYLAKE_I2C_0, "Intel Sunrise Point-LP I2C Controller-0", IG4_SKYLAKE},
+	{ PCI_CHIP_SKYLAKE_I2C_1, "Intel Sunrise Point-LP I2C Controller-1", IG4_SKYLAKE},
+	{ PCI_CHIP_SKYLAKE_I2C_2, "Intel Sunrise Point-LP I2C Controller-2", IG4_SKYLAKE},
+	{ PCI_CHIP_SKYLAKE_I2C_3, "Intel Sunrise Point-LP I2C Controller-3", IG4_SKYLAKE},
+	{ PCI_CHIP_SKYLAKE_I2C_4, "Intel Sunrise Point-LP I2C Controller-4", IG4_SKYLAKE},
+	{ PCI_CHIP_SKYLAKE_I2C_5, "Intel Sunrise Point-LP I2C Controller-5", IG4_SKYLAKE},
+	{ PCI_CHIP_APL_I2C_0, "Intel Apollo Lake I2C Controller-0", IG4_APL},
+	{ PCI_CHIP_APL_I2C_1, "Intel Apollo Lake I2C Controller-1", IG4_APL},
+	{ PCI_CHIP_APL_I2C_2, "Intel Apollo Lake I2C Controller-2", IG4_APL},
+	{ PCI_CHIP_APL_I2C_3, "Intel Apollo Lake I2C Controller-3", IG4_APL},
+	{ PCI_CHIP_APL_I2C_4, "Intel Apollo Lake I2C Controller-4", IG4_APL},
+	{ PCI_CHIP_APL_I2C_5, "Intel Apollo Lake I2C Controller-5", IG4_APL},
+	{ PCI_CHIP_APL_I2C_6, "Intel Apollo Lake I2C Controller-6", IG4_APL},
+	{ PCI_CHIP_APL_I2C_7, "Intel Apollo Lake I2C Controller-7", IG4_APL}
+};
+
 static int
 ig4iic_pci_probe(device_t dev)
 {
 	ig4iic_softc_t *sc = device_get_softc(dev);
+	uint32_t devid;
+	int i;
 
-	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);
+	devid = pci_get_devid(dev);
+	for (i = 0; i < nitems(ig4iic_pci_devices); i++) {
+		if (ig4iic_pci_devices[i].devid == devid) {
+			device_set_desc(dev, ig4iic_pci_devices[i].desc);
+			sc->version = ig4iic_pci_devices[i].version;
+			return (BUS_PROBE_DEFAULT);
+		}
 	}
-	return (BUS_PROBE_DEFAULT);
+	return (ENXIO);
 }
 
 static int
@@ -239,3 +228,7 @@ DRIVER_MODULE_ORDERED(ig4iic_pci, pci, ig4iic_pci_driv
 MODULE_DEPEND(ig4iic_pci, pci, 1, 1, 1);
 MODULE_DEPEND(ig4iic_pci, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
 MODULE_VERSION(ig4iic_pci, 1);
+/*
+ * Loading this module breaks suspend/resume on laptops
+ * Do not add MODULE_PNP_INFO until it's impleneted
+ */ 

Modified: stable/11/sys/dev/ichiic/ig4_reg.h
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_reg.h	Sun Sep 30 21:54:02 2018	(r339028)
+++ stable/11/sys/dev/ichiic/ig4_reg.h	Sun Sep 30 23:14:07 2018	(r339029)
@@ -78,6 +78,7 @@
 
 #define IG4_REG_CTL		0x0000	/* RW	Control Register */
 #define IG4_REG_TAR_ADD		0x0004	/* RW	Target Address */
+#define IG4_REG_HS_MADDR	0x000C	/* RW	High Speed Master Mode Code Address*/
 #define IG4_REG_DATA_CMD	0x0010	/* RW	Data Buffer and Command */
 #define IG4_REG_SS_SCL_HCNT	0x0014	/* RW	Std Speed clock High Count */
 #define IG4_REG_SS_SCL_LCNT	0x0018	/* RW	Std Speed clock Low Count */
@@ -92,7 +93,9 @@
 #define IG4_REG_CLR_RX_UNDER	0x0044	/* RO	Clear RX_Under Interrupt */
 #define IG4_REG_CLR_RX_OVER	0x0048	/* RO	Clear RX_Over Interrupt */
 #define IG4_REG_CLR_TX_OVER	0x004C	/* RO	Clear TX_Over Interrupt */
+#define IG4_REG_CLR_RD_REQ	0x0050	/* RO	Clear RD_Req Interrupt */
 #define IG4_REG_CLR_TX_ABORT	0x0054	/* RO	Clear TX_Abort Interrupt */
+#define IG4_REG_CLR_RX_DONE	0x0058	/* RO	Clear RX_Done Interrupt */
 #define IG4_REG_CLR_ACTIVITY	0x005C	/* RO	Clear Activity Interrupt */
 #define IG4_REG_CLR_STOP_DET	0x0060	/* RO	Clear STOP Detection Int */
 #define IG4_REG_CLR_START_DET	0x0064	/* RO	Clear START Detection Int */
@@ -108,6 +111,7 @@
 #define IG4_REG_DMA_TDLR	0x008C	/* RW	DMA Transmit Data Level */
 #define IG4_REG_DMA_RDLR	0x0090	/* RW	DMA Receive Data Level */
 #define IG4_REG_SDA_SETUP	0x0094	/* RW	SDA Setup */
+#define IG4_REG_ACK_GENERAL_CALL 0x0098	/* RW	I2C ACK General Call */
 #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 */
@@ -118,6 +122,9 @@
 #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 */
+#define IG4_REG_TX_ACK_COUNT	0x0218	/* RO	TX ACK Count */
+#define IG4_REG_RX_BYTE_COUNT	0x021C	/* RO	RX ACK Count */
+#define IG4_REG_DEVIDLE_CTRL	0x024C	/* RW	Device Control */
 /* Available at least on Atom SoCs */
 #define IG4_REG_CLK_PARMS	0x0800	/* RW	Clock Parameters */
 /* Available at least on Atom SoCs and Haswell mobile */
@@ -581,6 +588,17 @@
 /* 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
+
+/* Newer versions of the I2C controller allow to check whether
+ * the above ASSERT/DEASSERT is necessary by querying the DEVIDLE_CONTROL
+ * register.
+ * 
+ * the RESTORE_REQUIRED bit can be cleared by writing 1
+ * the DEVICE_IDLE status can be set to put the controller in an idle state
+ *
+ */
+#define IG4_RESTORE_REQUIRED	0x0008
+#define IG4_DEVICE_IDLE		0x0004
 
 /*
  * GENERAL - (RW) General Reigster				22.2.38

Modified: stable/11/sys/dev/ichiic/ig4_var.h
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_var.h	Sun Sep 30 21:54:02 2018	(r339028)
+++ stable/11/sys/dev/ichiic/ig4_var.h	Sun Sep 30 23:14:07 2018	(r339029)
@@ -47,7 +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 };
+enum ig4_vers { IG4_HASWELL, IG4_ATOM, IG4_SKYLAKE, IG4_APL };
 
 struct ig4iic_softc {
 	device_t	dev;


More information about the svn-src-all mailing list