* [PATCH V5] ARM: shmobile: Rework the PMIC IRQ line quirk
From: Simon Horman @ 2018-06-13 14:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdUsBNU-1y+_UfX6GKSC11pOB_BUhPKO-axUiO+BfgqVmw@mail.gmail.com>
On Wed, Jun 13, 2018 at 01:21:34PM +0200, Geert Uytterhoeven wrote:
> Hi Simon,
>
> On Wed, Jun 13, 2018 at 1:06 PM Simon Horman <horms@verge.net.au> wrote:
> > On Mon, Jun 11, 2018 at 02:15:13PM +0200, Marek Vasut wrote:
> > > Rather than hard-coding the quirk topology, which stopped scaling,
> > > parse the information from DT. The code looks for all compatible
> > > PMICs -- da9063 and da9210 -- and checks if their IRQ line is tied
> > > to the same pin. If so, the code sends a matching sequence to the
> > > PMIC to deassert the IRQ.
> > >
> > > Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
> > > Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> > > Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> > > Cc: Simon Horman <horms+renesas@verge.net.au>
> > > Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> > > Cc: linux-renesas-soc at vger.kernel.org
> > > Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> > > Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> (on Koelsch)
> >
> > This looks fine to me but I will wait to see if there are other reviews
> > before applying.
> >
> > Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
>
> Note that applying it now will break gose, as its DTS doesn't describe all
> regulators yet.
Ok, so old DT will break with new kernels?
^ permalink raw reply
* [PATCH] ARM64: dts: rockchip: add some pins to rk3399
From: Shawn Lin @ 2018-06-13 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <B649911B-28E0-4466-B3F0-15875FFB9D43@theobroma-systems.com>
On 2018/6/13 2:21, klaus.goger at theobroma-systems.com wrote:
> Hi Randy,
-----8<-------------
>> pcie {
>> + pcie_clkreqn: pci-clkreqn {
>> + rockchip,pins =
>> + <2 26 RK_FUNC_2 &pcfg_pull_none>;
>> + };
>> +
>> + pcie_clkreqnb: pci-clkreqnb {
>> + rockchip,pins =
>> + <4 24 RK_FUNC_1 &pcfg_pull_none>;
>> + };
>> +
>
> I?m not sure if pci-clkreqn is functional at all. If not I?m not sure if we should add it to the dtsi.
> Shawn may know more about it.
Please refer to commit 461a00bb9d539e
("arm64: dts: rockchip: kill pcie_clkreqn and pcie_clkreqnb for rk3399")
CLKREQ# is used for PCI-PM L1.x, but it's not functional for rk3399, so
we have to support CPM(clock power management), thus I kill them last
year.
>
>> pcie_clkreqn_cpm: pci-clkreqn-cpm {
>> rockchip,pins =
>> - <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
>> + <2 26 RK_FUNC_GPIO &pcfg_pull_none>;
>> };
>>
>> pcie_clkreqnb_cpm: pci-clkreqnb-cpm {
>> rockchip,pins =
>> - <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
>> + <4 24 RK_FUNC_GPIO &pcfg_pull_none>;
>> };
>> };
>>
>> --
>> 2.14.4
>
>
> Could we actually use RK_Pxx for all new pin definitions? Would increase readability a lot.
>
> Thanks,
> Klaus
>
>
--
Best Regards
Shawn Lin
^ permalink raw reply
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Ard Biesheuvel @ 2018-06-13 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <26470c5c-55db-9dff-3794-4e4a96c8bcb6@codeaurora.org>
On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
> Hi Ard,
>
> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>> A host bridge is allowed to remap BAR addresses using _TRA attribute in
>> _CRS windows.
>>
>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff window] (bus address [0x00100000-0x1fffffff])
>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>
>> When a VGA device is behind such a host bridge and the resource is
>> translated efifb driver is trying to do ioremap against bus address
>> rather than the resource address and is failing to probe.
>>
>> efifb: probing for efifb
>> efifb: cannot reserve video memory at 0x1e000000
>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>> efifb: mode is 800x600x32, linelength=3200, pages=1
>> efifb: scrolling: redraw
>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>
>> Use the host bridge offset information to convert bus address to
>> resource address in the fixup.
>>
>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>> ---
>
> I didn't see any messages about these getting picked up for 4.18.
>
> Are they queued on your own branch?
>
No, you never cc'ed me on them until now.
^ permalink raw reply
* [PATCH/RFT v2 2/2] arm64: dts: r8a77995: Add all HSCIF nodes
From: Simon Horman @ 2018-06-13 15:09 UTC (permalink / raw)
To: linux-arm-kernel
From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
This patch adds the device nodes all HSCIF serial ports
incl. clocks and power domain to the R8A77995 SoC.
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
[simon: updated internal clock from S3D1 to S3D1C to match documentation]
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm64/boot/dts/renesas/r8a77995.dtsi | 35 +++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
Based on renesas-devel-20180613-v4.17
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 16cbb34692ad..0a9caf9cdc86 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -242,6 +242,41 @@
resets = <&cpg 407>;
};
+ hscif0: serial at e6540000 {
+ compatible = "renesas,hscif-r8a77995",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe6540000 0 0x60>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 520>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+ <&dmac2 0x31>, <&dmac2 0x30>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 520>;
+ status = "disabled";
+ };
+
+ hscif3: serial at e66a0000 {
+ compatible = "renesas,hscif-r8a77995",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe66a0000 0 0x60>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 517>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 517>;
+ status = "disabled";
+ };
+
i2c0: i2c at e6500000 {
#address-cells = <1>;
#size-cells = <0>;
--
2.11.0
^ permalink raw reply related
* [PATCH] arm64: dts: hikey: Define wl1835 power capabilities
From: Ryan Grachek @ 2018-06-13 15:13 UTC (permalink / raw)
To: linux-arm-kernel
These properties are required for compatibility with runtime PM.
Without these properties, MMC host controller will not be aware
of power capabilities. When the wlcore driver attempts to power
on the device, it will erroneously fail with -EACCES.
Signed-off-by: Ryan Grachek <ryan@edited.us>
---
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index 38f881955217..c5feca8cd10b 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -323,6 +323,8 @@
bus-width = <0x4>;
cap-sd-highspeed;
non-removable;
+ cap-power-off-card;
+ keep-power-in-suspend;
vmmc-supply = <®_vdd_3v3>;
mmc-pwrseq = <&wl1835_pwrseq>;
--
2.11.0
^ permalink raw reply related
* [PATCH/RFT v2 1/2] arm64: dts: r8a77995: Add SCIF-{0, 1, 3, 4, 5} device nodes
From: Simon Horman @ 2018-06-13 15:13 UTC (permalink / raw)
To: linux-arm-kernel
From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
This patch adds the device nodes for SCIF-{0,1,3,4,5} serial ports,
incl. clocks and power domain.
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
[simon: updated internal clock from S3D1 to S3D1C to match documentation]
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm64/boot/dts/renesas/r8a77995.dtsi | 70 +++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
Based on renesas-devel-20180613-v4.17
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 1de6ffca4772..16cbb34692ad 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -605,6 +605,34 @@
status = "disabled";
};
+ scif0: serial at e6e60000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 207>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 207>;
+ status = "disabled";
+ };
+
+ scif1: serial at e6e68000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 206>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 206>;
+ status = "disabled";
+ };
+
scif2: serial at e6e88000 {
compatible = "renesas,scif-r8a77995",
"renesas,rcar-gen3-scif", "renesas,scif";
@@ -622,6 +650,48 @@
status = "disabled";
};
+ scif3: serial at e6c50000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 204>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 204>;
+ status = "disabled";
+ };
+
+ scif4: serial at e6c40000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 203>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 203>;
+ status = "disabled";
+ };
+
+ scif5: serial at e6f30000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6f30000 0 64>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 202>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 202>;
+ status = "disabled";
+ };
+
vin4: video at e6ef4000 {
compatible = "renesas,vin-r8a77995";
reg = <0 0xe6ef4000 0 0x1000>;
--
2.11.0
^ permalink raw reply related
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: okaya at codeaurora.org @ 2018-06-13 15:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8UG_D0AAR8Usdi7DrucqaEs+f-JTU1voR-CcrtNY2ZEQ@mail.gmail.com>
On 2018-06-13 11:06, Ard Biesheuvel wrote:
> On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
>> Hi Ard,
>>
>> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>>> A host bridge is allowed to remap BAR addresses using _TRA attribute
>>> in
>>> _CRS windows.
>>>
>>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff
>>> window] (bus address [0x00100000-0x1fffffff])
>>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>>
>>> When a VGA device is behind such a host bridge and the resource is
>>> translated efifb driver is trying to do ioremap against bus address
>>> rather than the resource address and is failing to probe.
>>>
>>> efifb: probing for efifb
>>> efifb: cannot reserve video memory at 0x1e000000
>>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>>> efifb: mode is 800x600x32, linelength=3200, pages=1
>>> efifb: scrolling: redraw
>>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>>
>>> Use the host bridge offset information to convert bus address to
>>> resource address in the fixup.
>>>
>>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>>> ---
>>
>> I didn't see any messages about these getting picked up for 4.18.
>>
>> Are they queued on your own branch?
>>
>
> No, you never cc'ed me on them until now.
Ouch, I hoped that you would get it via get_maintainer script. Sorry for
that.
^ permalink raw reply
* [PATCH] arm64: dts: qcom: Add pm8005 and pm8998 support
From: Stephen Boyd @ 2018-06-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
Add basic support for the pm8005 and pm8998 PMICs. For now just support
the GPIO controllers.
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
arch/arm64/boot/dts/qcom/pm8005.dtsi | 33 +++++++++++++++++
arch/arm64/boot/dts/qcom/pm8998.dtsi | 55 ++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/pm8005.dtsi
create mode 100644 arch/arm64/boot/dts/qcom/pm8998.dtsi
diff --git a/arch/arm64/boot/dts/qcom/pm8005.dtsi b/arch/arm64/boot/dts/qcom/pm8005.dtsi
new file mode 100644
index 000000000000..4d5aca3eeb69
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8005.dtsi
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright 2018 Google LLC. */
+
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&spmi_bus {
+ pm8005_lsid0: pmic at 4 {
+ compatible = "qcom,pm8005", "qcom,spmi-pmic";
+ reg = <0x4 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8005_gpio: gpios at c000 {
+ compatible = "qcom,pm8005-gpio", "qcom,spmi-gpio";
+ reg = <0xc000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+ <0 0xc1 0 IRQ_TYPE_NONE>,
+ <0 0xc2 0 IRQ_TYPE_NONE>,
+ <0 0xc3 0 IRQ_TYPE_NONE>;
+ };
+
+ };
+
+ pm8005_lsid1: pmic at 5 {
+ compatible = "qcom,pm8005", "qcom,spmi-pmic";
+ reg = <0x5 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
new file mode 100644
index 000000000000..92bed1e7d4bb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright 2018 Google LLC. */
+
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&spmi_bus {
+ pm8998_lsid0: pmic at 0 {
+ compatible = "qcom,pm8998", "qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8998_gpio: gpios at c000 {
+ compatible = "qcom,pm8998-gpio", "qcom,spmi-gpio";
+ reg = <0xc000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+ <0 0xc1 0 IRQ_TYPE_NONE>,
+ <0 0xc2 0 IRQ_TYPE_NONE>,
+ <0 0xc3 0 IRQ_TYPE_NONE>,
+ <0 0xc4 0 IRQ_TYPE_NONE>,
+ <0 0xc5 0 IRQ_TYPE_NONE>,
+ <0 0xc6 0 IRQ_TYPE_NONE>,
+ <0 0xc7 0 IRQ_TYPE_NONE>,
+ <0 0xc8 0 IRQ_TYPE_NONE>,
+ <0 0xc9 0 IRQ_TYPE_NONE>,
+ <0 0xca 0 IRQ_TYPE_NONE>,
+ <0 0xcb 0 IRQ_TYPE_NONE>,
+ <0 0xcc 0 IRQ_TYPE_NONE>,
+ <0 0xcd 0 IRQ_TYPE_NONE>,
+ <0 0xce 0 IRQ_TYPE_NONE>,
+ <0 0xcf 0 IRQ_TYPE_NONE>,
+ <0 0xd0 0 IRQ_TYPE_NONE>,
+ <0 0xd1 0 IRQ_TYPE_NONE>,
+ <0 0xd2 0 IRQ_TYPE_NONE>,
+ <0 0xd3 0 IRQ_TYPE_NONE>,
+ <0 0xd4 0 IRQ_TYPE_NONE>,
+ <0 0xd5 0 IRQ_TYPE_NONE>,
+ <0 0xd6 0 IRQ_TYPE_NONE>,
+ <0 0xd7 0 IRQ_TYPE_NONE>,
+ <0 0xd8 0 IRQ_TYPE_NONE>,
+ <0 0xd9 0 IRQ_TYPE_NONE>;
+ };
+
+ };
+
+ pm8998_lsid1: pmic at 1 {
+ compatible = "qcom,pm8998", "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
--
Sent by a computer through tubes
^ permalink raw reply related
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Ard Biesheuvel @ 2018-06-13 15:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <442896963833043f84dd9d0c14d88351@codeaurora.org>
On 13 June 2018 at 17:17, <okaya@codeaurora.org> wrote:
> On 2018-06-13 11:06, Ard Biesheuvel wrote:
>>
>> On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
>>>
>>> Hi Ard,
>>>
>>> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>>>>
>>>> A host bridge is allowed to remap BAR addresses using _TRA attribute in
>>>> _CRS windows.
>>>>
>>>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff
>>>> window] (bus address [0x00100000-0x1fffffff])
>>>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>>>
>>>> When a VGA device is behind such a host bridge and the resource is
>>>> translated efifb driver is trying to do ioremap against bus address
>>>> rather than the resource address and is failing to probe.
>>>>
>>>> efifb: probing for efifb
>>>> efifb: cannot reserve video memory at 0x1e000000
>>>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>>>> efifb: mode is 800x600x32, linelength=3200, pages=1
>>>> efifb: scrolling: redraw
>>>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>>>
>>>> Use the host bridge offset information to convert bus address to
>>>> resource address in the fixup.
>>>>
>>>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>>>> ---
>>>
>>>
>>> I didn't see any messages about these getting picked up for 4.18.
>>>
>>> Are they queued on your own branch?
>>>
>>
>> No, you never cc'ed me on them until now.
>
>
> Ouch, I hoped that you would get it via get_maintainer script. Sorry for
> that.
Actually, get_maintainer is right: this should go through the fbdev
tree not the EFI tree
Were you going to resend them? If not, I can find them in my archive
and ack them, and we will ask Bartlomiej to take them for v4.19
^ permalink raw reply
* [PATCH/RFT v2 1/2] arm64: dts: r8a77995: Add SCIF-{0,1,3,4,5} device nodes
From: Sergei Shtylyov @ 2018-06-13 15:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613151348.28697-1-horms+renesas@verge.net.au>
Hello!
On 06/13/2018 06:13 PM, Simon Horman wrote:
> From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
>
> This patch adds the device nodes for SCIF-{0,1,3,4,5} serial ports,
Why hyphen between SCIF and # here in the subject?
> incl. clocks and power domain.
>
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
> [simon: updated internal clock from S3D1 to S3D1C to match documentation]
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
[...]
MBR, Sergei
^ permalink raw reply
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: okaya at codeaurora.org @ 2018-06-13 15:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_ZRNvW9CeqRyUpQGnrkkoOi1Hh08re=_Gz=EGVTAvbsA@mail.gmail.com>
On 2018-06-13 11:22, Ard Biesheuvel wrote:
> On 13 June 2018 at 17:17, <okaya@codeaurora.org> wrote:
>> On 2018-06-13 11:06, Ard Biesheuvel wrote:
>>>
>>> On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
>>>>
>>>> Hi Ard,
>>>>
>>>> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>>>>>
>>>>> A host bridge is allowed to remap BAR addresses using _TRA
>>>>> attribute in
>>>>> _CRS windows.
>>>>>
>>>>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff
>>>>> window] (bus address [0x00100000-0x1fffffff])
>>>>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>>>>
>>>>> When a VGA device is behind such a host bridge and the resource is
>>>>> translated efifb driver is trying to do ioremap against bus address
>>>>> rather than the resource address and is failing to probe.
>>>>>
>>>>> efifb: probing for efifb
>>>>> efifb: cannot reserve video memory at 0x1e000000
>>>>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>>>>> efifb: mode is 800x600x32, linelength=3200, pages=1
>>>>> efifb: scrolling: redraw
>>>>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>>>>
>>>>> Use the host bridge offset information to convert bus address to
>>>>> resource address in the fixup.
>>>>>
>>>>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>>>>> ---
>>>>
>>>>
>>>> I didn't see any messages about these getting picked up for 4.18.
>>>>
>>>> Are they queued on your own branch?
>>>>
>>>
>>> No, you never cc'ed me on them until now.
>>
>>
>> Ouch, I hoped that you would get it via get_maintainer script. Sorry
>> for
>> that.
>
> Actually, get_maintainer is right: this should go through the fbdev
> tree not the EFI tree
>
> Were you going to resend them? If not, I can find them in my archive
> and ack them, and we will ask Bartlomiej to take them for v4.19
I prefer ack rather than resend to be honest.
^ permalink raw reply
* [PATCH V2 1/2] efi/fb: Simplify fixup code to prefer struct resource
From: Ard Biesheuvel @ 2018-06-13 15:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526653072-7153-1-git-send-email-okaya@codeaurora.org>
On 18 May 2018 at 16:17, Sinan Kaya <okaya@codeaurora.org> wrote:
> Get rid of base and size variables in favor of a struct resource.
> The conditional for checking window can be replaced with
> resource_contains().
>
> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> drivers/video/fbdev/efifb.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
> index 46a4484..6daac8d 100644
> --- a/drivers/video/fbdev/efifb.c
> +++ b/drivers/video/fbdev/efifb.c
> @@ -426,17 +426,20 @@ static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset)
>
> static void efifb_fixup_resources(struct pci_dev *dev)
> {
> - u64 base = screen_info.lfb_base;
> - u64 size = screen_info.lfb_size;
> + struct resource screen_res = {
> + .start = screen_info.lfb_base,
> + .end = screen_info.lfb_base + screen_info.lfb_size - 1,
> + .flags = IORESOURCE_MEM,
> + };
> int i;
>
> if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
> return;
>
> if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
> - base |= (u64)screen_info.ext_lfb_base << 32;
> + screen_res.start |= (u64)screen_info.ext_lfb_base << 32;
>
> - if (!base)
> + if (!screen_res.start)
> return;
>
> for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
> @@ -445,8 +448,10 @@ static void efifb_fixup_resources(struct pci_dev *dev)
> if (!(res->flags & IORESOURCE_MEM))
> continue;
>
> - if (res->start <= base && res->end >= base + size - 1) {
> - record_efifb_bar_resource(dev, i, base - res->start);
> + if (resource_contains(res, &screen_res)) {
> + u64 win_offset = screen_res.start - res->start;
> +
> + record_efifb_bar_resource(dev, i, win_offset);
> break;
> }
> }
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Ard Biesheuvel @ 2018-06-13 15:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526653072-7153-2-git-send-email-okaya@codeaurora.org>
On 18 May 2018 at 16:17, Sinan Kaya <okaya@codeaurora.org> wrote:
> A host bridge is allowed to remap BAR addresses using _TRA attribute in
> _CRS windows.
>
> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff window] (bus address [0x00100000-0x1fffffff])
> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>
> When a VGA device is behind such a host bridge and the resource is
> translated efifb driver is trying to do ioremap against bus address
> rather than the resource address and is failing to probe.
>
> efifb: probing for efifb
> efifb: cannot reserve video memory at 0x1e000000
> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
> efifb: mode is 800x600x32, linelength=3200, pages=1
> efifb: scrolling: redraw
> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>
> Use the host bridge offset information to convert bus address to
> resource address in the fixup.
>
> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Bartlomiej, could you please take these via the fbdev tree for v4.19?
Peter already gave his ack but Sinan dropped it (presumably because of
the split in v2)
Sinan, does this need to go to -stable? I.e., has it ever worked before?
> ---
> drivers/video/fbdev/efifb.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
> index 6daac8d..429cc85 100644
> --- a/drivers/video/fbdev/efifb.c
> +++ b/drivers/video/fbdev/efifb.c
> @@ -431,6 +431,7 @@ static void efifb_fixup_resources(struct pci_dev *dev)
> .end = screen_info.lfb_base + screen_info.lfb_size - 1,
> .flags = IORESOURCE_MEM,
> };
> + struct pci_bus_region region;
> int i;
>
> if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
> @@ -442,6 +443,10 @@ static void efifb_fixup_resources(struct pci_dev *dev)
> if (!screen_res.start)
> return;
>
> + region.start = screen_res.start;
> + region.end = screen_res.end;
> + pcibios_bus_to_resource(dev->bus, &screen_res, ®ion);
> +
> for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
> struct resource *res = &dev->resource[i];
>
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 2/4] ARM: Introduce ability to enable invalidate of BTB with ICIALLU on Cortex-A15 for CVE-2017-5715
From: Tom Rini @ 2018-06-13 15:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613133215.2cv7iyjb2laaha3j@kahuna>
On Wed, Jun 13, 2018 at 08:32:15AM -0500, Nishanth Menon wrote:
> On 23:05-20180612, Marek Vasut wrote:
> > On 06/12/2018 10:24 PM, Nishanth Menon wrote:
> [..]
> > > +#ifdef CONFIG_ARM_CORTEX_A15_CVE_2017_5715
> > > + mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
> > > + orr r0, r0, #1 << 0 @ Enable invalidates of BTB
> >
> > Can we use BIT() macro in the assembler code too ?
>
> Probably, but just following convention in the rest of the file. Do we
> want to change from existing code?
Agreed, we should follow the existing style (and I'm not 100% sure I
like using BIT() in asm files).
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180613/cebb11ee/attachment-0001.sig>
^ permalink raw reply
* [RFC PATCH 6/8] dts: coresight: Clean up the device tree graph bindings
From: Matt Sealey @ 2018-06-13 15:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c0d531ec-9201-bfd8-e6c3-9140698b0697@arm.com>
Hi Suzuki,
> > Why not use ?unit??
> >
> > I believe we had this discussion years ago about numbering serial ports
> > and sdhci (i.e. how do you know it?s UART0 or UART1 from just the address?
> > Some SoC?s don?t address sequentially *or* in a forward direction) - I
> > believe it?s not exactly codified in ePAPR, not am I sure where it may be
> > otherwise, but it exists.
>
> We have different situation here. We need to know *the port number* as
> understood by the hardware, so that we can enable *the specific* port for
> a given path.
For the purposes of abstraction, each port will have the property of having
a node which is pointed to by other nodes, and in the case of a true ATB
endpoint, no other nodes behind it.
It doesn't matter what the HW numbers it as as long as the driver can derive
it from whatever you put in the DT. So a funnel (which is ~8 ports muxed into
one output):
f1p0: port {
unit = <0>;
endpoint = <&f1out>;
};
f1p1: port {
unit = <4>;
endpoint = <&f1out>;
};
f1out: port {
endpoint = <&etf1>;
};
"unit" here is specific to the driver's understanding of ports within it's
own cycle of the graph. For a replicator you can invert the logic - input
ports don't need a unit, but the two outputs are filtered in CoreSight not
by leg but by transiting ATB ID in groups of 16 IDs. In that case maybe
you would want to describe all 8 possible units on each leg with the first
ID it would filter? Or just list tuples of filter IDs <id, first, last>
Who cares, really, as long as the driver knows what it means.
You don't need to namespace every property.
> As I mentioned above, we need the hardware numbers to enable the
> "specific" port.
Okay and how is this not able to be prescribed in a binding for "arm,coresight-funnel"
that:
"input ports are numbered from 0 to N where N is the maximum input port
number. This number is identified with the "unit" property, which directly
corresponds to the bit position in the funnel Ctrl_Reg register, and the
bit position multiplied by 3 for each 3-bit priority in the funnel
Priority_Ctrl_Reg, with N having a maximum of the defined register bitfield
DEVID[PORTCOUNT], minus one, for that component"
Or a replicator:
"output ports are numbered per the CoreSight ATB Replicator specification,
unit corresponding to the IDFILTERn register controlling ID filters for
that leg, with a maximum of the defined register bitfield DEVID[PORTNUM],
minus one"
One could clarify it, even, with labels for readability ("label" definitely
is a well defined if also completely arbitrary property).
..
> static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
> {
> u32 functl;
>
> CS_UNLOCK(drvdata->base);
>
> functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL);
> functl &= ~FUNNEL_HOLDTIME_MASK;
> functl |= FUNNEL_HOLDTIME;
> functl |= (1 << port);
> writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL);
> writel_relaxed(drvdata->priority, drvdata->base + FUNNEL_PRICTL);
>
> CS_LOCK(drvdata->base);
> }
>
> No we don't need to parse it in both ways, up and down. Btw, the trace
> paths are not statically created. They are done at runtime, as configured
> by the user.
You do realize this isn't how the hardware works, correct?
Trace paths are fixed, they may diverge with different configurations, but
the full CoreSight topology (all funnels, replicators and intermediary
Components) is entirely unchangeable.
The DT should provide the information to provide a reference acyclic directed
graph of the entire topology (or entirely reasonably programmable topology where
at all possible) - if a user wants to trace from ETM_0 then they only
have particular paths to particular sinks, for instance ETM_0 and ETF_0
may be on their own path, so you cannot just "configure as a user"
a path from ETM_1 to ETF_0 since there isn't one.
Walking said graphs with the knowledge that CoreSight specifically disallows
loopbacks in ATB topology is basic computer science problem - literally a
matter of topological sorting. But let's build a graph once and traverse it -
don't build the graph partially each time or try and build it to cross-check
every time. The paths are wires in the design, lets not fake to the user
that there is any configurability in that or try and encode that in the
DT.
> Coming back to your suggestion of "unit", what does it imply ?
Whatever the driver likes. For uart and mmc, it was just a spurious number
but it could be applied as the end of, say, ttyS<N> or mmcblk<N>p3 or used
in any other driver-specific manner. The number you put in is up to you,
but the valid numbers would be in the binding for that particular device.
> Its too generic a term for something as concrete as a port number.
Is it?
Why would you need a whole other property type to encode a u32 that
describes an arbitrary number specific to that hardware device?
Ta,
Matt
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
^ permalink raw reply
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: okaya at codeaurora.org @ 2018-06-13 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu9+M8zOtACPQ4_UMgp-M1LfZnciYe1VTQNqn_zNWJea4g@mail.gmail.com>
On 2018-06-13 11:45, Ard Biesheuvel wrote:
> On 18 May 2018 at 16:17, Sinan Kaya <okaya@codeaurora.org> wrote:
>> A host bridge is allowed to remap BAR addresses using _TRA attribute
>> in
>> _CRS windows.
>>
>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff
>> window] (bus address [0x00100000-0x1fffffff])
>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>
>> When a VGA device is behind such a host bridge and the resource is
>> translated efifb driver is trying to do ioremap against bus address
>> rather than the resource address and is failing to probe.
>>
>> efifb: probing for efifb
>> efifb: cannot reserve video memory at 0x1e000000
>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>> efifb: mode is 800x600x32, linelength=3200, pages=1
>> efifb: scrolling: redraw
>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>
>> Use the host bridge offset information to convert bus address to
>> resource address in the fixup.
>>
>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> Bartlomiej, could you please take these via the fbdev tree for v4.19?
> Peter already gave his ack but Sinan dropped it (presumably because of
> the split in v2)
>
> Sinan, does this need to go to -stable? I.e., has it ever worked
> before?
>
Yes, it needs to go to stable. It never worked before. Issue was found
during a graphics bring up with AST driver.
It needs a 32 bit graphics card and a 32 bit translating host bridge to
hit the issue.
>
>
>> ---
>> drivers/video/fbdev/efifb.c | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
>> index 6daac8d..429cc85 100644
>> --- a/drivers/video/fbdev/efifb.c
>> +++ b/drivers/video/fbdev/efifb.c
>> @@ -431,6 +431,7 @@ static void efifb_fixup_resources(struct pci_dev
>> *dev)
>> .end = screen_info.lfb_base + screen_info.lfb_size -
>> 1,
>> .flags = IORESOURCE_MEM,
>> };
>> + struct pci_bus_region region;
>> int i;
>>
>> if (efifb_pci_dev || screen_info.orig_video_isVGA !=
>> VIDEO_TYPE_EFI)
>> @@ -442,6 +443,10 @@ static void efifb_fixup_resources(struct pci_dev
>> *dev)
>> if (!screen_res.start)
>> return;
>>
>> + region.start = screen_res.start;
>> + region.end = screen_res.end;
>> + pcibios_bus_to_resource(dev->bus, &screen_res, ®ion);
>> +
>> for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
>> struct resource *res = &dev->resource[i];
>>
>> --
>> 2.7.4
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 4/4] net: emaclite: Remove xemaclite_mdio_setup return check
From: Radhey Shyam Pandey @ 2018-06-13 16:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613072905.GE24314@lunn.ch>
> -----Original Message-----
> From: Andrew Lunn [mailto:andrew at lunn.ch]
> Sent: Wednesday, June 13, 2018 12:59 PM
> To: Radhey Shyam Pandey <radheys@xilinx.com>
> Cc: davem at davemloft.net; michal.simek at xilinx.com;
> netdev at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org
> Subject: Re: [PATCH 4/4] net: emaclite: Remove xemaclite_mdio_setup return
> check
>
> On Wed, Jun 13, 2018 at 12:05:19PM +0530, Radhey Shyam Pandey wrote:
> > Errors are already reported in xemaclite_mdio_setup so avoid
> > reporting it again.
> >
> > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> > drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 +---
> > 1 files changed, 1 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> > index ec4608e..2a0c06e 100644
> > --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> > +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> > @@ -1143,9 +1143,7 @@ static int xemaclite_of_probe(struct
> platform_device *ofdev)
> > xemaclite_update_address(lp, ndev->dev_addr);
> >
> > lp->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-
> handle", 0);
> > - rc = xemaclite_mdio_setup(lp, &ofdev->dev);
> > - if (rc)
> > - dev_warn(&ofdev->dev, "error registering MDIO bus\n");
> > + xemaclite_mdio_setup(lp, &ofdev->dev);
> >
> > dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr);
>
> The patch itself is O.K.
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
>
> However, do you want to keep going if the MDIO bus fails? Maybe you
> should failed the probe?
Thanks for the review. Yes, I will fix it in next series.
-Radhey
>
> Andrew
^ permalink raw reply
* [linux-sunxi] Re: [PATCH v2 04/27] dt-bindings: display: sunxi-drm: Add TCON TOP description
From: Jernej Škrabec @ 2018-06-13 16:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613073456.jk72zw4rt4ysjco7@flea>
Hi,
Dne sreda, 13. junij 2018 ob 09:34:56 CEST je Maxime Ripard napisal(a):
> Hi,
>
> Thanks for working on this!
>
> On Tue, Jun 12, 2018 at 10:00:13PM +0200, Jernej Skrabec wrote:
> > TCON TOP main purpose is to configure whole display pipeline. It
> > determines relationships between mixers and TCONs, selects source TCON
> > for HDMI, muxes LCD and TV encoder GPIO output, selects TV encoder
> > clock source and contains additional TV TCON and DSI gates.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> >
> > .../bindings/display/sunxi/sun4i-drm.txt | 45 +++++++++++++++++++
> > include/dt-bindings/clock/sun8i-tcon-top.h | 11 +++++
> > 2 files changed, 56 insertions(+)
> > create mode 100644 include/dt-bindings/clock/sun8i-tcon-top.h
> >
> > diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> > b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index
> > 3346c1e2a7a0..ef64c589a4b3 100644
> > --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> > +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> >
> > @@ -187,6 +187,51 @@ And on the A23, A31, A31s and A33, you need one more
clock line:
> > - 'lvds-alt': An alternative clock source, separate from the TCON
> > channel 0
> >
> > clock, that can be used to drive the LVDS clock
> >
> > +TCON TOP
> > +--------
> > +
> > +TCON TOPs main purpose is to configure whole display pipeline. It
> > determines +relationships between mixers and TCONs, selects source TCON
> > for HDMI, muxes +LCD and TV encoder GPIO output, selects TV encoder clock
> > source and contains +additional TV TCON and DSI gates.
> > +
> > +It allows display pipeline to be configured in very different ways:
> > +
> > + / LCD0/LVDS0
> > + / TCON-LCD0
> > + | \ MIPI DSI
> > + mixer0 |
> > + \ / TCON-LCD1 - LCD1/LVDS1
> > + TCON-TOP
> > + / \ TCON-TV0 - TVE0/RGB
> > + mixer1 | \
> > + | TCON-TOP - HDMI
> > + | /
> > + \ TCON-TV1 - TVE1/RGB
> > +
> > +Note that both TCON TOP references same physical unit.
> > +
> > +Required properties:
> > + - compatible: value must be one of:
> > + * allwinner,sun8i-r40-tcon-top
> > + - reg: base address and size of the memory-mapped region.
> > + - clocks: phandle to the clocks feeding the TCON TOP
> > + * bus: TCON TOP interface clock
> > + - clock-names: clock name mentioned above
> > + - resets: phandle to the reset line driving the DRC
>
> s/DRC/TCON TOP/ ?
Yes, copy & paste issue
>
> > + * rst: TCON TOP reset line
>
> Remaining consistent with the clock name would be great
You mean "ahb"? I noticed that most other nodes with reset lines don't have a
name associated. Maybe I could just drop it and use first specified reset?
>
> > + - reset-names: reset name mentioned above
> > + - #clock-cells : must contain 1
>
> An example would be nice here
You mean node example? with ports? In the past, Rob was against examples
unless really necessary. Node from R40 DTSI can serve as an example.
>
> > +- ports: A ports node with endpoint definitions as defined in
> > + Documentation/devicetree/bindings/media/video-interfaces.txt. The
> > first port + should be the input for mixer0 mux. The second should be
> > the output for that + mux. Third port should be input for mixer1 mux.
> > Fourth port should be output + for mixer1 mux. Fifth port should be
> > input for HDMI mux. Sixth port should + be output for it. All output
> > endpoints should have reg property with the id + of the target TCON.
> > All ports should have only one enpoint connected to
> ^ endpoint
>
> I guess it would me more readable if you were to make it a bullet
> list, but this works for me otherwise.
Since I have to fix this patch anyway, I can refactor this text.
Best regards,
Jernej
^ permalink raw reply
* [linux-sunxi] Re: [PATCH v2 24/27] drm: of: Export drm_crtc_port_mask()
From: Jernej Škrabec @ 2018-06-13 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613073605.gnhcwrywooxhyryj@flea>
Dne sreda, 13. junij 2018 ob 09:36:05 CEST je Maxime Ripard napisal(a):
> On Tue, Jun 12, 2018 at 10:00:33PM +0200, Jernej Skrabec wrote:
> > Function is useful when drm_of_find_possible_crtcs() can't be used and
> > custom parsing is needed. This can happen for example when there is a
> > node with multiple muxes between crtc and encoder.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> >
> > drivers/gpu/drm/drm_of.c | 4 ++--
> > include/drm/drm_of.h | 8 ++++++++
> > 2 files changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> > index 1fe122461298..2e9cea3287b2 100644
> > --- a/drivers/gpu/drm/drm_of.c
> > +++ b/drivers/gpu/drm/drm_of.c
> > @@ -22,8 +22,8 @@ static void drm_release_of(struct device *dev, void
> > *data)>
> > * Given a port OF node, return the possible mask of the corresponding
> > * CRTC within a device's list of CRTCs. Returns zero if not found.
> > */
> >
> > -static uint32_t drm_crtc_port_mask(struct drm_device *dev,
> > - struct device_node *port)
> > +uint32_t drm_crtc_port_mask(struct drm_device *dev,
> > + struct device_node *port)
>
> It should probably be exported too?
Yes, of course. It will be in next version.
Best regards,
Jernej
^ permalink raw reply
* [PATCH v3 0/6] add virt-dma support for imx-sdma
From: Lucas Stach @ 2018-06-13 16:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528822708.13468.9.camel@nxp.com>
Hi Robin,
Am Dienstag, den 12.06.2018, 08:58 +0000 schrieb Robin Gong:
> Hi Lucas,
> Is the below DEAD LOCK issue same as your side? If yes, then
> I'm afraid that we have to make another patch for uart to split dma
> functions in uart driver out of the code area which protected by
> port.lock. The warning make sense since allocate sdma bd memory
> dynamically in virt-dma instead of static allocated as before. I'll
> make another uart patch into my next version patchset.
Yes, I see the same lockdep splat on my system. Though I'm not sure if
this is really the root cause of the issue I see.
I'm getting timeouts for a serdev attached device and I don't think
this system ever enters memory reclaim, so the issue reported by
lockdep seems to be a mostly theoretical on this system. But lets see
how far I get when you fixed this issue, maybe the real bug is hiding
behind this one.
Regards,
Lucas
^ permalink raw reply
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Bartlomiej Zolnierkiewicz @ 2018-06-13 16:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu9+M8zOtACPQ4_UMgp-M1LfZnciYe1VTQNqn_zNWJea4g@mail.gmail.com>
On Wednesday, June 13, 2018 05:45:48 PM Ard Biesheuvel wrote:
> On 18 May 2018 at 16:17, Sinan Kaya <okaya@codeaurora.org> wrote:
> > A host bridge is allowed to remap BAR addresses using _TRA attribute in
> > _CRS windows.
> >
> > pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff window] (bus address [0x00100000-0x1fffffff])
> > pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
> >
> > When a VGA device is behind such a host bridge and the resource is
> > translated efifb driver is trying to do ioremap against bus address
> > rather than the resource address and is failing to probe.
> >
> > efifb: probing for efifb
> > efifb: cannot reserve video memory at 0x1e000000
> > efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
> > efifb: mode is 800x600x32, linelength=3200, pages=1
> > efifb: scrolling: redraw
> > efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
> >
> > Use the host bridge offset information to convert bus address to
> > resource address in the fixup.
> >
> > Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> Bartlomiej, could you please take these via the fbdev tree for v4.19?
Sure, I will queue it after the current merge window.
> Peter already gave his ack but Sinan dropped it (presumably because of
> the split in v2)
Peter, can I (re)add your ACK to V2 patches?
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* [PATCH 0/2] mtd: rawnand: meson: add Amlogic NAND driver support
From: Yixun Lan @ 2018-06-13 16:13 UTC (permalink / raw)
To: linux-arm-kernel
These two patches try to add initial NAND driver support for Amlogic Meson
SoCs, current it has been tested on GXL(p212) and AXG(s400) platform.
Liang Yang (2):
dt-bindings: nand: meson: add Amlogic NAND controller driver
mtd: rawnand: meson: add support for Amlogic NAND flash controller
.../bindings/mtd/amlogic,meson-nand.txt | 118 ++
drivers/mtd/nand/raw/Kconfig | 8 +
drivers/mtd/nand/raw/Makefile | 3 +
drivers/mtd/nand/raw/meson_nand.c | 1422 +++++++++++++++++
4 files changed, 1551 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
create mode 100644 drivers/mtd/nand/raw/meson_nand.c
--
2.17.1
^ permalink raw reply
* [PATCH 1/2] dt-bindings: nand: meson: add Amlogic NAND controller driver
From: Yixun Lan @ 2018-06-13 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613161314.14894-1-yixun.lan@amlogic.com>
From: Liang Yang <liang.yang@amlogic.com>
Add Amlogic NAND controller dt-bindings for Meson SoC,
Current this driver support GXBB/GXL/AXG platform.
Signed-off-by: Liang Yang <liang.yang@amlogic.com>
Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
---
.../bindings/mtd/amlogic,meson-nand.txt | 118 ++++++++++++++++++
1 file changed, 118 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
new file mode 100644
index 000000000000..eac9f9433d5d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
@@ -0,0 +1,118 @@
+Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
+
+This file documents the properties in addition to those available in
+the MTD NAND bindings.
+
+Required properties:
+- compatible : contains one of:
+ - "amlogic,meson-gxl-nfc"
+ - "amlogic,meson-axg-nfc"
+- clocks :
+ A list of phandle + clock-specifier pairs for the clocks listed
+ in clock-names.
+
+- clock-names: Should contain the following:
+ "core" - NFC module gate clock
+ "clkin0" - Parent clock of internal mux
+ "clkin1" - Other parent clock of internal mux
+
+- pins : Select pins which NFC need.
+- nand_pins: Detail NAND pins information.
+ nand_pins: nand {
+ mux {
+ groups = "emmc_nand_d0",
+ "emmc_nand_d1",
+ "emmc_nand_d2",
+ "emmc_nand_d3",
+ "emmc_nand_d4",
+ "emmc_nand_d5",
+ "emmc_nand_d6",
+ "emmc_nand_d7",
+ "nand_ce0",
+ "nand_rb0",
+ "nand_ale",
+ "nand_cle",
+ "nand_wen_clk",
+ "nand_ren_wr";
+ function = "nand";
+ };
+ };
+
+- amlogic,mmc-syscon : Required for NAND clocks, it's shared with SD/eMMC
+ controller port C
+
+Optional children nodes:
+Children nodes represent the available nand chips.
+
+Optional properties:
+- meson-nand-user-mode :
+ only set 2 or 16 which mean the way of reading OOB bytes by NFC.
+- meson-nand-ran-mode :
+ setting 0 or 1, means disable/enable scrambler which keeps the balence
+ of 0 and 1
+
+Other properties:
+see Documentation/devicetree/bindings/mtd/nand.txt for generic bindings.
+
+Example demonstrate on AXG SoC:
+
+ sd_emmc_c: mmc at 7000 {
+ compatible = "simple-bus", "syscon";
+ reg = <0x0 0x7000 0x0 0x800>;
+ status = "okay";
+ };
+
+ nand: nfc at 7800 {
+ compatible = "amlogic,meson-axg-nfc";
+ reg = <0x0 0x7800 0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ clocks = <&clkc CLKID_SD_EMMC_C>,
+ <&clkc CLKID_SD_EMMC_C_CLK0>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+ amlogic,mmc-syscon = <&sd_mmc_c>;
+
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins>;
+
+ nand at 0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nand-on-flash-bbt;
+ nand-ecc-mode = "hw";
+ nand-ecc-strength = <8>;
+ nand-ecc-step-size = <1024>;
+
+ meson-nand-user-mode = <2>;
+ meson-nand-ran-mode = <1>;
+
+ partition at 0 {
+ label = "boot";
+ reg = <0x00000000 0x00200000>;
+ read-only;
+ };
+ partition at 200000 {
+ label = "env";
+ reg = <0x00200000 0x00400000>;
+ };
+ partition at 600000 {
+ label = "system";
+ reg = <0x00600000 0x00a00000>;
+ };
+ partition at 1000000 {
+ label = "rootfs";
+ reg = <0x01000000 0x03000000>;
+ };
+ partition at 4000000 {
+ label = "media";
+ reg = <0x04000000 0x8000000>;
+ };
+ };
+ };
--
2.17.1
^ permalink raw reply related
* [PATCH 2/2] mtd: rawnand: meson: add support for Amlogic NAND flash controller
From: Yixun Lan @ 2018-06-13 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613161314.14894-1-yixun.lan@amlogic.com>
From: Liang Yang <liang.yang@amlogic.com>
Add initial support for the Amlogic NAND flash controller which found
in the Meson-GXBB/GXL/AXG SoCs.
Singed-off-by: Liang Yang <liang.yang@amlogic.com>
Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
---
drivers/mtd/nand/raw/Kconfig | 8 +
drivers/mtd/nand/raw/Makefile | 3 +
drivers/mtd/nand/raw/meson_nand.c | 1422 +++++++++++++++++++++++++++++
3 files changed, 1433 insertions(+)
create mode 100644 drivers/mtd/nand/raw/meson_nand.c
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 19a2b283fbbe..b3c17a3ca8f4 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -534,4 +534,12 @@ config MTD_NAND_MTK
Enables support for NAND controller on MTK SoCs.
This controller is found on mt27xx, mt81xx, mt65xx SoCs.
+config MTD_NAND_MESON
+ tristate "Support for NAND flash controller on Amlogic's Meson SoCs"
+ depends on ARCH_MESON || COMPILE_TEST
+ select COMMON_CLK_REGMAP_MESON
+ select MFD_SYSCON
+ help
+ Enables support for NAND controller on Amlogic's Meson SoCs.
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 165b7ef9e9a1..cdf6162f38c3 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
+ccflags-$(CONFIG_MTD_NAND_MESON) += -I$(srctree)/drivers/clk/meson
+
obj-$(CONFIG_MTD_NAND) += nand.o
obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o
obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o
@@ -56,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
+obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_amd.o
diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
new file mode 100644
index 000000000000..28abc3684772
--- /dev/null
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -0,0 +1,1422 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Amlogic Meson Nand Flash Controller Driver
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Liang Yang <liang.yang@amlogic.com>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/module.h>
+#include <linux/iopoll.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include "clk-regmap.h"
+
+#define NFC_REG_CMD 0x00
+#define NFC_REG_CFG 0x04
+#define NFC_REG_DADR 0x08
+#define NFC_REG_IADR 0x0c
+#define NFC_REG_BUF 0x10
+#define NFC_REG_INFO 0x14
+#define NFC_REG_DC 0x18
+#define NFC_REG_ADR 0x1c
+#define NFC_REG_DL 0x20
+#define NFC_REG_DH 0x24
+#define NFC_REG_CADR 0x28
+#define NFC_REG_SADR 0x2c
+#define NFC_REG_PINS 0x30
+#define NFC_REG_VER 0x38
+
+
+#define NFC_CMD_DRD (0x8 << 14)
+#define NFC_CMD_IDLE (0xc << 14)
+#define NFC_CMD_DWR (0x4 << 14)
+#define NFC_CMD_CLE (0x5 << 14)
+#define NFC_CMD_ALE (0x6 << 14)
+#define NFC_CMD_ADL ((0 << 16) | (3 << 20))
+#define NFC_CMD_ADH ((1 << 16) | (3 << 20))
+#define NFC_CMD_AIL ((2 << 16) | (3 << 20))
+#define NFC_CMD_AIH ((3 << 16) | (3 << 20))
+#define NFC_CMD_SEED ((8 << 16) | (3 << 20))
+#define NFC_CMD_M2N ((0 << 17) | (2 << 20))
+#define NFC_CMD_N2M ((1 << 17) | (2 << 20))
+#define NFC_CMD_RB (1 << 20)
+#define NFC_CMD_IO6 ((0xb << 10) | (1 << 18))
+
+#define NFC_RB_USED (1 << 23)
+#define NFC_LARGE_PAGE (1 << 22)
+#define NFC_RW_OPS (2 << 20)
+
+#define NAND_TWB_TIME_CYCLE 10
+
+#define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \
+ ( \
+ (cmd_dir) | \
+ ((ran) << 19) | \
+ ((bch) << 14) | \
+ ((short_mode) << 13) | \
+ (((page_size) & 0x7f) << 6) | \
+ ((pages) & 0x3f) \
+ )
+
+#define GENCMDDADDRL(adl, addr) ((adl) | ((addr) & 0xffff))
+#define GENCMDDADDRH(adh, addr) ((adh) | (((addr) >> 16) & 0xffff))
+#define GENCMDIADDRL(ail, addr) ((ail) | ((addr) & 0xffff))
+#define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff))
+
+#define RB_STA(x) (1 << (26 + x))
+
+#define ECC_CHECK_RETURN_FF (-1)
+
+#define NAND_CE0 (0xe << 10)
+#define NAND_CE1 (0xd << 10)
+
+#define DMA_BUSY_TIMEOUT 0x100000
+
+#define MAX_CE_NUM 2
+#define RAN_ENABLE 1
+
+#define SD_EMMC_CLOCK 0x00
+#define CLK_ALWAYS_ON BIT(28)
+#define CLK_SELECT_NAND BIT(31)
+#define CLK_DIV_MASK GENMASK(5, 0)
+#define CLK_SRC_MASK GENMASK(7, 6)
+
+#define NFC_CLK_CYCLE 6
+
+/* nand flash controller delay 3 ns */
+#define NFC_DEFAULT_DELAY 3000
+
+#define MAX_ECC_INDEX 10
+
+#define MUX_CLK_NUM_PARENTS 2
+
+struct meson_nfc_info_format {
+ u16 info_bytes;
+ u8 zero_cnt; /* bit0~5 is valid */
+ struct ecc_sta {
+ u8 eccerr_cnt : 6;
+ u8 notused : 1;
+ u8 completed : 1;
+ } ecc;
+ u32 reserved;
+};
+
+#define PER_INFO_BYTE (sizeof(struct meson_nfc_info_format))
+
+struct meson_nfc_nand_chip {
+ struct list_head node;
+ struct nand_chip nand;
+ /*
+ * Then NAND controller support two oob modes:
+ * a) 2 user bytes with each ecc page;
+ * b) 16 user bytes with 1st ecc page and zero user byte
+ * with the other ecc pages.
+ * when using as mtd mode, the driver prefer to use 2 user bytes mode.
+ */
+ int user_mode;
+ int rand_mode; /* 0: disable scramble, 1: enable scramble */
+ int bch_mode;
+ int cs;
+
+ u8 *data_buf;
+ u8 *info_buf;
+};
+
+/*
+ * While booting from NAND, a page0 data is needed to tell ROM boot code
+ * to read SPL image, and the ROM boot code need to know which ecc mode
+ * is selected and whether scramble is enabled or not, and so on.
+ *
+ * So when updating SPL image, the driver need to store these informations
+ * into the page0, and SPL image will be loadded into next page - the page1.
+ */
+struct meson_nand_setup {
+ u32 d32;
+ u16 id;
+ u16 max;
+};
+
+struct meson_nand_page0 {
+ struct meson_nand_setup nand_setup;
+ unsigned char page_list[16];
+ unsigned short reserved[32];
+};
+
+struct meson_nand_ecc {
+ int bch;
+ int strength;
+ int parity;
+};
+
+struct meson_nfc_data {
+ struct meson_nand_ecc *ecc;
+ int ecc_num;
+ int bch_mode;
+ int short_bch;
+};
+
+struct meson_nfc_param {
+ int chip_select;
+ int rb_select;
+
+ int page_size;
+ int oob_size;
+ int ecc_size;
+ int ecc_bytes;
+
+ int rand_mode;
+ int oob_mode;
+ int bch_mode;
+ int ecc_step;
+
+ int ecc_max;
+};
+
+struct meson_nfc {
+ struct nand_hw_control controller;
+ struct clk *core_clk;
+ struct clk *device_clk;
+
+ struct device *dev;
+ void __iomem *reg_base;
+ struct regmap *reg_clk;
+
+ struct completion completion;
+ struct list_head chips;
+ struct meson_nfc_data *data;
+ struct meson_nfc_param param;
+ struct meson_nand_page0 *page0;
+
+ u8 *data_buf;
+ u8 *info_buf;
+};
+
+enum {
+ NFC_ECC_NONE = 0,
+ NFC_ECC_BCH8, /* bch8 with ecc page size of 512B */
+ NFC_ECC_BCH8_1K, /* bch8 with ecc page size of 1024B */
+ NFC_ECC_BCH24_1K,
+ NFC_ECC_BCH30_1K,
+ NFC_ECC_BCH40_1K,
+ NFC_ECC_BCH50_1K,
+ NFC_ECC_BCH60_1K,
+
+ /*
+ * Short mode is special only for page 0 when inplement booting
+ * from nand, which means a small size(384 bit / 8 = 48 Byte) of
+ * ecc page is used with a fixed ecc mode. rom code will use short mode
+ * to read page0 for getting nand parameters such as ecc, scramber, etc.
+ *
+ * Example, in GXL SoC, the first page adopt the short mode with
+ * 60bit ecc, while in AXG SoC, it adopt short mode with 8bit ecc.
+ */
+ NFC_ECC_BCH_SHORT,
+};
+
+enum {
+ NFC_USER2_OOB_BYTES = 2,
+ NFC_USER16_OOB_BYTES = 16,
+};
+
+#define MESON_ECC_DATA(b, s, p) \
+ { .bch = (b), .strength = (s), .parity = (p) }
+
+struct meson_nand_ecc meson_gxl_ecc[] = {
+ MESON_ECC_DATA(NFC_ECC_NONE, 0, 0),
+ MESON_ECC_DATA(NFC_ECC_BCH8, 8, 14),
+ MESON_ECC_DATA(NFC_ECC_BCH8_1K, 8, 14),
+ MESON_ECC_DATA(NFC_ECC_BCH24_1K, 24, 42),
+ MESON_ECC_DATA(NFC_ECC_BCH30_1K, 30, 54),
+ MESON_ECC_DATA(NFC_ECC_BCH40_1K, 40, 70),
+ MESON_ECC_DATA(NFC_ECC_BCH50_1K, 50, 88),
+ MESON_ECC_DATA(NFC_ECC_BCH60_1K, 60, 106),
+ MESON_ECC_DATA(NFC_ECC_BCH_SHORT, 0xff, 0xff),
+};
+
+struct meson_nand_ecc meson_axg_ecc[] = {
+ MESON_ECC_DATA(NFC_ECC_NONE, 0, 0),
+ MESON_ECC_DATA(NFC_ECC_BCH8, 8, 14),
+ MESON_ECC_DATA(NFC_ECC_BCH8_1K, 8, 14),
+ MESON_ECC_DATA(NFC_ECC_BCH_SHORT, 0xff, 0xff),
+};
+
+static inline struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand)
+{
+ return container_of(nand, struct meson_nfc_nand_chip, nand);
+}
+
+static int meson_nfc_page0_gen(struct meson_nfc *nfc)
+{
+ u32 cmd;
+
+ nfc->page0 = devm_kzalloc(nfc->dev,
+ sizeof(struct meson_nand_page0), GFP_KERNEL);
+ if(!nfc->page0)
+ return -ENOMEM;
+
+ cmd = CMDRWGEN(NFC_CMD_N2M, nfc->param.rand_mode,
+ nfc->param.bch_mode, 0,
+ nfc->param.ecc_size >> 3,
+ nfc->param.ecc_step);
+ cmd |= NFC_RB_USED | NFC_LARGE_PAGE | NFC_RW_OPS;
+ nfc->page0->nand_setup.d32 = cmd;
+
+ return 0;
+}
+
+static void meson_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+
+ if (chip != meson_chip->cs)
+ return;
+
+ nfc->param.chip_select = chip ? NAND_CE1 : NAND_CE0;
+ nfc->param.rb_select = chip ? NAND_CE1 : NAND_CE0;
+ nfc->param.oob_mode =
+ (meson_chip->user_mode == NFC_USER2_OOB_BYTES) ? 0 : 1;
+ nfc->param.rand_mode = meson_chip->rand_mode;
+ nfc->param.bch_mode = meson_chip->bch_mode;
+
+ nfc->param.ecc_step = mtd->writesize / nand->ecc.size;
+ nfc->param.ecc_size = nand->ecc.size;
+ nfc->param.ecc_bytes = nand->ecc.bytes;
+ nfc->param.page_size = mtd->writesize;
+ nfc->param.oob_size = mtd->oobsize;
+ nfc->param.ecc_max = nand->ecc.strength;
+
+ nfc->data_buf = meson_chip->data_buf;
+ nfc->info_buf = meson_chip->info_buf;
+}
+
+static inline void meson_nfc_cmd_idle(struct meson_nfc *nfc, u32 time)
+{
+ writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff),
+ nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_cmd_ctrl(struct mtd_info *mtd,
+ int cmd, unsigned int ctrl)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ cmd = nfc->param.chip_select | (cmd & 0xff);
+ cmd |= (ctrl & NAND_CLE) ? NFC_CMD_CLE : NFC_CMD_ALE;
+
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+}
+
+static inline void meson_nfc_cmd_seed(struct meson_nfc *nfc, u32 seed)
+{
+ writel(NFC_CMD_SEED | (0xc2 + (seed & 0x7fff)),
+ nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_cmd_m2n(struct meson_nfc *nfc, int raw)
+{
+ u32 cmd, pagesize, pages, shortm = 0;
+ int bch = nfc->param.bch_mode;
+ int len = nfc->param.page_size;
+
+ pagesize = nfc->param.ecc_size;
+
+ if (unlikely(raw)) {
+ bch = NAND_ECC_NONE;
+ len = nfc->param.page_size + nfc->param.oob_size;
+ cmd = NFC_CMD_M2N |
+ (len & 0x3fff) | (nfc->param.rand_mode << 19);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ return;
+ }
+
+ if (unlikely(bch == NFC_ECC_BCH_SHORT)) {
+ bch = nfc->data->short_bch;
+ pagesize = 384 >> 3;
+ pages = len / nfc->param.ecc_size;
+ memcpy(nfc->data_buf,
+ nfc->page0, sizeof(struct meson_nand_page0));
+ shortm = 1;
+ } else
+ pages = len / nfc->param.ecc_size;
+
+ cmd = CMDRWGEN(NFC_CMD_M2N,
+ nfc->param.rand_mode, bch, shortm, pagesize, pages);
+
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_cmd_n2m(struct meson_nfc *nfc, int raw)
+{
+ u32 cmd, pagesize, pages, shortm = 0;
+ int bch = nfc->param.bch_mode;
+ int len = nfc->param.page_size;
+
+ pagesize = nfc->param.ecc_size;
+
+ if (unlikely(raw)) {
+ bch = NAND_ECC_NONE;
+ len = nfc->param.page_size + nfc->param.oob_size;
+ cmd = (len & 0x3fff) | (nfc->param.rand_mode << 19) |
+ NFC_CMD_N2M;
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ return;
+ }
+
+ if (unlikely(bch == NFC_ECC_BCH_SHORT)) {
+ bch = nfc->data->short_bch;
+ pagesize = 384 >> 3;
+ pages = len / nfc->param.ecc_size;
+ shortm = 1;
+ } else
+ pages = len / nfc->param.ecc_size;
+
+ cmd = CMDRWGEN(NFC_CMD_N2M,
+ nfc->param.rand_mode, bch, shortm, pagesize, pages);
+
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+}
+
+static int meson_nfc_wait_cmd_finish(struct meson_nfc *nfc,
+ unsigned int timeout_ms)
+{
+ u32 cmd_size = 0;
+ int ret;
+
+ /* wait cmd fifo is empty */
+ ret = readl_poll_timeout(nfc->reg_base + NFC_REG_CMD,
+ cmd_size,
+ !((cmd_size >> 22) & 0x1f),
+ 10, timeout_ms * 1000);
+ if (ret)
+ dev_err(nfc->dev, "wait for empty cmd FIFO time out\n");
+
+ return ret;
+}
+
+static int meson_nfc_wait_dma_finish(struct meson_nfc *nfc)
+{
+ meson_nfc_cmd_idle(nfc, 0);
+ meson_nfc_cmd_idle(nfc, 0);
+
+ return meson_nfc_wait_cmd_finish(nfc, DMA_BUSY_TIMEOUT);
+}
+
+static inline struct meson_nfc_info_format *nfc_info_ptr(struct meson_nfc *nfc,
+ int index)
+{
+ return (struct meson_nfc_info_format *) &nfc->info_buf[index * 8];
+}
+
+static u8 *meson_nfc_oob_ptr(struct meson_nfc *nfc, int i)
+{
+ int x, len;
+ int ecc_bytes = nfc->param.ecc_bytes, temp = nfc->param.ecc_size;
+
+ x = i ? 16 : 0;
+ len = (nfc->param.oob_mode) ? (temp * (i + 1) + ecc_bytes * i + x) :
+ (temp * (i + 1) + (ecc_bytes + 2) * i);
+
+ return nfc->data_buf + len;
+}
+
+static u8 *meson_nfc_data_ptr(struct meson_nfc *nfc, int i)
+{
+ int len, x;
+ int temp = nfc->param.ecc_size + nfc->param.ecc_bytes;
+
+ x = i ? 16 : 0;
+ len = nfc->param.oob_mode ? (temp * i + x) : (temp + 2) * i;
+
+ return nfc->data_buf + len;
+}
+
+static void meson_nfc_prase_data_oob(struct meson_nfc *nfc, u8 *buf, u8 *oob)
+{
+ int i, oob_len = 0;
+ u8 *dsrc, *osrc;
+
+ for (i = 0; i < nfc->param.ecc_step; i++) {
+ if (buf) {
+ dsrc = meson_nfc_data_ptr(nfc, i);
+ memcpy(buf, dsrc, nfc->param.ecc_size);
+ buf += nfc->param.ecc_size;
+ }
+
+ if (nfc->param.oob_mode)
+ oob_len = (i) ? nfc->param.ecc_bytes :
+ nfc->param.ecc_bytes + 16;
+ else
+ oob_len = nfc->param.ecc_bytes + 2;
+
+ osrc = meson_nfc_oob_ptr(nfc, i);
+ memcpy(oob, osrc, oob_len);
+ oob += oob_len;
+ }
+}
+
+static void meson_nfc_format_data_oob(struct meson_nfc *nfc,
+ const u8 *buf, u8 *oob)
+{
+ int i, oob_len = 0;
+ u8 *dsrc, *osrc;
+
+ for (i = 0; i < nfc->param.ecc_step; i++) {
+ if (buf) {
+ dsrc = meson_nfc_data_ptr(nfc, i);
+ memcpy(dsrc, buf, nfc->param.ecc_size);
+ buf += nfc->param.ecc_size;
+ }
+
+ if (nfc->param.oob_mode)
+ oob_len = i ? nfc->param.ecc_bytes :
+ nfc->param.ecc_bytes + 16;
+ else
+ oob_len = nfc->param.ecc_bytes + 2;
+
+ osrc = meson_nfc_oob_ptr(nfc, i);
+ memcpy(osrc, oob, oob_len);
+ oob += oob_len;
+ }
+}
+
+static int meson_nfc_queue_rb(struct meson_nfc *nfc)
+{
+ u32 cmd, cfg;
+ int ret = 0;
+
+ init_completion(&nfc->completion);
+
+ cfg = readl(nfc->reg_base + NFC_REG_CFG);
+ cfg |= (1 << 21);
+ writel(cfg, nfc->reg_base + NFC_REG_CFG);
+
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+ cmd = nfc->param.chip_select | NFC_CMD_CLE | (NAND_CMD_STATUS & 0xff);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+
+ cmd = NFC_CMD_RB | NFC_CMD_IO6 | (1 << 16) | (0x18 & 0x1f);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ meson_nfc_cmd_idle(nfc, 2);
+
+ ret = wait_for_completion_timeout(&nfc->completion,
+ msecs_to_jiffies(1000));
+ if (ret == 0) {
+ dev_err(nfc->dev, "wait nand irq timeout\n");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static void meson_nfc_set_user_byte(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *oob_buf)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ struct meson_nfc_info_format *info;
+ int i, count;
+
+ if (nfc->param.oob_mode) {
+ memcpy(nfc->info_buf, oob_buf, 16);
+ return;
+ }
+
+ for (i = 0, count = 0; i < chip->ecc.steps; i++, count += 2) {
+ info = nfc_info_ptr(nfc, i);
+ info->info_bytes =
+ oob_buf[count] | (oob_buf[count + 1] << 8);
+ }
+}
+
+static void meson_nfc_get_user_byte(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *oob_buf)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ struct meson_nfc_info_format *info;
+ int i, count;
+
+ if (nfc->param.oob_mode) {
+ memcpy(oob_buf, nfc->info_buf, 16);
+ return;
+ }
+
+ for (i = 0, count = 0; i < chip->ecc.steps; i++, count += 2) {
+ info = nfc_info_ptr(nfc, i);
+ oob_buf[count] = info->info_bytes & 0xff;
+ oob_buf[count + 1] = (info->info_bytes >> 8) & 0xff;
+ }
+}
+
+static int meson_nfc_ecc_correct(struct mtd_info *mtd,
+ struct nand_chip *chip)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ struct meson_nfc_info_format *info;
+ u32 bitflips = 0, i;
+ u8 zero_cnt;
+
+ for (i = 0; i < nfc->param.ecc_step; i++) {
+ info = nfc_info_ptr(nfc, i);
+ if (info->ecc.eccerr_cnt == 0x3f) {
+ zero_cnt = info->zero_cnt & 0x3f;
+ if (nfc->param.rand_mode
+ && (zero_cnt < nfc->param.ecc_max))
+ return ECC_CHECK_RETURN_FF;
+ mtd->ecc_stats.failed++;
+ continue;
+ }
+ mtd->ecc_stats.corrected += info->ecc.eccerr_cnt;
+ bitflips = max_t(u32, bitflips, info->ecc.eccerr_cnt);
+ }
+
+ return bitflips;
+}
+
+static inline u8 meson_nfc_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ u32 cmd;
+
+ cmd = nfc->param.chip_select | NFC_CMD_DRD | 0;
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_cmd_idle(nfc, 0);
+ meson_nfc_cmd_idle(nfc, 0);
+
+ meson_nfc_wait_cmd_finish(nfc, 1000);
+
+ return readb(nfc->reg_base + NFC_REG_BUF);
+}
+
+static void meson_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ buf[i] = meson_nfc_read_byte(mtd);
+}
+
+static void meson_nfc_write_byte(struct mtd_info *mtd, u8 byte)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
+ u32 cmd;
+
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+
+ cmd = nfc->param.chip_select | NFC_CMD_DWR | (byte & 0xff);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+ meson_nfc_cmd_idle(nfc, 0);
+
+ meson_nfc_wait_cmd_finish(nfc, 1000);
+}
+
+static void meson_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ meson_nfc_write_byte(mtd, buf[i]);
+}
+
+static int meson_nfc_write_page_sub(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf, int page, int raw)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ dma_addr_t daddr, iaddr;
+ u32 cmd;
+ int ret;
+
+ nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
+ daddr = dma_map_single(nfc->dev, (void *)nfc->data_buf,
+ mtd->writesize + mtd->oobsize, DMA_TO_DEVICE);
+ ret = dma_mapping_error(nfc->dev, daddr);
+ if (ret) {
+ dev_err(nfc->dev, "dma mapping error\n");
+ return -EINVAL;
+ }
+
+ iaddr = dma_map_single(nfc->dev, (void *)nfc->info_buf,
+ nfc->param.ecc_step * PER_INFO_BYTE, DMA_TO_DEVICE);
+ ret = dma_mapping_error(nfc->dev, iaddr);
+ if (ret) {
+ dev_err(nfc->dev, "dma mapping error\n");
+ return -EINVAL;
+ }
+
+ cmd = GENCMDDADDRL(NFC_CMD_ADL, daddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ cmd = GENCMDDADDRH(NFC_CMD_ADH, daddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ cmd = GENCMDIADDRL(NFC_CMD_AIL, iaddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ cmd = GENCMDIADDRH(NFC_CMD_AIH, iaddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_cmd_seed(nfc, page);
+
+ meson_nfc_cmd_m2n(nfc, raw);
+
+ ret = meson_nfc_wait_dma_finish(nfc);
+
+ dma_unmap_single(nfc->dev, daddr,
+ mtd->writesize + mtd->oobsize, DMA_TO_DEVICE);
+ dma_unmap_single(nfc->dev, iaddr,
+ nfc->param.ecc_step * PER_INFO_BYTE, DMA_TO_DEVICE);
+
+ return nand_prog_page_end_op(chip);
+}
+
+static int meson_nfc_write_page_raw(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf, int oob_required, int page)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ u8 *oob_buf = chip->oob_poi;
+
+ meson_nfc_format_data_oob(nfc, buf, oob_buf);
+
+ return meson_nfc_write_page_sub(mtd, chip, nfc->data_buf, page, 1);
+}
+
+static int meson_nfc_write_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf,
+ int oob_required, int page)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ u8 *oob_buf = chip->oob_poi;
+
+ memcpy(nfc->data_buf, buf, mtd->writesize);
+ meson_nfc_set_user_byte(mtd, chip, oob_buf);
+
+ return meson_nfc_write_page_sub(mtd, chip, nfc->data_buf, page, 0);
+}
+
+static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc, int raw)
+{
+ struct meson_nfc_info_format *info;
+ int neccpages, i;
+
+ neccpages = raw ? 1 : nfc->param.ecc_step;
+
+ for (i = 0; i < neccpages; i++) {
+ info = nfc_info_ptr(nfc, neccpages - 1);
+ if (info->ecc.completed == 0)
+ dev_err(nfc->dev, "seems eccpage is invalid\n");
+ }
+}
+
+static int meson_nfc_read_page_sub(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf, int page, int raw)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ dma_addr_t daddr, iaddr;
+ u32 cmd;
+ int ret;
+
+ nand_read_page_op(chip, page, 0, NULL, 0);
+
+ daddr = dma_map_single(nfc->dev, nfc->data_buf,
+ mtd->writesize + mtd->oobsize, DMA_FROM_DEVICE);
+ ret = dma_mapping_error(nfc->dev, daddr);
+ if (ret) {
+ dev_err(nfc->dev, "dma mapping error\n");
+ return -EINVAL;
+ }
+
+ iaddr = dma_map_single(nfc->dev, nfc->info_buf,
+ nfc->param.ecc_step * PER_INFO_BYTE, DMA_FROM_DEVICE);
+ ret = dma_mapping_error(nfc->dev, iaddr);
+ if (ret) {
+ dev_err(nfc->dev, "dma mapping error\n");
+ return -EINVAL;
+ }
+
+ cmd = GENCMDDADDRL(NFC_CMD_ADL, daddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ cmd = GENCMDDADDRH(NFC_CMD_ADH, daddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ cmd = GENCMDIADDRL(NFC_CMD_AIL, iaddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ cmd = GENCMDIADDRH(NFC_CMD_AIH, iaddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_cmd_seed(nfc, page);
+
+ meson_nfc_cmd_n2m(nfc, raw);
+
+ ret = meson_nfc_wait_dma_finish(nfc);
+
+ meson_nfc_queue_rb(nfc);
+
+ meson_nfc_check_ecc_pages_valid(nfc, raw);
+
+ dma_unmap_single(nfc->dev, daddr,
+ mtd->writesize + mtd->oobsize, DMA_FROM_DEVICE);
+ dma_unmap_single(nfc->dev, iaddr,
+ nfc->param.ecc_step * PER_INFO_BYTE, DMA_FROM_DEVICE);
+
+ return ret;
+}
+
+static int meson_nfc_read_page_raw(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *buf, int oob_required, int page)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ u8 *oob_buf = chip->oob_poi;
+ int ret;
+
+ ret = meson_nfc_read_page_sub(mtd, chip, nfc->data_buf, page, 1);
+ if (ret)
+ return ret;
+
+ meson_nfc_prase_data_oob(nfc, buf, oob_buf);
+
+ return 0;
+}
+
+static int meson_nfc_read_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *buf, int oob_required, int page)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ u8 *oob_buf = chip->oob_poi;
+ int ret;
+
+ ret = meson_nfc_read_page_sub(mtd, chip, nfc->data_buf, page, 0);
+ if (ret)
+ return ret;
+
+ meson_nfc_get_user_byte(mtd, chip, oob_buf);
+
+ ret = meson_nfc_ecc_correct(mtd, chip);
+ if (ret == ECC_CHECK_RETURN_FF) {
+ if (buf)
+ memset(buf, 0xff, mtd->writesize);
+
+ memset(oob_buf, 0xff, mtd->oobsize);
+ return 0;
+ }
+ if (buf && (buf != nfc->data_buf))
+ memcpy(buf, nfc->data_buf, mtd->writesize);
+
+ return ret;
+}
+
+static int meson_nfc_read_oob_raw(struct mtd_info *mtd,
+ struct nand_chip *chip, int page)
+{
+ return meson_nfc_read_page_raw(mtd, chip, NULL, 1, page);
+}
+
+static int meson_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ return meson_nfc_read_page_hwecc(mtd, chip, NULL, 1, page);
+}
+
+static int meson_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+ int free_oob;
+
+ if (section > chip->ecc.steps)
+ return -ERANGE;
+
+ free_oob = nfc->param.oob_mode ? 16 : (chip->ecc.steps * 2);
+ oobregion->offset = section * chip->ecc.bytes + free_oob;
+ oobregion->length = chip->ecc.bytes;
+
+ return 0;
+}
+
+static int meson_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(chip);
+
+ if (section > chip->ecc.steps)
+ return -ERANGE;
+
+ oobregion->offset = 0;
+ oobregion->length = nfc->param.oob_mode ? 16 : (chip->ecc.steps * 2);
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
+ .ecc = meson_ooblayout_ecc,
+ .free = meson_ooblayout_free,
+};
+
+static int meson_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ struct meson_nand_ecc *meson_ecc = nfc->data->ecc;
+ int num = nfc->data->ecc_num;
+ int nsectors, i, bytes;
+
+ /* support only ecc hw mode */
+ if (nand->ecc.mode != NAND_ECC_HW) {
+ dev_err(dev, "ecc.mode not supported\n");
+ return -EINVAL;
+ }
+
+ if (!nand->ecc.size || !nand->ecc.strength) {
+ /* use datasheet requirements */
+ nand->ecc.strength = nand->ecc_strength_ds;
+ nand->ecc.size = nand->ecc_step_ds;
+ }
+
+ if (nand->ecc.options & NAND_ECC_MAXIMIZE) {
+ nand->ecc.size = 1024;
+ nsectors = mtd->writesize / nand->ecc.size;
+
+ /* Reserve 2 bytes for each ecc page */
+ if (meson_chip->user_mode == NFC_USER2_OOB_BYTES)
+ bytes = mtd->oobsize - 2 * nsectors;
+ else
+ bytes = mtd->oobsize - 16;
+
+ bytes /= nsectors;
+
+ /* and bytes has to be even. */
+ if (bytes % 2)
+ bytes--;
+
+ nand->ecc.strength = bytes * 8 / fls(8 * nand->ecc.size);
+ } else {
+ if (nand->ecc.strength > meson_ecc[num - 1].strength) {
+ dev_err(dev, "not support ecc strength\n");
+ return -EINVAL;
+ }
+ }
+
+ for (i = 0; i < num; i++) {
+ if ((meson_ecc[i].strength == 0xff)
+ || (nand->ecc.strength < meson_ecc[i].strength))
+ break;
+ }
+
+ if (!i) {
+ nand->ecc.strength = 0;
+ } else {
+ nand->ecc.strength = meson_ecc[i - 1].strength;
+ nand->ecc.bytes = meson_ecc[i - 1].parity;
+ }
+
+ meson_chip->bch_mode = meson_ecc[i - 1].bch;
+
+ if (nand->ecc.size != 512 && nand->ecc.size != 1024)
+ return -EINVAL;
+
+ nsectors = mtd->writesize / nand->ecc.size;
+ bytes =(meson_chip->user_mode == NFC_USER2_OOB_BYTES) ? nsectors * 2 : 16;
+ if (mtd->oobsize < (nand->ecc.bytes * nsectors + bytes))
+ return -EINVAL;
+
+ return 0;
+}
+
+static const char * sd_emmc_ext_clk0_parent_names[MUX_CLK_NUM_PARENTS];
+
+static struct clk_regmap sd_emmc_c_ext_clk0_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = SD_EMMC_CLOCK,
+ .mask = 0x3,
+ .shift = 6,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "sd_emmc_c_nand_clk_mux",
+ .ops = &clk_regmap_mux_ops,
+ .parent_names = sd_emmc_ext_clk0_parent_names,
+ .num_parents = ARRAY_SIZE(sd_emmc_ext_clk0_parent_names),
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap sd_emmc_c_ext_clk0_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = SD_EMMC_CLOCK,
+ .shift = 0,
+ .width = 6,
+ .flags = CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ONE_BASED,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "sd_emmc_c_nand_clk_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_names = (const char *[]){ "sd_emmc_c_nand_clk_mux" },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static int meson_nfc_clk_init(struct meson_nfc *nfc)
+{
+ struct clk_regmap *mux = &sd_emmc_c_ext_clk0_sel;
+ struct clk_regmap *div = &sd_emmc_c_ext_clk0_div;
+ struct clk *clk;
+ int i, ret;
+
+ /* request core clock */
+ nfc->core_clk = devm_clk_get(nfc->dev, "core");
+ if (IS_ERR(nfc->core_clk)) {
+ dev_err(nfc->dev, "failed to get core clk\n");
+ return PTR_ERR(nfc->core_clk);
+ }
+
+ /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
+ regmap_update_bits(nfc->reg_clk, 0,
+ CLK_SELECT_NAND | CLK_ALWAYS_ON | CLK_DIV_MASK,
+ CLK_SELECT_NAND | CLK_ALWAYS_ON | CLK_DIV_MASK);
+
+ /* get the mux parents */
+ for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
+ char name[16];
+
+ snprintf(name, sizeof(name), "clkin%d", i);
+ clk = devm_clk_get(nfc->dev, name);
+ if (IS_ERR(clk)) {
+ if (clk != ERR_PTR(-EPROBE_DEFER))
+ dev_err(nfc->dev, "Missing clock %s\n", name);
+ return PTR_ERR(clk);
+ }
+
+ sd_emmc_ext_clk0_parent_names[i] = __clk_get_name(clk);
+ }
+
+ mux->map = nfc->reg_clk;
+ clk = devm_clk_register(nfc->dev, &mux->hw);
+ if (WARN_ON(IS_ERR(clk)))
+ return PTR_ERR(clk);
+
+ div->map = nfc->reg_clk;
+ nfc->device_clk = devm_clk_register(nfc->dev, &div->hw);
+ if (WARN_ON(IS_ERR(nfc->device_clk)))
+ return PTR_ERR(nfc->device_clk);
+
+ ret = clk_prepare_enable(nfc->core_clk);
+ if (ret) {
+ dev_err(nfc->dev, "failed to enable core clk\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(nfc->device_clk);
+ if (ret) {
+ dev_err(nfc->dev, "failed to enable device clk\n");
+ clk_disable_unprepare(nfc->core_clk);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void meson_nfc_disable_clk(struct meson_nfc *nfc)
+{
+ clk_disable_unprepare(nfc->device_clk);
+ clk_disable_unprepare(nfc->core_clk);
+}
+
+static int meson_nfc_buffer_init(struct mtd_info *mtd)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ struct device *dev = nfc->dev;
+ int info_bytes, page_bytes;
+ int nsectors;
+
+ nsectors = mtd->writesize / nand->ecc.size;
+ info_bytes = nsectors * PER_INFO_BYTE;
+ page_bytes = mtd->writesize + mtd->oobsize;
+
+ if ((meson_chip->data_buf) && (meson_chip->info_buf))
+ return 0;
+
+ meson_chip->data_buf = devm_kzalloc(dev, page_bytes, GFP_KERNEL);
+ if (!meson_chip->data_buf)
+ return -ENOMEM;
+
+ meson_chip->info_buf = devm_kzalloc(dev, info_bytes, GFP_KERNEL);
+ if (!meson_chip->info_buf)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int meson_nfc_calc_set_timing(struct meson_nfc *nfc,
+ int rc_min, int rea_max, int rhoh_min)
+{
+ int div, bt_min, bt_max, bus_timing;
+ int ret;
+
+ div = DIV_ROUND_UP((rc_min / 1000), NFC_CLK_CYCLE);
+ ret = clk_set_rate(nfc->device_clk, 1000000000 / div);
+ if (ret) {
+ dev_err(nfc->dev, "failed to set nand clock rate\n");
+ return ret;
+ }
+
+ bt_min = (rea_max + NFC_DEFAULT_DELAY) / div;
+ bt_max = (NFC_DEFAULT_DELAY + rhoh_min + rc_min / 2) / div;
+
+ bt_min = DIV_ROUND_UP(bt_min, 1000);
+ bt_max = DIV_ROUND_UP(bt_max, 1000);
+
+ if (bt_max < bt_min)
+ return -EINVAL;
+
+ bus_timing = (bt_min + bt_max) / 2 + 1;
+
+ writel((1 << 21), nfc->reg_base + NFC_REG_CFG);
+ writel((NFC_CLK_CYCLE - 1) | (bus_timing << 5),
+ nfc->reg_base + NFC_REG_CFG);
+
+ writel((1 << 31), nfc->reg_base + NFC_REG_CMD);
+
+ return 0;
+}
+
+static int meson_nfc_setup_data_interface(struct mtd_info *mtd, int csline,
+ const struct nand_data_interface *conf)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ const struct nand_sdr_timings *timings;
+
+ timings = nand_get_sdr_timings(conf);
+ if (IS_ERR(timings))
+ return -ENOTSUPP;
+
+ if (csline == NAND_DATA_IFACE_CHECK_ONLY)
+ return 0;
+
+ meson_nfc_calc_set_timing(nfc, timings->tRC_min,
+ timings->tREA_max, timings->tRHOH_min);
+
+ return 0;
+}
+
+static int meson_nfc_get_nand_chip_dts(struct meson_nfc *nfc,
+ struct meson_nfc_nand_chip *chip, struct device_node *np)
+{
+ struct device *dev = nfc->dev;
+
+ if (of_property_read_u32(np, "reg", &chip->cs)) {
+ dev_err(dev, "can not get ce number\n");
+ return -EINVAL;
+ }
+
+ if (chip->cs > MAX_CE_NUM) {
+ dev_err(dev, "ce number is beyond\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(np, "meson-nand-user-mode", &chip->user_mode)) {
+ dev_err(dev, "can not get user oob mode\n");
+ return -EINVAL;
+ }
+
+ if ((chip->user_mode != NFC_USER2_OOB_BYTES)
+ || (chip->user_mode != NFC_USER16_OOB_BYTES))
+ chip->user_mode = NFC_USER2_OOB_BYTES;
+
+ if (of_property_read_u32(np, "meson-nand-ran-mode", &chip->rand_mode)) {
+ dev_err(dev, "can not get scramble mode\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int meson_nfc_nand_chip_init(struct device *dev, struct meson_nfc *nfc,
+ struct device_node *np)
+{
+ struct meson_nfc_nand_chip *chip;
+ struct nand_chip *nand;
+ struct mtd_info *mtd;
+ int ret;
+
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ ret = meson_nfc_get_nand_chip_dts(nfc, chip, np);
+ if (ret)
+ return ret;
+
+ nand = &chip->nand;
+ nand_set_flash_node(nand, np);
+ nand_set_controller_data(nand, nfc);
+
+ nand->options |= NAND_USE_BOUNCE_BUFFER;
+ nand->select_chip = meson_nfc_select_chip;
+ nand->write_byte = meson_nfc_write_byte;
+ nand->write_buf = meson_nfc_write_buf;
+ nand->read_byte = meson_nfc_read_byte;
+ nand->read_buf = meson_nfc_read_buf;
+ nand->cmd_ctrl = meson_nfc_cmd_ctrl;
+ nand->setup_data_interface = meson_nfc_setup_data_interface;
+
+ nand->chip_delay = 200;
+ nand->ecc.mode = NAND_ECC_HW;
+
+ nand->ecc.write_page_raw = meson_nfc_write_page_raw;
+ nand->ecc.write_page = meson_nfc_write_page_hwecc;
+ nand->ecc.write_oob_raw = nand_write_oob_std;
+ nand->ecc.write_oob = nand_write_oob_std;
+
+ nand->ecc.read_page_raw = meson_nfc_read_page_raw;
+ nand->ecc.read_page = meson_nfc_read_page_hwecc;
+ nand->ecc.read_oob_raw = meson_nfc_read_oob_raw;
+ nand->ecc.read_oob = meson_nfc_read_oob;
+
+ mtd = nand_to_mtd(nand);
+ mtd->owner = THIS_MODULE;
+ mtd->dev.parent = dev;
+ mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL,
+ "%s:nand", dev_name(dev));
+ if (!mtd->name) {
+ dev_err(nfc->dev, "Failed to allocate mtd->name\n");
+ return -ENOMEM;
+ }
+
+ mtd_set_ooblayout(mtd, &meson_ooblayout_ops);
+
+ ret = nand_scan_ident(mtd, 1, NULL);
+ if (ret) {
+ dev_err(dev, "failed to can ident\n");
+ return -ENODEV;
+ }
+
+ /* store bbt magic in page, cause OOB is not protected */
+ if (nand->bbt_options & NAND_BBT_USE_FLASH)
+ nand->bbt_options |= NAND_BBT_NO_OOB;
+
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
+
+ ret = meson_nfc_ecc_init(dev, mtd);
+ if (ret) {
+ dev_err(dev, "failed to ecc init\n");
+ return -EINVAL;
+ }
+
+ if (nand->options & NAND_BUSWIDTH_16) {
+ dev_err(dev, "16bits buswidth not supported");
+ return -EINVAL;
+ }
+
+ ret = meson_nfc_buffer_init(mtd);
+ if (ret)
+ return -ENOMEM;
+
+ ret = nand_scan_tail(mtd);
+ if (ret)
+ return -ENODEV;
+
+ ret = mtd_device_register(mtd, NULL, 0);
+ if (ret) {
+ dev_err(dev, "failed to register mtd device: %d\n", ret);
+ nand_release(mtd);
+ return ret;
+ }
+
+ list_add_tail(&chip->node, &nfc->chips);
+
+ return 0;
+}
+
+static int meson_nfc_nand_chips_init(struct device *dev, struct meson_nfc *nfc)
+{
+ struct device_node *np = dev->of_node;
+ struct device_node *nand_np;
+ int ret;
+
+ for_each_child_of_node(np, nand_np) {
+ ret = meson_nfc_nand_chip_init(dev, nfc, nand_np);
+ if (ret) {
+ of_node_put(nand_np);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static irqreturn_t meson_nfc_irq(int irq, void *id)
+{
+ struct meson_nfc *nfc = id;
+ u32 cfg;
+
+ cfg = readl(nfc->reg_base + NFC_REG_CFG);
+ cfg |= (1 << 21);
+ writel(cfg, nfc->reg_base + NFC_REG_CFG);
+
+ complete(&nfc->completion);
+ return IRQ_HANDLED;
+}
+
+static const struct meson_nfc_data meson_gxl_data = {
+ .short_bch = NFC_ECC_BCH60_1K,
+ .ecc = meson_gxl_ecc,
+ .ecc_num = ARRAY_SIZE(meson_gxl_ecc),
+};
+
+static const struct meson_nfc_data meson_axg_data = {
+ .short_bch = NFC_ECC_BCH8_1K,
+ .ecc = meson_axg_ecc,
+ .ecc_num = ARRAY_SIZE(meson_axg_ecc),
+};
+
+static const struct of_device_id meson_nfc_id_table[] = {
+ {
+ .compatible = "amlogic,meson-gxl-nfc",
+ .data = &meson_gxl_data,
+ }, {
+ .compatible = "amlogic,meson-axg-nfc",
+ .data = &meson_axg_data,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, meson_nfc_id_table);
+
+static int meson_nfc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct meson_nfc *nfc;
+ struct resource *res;
+ const struct of_device_id *of_nfc_id;
+ int ret, irq;
+
+ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
+ if (!nfc)
+ return -ENOMEM;
+
+ of_nfc_id = of_match_device(meson_nfc_id_table, &pdev->dev);
+ if (!of_nfc_id)
+ return -ENODEV;
+
+ nfc->data = (struct meson_nfc_data *)of_nfc_id->data;
+
+ spin_lock_init(&nfc->controller.lock);
+ init_waitqueue_head(&nfc->controller.wq);
+ INIT_LIST_HEAD(&nfc->chips);
+
+ nfc->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "Failed to nfc reg resource\n");
+ return -EINVAL;
+ }
+
+ nfc->reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(nfc->reg_base)) {
+ dev_err(dev, "Failed to lookup nfi reg base\n");
+ return PTR_ERR(nfc->reg_base);
+ }
+
+ nfc->reg_clk = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "amlogic,mmc-syscon");
+ if (IS_ERR(nfc->reg_clk)) {
+ dev_err(dev, "Failed to lookup clock base\n");
+ return PTR_ERR(nfc->reg_clk);
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "no nfi irq resource\n");
+ return -EINVAL;
+ }
+
+ ret = meson_nfc_clk_init(nfc);
+ if (ret) {
+ dev_err(dev, "failed to initialize nand clk\n");
+ goto err_clk;
+ }
+
+ ret = devm_request_irq(dev, irq, meson_nfc_irq, 0, dev_name(dev), nfc);
+ if (ret) {
+ dev_err(dev, "failed to request nfi irq\n");
+ ret = -EINVAL;
+ goto err_clk;
+ }
+
+ ret = dma_set_mask(dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(dev, "failed to set dma mask\n");
+ goto err_clk;
+ }
+
+ platform_set_drvdata(pdev, nfc);
+
+ ret = meson_nfc_nand_chips_init(dev, nfc);
+ if (ret) {
+ dev_err(dev, "failed to init nand chips\n");
+ goto err_clk;
+ }
+
+ meson_nfc_page0_gen(nfc);
+ return 0;
+
+err_clk:
+ clk_disable_unprepare(nfc->device_clk);
+ clk_disable_unprepare(nfc->core_clk);
+
+ return ret;
+}
+
+static int meson_nfc_remove(struct platform_device *pdev)
+{
+ struct meson_nfc *nfc = platform_get_drvdata(pdev);
+ struct meson_nfc_nand_chip *chip;
+
+ while (!list_empty(&nfc->chips)) {
+ chip = list_first_entry(&nfc->chips, struct meson_nfc_nand_chip,
+ node);
+ nand_release(nand_to_mtd(&chip->nand));
+ list_del(&chip->node);
+ }
+
+ meson_nfc_disable_clk(nfc);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver meson_nfc_driver = {
+ .probe = meson_nfc_probe,
+ .remove = meson_nfc_remove,
+ .driver = {
+ .name = "meson_nand",
+ .of_match_table = meson_nfc_id_table,
+ },
+};
+
+module_platform_driver(meson_nfc_driver);
+
+MODULE_LICENSE("Dual MIT/GPL");
+MODULE_AUTHOR("Liang Yang <liang.yang@amlogic.com>");
+MODULE_DESCRIPTION("Amlogic's Meson NAND Flash Controller driver");
--
2.17.1
^ permalink raw reply related
* [linux-sunxi] Re: [PATCH v2 14/27] drm/sun4i: Don't check for panel or bridge on TV TCONs
From: Jernej Škrabec @ 2018-06-13 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGb2v66QWr2CQhcfQ9BQds-0xeG=pS4MDzaNn7_HGz+q3gfkWA@mail.gmail.com>
Dne sreda, 13. junij 2018 ob 10:04:20 CEST je Chen-Yu Tsai napisal(a):
> On Wed, Jun 13, 2018 at 3:46 PM, Maxime Ripard
>
> <maxime.ripard@bootlin.com> wrote:
> > On Tue, Jun 12, 2018 at 10:00:23PM +0200, Jernej Skrabec wrote:
> >> TV TCONs are always connected to TV or HDMI encoder, so it doesn't make
> >> sense to check if panel or bridge is connected to them.
> >>
> >> Check if TCON has channel 0 and only then check for connected panel or
> >> bridges.
> >>
> >> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >> ---
> >>
> >> drivers/gpu/drm/sun4i/sun4i_tcon.c | 12 +++++++++---
> >> 1 file changed, 9 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> b/drivers/gpu/drm/sun4i/sun4i_tcon.c index b1205a7bc20f..c9ffa5381185
> >> 100644
> >> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> @@ -1189,13 +1189,19 @@ static const struct component_ops sun4i_tcon_ops
> >> = {>>
> >> static int sun4i_tcon_probe(struct platform_device *pdev)
> >> {
> >>
> >> struct device_node *node = pdev->dev.of_node;
> >>
> >> + const struct sun4i_tcon_quirks *quirks;
> >>
> >> struct drm_bridge *bridge;
> >> struct drm_panel *panel;
> >> int ret;
> >>
> >> - ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
> >> - if (ret == -EPROBE_DEFER)
> >> - return ret;
> >> + quirks = of_device_get_match_data(&pdev->dev);
> >
> > We should probably check ofr the pointer value before dereferencing it.
>
> I think we've discussed this before. If the driver has data structures
> for all the supported compatible strings, and it is device tree only,
> then we should just let it blow up in the user's face, since they are
> obviously doing something they shouldn't be doing to get the driver
> to probe without a compatible string match.
TCON can't work with no quirks specified, since that would mean that neither
channels are present. Additionally, sun4i_tcon_bind() also doesn't check if
quirks are NULL or not. So I concur with Chen-Yu here.
Best regards,
Jernej
^ permalink raw reply
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