Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Nov 2019 21:16:06 +0000 (UTC)
From:      Vladimir Kondratyev <wulf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354320 - head/sys/dev/ichiic
Message-ID:  <201911032116.xA3LG6QB078013@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: wulf
Date: Sun Nov  3 21:16:06 2019
New Revision: 354320
URL: https://svnweb.freebsd.org/changeset/base/354320

Log:
  [ig4] Add support for CannonLake controllers
  
  They are clocked at 216MHz rate, much higher than previous models.
  
  PR:		240485
  Submitted by:	Neel Chauhan <neel@neelc.org>

Modified:
  head/sys/dev/ichiic/ig4_iic.c
  head/sys/dev/ichiic/ig4_pci.c
  head/sys/dev/ichiic/ig4_reg.h
  head/sys/dev/ichiic/ig4_var.h

Modified: head/sys/dev/ichiic/ig4_iic.c
==============================================================================
--- head/sys/dev/ichiic/ig4_iic.c	Sun Nov  3 21:15:01 2019	(r354319)
+++ head/sys/dev/ichiic/ig4_iic.c	Sun Nov  3 21:16:06 2019	(r354320)
@@ -115,6 +115,10 @@ static const struct ig4_hw ig4iic_hw[] = {
 		.scl_fall_time = 208,
 		.sda_hold_time = 207,
 	},
+	[IG4_CANNONLAKE] = {
+		.ic_clock_rate = 216,
+		.sda_hold_time = 230,
+	},
 };
 
 static int ig4iic_set_config(ig4iic_softc_t *sc, bool reset);
@@ -912,7 +916,7 @@ ig4iic_set_config(ig4iic_softc_t *sc, bool reset)
 	uint32_t v;
 
 	v = reg_read(sc, IG4_REG_DEVIDLE_CTRL);
-	if (sc->version == IG4_SKYLAKE && (v & IG4_RESTORE_REQUIRED) ) {
+	if (IG4_HAS_ADDREGS(sc->version) && (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);
 		pause("i2crst", 1);
@@ -922,7 +926,7 @@ ig4iic_set_config(ig4iic_softc_t *sc, bool reset)
 	if ((sc->version == IG4_HASWELL || sc->version == IG4_ATOM) && reset) {
 		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 && reset) {
+	} else if (IG4_HAS_ADDREGS(sc->version) && reset) {
 		reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL);
 		reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL);
 	}
@@ -948,7 +952,7 @@ ig4iic_set_config(ig4iic_softc_t *sc, bool reset)
 	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) {
+	} else if (IG4_HAS_ADDREGS(sc->version)) {
 		v = reg_read(sc, IG4_REG_ACTIVE_LTR_VALUE);
 		v = reg_read(sc, IG4_REG_IDLE_LTR_VALUE);
 	}
@@ -1011,7 +1015,7 @@ ig4iic_attach(ig4iic_softc_t *sc)
 
 	ig4iic_get_config(sc);
 
-	error = ig4iic_set_config(sc, sc->version == IG4_SKYLAKE);
+	error = ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version));
 	if (error)
 		goto done;
 
@@ -1089,7 +1093,7 @@ ig4iic_suspend(ig4iic_softc_t *sc)
 
 	sx_xlock(&sc->call_lock);
 	set_controller(sc, 0);
-	if (sc->version == IG4_SKYLAKE) {
+	if (IG4_HAS_ADDREGS(sc->version)) {
 		/*
 		 * Place the device in the idle state, just to be safe
 		 */
@@ -1111,7 +1115,7 @@ int ig4iic_resume(ig4iic_softc_t *sc)
 	int error;
 
 	sx_xlock(&sc->call_lock);
-	if (ig4iic_set_config(sc, sc->version == IG4_SKYLAKE))
+	if (ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version)))
 		device_printf(sc->dev, "controller error during resume\n");
 	sx_xunlock(&sc->call_lock);
 
@@ -1183,7 +1187,7 @@ ig4iic_dump(ig4iic_softc_t *sc)
 	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) {
+	} else if (IG4_HAS_ADDREGS(sc->version)) {
 		REGDUMP(sc, IG4_REG_ACTIVE_LTR_VALUE);
 		REGDUMP(sc, IG4_REG_IDLE_LTR_VALUE);
 	}

Modified: head/sys/dev/ichiic/ig4_pci.c
==============================================================================
--- head/sys/dev/ichiic/ig4_pci.c	Sun Nov  3 21:15:01 2019	(r354319)
+++ head/sys/dev/ichiic/ig4_pci.c	Sun Nov  3 21:16:06 2019	(r354320)
@@ -90,6 +90,16 @@ static int ig4iic_pci_detach(device_t dev);
 #define PCI_CHIP_APL_I2C_5		0x5ab68086
 #define PCI_CHIP_APL_I2C_6		0x5ab88086
 #define PCI_CHIP_APL_I2C_7		0x5aba8086
+#define PCI_CHIP_CANNONLAKE_LP_I2C_0	0x9dc58086
+#define PCI_CHIP_CANNONLAKE_LP_I2C_1	0x9dc68086
+#define PCI_CHIP_CANNONLAKE_LP_I2C_2	0x9de88086
+#define PCI_CHIP_CANNONLAKE_LP_I2C_3	0x9de98086
+#define PCI_CHIP_CANNONLAKE_LP_I2C_4	0x9dea8086
+#define PCI_CHIP_CANNONLAKE_LP_I2C_5	0x9deb8086
+#define PCI_CHIP_CANNONLAKE_H_I2C_0	0xa3688086
+#define PCI_CHIP_CANNONLAKE_H_I2C_1	0xa3698086
+#define PCI_CHIP_CANNONLAKE_H_I2C_2	0xa36a8086
+#define PCI_CHIP_CANNONLAKE_H_I2C_3	0xa36b8086
 
 struct ig4iic_pci_device {
 	uint32_t	devid;
@@ -121,7 +131,17 @@ static struct ig4iic_pci_device ig4iic_pci_devices[] =
 	{ 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}
+	{ PCI_CHIP_APL_I2C_7, "Intel Apollo Lake I2C Controller-7", IG4_APL},
+	{ PCI_CHIP_CANNONLAKE_LP_I2C_0, "Intel Cannon Lake-LP I2C Controller-0", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_LP_I2C_1, "Intel Cannon Lake-LP I2C Controller-1", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_LP_I2C_2, "Intel Cannon Lake-LP I2C Controller-2", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_LP_I2C_3, "Intel Cannon Lake-LP I2C Controller-3", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_LP_I2C_4, "Intel Cannon Lake-LP I2C Controller-4", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_LP_I2C_5, "Intel Cannon Lake-LP I2C Controller-5", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_H_I2C_0, "Intel Cannon Lake-H I2C Controller-0", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_H_I2C_1, "Intel Cannon Lake-H I2C Controller-1", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_H_I2C_2, "Intel Cannon Lake-H I2C Controller-2", IG4_CANNONLAKE},
+	{ PCI_CHIP_CANNONLAKE_H_I2C_3, "Intel Cannon Lake-H I2C Controller-3", IG4_CANNONLAKE},
 };
 
 static int

Modified: head/sys/dev/ichiic/ig4_reg.h
==============================================================================
--- head/sys/dev/ichiic/ig4_reg.h	Sun Nov  3 21:15:01 2019	(r354319)
+++ head/sys/dev/ichiic/ig4_reg.h	Sun Nov  3 21:16:06 2019	(r354320)
@@ -117,7 +117,7 @@
 #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 */
+/* 0x200-0x2FF - Additional registers available on Skylake-U/Y and others */
 #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 */

Modified: head/sys/dev/ichiic/ig4_var.h
==============================================================================
--- head/sys/dev/ichiic/ig4_var.h	Sun Nov  3 21:15:01 2019	(r354319)
+++ head/sys/dev/ichiic/ig4_var.h	Sun Nov  3 21:16:06 2019	(r354320)
@@ -43,7 +43,10 @@
 #include "pci_if.h"
 #include "iicbus_if.h"
 
-enum ig4_vers { IG4_HASWELL, IG4_ATOM, IG4_SKYLAKE, IG4_APL };
+enum ig4_vers { IG4_HASWELL, IG4_ATOM, IG4_SKYLAKE, IG4_APL, IG4_CANNONLAKE };
+/* Controller has additional registers */
+#define	IG4_HAS_ADDREGS(vers)	((vers) == IG4_SKYLAKE || \
+	(vers) == IG4_CANNONLAKE)
 
 struct ig4_hw {
 	uint32_t	ic_clock_rate;	/* MHz */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911032116.xA3LG6QB078013>