diff options
Diffstat (limited to 'target/linux')
13 files changed, 1187 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.4/0239-ARM-dts-ls1021a-add-PCIe-dts-node.patch b/target/linux/layerscape/patches-4.4/0239-ARM-dts-ls1021a-add-PCIe-dts-node.patch new file mode 100644 index 0000000000..c267297258 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/0239-ARM-dts-ls1021a-add-PCIe-dts-node.patch @@ -0,0 +1,73 @@ +From 1f58043afef0dca3d12dc23ac3a35d7074412939 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 2 Feb 2016 16:30:07 +0800 +Subject: [PATCH 01/13] ARM: dts: ls1021a: add PCIe dts node + +Cherry-pick upstream patch. + +LS1021a contains two PCIe controllers. The patch adds their node to +dts file. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm/boot/dts/ls1021a.dtsi | 44 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi +index 9430a99..38272d0 100644 +--- a/arch/arm/boot/dts/ls1021a.dtsi ++++ b/arch/arm/boot/dts/ls1021a.dtsi +@@ -539,5 +539,49 @@ + dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; + }; ++ ++ pcie@3400000 { ++ compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; ++ reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ ++ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ ++ reg-names = "regs", "config"; ++ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ ++ fsl,pcie-scfg = <&scfg 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ num-lanes = <4>; ++ bus-range = <0x0 0xff>; ++ ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ ++ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ pcie@3500000 { ++ compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; ++ reg = <0x00 0x03500000 0x0 0x00010000 /* controller registers */ ++ 0x48 0x00000000 0x0 0x00002000>; /* configuration space */ ++ reg-names = "regs", "config"; ++ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>; ++ fsl,pcie-scfg = <&scfg 1>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ num-lanes = <4>; ++ bus-range = <0x0 0xff>; ++ ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ ++ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0000 0 0 1 &gic GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 2 &gic GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 3 &gic GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 4 &gic GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; ++ }; + }; + }; +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/0240-ARM-dts-ls1021a-add-SCFG-MSI-dts-node.patch b/target/linux/layerscape/patches-4.4/0240-ARM-dts-ls1021a-add-SCFG-MSI-dts-node.patch new file mode 100644 index 0000000000..760ea004a7 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/0240-ARM-dts-ls1021a-add-SCFG-MSI-dts-node.patch @@ -0,0 +1,61 @@ +From b57dcab78fdc76a6c56c2df71518fb022429e244 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Wed, 6 Apr 2016 19:02:07 +0800 +Subject: [PATCH 02/13] ARM: dts: ls1021a: add SCFG MSI dts node + +Cherry-pick upstream patch. + +Add SCFG MSI dts node and add msi-parent property to PCIe dts node +that points to the corresponding MSI node. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Tested-by: Alexander Stein <alexander.stein@systec-electronic.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm/boot/dts/ls1021a.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi +index 38272d0..527f653 100644 +--- a/arch/arm/boot/dts/ls1021a.dtsi ++++ b/arch/arm/boot/dts/ls1021a.dtsi +@@ -119,6 +119,20 @@ + + }; + ++ msi1: msi-controller@1570e00 { ++ compatible = "fsl,1s1021a-msi"; ++ reg = <0x0 0x1570e00 0x0 0x8>; ++ msi-controller; ++ interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ msi2: msi-controller@1570e08 { ++ compatible = "fsl,1s1021a-msi"; ++ reg = <0x0 0x1570e08 0x0 0x8>; ++ msi-controller; ++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ + ifc: ifc@1530000 { + compatible = "fsl,ifc", "simple-bus"; + reg = <0x0 0x1530000 0x0 0x10000>; +@@ -554,6 +568,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ ++ msi-parent = <&msi1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, +@@ -576,6 +591,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ ++ msi-parent = <&msi2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/0241-dt-bindings-Add-bindings-for-Layerscape-SCFG-MSI.patch b/target/linux/layerscape/patches-4.4/0241-dt-bindings-Add-bindings-for-Layerscape-SCFG-MSI.patch new file mode 100644 index 0000000000..8f7ae19a7a --- /dev/null +++ b/target/linux/layerscape/patches-4.4/0241-dt-bindings-Add-bindings-for-Layerscape-SCFG-MSI.patch @@ -0,0 +1,59 @@ +From 066320dd0643e66bc5afe0d0984e77b2e938a6f4 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Wed, 23 Mar 2016 19:08:19 +0800 +Subject: [PATCH 03/13] dt/bindings: Add bindings for Layerscape SCFG MSI + +Cherry-pick upstream patch. + +Some Layerscape SoCs use a simple MSI controller implementation. +It contains only two SCFG register to trigger and describe a +group 32 MSI interrupts. The patch adds bindings to describe +the controller. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + .../interrupt-controller/fsl,ls-scfg-msi.txt | 30 ++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt + +diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt +new file mode 100644 +index 0000000..9e38949 +--- /dev/null ++++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt +@@ -0,0 +1,30 @@ ++* Freescale Layerscape SCFG PCIe MSI controller ++ ++Required properties: ++ ++- compatible: should be "fsl,<soc-name>-msi" to identify ++ Layerscape PCIe MSI controller block such as: ++ "fsl,1s1021a-msi" ++ "fsl,1s1043a-msi" ++- msi-controller: indicates that this is a PCIe MSI controller node ++- reg: physical base address of the controller and length of memory mapped. ++- interrupts: an interrupt to the parent interrupt controller. ++ ++Optional properties: ++- interrupt-parent: the phandle to the parent interrupt controller. ++ ++This interrupt controller hardware is a second level interrupt controller that ++is hooked to a parent interrupt controller: e.g: ARM GIC for ARM-based ++platforms. If interrupt-parent is not provided, the default parent interrupt ++controller will be used. ++Each PCIe node needs to have property msi-parent that points to ++MSI controller node ++ ++Examples: ++ ++ msi1: msi-controller@1571000 { ++ compatible = "fsl,1s1043a-msi"; ++ reg = <0x0 0x1571000 0x0 0x8>, ++ msi-controller; ++ interrupts = <0 116 0x4>; ++ }; +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/3229-arm-dts-ls1021a-fix-typo-of-MSI-compatible-string.patch b/target/linux/layerscape/patches-4.4/3229-arm-dts-ls1021a-fix-typo-of-MSI-compatible-string.patch new file mode 100644 index 0000000000..270568d54b --- /dev/null +++ b/target/linux/layerscape/patches-4.4/3229-arm-dts-ls1021a-fix-typo-of-MSI-compatible-string.patch @@ -0,0 +1,40 @@ +From 2c39dc6c100854ed9d617bab9a25557adb6f531a Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:36 +0800 +Subject: [PATCH 05/13] arm: dts: ls1021a: fix typo of MSI compatible string + +Cherry-pick patchwork patch. + +"1" should be replaced by "l". This is a typo. +The patch is to fix it. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm/boot/dts/ls1021a.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi +index 527f653..a2a3e8e 100644 +--- a/arch/arm/boot/dts/ls1021a.dtsi ++++ b/arch/arm/boot/dts/ls1021a.dtsi +@@ -120,14 +120,14 @@ + }; + + msi1: msi-controller@1570e00 { +- compatible = "fsl,1s1021a-msi"; ++ compatible = "fsl,ls1021a-msi"; + reg = <0x0 0x1570e00 0x0 0x8>; + msi-controller; + interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>; + }; + + msi2: msi-controller@1570e08 { +- compatible = "fsl,1s1021a-msi"; ++ compatible = "fsl,ls1021a-msi"; + reg = <0x0 0x1570e08 0x0 0x8>; + msi-controller; + interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/3230-arm64-dts-ls1043a-fix-typo-of-MSI-compatible-string.patch b/target/linux/layerscape/patches-4.4/3230-arm64-dts-ls1043a-fix-typo-of-MSI-compatible-string.patch new file mode 100644 index 0000000000..569adda7a1 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/3230-arm64-dts-ls1043a-fix-typo-of-MSI-compatible-string.patch @@ -0,0 +1,50 @@ +From 56ff33e848d1a9b77f81e0d3b5ee0b79edcd4938 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Thu, 16 Feb 2017 17:52:08 +0800 +Subject: [PATCH 06/13] arm64: dts: ls1043a: fix typo of MSI compatible string + +Cherry-pick patchwork patch with context adjustment. + +"1" should be replaced by "l". This is a typo. +The patch is to fix it. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +index ae13e68..e51a6cb 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +@@ -991,7 +991,7 @@ + }; + + msi1: msi-controller1@1571000 { +- compatible = "fsl,1s1043a-msi"; ++ compatible = "fsl,ls1043a-msi"; + reg = <0x0 0x1571000 0x0 0x4>, + <0x0 0x1571004 0x0 0x4>; + reg-names = "msiir", "msir"; +@@ -1000,7 +1000,7 @@ + }; + + msi2: msi-controller2@1572000 { +- compatible = "fsl,1s1043a-msi"; ++ compatible = "fsl,ls1043a-msi"; + reg = <0x0 0x1572000 0x0 0x4>, + <0x0 0x1572004 0x0 0x4>; + reg-names = "msiir", "msir"; +@@ -1009,7 +1009,7 @@ + }; + + msi3: msi-controller3@1573000 { +- compatible = "fsl,1s1043a-msi"; ++ compatible = "fsl,ls1043a-msi"; + reg = <0x0 0x1573000 0x0 0x4>, + <0x0 0x1573004 0x0 0x4>; + reg-names = "msiir", "msir"; +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/3231-arm-dts-ls1021a-share-all-MSIs.patch b/target/linux/layerscape/patches-4.4/3231-arm-dts-ls1021a-share-all-MSIs.patch new file mode 100644 index 0000000000..828022f1a7 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/3231-arm-dts-ls1021a-share-all-MSIs.patch @@ -0,0 +1,42 @@ +From 190ae222ef6ded27021620afdc3f5a36861d3625 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:38 +0800 +Subject: [PATCH 07/13] arm: dts: ls1021a: share all MSIs + +Cherry-pick patchwork patch. + +In order to maximize the use of MSI, a PCIe controller will share +all MSI controllers. The patch changes msi-parent to refer to all +MSI controller dts nodes. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm/boot/dts/ls1021a.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi +index a2a3e8e..bf4ffeb 100644 +--- a/arch/arm/boot/dts/ls1021a.dtsi ++++ b/arch/arm/boot/dts/ls1021a.dtsi +@@ -568,7 +568,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi1>; ++ msi-parent = <&msi1>, <&msi2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, +@@ -591,7 +591,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi2>; ++ msi-parent = <&msi1>, <&msi2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/3232-arm64-dts-ls1043a-share-all-MSIs.patch b/target/linux/layerscape/patches-4.4/3232-arm64-dts-ls1043a-share-all-MSIs.patch new file mode 100644 index 0000000000..11cc1f87aa --- /dev/null +++ b/target/linux/layerscape/patches-4.4/3232-arm64-dts-ls1043a-share-all-MSIs.patch @@ -0,0 +1,51 @@ +From 60eedf7a9512683e2a8a998863cc5942e9dbdae5 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:39 +0800 +Subject: [PATCH 08/13] arm64: dts: ls1043a: share all MSIs + +Cherry-pick patchwork patch. + +In order to maximize the use of MSI, a PCIe controller will share +all MSI controllers. The patch changes "msi-parent" to refer to all +MSI controller dts nodes. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +index e51a6cb..92d18c5 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +@@ -1033,7 +1033,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi1>; ++ msi-parent = <&msi1>, <&msi2>, <&msi3>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 110 0x4>, +@@ -1058,7 +1058,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi2>; ++ msi-parent = <&msi1>, <&msi2>, <&msi3>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 120 0x4>, +@@ -1083,7 +1083,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi3>; ++ msi-parent = <&msi1>, <&msi2>, <&msi3>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 154 0x4>, +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/3233-arm64-dts-ls1046a-update-MSI-dts-node.patch b/target/linux/layerscape/patches-4.4/3233-arm64-dts-ls1046a-update-MSI-dts-node.patch new file mode 100644 index 0000000000..3bfcd297b2 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/3233-arm64-dts-ls1046a-update-MSI-dts-node.patch @@ -0,0 +1,118 @@ +From 1569c166572f9576c6726472b5a726a1a56900bd Mon Sep 17 00:00:00 2001 +From: Yangbo Lu <yangbo.lu@nxp.com> +Date: Thu, 16 Feb 2017 18:00:14 +0800 +Subject: [PATCH] arm64: dts: ls1046a: update MSI dts node + +Update MSI dts node according to below patchwork patch. + +arm64: dts: ls1046a: add MSI dts node +https://patchwork.kernel.org/patch/9520299 + +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 58 +++++++++++++------------- + 1 file changed, 30 insertions(+), 28 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +index 179c38b..f96be34 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +@@ -44,6 +44,8 @@ + * OTHER DEALINGS IN THE SOFTWARE. + */ + ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++ + / { + compatible = "fsl,ls1046a"; + interrupt-parent = <&gic>; +@@ -870,34 +872,34 @@ + big-endian; + }; + +- msi: msi-controller@1580000 { ++ msi1: msi-controller@1580000 { + compatible = "fsl,ls1046a-msi"; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; + msi-controller; ++ reg = <0x0 0x1580000 0x0 0x10000>; ++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; ++ }; + +- msi-bank@1580000 { +- reg = <0x0 0x1580000 0x0 0x10000>; +- interrupts = <0 116 0x4>, +- <0 111 0x4>, +- <0 112 0x4>, +- <0 113 0x4>; +- }; +- msi-bank@1590000 { +- reg = <0x0 0x1590000 0x0 0x10000>; +- interrupts = <0 126 0x4>, +- <0 121 0x4>, +- <0 122 0x4>, +- <0 123 0x4>; +- }; +- msi-bank@15a0000 { +- reg = <0x0 0x15a0000 0x0 0x10000>; +- interrupts = <0 160 0x4>, +- <0 155 0x4>, +- <0 156 0x4>, +- <0 157 0x4>; +- }; ++ msi2: msi-controller@1590000 { ++ compatible = "fsl,ls1046a-msi"; ++ msi-controller; ++ reg = <0x0 0x1590000 0x0 0x10000>; ++ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ msi3: msi-controller@15a0000 { ++ compatible = "fsl,ls1046a-msi"; ++ msi-controller; ++ reg = <0x0 0x15a0000 0x0 0x10000>; ++ interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; + }; + + pcie@3400000 { +@@ -916,7 +918,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi>; ++ msi-parent = <&msi1>, <&msi2>, <&msi3>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 110 0x4>, +@@ -941,7 +943,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi>; ++ msi-parent = <&msi1>, <&msi2>, <&msi3>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 120 0x4>, +@@ -966,7 +968,7 @@ + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ +- msi-parent = <&msi>; ++ msi-parent = <&msi1>, <&msi2>, <&msi3>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 154 0x4>, +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/3234-dts-ls1043a-change-GIC-register-for-rev1.1.patch b/target/linux/layerscape/patches-4.4/3234-dts-ls1043a-change-GIC-register-for-rev1.1.patch new file mode 100644 index 0000000000..2a11e72035 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/3234-dts-ls1043a-change-GIC-register-for-rev1.1.patch @@ -0,0 +1,37 @@ +From 118d9d4b959d30a582d4bd26d1a1918a43ea0ddf Mon Sep 17 00:00:00 2001 +From: Gong Qianyu <Qianyu.Gong@nxp.com> +Date: Wed, 7 Sep 2016 18:33:09 +0800 +Subject: [PATCH 13/13] dts: ls1043a: change GIC register for rev1.1 + +Cherry-pick sdk patch. + +Signed-off-by: Gong Qianyu <Qianyu.Gong@nxp.com> +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Mingkai Hu <mingkai.hu@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +index 92d18c5..3257c69 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +@@ -141,10 +141,10 @@ + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + interrupt-controller; +- reg = <0x0 0x1401000 0 0x1000>, /* GICD */ +- <0x0 0x1402000 0 0x2000>, /* GICC */ +- <0x0 0x1404000 0 0x2000>, /* GICH */ +- <0x0 0x1406000 0 0x2000>; /* GICV */ ++ reg = <0x0 0x1410000 0 0x10000>, /* GICD */ ++ <0x0 0x1420000 0 0x20000>, /* GICC */ ++ <0x0 0x1440000 0 0x20000>, /* GICH */ ++ <0x0 0x1460000 0 0x20000>; /* GICV */ + interrupts = <1 9 0xf08>; + }; + +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/8238-irqchip-ls-scfg-msi-fix-typo-of-MSI-compatible-strin.patch b/target/linux/layerscape/patches-4.4/8238-irqchip-ls-scfg-msi-fix-typo-of-MSI-compatible-strin.patch new file mode 100644 index 0000000000..c5dad9c490 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/8238-irqchip-ls-scfg-msi-fix-typo-of-MSI-compatible-strin.patch @@ -0,0 +1,62 @@ +From 5cb8ea9dfcea4092fd3710cce3980a44433dc58f Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:35 +0800 +Subject: [PATCH 04/13] irqchip/ls-scfg-msi: fix typo of MSI compatible strings + +Cherry-pick patchwork patch with context adjustment. + +The patch is to fix typo of the Layerscape SCFG MSI dts compatible +strings. "1" is replaced by "l". + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + .../devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt | 6 +++--- + drivers/irqchip/irq-ls-scfg-msi.c | 6 ++++-- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt +index 9e38949..2755cd1 100644 +--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt ++++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt +@@ -4,8 +4,8 @@ Required properties: + + - compatible: should be "fsl,<soc-name>-msi" to identify + Layerscape PCIe MSI controller block such as: +- "fsl,1s1021a-msi" +- "fsl,1s1043a-msi" ++ "fsl,ls1021a-msi" ++ "fsl,ls1043a-msi" + - msi-controller: indicates that this is a PCIe MSI controller node + - reg: physical base address of the controller and length of memory mapped. + - interrupts: an interrupt to the parent interrupt controller. +@@ -23,7 +23,7 @@ MSI controller node + Examples: + + msi1: msi-controller@1571000 { +- compatible = "fsl,1s1043a-msi"; ++ compatible = "fsl,ls1043a-msi"; + reg = <0x0 0x1571000 0x0 0x8>, + msi-controller; + interrupts = <0 116 0x4>; +diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c +index 47520fa..5b16f4a 100644 +--- a/drivers/irqchip/irq-ls-scfg-msi.c ++++ b/drivers/irqchip/irq-ls-scfg-msi.c +@@ -220,8 +220,10 @@ static int ls_scfg_msi_remove(struct platform_device *pdev) + + static const struct of_device_id ls_scfg_msi_id[] = { + { .compatible = "fsl,ls1012a-msi", }, +- { .compatible = "fsl,1s1021a-msi", }, +- { .compatible = "fsl,1s1043a-msi", }, ++ { .compatible = "fsl,1s1021a-msi", }, /* a typo */ ++ { .compatible = "fsl,1s1043a-msi", }, /* a typo */ ++ { .compatible = "fsl,ls1021a-msi", }, ++ { .compatible = "fsl,ls1043a-msi", }, + { .compatible = "fsl,ls1046a-msi", }, + {}, + }; +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/8239-irqchip-ls-scfg-msi-add-LS1046a-MSI-support.patch b/target/linux/layerscape/patches-4.4/8239-irqchip-ls-scfg-msi-add-LS1046a-MSI-support.patch new file mode 100644 index 0000000000..1a1c288db1 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/8239-irqchip-ls-scfg-msi-add-LS1046a-MSI-support.patch @@ -0,0 +1,298 @@ +From 20fd0e76257005cb46a2ce1a30018a45d96199bf Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:41 +0800 +Subject: [PATCH 10/13] irqchip/ls-scfg-msi: add LS1046a MSI support + +Cherry-pick patchwork patch with context adjustment. + +LS1046a includes 4 MSIRs, each MSIR is assigned a dedicate GIC +SPI interrupt and provides 32 MSI interrupts. Compared to previous +MSI, LS1046a's IBS(interrupt bit select) shift is changed to 2 and +total MSI interrupt number is changed to 128. + +The patch adds structure 'ls_scfg_msir' to describe MSIR setting and +'ibs_shift' to store the different value between the SoCs. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + drivers/irqchip/irq-ls-scfg-msi.c | 168 +++++++++++++++++++++++++++++--------- + 1 file changed, 131 insertions(+), 37 deletions(-) + +diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c +index 5b16f4a..6586076 100644 +--- a/drivers/irqchip/irq-ls-scfg-msi.c ++++ b/drivers/irqchip/irq-ls-scfg-msi.c +@@ -17,13 +17,24 @@ + #include <linux/irq.h> + #include <linux/irqchip/chained_irq.h> + #include <linux/irqdomain.h> ++#include <linux/of_irq.h> + #include <linux/of_pci.h> + #include <linux/of_platform.h> + #include <linux/spinlock.h> + +-#define MSI_MAX_IRQS 32 +-#define MSI_IBS_SHIFT 3 +-#define MSIR 4 ++#define MSI_IRQS_PER_MSIR 32 ++#define MSI_MSIR_OFFSET 4 ++ ++struct ls_scfg_msi_cfg { ++ u32 ibs_shift; /* Shift of interrupt bit select */ ++}; ++ ++struct ls_scfg_msir { ++ struct ls_scfg_msi *msi_data; ++ unsigned int index; ++ unsigned int gic_irq; ++ void __iomem *reg; ++}; + + struct ls_scfg_msi { + spinlock_t lock; +@@ -32,8 +43,11 @@ struct ls_scfg_msi { + struct irq_domain *msi_domain; + void __iomem *regs; + phys_addr_t msiir_addr; +- int irq; +- DECLARE_BITMAP(used, MSI_MAX_IRQS); ++ struct ls_scfg_msi_cfg *cfg; ++ u32 msir_num; ++ struct ls_scfg_msir *msir; ++ u32 irqs_num; ++ unsigned long *used; + }; + + static struct irq_chip ls_scfg_msi_irq_chip = { +@@ -55,7 +69,7 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) + + msg->address_hi = upper_32_bits(msi_data->msiir_addr); + msg->address_lo = lower_32_bits(msi_data->msiir_addr); +- msg->data = data->hwirq << MSI_IBS_SHIFT; ++ msg->data = data->hwirq; + } + + static int ls_scfg_msi_set_affinity(struct irq_data *irq_data, +@@ -81,8 +95,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain, + WARN_ON(nr_irqs != 1); + + spin_lock(&msi_data->lock); +- pos = find_first_zero_bit(msi_data->used, MSI_MAX_IRQS); +- if (pos < MSI_MAX_IRQS) ++ pos = find_first_zero_bit(msi_data->used, msi_data->irqs_num); ++ if (pos < msi_data->irqs_num) + __set_bit(pos, msi_data->used); + else + err = -ENOSPC; +@@ -106,7 +120,7 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain, + int pos; + + pos = d->hwirq; +- if (pos < 0 || pos >= MSI_MAX_IRQS) { ++ if (pos < 0 || pos >= msi_data->irqs_num) { + pr_err("failed to teardown msi. Invalid hwirq %d\n", pos); + return; + } +@@ -123,15 +137,17 @@ static const struct irq_domain_ops ls_scfg_msi_domain_ops = { + + static void ls_scfg_msi_irq_handler(struct irq_desc *desc) + { +- struct ls_scfg_msi *msi_data = irq_desc_get_handler_data(desc); ++ struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc); ++ struct ls_scfg_msi *msi_data = msir->msi_data; + unsigned long val; +- int pos, virq; ++ int pos, virq, hwirq; + + chained_irq_enter(irq_desc_get_chip(desc), desc); + +- val = ioread32be(msi_data->regs + MSIR); +- for_each_set_bit(pos, &val, MSI_MAX_IRQS) { +- virq = irq_find_mapping(msi_data->parent, (31 - pos)); ++ val = ioread32be(msir->reg); ++ for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) { ++ hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index; ++ virq = irq_find_mapping(msi_data->parent, hwirq); + if (virq) + generic_handle_irq(virq); + } +@@ -143,7 +159,7 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data) + { + /* Initialize MSI domain parent */ + msi_data->parent = irq_domain_add_linear(NULL, +- MSI_MAX_IRQS, ++ msi_data->irqs_num, + &ls_scfg_msi_domain_ops, + msi_data); + if (!msi_data->parent) { +@@ -164,16 +180,88 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data) + return 0; + } + ++static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index) ++{ ++ struct ls_scfg_msir *msir; ++ int virq, i, hwirq; ++ ++ virq = platform_get_irq(msi_data->pdev, index); ++ if (virq <= 0) ++ return -ENODEV; ++ ++ msir = &msi_data->msir[index]; ++ msir->index = index; ++ msir->msi_data = msi_data; ++ msir->gic_irq = virq; ++ msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index; ++ ++ irq_set_chained_handler_and_data(msir->gic_irq, ++ ls_scfg_msi_irq_handler, ++ msir); ++ ++ /* Release the hwirqs corresponding to this MSIR */ ++ for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { ++ hwirq = i << msi_data->cfg->ibs_shift | msir->index; ++ bitmap_clear(msi_data->used, hwirq, 1); ++ } ++ ++ return 0; ++} ++ ++static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir) ++{ ++ struct ls_scfg_msi *msi_data = msir->msi_data; ++ int i, hwirq; ++ ++ if (msir->gic_irq > 0) ++ irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL); ++ ++ for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { ++ hwirq = i << msi_data->cfg->ibs_shift | msir->index; ++ bitmap_set(msi_data->used, hwirq, 1); ++ } ++ ++ return 0; ++} ++ ++static struct ls_scfg_msi_cfg ls1021_msi_cfg = { ++ .ibs_shift = 3, ++}; ++ ++static struct ls_scfg_msi_cfg ls1046_msi_cfg = { ++ .ibs_shift = 2, ++}; ++ ++static const struct of_device_id ls_scfg_msi_id[] = { ++ /* The following two misspelled compatibles are obsolete */ ++ { .compatible = "fsl,1s1021a-msi", .data = &ls1021_msi_cfg}, ++ { .compatible = "fsl,1s1043a-msi", .data = &ls1021_msi_cfg}, ++ ++ { .compatible = "fsl,ls1012a-msi", .data = &ls1021_msi_cfg }, ++ { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, ++ { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, ++ { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ls_scfg_msi_id); ++ + static int ls_scfg_msi_probe(struct platform_device *pdev) + { ++ const struct of_device_id *match; + struct ls_scfg_msi *msi_data; + struct resource *res; +- int ret; ++ int i, ret; ++ ++ match = of_match_device(ls_scfg_msi_id, &pdev->dev); ++ if (!match) ++ return -ENODEV; + + msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data), GFP_KERNEL); + if (!msi_data) + return -ENOMEM; + ++ msi_data->cfg = (struct ls_scfg_msi_cfg *) match->data; ++ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + msi_data->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(msi_data->regs)) { +@@ -182,23 +270,37 @@ static int ls_scfg_msi_probe(struct platform_device *pdev) + } + msi_data->msiir_addr = res->start; + +- msi_data->irq = platform_get_irq(pdev, 0); +- if (msi_data->irq <= 0) { +- dev_err(&pdev->dev, "failed to get MSI irq\n"); +- return -ENODEV; +- } +- + msi_data->pdev = pdev; + spin_lock_init(&msi_data->lock); + ++ msi_data->irqs_num = MSI_IRQS_PER_MSIR * ++ (1 << msi_data->cfg->ibs_shift); ++ msi_data->used = devm_kcalloc(&pdev->dev, ++ BITS_TO_LONGS(msi_data->irqs_num), ++ sizeof(*msi_data->used), ++ GFP_KERNEL); ++ if (!msi_data->used) ++ return -ENOMEM; ++ /* ++ * Reserve all the hwirqs ++ * The available hwirqs will be released in ls1_msi_setup_hwirq() ++ */ ++ bitmap_set(msi_data->used, 0, msi_data->irqs_num); ++ ++ msi_data->msir_num = of_irq_count(pdev->dev.of_node); ++ msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num, ++ sizeof(*msi_data->msir), ++ GFP_KERNEL); ++ if (!msi_data->msir) ++ return -ENOMEM; ++ ++ for (i = 0; i < msi_data->msir_num; i++) ++ ls_scfg_msi_setup_hwirq(msi_data, i); ++ + ret = ls_scfg_msi_domains_init(msi_data); + if (ret) + return ret; + +- irq_set_chained_handler_and_data(msi_data->irq, +- ls_scfg_msi_irq_handler, +- msi_data); +- + platform_set_drvdata(pdev, msi_data); + + return 0; +@@ -207,8 +309,10 @@ static int ls_scfg_msi_probe(struct platform_device *pdev) + static int ls_scfg_msi_remove(struct platform_device *pdev) + { + struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev); ++ int i; + +- irq_set_chained_handler_and_data(msi_data->irq, NULL, NULL); ++ for (i = 0; i < msi_data->msir_num; i++) ++ ls_scfg_msi_teardown_hwirq(&msi_data->msir[i]); + + irq_domain_remove(msi_data->msi_domain); + irq_domain_remove(msi_data->parent); +@@ -218,16 +322,6 @@ static int ls_scfg_msi_remove(struct platform_device *pdev) + return 0; + } + +-static const struct of_device_id ls_scfg_msi_id[] = { +- { .compatible = "fsl,ls1012a-msi", }, +- { .compatible = "fsl,1s1021a-msi", }, /* a typo */ +- { .compatible = "fsl,1s1043a-msi", }, /* a typo */ +- { .compatible = "fsl,ls1021a-msi", }, +- { .compatible = "fsl,ls1043a-msi", }, +- { .compatible = "fsl,ls1046a-msi", }, +- {}, +-}; +- + static struct platform_driver ls_scfg_msi_driver = { + .driver = { + .name = "ls-scfg-msi", +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch b/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch new file mode 100644 index 0000000000..02fc020338 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch @@ -0,0 +1,139 @@ +From ab9d5c5c767c17bf9526f84beb5667f2a50e1a4d Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:42 +0800 +Subject: [PATCH] irqchip/ls-scfg-msi: add LS1043a v1.1 MSI support + +Cherry-pick patchwork patch with context adjustment. + +A MSI controller of LS1043a v1.0 only includes one MSIR and +is assigned one GIC interrupt. In order to support affinity, +LS1043a v1.1 MSI is assigned 4 MSIRs and 4 GIC interrupts. +But the MSIR has the different offset and only supports 8 MSIs. +The bits between variable bit_start and bit_end in structure +ls_scfg_msir are used to show 8 MSI interrupts. msir_irqs and +msir_base are added to describe the difference of MSI between +LS1043a v1.1 and other SoCs. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + drivers/irqchip/irq-ls-scfg-msi.c | 45 +++++++++++++++++++++++++++++++++------ + 1 file changed, 39 insertions(+), 6 deletions(-) + +diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c +index 6586076..71a2050 100644 +--- a/drivers/irqchip/irq-ls-scfg-msi.c ++++ b/drivers/irqchip/irq-ls-scfg-msi.c +@@ -25,14 +25,21 @@ + #define MSI_IRQS_PER_MSIR 32 + #define MSI_MSIR_OFFSET 4 + ++#define MSI_LS1043V1_1_IRQS_PER_MSIR 8 ++#define MSI_LS1043V1_1_MSIR_OFFSET 0x10 ++ + struct ls_scfg_msi_cfg { + u32 ibs_shift; /* Shift of interrupt bit select */ ++ u32 msir_irqs; /* The irq number per MSIR */ ++ u32 msir_base; /* The base address of MSIR */ + }; + + struct ls_scfg_msir { + struct ls_scfg_msi *msi_data; + unsigned int index; + unsigned int gic_irq; ++ unsigned int bit_start; ++ unsigned int bit_end; + void __iomem *reg; + }; + +@@ -140,13 +147,18 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc) + struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc); + struct ls_scfg_msi *msi_data = msir->msi_data; + unsigned long val; +- int pos, virq, hwirq; ++ int pos, size, virq, hwirq; + + chained_irq_enter(irq_desc_get_chip(desc), desc); + + val = ioread32be(msir->reg); +- for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) { +- hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index; ++ ++ pos = msir->bit_start; ++ size = msir->bit_end + 1; ++ ++ for_each_set_bit_from(pos, &val, size) { ++ hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) | ++ msir->index; + virq = irq_find_mapping(msi_data->parent, hwirq); + if (virq) + generic_handle_irq(virq); +@@ -193,14 +205,24 @@ static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index) + msir->index = index; + msir->msi_data = msi_data; + msir->gic_irq = virq; +- msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index; ++ msir->reg = msi_data->regs + msi_data->cfg->msir_base + 4 * index; ++ ++ if (msi_data->cfg->msir_irqs == MSI_LS1043V1_1_IRQS_PER_MSIR) { ++ msir->bit_start = 32 - ((msir->index + 1) * ++ MSI_LS1043V1_1_IRQS_PER_MSIR); ++ msir->bit_end = msir->bit_start + ++ MSI_LS1043V1_1_IRQS_PER_MSIR - 1; ++ } else { ++ msir->bit_start = 0; ++ msir->bit_end = msi_data->cfg->msir_irqs - 1; ++ } + + irq_set_chained_handler_and_data(msir->gic_irq, + ls_scfg_msi_irq_handler, + msir); + + /* Release the hwirqs corresponding to this MSIR */ +- for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { ++ for (i = 0; i < msi_data->cfg->msir_irqs; i++) { + hwirq = i << msi_data->cfg->ibs_shift | msir->index; + bitmap_clear(msi_data->used, hwirq, 1); + } +@@ -216,7 +238,7 @@ static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir) + if (msir->gic_irq > 0) + irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL); + +- for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { ++ for (i = 0; i < msi_data->cfg->msir_irqs; i++) { + hwirq = i << msi_data->cfg->ibs_shift | msir->index; + bitmap_set(msi_data->used, hwirq, 1); + } +@@ -226,10 +248,20 @@ static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir) + + static struct ls_scfg_msi_cfg ls1021_msi_cfg = { + .ibs_shift = 3, ++ .msir_irqs = MSI_IRQS_PER_MSIR, ++ .msir_base = MSI_MSIR_OFFSET, + }; + + static struct ls_scfg_msi_cfg ls1046_msi_cfg = { + .ibs_shift = 2, ++ .msir_irqs = MSI_IRQS_PER_MSIR, ++ .msir_base = MSI_MSIR_OFFSET, ++}; ++ ++static struct ls_scfg_msi_cfg ls1043_v1_1_msi_cfg = { ++ .ibs_shift = 2, ++ .msir_irqs = MSI_LS1043V1_1_IRQS_PER_MSIR, ++ .msir_base = MSI_LS1043V1_1_MSIR_OFFSET, + }; + + static const struct of_device_id ls_scfg_msi_id[] = { +@@ -240,6 +272,7 @@ static const struct of_device_id ls_scfg_msi_id[] = { + { .compatible = "fsl,ls1012a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, ++ { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg }, + { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg }, + {}, + }; +-- +2.1.0.27.g96db324 + diff --git a/target/linux/layerscape/patches-4.4/8241-irqchip-ls-scfg-msi-add-MSI-affinity-support.patch b/target/linux/layerscape/patches-4.4/8241-irqchip-ls-scfg-msi-add-MSI-affinity-support.patch new file mode 100644 index 0000000000..dbaef7a652 --- /dev/null +++ b/target/linux/layerscape/patches-4.4/8241-irqchip-ls-scfg-msi-add-MSI-affinity-support.patch @@ -0,0 +1,157 @@ +From a761ae710d6395af0d8d17a0b4b8f93a816ead46 Mon Sep 17 00:00:00 2001 +From: Minghuan Lian <Minghuan.Lian@nxp.com> +Date: Tue, 17 Jan 2017 17:32:43 +0800 +Subject: [PATCH 12/13] irqchip/ls-scfg-msi: add MSI affinity support + +Cherry-pick patchwork patch. + +For LS1046a and LS1043a v1.1, the MSI controller has 4 MSIRs and 4 GIC +SPI interrupts which can be associated with different Core. +So we can support affinity to improve the performance. +The MSI message data is a byte for Layerscape MSI. + 7 6 5 4 3 2 1 0 +| - | IBS | SRS | +SRS bit0-1 is to select a MSIR which is associated with a CPU. +IBS bit2-6 of ls1046, bit2-4 of ls1043a v1.1 is to select bit of the +MSIR. With affinity, only bits of MSIR0(srs=0 cpu0) are available. +All other bits of the MSIR1-3(cpu1-3) are reserved. The MSI hwirq +always equals bit index of the MSIR0. When changing affinity, MSI +message data will be appended corresponding SRS then MSI will be +moved to the corresponding core. +But in affinity mode, there is only 8 MSI interrupts for a controller +of LS1043a v1.1. It cannot meet the requirement of the some PCIe +devices such as 4 ports Ethernet card. In contrast, without affinity, +all MSIRs can be used for core 0, the MSI interrupts can up to 32. +So the parameter is added to control affinity mode. +"lsmsi=no-affinity" will disable affinity and increase MSI +interrupt number. + +Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com> +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +--- + drivers/irqchip/irq-ls-scfg-msi.c | 68 ++++++++++++++++++++++++++++++++++++--- + 1 file changed, 63 insertions(+), 5 deletions(-) + +diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c +index 71a2050..57e3d90 100644 +--- a/drivers/irqchip/irq-ls-scfg-msi.c ++++ b/drivers/irqchip/irq-ls-scfg-msi.c +@@ -40,6 +40,7 @@ struct ls_scfg_msir { + unsigned int gic_irq; + unsigned int bit_start; + unsigned int bit_end; ++ unsigned int srs; /* Shared interrupt register select */ + void __iomem *reg; + }; + +@@ -70,6 +71,19 @@ static struct msi_domain_info ls_scfg_msi_domain_info = { + .chip = &ls_scfg_msi_irq_chip, + }; + ++static int msi_affinity_flag = 1; ++ ++static int __init early_parse_ls_scfg_msi(char *p) ++{ ++ if (p && strncmp(p, "no-affinity", 11) == 0) ++ msi_affinity_flag = 0; ++ else ++ msi_affinity_flag = 1; ++ ++ return 0; ++} ++early_param("lsmsi", early_parse_ls_scfg_msi); ++ + static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) + { + struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(data); +@@ -77,12 +91,36 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) + msg->address_hi = upper_32_bits(msi_data->msiir_addr); + msg->address_lo = lower_32_bits(msi_data->msiir_addr); + msg->data = data->hwirq; ++ ++ if (msi_affinity_flag) ++ msg->data |= cpumask_first(data->common->affinity); + } + + static int ls_scfg_msi_set_affinity(struct irq_data *irq_data, + const struct cpumask *mask, bool force) + { +- return -EINVAL; ++ struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(irq_data); ++ u32 cpu; ++ ++ if (!msi_affinity_flag) ++ return -EINVAL; ++ ++ if (!force) ++ cpu = cpumask_any_and(mask, cpu_online_mask); ++ else ++ cpu = cpumask_first(mask); ++ ++ if (cpu >= msi_data->msir_num) ++ return -EINVAL; ++ ++ if (msi_data->msir[cpu].gic_irq <= 0) { ++ pr_warn("cannot bind the irq to cpu%d\n", cpu); ++ return -EINVAL; ++ } ++ ++ cpumask_copy(irq_data->common->affinity, mask); ++ ++ return IRQ_SET_MASK_OK; + } + + static struct irq_chip ls_scfg_msi_parent_chip = { +@@ -158,7 +196,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc) + + for_each_set_bit_from(pos, &val, size) { + hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) | +- msir->index; ++ msir->srs; + virq = irq_find_mapping(msi_data->parent, hwirq); + if (virq) + generic_handle_irq(virq); +@@ -221,10 +259,19 @@ static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index) + ls_scfg_msi_irq_handler, + msir); + ++ if (msi_affinity_flag) { ++ /* Associate MSIR interrupt to the cpu */ ++ irq_set_affinity(msir->gic_irq, get_cpu_mask(index)); ++ msir->srs = 0; /* This value is determined by the CPU */ ++ } else ++ msir->srs = index; ++ + /* Release the hwirqs corresponding to this MSIR */ +- for (i = 0; i < msi_data->cfg->msir_irqs; i++) { +- hwirq = i << msi_data->cfg->ibs_shift | msir->index; +- bitmap_clear(msi_data->used, hwirq, 1); ++ if (!msi_affinity_flag || msir->index == 0) { ++ for (i = 0; i < msi_data->cfg->msir_irqs; i++) { ++ hwirq = i << msi_data->cfg->ibs_shift | msir->index; ++ bitmap_clear(msi_data->used, hwirq, 1); ++ } + } + + return 0; +@@ -321,6 +368,17 @@ static int ls_scfg_msi_probe(struct platform_device *pdev) + bitmap_set(msi_data->used, 0, msi_data->irqs_num); + + msi_data->msir_num = of_irq_count(pdev->dev.of_node); ++ ++ if (msi_affinity_flag) { ++ u32 cpu_num; ++ ++ cpu_num = num_possible_cpus(); ++ if (msi_data->msir_num >= cpu_num) ++ msi_data->msir_num = cpu_num; ++ else ++ msi_affinity_flag = 0; ++ } ++ + msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num, + sizeof(*msi_data->msir), + GFP_KERNEL); +-- +2.1.0.27.g96db324 + |