svn commit: r273561 - head/sys/arm/freescale/imx

Ian Lepore ian at FreeBSD.org
Thu Oct 23 22:21:23 UTC 2014


Author: ian
Date: Thu Oct 23 22:21:22 2014
New Revision: 273561
URL: https://svnweb.freebsd.org/changeset/base/273561

Log:
  Install a temporary workaround to avoid problems in fdt data with linux's
  workaround for an imx6 chip erratum.  Linux works around the bug with
  changes in fdt data that we can't currently handle, so to enable running
  with standard vendor-supplied fdt data, this watches for an attempt to map
  the gpio1_6 interrupt and remaps it back to the standard ethernet interrupt.
  
  This can be undone when the intrng project is completed and our gpio drivers
  can also be interrupt controllers.

Modified:
  head/sys/arm/freescale/imx/imx6_machdep.c

Modified: head/sys/arm/freescale/imx/imx6_machdep.c
==============================================================================
--- head/sys/arm/freescale/imx/imx6_machdep.c	Thu Oct 23 21:38:54 2014	(r273560)
+++ head/sys/arm/freescale/imx/imx6_machdep.c	Thu Oct 23 22:21:22 2014	(r273561)
@@ -54,8 +54,39 @@ struct fdt_fixup_entry fdt_fixup_table[]
 	{ NULL, NULL }
 };
 
+static uint32_t gpio1_node;
+
+/*
+ * Work around the linux workaround for imx6 erratum 006687, in which some
+ * ethernet interrupts don't go to the GPC and thus won't wake the system from
+ * Wait mode. We don't use Wait mode (which halts the GIC, leaving only GPC
+ * interrupts able to wake the system), so we don't experience the bug at all.
+ * The linux workaround is to reconfigure GPIO1_6 as the ENET interrupt by
+ * writing magic values to an undocumented IOMUX register, then letting the gpio
+ * interrupt driver notify the ethernet driver.  We'll be able to do all that
+ * (even though we don't need to) once the INTRNG project is committed and the
+ * imx_gpio driver becomes an interrupt driver.  Until then, this crazy little
+ * workaround watches for requests to map an interrupt 6 with the interrupt
+ * controller node referring to gpio1, and it substitutes the proper ffec
+ * interrupt number.
+ */
+static int
+imx6_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
+    int *trig, int *pol)
+{
+
+	if (fdt32_to_cpu(intr[0]) == 6 && 
+	    OF_node_from_xref(iparent) == gpio1_node) {
+		*interrupt = 150;
+		*trig = INTR_TRIGGER_CONFORM;
+		*pol  = INTR_POLARITY_CONFORM;
+		return (0);
+	}
+	return (gic_decode_fdt(iparent, intr, interrupt, trig, pol));
+}
+
 fdt_pic_decode_t fdt_pic_table[] = {
-	&gic_decode_fdt,
+	&imx6_decode_fdt,
 	NULL
 };
 
@@ -84,6 +115,9 @@ void
 platform_late_init(void)
 {
 
+	/* Cache the gpio1 node handle for imx6_decode_fdt() workaround code. */
+	gpio1_node = OF_node_from_xref(
+	    OF_finddevice("/soc/aips-bus at 02000000/gpio at 0209c000"));
 }
 
 /*


More information about the svn-src-head mailing list