Skip to contentSkip to conversation

PCI irq mapping fixes and cleanups

PATCH Superseded Lucas Stach 7 participants 30 messages Feb 28, 2014 – Mar 11, 2014

Subsystems (10)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover PCI irq mapping fixes and cleanups

This series cleans up the PCI irq mapping for all the ARM PCI host drivers, so they handle it in the way defined in the common PCI bindings.

Testing appreciated.

Lucas Stach (7):
ARM: dts: tegra: add PCIe interrupt mapping properties
PCI: tegra: use new OF interrupt mapping when possible
PCI: rcar: use new OF interrupt mapping when possible
ARM: dts: exynos5440: fix PCIe interrupt mapping
ARM: dts: imx6: add PCIe interrupt mapping properties
PCI: designware: use new OF interrupt mapping when possible
PCI: designware: split samsung and fsl bindings

 .../devicetree/bindings/pci/designware-pcie.txt    | 69 +--------------------
 .../devicetree/bindings/pci/fsl,imx6q-pcie.txt     | 48 +++++++++++++++
 .../bindings/pci/nvidia,tegra20-pcie.txt           |  8 +++
 .../bindings/pci/samsung,exynos5440-pcie.txt       | 70 ++++++++++++++++++++++
 arch/arm/boot/dts/exynos5440.dtsi                  |  4 +-
 arch/arm/boot/dts/imx6qdl.dtsi                     | 11 ++++
 arch/arm/boot/dts/tegra20.dtsi                     |  4 ++
 arch/arm/boot/dts/tegra30.dtsi                     |  4 ++
 drivers/pci/host/pci-rcar-gen2.c                   |  8 ++-
 drivers/pci/host/pci-tegra.c                       |  7 ++-
 drivers/pci/host/pcie-designware.c                 |  8 ++-
 11 files changed, 168 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
Signature · 1 line
1.8.5.3
#1 lore raw

PATCH 1/7 ARM: dts: tegra: add PCIe interrupt mapping properties

Those are defined by the common PCI binding.

---
 Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 8 ++++++++
 arch/arm/boot/dts/tegra20.dtsi                                | 4 ++++
 arch/arm/boot/dts/tegra30.dtsi                                | 4 ++++
 3 files changed, 16 insertions(+)
Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt +8 -0
index 24cee06915c9..c300391e8d3e 100644
@@ -42,6 +42,10 @@ Required properties:
     - 0xc2000000: prefetchable memory region
   Please refer to the standard PCI bus binding document for a more detailed
   explanation.
+- #interrupt-cells: Size representation for interrupts (must be 1)
+- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties
+  Please refer to the standard PCI bus binding document for a more detailed
+  explanation.
 - clocks: Must contain an entry for each entry in clock-names.
   See ../clocks/clock-bindings.txt for details.
 - clock-names: Must include the following entries:
@@ -86,6 +90,10 @@ SoC DTSI:
 		              0 99 0x04>; /* MSI interrupt */
 		interrupt-names = "intr", "msi";
 
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
 		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
arch/arm/boot/dts/tegra20.dtsi +4 -0
index 480ecda3416b..52ef2cf0b142 100644
@@ -552,6 +552,10 @@
 			      GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
 		interrupt-names = "intr", "msi";
 
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
 		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
arch/arm/boot/dts/tegra30.dtsi +4 -0
index ed8e7700b46d..e5ab7adbc28a 100644
@@ -28,6 +28,10 @@
 			      GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
 		interrupt-names = "intr", "msi";
 
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
 		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
Signature · 1 line
1.8.5.3
#2 lore raw

PATCH 1/7 ARM: dts: tegra: add PCIe interrupt mapping properties

Quoted 1 line · Lucas Stach

Those are defined by the common PCI binding.

I have no reason to object to the two Tegra patches, but I'll wait for Thierry to take a closer look.

I expect once he does, I would apply patch 1/7 through the Tegra tree, and Bjorn would take patch 2/7 through the PCI tree. Does that make sense?

#3 lore raw

PATCH 2/7 PCI: tegra: use new OF interrupt mapping when possible

In reply to Lucas Stach

This is the recommended method of doing the IRQ
mapping. For old devicetrees we fall back to the
previous practice.

---
 drivers/pci/host/pci-tegra.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/pci/host/pci-tegra.c +6 -1
index 330f7e3a32dd..083cf37ca047 100644
@@ -639,10 +639,15 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
+	int irq;
 
 	tegra_cpuidle_pcie_irqs_in_use();
 
-	return pcie->irq;
+	irq = of_irq_parse_and_map_pci(pdev, slot, pin);
+	if (!irq)
+		irq = pcie->irq;
+
+	return irq;
 }
 
 static void tegra_pcie_add_bus(struct pci_bus *bus)
Signature · 1 line
1.8.5.3
#4 lore raw

PATCH 3/7 PCI: rcar: use new OF interrupt mapping when possible

In reply to Lucas Stach

This is the recommended method of doing the IRQ mapping. Still fall back to the old method in order to not break the just submitted board files.

---
 drivers/pci/host/pci-rcar-gen2.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/pci/host/pci-rcar-gen2.c +7 -1
index ceec147baec3..3aa0c6311a42 100644
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -160,8 +161,13 @@ static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	struct pci_sys_data *sys = dev->bus->sysdata;
 	struct rcar_pci_priv *priv = sys->private_data;
+	int irq;
+
+	irq = of_irq_parse_and_map_pci(dev, slot, pin);
+	if (!irq)
+		irq = priv->irq;
 
-	return priv->irq;
+	return irq;
 }
 
 /* PCI host controller setup */
Signature · 1 line
1.8.5.3
#5 lore raw

PATCH 4/7 ARM: dts: exynos5440: fix PCIe interrupt mapping

In reply to Lucas Stach

So it actually works.

---
 arch/arm/boot/dts/exynos5440.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/exynos5440.dtsi +2 -2
index 02a0a1226cef..65d425d9ec27 100644
@@ -274,7 +274,7 @@
 			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
 		num-lanes = <4>;
 		status = "disabled";
 	};
@@ -295,7 +295,7 @@
 			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 56>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		num-lanes = <4>;
 		status = "disabled";
 	};
Signature · 1 line
1.8.5.3
#6 lore raw

PATCH 4/7 ARM: dts: exynos5440: fix PCIe interrupt mapping

Quoted 13 lines · Lucas Stach

So it actually works.

---
 arch/arm/boot/dts/exynos5440.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/exynos5440.dtsi +0 -0
index 02a0a1226cef..65d425d9ec27 100644

arch/arm/boot/dts/exynos5440.dtsi line 277

Quoted 5 lines
arch/arm/boot/dts/exynos5440.dtsi +1 -1
@@ -274,7 +274,7 @@
 			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;

It makes build errors as below:

DTC arch/arm/boot/dts/exynos5440-ssdk5440.dtb
Error: arch/arm/boot/dts/exynos5440.dtsi:289.33-34 syntax error FATAL ERROR: Unable to parse input tree
make[1]: *** [arch/arm/boot/dts/exynos5440-ssdk5440.dtb] Error 1
make: *** [exynos5440-ssdk5440.dtb] Error 2

Would you fix it?

Best regards,
Jingoo Han

Quoted 14 lines
arch/arm/boot/dts/exynos5440.dtsi +1 -2
 		num-lanes = <4>;
 		status = "disabled";
 	};
@@ -295,7 +295,7 @@
 			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 56>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		num-lanes = <4>;
 		status = "disabled";
 	};
--

1.8.5.3

#7 lore raw

PATCH 4/7 ARM: dts: exynos5440: fix PCIe interrupt mapping

Quoted 22 lines · Jingoo Han
Quoted 13 lines · Lucas Stach

So it actually works.

---
 arch/arm/boot/dts/exynos5440.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/exynos5440.dtsi +0 -0
index 02a0a1226cef..65d425d9ec27 100644

arch/arm/boot/dts/exynos5440.dtsi line 277

Quoted 5 lines
arch/arm/boot/dts/exynos5440.dtsi +1 -1
@@ -274,7 +274,7 @@
 			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;

It makes build errors as below:

Quoted 7 lines

DTC arch/arm/boot/dts/exynos5440-ssdk5440.dtb
Error: arch/arm/boot/dts/exynos5440.dtsi:289.33-34 syntax error FATAL ERROR: Unable to parse input tree
make[1]: *** [arch/arm/boot/dts/exynos5440-ssdk5440.dtb] Error 1
make: *** [exynos5440-ssdk5440.dtb] Error 2

Would you fix it?

I fixed build errors after including 'arm-gic.h' as below:

arch/arm/boot/dts/exynos5440.dtsi +2 -0
@@ -9,6 +9,8 @@
  * published by the Free Software Foundation.
 */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
 #include "skeleton.dtsi"
 

Would you confirm this?

Best regards,
Jingoo Han

Quoted 15 lines
Quoted 15 lines
arch/arm/boot/dts/exynos5440.dtsi +1 -2
 		num-lanes = <4>;
 		status = "disabled";
 	};
@@ -295,7 +295,7 @@
 			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 56>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		num-lanes = <4>;
 		status = "disabled";
 	};
--

1.8.5.3

#8 lore raw

PATCH 4/7 ARM: dts: exynos5440: fix PCIe interrupt mapping

Am Montag, den 03.03.2014, 16:53 +0900 schrieb Jingoo Han:

Quoted 43 lines · Jingoo Han
Quoted 22 lines · Lucas Stach
Quoted 13 lines

So it actually works.

---
 arch/arm/boot/dts/exynos5440.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/exynos5440.dtsi +0 -0
index 02a0a1226cef..65d425d9ec27 100644

arch/arm/boot/dts/exynos5440.dtsi line 277

Quoted 5 lines
arch/arm/boot/dts/exynos5440.dtsi +1 -1
@@ -274,7 +274,7 @@
 			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;

It makes build errors as below:

Quoted 7 lines

DTC arch/arm/boot/dts/exynos5440-ssdk5440.dtb
Error: arch/arm/boot/dts/exynos5440.dtsi:289.33-34 syntax error FATAL ERROR: Unable to parse input tree
make[1]: *** [arch/arm/boot/dts/exynos5440-ssdk5440.dtb] Error 1
make: *** [exynos5440-ssdk5440.dtb] Error 2

Would you fix it?

I fixed build errors after including 'arm-gic.h' as below:

arch/arm/boot/dts/exynos5440.dtsi +2 -0
@@ -9,6 +9,8 @@
  * published by the Free Software Foundation.
 */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
 #include "skeleton.dtsi"
 
Quoted 1 line

Would you confirm this?

That's the right fix, I'll include this (together with the other feedback I received) in v2 of the series.

Regards,
Lucas

Signature · 4 lines
Pengutronix e.K.                           | Lucas Stach                 |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-5076 |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
#9 lore raw

PATCH 5/7 ARM: dts: imx6: add PCIe interrupt mapping properties

In reply to Lucas Stach

As defined by the common PCI bindings.

---
 arch/arm/boot/dts/imx6qdl.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/arm/boot/dts/imx6qdl.dtsi +11 -0
index fb28b2ecb1db..db3339e7d3a2 100644
@@ -10,6 +10,8 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
 #include "skeleton.dtsi"
 
 / {
@@ -126,7 +128,16 @@
 				  0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
 				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
+
 			interrupts = <0 123 0x04>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+
 			clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
 			clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
 			status = "disabled";
Signature · 1 line
1.8.5.3
#10 lore raw

PATCH 5/7 ARM: dts: imx6: add PCIe interrupt mapping properties

Quoted 21 lines · Lucas Stach

As defined by the common PCI bindings.

---
 arch/arm/boot/dts/imx6qdl.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/arm/boot/dts/imx6qdl.dtsi +2 -0
index fb28b2ecb1db..db3339e7d3a2 100644
@@ -10,6 +10,8 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
 #include "skeleton.dtsi"
 
 / {

arch/arm/boot/dts/imx6qdl.dtsi line 131

Quoted 4 lines
arch/arm/boot/dts/imx6qdl.dtsi +1 -0
@@ -126,7 +128,16 @@
 				  0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
 				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
+

Please drop these blank lines between properties.

Shawn

Quoted 15 lines
arch/arm/boot/dts/imx6qdl.dtsi +8 -0
 			interrupts = <0 123 0x04>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+
 			clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
 			clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
 			status = "disabled";
Signature · 1 line
1.8.5.3
#11 lore raw

PATCH 6/7 PCI: designware: use new OF interrupt mapping when possible

In reply to Lucas Stach

This is the recommended method of doing the IRQ
mapping. For old devicetrees we fall back to the
previous practice.

---
 drivers/pci/host/pcie-designware.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/pci/host/pcie-designware.c +7 -1
index 17ce88f79d2b..3e0c2af11528 100644
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/pci_regs.h>
 #include <linux/types.h>
@@ -738,8 +739,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
+	int irq;
 
-	return pp->irq;
+	irq = of_irq_parse_and_map_pci(dev, slot, pin);
+	if (!irq)
+		irq = pp->irq;
+
+	return irq;
 }
 
 static void dw_pcie_add_bus(struct pci_bus *bus)
Signature · 1 line
1.8.5.3
#12 lore raw

PATCH 6/7 PCI: designware: use new OF interrupt mapping when possible

Quoted 37 lines · Lucas Stach

This is the recommended method of doing the IRQ
mapping. For old devicetrees we fall back to the
previous practice.

---
 drivers/pci/host/pcie-designware.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/pci/host/pcie-designware.c +7 -2
index 17ce88f79d2b..3e0c2af11528 100644
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/pci_regs.h>
 #include <linux/types.h>
@@ -738,8 +739,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
+       int irq;
 
-       return pp->irq;
+       irq = of_irq_parse_and_map_pci(dev, slot, pin);
+       if (!irq)
+               irq = pp->irq;
+
+       return irq;
 }
 
 static void dw_pcie_add_bus(struct pci_bus *bus)
--
Quoted 2 lines

1.8.5.3

Lucas,

Please add the following which are required (at least the second one is required) for of_irq_parse_and_map_pci() to work properly for P2P bridges. With the changes below as well as my of/irq fix
(https://patchwork.kernel.org/patch/3762591/) I can now use devices behind a properly connected P2P bridge.

+++ b/drivers/pci/host/pcie-designware.c
@@ -493,7 +493,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)

        dw_pci.nr_controllers = 1;
        dw_pci.private_data = (void **)&pp;

- pci_common_init(&dw_pci);

+       pci_common_init_dev(pp->dev, &dw_pci);
        pci_assign_unassigned_resources();
 #ifdef CONFIG_PCI_DOMAINS
        dw_pci.domain++;

@@ -726,7 +726,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_s

        if (pp) {
                pp->root_bus_nr = sys->busnr;
-               bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+               bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
                                        sys, &sys->resources);
        } else {
                bus = NULL;

Thanks,

Tim

#13 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

In reply to Lucas Stach

The glue around the core designware IP is
significantly different between the Exynos and
i.MX, which is reflected in the DT bindings.

Note that this patch doesn't change any bindings, but just alters the documentation to match reality of deployed DTs and kernels.

---
 .../devicetree/bindings/pci/designware-pcie.txt    | 69 +--------------------
 .../devicetree/bindings/pci/fsl,imx6q-pcie.txt     | 48 +++++++++++++++
 .../bindings/pci/samsung,exynos5440-pcie.txt       | 70 ++++++++++++++++++++++
 3 files changed, 119 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
Documentation/devicetree/bindings/pci/designware-pcie.txt +1 -68
index d6fae13ff062..8274c80fe874 100644
@@ -1,15 +1,7 @@
 * Synopsys Designware PCIe interface
 
 Required properties:
-- compatible: should contain "snps,dw-pcie" to identify the
-	core, plus an identifier for the specific instance, such
-	as "samsung,exynos5440-pcie" or "fsl,imx6q-pcie".
-- reg: base addresses and lengths of the pcie controller,
-	the phy controller, additional register for the phy controller.
-- interrupts: interrupt values for level interrupt,
-	pulse interrupt, special interrupt.
-- clocks: from common clock binding: handle to pci clock.
-- clock-names: from common clock binding: should be "pcie" and "pcie_bus".
+- compatible: should contain "snps,dw-pcie" to identify the core.
 - #address-cells: set to <3>
 - #size-cells: set to <2>
 - device_type: set to "pci"
@@ -22,62 +14,3 @@ Required properties:
 
 Optional properties:
 - reset-gpio: gpio pin number of power good signal
-
-Optional properties for fsl,imx6q-pcie
-- power-on-gpio: gpio pin number of power-enable signal
-- wake-up-gpio: gpio pin number of incoming wakeup signal
-- disable-gpio: gpio pin number of outgoing rfkill/endpoint disable signal
-
-Example:
-
-SoC specific DT Entry:
-
-	pcie at 290000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x290000 0x1000
-			0x270000 0x1000
-			0x271000 0x40>;
-		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
-		clocks = <&clock 28>, <&clock 27>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
-			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
-		num-lanes = <4>;
-	};
-
-	pcie at 2a0000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x2a0000 0x1000
-			0x272000 0x1000
-			0x271040 0x40>;
-		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
-		clocks = <&clock 29>, <&clock 27>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
-			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 56>;
-		num-lanes = <4>;
-	};
-
-Board specific DT Entry:
-
-	pcie at 290000 {
-		reset-gpio = <&pin_ctrl 5 0>;
-	};
-
-	pcie at 2a0000 {
-		reset-gpio = <&pin_ctrl 22 0>;
-	};
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +48 -0

48 lines not on this page · raw message

Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt new file +70 -0

70 lines not on this page · raw message

Signature · 1 line
1.8.5.3
#14 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt line 10

Quoted 5 lines · Lucas Stach
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +5 -0
+Required properties:
+- compatible: "fsl,imx6q-pcie"
+- reg: base addresse and length of the pcie controller
+- interrupts: First entry must contain interrupt handle for controller
+  INTA output.

I think this should be documented as "optional" and only for backwards compatibility with old kernels.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt line 17

Quoted 7 lines

+- clocks: Must contain an entry for each entry in clock-names.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +6 -0
+       See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries: 
+       - "pcie_ref_125m"
+       - "sata_ref_100m"
+       - "lvds_gate"
+       - "pcie_axi"

I don't understand why you have completely different clocks here from the exynos documentation. The clock names should really be the same. Also, why do you have a "sata_ref_100m" clock? Is this just driving a device that happens to be on-board for a specific machine? Same for the "lvds_gate".

Arnd

#15 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

Am Freitag, den 28.02.2014, 21:03 +0100 schrieb Arnd Bergmann:

Quoted 18 lines · Lucas Stach

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt line 10

Quoted 5 lines
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +5 -0
+Required properties:
+- compatible: "fsl,imx6q-pcie"
+- reg: base addresse and length of the pcie controller
+- interrupts: First entry must contain interrupt handle for controller
+  INTA output.

I think this should be documented as "optional" and only for backwards compatibility with old kernels.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt line 17

Quoted 7 lines

+- clocks: Must contain an entry for each entry in clock-names.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +6 -0
+       See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries: 
+       - "pcie_ref_125m"
+       - "sata_ref_100m"
+       - "lvds_gate"
+       - "pcie_axi"
Quoted 6 lines

I don't understand why you have completely different clocks here from the exynos documentation. The clock names should really be the same. Also, why do you have a "sata_ref_100m" clock? Is this just driving a device that happens to be on-board for a specific machine? Same for the "lvds_gate".

Right, we should be able to reuse the clock names. Though I'm not really sure how the Samsung clocks maps to those used on i.MX, as the names are a bit generic. Maybe someone from Samsung could shed a bit of light on this.

On i.MX6 the clock names (which I have to agree are pretty bad) map as follows:
pcie_axi: host controller main register/bus access clock
pcie_ref_125m: pcie phy reference clock

sata_ref_100m: pcie bus 100MHz reference clock
lvds_gate: bad abstraction. Decides if the reference clock is sourced internal (i.e. the 100MHz ref clock above) or from an SoC external source. We should really find a better way of representing this in the clock tree.

Regards,
Lucas

Signature · 4 lines
Pengutronix e.K.                           | Lucas Stach                 |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-5076 |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
#16 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

Quoted 11 lines · Lucas Stach

Right, we should be able to reuse the clock names. Though I'm not really sure how the Samsung clocks maps to those used on i.MX, as the names are a bit generic. Maybe someone from Samsung could shed a bit of light on this.

On i.MX6 the clock names (which I have to agree are pretty bad) map as follows:
pcie_axi: host controller main register/bus access clock
pcie_ref_125m: pcie phy reference clock

sata_ref_100m: pcie bus 100MHz reference clock

That doesn't explain why it's called "sata_ref_100m".

Quoted 4 lines

lvds_gate: bad abstraction. Decides if the reference clock is sourced internal (i.e. the 100MHz ref clock above) or from an SoC external source. We should really find a better way of representing this in the clock tree.

I don't understand this description at all. Can you try to explain that with different words?

Arnd

#17 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

Am Dienstag, den 04.03.2014, 15:53 +0100 schrieb Arnd Bergmann:

Quoted 6 lines · Lucas Stach
Quoted 5 lines

Right, we should be able to reuse the clock names. Though I'm not really sure how the Samsung clocks maps to those used on i.MX, as the names are a bit generic. Maybe someone from Samsung could shed a bit of light on this.

Quoted 9 lines
Quoted 6 lines

On i.MX6 the clock names (which I have to agree are pretty bad) map as follows:
pcie_axi: host controller main register/bus access clock
pcie_ref_125m: pcie phy reference clock

sata_ref_100m: pcie bus 100MHz reference clock

That doesn't explain why it's called "sata_ref_100m".

I agree this is bad naming. It's called this way because someone decided to name it like the internal clock it is sourced from on most boards. This really should be pcie_ref, or something. I suspect this corresponds to the pcie_bus clock in the Exynos binding in which case we should just name it this way.

Quoted 8 lines
Quoted 4 lines

lvds_gate: bad abstraction. Decides if the reference clock is sourced internal (i.e. the 100MHz ref clock above) or from an SoC external source. We should really find a better way of representing this in the clock tree.

I don't understand this description at all. Can you try to explain that with different words?

On i.MX6 the PCIe reference clock is routed through a generic clock pad, which can be configured either as input or output. When the i.MX is the PCI master we source the clock from sata_ref_100m and configure this pad as clock output.
Somebody decided to abstract the input/output switch as a gate, which is arguably wrong, this should be a mux deciding between internal or external clock source.

The PCIe host driver should really only need the clk pad clock, activation of the sata_ref_100m clock should be handled through parent<->child relationship of those clocks in the clock tree, which isn't properly handled right now. I'll try to fix this up, but it won't be backward compatible in any way.

Regards,
Lucas

Signature · 4 lines
Pengutronix e.K.                           | Lucas Stach                 |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-5076 |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
#18 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

Quoted 7 lines · Lucas Stach
Quoted 7 lines
Quoted 6 lines

On i.MX6 the clock names (which I have to agree are pretty bad) map as follows:
pcie_axi: host controller main register/bus access clock
pcie_ref_125m: pcie phy reference clock

sata_ref_100m: pcie bus 100MHz reference clock

Quoted 7 lines
Quoted 2 lines

That doesn't explain why it's called "sata_ref_100m".

I agree this is bad naming. It's called this way because someone decided to name it like the internal clock it is sourced from on most boards. This really should be pcie_ref, or something. I suspect this corresponds to the pcie_bus clock in the Exynos binding in which case we should just name it this way.

Ok, so Exynos is missing one of the other clocks then? Or is the pcie_ref_125m clock something that should actually be listed under the node of the PHY?

Quoted 16 lines
Quoted 8 lines
Quoted 4 lines

lvds_gate: bad abstraction. Decides if the reference clock is sourced internal (i.e. the 100MHz ref clock above) or from an SoC external source. We should really find a better way of representing this in the clock tree.

I don't understand this description at all. Can you try to explain that with different words?

On i.MX6 the PCIe reference clock is routed through a generic clock pad, which can be configured either as input or output. When the i.MX is the PCI master we source the clock from sata_ref_100m and configure this pad as clock output.
Somebody decided to abstract the input/output switch as a gate, which is arguably wrong, this should be a mux deciding between internal or external clock source.

Quoted 5 lines

The PCIe host driver should really only need the clk pad clock, activation of the sata_ref_100m clock should be handled through parent<->child relationship of those clocks in the clock tree, which isn't properly handled right now. I'll try to fix this up, but it won't be backward compatible in any way.

Is it possible to treat this clock as a "global" clock rather than a device specific one, and pass NULL as the device for clk_get?

That's not nice, but at least it gives you a way to keep it out of the binding, and "just" creates a dependency between the specific PCI host controller and the way that clock is wired up on a particular SoC.

Arnd

#19 lore raw

PATCH 7/7 PCI: designware: split samsung and fsl bindings

In reply to Lucas Stach
Quoted 134 lines · Lucas Stach

The glue around the core designware IP is
significantly different between the Exynos and
i.MX, which is reflected in the DT bindings.

Note that this patch doesn't change any bindings, but just alters the documentation to match reality of deployed DTs and kernels.

---
 .../devicetree/bindings/pci/designware-pcie.txt    | 69 +--------------------
 .../devicetree/bindings/pci/fsl,imx6q-pcie.txt     | 48 +++++++++++++++
 .../bindings/pci/samsung,exynos5440-pcie.txt       | 70 ++++++++++++++++++++++
 3 files changed, 119 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
Documentation/devicetree/bindings/pci/designware-pcie.txt +1 -68
index d6fae13ff062..8274c80fe874 100644
@@ -1,15 +1,7 @@
 * Synopsys Designware PCIe interface
 
 Required properties:
-- compatible: should contain "snps,dw-pcie" to identify the
-       core, plus an identifier for the specific instance, such
-       as "samsung,exynos5440-pcie" or "fsl,imx6q-pcie".
-- reg: base addresses and lengths of the pcie controller,
-       the phy controller, additional register for the phy controller.
-- interrupts: interrupt values for level interrupt,
-       pulse interrupt, special interrupt.
-- clocks: from common clock binding: handle to pci clock.
-- clock-names: from common clock binding: should be "pcie" and "pcie_bus".
+- compatible: should contain "snps,dw-pcie" to identify the core.
 - #address-cells: set to <3>
 - #size-cells: set to <2>
 - device_type: set to "pci"
@@ -22,62 +14,3 @@ Required properties:
 
 Optional properties:
 - reset-gpio: gpio pin number of power good signal
-
-Optional properties for fsl,imx6q-pcie
-- power-on-gpio: gpio pin number of power-enable signal
-- wake-up-gpio: gpio pin number of incoming wakeup signal
-- disable-gpio: gpio pin number of outgoing rfkill/endpoint disable signal
-
-Example:
-
-SoC specific DT Entry:
-
-       pcie at 290000 {
-               compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-               reg = <0x290000 0x1000
-                       0x270000 0x1000
-                       0x271000 0x40>;
-               interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
-               clocks = <&clock 28>, <&clock 27>;
-               clock-names = "pcie", "pcie_bus";
-               #address-cells = <3>;
-               #size-cells = <2>;
-               device_type = "pci";
-               ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
-                         0x81000000 0 0          0x40001000 0 0x00010000   /* downstream I/O */
-                         0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0x0 0 &gic 53>;
-               num-lanes = <4>;
-       };
-
-       pcie at 2a0000 {
-               compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-               reg = <0x2a0000 0x1000
-                       0x272000 0x1000
-                       0x271040 0x40>;
-               interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
-               clocks = <&clock 29>, <&clock 27>;
-               clock-names = "pcie", "pcie_bus";
-               #address-cells = <3>;
-               #size-cells = <2>;
-               device_type = "pci";
-               ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
-                         0x81000000 0 0          0x60001000 0 0x00010000   /* downstream I/O */
-                         0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0x0 0 &gic 56>;
-               num-lanes = <4>;
-       };
-
-Board specific DT Entry:
-
-       pcie at 290000 {
-               reset-gpio = <&pin_ctrl 5 0>;
-       };
-
-       pcie at 2a0000 {
-               reset-gpio = <&pin_ctrl 22 0>;
-       };
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +27 -0
new file mode 100644
index 000000000000..93fbfd62f13c
@@ -0,0 +1,48 @@
+* Freescale i.MX6 PCIe interface
+
+This PCIe host controller is based on the Synopsis Designware PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+- compatible: "fsl,imx6q-pcie"
+- reg: base addresse and length of the pcie controller
+- interrupts: First entry must contain interrupt handle for controller
+  INTA output.
+- clocks: Must contain an entry for each entry in clock-names.
+       See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries:
+       - "pcie_ref_125m"
+       - "sata_ref_100m"
+       - "lvds_gate"
+       - "pcie_axi"
+
+Optional properties:
+- power-on-gpio: gpio pin number of power-enable signal
+- wake-up-gpio:  gpio pin number of incoming wakeup signal
+- disable-gpio:  gpio pin number of outgoing rfkill/endpoint disable signal
+
+Example:
+
+       pcie at 0x01000000 {
+               compatible = "fsl,imx6q-pcie", "snps,dw-pcie";

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt line 37

Quoted 10 lines
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +10 -0
+               reg = <0x01ffc000 0x4000>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               device_type = "pci";
+               ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
+                         0x81000000 0 0          0x01f80000 0 0x00010000
+                         0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
+               num-lanes = <1>;
+
+               interrupts = <0 123 0x04>;

Lucas,

I'm still trying to understand DT interrupt specification and mapping.
Should this be:

interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>

It seems there is a lot of mixed use of numbers vs defines from linux/include/dt-bindings in dts files for both gpio and interrupt levels.

Thanks,

Tim

Quoted 90 lines
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt new file +11 -0
+
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0x7>;
+               interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+
+               clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
+               clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
+       };
Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt new file +70 -1
new file mode 100644
index 000000000000..0b4de1014876
@@ -0,0 +1,70 @@
+* Samsung Exynos 5440 PCIe interface
+
+This PCIe host controller is based on the Synopsis Designware PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+- compatible: "samsung,exynos5440-pcie"
+- reg: base addresses and lengths of the pcie controller,
+       the phy controller, additional register for the phy controller.
+- interrupts: A list of interrupt outputs for level interrupt,
+       pulse interrupt, special interrupt.
+- clocks: Must contain an entry for each entry in clock-names.
+       See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries:
+       - "pcie"
+       - "pcie_bus"
+
+Example:
+
+SoC specific DT Entry:
+
+       pcie at 290000 {
+               compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+               reg = <0x290000 0x1000
+                       0x270000 0x1000
+                       0x271000 0x40>;
+               interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
+               clocks = <&clock 28>, <&clock 27>;
+               clock-names = "pcie", "pcie_bus";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               device_type = "pci";
+               ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
+                         0x81000000 0 0          0x40001000 0 0x00010000   /* downstream I/O */
+                         0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+               num-lanes = <4>;
+       };
+
+       pcie at 2a0000 {
+               compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+               reg = <0x2a0000 0x1000
+                       0x272000 0x1000
+                       0x271040 0x40>;
+               interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
+               clocks = <&clock 29>, <&clock 27>;
+               clock-names = "pcie", "pcie_bus";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               device_type = "pci";
+               ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
+                         0x81000000 0 0          0x60001000 0 0x00010000   /* downstream I/O */
+                         0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+               num-lanes = <4>;
+       };
+
+Board specific DT Entry:
+
+       pcie at 290000 {
+               reset-gpio = <&pin_ctrl 5 0>;
+       };
+
+       pcie at 2a0000 {
+               reset-gpio = <&pin_ctrl 22 0>;
+       };
--

1.8.5.3

#20 lore raw

cover PCI irq mapping fixes and cleanups

In reply to Lucas Stach
Quoted 6 lines · Lucas Stach

This series cleans up the PCI irq mapping for all the ARM PCI host drivers, so they handle it in the way defined in the common PCI bindings.

Testing appreciated.

Quoted 8 lines

Lucas Stach (7):
ARM: dts: tegra: add PCIe interrupt mapping properties
PCI: tegra: use new OF interrupt mapping when possible
PCI: rcar: use new OF interrupt mapping when possible
ARM: dts: exynos5440: fix PCIe interrupt mapping
ARM: dts: imx6: add PCIe interrupt mapping properties
PCI: designware: use new OF interrupt mapping when possible
PCI: designware: split samsung and fsl bindings

Patches 1-6

For the last patch, the clock information looks like it needs to be fixed. I realize that you are just documenting what the driver is using at the moment, but that is not a proper way of establishing a binding.

Arnd

#21 lore raw

cover PCI irq mapping fixes and cleanups

In reply to Lucas Stach
Quoted 30 lines · Lucas Stach

This series cleans up the PCI irq mapping for all the ARM PCI host drivers, so they handle it in the way defined in the common PCI bindings.

Testing appreciated.

Lucas Stach (7):
ARM: dts: tegra: add PCIe interrupt mapping properties
PCI: tegra: use new OF interrupt mapping when possible
PCI: rcar: use new OF interrupt mapping when possible
ARM: dts: exynos5440: fix PCIe interrupt mapping
ARM: dts: imx6: add PCIe interrupt mapping properties
PCI: designware: use new OF interrupt mapping when possible
PCI: designware: split samsung and fsl bindings

 .../devicetree/bindings/pci/designware-pcie.txt    | 69 +--------------------
 .../devicetree/bindings/pci/fsl,imx6q-pcie.txt     | 48 +++++++++++++++
 .../bindings/pci/nvidia,tegra20-pcie.txt           |  8 +++
 .../bindings/pci/samsung,exynos5440-pcie.txt       | 70 ++++++++++++++++++++++
 arch/arm/boot/dts/exynos5440.dtsi                  |  4 +-
 arch/arm/boot/dts/imx6qdl.dtsi                     | 11 ++++
 arch/arm/boot/dts/tegra20.dtsi                     |  4 ++
 arch/arm/boot/dts/tegra30.dtsi                     |  4 ++
 drivers/pci/host/pci-rcar-gen2.c                   |  8 ++-
 drivers/pci/host/pci-tegra.c                       |  7 ++-
 drivers/pci/host/pcie-designware.c                 |  8 ++-
 11 files changed, 168 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
Quoted 3 lines

--
1.8.5.3

Lucas,

In testing this on IMX6 I'm finding that 'of_irq_parse_and_map_pci()'
always returns -EINVAL because it can't find a dt node for the host
bridge: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/of/of_pci_irq.c#n60.

So it seems there is still something missing in the imx6 devicetree regarding a 'host bridge'? Is this solution expecting the range/interrupt data from the PCI host controller to be encapsulated in a host-bridge node such as
http://lxr.missinglinkelectronics.com/linux/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt#L124?
If so, thats not how the imx6 host controller node is currently
defined.

In my particular test case I have a baseboard with a socket on it and a PLX PEX860x PCIe switch on an add-in card. So I don't think it makes sense to me to describe the add-in card in the baseboard DT -
that wouldn't be very plug-n-play. By the way, I'm not referring to
the add-in card with the TI-XIO2001 PCIe-to-PCI bridge with the mismapped IRQ's - I'm aware that I would need to deal with that somehow in devicetree (still trying to understand how).

Thanks,

Tim

#22 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 3 lines · Tim Harvey

In testing this on IMX6 I'm finding that 'of_irq_parse_and_map_pci()'
always returns -EINVAL because it can't find a dt node for the host
bridge: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/of/of_pci_irq.c#n60.

There may be some kind of issue in the pcie-designware.c:

static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)

{
        struct pci_bus *bus;
        struct pcie_port *pp = sys_to_pcie(sys);

        if (pp) {
                pp->root_bus_nr = sys->busnr;
                bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
                                     ^^^^^^^^^^^
                                     Shouldn't be null for DT cases.

Perhaps since the driver doesn't pass in a parent pointer, no parent device is associated with the struct pci_bus that gets created, so pci_bus_to_OF_node will always fail and the DT PCI mechanisms become broken.

Jason

#23 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 20 lines · Jason Gunthorpe
Quoted 3 lines · Tim Harvey

In testing this on IMX6 I'm finding that 'of_irq_parse_and_map_pci()' always returns -EINVAL because it can't find a dt node for the host bridge:

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/of/of_pci_irq.c#n60.

There may be some kind of issue in the pcie-designware.c:

static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)

{
        struct pci_bus *bus;
        struct pcie_port *pp = sys_to_pcie(sys);

        if (pp) {
                pp->root_bus_nr = sys->busnr;
                bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
                                     ^^^^^^^^^^^
                                     Shouldn't be null for DT cases.
Quoted 4 lines

Perhaps since the driver doesn't pass in a parent pointer, no parent device is associated with the struct pci_bus that gets created, so pci_bus_to_OF_node will always fail and the DT PCI mechanisms become broken.

Jason,
Thank you for your advice. :-)

Tim,
I tested the following as Jason guided.
You can test i.MX PCIe with this.

./drivers/pci/host/pcie-designware.c
@@ -726,7 +727,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)

        if (pp) {
                pp->root_bus_nr = sys->busnr;
-               bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+               bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
                                        sys, &sys->resources);
        } else {
                bus = NULL;

However, I think that we may need to replace 'pci_common_init()' with 'pci_common_init_dev()'.

Best regards,
Jingoo Han

#24 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 21 lines · Jingoo Han
Quoted 20 lines · Jason Gunthorpe
Quoted 3 lines · Tim Harvey

In testing this on IMX6 I'm finding that 'of_irq_parse_and_map_pci()' always returns -EINVAL because it can't find a dt node for the host bridge:

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/of/of_pci_irq.c#n60.

There may be some kind of issue in the pcie-designware.c:

static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)

{
        struct pci_bus *bus;
        struct pcie_port *pp = sys_to_pcie(sys);

        if (pp) {
                pp->root_bus_nr = sys->busnr;
                bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
                                     ^^^^^^^^^^^
                                     Shouldn't be null for DT cases.
Quoted 7 lines
Quoted 4 lines

Perhaps since the driver doesn't pass in a parent pointer, no parent device is associated with the struct pci_bus that gets created, so pci_bus_to_OF_node will always fail and the DT PCI mechanisms become broken.

Jason,
Thank you for your advice. :-)

Jason,

Yes thank you - this does eliminate the -EINVAL from of_irq_parse_pci() but something still is wrong (see below)

Quoted 3 lines

Tim,
I tested the following as Jason guided.

Jingoo,

Did you test this on in a configuration where devices are behind a PCIe switch? I'm still not getting the right IRQ's for that configuration.

I'm working with the following patch:

drivers/pci/host/pcie-designware.c +4 -2
index 3e0c2af..a563a8d 100644
@@ -493,7 +493,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
        dw_pci.nr_controllers = 1;
        dw_pci.private_data = (void **)&pp;
 
-       pci_common_init(&dw_pci);
+       pci_common_init_dev(pp->dev, &dw_pci);
        pci_assign_unassigned_resources();
 #ifdef CONFIG_PCI_DOMAINS
        dw_pci.domain++;
@@ -726,7 +726,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_s
 
        if (pp) {
                pp->root_bus_nr = sys->busnr;
-               bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+               bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
                                        sys, &sys->resources);
        } else {
                bus = NULL;
@@ -742,6 +742,8 @@ static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slo
        int irq;
 
        irq = of_irq_parse_and_map_pci(dev, slot, pin);
+       dev_info(&dev->dev, "%s: %04x:%04x slot%d pin%d irq%d\n",
+               __func__, dev->vendor, dev->device, slot, pin, irq);
        if (!irq)
                irq = pp->irq;
 

The configuration I'm testing is:
root at OpenWrt:/# lspci -n
00:00.0 0604: 16c3:abcd (rev 01)
01:00.0 0604: 10b5:8609 (rev ba)
01:00.1 0880: 10b5:8609 (rev ba)
02:01.0 0604: 10b5:8609 (rev ba)
02:04.0 0604: 10b5:8609 (rev ba)
02:05.0 0604: 10b5:8609 (rev ba)
02:06.0 0604: 10b5:8609 (rev ba)
02:07.0 0604: 10b5:8609 (rev ba)
02:08.0 0604: 10b5:8609 (rev ba)
02:09.0 0604: 10b5:8609 (rev ba)
07:00.0 0280: 168c:002b (rev 01)
08:00.0 0200: 11ab:4380
root at OpenWrt:/# lspci -tnv -[0000:00]---00.0-[01-09]--+-00.0-[02-09]--+-01.0-[03]--

                           |               +-04.0-[04]--
                           |               +-05.0-[05]--
                           |               +-06.0-[06]--
                           |               +-07.0-[07]----00.0  168c:002b
                           |               +-08.0-[08]----00.0  11ab:4380
                           |               \-09.0-[09]--
                           \-00.1  10b5:8609

The dev_info showing what of_irq_parse_and_map_pci() above produces:

[    1.818485] pci 0000:00:00.0: dw_pcie_map_irq: 16c3:abcd slot0 pin1 irq20
[    1.818703] pci 0000:01:00.0: dw_pcie_map_irq: 10b5:8609 slot0 pin1 irq20
[    1.818939] pci 0000:01:00.1: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.819179] pci 0000:02:01.0: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.819395] pci 0000:02:04.0: dw_pcie_map_irq: 10b5:8609 slot0 pin1 irq20
[    1.819631] pci 0000:02:05.0: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.819859] pci 0000:02:06.0: dw_pcie_map_irq: 10b5:8609 slot0 pin3 irq0
[    1.820087] pci 0000:02:07.0: dw_pcie_map_irq: 10b5:8609 slot0 pin4 irq0
[    1.820404] pci 0000:02:08.0: dw_pcie_map_irq: 10b5:8609 slot0 pin1 irq20
[    1.820650] pci 0000:02:09.0: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.820881] pci 0000:07:00.0: dw_pcie_map_irq: 168c:002b slot0 pin4 irq0
[    1.821100] pci 0000:08:00.0: dw_pcie_map_irq: 11ab:4380 slot0 pin1 irq20

I'm not clear why irq 20 is getting returned for all the slots with (slot%4)=0 and func=0. If I start debugging of_irq_parse_pci() I see that it walks up the tree until it gets to the pcie host controller then calls of_irq_parse_raw() which is returning irq20 or -EINVAL.

Tim

Quoted 19 lines

You can test i.MX PCIe with this.

./drivers/pci/host/pcie-designware.c

(quoted diff) +1 -1
@@ -726,7 +727,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 
        if (pp) {
                pp->root_bus_nr = sys->busnr;
-               bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+               bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
                                        sys, &sys->resources);
        } else {
                bus = NULL;

However, I think that we may need to replace 'pci_common_init()' with 'pci_common_init_dev()'.

Best regards,
Jingoo Han

#25 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 4 lines · Tim Harvey

I'm not clear why irq 20 is getting returned for all the slots with (slot%4)=0 and func=0. If I start debugging of_irq_parse_pci() I see that it walks up the tree until it gets to the pcie host controller then calls of_irq_parse_raw() which is returning irq20 or -EINVAL.

Can you share your DT as well?

Jason

#26 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 8 lines · Jason Gunthorpe
Quoted 4 lines · Tim Harvey

I'm not clear why irq 20 is getting returned for all the slots with (slot%4)=0 and func=0. If I start debugging of_irq_parse_pci() I see that it walks up the tree until it gets to the pcie host controller then calls of_irq_parse_raw() which is returning irq20 or -EINVAL.

Can you share your DT as well?

sure - I'm not sure what the best way to show this is (a dtc commandline probably?). This is from u-boot:

/ {
        board = "GW5410-SP275-B";
        system-serial = [35 30 38 38 30];
        #address-cells = <0x00000001>;
        #size-cells = <0x00000001>;
        model = "Gateworks Ventana i.MX6 Quad GW54XX";
        compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
        chosen {
                bootargs = "console=ttymxc1,115200";
        };
        aliases {
                gpio0 = "/soc/aips-bus at 02000000/gpio at 0209c000";
                gpio1 = "/soc/aips-bus at 02000000/gpio at 020a0000";
                gpio2 = "/soc/aips-bus at 02000000/gpio at 020a4000";
                gpio3 = "/soc/aips-bus at 02000000/gpio at 020a8000";
                gpio4 = "/soc/aips-bus at 02000000/gpio at 020ac000";
                gpio5 = "/soc/aips-bus at 02000000/gpio at 020b0000";
                gpio6 = "/soc/aips-bus at 02000000/gpio at 020b4000";
                i2c0 = "/soc/aips-bus at 02100000/i2c at 021a0000";
                i2c1 = "/soc/aips-bus at 02100000/i2c at 021a4000";
                i2c2 = "/soc/aips-bus at 02100000/i2c at 021a8000";
                serial0 =
"/soc/aips-bus at 02000000/spba-bus at 02000000/serial at 02020000";
                serial1 = "/soc/aips-bus at 02100000/serial at 021e8000";
                serial4 = "/soc/aips-bus at 02100000/serial at 021f4000";
                can0 = "/soc/aips-bus at 02000000/flexcan at 02090000";
                ethernet0 = "/soc/aips-bus at 02100000/ethernet at 02188000";
                led0 = "/leds/user1";
                led1 = "/leds/user2";
                led2 = "/leds/user3";
                nand = "/soc/gpmi-nand at 00112000";
                usb0 = "/soc/aips-bus at 02100000/usb at 02184200";
                usb1 = "/soc/aips-bus at 02100000/usb at 02184000";
                usdhc2 = "/soc/aips-bus at 02100000/usdhc at 02198000";
        };
        memory {
                device_type = "memory";
                reg = <0x10000000 0x40000000>;
        };
        interrupt-controller at 00a01000 {
                compatible = "arm,cortex-a9-gic";
                #interrupt-cells = <0x00000003>;
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
                interrupt-controller;
                reg = <0x00a01000 0x00001000 0x00a00100 0x00000100>;
                linux,phandle = <0x00000001>;
                phandle = <0x00000001>;
        };
        clocks {
                #address-cells = <0x00000001>;
                #size-cells = <0x00000000>;
                ckil {
                        compatible = "fsl,imx-ckil", "fixed-clock";
                        clock-frequency = <0x00008000>;
                };
                ckih1 {
                        compatible = "fsl,imx-ckih1", "fixed-clock";
                        clock-frequency = <0x00000000>;
                };
                osc {
                        compatible = "fsl,imx-osc", "fixed-clock";
                        clock-frequency = <0x016e3600>;
                };
        };
        soc {
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
                compatible = "simple-bus";
                interrupt-parent = <0x00000001>;
                ranges;
                dma-apbh at 00110000 {
                        compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
                        reg = <0x00110000 0x00002000>;
                        interrupts = <0x00000000 0x0000000d 0x00000004
0x00000000 0x0000000d 0x00000004 0x00000000 0x0000000d 0x00000004
0x00000000 0x0000000d 0x00000004>;
                        interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
                        #dma-cells = <0x00000001>;
                        dma-channels = <0x00000004>;
                        clocks = <0x00000002 0x0000006a>;
                        linux,phandle = <0x00000003>;
                        phandle = <0x00000003>;
                };
                gpmi-nand at 00112000 {
                        compatible = "fsl,imx6q-gpmi-nand";
                        #address-cells = <0x00000001>;
                        #size-cells = <0x00000001>;
                        reg = <0x00112000 0x00002000 0x00114000 0x00002000>;
                        reg-names = "gpmi-nand", "bch";
                        interrupts = <0x00000000 0x0000000f 0x00000004>;
                        interrupt-names = "bch";
                        clocks = <0x00000002 0x00000098 0x00000002
0x00000099 0x00000002 0x00000097 0x00000002 0x00000096 0x00000002
0x00000095>;
                        clock-names = "gpmi_io", "gpmi_apb",
"gpmi_bch", "gpmi_bch_apb", "per1_bch";
                        dmas = <0x00000003 0x00000000>;
                        dma-names = "rx-tx";
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <0x00000004>;
                        partition at 0 {
                                label = "uboot";
                                reg = <0x00000000 0x01000000>;
                        };
                        partition at 1000000 {
                                label = "env";
                                reg = <0x01000000 0x00100000>;
                        };
                        partition at 1100000 {
                                label = "rootfs";
                                reg = <0x01100000 0x0ef00000>;
                        };
                };
                timer at 00a00600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0x00a00600 0x00000020>;
                        interrupts = <0x00000001 0x0000000d 0x00000f01>;
                        clocks = <0x00000002 0x0000000f>;
                };
                l2-cache at 00a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x00001000>;
                        interrupts = <0x00000000 0x0000005c 0x00000004>;
                        cache-unified;
                        cache-level = <0x00000002>;
                        arm,tag-latency = <0x00000004 0x00000002 0x00000003>;
                        arm,data-latency = <0x00000004 0x00000002 0x00000003>;
                        linux,phandle = <0x00000022>;
                        phandle = <0x00000022>;
                };
                pcie at 0x01000000 {
                        compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
                        reg = <0x01ffc000 0x00004000>;
                        #address-cells = <0x00000003>;
                        #size-cells = <0x00000002>;
                        device_type = "pci";
                        ranges = * 0x18000ce0 [0x00000048];
                        num-lanes = <0x00000001>;
                        interrupts = <0x00000000 0x0000007b 0x00000004>;
                        #interrupt-cells = <0x00000001>;
                        interrupt-map-mask = <0x00000000 0x00000000
0x00000000 0x00000007>;
                        interrupt-map = * 0x18000d88 [0x00000080];
                        clocks = <0x00000002 0x000000bd 0x00000002
0x000000bb 0x00000002 0x000000ce 0x00000002 0x00000090>;
                        clock-names = "pcie_ref_125m",
"sata_ref_100m", "lvds_gate", "pcie_axi";
                        status = "okay";
                        reset-gpio = <0x00000005 0x0000001d 0x00000000>;
                };
                pmu {
                        compatible = "arm,cortex-a9-pmu";
                        interrupts = <0x00000000 0x0000005e 0x00000004>;
                };
                aips-bus at 02000000 {
                        compatible = "fsl,aips-bus", "simple-bus";
                        #address-cells = <0x00000001>;
                        #size-cells = <0x00000001>;
                        reg = <0x02000000 0x00100000>;
                        ranges;
                        spba-bus at 02000000 {
                                compatible = "fsl,spba-bus", "simple-bus";
                                #address-cells = <0x00000001>;
                                #size-cells = <0x00000001>;
                                reg = <0x02000000 0x00040000>;
                                ranges;
                                spdif at 02004000 {
                                        compatible = "fsl,imx35-spdif";
                                        reg = <0x02004000 0x00004000>;
                                        interrupts = <0x00000000
0x00000034 0x00000004>;
                                        dmas = <0x00000006 0x0000000e
0x00000012 0x00000000 0x00000006 0x0000000f 0x00000012 0x00000000>;
                                        dma-names = "rx", "tx";
                                        clocks = * 0x18001084 [0x00000048];
                                        clock-names = "core", "rxtx0",
"rxtx1", "rxtx2", "rxtx3", "rxtx4", "rxtx5", "rxtx6", "rxtx7";
                                        status = "disabled";
                                };
                                serial at 02020000 {
                                        compatible = "fsl,imx6q-uart",
"fsl,imx21-uart";
                                        reg = <0x02020000 0x00004000>;
                                        interrupts = <0x00000000
0x0000001a 0x00000004>;
                                        clocks = <0x00000002
0x000000a0 0x00000002 0x000000a1>;
                                        clock-names = "ipg", "per";
                                        dmas = <0x00000006 0x00000019
0x00000004 0x00000000 0x00000006 0x0000001a 0x00000004 0x00000000>;
                                        dma-names = "rx", "tx";
                                        status = "okay";
                                        pinctrl-names = "default";
                                        pinctrl-0 = <0x00000007>;
                                };
                                esai at 02024000 {
                                        reg = <0x02024000 0x00004000>;
                                        interrupts = <0x00000000
0x00000033 0x00000004>;
                                };
                                ssi at 0202c000 {
                                        compatible = "fsl,imx6q-ssi",
"fsl,imx21-ssi";
                                        reg = <0x0202c000 0x00004000>;
                                        interrupts = <0x00000000
0x0000002f 0x00000004>;
                                        clocks = <0x00000002 0x000000b3>;
                                        dmas = <0x00000006 0x00000029
0x00000001 0x00000000 0x00000006 0x0000002a 0x00000001 0x00000000>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <0x0000000f>;
                                        fsl,ssi-dma-events =
<0x0000002a 0x00000029>;
                                        status = "okay";
                                        fsl,mode = "i2s-slave";
                                };
                                ssi at 02030000 {
                                        compatible = "fsl,imx6q-ssi",
"fsl,imx21-ssi";
                                        reg = <0x02030000 0x00004000>;
                                        interrupts = <0x00000000
0x00000030 0x00000004>;
                                        clocks = <0x00000002 0x000000b4>;
                                        dmas = <0x00000006 0x0000002d
0x00000001 0x00000000 0x00000006 0x0000002e 0x00000001 0x00000000>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <0x0000000f>;
                                        fsl,ssi-dma-events =
<0x0000002e 0x0000002d>;
                                        status = "disabled";
                                };
                                asrc at 02034000 {
                                        reg = <0x02034000 0x00004000>;
                                        interrupts = <0x00000000
0x00000032 0x00000004>;
                                };
                                spba at 0203c000 {
                                        reg = <0x0203c000 0x00004000>;
                                };
                                ecspi at 02018000 {
                                        #address-cells = <0x00000001>;
                                        #size-cells = <0x00000000>;
                                        compatible =
"fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02018000 0x00004000>;
                                        interrupts = <0x00000000
0x00000023 0x00000004>;
                                        clocks = <0x00000002
0x00000074 0x00000002 0x00000074>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                        };
                        vpu at 02040000 {
                                reg = <0x02040000 0x0003c000>;
                                interrupts = <0x00000000 0x00000003
0x00000004 0x00000000 0x0000000c 0x00000004>;
                        };
                        aipstz at 0207c000 {
                                reg = <0x0207c000 0x00004000>;
                        };
                        pwm at 02080000 {
                                #pwm-cells = <0x00000002>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02080000 0x00004000>;
                                interrupts = <0x00000000 0x00000053 0x00000004>;
                                clocks = <0x00000002 0x0000003e
0x00000002 0x00000091>;
                                clock-names = "ipg", "per";
                        };
                        pwm at 02084000 {
                                #pwm-cells = <0x00000002>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02084000 0x00004000>;
                                interrupts = <0x00000000 0x00000054 0x00000004>;
                                clocks = <0x00000002 0x0000003e
0x00000002 0x00000092>;
                                clock-names = "ipg", "per";
                        };
                        pwm at 02088000 {
                                #pwm-cells = <0x00000002>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02088000 0x00004000>;
                                interrupts = <0x00000000 0x00000055 0x00000004>;
                                clocks = <0x00000002 0x0000003e
0x00000002 0x00000093>;
                                clock-names = "ipg", "per";
                        };
                        pwm at 0208c000 {
                                #pwm-cells = <0x00000002>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x0208c000 0x00004000>;
                                interrupts = <0x00000000 0x00000056 0x00000004>;
                                clocks = <0x00000002 0x0000003e
0x00000002 0x00000094>;
                                clock-names = "ipg", "per";
                        };
                        flexcan at 02090000 {
                                compatible = "fsl,imx6q-flexcan";
                                reg = <0x02090000 0x00004000>;
                                interrupts = <0x00000000 0x0000006e 0x00000004>;
                                clocks = <0x00000002 0x0000006c
0x00000002 0x0000006d>;
                                clock-names = "ipg", "per";
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <0x00000008>;
                        };
                        flexcan at 02094000 {
                                compatible = "fsl,imx6q-flexcan";
                                reg = <0x02094000 0x00004000>;
                                interrupts = <0x00000000 0x0000006f 0x00000004>;
                                clocks = <0x00000002 0x0000006e
0x00000002 0x0000006f>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                        gpt at 02098000 {
                                compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
                                reg = <0x02098000 0x00004000>;
                                interrupts = <0x00000000 0x00000037 0x00000004>;
                                clocks = <0x00000002 0x00000077
0x00000002 0x00000078>;
                                clock-names = "ipg", "per";
                        };
                        gpio at 0209c000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x0209c000 0x00004000>;
                                interrupts = <0x00000000 0x00000042
0x00000004 0x00000000 0x00000043 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                                linux,phandle = <0x00000005>;
                                phandle = <0x00000005>;
                        };
                        gpio at 020a0000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a0000 0x00004000>;
                                interrupts = <0x00000000 0x00000044
0x00000004 0x00000000 0x00000045 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                        };
                        gpio at 020a4000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a4000 0x00004000>;
                                interrupts = <0x00000000 0x00000046
0x00000004 0x00000000 0x00000047 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                                linux,phandle = <0x00000027>;
                                phandle = <0x00000027>;
                        };
                        gpio at 020a8000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a8000 0x00004000>;
                                interrupts = <0x00000000 0x00000048
0x00000004 0x00000000 0x00000049 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                                linux,phandle = <0x00000026>;
                                phandle = <0x00000026>;
                        };
                        gpio at 020ac000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020ac000 0x00004000>;
                                interrupts = <0x00000000 0x0000004a
0x00000004 0x00000000 0x0000004b 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                        };
                        gpio at 020b0000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020b0000 0x00004000>;
                                interrupts = <0x00000000 0x0000004c
0x00000004 0x00000000 0x0000004d 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                        };
                        gpio at 020b4000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020b4000 0x00004000>;
                                interrupts = <0x00000000 0x0000004e
0x00000004 0x00000000 0x0000004f 0x00000004>;
                                gpio-controller;
                                #gpio-cells = <0x00000002>;
                                interrupt-controller;
                                #interrupt-cells = <0x00000002>;
                                linux,phandle = <0x00000018>;
                                phandle = <0x00000018>;
                        };
                        kpp at 020b8000 {
                                reg = <0x020b8000 0x00004000>;
                                interrupts = <0x00000000 0x00000052 0x00000004>;
                        };
                        wdog at 020bc000 {
                                compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
                                reg = <0x020bc000 0x00004000>;
                                interrupts = <0x00000000 0x00000050 0x00000004>;
                                clocks = <0x00000002 0x00000000>;
                        };
                        wdog at 020c0000 {
                                compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
                                reg = <0x020c0000 0x00004000>;
                                interrupts = <0x00000000 0x00000051 0x00000004>;
                                clocks = <0x00000002 0x00000000>;
                                status = "disabled";
                        };
                        ccm at 020c4000 {
                                compatible = "fsl,imx6q-ccm";
                                reg = <0x020c4000 0x00004000>;
                                interrupts = <0x00000000 0x00000057
0x00000004 0x00000000 0x00000058 0x00000004>;
                                #clock-cells = <0x00000001>;
                                linux,phandle = <0x00000002>;
                                phandle = <0x00000002>;
                        };
                        anatop at 020c8000 {
                                compatible = "fsl,imx6q-anatop",
"syscon", "simple-bus";
                                reg = <0x020c8000 0x00001000>;
                                interrupts = <0x00000000 0x00000031
0x00000004 0x00000000 0x00000036 0x00000004 0x00000000 0x0000007f
0x00000004>;
                                linux,phandle = <0x00000009>;
                                phandle = <0x00000009>;
                                regulator-1p1 at 110 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd1p1";
                                        regulator-min-microvolt = "", "5";
                                        regulator-max-microvolt = <0x0014fb18>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x00000110>;
                                        anatop-vol-bit-shift = <0x00000008>;
                                        anatop-vol-bit-width = <0x00000005>;
                                        anatop-min-bit-val = <0x00000004>;
                                        anatop-min-voltage = "", "5";
                                        anatop-max-voltage = <0x0014fb18>;
                                };
                                regulator-3p0 at 120 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd3p0";
                                        regulator-min-microvolt = <0x002ab980>;
                                        regulator-max-microvolt = <0x003010b0>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x00000120>;
                                        anatop-vol-bit-shift = <0x00000008>;
                                        anatop-vol-bit-width = <0x00000005>;
                                        anatop-min-bit-val = <0x00000000>;
                                        anatop-min-voltage = <0x00280de8>;
                                        anatop-max-voltage = <0x0033e140>;
                                };
                                regulator-2p5 at 130 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd2p5";
                                        regulator-min-microvolt = <0x001e8480>;
                                        regulator-max-microvolt = <0x0029f630>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x00000130>;
                                        anatop-vol-bit-shift = <0x00000008>;
                                        anatop-vol-bit-width = <0x00000005>;
                                        anatop-min-bit-val = <0x00000000>;
                                        anatop-min-voltage = <0x001e8480>;
                                        anatop-max-voltage = <0x0029f630>;
                                };
                                regulator-vddcore at 140 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "cpu";
                                        regulator-min-microvolt = <0x000b1008>;
                                        regulator-max-microvolt = <0x00162010>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x00000140>;
                                        anatop-vol-bit-shift = <0x00000000>;
                                        anatop-vol-bit-width = <0x00000005>;
                                        anatop-delay-reg-offset = <0x00000170>;
                                        anatop-delay-bit-shift = <0x00000018>;
                                        anatop-delay-bit-width = <0x00000002>;
                                        anatop-min-bit-val = <0x00000001>;
                                        anatop-min-voltage = <0x000b1008>;
                                        anatop-max-voltage = <0x00162010>;
                                        linux,phandle = <0x00000023>;
                                        phandle = <0x00000023>;
                                };
                                regulator-vddpu at 140 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vddpu";
                                        regulator-min-microvolt = <0x000b1008>;
                                        regulator-max-microvolt = <0x00162010>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x00000140>;
                                        anatop-vol-bit-shift = <0x00000009>;
                                        anatop-vol-bit-width = <0x00000005>;
                                        anatop-delay-reg-offset = <0x00000170>;
                                        anatop-delay-bit-shift = <0x0000001a>;
                                        anatop-delay-bit-width = <0x00000002>;
                                        anatop-min-bit-val = <0x00000001>;
                                        anatop-min-voltage = <0x000b1008>;
                                        anatop-max-voltage = <0x00162010>;
                                        linux,phandle = <0x00000024>;
                                        phandle = <0x00000024>;
                                };
                                regulator-vddsoc at 140 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vddsoc";
                                        regulator-min-microvolt = <0x000b1008>;
                                        regulator-max-microvolt = <0x00162010>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x00000140>;
                                        anatop-vol-bit-shift = <0x00000012>;
                                        anatop-vol-bit-width = <0x00000005>;
                                        anatop-delay-reg-offset = <0x00000170>;
                                        anatop-delay-bit-shift = <0x0000001c>;
                                        anatop-delay-bit-width = <0x00000002>;
                                        anatop-min-bit-val = <0x00000001>;
                                        anatop-min-voltage = <0x000b1008>;
                                        anatop-max-voltage = <0x00162010>;
                                        linux,phandle = <0x00000025>;
                                        phandle = <0x00000025>;
                                };
                        };
                        tempmon {
                                compatible = "fsl,imx6q-tempmon";
                                interrupts = <0x00000000 0x00000031 0x00000004>;
                                fsl,tempmon = <0x00000009>;
                                fsl,tempmon-data = <0x0000000a>;
                        };
                        usbphy at 020c9000 {
                                compatible = "fsl,imx6q-usbphy",
"fsl,imx23-usbphy";
                                reg = <0x020c9000 0x00001000>;
                                interrupts = <0x00000000 0x0000002c 0x00000004>;
                                clocks = <0x00000002 0x000000b6>;
                                linux,phandle = <0x00000010>;
                                phandle = <0x00000010>;
                        };
                        usbphy at 020ca000 {
                                compatible = "fsl,imx6q-usbphy",
"fsl,imx23-usbphy";
                                reg = <0x020ca000 0x00001000>;
                                interrupts = <0x00000000 0x0000002d 0x00000004>;
                                clocks = <0x00000002 0x000000b7>;
                                linux,phandle = <0x00000014>;
                                phandle = <0x00000014>;
                        };
                        snvs at 020cc000 {
                                compatible = "fsl,sec-v4.0-mon", "simple-bus";
                                #address-cells = <0x00000001>;
                                #size-cells = <0x00000001>;
                                ranges = <0x00000000 0x020cc000 0x00004000>;
                                snvs-rtc-lp at 34 {
                                        compatible = "fsl,sec-v4.0-mon-rtc-lp";
                                        reg = <0x00000034 0x00000058>;
                                        interrupts = <0x00000000
0x00000013 0x00000004 0x00000000 0x00000014 0x00000004>;
                                };
                        };
                        epit at 020d0000 {
                                reg = <0x020d0000 0x00004000>;
                                interrupts = <0x00000000 0x00000038 0x00000004>;
                        };
                        epit at 020d4000 {
                                reg = <0x020d4000 0x00004000>;
                                interrupts = <0x00000000 0x00000039 0x00000004>;
                        };
                        src at 020d8000 {
                                compatible = "fsl,imx6q-src", "fsl,imx51-src";
                                reg = <0x020d8000 0x00004000>;
                                interrupts = <0x00000000 0x0000005b
0x00000004 0x00000000 0x00000060 0x00000004>;
                                #reset-cells = <0x00000001>;
                                linux,phandle = <0x00000021>;
                                phandle = <0x00000021>;
                        };
                        gpc at 020dc000 {
                                compatible = "fsl,imx6q-gpc";
                                reg = <0x020dc000 0x00004000>;
                                interrupts = <0x00000000 0x00000059
0x00000004 0x00000000 0x0000005a 0x00000004>;
                        };
                        iomuxc-gpr at 020e0000 {
                                compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
                                reg = <0x020e0000 0x00000038>;
                                linux,phandle = <0x0000000c>;
                                phandle = <0x0000000c>;
                        };
                        iomuxc at 020e0000 {
                                compatible = "fsl,imx6q-iomuxc";
                                reg = <0x020e0000 0x00004000>;
                                pinctrl-names = "default";
                                pinctrl-0 = <0x0000000b>;
                                audmux {
                                        audmux-1 {
                                                fsl,pins = *
0x18002eb8 [0x00000060];
                                                linux,phandle = <0x0000001e>;
                                                phandle = <0x0000001e>;
                                        };
                                        audmux-2 {
                                                fsl,pins = *
0x18002f58 [0x00000060];
                                        };
                                        audmux-3 {
                                                fsl,pins = *
0x18002fd8 [0x00000048];
                                        };
                                        audmux-4 {
                                                fsl,pins = *
0x18003040 [0x00000048];
                                        };
                                };
                                ecspi1 {
                                        ecspi1grp-1 {
                                                fsl,pins = *
0x180030b8 [0x00000048];
                                        };
                                        ecspi1grp-2 {
                                                fsl,pins = *
0x18003120 [0x00000048];
                                        };
                                };
                                ecspi3 {
                                        ecspi3grp-1 {
                                                fsl,pins = *
0x18003198 [0x00000048];
                                        };
                                };
                                enet {
                                        enetgrp-1 {
                                                fsl,pins = *
0x18003210 [0x00000180];
                                                linux,phandle = <0x00000016>;
                                                phandle = <0x00000016>;
                                        };
                                        enetgrp-2 {
                                                fsl,pins = *
0x180033d0 [0x00000168];
                                        };
                                        enetgrp-3 {
                                                fsl,pins = *
0x18003558 [0x00000180];
                                        };
                                };
                                esai {
                                        esaigrp-1 {
                                                fsl,pins = *
0x18003708 [0x000000d8];
                                        };
                                        esaigrp-2 {
                                                fsl,pins = *
0x18003800 [0x000000f0];
                                        };
                                };
                                flexcan1 {
                                        flexcan1grp-1 {
                                                fsl,pins = <0x0000020c
0x000005dc 0x000007e4 0x00000002 0x00000000 0x80000000 0x00000208
0x000005d8 0x00000000 0x00000002 0x00000000 0x80000000>;
                                                linux,phandle = <0x00000008>;
                                                phandle = <0x00000008>;
                                        };
                                        flexcan1grp-2 {
                                                fsl,pins = <0x00000240
0x00000610 0x00000000 0x00000003 0x00000000 0x80000000 0x0000020c
0x000005dc 0x000007e4 0x00000002 0x00000000 0x80000000>;
                                        };
                                };
                                flexcan2 {
                                        flexcan2grp-1 {
                                                fsl,pins = <0x00000218
0x000005e8 0x00000000 0x00000000 0x00000000 0x80000000 0x0000021c
0x000005ec 0x000007e8 0x00000000 0x00000000 0x80000000>;
                                        };
                                };
                                gpmi-nand {
                                        gpmi-nand-1 {
                                                fsl,pins = *
0x18003a68 [0x00000198];
                                        };
                                        gpmi-nand-2 {
                                                fsl,pins = *
0x18003c20 [0x00000180];
                                                linux,phandle = <0x00000004>;
                                                phandle = <0x00000004>;
                                        };
                                };
                                hdmi_hdcp {
                                        hdmihdcpgrp-1 {
                                                fsl,pins = <0x00000210
0x000005e0 0x00000890 0x00000002 0x00000001 0x4001b8b1 0x00000214
0x000005e4 0x00000894 0x00000002 0x00000001 0x4001b8b1>;
                                        };
                                        hdmihdcpgrp-2 {
                                                fsl,pins = <0x0000008c
0x000003a0 0x00000890 0x00000004 0x00000000 0x4001b8b1 0x00000090
0x000003a4 0x00000894 0x00000004 0x00000000 0x4001b8b1>;
                                        };
                                        hdmihdcpgrp-3 {
                                                fsl,pins = <0x0000008c
0x000003a0 0x00000890 0x00000004 0x00000000 0x4001b8b1 0x00000214
0x000005e4 0x00000894 0x00000002 0x00000001 0x4001b8b1>;
                                        };
                                };
                                hdmi_cec {
                                        hdmicecgrp-1 {
                                                fsl,pins = <0x00000088
0x0000039c 0x0000088c 0x00000006 0x00000000 0x0001f8b0>;
                                        };
                                        hdmicecgrp-2 {
                                                fsl,pins = <0x0000020c
0x000005dc 0x0000088c 0x00000006 0x00000001 0x0001f8b0>;
                                        };
                                };
                                i2c1 {
                                        i2c1grp-1 {
                                                fsl,pins = <0x000000a4
0x000003b8 0x00000898 0x00000006 0x00000000 0x4001b8b1 0x000000c4
0x000003d8 0x0000089c 0x00000001 0x00000000 0x4001b8b1>;
                                                linux,phandle = <0x0000001a>;
                                                phandle = <0x0000001a>;
                                        };
                                        i2c1grp-2 {
                                                fsl,pins = <0x00000278
0x00000648 0x0000089c 0x00000004 0x00000001 0x4001b8b1 0x0000027c
0x0000064c 0x00000898 0x00000004 0x00000001 0x4001b8b1>;
                                        };
                                };
                                i2c2 {
                                        i2c2grp-1 {
                                                fsl,pins = <0x0000008c
0x000003a0 0x000008a0 0x00000006 0x00000000 0x4001b8b1 0x00000090
0x000003a4 0x000008a4 0x00000006 0x00000000 0x4001b8b1>;
                                        };
                                        i2c2grp-2 {
                                                fsl,pins = <0x00000210
0x000005e0 0x000008a0 0x00000004 0x00000001 0x4001b8b1 0x00000214
0x000005e4 0x000008a4 0x00000004 0x00000001 0x4001b8b1>;
                                                linux,phandle = <0x0000001b>;
                                                phandle = <0x0000001b>;
                                        };
                                        i2c2grp-3 {
                                                fsl,pins = <0x0000008c
0x000003a0 0x000008a0 0x00000006 0x00000000 0x4001b8b1 0x00000214
0x000005e4 0x000008a4 0x00000004 0x00000001 0x4001b8b1>;
                                        };
                                };
                                i2c3 {
                                        i2c3grp-1 {
                                                fsl,pins = <0x00000094
0x000003a8 0x000008a8 0x00000006 0x00000000 0x4001b8b1 0x00000098
0x000003ac 0x000008ac 0x00000006 0x00000000 0x4001b8b1>;
                                        };
                                        i2c3grp-2 {
                                                fsl,pins = <0x0000022c
0x000005fc 0x000008a8 0x00000002 0x00000001 0x4001b8b1 0x00000230
0x00000600 0x000008ac 0x00000002 0x00000001 0x4001b8b1>;
                                                linux,phandle = <0x0000001c>;
                                                phandle = <0x0000001c>;
                                        };
                                        i2c3grp-3 {
                                                fsl,pins = <0x0000023c
0x0000060c 0x000008a8 0x00000006 0x00000002 0x4001b8b1 0x00000248
0x00000618 0x000008ac 0x00000006 0x00000002 0x4001b8b1>;
                                        };
                                        i2c3grp-4 {
                                                fsl,pins = <0x0000022c
0x000005fc 0x000008a8 0x00000002 0x00000001 0x4001b8b1 0x00000098
0x000003ac 0x000008ac 0x00000006 0x00000000 0x4001b8b1>;
                                        };
                                };
                                ipu1 {
                                        ipu1grp-1 {
                                                fsl,pins = *
0x180042ec [0x000002b8];
                                        };
                                        ipu1grp-2 {
                                                fsl,pins = *
0x180045c4 [0x00000120];
                                        };
                                        ipu1grp-3 {
                                                fsl,pins = *
0x18004704 [0x000001c8];
                                        };
                                };
                                mlb {
                                        mlbgrp-1 {
                                                fsl,pins = *
0x180048f8 [0x00000048];
                                        };
                                        mlbgrp-2 {
                                                fsl,pins = *
0x18004960 [0x00000048];
                                        };
                                };
                                pwm0 {
                                        pwm0grp-1 {
                                                fsl,pins = <0x00000344
0x0000072c 0x00000000 0x00000003 0x00000000 0x0001b0b1>;
                                        };
                                };
                                pwm3 {
                                        pwm3grp-1 {
                                                fsl,pins = <0x00000320
0x00000708 0x00000000 0x00000002 0x00000000 0x0001b0b1>;
                                        };
                                };
                                spdif {
                                        spdifgrp-1 {
                                                fsl,pins = <0x00000210
0x000005e0 0x00000914 0x00000006 0x00000002 0x0001b0b0>;
                                        };
                                        spdifgrp-2 {
                                                fsl,pins = <0x00000248
0x00000618 0x00000914 0x00000004 0x00000003 0x0001b0b0 0x0000024c
0x0000061c 0x00000000 0x00000004 0x00000000 0x0001b0b0>;
                                        };
                                        spdifgrp-3 {
                                                fsl,pins = <0x000001e4
0x000004f8 0x00000000 0x00000003 0x00000000 0x0001b0b0>;
                                        };
                                };
                                uart1 {
                                        uart1grp-1 {
                                                fsl,pins = <0x00000280
0x00000650 0x00000000 0x00000003 0x00000000 0x0001b0b1 0x00000284
0x00000654 0x00000920 0x00000003 0x00000001 0x0001b0b1>;
                                        };
                                        uart1grp-2 {
                                                fsl,pins = <0x000002a8
0x00000690 0x00000000 0x00000001 0x00000000 0x0001b0b1 0x000002ac
0x00000694 0x00000920 0x00000001 0x00000003 0x0001b0b1>;
                                                linux,phandle = <0x00000007>;
                                                phandle = <0x00000007>;
                                        };
                                };
                                uart2 {
                                        uart2grp-1 {
                                                fsl,pins = <0x000000bc
0x000003d0 0x00000000 0x00000004 0x00000000 0x0001b0b1 0x000000c0
0x000003d4 0x00000928 0x00000004 0x00000001 0x0001b0b1>;
                                        };
                                        uart2grp-2 {
                                                fsl,pins = *
0x18004c58 [0x00000060];
                                        };
                                        uart2grp-3 {
                                                fsl,pins = <0x00000338
0x00000720 0x00000000 0x00000002 0x00000000 0x0001b0b1 0x0000032c
0x00000714 0x00000928 0x00000002 0x00000006 0x0001b0b1>;
                                                linux,phandle = <0x0000001f>;
                                                phandle = <0x0000001f>;
                                        };
                                };
                                uart3 {
                                        uart3grp-1 {
                                                fsl,pins = *
0x18004d58 [0x00000060];
                                        };
                                        uart3grp-2 {
                                                fsl,pins = *
0x18004dd8 [0x00000060];
                                        };
                                        uart3grp-3 {
                                                fsl,pins = <0x000000b4
0x000003c8 0x00000000 0x00000002 0x00000000 0x0001b0b1 0x000000b8
0x000003cc 0x00000930 0x00000002 0x00000001 0x0001b0b1>;
                                        };
                                };
                                uart4 {
                                        uart4grp-1 {
                                                fsl,pins = <0x000001f8
0x000005c8 0x00000000 0x00000004 0x00000000 0x0001b0b1 0x000001fc
0x000005cc 0x00000938 0x00000004 0x00000001 0x0001b0b1>;
                                        };
                                };
                                uart5 {
                                        uart5grp-1 {
                                                fsl,pins = <0x00000200
0x000005d0 0x00000000 0x00000004 0x00000000 0x0001b0b1 0x00000204
0x000005d4 0x00000940 0x00000004 0x00000001 0x0001b0b1>;
                                                linux,phandle = <0x00000020>;
                                                phandle = <0x00000020>;
                                        };
                                };
                                usbotg {
                                        usbotggrp-1 {
                                                fsl,pins = <0x00000224
0x000005f4 0x00000004 0x00000003 0xff0d0101 0x00017059>;
                                                linux,phandle = <0x00000013>;
                                                phandle = <0x00000013>;
                                        };
                                        usbotggrp-2 {
                                                fsl,pins = <0x000001d8
0x000004ec 0x00000004 0x00000000 0xff0d0100 0x00017059>;
                                        };
                                };
                                usbh2 {
                                        usbh2grp-1 {
                                                fsl,pins = <0x00000058
0x0000036c 0x00000000 0x00000000 0x00000000 0x40013030 0x00000074
0x00000388 0x00000000 0x00000000 0x00000000 0x40013030>;
                                        };
                                        usbh2grp-2 {
                                                fsl,pins = <0x00000074
0x00000388 0x00000000 0x00000000 0x00000000 0x40017030>;
                                        };
                                };
                                usbh3 {
                                        usbh3grp-1 {
                                                fsl,pins = <0x0000006c
0x00000380 0x00000000 0x00000000 0x00000000 0x40013030 0x00000084
0x00000398 0x00000000 0x00000000 0x00000000 0x40013030>;
                                        };
                                        usbh3grp-2 {
                                                fsl,pins = <0x00000084
0x00000398 0x00000000 0x00000000 0x00000000 0x40017030>;
                                        };
                                };
                                usdhc1 {
                                        usdhc1grp-1 {
                                                fsl,pins = *
0x18005168 [0x000000f0];
                                        };
                                        usdhc1grp-2 {
                                                fsl,pins = *
0x18005278 [0x00000090];
                                        };
                                };
                                usdhc2 {
                                        usdhc2grp-1 {
                                                fsl,pins = *
0x18005338 [0x000000f0];
                                        };
                                        usdhc2grp-2 {
                                                fsl,pins = *
0x18005448 [0x00000090];
                                        };
                                };
                                usdhc3 {
                                        usdhc3grp-1 {
                                                fsl,pins = *
0x18005508 [0x000000f0];
                                        };
                                        usdhc3grp-1-100mhz {
                                                fsl,pins = *
0x18005620 [0x000000f0];
                                        };
                                        usdhc3grp-1-200mhz {
                                                fsl,pins = *
0x18005738 [0x000000f0];
                                        };
                                        usdhc3grp-2 {
                                                fsl,pins = *
0x18005848 [0x00000090];
                                                linux,phandle = <0x00000017>;
                                                phandle = <0x00000017>;
                                        };
                                };
                                usdhc4 {
                                        usdhc4grp-1 {
                                                fsl,pins = *
0x18005928 [0x000000f0];
                                        };
                                        usdhc4grp-2 {
                                                fsl,pins = *
0x18005a38 [0x00000090];
                                        };
                                };
                                weim {
                                        weim_cs0grp-1 {
                                                fsl,pins = <0x000000f8
0x0000040c 0x00000000 0x00000000 0x00000000 0x0000b0b1>;
                                        };
                                        weim_norgrp-1 {
                                                fsl,pins = *
0x18005b38 [0x00000408];
                                        };
                                };
                                ipu2 {
                                        ipu2grp-1 {
                                                fsl,pins = *
0x18005f70 [0x000002b8];
                                        };
                                };
                                hog {
                                        hoggrp {
                                                fsl,pins = *
0x18006250 [0x00000138];
                                                linux,phandle = <0x0000000b>;
                                                phandle = <0x0000000b>;
                                        };
                                };
                        };
                        ldb at 020e0008 {
                                #address-cells = <0x00000001>;
                                #size-cells = <0x00000000>;
                                compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
                                gpr = <0x0000000c>;
                                status = "okay";
                                clocks = <0x00000002 0x00000021
0x00000002 0x00000022 0x00000002 0x00000027 0x00000002 0x00000028
0x00000002 0x00000029 0x00000002 0x0000002a 0x00000002 0x00000087
0x00000002 0x00000088>;
                                clock-names = "di0_pll", "di1_pll",
"di0_sel", "di1_sel", "di2_sel", "di3_sel", "di0", "di1";
                                lvds-channel at 0 {
                                        reg = <0x00000000>;
                                        status = "disabled";
                                        crtcs = <0x0000000d 0x00000000
0x0000000d 0x00000001 0x0000000e 0x00000000 0x0000000e 0x00000001>;
                                };
                                lvds-channel at 1 {
                                        reg = <0x00000001>;
                                        status = "okay";
                                        crtcs = <0x0000000d 0x00000000
0x0000000d 0x00000001 0x0000000e 0x00000000 0x0000000e 0x00000001>;
                                        fsl,data-mapping = "spwg";
                                        fsl,data-width = <0x00000012>;
                                        display-timings {
                                                native-mode = <0x0000000f>;
                                                hsd100pxn1 {
clock-frequency = <0x03dfd240>;
                                                        hactive = <0x00000400>;
                                                        vactive = <0x00000300>;
                                                        hback-porch =

<0x000000dc>;
hfront-porch =
<0x00000028>;
vback-porch =
<0x00000015>;
vfront-porch =
<0x00000007>;
hsync-len =
<0x0000003c>;
vsync-len =
<0x0000000a>;
linux,phandle

= <0x0000000f>;
                                                        phandle = <0x0000000f>;
                                                };
                                        };
                                };
                        };
                        dcic at 020e4000 {
                                reg = <0x020e4000 0x00004000>;
                                interrupts = <0x00000000 0x0000007c 0x00000004>;
                        };
                        dcic at 020e8000 {
                                reg = <0x020e8000 0x00004000>;
                                interrupts = <0x00000000 0x0000007d 0x00000004>;
                        };
                        sdma at 020ec000 {
                                compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
                                reg = <0x020ec000 0x00004000>;
                                interrupts = <0x00000000 0x00000002 0x00000004>;
                                clocks = <0x00000002 0x0000009b
0x00000002 0x0000009b>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <0x00000003>;
                                fsl,sdma-ram-script-name =
"imx/sdma/sdma-imx6q.bin";
                                linux,phandle = <0x00000006>;
                                phandle = <0x00000006>;
                        };
                };
                aips-bus at 02100000 {
                        compatible = "fsl,aips-bus", "simple-bus";
                        #address-cells = <0x00000001>;
                        #size-cells = <0x00000001>;
                        reg = <0x02100000 0x00100000>;
                        ranges;
                        caam at 02100000 {
                                reg = <0x02100000 0x00040000>;
                                interrupts = <0x00000000 0x00000069
0x00000004 0x00000000 0x0000006a 0x00000004>;
                        };
                        aipstz at 0217c000 {
                                reg = <0x0217c000 0x00004000>;
                        };
                        usb at 02184000 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184000 0x00000200>;
                                interrupts = <0x00000000 0x0000002b 0x00000004>;
                                clocks = <0x00000002 0x000000a2>;
                                fsl,usbphy = <0x00000010>;
                                fsl,usbmisc = <0x00000011 0x00000000>;
                                status = "okay";
                                vbus-supply = <0x00000012>;
                                pinctrl-names = "default";
                                pinctrl-0 = <0x00000013>;
                                disable-over-current;
                        };
                        usb at 02184200 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184200 0x00000200>;
                                interrupts = <0x00000000 0x00000028 0x00000004>;
                                clocks = <0x00000002 0x000000a2>;
                                fsl,usbphy = <0x00000014>;
                                fsl,usbmisc = <0x00000011 0x00000001>;
                                status = "okay";
                                vbus-supply = <0x00000015>;
                        };
                        usb at 02184400 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184400 0x00000200>;
                                interrupts = <0x00000000 0x00000029 0x00000004>;
                                clocks = <0x00000002 0x000000a2>;
                                fsl,usbmisc = <0x00000011 0x00000002>;
                                status = "disabled";
                        };
                        usb at 02184600 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184600 0x00000200>;
                                interrupts = <0x00000000 0x0000002a 0x00000004>;
                                clocks = <0x00000002 0x000000a2>;
                                fsl,usbmisc = <0x00000011 0x00000003>;
                                status = "disabled";
                        };
                        usbmisc at 02184800 {
                                #index-cells = <0x00000001>;
                                compatible = "fsl,imx6q-usbmisc";
                                reg = <0x02184800 0x00000200>;
                                clocks = <0x00000002 0x000000a2>;
                                linux,phandle = <0x00000011>;
                                phandle = <0x00000011>;
                        };
                        ethernet at 02188000 {
                                compatible = "fsl,imx6q-fec";
                                reg = <0x02188000 0x00004000>;
                                interrupts = <0x00000000 0x00000076
0x00000004 0x00000000 0x00000077 0x00000004>;
                                clocks = <0x00000002 0x00000075
0x00000002 0x00000075 0x00000002 0x000000be>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <0x00000016>;
                                phy-mode = "rgmii";
                                phy-reset-gpios = <0x00000005
0x0000001e 0x00000000>;
                        };
                        mlb at 0218c000 {
                                reg = <0x0218c000 0x00004000>;
                                interrupts = <0x00000000 0x00000035
0x00000004 0x00000000 0x00000075 0x00000004 0x00000000 0x0000007e
0x00000004>;
                        };
                        usdhc at 02190000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02190000 0x00004000>;
                                interrupts = <0x00000000 0x00000016 0x00000004>;
                                clocks = <0x00000002 0x000000a3
0x00000002 0x000000a3 0x00000002 0x000000a3>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <0x00000004>;
                                status = "disabled";
                        };
                        usdhc at 02194000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02194000 0x00004000>;
                                interrupts = <0x00000000 0x00000017 0x00000004>;
                                clocks = <0x00000002 0x000000a4
0x00000002 0x000000a4 0x00000002 0x000000a4>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <0x00000004>;
                                status = "disabled";
                        };
                        usdhc at 02198000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02198000 0x00004000>;
                                interrupts = <0x00000000 0x00000018 0x00000004>;
                                clocks = <0x00000002 0x000000a5
0x00000002 0x000000a5 0x00000002 0x000000a5>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <0x00000004>;
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <0x00000017>;
                                cd-gpios = <0x00000018 0x00000000 0x00000000>;
                                vmmc-supply = <0x00000019>;
                        };
                        usdhc at 0219c000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x0219c000 0x00004000>;
                                interrupts = <0x00000000 0x00000019 0x00000004>;
                                clocks = <0x00000002 0x000000a6
0x00000002 0x000000a6 0x00000002 0x000000a6>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <0x00000004>;
                                status = "disabled";
                        };
                        i2c at 021a0000 {
                                #address-cells = <0x00000001>;
                                #size-cells = <0x00000000>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a0000 0x00004000>;
                                interrupts = <0x00000000 0x00000024 0x00000004>;
                                clocks = <0x00000002 0x0000007d>;
                                status = "okay";
                                clock-frequency = <0x000186a0>;
                                pinctrl-names = "default";
                                pinctrl-0 = <0x0000001a>;
                                eeprom at 50 {
                                        compatible = "atmel,24c02";
                                        reg = <0x00000050>;
                                        pagesize = <0x00000010>;
                                };
                                eeprom at 51 {
                                        compatible = "atmel,24c02";
                                        reg = <0x00000051>;
                                        pagesize = <0x00000010>;
                                };
                                eeprom at 52 {
                                        compatible = "atmel,24c02";
                                        reg = <0x00000052>;
                                        pagesize = <0x00000010>;
                                };
                                eeprom at 53 {
                                        compatible = "atmel,24c02";
                                        reg = <0x00000053>;
                                        pagesize = <0x00000010>;
                                };
                                pca9555 at 23 {
                                        compatible = "nxp,pca9555";
                                        reg = <0x00000023>;
                                        gpio-controller;
                                        #gpio-cells = <0x00000002>;
                                };
                                gsc at 29 {
                                        compatible = "gw,gsp";
                                        reg = <0x00000029>;
                                };
                                ds1672 at 68 {
                                        compatible = "dallas,ds1672";
                                        reg = <0x00000068>;
                                };
                        };
                        i2c at 021a4000 {
                                #address-cells = <0x00000001>;
                                #size-cells = <0x00000000>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a4000 0x00004000>;
                                interrupts = <0x00000000 0x00000025 0x00000004>;
                                clocks = <0x00000002 0x0000007e>;
                                status = "okay";
                                clock-frequency = <0x000186a0>;
                                pinctrl-names = "default";
                                pinctrl-0 = <0x0000001b>;
                                pfuze100 at 08 {
                                        compatible = "fsl,pfuze100";
                                        reg = <0x00000008>;
                                        regulators {
                                                sw1ab {

regulator-min-microvolt = <0x000493e0>;

regulator-max-microvolt = <0x001c9c38>;
                                                        regulator-boot-on;
                                                        regulator-always-on;
regulator-ramp-delay = <0x0000186a>;
                                                };
                                                sw1c {

regulator-min-microvolt = <0x000493e0>;

regulator-max-microvolt = <0x001c9c38>;
                                                        regulator-boot-on;
                                                        regulator-always-on;
regulator-ramp-delay = <0x0000186a>;
                                                };
                                                sw2 {

regulator-min-microvolt = "", "5";

regulator-max-microvolt = <0x003c45b0>;
                                                        regulator-boot-on;
                                                        regulator-always-on;
                                                };
                                                sw3a {

regulator-min-microvolt = <0x00061a80>;

regulator-max-microvolt = <0x001e22d8>;
                                                        regulator-boot-on;
                                                        regulator-always-on;
                                                };
                                                sw3b {

regulator-min-microvolt = <0x00061a80>;

regulator-max-microvolt = <0x001e22d8>;
                                                        regulator-boot-on;
                                                        regulator-always-on;
                                                };
                                                sw4 {

regulator-min-microvolt = "", "5";

regulator-max-microvolt = <0x00325aa0>;
linux,phandle

= <0x0000001d>;
                                                        phandle = <0x0000001d>;
                                                };
                                                swbst {

regulator-min-microvolt = <0x004c4b40>;

regulator-max-microvolt = <0x004e9530>;
                                                };
                                                vsnvs {

regulator-min-microvolt = <0x000f4240>;

regulator-max-microvolt = <0x002dc6c0>;
                                                        regulator-boot-on;
                                                        regulator-always-on;
                                                };
                                                vrefddr {
                                                        regulator-boot-on;
                                                        regulator-always-on;
                                                };
                                                vgen1 {

regulator-min-microvolt = "", "5";

regulator-max-microvolt = <0x0017a6b0>;
                                                };
                                                vgen2 {

regulator-min-microvolt = "", "5";

regulator-max-microvolt = <0x0017a6b0>;
                                                };
                                                vgen3 {

regulator-min-microvolt = <0x001b7740>;

regulator-max-microvolt = <0x00325aa0>;
                                                };
                                                vgen4 {

regulator-min-microvolt = <0x001b7740>;

regulator-max-microvolt = <0x00325aa0>;
                                                        regulator-always-on;
                                                };
                                                vgen5 {

regulator-min-microvolt = <0x001b7740>;

regulator-max-microvolt = <0x00325aa0>;
                                                        regulator-always-on;
                                                };
                                                vgen6 {

regulator-min-microvolt = <0x001b7740>;

regulator-max-microvolt = <0x00325aa0>;
                                                        regulator-always-on;
                                                };
                                        };
                                };
                                pex8609 at 3f {
                                        compatible = "plx,pex8609";
                                        reg = <0x0000003f>;
                                };
                                si52147 at 6b {
                                        compatible = "sil,si52147";
                                        reg = <0x0000006b>;
                                };
                        };
                        i2c at 021a8000 {
                                #address-cells = <0x00000001>;
                                #size-cells = <0x00000000>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a8000 0x00004000>;
                                interrupts = <0x00000000 0x00000026 0x00000004>;
                                clocks = <0x00000002 0x0000007f>;
                                status = "okay";
                                clock-frequency = <0x000186a0>;
                                pinctrl-names = "default";
                                pinctrl-0 = <0x0000001c>;
                                fxos8700 at 1e {
                                        compatible = "fsl,fxos8700";
                                        reg = <0x0000001e>;
                                };
                                sgtl5000 at 0a {
                                        compatible = "fsl,sgtl5000";
                                        reg = <0x0000000a>;
                                        clocks = <0x00000002 0x000000c9>;
                                        VDDA-supply = <0x0000001d>;
                                        VDDIO-supply = <0x00000019>;
                                        linux,phandle = <0x00000029>;
                                        phandle = <0x00000029>;
                                };
                                adv7611 at 4c {
                                        compatible = "adi,adv7611";
                                        reg = <0x0000004c>;
                                };
                                egalax_ts at 04 {
                                        compatible = "eeti,egalax_ts";
                                        reg = <0x00000004>;
                                        interrupt-parent = <0x00000018>;
                                        interrupts = <0x0000000c 0x00000002>;
                                        wakeup-gpios = <0x00000018
0x0000000c 0x00000000>;
                                };
                                adv7393 at 2a {
                                        compatible = "adi,adv7393";
                                        reg = <0x0000002a>;
                                };
                                adv7180 at 20 {
                                        compatible = "adi,adv7180";
                                        reg = <0x00000020>;
                                };
                        };
                        romcp at 021ac000 {
                                reg = <0x021ac000 0x00004000>;
                        };
                        mmdc at 021b0000 {
                                compatible = "fsl,imx6q-mmdc";
                                reg = <0x021b0000 0x00004000>;
                        };
                        mmdc at 021b4000 {
                                reg = <0x021b4000 0x00004000>;
                        };
                        weim at 021b8000 {
                                compatible = "fsl,imx6q-weim";
                                reg = <0x021b8000 0x00004000>;
                                interrupts = <0x00000000 0x0000000e 0x00000004>;
                                clocks = <0x00000002 0x000000c4>;
                        };
                        ocotp at 021bc000 {
                                compatible = "fsl,imx6q-ocotp", "syscon";
                                reg = <0x021bc000 0x00004000>;
                                linux,phandle = <0x0000000a>;
                                phandle = <0x0000000a>;
                        };
                        tzasc at 021d0000 {
                                reg = <0x021d0000 0x00004000>;
                                interrupts = <0x00000000 0x0000006c 0x00000004>;
                        };
                        tzasc at 021d4000 {
                                reg = <0x021d4000 0x00004000>;
                                interrupts = <0x00000000 0x0000006d 0x00000004>;
                        };
                        audmux at 021d8000 {
                                compatible = "fsl,imx6q-audmux",
"fsl,imx31-audmux";
                                reg = <0x021d8000 0x00004000>;
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <0x0000001e>;
                        };
                        mipi at 021dc000 {
                                reg = <0x021dc000 0x00004000>;
                        };
                        mipi at 021e0000 {
                                reg = <0x021e0000 0x00004000>;
                        };
                        vdoa at 021e4000 {
                                reg = <0x021e4000 0x00004000>;
                                interrupts = <0x00000000 0x00000012 0x00000004>;
                        };
                        serial at 021e8000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021e8000 0x00004000>;
                                interrupts = <0x00000000 0x0000001b 0x00000004>;
                                clocks = <0x00000002 0x000000a0
0x00000002 0x000000a1>;
                                clock-names = "ipg", "per";
                                dmas = <0x00000006 0x0000001b
0x00000004 0x00000000 0x00000006 0x0000001c 0x00000004 0x00000000>;
                                dma-names = "rx", "tx";
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <0x0000001f>;
                        };
                        serial at 021f4000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021f4000 0x00004000>;
                                interrupts = <0x00000000 0x0000001e 0x00000004>;
                                clocks = <0x00000002 0x000000a0
0x00000002 0x000000a1>;
                                clock-names = "ipg", "per";
                                dmas = <0x00000006 0x00000021
0x00000004 0x00000000 0x00000006 0x00000022 0x00000004 0x00000000>;
                                dma-names = "rx", "tx";
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <0x00000020>;
                        };
                };
                ipu at 02400000 {
                        #crtc-cells = <0x00000001>;
                        compatible = "fsl,imx6q-ipu";
                        reg = <0x02400000 0x00400000>;
                        interrupts = <0x00000000 0x00000006 0x00000004
0x00000000 0x00000005 0x00000004>;
                        clocks = <0x00000002 0x00000082 0x00000002
0x00000083 0x00000002 0x00000084>;
                        clock-names = "bus", "di0", "di1";
                        resets = <0x00000021 0x00000002>;
                        linux,phandle = <0x0000000d>;
                        phandle = <0x0000000d>;
                };
                sram at 00900000 {
                        compatible = "mmio-sram";
                        reg = <0x00900000 0x00040000>;
                        clocks = <0x00000002 0x0000008e>;
                };
                sata at 02200000 {
                        compatible = "fsl,imx6q-ahci";
                        reg = <0x02200000 0x00004000>;
                        interrupts = <0x00000000 0x00000027 0x00000004>;
                        clocks = <0x00000002 0x0000009a 0x00000002
0x000000bb 0x00000002 0x00000069>;
                        clock-names = "sata", "sata_ref", "ahb";
                        status = "okay";
                };
                ipu at 02800000 {
                        #crtc-cells = <0x00000001>;
                        compatible = "fsl,imx6q-ipu";
                        reg = <0x02800000 0x00400000>;
                        interrupts = <0x00000000 0x00000008 0x00000004
0x00000000 0x00000007 0x00000004>;
                        clocks = <0x00000002 0x00000085 0x00000002
0x00000086 0x00000002 0x00000089>;
                        clock-names = "bus", "di0", "di1";
                        resets = <0x00000021 0x00000004>;
                        linux,phandle = <0x0000000e>;
                        phandle = <0x0000000e>;
                };
        };
        cpus {
                #address-cells = <0x00000001>;
                #size-cells = <0x00000000>;
                cpu at 0 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <0x00000000>;
                        next-level-cache = <0x00000022>;
                        operating-points = <0x00124f80 0x00137478
0x000f32a0 0x001312d0 0x000c15c0 0x00118c30 0x00060ae0 0x000e7ef0>;
                        clock-latency = <0x0000ee6c>;
                        clocks = <0x00000002 0x00000068 0x00000002
0x00000006 0x00000002 0x00000010 0x00000002 0x00000011 0x00000002
0x000000aa>;
                        clock-names = "arm", "pll2_pfd2_396m", "step",
"pll1_sw", "pll1_sys";
                        arm-supply = <0x00000023>;
                        pu-supply = <0x00000024>;
                        soc-supply = <0x00000025>;
                };
                cpu at 1 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <0x00000001>;
                        next-level-cache = <0x00000022>;
                };
                cpu at 2 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <0x00000002>;
                        next-level-cache = <0x00000022>;
                };
                cpu at 3 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <0x00000003>;
                        next-level-cache = <0x00000022>;
                };
        };
        leds {
                compatible = "gpio-leds";
                user1 {
                        label = "user1";
                        gpios = <0x00000026 0x00000006 0x00000000>;
                        default-state = "on";
                        linux,default-trigger = "heartbeat";
                };
                user2 {
                        label = "user2";
                        gpios = <0x00000026 0x00000007 0x00000000>;
                        default-state = "off";
                };
                user3 {
                        label = "user3";
                        gpios = <0x00000026 0x0000000f 0x00000001>;
                        default-state = "off";
                };
        };
        pps {
                compatible = "pps-gpio";
                gpios = <0x00000005 0x0000001a 0x00000000>;
                status = "okay";
        };
        regulators {
                compatible = "simple-bus";
                1p0v {
                        compatible = "regulator-fixed";
                        regulator-name = "1P0V";
                        regulator-min-microvolt = <0x000f4240>;
                        regulator-max-microvolt = <0x000f4240>;
                        regulator-always-on;
                };
                3p3v {
                        compatible = "regulator-fixed";
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <0x00325aa0>;
                        regulator-max-microvolt = <0x00325aa0>;
                        regulator-always-on;
                        linux,phandle = <0x00000019>;
                        phandle = <0x00000019>;
                };
                usb_h1_vbus {
                        compatible = "regulator-fixed";
                        regulator-name = "usb_h1_vbus";
                        regulator-min-microvolt = <0x004c4b40>;
                        regulator-max-microvolt = <0x004c4b40>;
                        regulator-always-on;
                        linux,phandle = <0x00000015>;
                        phandle = <0x00000015>;
                };
                usb_otg_vbus {
                        compatible = "regulator-fixed";
                        regulator-name = "usb_otg_vbus";
                        regulator-min-microvolt = <0x004c4b40>;
                        regulator-max-microvolt = <0x004c4b40>;
                        gpio = <0x00000027 0x00000016 0x00000000>;
                        enable-active-high;
                        linux,phandle = <0x00000012>;
                        phandle = <0x00000012>;
                };
        };
        sound {
                compatible = "fsl,imx6q-sabrelite-sgtl5000",
"fsl,imx-audio-sgtl5000";
                model = "imx6q-sabrelite-sgtl5000";
                ssi-controller = <0x00000028>;
                audio-codec = <0x00000029>;
                audio-routing = "MIC_IN", "Mic Jack", "Mic Jack", "Mic
Bias", "Headphone Jack", "HP_OUT";
                mux-int-port = <0x00000001>;
                mux-ext-port = <0x00000004>;
        };
};

Tim

Quoted 2 lines

Jason

#27 lore raw

cover PCI irq mapping fixes and cleanups

In reply to Tim Harvey
Quoted 4 lines · Tim Harvey
Quoted 3 lines · Jingoo Han
Quoted 2 lines · Jason Gunthorpe

On Fri, Feb 28, 2014 at 04:53:33PM -0800, Tim Harvey wrote:

<snip>

Quoted 39 lines

The configuration I'm testing is:
root at OpenWrt:/# lspci -n
00:00.0 0604: 16c3:abcd (rev 01)
01:00.0 0604: 10b5:8609 (rev ba)
01:00.1 0880: 10b5:8609 (rev ba)
02:01.0 0604: 10b5:8609 (rev ba)
02:04.0 0604: 10b5:8609 (rev ba)
02:05.0 0604: 10b5:8609 (rev ba)
02:06.0 0604: 10b5:8609 (rev ba)
02:07.0 0604: 10b5:8609 (rev ba)
02:08.0 0604: 10b5:8609 (rev ba)
02:09.0 0604: 10b5:8609 (rev ba)
07:00.0 0280: 168c:002b (rev 01)
08:00.0 0200: 11ab:4380
root at OpenWrt:/# lspci -tnv -[0000:00]---00.0-[01-09]--+-00.0-[02-09]--+-01.0-[03]--

                           |               +-04.0-[04]--
                           |               +-05.0-[05]--
                           |               +-06.0-[06]--
                           |               +-07.0-[07]----00.0  168c:002b
                           |               +-08.0-[08]----00.0  11ab:4380
                           |               \-09.0-[09]--
                           \-00.1  10b5:8609

The dev_info showing what of_irq_parse_and_map_pci() above produces:

[    1.818485] pci 0000:00:00.0: dw_pcie_map_irq: 16c3:abcd slot0 pin1 irq20
[    1.818703] pci 0000:01:00.0: dw_pcie_map_irq: 10b5:8609 slot0 pin1 irq20
[    1.818939] pci 0000:01:00.1: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.819179] pci 0000:02:01.0: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.819395] pci 0000:02:04.0: dw_pcie_map_irq: 10b5:8609 slot0 pin1 irq20
[    1.819631] pci 0000:02:05.0: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.819859] pci 0000:02:06.0: dw_pcie_map_irq: 10b5:8609 slot0 pin3 irq0
[    1.820087] pci 0000:02:07.0: dw_pcie_map_irq: 10b5:8609 slot0 pin4 irq0
[    1.820404] pci 0000:02:08.0: dw_pcie_map_irq: 10b5:8609 slot0 pin1 irq20
[    1.820650] pci 0000:02:09.0: dw_pcie_map_irq: 10b5:8609 slot0 pin2 irq0
[    1.820881] pci 0000:07:00.0: dw_pcie_map_irq: 168c:002b slot0 pin4 irq0
[    1.821100] pci 0000:08:00.0: dw_pcie_map_irq: 11ab:4380 slot0 pin1 irq20
Quoted 4 lines

I'm not clear why irq 20 is getting returned for all the slots with (slot%4)=0 and func=0. If I start debugging of_irq_parse_pci() I see that it walks up the tree until it gets to the pcie host controller then calls of_irq_parse_raw() which is returning irq20 or -EINVAL.

For the slots above that are swizzling to pin1 this appears to be an issue with irq_create_of_mapping() called form of_irq_parse_and_map_pci(). The GIC function that translates the interrupt per domain is given irq_data: 0x123 0x04 0x00 (meaning GIC IRQ 123, which should get 32 added to it for irq155). Instead, the implementation of gic_irq_domain_xlate()
(http://lxr.missinglinkelectronics.com/linux/drivers/irqchip/irq-gic.c#L832)
adds 32 to the 0x04 returning 20:

[    1.841781] of_irq_parse_raw:  /soc/pcie at 0x01000000:00000001
[    1.841813] of_irq_parse_raw: ipar=/soc/pcie at 0x01000000, size=1
[    1.841838]  -> addrsize=3
[    1.841870]  -> match=1 (imaplen=28)
[    1.841903]  -> newintsize=3, newaddrsize=1
[    1.841916]  -> imaplen=23
[    1.841928]  -> new parent: /interrupt-controller at 00a01000
[    1.841946]  -> got it !
[    1.841972] irq_create_of_mapping: calling xlate for 123/4/0 3
[    1.841984] irq_create_of_mapping got irq from xlate: 20
^^^^^ added debugging shows 3 u32's passed to xlate and returned value of 20
[    1.841998] irq: irq_create_mapping(0xbec10400, 0x14)
[    1.842009] irq: -> using domain @bec10400
[    1.842021] irq: -> existing mapping on virq 20
[    1.842032] irq_create_of_mapping created virq=20
[    1.842042] irq_create_of_mapping returning virq=20
[    1.842059] pci 0000:00:00.0: dw_pcie_map_irq: 16c3:abcd slot0 pin1 irq20

Perhaps this is a byte-ordering issue? I'm wondering if the args created in of_irq_parse_pci are getting put in the wrong place for what irq_create_of_mapping() expects.

For the slots above that swizzle to pin2,3,4 of_irq_parse_raw() returns -EINVAL because for some reason it can't match an interrupt mapping for the pcie host controller:

[    1.842996] of_irq_parse_raw:  /soc/pcie at 0x01000000/pcie at 0,0:00000002
[    1.843046] of_irq_parse_raw: ipar=/soc/pcie at 0x01000000, size=1
[    1.843070]  -> addrsize=3
[    1.843100]  -> match=0 (imaplen=28)

^^^^^ indicates no match in interrupt map.

I think this is because size=1 above, when we should see an interrupt-map of size 4. I'm guessing that the function is confused between the single interrupt in the DT for the host controller, vs the interrupt-map for the PCI interrupts.

At this point, with no match, of_irq_parse_raw() will travel up to the parent of the interrupt which is wrong.

Note the pcie host controller DT is:

    pcie: pcie at 0x01000000 {
      compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
      reg = <0x01ffc000 0x4000>; /* DBI */
      #address-cells = <3>;
      #size-cells = <2>;
      device_type = "pci";
      ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000 /*
configuration space */
          0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
          0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /*
non-prefetchable memory */
      num-lanes = <1>;

      interrupts = <0 123 0x04>;

      #interrupt-cells = <1>;
      interrupt-map-mask = <0 0 0 0x7>;
      interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;

      clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
      clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
      status = "disabled";
    };

Tim

Quoted 22 lines

Tim

Quoted 19 lines

You can test i.MX PCIe with this.

./drivers/pci/host/pcie-designware.c

drivers/pci/host/pcie-designware.c +1 -1
@@ -726,7 +727,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 
        if (pp) {
                pp->root_bus_nr = sys->busnr;
-               bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+               bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
                                        sys, &sys->resources);
        } else {
                bus = NULL;

However, I think that we may need to replace 'pci_common_init()' with 'pci_common_init_dev()'.

Best regards,
Jingoo Han

#28 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 2 lines · Tim Harvey

of_irq_parse_and_map_pci(). The GIC function that translates the interrupt per domain is given irq_data: 0x123 0x04 0x00

This has been shifted by 1 byte..

Quoted 8 lines

IRQ 123, which should get 32 added to it for irq155). Instead, the implementation of gic_irq_domain_xlate()
(http://lxr.missinglinkelectronics.com/linux/drivers/irqchip/irq-gic.c#L832)
adds 32 to the 0x04 returning 20:

[    1.841781] of_irq_parse_raw:  /soc/pcie at 0x01000000:00000001
[    1.841813] of_irq_parse_raw: ipar=/soc/pcie at 0x01000000, size=1
[    1.841838]  -> addrsize=3
[    1.841870]  -> match=1 (imaplen=28)
                              ^^^^^^^^^^^^^

That looks odd, it should be the number of dwords in the interrupt-map, you have 4 lines of 8 dwords each, so it should be 32.

You have 7*4, which really suggests to me that your interrupt-map is corrupted somehow, are you sure you are using this:

Quoted 4 lines
      interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;

If an element was missing it would explain why everything is broken, in fact if GIC_SPI was missing it would match the debug perfectly.

Quoted 4 lines
[    1.841903]  -> newintsize=3, newaddrsize=1
[    1.841916]  -> imaplen=23
[    1.841928]  -> new parent: /interrupt-controller at 00a01000
[    1.841946]  -> got it !

K..

Quoted 1 line
[    1.841972] irq_create_of_mapping: calling xlate for 123/4/0 3

And it is the wrong data.. 123/4/0 is

Quoted 8 lines

For the slots above that swizzle to pin2,3,4 of_irq_parse_raw() returns -EINVAL because for some reason it can't match an interrupt mapping for the pcie host controller:

[    1.842996] of_irq_parse_raw:  /soc/pcie at 0x01000000/pcie at 0,0:00000002
[    1.843046] of_irq_parse_raw: ipar=/soc/pcie at 0x01000000, size=1
[    1.843070]  -> addrsize=3
[    1.843100]  -> match=0 (imaplen=28)

^^^^^ indicates no match in interrupt map.

Well, since we know the map is corrupted somehow, it isn't surprising that the 2nd entry won't match anything. It is probably matching against '0 0 2 &intc'

Jason

#29 lore raw

cover PCI irq mapping fixes and cleanups

Quoted 15 lines · Jason Gunthorpe
Quoted 2 lines · Tim Harvey

of_irq_parse_and_map_pci(). The GIC function that translates the interrupt per domain is given irq_data: 0x123 0x04 0x00

This has been shifted by 1 byte..

Quoted 8 lines

IRQ 123, which should get 32 added to it for irq155). Instead, the implementation of gic_irq_domain_xlate()
(http://lxr.missinglinkelectronics.com/linux/drivers/irqchip/irq-gic.c#L832)
adds 32 to the 0x04 returning 20:

[    1.841781] of_irq_parse_raw:  /soc/pcie at 0x01000000:00000001
[    1.841813] of_irq_parse_raw: ipar=/soc/pcie at 0x01000000, size=1
[    1.841838]  -> addrsize=3
[    1.841870]  -> match=1 (imaplen=28)
Quoted 5 lines
                              ^^^^^^^^^^^^^

That looks odd, it should be the number of dwords in the interrupt-map, you have 4 lines of 8 dwords each, so it should be 32.

(+cc Grant Likely)

imaplen does indeed get initialized to 32 (size of interrupt-map / sizeof(u32)) but its printed above after its been decremented in the loop which is misleading
(http://lxr.missinglinkelectronics.com/linux/drivers/of/irq.c#L201)

The issue appears to me to be a bug in of_irq_parse_raw() which has been around since Graht's original commit:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/of/irq.c?id=7dc2e1134a22dc242175d5321c0c9e97d16eb87b

drivers/of/irq.c +3 -3
index 9bcf2cf..8829197 100644
@@ -237,11 +237,11 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle
                        /* Check for malformed properties */
                        if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)
                                goto fail;
-                       if (imaplen < (newaddrsize + newintsize))
+                       if (imaplen < newintsize)
                                goto fail;
 
-                       imap += newaddrsize + newintsize;
-                       imaplen -= newaddrsize + newintsize;
+                       imap += newintsize;
+                       imaplen -= newintsize;
 
                        pr_debug(" -> imaplen=%d\n", imaplen);
                }

The issue is that the interrupt-map table point (imap) needs to be incremented over the parent unit interrupt specifier which is newintsize cells, not newaddrsize + newintsize cells. The invalid calculation would cause the pointer to get mis-aligned and thus only the first interrupt entry would ever get properly checked for a match.

It looks like of_irq_parse_raw() is only called from of_irq_parse_pci() which prior to Lucas' patch was only called from pci_read_irq_line() called from pcibios_setup_device() used in arch/arm/powerpc, so perhaps this function isn't widely used explaining why the bug was never caught.

I'll post a patch shortly with the above fix.

<snip>

Quoted 3 lines
Quoted 1 line
[    1.841972] irq_create_of_mapping: calling xlate for 123/4/0 3

And it is the wrong data.. 123/4/0 is

right - this is shifted because of the issue above.

With the above patch Lucas' original patch now operates correctly to resolve the 4 legacy PCI interrupts required when using a P2P bridge on the IMX6.

Tim