* [PATCH v3 3/3] ARM: DT: add power-off support to linkstation lsgl and kuroboxpro
From: Roger Shimizu @ 2016-12-27 7:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161227070611.14852-1-rogershimizu@gmail.com>
A few models of Linkstation / KuroBox has micro-controller which
controls the power (as well as FAN, but not related here), while
others not. So remove the restart-poweroff driver in linkstation
common dtsi file, and specify the proper power driver in dts
of each device.
Devices need micro-controler to power-off:
- Linkstation LS-GL
- KuroBox Pro
Device continues using original restart-poweroff driver:
- Linkstation LS-WTGL
To: Jason Cooper <jason@lakedaemon.net>
To: Andrew Lunn <andrew@lunn.ch>
To: Gregory Clement <gregory.clement@free-electrons.com>
To: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Cc: Ryan Tandy <ryan@nardis.ca>
Cc: linux-pm at vger.kernel.org
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Reported-by: Ryan Tandy <ryan@nardis.ca>
Tested-by: Ryan Tandy <ryan@nardis.ca>
Signed-off-by: Roger Shimizu <rogershimizu@gmail.com>
---
arch/arm/boot/dts/orion5x-kuroboxpro.dts | 8 ++++++++
arch/arm/boot/dts/orion5x-linkstation-lsgl.dts | 10 ++++++++++
arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts | 4 ++++
arch/arm/boot/dts/orion5x-linkstation.dtsi | 4 ----
4 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/orion5x-kuroboxpro.dts b/arch/arm/boot/dts/orion5x-kuroboxpro.dts
index 1a672b098d0b..aba38d802bda 100644
--- a/arch/arm/boot/dts/orion5x-kuroboxpro.dts
+++ b/arch/arm/boot/dts/orion5x-kuroboxpro.dts
@@ -60,6 +60,14 @@
<MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
<MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x40000>,
<MBUS_ID(0x01, 0x1e) 0 0xfc000000 0x1000000>;
+
+ internal-regs {
+ power_off {
+ compatible = "linkstation,power-off";
+ reg = <0x12100 0x100>;
+ clocks = <&core_clk 0>;
+ };
+ };
};
memory { /* 128 MB */
diff --git a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
index 51dc734cd5b9..370fc17a6dd9 100644
--- a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
+++ b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
@@ -56,6 +56,16 @@
model = "Buffalo Linkstation Pro/Live";
compatible = "buffalo,lsgl", "marvell,orion5x-88f5182", "marvell,orion5x";
+ soc {
+ internal-regs {
+ power_off {
+ compatible = "linkstation,power-off";
+ reg = <0x12100 0x100>;
+ clocks = <&core_clk 0>;
+ };
+ };
+ };
+
memory { /* 128 MB */
device_type = "memory";
reg = <0x00000000 0x8000000>;
diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
index 0eead400f427..571a71f5b7ad 100644
--- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
+++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
@@ -59,6 +59,10 @@
reg = <0x00000000 0x4000000>;
};
+ restart_poweroff {
+ compatible = "restart-poweroff";
+ };
+
gpio_keys {
power-on-switch {
gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/orion5x-linkstation.dtsi b/arch/arm/boot/dts/orion5x-linkstation.dtsi
index ed456ab35fd8..40770a8d4b36 100644
--- a/arch/arm/boot/dts/orion5x-linkstation.dtsi
+++ b/arch/arm/boot/dts/orion5x-linkstation.dtsi
@@ -57,10 +57,6 @@
<MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x40000>;
};
- restart_poweroff {
- compatible = "restart-poweroff";
- };
-
regulators {
compatible = "simple-bus";
#address-cells = <1>;
--
2.11.0
^ permalink raw reply related
* [PATCH 0/9] Runtime PM for Exynos pin controller driver
From: Marek Szyprowski @ 2016-12-27 8:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANAwSgRQuoriU923XT1B_0CVX2rzOR+8j2YHLMYRUu3gGySEBw@mail.gmail.com>
Hi Anand,
On 2016-12-24 11:10, Anand Moon wrote:
> Hi Marek
>
> On 23 December 2016 at 17:54, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> Hello,
>>
>> This patchset is a next step to add support for audio power domain on
>> Exynos5 SoCs.
>>
>> Audio power domain on Exynos5 SoCs contains following hardware modules:
>> 1. clock controller
>> 2. pin controller
>> 3. PL330 DMA controller
>> 4. I2S audio controller
>>
>> Till now it was assumed that pin controller is located in the "always on"
>> power domain and lacked runtime power management. This patch finally
>> removes such assumption and adds runtime pm support and awareness to this
>> driver. To achieve this, some changes in the Exynos platform support code
>> were needed, like moving pad retention control to the pin controller driver.
>> Some cleanup to the pin controller driver has been also done while changing
>> the code. This new feature requires some additional information in the
>> device tree, what is handled by patches 1,2 and 9.
>>
>> Please note that patches are ordered in such a way that the changes can be
>> bisected, so the properties are added to dts before the code requiring them.
>>
>> The other patches related to enabling full support for audio power domain
>> can be found here:
>> 1. PL330 ADMA controller non-irqsafe runtime PM:
>> https://www.spinics.net/lists/arm-kernel/msg550008.html
>> 2. Runtime PM for clock controllers (Exynos Audio subsystem will be added
>> in v4 soon): https://www.spinics.net/lists/arm-kernel/msg538122.html
>>
>> Patches are based on linux-next from 2016.12.22.
>>
>> Best regards
>> Marek Szyprowski
>> Samsung R&D Institute Poland
>>
>>
>> Patch summary:
>>
>> Marek Szyprowski (9):
>> ARM: dts: exynos: Add PMU syscon to pinctrl nodes
>> ARM: dts: exynos: Add pinctrl sleep state for 542x i2s module
>> pinctrl: samsung: Remove dead code
>> pinctrl: samsung: Use generic of_device_get_match_data helper
>> pinctrl: samsung: Move retention control from mach-exynos to the
>> pinctrl driver
>> pinctrl: samsung: Replace syscore ops with standard platform device
>> pm_ops
>> pinctrl: samsung: Add property to mark pad state as suitable for power
>> down
>> pinctrl: samsung: Add runtime PM support
>> ARM: dts: exynos: Add audio power domain support to Exynos542x SoCs
>>
>> .../bindings/pinctrl/samsung-pinctrl.txt | 12 ++
>> arch/arm/boot/dts/exynos3250.dtsi | 2 +
>> arch/arm/boot/dts/exynos4210.dtsi | 3 +
>> arch/arm/boot/dts/exynos4x12.dtsi | 3 +
>> arch/arm/boot/dts/exynos5250.dtsi | 4 +
>> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 11 ++
>> arch/arm/boot/dts/exynos5420.dtsi | 18 ++-
>> arch/arm/mach-exynos/suspend.c | 64 ---------
>> drivers/pinctrl/samsung/pinctrl-exynos.c | 148 +++++++++++++++++++++
>> drivers/pinctrl/samsung/pinctrl-samsung.c | 126 ++++++++----------
>> drivers/pinctrl/samsung/pinctrl-samsung.h | 15 +++
>> 11 files changed, 271 insertions(+), 135 deletions(-)
>>
> Is their core configuration missing to enable audio through HDMI on
> Odroid Boards.
> I could not get the sound working on Odroid XU4.
Audio support for HDMI on Exynos requires some additional code. We will take
a look at this too.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply
* [PATCH] crypto: arm/aes-neonbs - process 8 blocks in parallel if we can
From: Herbert Xu @ 2016-12-27 8:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481291246-20216-1-git-send-email-ard.biesheuvel@linaro.org>
On Fri, Dec 09, 2016 at 01:47:26PM +0000, Ard Biesheuvel wrote:
> The bit-sliced NEON implementation of AES only performs optimally if
> it can process 8 blocks of input in parallel. This is due to the nature
> of bit slicing, where the n-th bit of each byte of AES state of each input
> block is collected into NEON register 'n', for registers q0 - q7.
>
> This implies that the amount of work for the transform is fixed,
> regardless of whether we are handling just one block or 8 in parallel.
>
> So let's try a bit harder to iterate over the input in suitably sized
> chunks, by increasing the chunksize to 8 * AES_BLOCK_SIZE, and tweaking
> the loops to only process multiples of the chunk size, unless we are
> handling the last chunk in the input stream.
>
> Note that the skcipher walk API guarantees that a step in the walk never
> returns less that 'chunksize' bytes if there are at least that many bytes
> of input still available. However, it does *not* guarantee that those steps
> produce an exact multiple of the chunk size.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
I like this patch. However, I had different plans for the chunksize
attribute. It's primarily meant to be a hint to the upper layer
in case it does partial updates. It's meant to provide the minimum
number of bytes a partial update can carry without screwing up
subsequent updates.
It just happens to be the same value that we were using during
an skcipher walk.
So I think for your case we should add a new attribute, perhaps
walk_chunksize or walksize, which doesn't need to be exported to
the outside at all and can then be used by the walk interface.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH v2 2/3] crypto: arm64/chacha20 - implement NEON version based on SSE3 code
From: Herbert Xu @ 2016-12-27 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481294033-23508-3-git-send-email-ard.biesheuvel@linaro.org>
On Fri, Dec 09, 2016 at 02:33:52PM +0000, Ard Biesheuvel wrote:
>
> + .chunksize = 4 * CHACHA20_BLOCK_SIZE,
This should use a new attribute specific to the walk interface.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] crypto: arm64/aes: reimplement bit-sliced ARM/NEON implementation for arm64
From: Herbert Xu @ 2016-12-27 9:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481564758-7275-1-git-send-email-ard.biesheuvel@linaro.org>
On Mon, Dec 12, 2016 at 05:45:58PM +0000, Ard Biesheuvel wrote:
>
> + .chunksize = 8 * AES_BLOCK_SIZE,
Same comment as to the previous patches regarding chunksize.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH 1/9] irqchip/ls-scfg-msi: fix typo of MSI compatible strings
From: Minghuan Lian @ 2016-12-27 9:12 UTC (permalink / raw)
To: linux-arm-kernel
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>
---
.../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 at 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 02cca74c..cef67cc 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -219,8 +219,10 @@ static int ls_scfg_msi_remove(struct platform_device *pdev)
}
static const struct of_device_id ls_scfg_msi_id[] = {
- { .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", },
{},
};
--
1.9.1
^ permalink raw reply related
* [PATCH 2/9] arm: dts: ls1021a: fix typo of MSI compatible string
From: Minghuan Lian @ 2016-12-27 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
"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>
---
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 282d854..6651938 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -122,14 +122,14 @@
};
msi1: msi-controller at 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 at 1570e08 {
- compatible = "fsl,1s1021a-msi";
+ compatible = "fsl,ls1021a-msi";
reg = <0x0 0x1570e08 0x0 0x8>;
msi-controller;
interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
--
1.9.1
^ permalink raw reply related
* [PATCH 3/9] arm64: dts: ls1043a: fix typo of MSI compatible string
From: Minghuan Lian @ 2016-12-27 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
"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>
---
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 ec13a6e..692fc35 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -589,21 +589,21 @@
};
msi1: msi-controller1 at 1571000 {
- compatible = "fsl,1s1043a-msi";
+ compatible = "fsl,ls1043a-msi";
reg = <0x0 0x1571000 0x0 0x8>;
msi-controller;
interrupts = <0 116 0x4>;
};
msi2: msi-controller2 at 1572000 {
- compatible = "fsl,1s1043a-msi";
+ compatible = "fsl,ls1043a-msi";
reg = <0x0 0x1572000 0x0 0x8>;
msi-controller;
interrupts = <0 126 0x4>;
};
msi3: msi-controller3 at 1573000 {
- compatible = "fsl,1s1043a-msi";
+ compatible = "fsl,ls1043a-msi";
reg = <0x0 0x1573000 0x0 0x8>;
msi-controller;
interrupts = <0 160 0x4>;
--
1.9.1
^ permalink raw reply related
* [PATCH 4/9] arm: dts: ls1021a: share all MSIs
From: Minghuan Lian @ 2016-12-27 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
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>
---
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 6651938..1c82024 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -723,7 +723,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>,
@@ -746,7 +746,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>,
--
1.9.1
^ permalink raw reply related
* [PATCH 5/9] arm64: dts: ls1043a: share all MSIs
From: Minghuan Lian @ 2016-12-27 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
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>
---
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 692fc35..3947220 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -625,7 +625,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>,
@@ -650,7 +650,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>,
@@ -675,7 +675,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>,
--
1.9.1
^ permalink raw reply related
* [PATCH 6/9] arm64: dts: ls1046a: add MSI dts node
From: Minghuan Lian @ 2016-12-27 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
LS1046a includes 3 MSI controllers.
Each controller supports 128 interrupts.
Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
.../interrupt-controller/fsl,ls-scfg-msi.txt | 1 +
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 31 ++++++++++++++++++++++
2 files changed, 32 insertions(+)
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 2755cd1..54597b0 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -6,6 +6,7 @@ Required properties:
Layerscape PCIe MSI controller block such as:
"fsl,ls1021a-msi"
"fsl,ls1043a-msi"
+ "fsl,ls1046a-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.
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 38806ca..49dbafc 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -511,5 +511,36 @@
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
};
+
+ msi1: msi-controller at 1580000 {
+ compatible = "fsl,ls1046a-msi";
+ 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>;
+ };
+
+ msi2: msi-controller at 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 at 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>;
+ };
+
};
};
--
1.9.1
^ permalink raw reply related
* [PATCH 7/9] irqchip/ls-scfg-msi: add LS1046a MSI support
From: Minghuan Lian @ 2016-12-27 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
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>
---
.../interrupt-controller/fsl,ls-scfg-msi.txt | 2 +-
drivers/irqchip/irq-ls-scfg-msi.c | 161 ++++++++++++++++-----
2 files changed, 127 insertions(+), 36 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 54597b0..dde4552 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -6,7 +6,7 @@ Required properties:
Layerscape PCIe MSI controller block such as:
"fsl,ls1021a-msi"
"fsl,ls1043a-msi"
- "fsl,ls1046a-msi"
+ "fsl,ls1046a-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.
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index cef67cc..67547bd 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 void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
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,83 @@ 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[] = {
+ { .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 +265,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 +304,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,14 +317,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,1s1021a-msi", }, /* a typo */
- { .compatible = "fsl,1s1043a-msi", }, /* a typo */
- { .compatible = "fsl,ls1021a-msi", },
- { .compatible = "fsl,ls1043a-msi", },
- {},
-};
-
static struct platform_driver ls_scfg_msi_driver = {
.driver = {
.name = "ls-scfg-msi",
--
1.9.1
^ permalink raw reply related
* [PATCH 8/9] irqchip/ls-scfg-msi: add LS1043a v1.1 MSI support
From: Minghuan Lian @ 2016-12-27 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
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>
---
.../interrupt-controller/fsl,ls-scfg-msi.txt | 1 +
drivers/irqchip/irq-ls-scfg-msi.c | 45 +++++++++++++++++++---
2 files changed, 40 insertions(+), 6 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 dde4552..49ccabb 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -7,6 +7,7 @@ Required properties:
"fsl,ls1021a-msi"
"fsl,ls1043a-msi"
"fsl,ls1046a-msi"
+ "fsl,ls1043a-v1.1-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.
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 67547bd..dc19569 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,15 +248,26 @@ 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[] = {
{ .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 },
{},
};
--
1.9.1
^ permalink raw reply related
* [PATCH 9/9] irqchip/ls-scfg-msi: add MSI affinity support
From: Minghuan Lian @ 2016-12-27 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>
For LS1046a and LS1043a v1.1, the MSI controller has 4 MSIRs and 4
CPUs. A GIC SPI interrupt of MSIR can be associated with a CPU.
When changing MSI interrupt affinity, this MSI will be moved to the
corresponding MSIR and MSI message data will be changed according to
MSIR. when requesting a MSI, the bits of all 4 MSIR will be reserved.
The parameter 'msi_affinity_flag' is provide to change this mode.
"lsmsi=no-affinity" will disable affinity, all MSI can only be
associated with CPU 0.
Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
drivers/irqchip/irq-ls-scfg-msi.c | 75 ++++++++++++++++++++++++++++++++++++---
1 file changed, 70 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index dc19569..753fe39 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 @@ struct ls_scfg_msi {
.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,43 @@ 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) {
+ u32 msir_index;
+
+ msir_index = cpumask_first(data->common->affinity);
+ if (msir_index >= msi_data->msir_num)
+ msir_index = 0;
+
+ msg->data |= msir_index;
+ }
}
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 +203,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 +266,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;
@@ -316,6 +370,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);
--
1.9.1
^ permalink raw reply related
* [PATCH v2 00/12] Add basic code support for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
The i.MX 6SoloLiteLite application processors are NXP's
latest additions to a growing family of multimedia-focused
products offering high-performance processing optimized for
lowest power consumption. The i.MX 6SoloLiteLite processors
feature NXP's advanced implementation of the ARM Cortex-A9 core,
which can be interfaced with LPDDR3 and LPDDR2 DRAM memory devices.
i.MX6SLL is a new SOC of the i.MX6 family, shares many common modules,
so most of the MSL code can be resued from i.MX6 serious SOC.
change for V2:
- address comments in dts and dtsi from Fabio.
- split the doc update into two patch, fix typo.
- address comments in clock driver, add necessary 'const'qualifier.
Bai Ping (12):
ARM: imx: Add basic msl support for imx6sll
driver: clocksource: add gpt timer for imx6sll
Document: dt: binding: imx: update clock doc for imx6sll
driver: clk: imx: Add clock driver for imx6sll
Document: dt: binding: imx: update pinctrl doc for imx6sll
driver: pinctrl: imx: Add pinctrl driver support for imx6sll
ARM: dts: imx: Add basic dtsi for imx6sll
ARM: dts: imx: Add imx6sll EVK board dts support
ARM: debug: Add low level debug support for imx6sll
ARM: imx: Add suspend/resume support for imx6sll
ARM: imx: correct i.mx6sll dram io low power mode
ARM: configs: enable imx6sll support in defconfig
.../devicetree/bindings/clock/imx6sll-clock.txt | 37 +
.../bindings/pinctrl/fsl,imx6sll-pinctrl.txt | 37 +
arch/arm/Kconfig.debug | 9 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/imx6sll-evk.dts | 474 +++++++++++
arch/arm/boot/dts/imx6sll-pinfunc.h | 882 +++++++++++++++++++++
arch/arm/boot/dts/imx6sll.dtsi | 843 ++++++++++++++++++++
arch/arm/configs/imx_v6_v7_defconfig | 1 +
arch/arm/include/debug/imx-uart.h | 10 +
arch/arm/mach-imx/Kconfig | 8 +
arch/arm/mach-imx/Makefile | 1 +
arch/arm/mach-imx/cpu.c | 3 +
arch/arm/mach-imx/cpuidle-imx6sl.c | 7 +-
arch/arm/mach-imx/gpc.c | 8 +
arch/arm/mach-imx/mach-imx6sl.c | 10 +-
arch/arm/mach-imx/mxc.h | 6 +
arch/arm/mach-imx/pm-imx6.c | 49 +-
arch/arm/mach-imx/suspend-imx6.S | 29 +-
drivers/clk/imx/Makefile | 1 +
drivers/clk/imx/clk-imx6sll.c | 369 +++++++++
drivers/clocksource/timer-imx-gpt.c | 1 +
drivers/pinctrl/freescale/Kconfig | 7 +
drivers/pinctrl/freescale/Makefile | 1 +
drivers/pinctrl/freescale/pinctrl-imx6sll.c | 385 +++++++++
include/dt-bindings/clock/imx6sll-clock.h | 204 +++++
25 files changed, 3352 insertions(+), 32 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/imx6sll-clock.txt
create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
create mode 100644 arch/arm/boot/dts/imx6sll-evk.dts
create mode 100644 arch/arm/boot/dts/imx6sll-pinfunc.h
create mode 100644 arch/arm/boot/dts/imx6sll.dtsi
create mode 100644 drivers/clk/imx/clk-imx6sll.c
create mode 100644 drivers/pinctrl/freescale/pinctrl-imx6sll.c
create mode 100644 include/dt-bindings/clock/imx6sll-clock.h
--
1.9.1
^ permalink raw reply
* [PATCH v2 01/12] ARM: imx: Add basic msl support for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add basic MSL support for i.MX6SLL.
The i.MX 6SoloLiteLite application processors are NXP's latest
additions to a growing family of multimedia-focused products
offering high-performance processing optimized for lowest power
consumption. The i.MX 6SoloLiteLite processors feature NXP's advanced
implementation of the ARM Cortex-A9 core, which can be interfaced
with LPDDR3 and LPDDR2 DRAM memory devices.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
arch/arm/mach-imx/Kconfig | 7 +++++++
arch/arm/mach-imx/Makefile | 1 +
arch/arm/mach-imx/cpu.c | 3 +++
arch/arm/mach-imx/cpuidle-imx6sl.c | 7 +++++--
arch/arm/mach-imx/gpc.c | 8 ++++++++
arch/arm/mach-imx/mach-imx6sl.c | 10 ++++++++--
arch/arm/mach-imx/mxc.h | 6 ++++++
7 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 936c59d..33bcfda 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -512,6 +512,13 @@ config SOC_IMX6SL
help
This enables support for Freescale i.MX6 SoloLite processor.
+config SOC_IMX6SLL
+ bool "i.MX6 SoloLiteLite support"
+ select SOC_IMX6
+
+ help
+ This enables support for Freescale i.MX6 SoloLiteLite processor.
+
config SOC_IMX6SX
bool "i.MX6 SoloX support"
select PINCTRL_IMX6SX
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index cab1289..f2bf650 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
endif
obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index b3347d3..62e8c0f 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -131,6 +131,9 @@ struct device * __init imx_soc_device_init(void)
case MXC_CPU_IMX6UL:
soc_id = "i.MX6UL";
break;
+ case MXC_CPU_IMX6SLL:
+ soc_id = "i.MX6SLL";
+ break;
case MXC_CPU_IMX7D:
soc_id = "i.MX7D";
break;
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
index 8d866fb..124f982 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sl.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -11,6 +11,7 @@
#include <asm/cpuidle.h>
#include "common.h"
+#include "hardware.h"
#include "cpuidle.h"
static int imx6sl_enter_wait(struct cpuidle_device *dev,
@@ -21,9 +22,11 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
* Software workaround for ERR005311, see function
* description for details.
*/
- imx6sl_set_wait_clk(true);
+ if (cpu_is_imx6sl())
+ imx6sl_set_wait_clk(true);
cpu_do_idle();
- imx6sl_set_wait_clk(false);
+ if (cpu_is_imx6sl())
+ imx6sl_set_wait_clk(false);
imx6_set_lpm(WAIT_CLOCKED);
return index;
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 1dc2a34..4ed8a63 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -26,6 +26,7 @@
#include "hardware.h"
#define GPC_CNTR 0x000
+#define GPC_CNTR_L2_PGE 22
#define GPC_IMR1 0x008
#define GPC_PGC_GPU_PDN 0x260
#define GPC_PGC_GPU_PUPSCR 0x264
@@ -243,6 +244,7 @@ static int __init imx_gpc_init(struct device_node *node,
{
struct irq_domain *parent_domain, *domain;
int i;
+ u32 val;
if (!parent) {
pr_err("%s: no parent, giving up\n", node->full_name);
@@ -271,6 +273,12 @@ static int __init imx_gpc_init(struct device_node *node,
for (i = 0; i < IMR_NUM; i++)
writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
+ /* clear the L2_PGE bit on i.MX6SLL */
+ if (cpu_is_imx6sll()) {
+ val = readl_relaxed(gpc_base + GPC_CNTR);
+ val &= ~(1 << GPC_CNTR_L2_PGE);
+ writel_relaxed(val, gpc_base + GPC_CNTR);
+ }
/*
* Clear the OF_POPULATED flag set in of_irq_init so that
* later the GPC power domain driver will not be skipped.
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 0408490..462ed9c 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -17,6 +17,7 @@
#include <asm/mach/map.h>
#include "common.h"
+#include "hardware.h"
#include "cpuidle.h"
static void __init imx6sl_fec_init(void)
@@ -54,7 +55,8 @@ static void __init imx6sl_init_machine(void)
of_platform_default_populate(NULL, NULL, parent);
- imx6sl_fec_init();
+ if (cpu_is_imx6sl())
+ imx6sl_fec_init();
imx_anatop_init();
imx6sl_pm_init();
}
@@ -66,11 +68,15 @@ static void __init imx6sl_init_irq(void)
imx_init_l2cache();
imx_src_init();
irqchip_init();
- imx6_pm_ccm_init("fsl,imx6sl-ccm");
+ if (cpu_is_imx6sl())
+ imx6_pm_ccm_init("fsl,imx6sl-ccm");
+ else
+ imx6_pm_ccm_init("fsl,imx6sll-ccm");
}
static const char * const imx6sl_dt_compat[] __initconst = {
"fsl,imx6sl",
+ "fsl,imx6sll",
NULL,
};
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index 34f2ff6..e047611 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -39,6 +39,7 @@
#define MXC_CPU_IMX6SX 0x62
#define MXC_CPU_IMX6Q 0x63
#define MXC_CPU_IMX6UL 0x64
+#define MXC_CPU_IMX6SLL 0x67
#define MXC_CPU_IMX7D 0x72
#define IMX_DDR_TYPE_LPDDR2 1
@@ -73,6 +74,11 @@ static inline bool cpu_is_imx6ul(void)
return __mxc_cpu_type == MXC_CPU_IMX6UL;
}
+static inline bool cpu_is_imx6sll(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6SLL;
+}
+
static inline bool cpu_is_imx6q(void)
{
return __mxc_cpu_type == MXC_CPU_IMX6Q;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 02/12] driver: clocksource: add gpt timer for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add gpt timer support for i.MX6SLL.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
drivers/clocksource/timer-imx-gpt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c
index f595460..f71822d 100644
--- a/drivers/clocksource/timer-imx-gpt.c
+++ b/drivers/clocksource/timer-imx-gpt.c
@@ -556,4 +556,5 @@ static int __init imx6dl_timer_init_dt(struct device_node *np)
CLOCKSOURCE_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6sll_timer, "fsl,imx6sll-gpt", imx6dl_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt);
--
1.9.1
^ permalink raw reply related
* [PATCH v2 03/12] Document: dt: binding: imx: update clock doc for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add clock binding doc uppdate for imx6sll.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
.../devicetree/bindings/clock/imx6sll-clock.txt | 37 ++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/imx6sll-clock.txt
diff --git a/Documentation/devicetree/bindings/clock/imx6sll-clock.txt b/Documentation/devicetree/bindings/clock/imx6sll-clock.txt
new file mode 100644
index 0000000..3a46787
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx6sll-clock.txt
@@ -0,0 +1,37 @@
+* Clock bindings for Freescale i.MX6 SLL
+
+Required properties:
+- compatible: Should be "fsl,imx6sll-ccm"
+- reg: Address and length of the register set
+- #clock-cells: Should be <1>
+- clocks: list of clock specifiers, must contain an entry for each required
+ entry in clock-names
+- clock-names: should include entries "ckil", "osc", "ipp_di0" and "ipp_di1"
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx6sll-clock.h
+for the full list of i.MX6 SLL clock IDs.
+
+Examples:
+
+#include <dt-bindings/clock/imx6sll-clock.h>
+
+clks: ccm at 020c4000 {
+ compatible = "fsl,imx6sll-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>;
+ clock-names = "ckil", "osc", "ipp_di0", "ipp_di1";
+};
+
+uart1: serial at 02020000 {
+ compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_UART1_IPG>,
+ <&clks IMX6SLL_CLK_UART1_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v2 04/12] driver: clk: imx: Add clock driver for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add clk driver support for imx6sll.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
drivers/clk/imx/Makefile | 1 +
drivers/clk/imx/clk-imx6sll.c | 369 ++++++++++++++++++++++++++++++
include/dt-bindings/clock/imx6sll-clock.h | 204 +++++++++++++++++
3 files changed, 574 insertions(+)
create mode 100644 drivers/clk/imx/clk-imx6sll.c
create mode 100644 include/dt-bindings/clock/imx6sll-clock.h
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 1ada68a..9fb8e1f 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SOC_IMX35) += clk-imx35.o
obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o
obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o
diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c
new file mode 100644
index 0000000..73758fe1
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sll.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx6sll-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+#define CCM_ANALOG_PLL_BYPASS (0x1 << 16)
+#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
+#define CCDR 0x4
+#define xPLL_CLR(offset) (offset + 0x8)
+
+static const char *pll_bypass_src_sels[] = { "osc", "dummy", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *axi_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[] = {"periph", "axi_alt_sel", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ssi_sels[] = {"pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", "dummy",};
+static const char *spdif_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *lcdif_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *lcdif_sels[] = { "lcdif_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static const char *epdc_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *epdc_sels[] = { "epdc_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static struct clk *clks[IMX6SLL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const int clks_init_on[] __initconst = {
+ IMX6SLL_CLK_AIPSTZ1, IMX6SLL_CLK_AIPSTZ2,
+ IMX6SLL_CLK_OCRAM, IMX6SLL_CLK_ARM, IMX6SLL_CLK_ROM,
+ IMX6SLL_CLK_MMDC_P0_FAST, IMX6SLL_CLK_MMDC_P0_IPG,
+};
+
+static const struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { }
+};
+
+static const struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static u32 share_count_audio;
+static u32 share_count_ssi1;
+static u32 share_count_ssi2;
+static u32 share_count_ssi3;
+
+static void __init imx6sll_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+
+ clks[IMX6SLL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+
+ clks[IMX6SLL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
+ clks[IMX6SLL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc");
+
+ /* ipp_di clock is external input */
+ clks[IMX6SLL_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0");
+ clks[IMX6SLL_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ /* Do not bypass PLLs initially */
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x0));
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x10));
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x20));
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x30));
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x70));
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xa0));
+ writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xe0));
+
+ clks[IMX6SLL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SLL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ clks[IMX6SLL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+ clks[IMX6SLL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+ clks[IMX6SLL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+ clks[IMX6SLL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+ clks[IMX6SLL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+ clks[IMX6SLL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+ clks[IMX6SLL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+
+ clks[IMX6SLL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SLL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ clks[IMX6SLL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
+ clks[IMX6SLL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clks[IMX6SLL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clks[IMX6SLL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clks[IMX6SLL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clks[IMX6SLL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clks[IMX6SLL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+ * Bit 20 is the reserved and read-only bit, we do this only for:
+ * - Do nothing for usbphy clk_enable/disable
+ * - Keep refcount when do usbphy clk_enable/disable, in that case,
+ * the clk framework many need to enable/disable usbphy's parent
+ */
+ clks[IMX6SLL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clks[IMX6SLL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+ /*
+ * usbphy*_gate needs to be on after system boots up, and software
+ * never needs to control it anymore.
+ */
+ clks[IMX6SLL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clks[IMX6SLL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ /* name parent_name reg idx */
+ clks[IMX6SLL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clks[IMX6SLL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clks[IMX6SLL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clks[IMX6SLL_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
+ clks[IMX6SLL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6SLL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6SLL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6SLL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ clks[IMX6SLL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SLL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+ clks[IMX6SLL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SLL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div",
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+
+ /* name parent_name mult div */
+ clks[IMX6SLL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clks[IMX6SLL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clks[IMX6SLL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6SLL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX6SLL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6SLL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
+ clks[IMX6SLL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
+ clks[IMX6SLL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
+ clks[IMX6SLL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6SLL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6SLL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SLL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SLL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SLL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SLL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SLL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SLL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SLL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SLL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
+ clks[IMX6SLL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+ clks[IMX6SLL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
+ clks[IMX6SLL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x30, 7, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
+ clks[IMX6SLL_CLK_EPDC_PRE_SEL] = imx_clk_mux("epdc_pre_sel", base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels));
+ clks[IMX6SLL_CLK_EPDC_SEL] = imx_clk_mux("epdc_sel", base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels));
+ clks[IMX6SLL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+ clks[IMX6SLL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
+ clks[IMX6SLL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
+
+ clks[IMX6SLL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6SLL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ clks[IMX6SLL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6SLL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6SLL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6SLL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3);
+ clks[IMX6SLL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
+ clks[IMX6SLL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clks[IMX6SLL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6SLL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6SLL_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
+ clks[IMX6SLL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
+ clks[IMX6SLL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
+ clks[IMX6SLL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
+ clks[IMX6SLL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
+ clks[IMX6SLL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
+ clks[IMX6SLL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
+ clks[IMX6SLL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
+ clks[IMX6SLL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
+ clks[IMX6SLL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x30, 12, 3);
+ clks[IMX6SLL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x30, 9, 3);
+ clks[IMX6SLL_CLK_EPDC_PODF] = imx_clk_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3);
+ clks[IMX6SLL_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
+ clks[IMX6SLL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3);
+
+ clks[IMX6SLL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+ clks[IMX6SLL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6SLL_CLK_AXI_PODF] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clks[IMX6SLL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+
+ clks[IMX6SLL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX6SLL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
+ clks[IMX6SLL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clks[IMX6SLL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
+
+ clks[IMX6SLL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
+ clks[IMX6SLL_CLK_LDB_DI1_SEL] = imx_clk_mux("ldb_di1_sel", base + 0x1c, 7, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels));
+ clks[IMX6SLL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+ clks[IMX6SLL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1_div_sel", base + 0x20, 10, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+
+ /* CCGR0 */
+ clks[IMX6SLL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
+ clks[IMX6SLL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
+ clks[IMX6SLL_CLK_DCP] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10);
+ clks[IMX6SLL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28);
+ clks[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28);
+
+ /* CCGR1 */
+ clks[IMX6SLL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
+ clks[IMX6SLL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
+ clks[IMX6SLL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
+ clks[IMX6SLL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
+ clks[IMX6SLL_CLK_UART3_IPG] = imx_clk_gate2("uart3_ipg", "ipg", base + 0x6c, 10);
+ clks[IMX6SLL_CLK_UART3_SERIAL] = imx_clk_gate2("uart3_serial", "uart_podf", base + 0x6c, 10);
+ clks[IMX6SLL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
+ clks[IMX6SLL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
+ clks[IMX6SLL_CLK_GPT_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20);
+ clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22);
+ clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24);
+ clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24);
+
+ /* CCGR2 */
+ clks[IMX6SLL_CLK_CSI] = imx_clk_gate2("csi", "axi", base + 0x70, 2);
+ clks[IMX6SLL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
+ clks[IMX6SLL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
+ clks[IMX6SLL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
+ clks[IMX6SLL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
+ clks[IMX6SLL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28);
+ clks[IMX6SLL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30);
+
+ /* CCGR3 */
+ clks[IMX6SLL_CLK_UART5_IPG] = imx_clk_gate2("uart5_ipg", "ipg", base + 0x74, 2);
+ clks[IMX6SLL_CLK_UART5_SERIAL] = imx_clk_gate2("uart5_serial", "uart_podf", base + 0x74, 2);
+ clks[IMX6SLL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4);
+ clks[IMX6SLL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4);
+ clks[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10);
+ clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16);
+ clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
+ clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
+ clks[IMX6SLL_CLK_OCRAM] = imx_clk_gate("ocram", "ahb", base + 0x74, 28);
+
+ /* CCGR4 */
+ clks[IMX6SLL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
+ clks[IMX6SLL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
+ clks[IMX6SLL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
+ clks[IMX6SLL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
+
+ /* CCGR5 */
+ clks[IMX6SLL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
+ clks[IMX6SLL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clks[IMX6SLL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10);
+ clks[IMX6SLL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clks[IMX6SLL_CLK_EXTERN_AUDIO] = imx_clk_gate2_shared("extern_audio", "extern_audio_podf", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SLL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SLL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SLL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SLL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SLL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SLL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SLL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SLL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SLL_CLK_UART1_IPG] = imx_clk_gate2("uart1_ipg", "ipg", base + 0x7c, 24);
+ clks[IMX6SLL_CLK_UART1_SERIAL] = imx_clk_gate2("uart1_serial", "uart_podf", base + 0x7c, 24);
+
+ /* CCGR6 */
+ clks[IMX6SLL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6SLL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6SLL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6SLL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+
+ /* mask handshake of mmdc */
+ writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ if (IS_ERR(clks[i]))
+ pr_err("i.MX6SLL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i]));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* set perclk to from OSC */
+ clk_set_parent(clks[IMX6SLL_CLK_PERCLK_SEL], clks[IMX6SLL_CLK_OSC]);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY1_GATE]);
+ clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY2_GATE]);
+ }
+
+ /* Lower the AHB clock rate before changing the clock source. */
+ clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000);
+
+ /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+ clk_set_parent(clks[IMX6SLL_CLK_PERIPH_CLK2_SEL], clks[IMX6SLL_CLK_PLL3_USB_OTG]);
+ clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_CLK2]);
+ clk_set_parent(clks[IMX6SLL_CLK_PERIPH_PRE], clks[IMX6SLL_CLK_PLL2_BUS]);
+ clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_PRE]);
+
+ clk_set_rate(clks[IMX6SLL_CLK_AHB], 132000000);
+}
+
+CLK_OF_DECLARE(imx6sll, "fsl,imx6sll-ccm", imx6sll_clocks_init);
+
diff --git a/include/dt-bindings/clock/imx6sll-clock.h b/include/dt-bindings/clock/imx6sll-clock.h
new file mode 100644
index 0000000..39c2567
--- /dev/null
+++ b/include/dt-bindings/clock/imx6sll-clock.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX6SLL_H
+#define __DT_BINDINGS_CLOCK_IMX6SLL_H
+
+#define IMX6SLL_CLK_DUMMY 0
+#define IMX6SLL_CLK_CKIL 1
+#define IMX6SLL_CLK_OSC 2
+#define IMX6SLL_PLL1_BYPASS_SRC 3
+#define IMX6SLL_PLL2_BYPASS_SRC 4
+#define IMX6SLL_PLL3_BYPASS_SRC 5
+#define IMX6SLL_PLL4_BYPASS_SRC 6
+#define IMX6SLL_PLL5_BYPASS_SRC 7
+#define IMX6SLL_PLL6_BYPASS_SRC 8
+#define IMX6SLL_PLL7_BYPASS_SRC 9
+#define IMX6SLL_CLK_PLL1 10
+#define IMX6SLL_CLK_PLL2 11
+#define IMX6SLL_CLK_PLL3 12
+#define IMX6SLL_CLK_PLL4 13
+#define IMX6SLL_CLK_PLL5 14
+#define IMX6SLL_CLK_PLL6 15
+#define IMX6SLL_CLK_PLL7 16
+#define IMX6SLL_PLL1_BYPASS 17
+#define IMX6SLL_PLL2_BYPASS 18
+#define IMX6SLL_PLL3_BYPASS 19
+#define IMX6SLL_PLL4_BYPASS 20
+#define IMX6SLL_PLL5_BYPASS 21
+#define IMX6SLL_PLL6_BYPASS 22
+#define IMX6SLL_PLL7_BYPASS 23
+#define IMX6SLL_CLK_PLL1_SYS 24
+#define IMX6SLL_CLK_PLL2_BUS 25
+#define IMX6SLL_CLK_PLL3_USB_OTG 26
+#define IMX6SLL_CLK_PLL4_AUDIO 27
+#define IMX6SLL_CLK_PLL5_VIDEO 28
+#define IMX6SLL_CLK_PLL6_ENET 29
+#define IMX6SLL_CLK_PLL7_USB_HOST 30
+#define IMX6SLL_CLK_USBPHY1 31
+#define IMX6SLL_CLK_USBPHY2 32
+#define IMX6SLL_CLK_USBPHY1_GATE 33
+#define IMX6SLL_CLK_USBPHY2_GATE 34
+#define IMX6SLL_CLK_PLL2_PFD0 35
+#define IMX6SLL_CLK_PLL2_PFD1 36
+#define IMX6SLL_CLK_PLL2_PFD2 37
+#define IMX6SLL_CLK_PLL2_PFD3 38
+#define IMX6SLL_CLK_PLL3_PFD0 39
+#define IMX6SLL_CLK_PLL3_PFD1 40
+#define IMX6SLL_CLK_PLL3_PFD2 41
+#define IMX6SLL_CLK_PLL3_PFD3 42
+#define IMX6SLL_CLK_PLL4_POST_DIV 43
+#define IMX6SLL_CLK_PLL4_AUDIO_DIV 44
+#define IMX6SLL_CLK_PLL5_POST_DIV 45
+#define IMX6SLL_CLK_PLL5_VIDEO_DIV 46
+#define IMX6SLL_CLK_PLL2_198M 47
+#define IMX6SLL_CLK_PLL3_120M 48
+#define IMX6SLL_CLK_PLL3_80M 49
+#define IMX6SLL_CLK_PLL3_60M 50
+#define IMX6SLL_CLK_STEP 51
+#define IMX6SLL_CLK_PLL1_SW 52
+#define IMX6SLL_CLK_AXI_ALT_SEL 53
+#define IMX6SLL_CLK_AXI_SEL 54
+#define IMX6SLL_CLK_PERIPH_PRE 55
+#define IMX6SLL_CLK_PERIPH2_PRE 56
+#define IMX6SLL_CLK_PERIPH_CLK2_SEL 57
+#define IMX6SLL_CLK_PERIPH2_CLK2_SEL 58
+#define IMX6SLL_CLK_PERCLK_SEL 59
+#define IMX6SLL_CLK_USDHC1_SEL 60
+#define IMX6SLL_CLK_USDHC2_SEL 61
+#define IMX6SLL_CLK_USDHC3_SEL 62
+#define IMX6SLL_CLK_SSI1_SEL 63
+#define IMX6SLL_CLK_SSI2_SEL 64
+#define IMX6SLL_CLK_SSI3_SEL 65
+#define IMX6SLL_CLK_PXP_SEL 66
+#define IMX6SLL_CLK_LCDIF_PRE_SEL 67
+#define IMX6SLL_CLK_LCDIF_SEL 68
+#define IMX6SLL_CLK_EPDC_PRE_SEL 69
+#define IMX6SLL_CLK_SPDIF_SEL 70
+#define IMX6SLL_CLK_ECSPI_SEL 71
+#define IMX6SLL_CLK_UART_SEL 72
+#define IMX6SLL_CLK_ARM 73
+#define IMX6SLL_CLK_PERIPH 74
+#define IMX6SLL_CLK_PERIPH2 75
+#define IMX6SLL_CLK_PERIPH2_CLK2 76
+#define IMX6SLL_CLK_PERIPH_CLK2 77
+#define IMX6SLL_CLK_MMDC_PODF 78
+#define IMX6SLL_CLK_AXI_PODF 79
+#define IMX6SLL_CLK_AHB 80
+#define IMX6SLL_CLK_IPG 81
+#define IMX6SLL_CLK_PERCLK 82
+#define IMX6SLL_CLK_USDHC1_PODF 83
+#define IMX6SLL_CLK_USDHC2_PODF 84
+#define IMX6SLL_CLK_USDHC3_PODF 85
+#define IMX6SLL_CLK_SSI1_PRED 86
+#define IMX6SLL_CLK_SSI2_PRED 87
+#define IMX6SLL_CLK_SSI3_PRED 88
+#define IMX6SLL_CLK_SSI1_PODF 89
+#define IMX6SLL_CLK_SSI2_PODF 90
+#define IMX6SLL_CLK_SSI3_PODF 91
+#define IMX6SLL_CLK_PXP_PODF 92
+#define IMX6SLL_CLK_LCDIF_PRED 93
+#define IMX6SLL_CLK_LCDIF_PODF 94
+#define IMX6SLL_CLK_EPDC_SEL 95
+#define IMX6SLL_CLK_EPDC_PODF 96
+#define IMX6SLL_CLK_SPDIF_PRED 97
+#define IMX6SLL_CLK_SPDIF_PODF 98
+#define IMX6SLL_CLK_ECSPI_PODF 99
+#define IMX6SLL_CLK_UART_PODF 100
+
+/* CCGR 0 */
+#define IMX6SLL_CLK_AIPSTZ1 101
+#define IMX6SLL_CLK_AIPSTZ2 102
+#define IMX6SLL_CLK_DCP 103
+#define IMX6SLL_CLK_UART2_IPG 104
+#define IMX6SLL_CLK_UART2_SERIAL 105
+
+/* CCGR 1 */
+#define IMX6SLL_CLK_ECSPI1 106
+#define IMX6SLL_CLK_ECSPI2 107
+#define IMX6SLL_CLK_ECSPI3 108
+#define IMX6SLL_CLK_ECSPI4 109
+#define IMX6SLL_CLK_UART3_IPG 110
+#define IMX6SLL_CLK_UART3_SERIAL 111
+#define IMX6SLL_CLK_UART4_IPG 112
+#define IMX6SLL_CLK_UART4_SERIAL 113
+#define IMX6SLL_CLK_EPIT1 114
+#define IMX6SLL_CLK_EPIT2 115
+#define IMX6SLL_CLK_GPT_BUS 116
+#define IMX6SLL_CLK_GPT_SERIAL 117
+
+/* CCGR2 */
+#define IMX6SLL_CLK_CSI 118
+#define IMX6SLL_CLK_I2C1 119
+#define IMX6SLL_CLK_I2C2 120
+#define IMX6SLL_CLK_I2C3 121
+#define IMX6SLL_CLK_OCOTP 122
+#define IMX6SLL_CLK_LCDIF_APB 123
+#define IMX6SLL_CLK_PXP 124
+
+/* CCGR3 */
+#define IMX6SLL_CLK_UART5_IPG 125
+#define IMX6SLL_CLK_UART5_SERIAL 126
+#define IMX6SLL_CLK_EPDC_AXI 127
+#define IMX6SLL_CLK_EPDC_PIX 128
+#define IMX6SLL_CLK_LCDIF_PIX 129
+#define IMX6SLL_CLK_WDOG1 130
+#define IMX6SLL_CLK_MMDC_P0_FAST 131
+#define IMX6SLL_CLK_MMDC_P0_IPG 132
+#define IMX6SLL_CLK_OCRAM 133
+
+/* CCGR4 */
+#define IMX6SLL_CLK_PWM1 134
+#define IMX6SLL_CLK_PWM2 135
+#define IMX6SLL_CLK_PWM3 136
+#define IMX6SLL_CLK_PWM4 137
+
+/* CCGR 5 */
+#define IMX6SLL_CLK_ROM 138
+#define IMX6SLL_CLK_SDMA 139
+#define IMX6SLL_CLK_KPP 140
+#define IMX6SLL_CLK_WDOG2 141
+#define IMX6SLL_CLK_SPBA 142
+#define IMX6SLL_CLK_SPDIF 143
+#define IMX6SLL_CLK_SPDIF_GCLK 144
+#define IMX6SLL_CLK_SSI1 145
+#define IMX6SLL_CLK_SSI1_IPG 146
+#define IMX6SLL_CLK_SSI2 147
+#define IMX6SLL_CLK_SSI2_IPG 148
+#define IMX6SLL_CLK_SSI3 149
+#define IMX6SLL_CLK_SSI3_IPG 150
+#define IMX6SLL_CLK_UART1_IPG 151
+#define IMX6SLL_CLK_UART1_SERIAL 152
+
+/* CCGR 6 */
+#define IMX6SLL_CLK_USBOH3 153
+#define IMX6SLL_CLK_USDHC1 154
+#define IMX6SLL_CLK_USDHC2 155
+#define IMX6SLL_CLK_USDHC3 156
+
+#define IMX6SLL_CLK_IPP_DI0 157
+#define IMX6SLL_CLK_IPP_DI1 158
+#define IMX6SLL_CLK_LDB_DI0_SEL 159
+#define IMX6SLL_CLK_LDB_DI0_DIV_3_5 160
+#define IMX6SLL_CLK_LDB_DI0_DIV_7 161
+#define IMX6SLL_CLK_LDB_DI0_DIV_SEL 162
+#define IMX6SLL_CLK_LDB_DI0 163
+#define IMX6SLL_CLK_LDB_DI1_SEL 164
+#define IMX6SLL_CLK_LDB_DI1_DIV_3_5 165
+#define IMX6SLL_CLK_LDB_DI1_DIV_7 166
+#define IMX6SLL_CLK_LDB_DI1_DIV_SEL 167
+#define IMX6SLL_CLK_LDB_DI1 168
+#define IMX6SLL_CLK_EXTERN_AUDIO_SEL 169
+#define IMX6SLL_CLK_EXTERN_AUDIO_PRED 170
+#define IMX6SLL_CLK_EXTERN_AUDIO_PODF 171
+#define IMX6SLL_CLK_EXTERN_AUDIO 172
+
+#define IMX6SLL_CLK_END 173
+
+#endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */
--
1.9.1
^ permalink raw reply related
* [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add pinctrl binding doc update for imx6sll.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
.../bindings/pinctrl/fsl,imx6sll-pinctrl.txt | 37 ++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
new file mode 100644
index 0000000..9561c1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
@@ -0,0 +1,37 @@
+* Freescale i.MX6 SLL IOMUX Controller
+
+Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: "fsl,imx6sll-iomuxc"
+- fsl,pins: each entry consists of 6 integers and represents the mux and config
+ setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
+ input_val> are specified using a PIN_FUNC_ID macro, which can be found in
+ imx6sll-pinfunc.h under device tree source folder. The last integer CONFIG is
+ the pad setting value like pull-up on this pin. Please refer to i.MX6SLL
+ Reference Manual for detailed CONFIG settings.
+
+CONFIG bits definition:
+PAD_CTL_LVE (1 << 22)
+PAD_CTL_HYS (1 << 16)
+PAD_CTL_PUS_100K_DOWN (0 << 14)
+PAD_CTL_PUS_47K_UP (1 << 14)
+PAD_CTL_PUS_100K_UP (2 << 14)
+PAD_CTL_PUS_22K_UP (3 << 14)
+PAD_CTL_PUE (1 << 13)
+PAD_CTL_PKE (1 << 12)
+PAD_CTL_ODE (1 << 11)
+PAD_CTL_SPEED_LOW (0 << 6)
+PAD_CTL_SPEED_MED (1 << 6)
+PAD_CTL_SPEED_HIGH (3 << 6)
+PAD_CTL_DSE_DISABLE (0 << 3)
+PAD_CTL_DSE_260ohm (1 << 3)
+PAD_CTL_DSE_130ohm (2 << 3)
+PAD_CTL_DSE_87ohm (3 << 3)
+PAD_CTL_DSE_65ohm (4 << 3)
+PAD_CTL_DSE_52ohm (5 << 3)
+PAD_CTL_DSE_43ohm (6 << 3)
+PAD_CTL_DSE_37ohm (7 << 3)
+PAD_CTL_SRE_FAST (1 << 0)
+PAD_CTL_SRE_SLOW (0 << 0)
--
1.9.1
^ permalink raw reply related
* [PATCH v2 06/12] driver: pinctrl: imx: Add pinctrl driver support for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add pinctrl driver support for imx6sll.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
arch/arm/mach-imx/Kconfig | 1 +
drivers/pinctrl/freescale/Kconfig | 7 +
drivers/pinctrl/freescale/Makefile | 1 +
drivers/pinctrl/freescale/pinctrl-imx6sll.c | 385 ++++++++++++++++++++++++++++
4 files changed, 394 insertions(+)
create mode 100644 drivers/pinctrl/freescale/pinctrl-imx6sll.c
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 33bcfda..c907d9f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -514,6 +514,7 @@ config SOC_IMX6SL
config SOC_IMX6SLL
bool "i.MX6 SoloLiteLite support"
+ select PINCTRL_IMX6SLL
select SOC_IMX6
help
diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig
index fc8cbf6..93ca39f 100644
--- a/drivers/pinctrl/freescale/Kconfig
+++ b/drivers/pinctrl/freescale/Kconfig
@@ -81,6 +81,13 @@ config PINCTRL_IMX6SL
help
Say Y here to enable the imx6sl pinctrl driver
+config PINCTRL_IMX6SLL
+ bool "IMX6SL pinctrl driver"
+ depends on SOC_IMX6SLL
+ select PINCTRL_IMX
+ help
+ Say Y here to enable the imx6sl pinctrl driver
+
config PINCTRL_IMX6SX
bool "IMX6SX pinctrl driver"
depends on SOC_IMX6SX
diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile
index d44c9e2..5f23765 100644
--- a/drivers/pinctrl/freescale/Makefile
+++ b/drivers/pinctrl/freescale/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6dl.o
obj-$(CONFIG_PINCTRL_IMX6SL) += pinctrl-imx6sl.o
+obj-$(CONFIG_PINCTRL_IMX6SLL) += pinctrl-imx6sll.o
obj-$(CONFIG_PINCTRL_IMX6SX) += pinctrl-imx6sx.o
obj-$(CONFIG_PINCTRL_IMX6UL) += pinctrl-imx6ul.o
obj-$(CONFIG_PINCTRL_IMX7D) += pinctrl-imx7d.o
diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sll.c b/drivers/pinctrl/freescale/pinctrl-imx6sll.c
new file mode 100644
index 0000000..2f4baff
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx6sll.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Author: Bai Ping <ping.bai@nxp.com>
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum imx6sll_pads {
+ MX6SLL_PAD_RESERVE0 = 0,
+ MX6SLL_PAD_RESERVE1 = 1,
+ MX6SLL_PAD_RESERVE2 = 2,
+ MX6SLL_PAD_RESERVE3 = 3,
+ MX6SLL_PAD_RESERVE4 = 4,
+ MX6SLL_PAD_WDOG_B = 5,
+ MX6SLL_PAD_REF_CLK_24M = 6,
+ MX6SLL_PAD_REF_CLK_32K = 7,
+ MX6SLL_PAD_PWM1 = 8,
+ MX6SLL_PAD_KEY_COL0 = 9,
+ MX6SLL_PAD_KEY_ROW0 = 10,
+ MX6SLL_PAD_KEY_COL1 = 11,
+ MX6SLL_PAD_KEY_ROW1 = 12,
+ MX6SLL_PAD_KEY_COL2 = 13,
+ MX6SLL_PAD_KEY_ROW2 = 14,
+ MX6SLL_PAD_KEY_COL3 = 15,
+ MX6SLL_PAD_KEY_ROW3 = 16,
+ MX6SLL_PAD_KEY_COL4 = 17,
+ MX6SLL_PAD_KEY_ROW4 = 18,
+ MX6SLL_PAD_KEY_COL5 = 19,
+ MX6SLL_PAD_KEY_ROW5 = 20,
+ MX6SLL_PAD_KEY_COL6 = 21,
+ MX6SLL_PAD_KEY_ROW6 = 22,
+ MX6SLL_PAD_KEY_COL7 = 23,
+ MX6SLL_PAD_KEY_ROW7 = 24,
+ MX6SLL_PAD_EPDC_DATA00 = 25,
+ MX6SLL_PAD_EPDC_DATA01 = 26,
+ MX6SLL_PAD_EPDC_DATA02 = 27,
+ MX6SLL_PAD_EPDC_DATA03 = 28,
+ MX6SLL_PAD_EPDC_DATA04 = 29,
+ MX6SLL_PAD_EPDC_DATA05 = 30,
+ MX6SLL_PAD_EPDC_DATA06 = 31,
+ MX6SLL_PAD_EPDC_DATA07 = 32,
+ MX6SLL_PAD_EPDC_DATA08 = 33,
+ MX6SLL_PAD_EPDC_DATA09 = 34,
+ MX6SLL_PAD_EPDC_DATA10 = 35,
+ MX6SLL_PAD_EPDC_DATA11 = 36,
+ MX6SLL_PAD_EPDC_DATA12 = 37,
+ MX6SLL_PAD_EPDC_DATA13 = 38,
+ MX6SLL_PAD_EPDC_DATA14 = 39,
+ MX6SLL_PAD_EPDC_DATA15 = 40,
+ MX6SLL_PAD_EPDC_SDCLK = 41,
+ MX6SLL_PAD_EPDC_SDLE = 42,
+ MX6SLL_PAD_EPDC_SDOE = 43,
+ MX6SLL_PAD_EPDC_SDSHR = 44,
+ MX6SLL_PAD_EPDC_SDCE0 = 45,
+ MX6SLL_PAD_EPDC_SDCE1 = 46,
+ MX6SLL_PAD_EPDC_SDCE2 = 47,
+ MX6SLL_PAD_EPDC_SDCE3 = 48,
+ MX6SLL_PAD_EPDC_GDCLK = 49,
+ MX6SLL_PAD_EPDC_GDOE = 50,
+ MX6SLL_PAD_EPDC_GDRL = 51,
+ MX6SLL_PAD_EPDC_GDSP = 52,
+ MX6SLL_PAD_EPDC_VCOM0 = 53,
+ MX6SLL_PAD_EPDC_VCOM1 = 54,
+ MX6SLL_PAD_EPDC_BDR0 = 55,
+ MX6SLL_PAD_EPDC_BDR1 = 56,
+ MX6SLL_PAD_EPDC_PWR_CTRL0 = 57,
+ MX6SLL_PAD_EPDC_PWR_CTRL1 = 58,
+ MX6SLL_PAD_EPDC_PWR_CTRL2 = 59,
+ MX6SLL_PAD_EPDC_PWR_CTRL3 = 60,
+ MX6SLL_PAD_EPDC_PWR_COM = 61,
+ MX6SLL_PAD_EPDC_PWR_INT = 62,
+ MX6SLL_PAD_EPDC_PWR_STAT = 63,
+ MX6SLL_PAD_EPDC_PWR_WAKE = 64,
+ MX6SLL_PAD_LCD_CLK = 65,
+ MX6SLL_PAD_LCD_ENABLE = 66,
+ MX6SLL_PAD_LCD_HSYNC = 67,
+ MX6SLL_PAD_LCD_VSYNC = 68,
+ MX6SLL_PAD_LCD_RESET = 69,
+ MX6SLL_PAD_LCD_DATA00 = 70,
+ MX6SLL_PAD_LCD_DATA01 = 71,
+ MX6SLL_PAD_LCD_DATA02 = 72,
+ MX6SLL_PAD_LCD_DATA03 = 73,
+ MX6SLL_PAD_LCD_DATA04 = 74,
+ MX6SLL_PAD_LCD_DATA05 = 75,
+ MX6SLL_PAD_LCD_DATA06 = 76,
+ MX6SLL_PAD_LCD_DATA07 = 77,
+ MX6SLL_PAD_LCD_DATA08 = 78,
+ MX6SLL_PAD_LCD_DATA09 = 79,
+ MX6SLL_PAD_LCD_DATA10 = 80,
+ MX6SLL_PAD_LCD_DATA11 = 81,
+ MX6SLL_PAD_LCD_DATA12 = 82,
+ MX6SLL_PAD_LCD_DATA13 = 83,
+ MX6SLL_PAD_LCD_DATA14 = 84,
+ MX6SLL_PAD_LCD_DATA15 = 85,
+ MX6SLL_PAD_LCD_DATA16 = 86,
+ MX6SLL_PAD_LCD_DATA17 = 87,
+ MX6SLL_PAD_LCD_DATA18 = 88,
+ MX6SLL_PAD_LCD_DATA19 = 89,
+ MX6SLL_PAD_LCD_DATA20 = 90,
+ MX6SLL_PAD_LCD_DATA21 = 91,
+ MX6SLL_PAD_LCD_DATA22 = 92,
+ MX6SLL_PAD_LCD_DATA23 = 93,
+ MX6SLL_PAD_AUD_RXFS = 94,
+ MX6SLL_PAD_AUD_RXC = 95,
+ MX6SLL_PAD_AUD_RXD = 96,
+ MX6SLL_PAD_AUD_TXC = 97,
+ MX6SLL_PAD_AUD_TXFS = 98,
+ MX6SLL_PAD_AUD_TXD = 99,
+ MX6SLL_PAD_AUD_MCLK = 100,
+ MX6SLL_PAD_UART1_RXD = 101,
+ MX6SLL_PAD_UART1_TXD = 102,
+ MX6SLL_PAD_I2C1_SCL = 103,
+ MX6SLL_PAD_I2C1_SDA = 104,
+ MX6SLL_PAD_I2C2_SCL = 105,
+ MX6SLL_PAD_I2C2_SDA = 106,
+ MX6SLL_PAD_ECSPI1_SCLK = 107,
+ MX6SLL_PAD_ECSPI1_MOSI = 108,
+ MX6SLL_PAD_ECSPI1_MISO = 109,
+ MX6SLL_PAD_ECSPI1_SS0 = 110,
+ MX6SLL_PAD_ECSPI2_SCLK = 111,
+ MX6SLL_PAD_ECSPI2_MOSI = 112,
+ MX6SLL_PAD_ECSPI2_MISO = 113,
+ MX6SLL_PAD_ECSPI2_SS0 = 114,
+ MX6SLL_PAD_SD1_CLK = 115,
+ MX6SLL_PAD_SD1_CMD = 116,
+ MX6SLL_PAD_SD1_DATA0 = 117,
+ MX6SLL_PAD_SD1_DATA1 = 118,
+ MX6SLL_PAD_SD1_DATA2 = 119,
+ MX6SLL_PAD_SD1_DATA3 = 120,
+ MX6SLL_PAD_SD1_DATA4 = 121,
+ MX6SLL_PAD_SD1_DATA5 = 122,
+ MX6SLL_PAD_SD1_DATA6 = 123,
+ MX6SLL_PAD_SD1_DATA7 = 124,
+ MX6SLL_PAD_SD2_RESET = 125,
+ MX6SLL_PAD_SD2_CLK = 126,
+ MX6SLL_PAD_SD2_CMD = 127,
+ MX6SLL_PAD_SD2_DATA0 = 128,
+ MX6SLL_PAD_SD2_DATA1 = 129,
+ MX6SLL_PAD_SD2_DATA2 = 130,
+ MX6SLL_PAD_SD2_DATA3 = 131,
+ MX6SLL_PAD_SD2_DATA4 = 132,
+ MX6SLL_PAD_SD2_DATA5 = 133,
+ MX6SLL_PAD_SD2_DATA6 = 134,
+ MX6SLL_PAD_SD2_DATA7 = 135,
+ MX6SLL_PAD_SD3_CLK = 136,
+ MX6SLL_PAD_SD3_CMD = 137,
+ MX6SLL_PAD_SD3_DATA0 = 138,
+ MX6SLL_PAD_SD3_DATA1 = 139,
+ MX6SLL_PAD_SD3_DATA2 = 140,
+ MX6SLL_PAD_SD3_DATA3 = 141,
+ MX6SLL_PAD_GPIO4_IO20 = 142,
+ MX6SLL_PAD_GPIO4_IO21 = 143,
+ MX6SLL_PAD_GPIO4_IO19 = 144,
+ MX6SLL_PAD_GPIO4_IO25 = 145,
+ MX6SLL_PAD_GPIO4_IO18 = 146,
+ MX6SLL_PAD_GPIO4_IO24 = 147,
+ MX6SLL_PAD_GPIO4_IO23 = 148,
+ MX6SLL_PAD_GPIO4_IO17 = 149,
+ MX6SLL_PAD_GPIO4_IO22 = 150,
+ MX6SLL_PAD_GPIO4_IO16 = 151,
+ MX6SLL_PAD_GPIO4_IO26 = 152,
+};
+
+enum imx6sll_lpsr_pads {
+ MX6SLL_PAD_SNVS_TAMPER = 0,
+ MX6SLL_PAD_SNVS_PMIC_ON_REQ = 1,
+ MX6SLL_PAD_SNVS_PMIC_STBY_REQ = 2,
+ MX6SLL_PAD_SNVS_BOOT_MODE0 = 3,
+ MX6SLL_PAD_SNVS_BOOT_MODE1 = 4,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx6sll_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_WDOG_B),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_REF_CLK_24M),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_REF_CLK_32K),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_PWM1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA00),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA01),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA02),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA03),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA04),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA05),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA06),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA07),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA08),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA09),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA10),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA11),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA12),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA13),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA14),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA15),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDLE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDOE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDSHR),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDOE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDRL),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDSP),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_VCOM0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_VCOM1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_BDR0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_BDR1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_COM),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_INT),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_STAT),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_WAKE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_ENABLE),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_HSYNC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_VSYNC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_RESET),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA00),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA01),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA02),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA03),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA04),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA05),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA06),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA07),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA08),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA09),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA10),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA11),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA12),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA13),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA14),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA15),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA16),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA17),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA18),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA19),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA20),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA21),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA22),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA23),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXFS),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXC),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXFS),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_MCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_UART1_RXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_UART1_TXD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C1_SCL),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C1_SDA),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C2_SCL),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_I2C2_SDA),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_MISO),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_SS0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_MISO),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_SS0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_CMD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_RESET),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_CMD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA4),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA5),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA6),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA7),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_CLK),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_CMD),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA0),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA1),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA2),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA3),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO20),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO21),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO19),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO25),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO18),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO24),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO23),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO17),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO22),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO16),
+ IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO26),
+};
+
+static struct imx_pinctrl_soc_info imx6sll_pinctrl_info = {
+ .pins = imx6sll_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx6sll_pinctrl_pads),
+ .gpr_compatible = "fsl,imx6sll-iomuxc-gpr",
+};
+
+static const struct of_device_id imx6sll_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx6sll-iomuxc", .data = &imx6sll_pinctrl_info, },
+ { /* sentinel */ }
+};
+
+static int imx6sll_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct imx_pinctrl_soc_info *pinctrl_info;
+
+ match = of_match_device(imx6sll_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+ return imx_pinctrl_probe(pdev, pinctrl_info);
+}
+
+static struct platform_driver imx6sll_pinctrl_driver = {
+ .driver = {
+ .name = "imx6sll-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx6sll_pinctrl_of_match),
+ },
+ .probe = imx6sll_pinctrl_probe,
+};
+
+static int __init imx6sll_pinctrl_init(void)
+{
+ return platform_driver_register(&imx6sll_pinctrl_driver);
+}
+arch_initcall(imx6sll_pinctrl_init);
+
+static void __exit imx6sll_pinctrl_exit(void)
+{
+ platform_driver_unregister(&imx6sll_pinctrl_driver);
+}
+module_exit(imx6sll_pinctrl_exit);
--
1.9.1
^ permalink raw reply related
* [PATCH v2 08/12] ARM: dts: imx: Add imx6sll EVK board dts support
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add basic dts support for imx6sll EVK board.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/imx6sll-evk.dts | 474 ++++++++++++++++++++++++++++++++++++++
2 files changed, 476 insertions(+)
create mode 100644 arch/arm/boot/dts/imx6sll-evk.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 38c595d..24eb4bd 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -416,6 +416,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
dtb-$(CONFIG_SOC_IMX6SL) += \
imx6sl-evk.dtb \
imx6sl-warp.dtb
+dtb-$(CONFIG_SOC_IMX6SLL) += \
+ imx6sll-evk.dtb
dtb-$(CONFIG_SOC_IMX6SX) += \
imx6sx-nitrogen6sx.dtb \
imx6sx-sabreauto.dtb \
diff --git a/arch/arm/boot/dts/imx6sll-evk.dts b/arch/arm/boot/dts/imx6sll-evk.dts
new file mode 100644
index 0000000..7b8264b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-evk.dts
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sll.dtsi"
+
+/ {
+ model = "Freescale i.MX6SLL EVK Board";
+ compatible = "fsl,imx6sll-evk", "fsl,imx6sll";
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ reg_usb_otg1_vbus: reg-usb-otg1-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: reg-usb-otg2-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_aud3v: reg-aud3v {
+ compatible = "regulator-fixed";
+ regulator-name = "wm8962-supply-3v15";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-boot-on;
+ };
+
+ reg_aud4v: reg-aud4v {
+ compatible = "regulator-fixed";
+ regulator-name = "wm8962-supply-4v2";
+ regulator-min-microvolt = <4325000>;
+ regulator-max-microvolt = <4325000>;
+ regulator-boot-on;
+ };
+
+ reg_lcd: reg-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd-pwr";
+ gpio = <&gpio4 8 0>;
+ enable-active-high;
+ };
+
+ reg_sd1_vmmc: reg-sd1-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "SD1_SPWR";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+ soc-supply = <&sw1c_reg>;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100 at 08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6SLL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
+ MX6SLL_PAD_GPIO4_IO22__GPIO4_IO22 0x17059
+ MX6SLL_PAD_KEY_COL3__GPIO3_IO30 0x17059
+ /*
+ * Must set the LVE of pad SD2_RESET, otherwise current
+ * leakage through eMMC chip will pull high the VCCQ to
+ * 2.6v, which will impact SD1 and SD3 SD3.0 voltage switch.
+ */
+ MX6SLL_PAD_SD2_RESET__GPIO4_IO27 0x417059
+ MX6SLL_PAD_KEY_COL4__GPIO4_IO00 0x17059
+ MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059 /* SD3 CD */
+ MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x17059 /*SD3 RESET */
+ MX6SLL_PAD_KEY_COL5__GPIO4_IO02 0x17059
+ MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x17059 /* HP DETECT */
+ /* CHG_FLT, CHG_UOK/DOK, CHG_STATUS */
+ MX6SLL_PAD_ECSPI2_MISO__GPIO4_IO14 0x17000
+ MX6SLL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x17000
+ MX6SLL_PAD_ECSPI2_SS0__GPIO4_IO15 0x17000
+ >;
+ };
+
+ pinctrl_audmux3: audmux3grp {
+ fsl,pins = <
+ MX6SLL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
+ MX6SLL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
+ MX6SLL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
+ MX6SLL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
+ MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_csi1: csi1grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_GDRL__CSI_MCLK 0x1b088
+ MX6SLL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x1b088
+ MX6SLL_PAD_EPDC_GDSP__CSI_VSYNC 0x1b088
+ MX6SLL_PAD_EPDC_GDOE__CSI_HSYNC 0x1b088
+ MX6SLL_PAD_EPDC_DATA02__CSI_DATA02 0x1b088
+ MX6SLL_PAD_EPDC_DATA03__CSI_DATA03 0x1b088
+ MX6SLL_PAD_EPDC_DATA04__CSI_DATA04 0x1b088
+ MX6SLL_PAD_EPDC_DATA05__CSI_DATA05 0x1b088
+ MX6SLL_PAD_EPDC_DATA06__CSI_DATA06 0x1b088
+ MX6SLL_PAD_EPDC_DATA07__CSI_DATA07 0x1b088
+ MX6SLL_PAD_EPDC_SDCLK__CSI_DATA08 0x1b088
+ MX6SLL_PAD_EPDC_SDLE__CSI_DATA09 0x1b088
+ MX6SLL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
+ MX6SLL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
+ >;
+ };
+
+ pinctrl_lcdif_dat: lcdifdatgrp {
+ fsl,pins = <
+ MX6SLL_PAD_LCD_DATA00__LCD_DATA00 0x79
+ MX6SLL_PAD_LCD_DATA01__LCD_DATA01 0x79
+ MX6SLL_PAD_LCD_DATA02__LCD_DATA02 0x79
+ MX6SLL_PAD_LCD_DATA03__LCD_DATA03 0x79
+ MX6SLL_PAD_LCD_DATA04__LCD_DATA04 0x79
+ MX6SLL_PAD_LCD_DATA05__LCD_DATA05 0x79
+ MX6SLL_PAD_LCD_DATA06__LCD_DATA06 0x79
+ MX6SLL_PAD_LCD_DATA07__LCD_DATA07 0x79
+ MX6SLL_PAD_LCD_DATA08__LCD_DATA08 0x79
+ MX6SLL_PAD_LCD_DATA09__LCD_DATA09 0x79
+ MX6SLL_PAD_LCD_DATA10__LCD_DATA10 0x79
+ MX6SLL_PAD_LCD_DATA11__LCD_DATA11 0x79
+ MX6SLL_PAD_LCD_DATA12__LCD_DATA12 0x79
+ MX6SLL_PAD_LCD_DATA13__LCD_DATA13 0x79
+ MX6SLL_PAD_LCD_DATA14__LCD_DATA14 0x79
+ MX6SLL_PAD_LCD_DATA15__LCD_DATA15 0x79
+ MX6SLL_PAD_LCD_DATA16__LCD_DATA16 0x79
+ MX6SLL_PAD_LCD_DATA17__LCD_DATA17 0x79
+ MX6SLL_PAD_LCD_DATA18__LCD_DATA18 0x79
+ MX6SLL_PAD_LCD_DATA19__LCD_DATA19 0x79
+ MX6SLL_PAD_LCD_DATA20__LCD_DATA20 0x79
+ MX6SLL_PAD_LCD_DATA21__LCD_DATA21 0x79
+ MX6SLL_PAD_LCD_DATA22__LCD_DATA22 0x79
+ MX6SLL_PAD_LCD_DATA23__LCD_DATA23 0x79
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdifctrlgrp {
+ fsl,pins = <
+ MX6SLL_PAD_LCD_CLK__LCD_CLK 0x79
+ MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE 0x79
+ MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC 0x79
+ MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC 0x79
+ MX6SLL_PAD_LCD_RESET__LCD_RESET 0x79
+ MX6SLL_PAD_ECSPI1_SCLK__GPIO4_IO08 0x79
+ >;
+ };
+
+ pinctrl_max17135: max17135grp-1 {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13 0x80000000 /* pwrgood */
+ MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03 0x80000000 /* vcom_ctrl */
+ MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14 0x80000000 /* wakeup */
+ MX6SLL_PAD_EPDC_PWR_CTRL0__GPIO2_IO07 0x80000000 /* v3p3 */
+ MX6SLL_PAD_EPDC_PWR_IRQ__GPIO2_IO12 0x80000000 /* pwr int */
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6SLL_PAD_SD2_DATA4__SPDIF_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1
+ MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x17059
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x13059
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x17059
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x17059
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x17059
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x170b9
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x130b9
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170b9
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170b9
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170b9
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+ fsl,pins = <
+ MX6SLL_PAD_SD1_CMD__SD1_CMD 0x170f9
+ MX6SLL_PAD_SD1_CLK__SD1_CLK 0x130f9
+ MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170f9
+ MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170f9
+ MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170f9
+ MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6SLL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
+ MX6SLL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pwm1: pmw1grp {
+ fsl,pins = <
+ MX6SLL_PAD_PWM1__PWM1_OUT 0x110b0
+ >;
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+ lcd-supply = <®_lcd>;
+ display = <&display>;
+ status = "okay";
+
+ display: display {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <®_sd1_vmmc>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <®_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ disable-over-current;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <®_usb_otg2_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v2 09/12] ARM: debug: Add low level debug support for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add low level debug support for i.MX6SLL.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
arch/arm/Kconfig.debug | 9 +++++++++
arch/arm/include/debug/imx-uart.h | 10 ++++++++++
2 files changed, 19 insertions(+)
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 408540f..d52d48c 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -405,6 +405,13 @@ choice
Say Y here if you want kernel low-level debugging support
on i.MX6SL.
+ config DEBUG_IMX6SLL_UART
+ bool "i.MX6SLL Debug UART"
+ depends on SOC_IMX6SLL
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6SLL.
+
config DEBUG_IMX6SX_UART
bool "i.MX6SX Debug UART"
depends on SOC_IMX6SX
@@ -1374,6 +1381,7 @@ config DEBUG_IMX_UART_PORT
DEBUG_IMX53_UART || \
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
+ DEBUG_IMX6SLL_UART || \
DEBUG_IMX6SX_UART || \
DEBUG_IMX6UL_UART || \
DEBUG_IMX7D_UART
@@ -1428,6 +1436,7 @@ config DEBUG_LL_INCLUDE
DEBUG_IMX53_UART ||\
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
+ DEBUG_IMX6SLL_UART || \
DEBUG_IMX6SX_UART || \
DEBUG_IMX6UL_UART || \
DEBUG_IMX7D_UART
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e9..24e60ce 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -81,6 +81,14 @@
#define IMX6SL_UART_BASE_ADDR(n) IMX6SL_UART##n##_BASE_ADDR
#define IMX6SL_UART_BASE(n) IMX6SL_UART_BASE_ADDR(n)
+#define IMX6SLL_UART1_BASE_ADDR 0x02020000
+#define IMX6SLL_UART2_BASE_ADDR 0x02024000
+#define IMX6SLL_UART3_BASE_ADDR 0x02034000
+#define IMX6SLL_UART4_BASE_ADDR 0x02018000
+#define IMX6SLL_UART5_BASE_ADDR 0x021f4000
+#define IMX6SLL_UART_BASE_ADDR(n) IMX6SLL_UART##n##_BASE_ADDR
+#define IMX6SLL_UART_BASE(n) IMX6SLL_UART_BASE_ADDR(n)
+
#define IMX6SX_UART1_BASE_ADDR 0x02020000
#define IMX6SX_UART2_BASE_ADDR 0x021e8000
#define IMX6SX_UART3_BASE_ADDR 0x021ec000
@@ -133,6 +141,8 @@
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q)
#elif defined(CONFIG_DEBUG_IMX6SL_UART)
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL)
+#elif defined(CONFIG_DEBUG_IMX6SLL_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SLL)
#elif defined(CONFIG_DEBUG_IMX6SX_UART)
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX)
#elif defined(CONFIG_DEBUG_IMX6UL_UART)
--
1.9.1
^ permalink raw reply related
* [PATCH v2 10/12] ARM: imx: Add suspend/resume support for imx6sll
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
Add suspend/resume support for imx6sll.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
arch/arm/mach-imx/pm-imx6.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 1515e49..2ed4316 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -145,6 +145,13 @@ struct imx6_pm_socdata {
0x494, 0x4b0, /* MODE_CTL, MODE, */
};
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+ 0x294, 0x298, 0x29c, 0x2a0, /* DQM0 ~ DQM3 */
+ 0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
+ 0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK_0, GPR_ADDDS */
+ 0x2a4, 0x2a8, /* SDCKE0, SDCKE1*/
+};
+
static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.mmdc_compat = "fsl,imx6q-mmdc",
.src_compat = "fsl,imx6q-src",
@@ -195,6 +202,15 @@ struct imx6_pm_socdata {
.mmdc_io_offset = imx6ul_mmdc_io_offset,
};
+static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6sll-mmdc",
+ .src_compat = "fsl,imx6sll-src",
+ .iomuxc_compat = "fsl,imx6sll-iomuxc",
+ .gpc_compat = "fsl,imx6sll-gpc",
+ .pl310_compat = "arm,pl310-cache",
+ .mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
+ .mmdc_io_offset = imx6sll_mmdc_io_offset,
+};
/*
* This structure is for passing necessary data for low level ocram
* suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
@@ -293,9 +309,10 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x2 << BP_CLPCR_LPM;
val &= ~BM_CLPCR_VSTBY;
val &= ~BM_CLPCR_SBYOS;
- if (cpu_is_imx6sl())
+ if (cpu_is_imx6sl() || cpu_is_imx6sll())
val |= BM_CLPCR_BYPASS_PMIC_READY;
- if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
+ cpu_is_imx6sll())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -310,9 +327,10 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x3 << BP_CLPCR_STBY_COUNT;
val |= BM_CLPCR_VSTBY;
val |= BM_CLPCR_SBYOS;
- if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6sll())
val |= BM_CLPCR_BYPASS_PMIC_READY;
- if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() ||
+ cpu_is_imx6ul() || cpu_is_imx6sll())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -373,6 +391,7 @@ static int imx6q_pm_enter(suspend_state_t state)
imx6sl_set_wait_clk(true);
/* Zzz ... */
cpu_do_idle();
+
if (cpu_is_imx6sl())
imx6sl_set_wait_clk(false);
imx_gpc_post_resume();
@@ -632,7 +651,10 @@ void __init imx6dl_pm_init(void)
void __init imx6sl_pm_init(void)
{
- imx6_pm_common_init(&imx6sl_pm_data);
+ if (cpu_is_imx6sl())
+ imx6_pm_common_init(&imx6sl_pm_data);
+ else
+ imx6_pm_common_init(&imx6sll_pm_data);
}
void __init imx6sx_pm_init(void)
--
1.9.1
^ permalink raw reply related
* [PATCH v2 11/12] ARM: imx: correct i.mx6sll dram io low power mode
From: Bai Ping @ 2016-12-27 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>
i.MX6SLL has different DRAM IO offset, and it has no
CAS/RAS/ODT/RESET pin now, correct the DRAM IO offset.
To better support all different i.MX6 SoCs and different
DRAM types, introduce a new column to store the low power
settings for DRAM IO, then suspend asm code no need to check
SoC or DRAM type, just get the DRAM IO's low power
settings from OCRAM pm_info and set to each DRAM IO.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
arch/arm/mach-imx/pm-imx6.c | 17 ++++++++++++++++-
arch/arm/mach-imx/suspend-imx6.S | 29 +++++++----------------------
2 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 2ed4316..5fb78a9 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -230,7 +230,7 @@ struct imx6_cpu_pm_info {
struct imx6_pm_base gpc_base;
struct imx6_pm_base l2_base;
u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
- u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+ u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][3]; /* To save offset,value and low power setting */
} __aligned(8);
void imx6_set_int_mem_clk_lpm(bool enable)
@@ -570,6 +570,21 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
pm_info->mmdc_io_val[i][1] =
readl_relaxed(pm_info->iomuxc_base.vbase +
mmdc_offset_array[i]);
+ pm_info->mmdc_io_val[i][2] = 0;
+
+ }
+
+ /* i.MX6SLL has no DRAM RESET pin */
+ if (cpu_is_imx6sll()) {
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 2][2] = 0x1000;
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 1][2] = 0x1000;
+ } else {
+ if (pm_info->ddr_type == IMX_DDR_TYPE_LPDDR2) {
+ /* for LPDDR2, CKE0/1 and RESET pin need special setting */
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 3][2] = 0x1000;
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 2][2] = 0x1000;
+ pm_info->mmdc_io_val[pm_info->mmdc_io_num - 1][2] = 0x80000;
+ }
}
imx6_suspend_in_ocram_fn = fncpy(
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index 76ee2ce..c9a26f4 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -104,7 +104,7 @@
add r7, r7, r0
1:
ldr r8, [r7], #0x4
- ldr r9, [r7], #0x4
+ ldr r9, [r7], #0x8
str r9, [r11, r8]
subs r6, r6, #0x1
bne 1b
@@ -179,7 +179,6 @@ ENTRY(imx6_suspend)
ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
ldr r6, [r11, #0x0]
- /* use r11 to store the IO address */
ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
/* store physical resume addr and pm_info address. */
str r9, [r11, #MX6Q_SRC_GPR1]
@@ -207,32 +206,18 @@ poll_dvfs_set:
ands r7, r7, #(1 << 25)
beq poll_dvfs_set
+ /* use r11 to store the IO address */
ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
- ldr r6, =0x0
- ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
add r8, r8, r0
- /* LPDDR2's last 3 IOs need special setting */
- cmp r3, #IMX_DDR_TYPE_LPDDR2
- subeq r7, r7, #0x3
set_mmdc_io_lpm:
- ldr r9, [r8], #0x8
- str r6, [r11, r9]
- subs r7, r7, #0x1
+ ldr r7, [r8], #0x8
+ ldr r9, [r8], #0x4
+ str r9, [r11, r7]
+ subs r6, r6, #0x1
bne set_mmdc_io_lpm
- cmp r3, #IMX_DDR_TYPE_LPDDR2
- bne set_mmdc_io_lpm_done
- ldr r6, =0x1000
- ldr r9, [r8], #0x8
- str r6, [r11, r9]
- ldr r9, [r8], #0x8
- str r6, [r11, r9]
- ldr r6, =0x80000
- ldr r9, [r8]
- str r6, [r11, r9]
-set_mmdc_io_lpm_done:
-
/*
* mask all GPC interrupts before
* enabling the RBC counters to
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox