From mchehab+huawei at kernel.org  Sun Aug  1 09:55:00 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Sun, 1 Aug 2021 18:55:00 +0200
Subject: [PATCH v8 00/11] Add support for Hikey 970 PCIe
In-Reply-To: <cover.1627637745.git.mchehab+huawei@kernel.org>
References: <cover.1627637745.git.mchehab+huawei@kernel.org>
Message-ID: <20210801185500.7fbb1849@coco.lan>

Em Fri, 30 Jul 2021 11:50:03 +0200
Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:

> On this version, the DT bindings were split on a separate patch series:
> 	https://lore.kernel.org/lkml/cover.1627637448.git.mchehab+huawei at kernel.org/
> 
> The patches here should apply cleanly on the top of v5.14-rc1.
> 
> patch1 contains a PHY for Kirin 970 PCIe.
> 
> The remaining patches add support for Kirin 970 at the pcie-kirin driver, and
> add the needed logic to compile it as module and to allow to dynamically
> remove the driver in runtime.
> 
> Tested on HiKey970:
> 
>   # lspci -D -PP
>   0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3670 (rev 01)
>   0000:00:00.0/01:00.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
>   0000:00:00.0/01:00.0/02:01.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
>   0000:00:00.0/01:00.0/02:04.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
>   0000:00:00.0/01:00.0/02:05.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
>   0000:00:00.0/01:00.0/02:07.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
>   0000:00:00.0/01:00.0/02:09.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
>   0000:00:00.0/01:00.0/02:01.0/03:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a809
>   0000:00:00.0/01:00.0/02:07.0/06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 07)


As a reference, this is HiKey970 with both M.2 and mini-PCIe slots with
devices:

# lspci -D -PP
0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3670 (rev 01)
0000:00:00.0/01:00.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
0000:00:00.0/01:00.0/02:01.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
0000:00:00.0/01:00.0/02:04.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
0000:00:00.0/01:00.0/02:05.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
0000:00:00.0/01:00.0/02:07.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
0000:00:00.0/01:00.0/02:09.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
0000:00:00.0/01:00.0/02:01.0/03:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a809
0000:00:00.0/01:00.0/02:05.0/05:00.0 Network controller: Intel Corporation Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (rev 5e)
0000:00:00.0/01:00.0/02:07.0/06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 07)

Regards,
Mauro

Thanks,
Mauro


From robh at kernel.org  Mon Aug  2 13:55:45 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 14:55:45 -0600
Subject: [PATCH v5 2/6] dt-bindings: phy: renesas,usb2-phy: Document
 RZ/G2L phy bindings
In-Reply-To: <20210727185527.19907-3-biju.das.jz@bp.renesas.com>
References: <20210727185527.19907-1-biju.das.jz@bp.renesas.com>
 <20210727185527.19907-3-biju.das.jz@bp.renesas.com>
Message-ID: <YQhb0Ygfod+K9Xf6@robh.at.kernel.org>

On Tue, 27 Jul 2021 19:55:23 +0100, Biju Das wrote:
> Document USB phy bindings for RZ/G2L SoC.
> 
> RZ/G2L USB2.0 phy uses line ctrl register for OTG_ID pin changes. It uses
> a different OTG-BC interrupt bit for device recognition. Apart from this,
> the PHY reset is controlled by USBPHY control IP and Document reset is a
> required property.
> 
> Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v4->v5:
>  * Removed 'properties' and just used 'required' for RZ/G2L SoC.
> v3->v4:
>  * Removed second reset
>  * Added family specific compatible string.
> v2->v3
>  * Created a new compatible for RZ/G2L as per Geert's suggestion.
>  * Added resets required properties for RZ/G2L SoC.
> ---
>  .../devicetree/bindings/phy/renesas,usb2-phy.yaml | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Mon Aug  2 14:33:39 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 15:33:39 -0600
Subject: [PATCH 1/9] dt-bindings: phy: mediatek: tphy: support type
 switch by pericfg
In-Reply-To: <1627459111-2907-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1627459111-2907-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQhks7ca6Gr5gAPC@robh.at.kernel.org>

On Wed, 28 Jul 2021 15:58:23 +0800, Chunfeng Yun wrote:
> Add support type switch by pericfg register between USB3, PCIe,
> SATA, SGMII, this is used to replace the way through efuse or
> jumper.
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  .../devicetree/bindings/phy/mediatek,tphy.yaml   | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From mchehab+huawei at kernel.org  Mon Aug  2 21:38:54 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue,  3 Aug 2021 06:38:54 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to work
Message-ID: <cover.1627965261.git.mchehab+huawei@kernel.org>

Hi Rob,

That's the third version of the DT bindings for Kirin 970 PCIE and its
corresponding PHY. 

It is identical to v2, except by:
	-          pcie at 7,0 { // Lane 7: Ethernet
	+          pcie at 7,0 { // Lane 6: Ethernet

at Documentation/devicetree/bindings/pci/hisilicon,kirin-pcie.yaml

IMO, the best would be to merge this series via your tree, as it
depends on the patch converting the DT bindings for the PCIe DWC
driver.

v3:
  - Fixed a comment on patch 3: The Ethernet controller is at lane 6.

v2:
  - removed the DTS file. I'll submit it in separate, once having
    everything else merged;
  - it now doesn't produce any warnings with:
        make DT_SCHEMA_FILES=Documentation/devicetree/bindings/pci/hisilicon,kirin
-pcie.yaml DT_CHECKER_FLAGS=-m dt_binding_check
  - added the upstream node;
  - the clock enable now uses a new property (hisilicon,clken-gpios);
  - the reg for the PCI devices are now properly filled;
  - the pcie at x,y nodes now match the port number from table 4-1 from the
   datasheet.


Mauro Carvalho Chehab (4):
  dt-bindings: PCI: kirin: Fix compatible string
  dt-bindings: PCI: kirin: Convert kirin-pcie.txt to yaml
  dt-bindings: PCI: kirin: Add support for Kirin970
  dt-bindings: phy: Add bindings for HiKey 970 PCIe PHY

 .../bindings/pci/hisilicon,kirin-pcie.yaml    | 160 ++++++++++++++++++
 .../devicetree/bindings/pci/kirin-pcie.txt    |  50 ------
 .../devicetree/bindings/pci/snps,dw-pcie.yaml |   2 +-
 .../phy/hisilicon,phy-hi3670-pcie.yaml        |  86 ++++++++++
 MAINTAINERS                                   |   2 +-
 5 files changed, 248 insertions(+), 52 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon,kirin-pcie.yaml
 delete mode 100644 Documentation/devicetree/bindings/pci/kirin-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml

-- 
2.31.1




From mchehab+huawei at kernel.org  Mon Aug  2 21:38:58 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue,  3 Aug 2021 06:38:58 +0200
Subject: [PATCH v3 4/4] dt-bindings: phy: Add bindings for HiKey 970 PCIe PHY
In-Reply-To: <cover.1627965261.git.mchehab+huawei@kernel.org>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
Message-ID: <b5809d8acf257834dd84807aa0474f68a94d8084.1627965261.git.mchehab+huawei@kernel.org>

Document the bindings for HiKey 970 (hi3670) PCIe PHY
interface, supported via the pcie-kirin driver.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 .../phy/hisilicon,phy-hi3670-pcie.yaml        | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml

diff --git a/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml b/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
new file mode 100644
index 000000000000..1e0153e4f4a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/hisilicon,phy-hi3670-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Kirin970 PCIe PHY
+
+maintainers:
+  - Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+
+description: |+
+  Bindings for PCIe PHY on HiSilicon Kirin 970.
+
+properties:
+  compatible:
+    const: hisilicon,hi970-pcie-phy
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+    description: PHY Control registers
+
+  phy-supply:
+    description: The PCIe PHY power supply
+
+  clocks:
+    items:
+      - description: PCIe PHY clock
+      - description: PCIe AUX clock
+      - description: PCIe APB PHY clock
+      - description: PCIe APB SYS clock
+      - description: PCIe ACLK clock
+
+  clock-names:
+    items:
+      - const: phy_ref
+      - const: aux
+      - const: apb_phy
+      - const: apb_sys
+      - const: aclk
+
+  clkreq-gpios:
+    description: Clock request GPIOs
+    maxItems: 3
+
+  hisilicon,eye-diagram-param:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: Eye diagram for phy.
+
+required:
+  - "#phy-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - hisilicon,eye-diagram-param
+  - phy-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/hi3670-clock.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+      pcie_phy: pcie-phy at fc000000 {
+        compatible = "hisilicon,hi970-pcie-phy";
+        reg = <0x0 0xfc000000 0x0 0x80000>;
+        #phy-cells = <0>;
+        phy-supply = <&ldo33>;
+        clocks = <&crg_ctrl HI3670_CLK_GATE_PCIEPHY_REF>,
+                 <&crg_ctrl HI3670_CLK_GATE_PCIEAUX>,
+                 <&crg_ctrl HI3670_PCLK_GATE_PCIE_PHY>,
+                 <&crg_ctrl HI3670_PCLK_GATE_PCIE_SYS>,
+                 <&crg_ctrl HI3670_ACLK_GATE_PCIE>;
+        clock-names = "phy_ref", "aux",
+                      "apb_phy", "apb_sys", "aclk";
+        hisilicon,eye-diagram-param = <0xffffffff 0xffffffff
+                                       0xffffffff 0xffffffff 0xffffffff>;
+      };
+    };
-- 
2.31.1



From robh+dt at kernel.org  Tue Aug  3 15:11:42 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 16:11:42 -0600
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <cover.1627965261.git.mchehab+huawei@kernel.org>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
Message-ID: <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>

On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
<mchehab+huawei at kernel.org> wrote:
>
> Hi Rob,
>
> That's the third version of the DT bindings for Kirin 970 PCIE and its
> corresponding PHY.
>
> It is identical to v2, except by:
>         -          pcie at 7,0 { // Lane 7: Ethernet
>         +          pcie at 7,0 { // Lane 6: Ethernet

Can you check whether you have DT node links in sysfs for the PCI
devices? If you don't, then something is wrong still in the topology
or the PCI core is failing to set the DT node pointer in struct
device. Though you don't rely on that currently, we want the topology
to match. It's possible this never worked on arm/arm64 as mainly
powerpc relied on this.

I'd like some way to validate the DT matches the PCI topology. We
could have a tool that generates the DT structure based on the PCI
topology.

> at Documentation/devicetree/bindings/pci/hisilicon,kirin-pcie.yaml
>
> IMO, the best would be to merge this series via your tree, as it
> depends on the patch converting the DT bindings for the PCIe DWC
> driver.

Yes, agreed.

Rob


From robh at kernel.org  Tue Aug  3 15:29:00 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 16:29:00 -0600
Subject: [PATCH v3 4/4] dt-bindings: phy: Add bindings for HiKey 970 PCIe
 PHY
In-Reply-To: <b5809d8acf257834dd84807aa0474f68a94d8084.1627965261.git.mchehab+huawei@kernel.org>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <b5809d8acf257834dd84807aa0474f68a94d8084.1627965261.git.mchehab+huawei@kernel.org>
Message-ID: <YQnDLFmvV3AtihBy@robh.at.kernel.org>

On Tue, Aug 03, 2021 at 06:38:58AM +0200, Mauro Carvalho Chehab wrote:
> Document the bindings for HiKey 970 (hi3670) PCIe PHY
> interface, supported via the pcie-kirin driver.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> ---
>  .../phy/hisilicon,phy-hi3670-pcie.yaml        | 86 +++++++++++++++++++
>  1 file changed, 86 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml b/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
> new file mode 100644
> index 000000000000..1e0153e4f4a5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
> @@ -0,0 +1,86 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/hisilicon,phy-hi3670-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: HiSilicon Kirin970 PCIe PHY
> +
> +maintainers:
> +  - Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> +
> +description: |+
> +  Bindings for PCIe PHY on HiSilicon Kirin 970.
> +
> +properties:
> +  compatible:
> +    const: hisilicon,hi970-pcie-phy
> +
> +  "#phy-cells":
> +    const: 0
> +
> +  reg:
> +    maxItems: 1
> +    description: PHY Control registers
> +
> +  phy-supply:
> +    description: The PCIe PHY power supply
> +
> +  clocks:
> +    items:
> +      - description: PCIe PHY clock
> +      - description: PCIe AUX clock
> +      - description: PCIe APB PHY clock
> +      - description: PCIe APB SYS clock
> +      - description: PCIe ACLK clock
> +
> +  clock-names:
> +    items:
> +      - const: phy_ref
> +      - const: aux
> +      - const: apb_phy
> +      - const: apb_sys
> +      - const: aclk
> +
> +  clkreq-gpios:
> +    description: Clock request GPIOs
> +    maxItems: 3

This can be dropped now?

If not, at least use the same property name. (But really, why duplicate 
information in DT).

Rob


From mchehab+huawei at kernel.org  Wed Aug  4 00:18:53 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed,  4 Aug 2021 09:18:53 +0200
Subject: [PATCH v4 0/4] DT schema changes for HiKey970 PCIe hardware to work
Message-ID: <cover.1628061310.git.mchehab+huawei@kernel.org>

Hi Rob,

It follows the DT bindings for Kirin 970 PCIE and its corresponding PHY,
rebased on the top of next-20210803.

It should apply cleanly on the top of:
	https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=dt/next

Note: you mentioned that patch 1 was already applied, but it is not
there yet. I opted to keep it at the tree, in case someone wants to
apply this series on the top of linux-next.

v4:
  - Rebased and fixed a merge conflict

v3:
  - Fixed a comment on patch 3: The Ethernet controller is at lane 6.

v2:
  - removed the DTS file. I'll submit it in separate, once having
    everything else merged;
  - it now doesn't produce any warnings with:
        make DT_SCHEMA_FILES=Documentation/devicetree/bindings/pci/hisilicon,kirin
-pcie.yaml DT_CHECKER_FLAGS=-m dt_binding_check
  - added the upstream node;
  - the clock enable now uses a new property (hisilicon,clken-gpios);
  - the reg for the PCI devices are now properly filled;
  - the pcie at x,y nodes now match the port number from table 4-1 from the
   datasheet.


Mauro Carvalho Chehab (4):
  dt-bindings: PCI: kirin: Fix compatible string
  dt-bindings: PCI: kirin: Convert kirin-pcie.txt to yaml
  dt-bindings: PCI: kirin: Add support for Kirin970
  dt-bindings: phy: Add bindings for HiKey 970 PCIe PHY

 .../bindings/pci/hisilicon,kirin-pcie.yaml    | 160 ++++++++++++++++++
 .../devicetree/bindings/pci/kirin-pcie.txt    |  50 ------
 .../devicetree/bindings/pci/snps,dw-pcie.yaml |   2 +-
 .../phy/hisilicon,phy-hi3670-pcie.yaml        |  82 +++++++++
 MAINTAINERS                                   |   2 +-
 5 files changed, 244 insertions(+), 52 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon,kirin-pcie.yaml
 delete mode 100644 Documentation/devicetree/bindings/pci/kirin-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml

-- 
2.31.1




From mchehab+huawei at kernel.org  Wed Aug  4 00:18:57 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed,  4 Aug 2021 09:18:57 +0200
Subject: [PATCH v4 4/4] dt-bindings: phy: Add bindings for HiKey 970 PCIe PHY
In-Reply-To: <cover.1628061310.git.mchehab+huawei@kernel.org>
References: <cover.1628061310.git.mchehab+huawei@kernel.org>
Message-ID: <461495431dd28ad2779658659f137db4bd747aa8.1628061310.git.mchehab+huawei@kernel.org>

Document the bindings for HiKey 970 (hi3670) PCIe PHY
interface, supported via the pcie-kirin driver.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 .../phy/hisilicon,phy-hi3670-pcie.yaml        | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml

diff --git a/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml b/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
new file mode 100644
index 000000000000..17367a0275fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/hisilicon,phy-hi3670-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Kirin970 PCIe PHY
+
+maintainers:
+  - Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+
+description: |+
+  Bindings for PCIe PHY on HiSilicon Kirin 970.
+
+properties:
+  compatible:
+    const: hisilicon,hi970-pcie-phy
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+    description: PHY Control registers
+
+  phy-supply:
+    description: The PCIe PHY power supply
+
+  clocks:
+    items:
+      - description: PCIe PHY clock
+      - description: PCIe AUX clock
+      - description: PCIe APB PHY clock
+      - description: PCIe APB SYS clock
+      - description: PCIe ACLK clock
+
+  clock-names:
+    items:
+      - const: phy_ref
+      - const: aux
+      - const: apb_phy
+      - const: apb_sys
+      - const: aclk
+
+  hisilicon,eye-diagram-param:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: Eye diagram for phy.
+
+required:
+  - "#phy-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - hisilicon,eye-diagram-param
+  - phy-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/hi3670-clock.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+      pcie_phy: pcie-phy at fc000000 {
+        compatible = "hisilicon,hi970-pcie-phy";
+        reg = <0x0 0xfc000000 0x0 0x80000>;
+        #phy-cells = <0>;
+        phy-supply = <&ldo33>;
+        clocks = <&crg_ctrl HI3670_CLK_GATE_PCIEPHY_REF>,
+                 <&crg_ctrl HI3670_CLK_GATE_PCIEAUX>,
+                 <&crg_ctrl HI3670_PCLK_GATE_PCIE_PHY>,
+                 <&crg_ctrl HI3670_PCLK_GATE_PCIE_SYS>,
+                 <&crg_ctrl HI3670_ACLK_GATE_PCIE>;
+        clock-names = "phy_ref", "aux",
+                      "apb_phy", "apb_sys", "aclk";
+        hisilicon,eye-diagram-param = <0xffffffff 0xffffffff
+                                       0xffffffff 0xffffffff 0xffffffff>;
+      };
+    };
-- 
2.31.1



From yoshihiro.shimoda.uh at renesas.com  Wed Aug  4 02:38:39 2021
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Wed, 4 Aug 2021 09:38:39 +0000
Subject: [PATCH v5 2/6] dt-bindings: phy: renesas,usb2-phy: Document
 RZ/G2L phy bindings
In-Reply-To: <20210727185527.19907-3-biju.das.jz@bp.renesas.com>
References: <20210727185527.19907-1-biju.das.jz@bp.renesas.com>
 <20210727185527.19907-3-biju.das.jz@bp.renesas.com>
Message-ID: <TY2PR01MB3692AD87163F3C1FAD471FBAD8F19@TY2PR01MB3692.jpnprd01.prod.outlook.com>

Hi Biju-san,

> From: Biju Das, Sent: Wednesday, July 28, 2021 3:55 AM
> 
> Document USB phy bindings for RZ/G2L SoC.
> 
> RZ/G2L USB2.0 phy uses line ctrl register for OTG_ID pin changes. It uses
> a different OTG-BC interrupt bit for device recognition. Apart from this,
> the PHY reset is controlled by USBPHY control IP and Document reset is a
> required property.
> 
> Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>

Best regards,
Yoshihiro Shimoda



From yoshihiro.shimoda.uh at renesas.com  Wed Aug  4 02:38:44 2021
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Wed, 4 Aug 2021 09:38:44 +0000
Subject: [PATCH v5 3/6] phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY
 support for RZ/G2L
In-Reply-To: <20210727185527.19907-4-biju.das.jz@bp.renesas.com>
References: <20210727185527.19907-1-biju.das.jz@bp.renesas.com>
 <20210727185527.19907-4-biju.das.jz@bp.renesas.com>
Message-ID: <TY2PR01MB3692C209506A5FB1465EF7E3D8F19@TY2PR01MB3692.jpnprd01.prod.outlook.com>

Hi Biju-san,

> From: Biju Das, Sent: Wednesday, July 28, 2021 3:55 AM
> 
> This patch adds USB2.0 PHY support for RZ/G2L SoC.
> 
> We need to use a different compatible string due to some differences
> with R-Car Gen3 USB2.0 PHY. It uses line ctrl register for OTG_ID
> pin changes and different OTG-BC interrupt bit for device recognition.
> 
> Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>

Also, I tested this on my environment (r8a77951-salvator-xs),
and I didn't observe any regression. So,

Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com> # on R-Car

Best regards,
Yoshihiro Shimoda



From mchehab+huawei at kernel.org  Tue Aug  3 23:50:45 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 4 Aug 2021 08:50:45 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
Message-ID: <20210804085045.3dddbb9c@coco.lan>

Em Tue, 3 Aug 2021 16:11:42 -0600
Rob Herring <robh+dt at kernel.org> escreveu:

> On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> <mchehab+huawei at kernel.org> wrote:
> >
> > Hi Rob,
> >
> > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > corresponding PHY.
> >
> > It is identical to v2, except by:
> >         -          pcie at 7,0 { // Lane 7: Ethernet
> >         +          pcie at 7,0 { // Lane 6: Ethernet  
> 
> Can you check whether you have DT node links in sysfs for the PCI
> devices? If you don't, then something is wrong still in the topology
> or the PCI core is failing to set the DT node pointer in struct
> device. Though you don't rely on that currently, we want the topology
> to match. It's possible this never worked on arm/arm64 as mainly
> powerpc relied on this.
>
> I'd like some way to validate the DT matches the PCI topology. We
> could have a tool that generates the DT structure based on the PCI
> topology.

The of_node node link is on those places:

	$ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
	/sys/devices/platform/soc/f4000000.pcie/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node

This is the pci stuff under firmware:

	$ tree /sys/firmware/devicetree/base/soc/pcie at f4000000/
	/sys/firmware/devicetree/base/soc/pcie at f4000000/
	??? #address-cells
	??? bus-range
	??? compatible
	??? device_type
	??? hisilicon,clken-gpios
	??? #interrupt-cells
	??? interrupt-map
	??? interrupt-map-mask
	??? interrupt-names
	??? interrupts
	??? msi-parent
	??? name
	??? num-lanes
	??? pcie at 0,0
	??? ??? #address-cells
	??? ??? compatible
	??? ??? device_type
	??? ??? name
	??? ??? pcie at 1,0
	??? ??? ??? #address-cells
	??? ??? ??? compatible
	??? ??? ??? device_type
	??? ??? ??? name
	??? ??? ??? ranges
	??? ??? ??? reg
	??? ??? ??? reset-gpios
	??? ??? ??? #size-cells
	??? ??? pcie at 5,0
	??? ??? ??? #address-cells
	??? ??? ??? compatible
	??? ??? ??? device_type
	??? ??? ??? name
	??? ??? ??? ranges
	??? ??? ??? reg
	??? ??? ??? reset-gpios
	??? ??? ??? #size-cells
	??? ??? pcie at 7,0
	??? ??? ??? #address-cells
	??? ??? ??? compatible
	??? ??? ??? device_type
	??? ??? ??? name
	??? ??? ??? ranges
	??? ??? ??? reg
	??? ??? ??? reset-gpios
	??? ??? ??? #size-cells
	??? ??? ranges
	??? ??? reg
	??? ??? #size-cells
	??? phys
	??? ranges
	??? reg
	??? reg-names
	??? reset-gpios
	??? #size-cells

And this is what we get from the pcie devnode:

	/sys/devices/platform/soc/f4000000.pcie/
	??? driver -> ../../../../bus/platform/drivers/kirin-pcie
	??? driver_override
	??? modalias
	??? of_node -> ../../../../firmware/devicetree/base/soc/pcie at f4000000
	??? pci0000:00
	??? ??? 0000:00:00.0
	??? ??? ??? 0000:00:00.0:pcie001
	??? ??? ??? ??? driver -> ../../../../../../../bus/pci_express/drivers/pcie_pme
	??? ??? ??? ??? power
	??? ??? ??? ??? subsystem -> ../../../../../../../bus/pci_express
	??? ??? ??? ??? uevent
	??? ??? ??? 0000:00:00.0:pcie002
	??? ??? ??? ??? driver -> ../../../../../../../bus/pci_express/drivers/aer
	??? ??? ??? ??? power
	??? ??? ??? ??? subsystem -> ../../../../../../../bus/pci_express
	??? ??? ??? ??? uevent
	??? ??? ??? 0000:00:00.0:pcie010
	??? ??? ??? ??? power
	??? ??? ??? ??? subsystem -> ../../../../../../../bus/pci_express
	??? ??? ??? ??? uevent
	??? ??? ??? 0000:01:00.0
	??? ??? ??? ??? 0000:01:00.0:pcie102
	??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? subsystem -> ../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? 0000:02:01.0
	??? ??? ??? ??? ??? 0000:02:01.0:pcie202
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:02:01.0:pcie210
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:03:00.0
	??? ??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? ??? driver -> ../../../../../../../../../bus/pci/drivers/nvme
	??? ??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? ??? ??? clkpm
	??? ??? ??? ??? ??? ??? ??? l1_aspm
	??? ??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? ??? nvme
	??? ??? ??? ??? ??? ??? ??? nvme0
	??? ??? ??? ??? ??? ???     ??? address
	??? ??? ??? ??? ??? ???     ??? cntlid
	??? ??? ??? ??? ??? ???     ??? dev
	??? ??? ??? ??? ??? ???     ??? device -> ../../../0000:03:00.0
	??? ??? ??? ??? ??? ???     ??? firmware_rev
	??? ??? ??? ??? ??? ???     ??? kato
	??? ??? ??? ??? ??? ???     ??? model
	??? ??? ??? ??? ??? ???     ??? ng0n1
	??? ??? ??? ??? ??? ???     ??? ??? dev
	??? ??? ??? ??? ??? ???     ??? ??? device -> ../../nvme0
	??? ??? ??? ??? ??? ???     ??? ??? power
	??? ??? ??? ??? ??? ???     ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? ??? subsystem -> ../../../../../../../../../../../../class/nvme-generic
	??? ??? ??? ??? ??? ???     ??? ??? uevent
	??? ??? ??? ??? ??? ???     ??? numa_node
	??? ??? ??? ??? ??? ???     ??? nvme0n1
	??? ??? ??? ??? ??? ???     ??? ??? alignment_offset
	??? ??? ??? ??? ??? ???     ??? ??? bdi -> ../../../../../../../../../../../virtual/bdi/259:0
	??? ??? ??? ??? ??? ???     ??? ??? capability
	??? ??? ??? ??? ??? ???     ??? ??? dev
	??? ??? ??? ??? ??? ???     ??? ??? device -> ../../nvme0
	??? ??? ??? ??? ??? ???     ??? ??? discard_alignment
	??? ??? ??? ??? ??? ???     ??? ??? eui
	??? ??? ??? ??? ??? ???     ??? ??? events
	??? ??? ??? ??? ??? ???     ??? ??? events_async
	??? ??? ??? ??? ??? ???     ??? ??? events_poll_msecs
	??? ??? ??? ??? ??? ???     ??? ??? ext_range
	??? ??? ??? ??? ??? ???     ??? ??? hidden
	??? ??? ??? ??? ??? ???     ??? ??? holders
	??? ??? ??? ??? ??? ???     ??? ??? inflight
	??? ??? ??? ??? ??? ???     ??? ??? integrity
	??? ??? ??? ??? ??? ???     ??? ??? ??? device_is_integrity_capable
	??? ??? ??? ??? ??? ???     ??? ??? ??? format
	??? ??? ??? ??? ??? ???     ??? ??? ??? protection_interval_bytes
	??? ??? ??? ??? ??? ???     ??? ??? ??? read_verify
	??? ??? ??? ??? ??? ???     ??? ??? ??? tag_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? write_generate
	??? ??? ??? ??? ??? ???     ??? ??? mq
	??? ??? ??? ??? ??? ???     ??? ??? ??? 0
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu0
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu1
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu2
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu3
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu4
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu5
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu6
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu7
	??? ??? ??? ??? ??? ???     ??? ???     ??? cpu_list
	??? ??? ??? ??? ??? ???     ??? ???     ??? nr_reserved_tags
	??? ??? ??? ??? ??? ???     ??? ???     ??? nr_tags
	??? ??? ??? ??? ??? ???     ??? ??? nsid
	??? ??? ??? ??? ??? ???     ??? ??? nvme0n1p1
	??? ??? ??? ??? ??? ???     ??? ??? ??? alignment_offset
	??? ??? ??? ??? ??? ???     ??? ??? ??? dev
	??? ??? ??? ??? ??? ???     ??? ??? ??? discard_alignment
	??? ??? ??? ??? ??? ???     ??? ??? ??? holders
	??? ??? ??? ??? ??? ???     ??? ??? ??? inflight
	??? ??? ??? ??? ??? ???     ??? ??? ??? partition
	??? ??? ??? ??? ??? ???     ??? ??? ??? power
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? ??? ??? ro
	??? ??? ??? ??? ??? ???     ??? ??? ??? size
	??? ??? ??? ??? ??? ???     ??? ??? ??? start
	??? ??? ??? ??? ??? ???     ??? ??? ??? stat
	??? ??? ??? ??? ??? ???     ??? ??? ??? subsystem -> ../../../../../../../../../../../../../class/block
	??? ??? ??? ??? ??? ???     ??? ??? ??? uevent
	??? ??? ??? ??? ??? ???     ??? ??? power
	??? ??? ??? ??? ??? ???     ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? ??? queue
	??? ??? ??? ??? ??? ???     ??? ??? ??? add_random
	??? ??? ??? ??? ??? ???     ??? ??? ??? chunk_sectors
	??? ??? ??? ??? ??? ???     ??? ??? ??? dax
	??? ??? ??? ??? ??? ???     ??? ??? ??? discard_granularity
	??? ??? ??? ??? ??? ???     ??? ??? ??? discard_max_bytes
	??? ??? ??? ??? ??? ???     ??? ??? ??? discard_max_hw_bytes
	??? ??? ??? ??? ??? ???     ??? ??? ??? discard_zeroes_data
	??? ??? ??? ??? ??? ???     ??? ??? ??? fua
	??? ??? ??? ??? ??? ???     ??? ??? ??? hw_sector_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? io_poll
	??? ??? ??? ??? ??? ???     ??? ??? ??? io_poll_delay
	??? ??? ??? ??? ??? ???     ??? ??? ??? iosched
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? aging_expire
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? async_depth
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? fifo_batch
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? front_merges
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? read_expire
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? write_expire
	??? ??? ??? ??? ??? ???     ??? ??? ??? ??? writes_starved
	??? ??? ??? ??? ??? ???     ??? ??? ??? iostats
	??? ??? ??? ??? ??? ???     ??? ??? ??? io_timeout
	??? ??? ??? ??? ??? ???     ??? ??? ??? logical_block_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? max_discard_segments
	??? ??? ??? ??? ??? ???     ??? ??? ??? max_hw_sectors_kb
	??? ??? ??? ??? ??? ???     ??? ??? ??? max_integrity_segments
	??? ??? ??? ??? ??? ???     ??? ??? ??? max_sectors_kb
	??? ??? ??? ??? ??? ???     ??? ??? ??? max_segments
	??? ??? ??? ??? ??? ???     ??? ??? ??? max_segment_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? minimum_io_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? nomerges
	??? ??? ??? ??? ??? ???     ??? ??? ??? nr_requests
	??? ??? ??? ??? ??? ???     ??? ??? ??? nr_zones
	??? ??? ??? ??? ??? ???     ??? ??? ??? optimal_io_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? physical_block_size
	??? ??? ??? ??? ??? ???     ??? ??? ??? read_ahead_kb
	??? ??? ??? ??? ??? ???     ??? ??? ??? rotational
	??? ??? ??? ??? ??? ???     ??? ??? ??? rq_affinity
	??? ??? ??? ??? ??? ???     ??? ??? ??? scheduler
	??? ??? ??? ??? ??? ???     ??? ??? ??? stable_writes
	??? ??? ??? ??? ??? ???     ??? ??? ??? virt_boundary_mask
	??? ??? ??? ??? ??? ???     ??? ??? ??? wbt_lat_usec
	??? ??? ??? ??? ??? ???     ??? ??? ??? write_cache
	??? ??? ??? ??? ??? ???     ??? ??? ??? write_same_max_bytes
	??? ??? ??? ??? ??? ???     ??? ??? ??? write_zeroes_max_bytes
	??? ??? ??? ??? ??? ???     ??? ??? ??? zone_append_max_bytes
	??? ??? ??? ??? ??? ???     ??? ??? ??? zoned
	??? ??? ??? ??? ??? ???     ??? ??? ??? zone_write_granularity
	??? ??? ??? ??? ??? ???     ??? ??? range
	??? ??? ??? ??? ??? ???     ??? ??? removable
	??? ??? ??? ??? ??? ???     ??? ??? ro
	??? ??? ??? ??? ??? ???     ??? ??? size
	??? ??? ??? ??? ??? ???     ??? ??? slaves
	??? ??? ??? ??? ??? ???     ??? ??? stat
	??? ??? ??? ??? ??? ???     ??? ??? subsystem -> ../../../../../../../../../../../../class/block
	??? ??? ??? ??? ??? ???     ??? ??? uevent
	??? ??? ??? ??? ??? ???     ??? ??? wwid
	??? ??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? pm_qos_latency_tolerance_us
	??? ??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? queue_count
	??? ??? ??? ??? ??? ???     ??? rescan_controller
	??? ??? ??? ??? ??? ???     ??? reset_controller
	??? ??? ??? ??? ??? ???     ??? serial
	??? ??? ??? ??? ??? ???     ??? sqsize
	??? ??? ??? ??? ??? ???     ??? state
	??? ??? ??? ??? ??? ???     ??? subsysnqn
	??? ??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../../class/nvme
	??? ??? ??? ??? ??? ???     ??? transport
	??? ??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? ??? pools
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? ??? reset
	??? ??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? ??? resource0
	??? ??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci
	??? ??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? driver -> ../../../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? pci_bus
	??? ??? ??? ??? ??? ??? 0000:03
	??? ??? ??? ??? ???     ??? cpuaffinity
	??? ??? ??? ??? ???     ??? cpulistaffinity
	??? ??? ??? ??? ???     ??? device -> ../../../0000:02:01.0
	??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ???     ??? rescan
	??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../class/pci_bus
	??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? reset
	??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? secondary_bus_number
	??? ??? ??? ??? ??? subordinate_bus_number
	??? ??? ??? ??? ??? subsystem -> ../../../../../../../../bus/pci
	??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? 0000:02:04.0
	??? ??? ??? ??? ??? 0000:02:04.0:pcie202
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:02:04.0:pcie210
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? driver -> ../../../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? pci_bus
	??? ??? ??? ??? ??? ??? 0000:04
	??? ??? ??? ??? ???     ??? cpuaffinity
	??? ??? ??? ??? ???     ??? cpulistaffinity
	??? ??? ??? ??? ???     ??? device -> ../../../0000:02:04.0
	??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ???     ??? rescan
	??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../class/pci_bus
	??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? secondary_bus_number
	??? ??? ??? ??? ??? subordinate_bus_number
	??? ??? ??? ??? ??? subsystem -> ../../../../../../../../bus/pci
	??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? 0000:02:05.0
	??? ??? ??? ??? ??? 0000:02:05.0:pcie202
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:02:05.0:pcie210
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:05:00.0
	??? ??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? ??? ??? clkpm
	??? ??? ??? ??? ??? ??? ??? l0s_aspm
	??? ??? ??? ??? ??? ??? ??? l1_aspm
	??? ??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? ??? reset
	??? ??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? ??? resource0
	??? ??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci
	??? ??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? driver -> ../../../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? pci_bus
	??? ??? ??? ??? ??? ??? 0000:05
	??? ??? ??? ??? ???     ??? cpuaffinity
	??? ??? ??? ??? ???     ??? cpulistaffinity
	??? ??? ??? ??? ???     ??? device -> ../../../0000:02:05.0
	??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ???     ??? rescan
	??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../class/pci_bus
	??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? secondary_bus_number
	??? ??? ??? ??? ??? subordinate_bus_number
	??? ??? ??? ??? ??? subsystem -> ../../../../../../../../bus/pci
	??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? 0000:02:07.0
	??? ??? ??? ??? ??? 0000:02:07.0:pcie202
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:02:07.0:pcie210
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:06:00.0
	??? ??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? ??? driver -> ../../../../../../../../../bus/pci/drivers/r8169
	??? ??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? ??? ??? clkpm
	??? ??? ??? ??? ??? ??? ??? l1_aspm
	??? ??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? ??? mdio_bus
	??? ??? ??? ??? ??? ??? ??? r8169-600
	??? ??? ??? ??? ??? ???     ??? device -> ../../../0000:06:00.0
	??? ??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? r8169-600:00
	??? ??? ??? ??? ??? ???     ??? ??? attached_dev -> ../../../net/enp6s0
	??? ??? ??? ??? ??? ???     ??? ??? driver -> ../../../../../../../../../../../../bus/mdio_bus/drivers/RTL8211E Gigabit Ethernet
	??? ??? ??? ??? ??? ???     ??? ??? phy_dev_flags
	??? ??? ??? ??? ??? ???     ??? ??? phy_has_fixups
	??? ??? ??? ??? ??? ???     ??? ??? phy_id
	??? ??? ??? ??? ??? ???     ??? ??? phy_interface
	??? ??? ??? ??? ??? ???     ??? ??? power
	??? ??? ??? ??? ??? ???     ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? ??? statistics
	??? ??? ??? ??? ??? ???     ??? ??? ??? errors
	??? ??? ??? ??? ??? ???     ??? ??? ??? reads
	??? ??? ??? ??? ??? ???     ??? ??? ??? transfers
	??? ??? ??? ??? ??? ???     ??? ??? ??? writes
	??? ??? ??? ??? ??? ???     ??? ??? subsystem -> ../../../../../../../../../../../../bus/mdio_bus
	??? ??? ??? ??? ??? ???     ??? ??? uevent
	??? ??? ??? ??? ??? ???     ??? statistics
	??? ??? ??? ??? ??? ???     ??? ??? errors
	??? ??? ??? ??? ??? ???     ??? ??? errors_0
	??? ??? ??? ??? ??? ???     ??? ??? errors_1
	??? ??? ??? ??? ??? ???     ??? ??? errors_10
	??? ??? ??? ??? ??? ???     ??? ??? errors_11
	??? ??? ??? ??? ??? ???     ??? ??? errors_12
	??? ??? ??? ??? ??? ???     ??? ??? errors_13
	??? ??? ??? ??? ??? ???     ??? ??? errors_14
	??? ??? ??? ??? ??? ???     ??? ??? errors_15
	??? ??? ??? ??? ??? ???     ??? ??? errors_16
	??? ??? ??? ??? ??? ???     ??? ??? errors_17
	??? ??? ??? ??? ??? ???     ??? ??? errors_18
	??? ??? ??? ??? ??? ???     ??? ??? errors_19
	??? ??? ??? ??? ??? ???     ??? ??? errors_2
	??? ??? ??? ??? ??? ???     ??? ??? errors_20
	??? ??? ??? ??? ??? ???     ??? ??? errors_21
	??? ??? ??? ??? ??? ???     ??? ??? errors_22
	??? ??? ??? ??? ??? ???     ??? ??? errors_23
	??? ??? ??? ??? ??? ???     ??? ??? errors_24
	??? ??? ??? ??? ??? ???     ??? ??? errors_25
	??? ??? ??? ??? ??? ???     ??? ??? errors_26
	??? ??? ??? ??? ??? ???     ??? ??? errors_27
	??? ??? ??? ??? ??? ???     ??? ??? errors_28
	??? ??? ??? ??? ??? ???     ??? ??? errors_29
	??? ??? ??? ??? ??? ???     ??? ??? errors_3
	??? ??? ??? ??? ??? ???     ??? ??? errors_30
	??? ??? ??? ??? ??? ???     ??? ??? errors_31
	??? ??? ??? ??? ??? ???     ??? ??? errors_4
	??? ??? ??? ??? ??? ???     ??? ??? errors_5
	??? ??? ??? ??? ??? ???     ??? ??? errors_6
	??? ??? ??? ??? ??? ???     ??? ??? errors_7
	??? ??? ??? ??? ??? ???     ??? ??? errors_8
	??? ??? ??? ??? ??? ???     ??? ??? errors_9
	??? ??? ??? ??? ??? ???     ??? ??? reads
	??? ??? ??? ??? ??? ???     ??? ??? reads_0
	??? ??? ??? ??? ??? ???     ??? ??? reads_1
	??? ??? ??? ??? ??? ???     ??? ??? reads_10
	??? ??? ??? ??? ??? ???     ??? ??? reads_11
	??? ??? ??? ??? ??? ???     ??? ??? reads_12
	??? ??? ??? ??? ??? ???     ??? ??? reads_13
	??? ??? ??? ??? ??? ???     ??? ??? reads_14
	??? ??? ??? ??? ??? ???     ??? ??? reads_15
	??? ??? ??? ??? ??? ???     ??? ??? reads_16
	??? ??? ??? ??? ??? ???     ??? ??? reads_17
	??? ??? ??? ??? ??? ???     ??? ??? reads_18
	??? ??? ??? ??? ??? ???     ??? ??? reads_19
	??? ??? ??? ??? ??? ???     ??? ??? reads_2
	??? ??? ??? ??? ??? ???     ??? ??? reads_20
	??? ??? ??? ??? ??? ???     ??? ??? reads_21
	??? ??? ??? ??? ??? ???     ??? ??? reads_22
	??? ??? ??? ??? ??? ???     ??? ??? reads_23
	??? ??? ??? ??? ??? ???     ??? ??? reads_24
	??? ??? ??? ??? ??? ???     ??? ??? reads_25
	??? ??? ??? ??? ??? ???     ??? ??? reads_26
	??? ??? ??? ??? ??? ???     ??? ??? reads_27
	??? ??? ??? ??? ??? ???     ??? ??? reads_28
	??? ??? ??? ??? ??? ???     ??? ??? reads_29
	??? ??? ??? ??? ??? ???     ??? ??? reads_3
	??? ??? ??? ??? ??? ???     ??? ??? reads_30
	??? ??? ??? ??? ??? ???     ??? ??? reads_31
	??? ??? ??? ??? ??? ???     ??? ??? reads_4
	??? ??? ??? ??? ??? ???     ??? ??? reads_5
	??? ??? ??? ??? ??? ???     ??? ??? reads_6
	??? ??? ??? ??? ??? ???     ??? ??? reads_7
	??? ??? ??? ??? ??? ???     ??? ??? reads_8
	??? ??? ??? ??? ??? ???     ??? ??? reads_9
	??? ??? ??? ??? ??? ???     ??? ??? transfers
	??? ??? ??? ??? ??? ???     ??? ??? transfers_0
	??? ??? ??? ??? ??? ???     ??? ??? transfers_1
	??? ??? ??? ??? ??? ???     ??? ??? transfers_10
	??? ??? ??? ??? ??? ???     ??? ??? transfers_11
	??? ??? ??? ??? ??? ???     ??? ??? transfers_12
	??? ??? ??? ??? ??? ???     ??? ??? transfers_13
	??? ??? ??? ??? ??? ???     ??? ??? transfers_14
	??? ??? ??? ??? ??? ???     ??? ??? transfers_15
	??? ??? ??? ??? ??? ???     ??? ??? transfers_16
	??? ??? ??? ??? ??? ???     ??? ??? transfers_17
	??? ??? ??? ??? ??? ???     ??? ??? transfers_18
	??? ??? ??? ??? ??? ???     ??? ??? transfers_19
	??? ??? ??? ??? ??? ???     ??? ??? transfers_2
	??? ??? ??? ??? ??? ???     ??? ??? transfers_20
	??? ??? ??? ??? ??? ???     ??? ??? transfers_21
	??? ??? ??? ??? ??? ???     ??? ??? transfers_22
	??? ??? ??? ??? ??? ???     ??? ??? transfers_23
	??? ??? ??? ??? ??? ???     ??? ??? transfers_24
	??? ??? ??? ??? ??? ???     ??? ??? transfers_25
	??? ??? ??? ??? ??? ???     ??? ??? transfers_26
	??? ??? ??? ??? ??? ???     ??? ??? transfers_27
	??? ??? ??? ??? ??? ???     ??? ??? transfers_28
	??? ??? ??? ??? ??? ???     ??? ??? transfers_29
	??? ??? ??? ??? ??? ???     ??? ??? transfers_3
	??? ??? ??? ??? ??? ???     ??? ??? transfers_30
	??? ??? ??? ??? ??? ???     ??? ??? transfers_31
	??? ??? ??? ??? ??? ???     ??? ??? transfers_4
	??? ??? ??? ??? ??? ???     ??? ??? transfers_5
	??? ??? ??? ??? ??? ???     ??? ??? transfers_6
	??? ??? ??? ??? ??? ???     ??? ??? transfers_7
	??? ??? ??? ??? ??? ???     ??? ??? transfers_8
	??? ??? ??? ??? ??? ???     ??? ??? transfers_9
	??? ??? ??? ??? ??? ???     ??? ??? writes
	??? ??? ??? ??? ??? ???     ??? ??? writes_0
	??? ??? ??? ??? ??? ???     ??? ??? writes_1
	??? ??? ??? ??? ??? ???     ??? ??? writes_10
	??? ??? ??? ??? ??? ???     ??? ??? writes_11
	??? ??? ??? ??? ??? ???     ??? ??? writes_12
	??? ??? ??? ??? ??? ???     ??? ??? writes_13
	??? ??? ??? ??? ??? ???     ??? ??? writes_14
	??? ??? ??? ??? ??? ???     ??? ??? writes_15
	??? ??? ??? ??? ??? ???     ??? ??? writes_16
	??? ??? ??? ??? ??? ???     ??? ??? writes_17
	??? ??? ??? ??? ??? ???     ??? ??? writes_18
	??? ??? ??? ??? ??? ???     ??? ??? writes_19
	??? ??? ??? ??? ??? ???     ??? ??? writes_2
	??? ??? ??? ??? ??? ???     ??? ??? writes_20
	??? ??? ??? ??? ??? ???     ??? ??? writes_21
	??? ??? ??? ??? ??? ???     ??? ??? writes_22
	??? ??? ??? ??? ??? ???     ??? ??? writes_23
	??? ??? ??? ??? ??? ???     ??? ??? writes_24
	??? ??? ??? ??? ??? ???     ??? ??? writes_25
	??? ??? ??? ??? ??? ???     ??? ??? writes_26
	??? ??? ??? ??? ??? ???     ??? ??? writes_27
	??? ??? ??? ??? ??? ???     ??? ??? writes_28
	??? ??? ??? ??? ??? ???     ??? ??? writes_29
	??? ??? ??? ??? ??? ???     ??? ??? writes_3
	??? ??? ??? ??? ??? ???     ??? ??? writes_30
	??? ??? ??? ??? ??? ???     ??? ??? writes_31
	??? ??? ??? ??? ??? ???     ??? ??? writes_4
	??? ??? ??? ??? ??? ???     ??? ??? writes_5
	??? ??? ??? ??? ??? ???     ??? ??? writes_6
	??? ??? ??? ??? ??? ???     ??? ??? writes_7
	??? ??? ??? ??? ??? ???     ??? ??? writes_8
	??? ??? ??? ??? ??? ???     ??? ??? writes_9
	??? ??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../../class/mdio_bus
	??? ??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? ??? net
	??? ??? ??? ??? ??? ??? ??? enp6s0
	??? ??? ??? ??? ??? ???     ??? addr_assign_type
	??? ??? ??? ??? ??? ???     ??? address
	??? ??? ??? ??? ??? ???     ??? addr_len
	??? ??? ??? ??? ??? ???     ??? broadcast
	??? ??? ??? ??? ??? ???     ??? carrier
	??? ??? ??? ??? ??? ???     ??? carrier_changes
	??? ??? ??? ??? ??? ???     ??? carrier_down_count
	??? ??? ??? ??? ??? ???     ??? carrier_up_count
	??? ??? ??? ??? ??? ???     ??? device -> ../../../0000:06:00.0
	??? ??? ??? ??? ??? ???     ??? dev_id
	??? ??? ??? ??? ??? ???     ??? dev_port
	??? ??? ??? ??? ??? ???     ??? dormant
	??? ??? ??? ??? ??? ???     ??? duplex
	??? ??? ??? ??? ??? ???     ??? flags
	??? ??? ??? ??? ??? ???     ??? gro_flush_timeout
	??? ??? ??? ??? ??? ???     ??? ifalias
	??? ??? ??? ??? ??? ???     ??? ifindex
	??? ??? ??? ??? ??? ???     ??? iflink
	??? ??? ??? ??? ??? ???     ??? link_mode
	??? ??? ??? ??? ??? ???     ??? mtu
	??? ??? ??? ??? ??? ???     ??? name_assign_type
	??? ??? ??? ??? ??? ???     ??? napi_defer_hard_irqs
	??? ??? ??? ??? ??? ???     ??? netdev_group
	??? ??? ??? ??? ??? ???     ??? operstate
	??? ??? ??? ??? ??? ???     ??? phydev -> ../../mdio_bus/r8169-600/r8169-600:00
	??? ??? ??? ??? ??? ???     ??? phys_port_id
	??? ??? ??? ??? ??? ???     ??? phys_port_name
	??? ??? ??? ??? ??? ???     ??? phys_switch_id
	??? ??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ???     ??? proto_down
	??? ??? ??? ??? ??? ???     ??? queues
	??? ??? ??? ??? ??? ???     ??? ??? rx-0
	??? ??? ??? ??? ??? ???     ??? ??? ??? rps_cpus
	??? ??? ??? ??? ??? ???     ??? ??? ??? rps_flow_cnt
	??? ??? ??? ??? ??? ???     ??? ??? tx-0
	??? ??? ??? ??? ??? ???     ???     ??? byte_queue_limits
	??? ??? ??? ??? ??? ???     ???     ??? ??? hold_time
	??? ??? ??? ??? ??? ???     ???     ??? ??? inflight
	??? ??? ??? ??? ??? ???     ???     ??? ??? limit
	??? ??? ??? ??? ??? ???     ???     ??? ??? limit_max
	??? ??? ??? ??? ??? ???     ???     ??? ??? limit_min
	??? ??? ??? ??? ??? ???     ???     ??? traffic_class
	??? ??? ??? ??? ??? ???     ???     ??? tx_maxrate
	??? ??? ??? ??? ??? ???     ???     ??? tx_timeout
	??? ??? ??? ??? ??? ???     ???     ??? xps_cpus
	??? ??? ??? ??? ??? ???     ???     ??? xps_rxqs
	??? ??? ??? ??? ??? ???     ??? speed
	??? ??? ??? ??? ??? ???     ??? statistics
	??? ??? ??? ??? ??? ???     ??? ??? collisions
	??? ??? ??? ??? ??? ???     ??? ??? multicast
	??? ??? ??? ??? ??? ???     ??? ??? rx_bytes
	??? ??? ??? ??? ??? ???     ??? ??? rx_compressed
	??? ??? ??? ??? ??? ???     ??? ??? rx_crc_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_dropped
	??? ??? ??? ??? ??? ???     ??? ??? rx_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_fifo_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_frame_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_length_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_missed_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_nohandler
	??? ??? ??? ??? ??? ???     ??? ??? rx_over_errors
	??? ??? ??? ??? ??? ???     ??? ??? rx_packets
	??? ??? ??? ??? ??? ???     ??? ??? tx_aborted_errors
	??? ??? ??? ??? ??? ???     ??? ??? tx_bytes
	??? ??? ??? ??? ??? ???     ??? ??? tx_carrier_errors
	??? ??? ??? ??? ??? ???     ??? ??? tx_compressed
	??? ??? ??? ??? ??? ???     ??? ??? tx_dropped
	??? ??? ??? ??? ??? ???     ??? ??? tx_errors
	??? ??? ??? ??? ??? ???     ??? ??? tx_fifo_errors
	??? ??? ??? ??? ??? ???     ??? ??? tx_heartbeat_errors
	??? ??? ??? ??? ??? ???     ??? ??? tx_packets
	??? ??? ??? ??? ??? ???     ??? ??? tx_window_errors
	??? ??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../../class/net
	??? ??? ??? ??? ??? ???     ??? testing
	??? ??? ??? ??? ??? ???     ??? threaded
	??? ??? ??? ??? ??? ???     ??? tx_queue_len
	??? ??? ??? ??? ??? ???     ??? type
	??? ??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? ??? reset
	??? ??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? ??? resource2
	??? ??? ??? ??? ??? ??? resource4
	??? ??? ??? ??? ??? ??? resource4_wc
	??? ??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci
	??? ??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? ??? ??? vpd
	??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? driver -> ../../../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? pci_bus
	??? ??? ??? ??? ??? ??? 0000:06
	??? ??? ??? ??? ???     ??? cpuaffinity
	??? ??? ??? ??? ???     ??? cpulistaffinity
	??? ??? ??? ??? ???     ??? device -> ../../../0000:02:07.0
	??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ???     ??? rescan
	??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../class/pci_bus
	??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? secondary_bus_number
	??? ??? ??? ??? ??? subordinate_bus_number
	??? ??? ??? ??? ??? subsystem -> ../../../../../../../../bus/pci
	??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? 0000:02:09.0
	??? ??? ??? ??? ??? 0000:02:09.0:pcie202
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? 0000:02:09.0:pcie210
	??? ??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? subsystem -> ../../../../../../../../../bus/pci_express
	??? ??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? ??? class
	??? ??? ??? ??? ??? config
	??? ??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? ??? current_link_width
	??? ??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? ??? device
	??? ??? ??? ??? ??? devspec
	??? ??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? ??? driver -> ../../../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? ??? ??? driver_override
	??? ??? ??? ??? ??? enable
	??? ??? ??? ??? ??? irq
	??? ??? ??? ??? ??? link
	??? ??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? ??? local_cpus
	??? ??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? ??? max_link_width
	??? ??? ??? ??? ??? modalias
	??? ??? ??? ??? ??? msi_bus
	??? ??? ??? ??? ??? numa_node
	??? ??? ??? ??? ??? pci_bus
	??? ??? ??? ??? ??? ??? 0000:07
	??? ??? ??? ??? ???     ??? cpuaffinity
	??? ??? ??? ??? ???     ??? cpulistaffinity
	??? ??? ??? ??? ???     ??? device -> ../../../0000:02:09.0
	??? ??? ??? ??? ???     ??? power
	??? ??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ???     ??? ??? control
	??? ??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ??? ???     ??? rescan
	??? ??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../../class/pci_bus
	??? ??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? ??? power
	??? ??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? ??? power_state
	??? ??? ??? ??? ??? remove
	??? ??? ??? ??? ??? rescan
	??? ??? ??? ??? ??? resource
	??? ??? ??? ??? ??? revision
	??? ??? ??? ??? ??? secondary_bus_number
	??? ??? ??? ??? ??? subordinate_bus_number
	??? ??? ??? ??? ??? subsystem -> ../../../../../../../../bus/pci
	??? ??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? ??? uevent
	??? ??? ??? ??? ??? vendor
	??? ??? ??? ??? aer_dev_correctable
	??? ??? ??? ??? aer_dev_fatal
	??? ??? ??? ??? aer_dev_nonfatal
	??? ??? ??? ??? ari_enabled
	??? ??? ??? ??? broken_parity_status
	??? ??? ??? ??? class
	??? ??? ??? ??? config
	??? ??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? ??? current_link_speed
	??? ??? ??? ??? current_link_width
	??? ??? ??? ??? d3cold_allowed
	??? ??? ??? ??? device
	??? ??? ??? ??? devspec
	??? ??? ??? ??? dma_mask_bits
	??? ??? ??? ??? driver -> ../../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? ??? driver_override
	??? ??? ??? ??? enable
	??? ??? ??? ??? irq
	??? ??? ??? ??? link
	??? ??? ??? ??? ??? l0s_aspm
	??? ??? ??? ??? ??? l1_aspm
	??? ??? ??? ??? local_cpulist
	??? ??? ??? ??? local_cpus
	??? ??? ??? ??? max_link_speed
	??? ??? ??? ??? max_link_width
	??? ??? ??? ??? modalias
	??? ??? ??? ??? msi_bus
	??? ??? ??? ??? numa_node
	??? ??? ??? ??? pci_bus
	??? ??? ??? ??? ??? 0000:02
	??? ??? ??? ???     ??? cpuaffinity
	??? ??? ??? ???     ??? cpulistaffinity
	??? ??? ??? ???     ??? device -> ../../../0000:01:00.0
	??? ??? ??? ???     ??? power
	??? ??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ??? ???     ??? ??? control
	??? ??? ??? ???     ??? ??? runtime_active_time
	??? ??? ??? ???     ??? ??? runtime_status
	??? ??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ??? ???     ??? rescan
	??? ??? ??? ???     ??? subsystem -> ../../../../../../../../../class/pci_bus
	??? ??? ??? ???     ??? uevent
	??? ??? ??? ??? power
	??? ??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? ??? control
	??? ??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? ??? runtime_status
	??? ??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? ??? wakeup
	??? ??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? ??? power_state
	??? ??? ??? ??? remove
	??? ??? ??? ??? rescan
	??? ??? ??? ??? reset
	??? ??? ??? ??? resource
	??? ??? ??? ??? resource0
	??? ??? ??? ??? revision
	??? ??? ??? ??? secondary_bus_number
	??? ??? ??? ??? subordinate_bus_number
	??? ??? ??? ??? subsystem -> ../../../../../../../bus/pci
	??? ??? ??? ??? subsystem_device
	??? ??? ??? ??? subsystem_vendor
	??? ??? ??? ??? uevent
	??? ??? ??? ??? vendor
	??? ??? ??? aer_dev_correctable
	??? ??? ??? aer_dev_fatal
	??? ??? ??? aer_dev_nonfatal
	??? ??? ??? aer_rootport_total_err_cor
	??? ??? ??? aer_rootport_total_err_fatal
	??? ??? ??? aer_rootport_total_err_nonfatal
	??? ??? ??? ari_enabled
	??? ??? ??? broken_parity_status
	??? ??? ??? class
	??? ??? ??? config
	??? ??? ??? consistent_dma_mask_bits
	??? ??? ??? current_link_speed
	??? ??? ??? current_link_width
	??? ??? ??? d3cold_allowed
	??? ??? ??? device
	??? ??? ??? devspec
	??? ??? ??? dma_mask_bits
	??? ??? ??? driver -> ../../../../../../bus/pci/drivers/pcieport
	??? ??? ??? driver_override
	??? ??? ??? enable
	??? ??? ??? irq
	??? ??? ??? link
	??? ??? ??? local_cpulist
	??? ??? ??? local_cpus
	??? ??? ??? max_link_speed
	??? ??? ??? max_link_width
	??? ??? ??? modalias
	??? ??? ??? msi_bus
	??? ??? ??? numa_node
	??? ??? ??? of_node -> ../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
	??? ??? ??? pci_bus
	??? ??? ??? ??? 0000:01
	??? ??? ???     ??? cpuaffinity
	??? ??? ???     ??? cpulistaffinity
	??? ??? ???     ??? device -> ../../../0000:00:00.0
	??? ??? ???     ??? of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
	??? ??? ???     ??? power
	??? ??? ???     ??? ??? autosuspend_delay_ms
	??? ??? ???     ??? ??? control
	??? ??? ???     ??? ??? runtime_active_time
	??? ??? ???     ??? ??? runtime_status
	??? ??? ???     ??? ??? runtime_suspended_time
	??? ??? ???     ??? rescan
	??? ??? ???     ??? subsystem -> ../../../../../../../../class/pci_bus
	??? ??? ???     ??? uevent
	??? ??? ???     ??? waiting_for_supplier
	??? ??? ??? power
	??? ??? ??? ??? autosuspend_delay_ms
	??? ??? ??? ??? control
	??? ??? ??? ??? runtime_active_time
	??? ??? ??? ??? runtime_status
	??? ??? ??? ??? runtime_suspended_time
	??? ??? ??? ??? wakeup
	??? ??? ??? ??? wakeup_abort_count
	??? ??? ??? ??? wakeup_active
	??? ??? ??? ??? wakeup_active_count
	??? ??? ??? ??? wakeup_count
	??? ??? ??? ??? wakeup_expire_count
	??? ??? ??? ??? wakeup_last_time_ms
	??? ??? ??? ??? wakeup_max_time_ms
	??? ??? ??? ??? wakeup_total_time_ms
	??? ??? ??? power_state
	??? ??? ??? remove
	??? ??? ??? rescan
	??? ??? ??? reset
	??? ??? ??? resource
	??? ??? ??? resource0
	??? ??? ??? revision
	??? ??? ??? secondary_bus_number
	??? ??? ??? subordinate_bus_number
	??? ??? ??? subsystem -> ../../../../../../bus/pci
	??? ??? ??? subsystem_device
	??? ??? ??? subsystem_vendor
	??? ??? ??? uevent
	??? ??? ??? vendor
	??? ??? pci_bus
	??? ??? ??? 0000:00
	??? ???     ??? cpuaffinity
	??? ???     ??? cpulistaffinity
	??? ???     ??? device -> ../../../pci0000:00
	??? ???     ??? of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000
	??? ???     ??? power
	??? ???     ??? ??? autosuspend_delay_ms
	??? ???     ??? ??? control
	??? ???     ??? ??? runtime_active_time
	??? ???     ??? ??? runtime_status
	??? ???     ??? ??? runtime_suspended_time
	??? ???     ??? rescan
	??? ???     ??? subsystem -> ../../../../../../../class/pci_bus
	??? ???     ??? uevent
	??? ???     ??? waiting_for_supplier
	??? ??? power
	??? ??? ??? autosuspend_delay_ms
	??? ??? ??? control
	??? ??? ??? runtime_active_time
	??? ??? ??? runtime_status
	??? ??? ??? runtime_suspended_time
	??? ??? uevent
	??? power
	??? ??? autosuspend_delay_ms
	??? ??? control
	??? ??? runtime_active_time
	??? ??? runtime_status
	??? ??? runtime_suspended_time
	??? subsystem -> ../../../../bus/platform
	??? supplier:amba:e8a12000.gpio -> ../../../virtual/devlink/amba:e8a12000.gpio--platform:f4000000.pcie
	??? supplier:amba:e8a1c000.gpio -> ../../../virtual/devlink/amba:e8a1c000.gpio--platform:f4000000.pcie
	??? supplier:amba:e8a1f000.gpio -> ../../../virtual/devlink/amba:e8a1f000.gpio--platform:f4000000.pcie
	??? supplier:amba:fff10000.gpio -> ../../../virtual/devlink/amba:fff10000.gpio--platform:f4000000.pcie
	??? supplier:phy:phy-fc000000.pcie-phy.1 -> ../../../virtual/devlink/phy:phy-fc000000.pcie-phy.1--platform:f4000000.pcie
	??? supplier:platform:fc000000.pcie-phy -> ../../../virtual/devlink/platform:fc000000.pcie-phy--platform:f4000000.pcie
	??? uevent

Thanks,
Mauro


From baruch at tkos.co.il  Wed Aug  4 07:05:05 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:05 +0300
Subject: [PATCH v2 1/6] dt-bindings: phy: qcom,qmp: Add IPQ6018 USB3 PHY
Message-ID: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>

Add compatible string for USB3 PHY in Qualcomm IPQ6018 SoC.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index f0497b8623ad..3ae865988f04 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -18,6 +18,7 @@ properties:
   compatible:
     enum:
       - qcom,ipq6018-qmp-pcie-phy
+      - qcom,ipq6018-qmp-usb3-phy
       - qcom,ipq8074-qmp-pcie-phy
       - qcom,ipq8074-qmp-usb3-phy
       - qcom,msm8996-qmp-pcie-phy
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:06 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:06 +0300
Subject: [PATCH v2 2/6] phy: qcom-qmp: add USB3 PHY support for IPQ6018
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <6eec7ef4ecd1e8360ebe8e425151121684e997ed.1628085910.git.baruch@tkos.co.il>

Initialization is identical to the IPQ8074 USB3 PHY.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index cfe359488f5c..da02279534f0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -5225,6 +5225,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
 	}, {
 		.compatible = "qcom,ipq6018-qmp-pcie-phy",
 		.data = &ipq6018_pciephy_cfg,
+	}, {
+		.compatible = "qcom,ipq6018-qmp-usb3-phy",
+		.data = &ipq8074_usb3phy_cfg,
 	}, {
 		.compatible = "qcom,sc7180-qmp-usb3-phy",
 		.data = &sc7180_usb3phy_cfg,
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:08 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:08 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>

From: Balaji Prakash J <bjagadee at codeaurora.org>

Set reference clock period when it differs from dwc3 default hardware
set.

Tested (USB2 only) on IPQ6010 SoC based board with 24 MHz reference
clock while hardware default is 19.2 MHz.

Signed-off-by: Balaji Prakash J <bjagadee at codeaurora.org>
[ baruch: rewrite commit message; drop GFLADJ code; remove 'quirk-' from
  property name; mention tested hardware ]
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v2:

  Remove snps,quirk-ref-clock-adjustment; not needed for tested hardware

  Rename DT property to snps,ref-clock-period (Thinh Nguyen)

  Use FIELD_PREP() (Bjorn Andersson)
---
 drivers/usb/dwc3/core.c | 29 +++++++++++++++++++++++++++++
 drivers/usb/dwc3/core.h |  6 ++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ba74ad7f6995..7ec5bfb5fc11 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -26,6 +26,7 @@
 #include <linux/acpi.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/reset.h>
+#include <linux/bitfield.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -351,6 +352,29 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 	}
 }
 
+/**
+ * dwc3_ref_clk_period - Reference clock period configuration
+ *		Default reference clock period depends on hardware
+ *		configuration. For systems with reference clock that differs
+ *		from the default, this will set clock period in DWC3_GUCTL
+ *		register.
+ * @dwc: Pointer to our controller context structure
+ * @ref_clk_per: reference clock period in ns
+ */
+static void dwc3_ref_clk_period(struct dwc3 *dwc)
+{
+	u32 reg;
+
+	if (dwc->ref_clk_per == 0)
+		return;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+	reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
+	reg |=  FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, dwc->ref_clk_per);
+	dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+}
+
+
 /**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
@@ -1011,6 +1035,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	/* Adjust Frame Length */
 	dwc3_frame_length_adjustment(dwc);
 
+	/* Adjust Reference Clock Period */
+	dwc3_ref_clk_period(dwc);
+
 	dwc3_set_incr_burst_type(dwc);
 
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
@@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 				    &dwc->hsphy_interface);
 	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
 				 &dwc->fladj);
+	device_property_read_u32(dev, "snps,ref-clock-period",
+				 &dwc->ref_clk_per);
 
 	dwc->dis_metastability_quirk = device_property_read_bool(dev,
 				"snps,dis_metastability_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 5991766239ba..1e4e21ea9d97 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -386,6 +386,10 @@
 #define DWC3_GFLADJ_30MHZ_SDBND_SEL		BIT(7)
 #define DWC3_GFLADJ_30MHZ_MASK			0x3f
 
+/* Global User Control Register*/
+#define DWC3_GUCTL_REFCLKPER_MASK		0xffc00000
+#define DWC3_GUCTL_REFCLKPER_SEL		22
+
 /* Global User Control Register 2 */
 #define DWC3_GUCTL2_RST_ACTBITLATER		BIT(14)
 
@@ -969,6 +973,7 @@ struct dwc3_scratchpad_array {
  * @regs: base address for our registers
  * @regs_size: address space size
  * @fladj: frame length adjustment
+ * @ref_clk_per: reference clock period configuration
  * @irq_gadget: peripheral controller's IRQ number
  * @otg_irq: IRQ number for OTG IRQs
  * @current_otg_role: current role of operation while using the OTG block
@@ -1141,6 +1146,7 @@ struct dwc3 {
 	struct power_supply	*usb_psy;
 
 	u32			fladj;
+	u32			ref_clk_per;
 	u32			irq_gadget;
 	u32			otg_irq;
 	u32			current_otg_role;
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:09 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:09 +0300
Subject: [PATCH v2 5/6] dt-bindings: usb: qcom,dwc3: add binding for IPQ6018
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <24ce7c1258790b35a08e14a1e79a9447c3fed354.1628085910.git.baruch@tkos.co.il>

Add compatible string for Qualcomm IPQ6018 SoC.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
index 4e6451789806..55ed4b4c7f51 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
@@ -13,6 +13,7 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,ipq6018-dwc3
           - qcom,msm8996-dwc3
           - qcom,msm8998-dwc3
           - qcom,sc7180-dwc3
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:07 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:07 +0300
Subject: [PATCH v2 3/6] dt-bindings: usb: dwc3: add reference clock period
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <22f62c59471e128b681a731997a9416ab2e91acf.1628085910.git.baruch@tkos.co.il>

Document the snps,ref-clock-period property that describes reference
clock period when it deviates from the default set value.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
index 41416fbd92aa..c8027d2852cd 100644
--- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
@@ -252,6 +252,15 @@ properties:
     minimum: 0
     maximum: 0x3f
 
+  snps,ref-clock-period:
+    description:
+      Value for REFCLKPER field of GUCTL register for post-silicon reference
+      clock period in nanoseconds, when the hardware set default does not match
+      the actual clock.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 0x3ff
+
   snps,rx-thr-num-pkt-prd:
     description:
       Periodic ESS RX packet threshold count (host mode only). Set this and
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:10 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:10 +0300
Subject: [PATCH v2 6/6] arm64: qcom: ipq6018: add usb3 DT description
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <436c458546b2a783af36a190ed72ebc5c74de44e.1628085910.git.baruch@tkos.co.il>

From: Kathiravan T <kathirav at codeaurora.org>

Based on downstream codeaurora code.

Tested (USB2 only) on IPQ6010 based hardware.

Signed-off-by: Kathiravan T <kathirav at codeaurora.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 83 +++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 9fa5b028e4f3..ab701da582e5 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -524,6 +524,89 @@ qrtr_requests {
 			};
 		};
 
+		ssphy_0: ssphy at 78000 {
+			compatible = "qcom,ipq6018-qmp-usb3-phy";
+			reg = <0x0 0x78000 0x0 0x1C4>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			#clock-cells = <1>;
+			ranges;
+
+			clocks = <&gcc GCC_USB0_AUX_CLK>,
+				 <&gcc GCC_USB0_PHY_CFG_AHB_CLK>, <&xo>;
+			clock-names = "aux", "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_USB0_PHY_BCR>,
+				 <&gcc GCC_USB3PHY_0_PHY_BCR>;
+			reset-names = "phy","common";
+			status = "disabled";
+
+			usb0_ssphy: lane at 78200 {
+				reg = <0x0 0x00078200 0x0 0x130>, /* Tx */
+				      <0x0 0x00078400 0x0 0x200>, /* Rx */
+				      <0x0 0x00078800 0x0 0x1F8>, /* PCS */
+				      <0x0 0x00078600 0x0 0x044>; /* PCS misc */
+				#phy-cells = <0>;
+				clocks = <&gcc GCC_USB0_PIPE_CLK>;
+				clock-names = "pipe0";
+				clock-output-names = "gcc_usb0_pipe_clk_src";
+			};
+		};
+
+		qusb_phy_0: qusb at 79000 {
+			compatible = "qcom,ipq6018-qusb2-phy";
+			reg = <0x0 0x079000 0x0 0x180>;
+			#phy-cells = <0>;
+
+			clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>,
+				<&xo>;
+			clock-names = "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+			status = "disabled";
+		};
+
+		usb3: usb3 at 8A00000 {
+			compatible = "qcom,ipq6018-dwc3", "qcom,dwc3";
+			reg = <0x0 0x8AF8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			clocks = <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
+				<&gcc GCC_USB0_MASTER_CLK>,
+				<&gcc GCC_USB0_SLEEP_CLK>,
+				<&gcc GCC_USB0_MOCK_UTMI_CLK>;
+			clock-names = "sys_noc_axi",
+				"master",
+				"sleep",
+				"mock_utmi";
+
+			assigned-clocks = <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
+					  <&gcc GCC_USB0_MASTER_CLK>,
+					  <&gcc GCC_USB0_MOCK_UTMI_CLK>;
+			assigned-clock-rates = <133330000>,
+					       <133330000>,
+					       <20000000>;
+
+			resets = <&gcc GCC_USB0_BCR>;
+			status = "disabled";
+
+			dwc_0: dwc3 at 8A00000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x8A00000 0x0 0xcd00>;
+				interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&qusb_phy_0>, <&usb0_ssphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				tx-fifo-resize;
+				snps,is-utmi-l1-suspend;
+				snps,hird-threshold = /bits/ 8 <0x0>;
+				snps,dis_u2_susphy_quirk;
+				snps,dis_u3_susphy_quirk;
+				snps,ref-clock-period = <0x32>;
+				dr_mode = "host";
+			};
+		};
 	};
 
 	wcss: wcss-smp2p {
-- 
2.30.2



From balbi at kernel.org  Wed Aug  4 07:11:58 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Wed, 04 Aug 2021 17:11:58 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
Message-ID: <87lf5h5mc2.fsf@kernel.org>


Hi,

Baruch Siach <baruch at tkos.co.il> writes:
> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>  				    &dwc->hsphy_interface);
>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>  				 &dwc->fladj);
> +	device_property_read_u32(dev, "snps,ref-clock-period",
> +				 &dwc->ref_clk_per);

I wonder if it would make more sense to pass an actual clock reference
here. If valid, then reconfigure the period to the value returned by
clk_get_rate(). It would avoid yet another DT binding. If we make the
clock optional, then we won't affect any other platforms. The clock
itself could be a regular fixed clock node.

-- 
balbi


From baruch at tkos.co.il  Wed Aug  4 07:22:27 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 04 Aug 2021 17:22:27 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87lf5h5mc2.fsf@kernel.org>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org>
Message-ID: <87v94lxpb0.fsf@tarshish>

Hi Felipe,

On Wed, Aug 04 2021, Felipe Balbi wrote:
> Baruch Siach <baruch at tkos.co.il> writes:
>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>  				    &dwc->hsphy_interface);
>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>  				 &dwc->fladj);
>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>> +				 &dwc->ref_clk_per);
>
> I wonder if it would make more sense to pass an actual clock reference
> here. If valid, then reconfigure the period to the value returned by
> clk_get_rate(). It would avoid yet another DT binding. If we make the
> clock optional, then we won't affect any other platforms. The clock
> itself could be a regular fixed clock node.

Thinh Nguyen asked to add a dedicated DT property. He explained that
clk_get_rate() does not work for PCI hosted dwc3. This is the most
complete summary of the discussion:

  https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32 at synopsys.com

baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From robh at kernel.org  Wed Aug  4 07:24:12 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 4 Aug 2021 08:24:12 -0600
Subject: [PATCH v4 4/4] dt-bindings: phy: Add bindings for HiKey 970 PCIe
 PHY
In-Reply-To: <461495431dd28ad2779658659f137db4bd747aa8.1628061310.git.mchehab+huawei@kernel.org>
References: <cover.1628061310.git.mchehab+huawei@kernel.org>
 <461495431dd28ad2779658659f137db4bd747aa8.1628061310.git.mchehab+huawei@kernel.org>
Message-ID: <YQqjDICecHumVay2@robh.at.kernel.org>

On Wed, 04 Aug 2021 09:18:57 +0200, Mauro Carvalho Chehab wrote:
> Document the bindings for HiKey 970 (hi3670) PCIe PHY
> interface, supported via the pcie-kirin driver.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> ---
>  .../phy/hisilicon,phy-hi3670-pcie.yaml        | 82 +++++++++++++++++++
>  1 file changed, 82 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,phy-hi3670-pcie.yaml
> 

Applied, thanks!


From balbi at kernel.org  Wed Aug  4 07:30:42 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Wed, 04 Aug 2021 17:30:42 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87v94lxpb0.fsf@tarshish>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
Message-ID: <87im0l5lj1.fsf@kernel.org>


Hi,

Baruch Siach <baruch at tkos.co.il> writes:
> Hi Felipe,
>
> On Wed, Aug 04 2021, Felipe Balbi wrote:
>> Baruch Siach <baruch at tkos.co.il> writes:
>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>>  				    &dwc->hsphy_interface);
>>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>>  				 &dwc->fladj);
>>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>>> +				 &dwc->ref_clk_per);
>>
>> I wonder if it would make more sense to pass an actual clock reference
>> here. If valid, then reconfigure the period to the value returned by
>> clk_get_rate(). It would avoid yet another DT binding. If we make the
>> clock optional, then we won't affect any other platforms. The clock
>> itself could be a regular fixed clock node.
>
> Thinh Nguyen asked to add a dedicated DT property. He explained that
> clk_get_rate() does not work for PCI hosted dwc3. This is the most
> complete summary of the discussion:

Hence the "optional" :-)

Or, perhaps, Thinh wants to use this for internal FPGA-based validation?

In that case, I'm okay with the property.

-- 
balbi


From mchehab+huawei at kernel.org  Wed Aug  4 09:02:56 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed,  4 Aug 2021 18:02:56 +0200
Subject: [PATCH v9 00/11] Add support for Hikey 970 PCIe
Message-ID: <cover.1628092716.git.mchehab+huawei@kernel.org>

The DT schema used by this series got merged at:

	https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=dt/next

The series should apply cleanly on the top of v5.14-rc1.

patch1 contains a PHY for Kirin 970 PCIe.

The remaining patches add support for Kirin 970 at the pcie-kirin driver, and
add the needed logic to compile it as module and to allow to dynamically
remove the driver in runtime.

Tested on HiKey970:

  # lspci -D -PP
  0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3670 (rev 01)
  0000:00:00.0/01:00.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:01.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:04.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:05.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:07.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:09.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:01.0/03:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a809
  0000:00:00.0/01:00.0/02:07.0/06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 07)

Tested on HiKey960:

  # lspci -D 
  0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3660 (rev 01)

---

v9:
  - Did some cleanups at patches 1 and 5

Mauro Carvalho Chehab (11):
  phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
  PCI: kirin: Reorganize the PHY logic inside the driver
  PCI: kirin: Add support for a PHY layer
  PCI: kirin: Use regmap for APB registers
  PCI: kirin: Add support for bridge slot DT schema
  PCI: kirin: Add Kirin 970 compatible
  PCI: kirin: Add MODULE_* macros
  PCI: kirin: Allow building it as a module
  PCI: kirin: Add power_off support for Kirin 960 PHY
  PCI: kirin: fix poweroff sequence
  PCI: kirin: Allow removing the driver

 drivers/pci/controller/dwc/Kconfig      |   2 +-
 drivers/pci/controller/dwc/pcie-kirin.c | 646 ++++++++++++++-----
 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 801 ++++++++++++++++++++++++
 5 files changed, 1312 insertions(+), 148 deletions(-)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

-- 
2.31.1




From mchehab+huawei at kernel.org  Wed Aug  4 09:02:57 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed,  4 Aug 2021 18:02:57 +0200
Subject: [PATCH v9 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
In-Reply-To: <cover.1628092716.git.mchehab+huawei@kernel.org>
References: <cover.1628092716.git.mchehab+huawei@kernel.org>
Message-ID: <90aada2f51b58c162e199faf823ba887e50f1dc6.1628092716.git.mchehab+huawei@kernel.org>

The Kirin 970 PHY is somewhat similar to the Kirin 960, but it
does a lot more. Add the needed bits for PCIe to start working on
HiKey 970 boards.

Co-developed-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 801 ++++++++++++++++++++++++
 3 files changed, 812 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 4d008cfc279c..d3b92c288554 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -33,6 +33,16 @@ config PHY_HI3670_USB
 
 	  To compile this driver as a module, choose M here.
 
+config PHY_HI3670_PCIE
+	tristate "hi3670 PCIe PHY support"
+	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+	select GENERIC_PHY
+	select MFD_SYSCON
+	help
+	  Enable this to support the HiSilicon hi3670 PCIe PHY.
+
+	  To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
 	tristate "HiSilicon STB SoCs COMBPHY support"
 	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 51729868145b..4029d3813b1e 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_HI6220_USB)		+= phy-hi6220-usb.o
 obj-$(CONFIG_PHY_HI3660_USB)		+= phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HI3670_USB)		+= phy-hi3670-usb3.o
+obj-$(CONFIG_PHY_HI3670_PCIE)		+= phy-hi3670-pcie.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)		+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)	+= phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
new file mode 100644
index 000000000000..d578b4ed1500
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -0,0 +1,801 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe phy driver for Kirin 970
+ *
+ * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
+ *		https://www.huawei.com
+ * Copyright (C) 2021 Huawei Technologies Co., Ltd.
+ *		https://www.huawei.com
+ *
+ * Authors:
+ *	Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+ *	Manivannan Sadhasivam <mani at kernel.org>
+ *
+ * Based on:
+ * 	https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei at kernel.org/
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AXI_CLK_FREQ			207500000
+#define REF_CLK_FREQ			100000000
+
+/* PCIe CTRL registers */
+#define SOC_PCIECTRL_CTRL0_ADDR   0x000
+#define SOC_PCIECTRL_CTRL1_ADDR   0x004
+#define SOC_PCIECTRL_CTRL7_ADDR   0x01c
+#define SOC_PCIECTRL_CTRL12_ADDR  0x030
+#define SOC_PCIECTRL_CTRL20_ADDR  0x050
+#define SOC_PCIECTRL_CTRL21_ADDR  0x054
+#define SOC_PCIECTRL_STATE0_ADDR  0x400
+
+/* PCIe PHY registers */
+#define SOC_PCIEPHY_CTRL0_ADDR    0x000
+#define SOC_PCIEPHY_CTRL1_ADDR    0x004
+#define SOC_PCIEPHY_CTRL2_ADDR    0x008
+#define SOC_PCIEPHY_CTRL3_ADDR    0x00c
+#define SOC_PCIEPHY_CTRL38_ADDR   0x0098
+#define SOC_PCIEPHY_STATE0_ADDR   0x400
+
+#define PCIE_LINKUP_ENABLE            (0x8020)
+#define PCIE_ELBI_SLV_DBI_ENABLE      (0x1 << 21)
+#define PCIE_LTSSM_ENABLE_BIT         (0x1 << 11)
+#define PCIEPHY_RESET_BIT             (0x1 << 17)
+#define PCIEPHY_PIPE_LINE0_RESET_BIT  (0x1 << 19)
+
+#define PORT_MSI_CTRL_ADDR            0x820
+#define PORT_MSI_CTRL_UPPER_ADDR      0x824
+#define PORT_MSI_CTRL_INT0_ENABLE     0x828
+
+#define EYEPARAM_NOCFG 0xFFFFFFFF
+#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1 0x3001
+#define SUP_DIG_LVL_OVRD_IN 0xf
+#define LANEN_DIG_ASIC_TX_OVRD_IN_1 0x1002
+#define LANEN_DIG_ASIC_TX_OVRD_IN_2 0x1003
+
+/* hi3670 pciephy register */
+#define SOC_PCIEPHY_MMC1PLL_CTRL1  0xc04
+#define SOC_PCIEPHY_MMC1PLL_CTRL16 0xC40
+#define SOC_PCIEPHY_MMC1PLL_CTRL17 0xC44
+#define SOC_PCIEPHY_MMC1PLL_CTRL20 0xC50
+#define SOC_PCIEPHY_MMC1PLL_CTRL21 0xC54
+#define SOC_PCIEPHY_MMC1PLL_STAT0  0xE00
+
+#define CRGPERIPH_PEREN12   0x470
+#define CRGPERIPH_PERDIS12  0x474
+#define CRGPERIPH_PCIECTRL0 0x800
+
+/* define ie,oe cfg */
+#define IO_IE_EN_HARD_BYPASS         (0x1 << 27)
+#define IO_OE_EN_HARD_BYPASS         (0x1 << 11)
+#define IO_HARD_CTRL_DEBOUNCE_BYPASS (0x1 << 10)
+#define IO_OE_GT_MODE                (0x2 << 7)
+#define DEBOUNCE_WAITCFG_IN          (0xf << 20)
+#define DEBOUNCE_WAITCFG_OUT         (0xf << 13)
+
+/* noc power domain */
+#define NOC_POWER_IDLEREQ_1 0x38c
+#define NOC_POWER_IDLE_1    0x394
+#define NOC_PW_MASK         0x10000
+#define NOC_PW_SET_BIT      0x1
+
+#define NUM_EYEPARAM		5
+
+/* info located in sysctrl */
+#define SCTRL_PCIE_CMOS_OFFSET	0x60
+#define SCTRL_PCIE_CMOS_BIT	0x10
+#define SCTRL_PCIE_ISO_OFFSET	0x44
+#define SCTRL_PCIE_ISO_BIT	0x30
+#define SCTRL_PCIE_HPCLK_OFFSET	0x190
+#define SCTRL_PCIE_HPCLK_BIT	0x184000
+#define SCTRL_PCIE_OE_OFFSET	0x14a
+#define PCIE_DEBOUNCE_PARAM	0xF0F400
+#define PCIE_OE_BYPASS		(0x3 << 28)
+
+/* peri_crg ctrl */
+#define CRGCTRL_PCIE_ASSERT_OFFSET	0x88
+#define CRGCTRL_PCIE_ASSERT_BIT		0x8c000000
+
+/* Time for delay */
+#define PIPE_CLK_WAIT_MIN	550
+#define PIPE_CLK_WAIT_MAX	600
+#define TIME_CMOS_MIN		100
+#define TIME_CMOS_MAX		105
+#define TIME_PHY_PD_MIN		10
+#define TIME_PHY_PD_MAX		11
+
+struct hi3670_pcie_phy {
+	struct device	*dev;
+	void __iomem	*base;
+	struct regmap	*apb;
+	struct regmap	*crgctrl;
+	struct regmap	*sysctrl;
+	struct regmap	*pmctrl;
+	struct clk	*apb_sys_clk;
+	struct clk	*apb_phy_clk;
+	struct clk	*phy_ref_clk;
+	struct clk	*aclk;
+	struct clk	*aux_clk;
+	u32		eye_param[NUM_EYEPARAM];
+};
+
+
+/* Registers in PCIePHY */
+static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy,
+					 u32 val, u32 reg)
+{
+	writel(val, phy->base + 0x40000 + reg);
+}
+
+static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
+{
+	return readl(phy->base + 0x40000 + reg);
+}
+
+static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
+						u32 val, u32 reg)
+{
+	writel(val, phy->base + reg * 4);
+}
+
+static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
+					      u32 reg)
+{
+	return readl(phy->base + reg * 4);
+}
+
+static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
+{
+	u32 val;
+
+	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
+	val |= PCIE_DEBOUNCE_PARAM;
+	if (enable)
+		val &= ~PCIE_OE_BYPASS;
+	else
+		val |= PCIE_OE_BYPASS;
+	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
+}
+
+static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np;
+	int ret, i;
+
+	np = dev->of_node;
+
+	ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
+					 phy->eye_param, NUM_EYEPARAM);
+	if (!ret)
+		return;
+
+	/* There's no optional eye_param property. Set array to default */
+	for (i = 0; i < NUM_EYEPARAM; i++)
+		phy->eye_param[i] = EYEPARAM_NOCFG;
+}
+
+static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = kirin_apb_natural_phy_readl(phy, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
+		val &= (~0xf00);
+		val |= (phy->eye_param[1] << 8) | (0x1 << 12);
+	}
+	kirin_apb_natural_phy_writel(phy, val, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+	val &= (~0x1FBF);
+	if (phy->eye_param[2] != EYEPARAM_NOCFG)
+		val |= (phy->eye_param[2]<< 0) | (0x1 << 6);
+
+	if (phy->eye_param[3] != EYEPARAM_NOCFG)
+		val |= (phy->eye_param[3] << 7) | (0x1 << 13);
+
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+
+	val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
+	if (phy->eye_param[0] != EYEPARAM_NOCFG) {
+		val &= (~0x1C0);
+		val |= (phy->eye_param[0] << 6) | (0x1 << 9);
+	}
+	kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+	if (phy->eye_param[4] != EYEPARAM_NOCFG) {
+		val &= (~0x7E00);
+		val |= (phy->eye_param[4] << 9) | (0x1 << 15);
+	}
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+}
+
+static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* change 2p mem_ctrl */
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR, 0x02605550);
+
+	/* pull up sys_aux_pwr_det */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
+	val |= (0x1 << 10);
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
+
+	/* output, pull down */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val &= ~(0x3 << 2);
+	val |= (0x1 << 1);
+	val &= ~(0x1 << 0);
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+
+	/* Handle phy_reset and lane0_reset to HW */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
+	val |= PCIEPHY_RESET_BIT;
+	val &= ~PCIEPHY_PIPE_LINE0_RESET_BIT;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
+
+	/* fix chip bug: TxDetectRx fail */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL38_ADDR);
+	val |= (0x1 << 2);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL38_ADDR);
+}
+
+static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* choose FNPLL */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL1);
+	val |= (0x1 << 27);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL1);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+	val &= 0xF000FFFF;
+	/* fnpll fbdiv = 0xD0 */
+	val |= (0xd0 << 16);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL17);
+	val &= 0xFF000000;
+	/* fnpll fracdiv = 0x555555 */
+	val |= (0x555555 << 0);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL17);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+	val &= 0xF5FF88FF;
+	/* fnpll dll_en = 0x1 */
+	val |= (0x1 << 27);
+	/* fnpll postdiv1 = 0x5 */
+	val |= (0x5 << 8);
+	/* fnpll postdiv2 = 0x4 */
+	val |= (0x4 << 12);
+	/* fnpll pll_mode = 0x0 */
+	val &= ~(0x1 << 25);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	hi3670_apb_phy_writel(phy, 0x20, SOC_PCIEPHY_MMC1PLL_CTRL21);
+}
+
+static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int time = 200;
+
+	if (enable) {
+		/* pd = 0 */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+		val &= ~(0x1 << 0);
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+
+		/* choose FNPLL */
+		while (!(val & 0x10)) {
+			if (!time) {
+				dev_err(dev, "wait for pll_lock timeout\n");
+				return -1;
+			}
+			time --;
+			udelay(1);
+			val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+		}
+
+		/* pciepll_bp = 0 */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+		val &= ~(0x1 << 16);
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	} else {
+		/* pd = 1 */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+		val |= (0x1 << 0);
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		/* pciepll_bp = 1 */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+		val |= (0x1 << 16);
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+	}
+
+	 return 0;
+}
+
+static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	if (open)
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
+		regmap_write(phy->crgctrl, CRGPERIPH_PEREN12, 0x9000);
+	else
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, 0x9000);
+}
+
+static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	if (open)
+		val &= ~(0x1 << 1); //enable hard gt mode
+	else
+		val |= (0x1 << 1); //disable hard gt mode
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+	/* disable soft gt mode */
+	regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, 0x4000);
+}
+
+static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl , CRGPERIPH_PCIECTRL0, &val);
+
+	/* set ie cfg */
+	val |= IO_IE_EN_HARD_BYPASS;
+
+	/* set oe cfg */
+	val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
+
+	/* set phy_debounce in&out time */
+	val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
+
+	/* select oe_gt_mode */
+	val |= IO_OE_GT_MODE;
+
+	if (en_flag)
+		val &= ~IO_OE_EN_HARD_BYPASS;
+	else
+		val |= IO_OE_EN_HARD_BYPASS;
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+}
+
+static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	if (open) {
+		regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR, 0x20000070);
+
+		hi3670_pcie_oe_ctrl(phy, true);
+
+		/* en hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val &= ~(0x1 << 0);
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, 0x2000);
+
+	} else {
+		/* disable hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val |= (0x1 << 0);
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, 0x2000);
+
+		hi3670_pcie_oe_ctrl(phy, false);
+       }
+}
+
+static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int ret = 0;
+
+	if (!clk_on)
+		goto close_clocks;
+
+	/* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
+	val &= ~(0x1 << 8);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
+
+	hi3670_pcie_pll_init(phy);
+
+	ret = hi3670_pcie_pll_ctrl(phy, true);
+	if (ret) {
+		dev_err(dev, "Failed to enable pll\n");
+		return -1;
+	}
+	hi3670_pcie_hp_debounce_gt(phy, true);
+	hi3670_pcie_phyref_gt(phy, true);
+	hi3670_pcie_ioref_gt(phy, true);
+
+	ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
+	if (ret) {
+		dev_err(dev, "Failed to set rate\n");
+		goto close_clocks;
+	}
+
+	return 0;
+
+close_clocks:
+	hi3670_pcie_ioref_gt(phy, false);
+	hi3670_pcie_phyref_gt(phy, false);
+	hi3670_pcie_hp_debounce_gt(phy, false);
+
+	hi3670_pcie_pll_ctrl(phy, false);
+
+	return ret;
+}
+
+static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	u32 time = 100;
+	u32 pipe_clk_stable = 0x1 << 19;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	while (val & pipe_clk_stable) {
+		mdelay(1);
+		if (time == 0) {
+			dev_err(dev, "PIPE clk is not stable\n");
+			return false;
+		}
+		time--;
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	}
+
+	return true;
+}
+
+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 time = 100;
+	unsigned int val = NOC_PW_MASK;
+	int rst;
+
+	if (enable)
+		val = NOC_PW_MASK | NOC_PW_SET_BIT;
+	else
+		val = NOC_PW_MASK;
+	rst = enable ? 1 : 0;
+
+	regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
+
+	time = 100;
+	regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	while((val & NOC_PW_SET_BIT) != rst) {
+		udelay(10);
+		if (!time) {
+			dev_err(dev, "Failed to reverse noc power-status\n");
+			return -1;
+		}
+		time--;
+		regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	}
+
+	return 0;
+}
+
+static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
+{
+	struct device_node *pcie_port;
+	struct device *dev = phy->dev;
+	struct device *pcie_dev;
+
+	pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
+	if (!pcie_port) {
+		dev_err(dev, "no pcie node found in %s\n",
+			dev->parent->of_node->full_name);
+		return -ENODEV;
+	}
+
+	pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
+	if (!pcie_dev) {
+                dev_err(dev, "Didn't find pcie device\n");
+                return -ENODEV;
+        }
+
+        /*
+	 * We might just use NULL instead of the APB name, as the
+	 * pcie-kirin currently registers directly just one regmap (although
+	 * the DWC driver register other regmaps).
+	 *
+	 * Yet, it sounds safer to warrant that it will be accessing the
+	 * right regmap. So, let's use the named version.
+	 */
+	phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
+	if (!phy->apb) {
+		dev_err(dev, "Failed to get APB regmap\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto close_clk;
+
+	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->phy_ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->apb_sys_clk);
+	if (ret)
+		goto apb_sys_fail;
+
+	ret = clk_prepare_enable(phy->apb_phy_clk);
+	if (ret)
+		goto apb_phy_fail;
+
+	ret = clk_prepare_enable(phy->aclk);
+	if (ret)
+		goto aclk_fail;
+
+	ret = clk_prepare_enable(phy->aux_clk);
+	if (ret)
+		goto aux_clk_fail;
+
+	return 0;
+
+close_clk:
+	clk_disable_unprepare(phy->aux_clk);
+aux_clk_fail:
+	clk_disable_unprepare(phy->aclk);
+aclk_fail:
+	clk_disable_unprepare(phy->apb_phy_clk);
+apb_phy_fail:
+	clk_disable_unprepare(phy->apb_sys_clk);
+apb_sys_fail:
+	clk_disable_unprepare(phy->phy_ref_clk);
+
+	return ret;
+}
+
+static int hi3670_pcie_phy_init(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int ret;
+
+	/*
+	 * The code under hi3670_pcie_get_resources_from_pcie() need to
+	 * access the reset-gpios and the APB registers, both from the
+	 * pcie-kirin driver.
+	 *
+	 * The APB is obtained via the pcie driver's regmap
+	 * Such kind of resource can only be obtained during the PCIe
+	 * power_on sequence, as the code inside pcie-kirin needs to
+	 * be already probed, as it needs to register the APB regmap.
+	 */
+
+	ret = hi3670_pcie_get_resources_from_pcie(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int val, ret;
+
+	/* Power supply for Host */
+	regmap_write(phy->sysctrl,
+		     SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
+	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
+
+	hi3670_pcie_phy_oe_enable(phy, true);
+
+	ret = kirin_pcie_clk_ctrl(phy, true);
+	if (ret)
+		return ret;
+
+	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
+	regmap_write(phy->sysctrl,
+		     SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
+	regmap_write(phy->crgctrl,
+		     CRGCTRL_PCIE_ASSERT_OFFSET, CRGCTRL_PCIE_ASSERT_BIT);
+	regmap_write(phy->sysctrl,
+		     SCTRL_PCIE_HPCLK_OFFSET, SCTRL_PCIE_HPCLK_BIT);
+
+	hi3670_pcie_natural_cfg(phy);
+
+	ret = hi3670_pcie_allclk_ctrl(phy, true);
+	if (ret)
+		goto disable_clks;
+
+	/* pull down phy_test_powerdown signal */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL0_ADDR);
+	val &= ~(0x1 << 22);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL0_ADDR);
+
+	/* deassert controller perst_n */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val |= (0x1 << 2);
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+	udelay(10);
+
+	ret = is_pipe_clk_stable(phy);
+	if (!ret)
+		goto disable_clks;
+
+	hi3670_pcie_set_eyeparam(phy);
+
+	ret = hi3670_pcie_noc_power(phy, false);
+	if (ret)
+		goto disable_clks;
+
+	return 0;
+
+disable_clks:
+	kirin_pcie_clk_ctrl(phy, false);
+	return ret;
+}
+
+static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+
+	hi3670_pcie_phy_oe_enable(phy, false);
+
+	hi3670_pcie_allclk_ctrl(phy, false);
+
+	/* Drop power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0x00);
+
+	/* FIXME: calling it causes an Asynchronous SError interrupt */
+//	kirin_pcie_clk_ctrl(phy, false);
+
+	return 0;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+	.init		= hi3670_pcie_phy_init,
+	.power_on	= hi3670_pcie_phy_power_on,
+	.power_off	= hi3670_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
+					 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* syscon */
+	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
+	if (IS_ERR(phy->crgctrl))
+		return PTR_ERR(phy->crgctrl);
+
+	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	/* clocks */
+	phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
+	if (IS_ERR(phy->phy_ref_clk))
+		return PTR_ERR(phy->phy_ref_clk);
+
+	phy->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(phy->aux_clk))
+		return PTR_ERR(phy->aux_clk);
+
+	phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
+	if (IS_ERR(phy->apb_phy_clk))
+		return PTR_ERR(phy->apb_phy_clk);
+
+	phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
+	if (IS_ERR(phy->apb_sys_clk))
+		return PTR_ERR(phy->apb_sys_clk);
+
+	phy->aclk = devm_clk_get(dev, "aclk");
+	if (IS_ERR(phy->aclk))
+		return PTR_ERR(phy->aclk);
+
+	/* registers */
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	hi3670_pcie_get_eyeparam(phy);
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct hi3670_pcie_phy *phy;
+	struct phy *generic_phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+
+	ret = hi3670_pcie_phy_get_resources(phy, pdev);
+	if (ret)
+		return ret;
+
+	generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_pcie_phy_match[] = {
+	{
+		.compatible = "hisilicon,hi970-pcie-phy",
+	},
+	{},
+};
+
+static struct platform_driver hi3670_pcie_phy_driver = {
+	.probe	= hi3670_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= hi3670_pcie_phy_match,
+		.name		= "hi3670_pcie_phy",
+		.suppress_bind_attrs = true,
+	}
+};
+builtin_platform_driver(hi3670_pcie_phy_driver);
+
+MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
+MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab at kernel.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <mani at kernel.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1



From robh at kernel.org  Wed Aug  4 09:28:53 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 4 Aug 2021 10:28:53 -0600
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <20210804085045.3dddbb9c@coco.lan>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
Message-ID: <YQrARd7wgYS1nywt@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:
> Em Tue, 3 Aug 2021 16:11:42 -0600
> Rob Herring <robh+dt at kernel.org> escreveu:
> 
> > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > <mchehab+huawei at kernel.org> wrote:
> > >
> > > Hi Rob,
> > >
> > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > corresponding PHY.
> > >
> > > It is identical to v2, except by:
> > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > >         +          pcie at 7,0 { // Lane 6: Ethernet  
> > 
> > Can you check whether you have DT node links in sysfs for the PCI
> > devices? If you don't, then something is wrong still in the topology
> > or the PCI core is failing to set the DT node pointer in struct
> > device. Though you don't rely on that currently, we want the topology
> > to match. It's possible this never worked on arm/arm64 as mainly
> > powerpc relied on this.
> >
> > I'd like some way to validate the DT matches the PCI topology. We
> > could have a tool that generates the DT structure based on the PCI
> > topology.
> 
> The of_node node link is on those places:
> 
> 	$ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> 	/sys/devices/platform/soc/f4000000.pcie/of_node
> 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node

Looks like we're missing some... 

It's not immediately obvious to me what's wrong here. Only the root 
bus is getting it's DT node set. The relevant code is pci_scan_device(), 
pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try 
to reproduce and debug it.

In the mean time, I applied the series but haven't pushed it out.

Rob


From martin.blumenstingl at googlemail.com  Wed Aug  4 14:58:23 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Wed, 4 Aug 2021 23:58:23 +0200
Subject: [PATCHv2 1/4] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
References: <20210716103651.1455-1-linux.amoon@gmail.com>
 <20210716103651.1455-2-linux.amoon@gmail.com>
 <CAFBinCDeqauw_V-Vn9cat9HaCXj6HEMz6G+G+VbqCNtGEFGYzg@mail.gmail.com>
 <CANAwSgQ5PDGUWMH-jxnz5wwutUVniTn7RAe=4J=8-jbmqxYRRg@mail.gmail.com>
 <CAFBinCBhg+dije+3DvV_V_kqHv9q+r4EPxXCYFti6KuA4mK7KQ@mail.gmail.com>
 <CANAwSgT9-5zGr67aGzBmW6WDBfeiAvjv_zv2UbRC+YbgAGg==A@mail.gmail.com>
 <CAFBinCCGA0b=LVjbQood+iN+DHLodY0RJ-GrSOcgdzrDFJ25pQ@mail.gmail.com>
 <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
Message-ID: <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>

On Sun, Jul 18, 2021 at 9:09 PM Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
>
> Hi Anand,
>
> On Sun, Jul 18, 2021 at 4:01 PM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> [...]
> > > From the schematics [1]
> > > https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20160226.pdf
> > >
> > > You could find references to PWREN  <--- GPIOAO.BIT5
> > > The second reference is USB HOST Power Switch
> > > The third reference is USB HOST POWER.
> > >
> > > Hope I am clean in my thought process now.
> > Can you please point out the page numbers for me?
> >
> > What I am seeing on page 1 is:
> > GPIOAO_5 (called GPIOAO.BIT5) is connected as an INPUT to the USB_OTG
> > PWREN signal (that's the green box with the label "USB_OTG.SchDoc"
> > above it).
> I unfortunately missed your question on IRC on this topic:
> <armoon> xdarklight: just want to understand the confusion on PWREN,
> either is INPUT / OTPUT to usb hub am I correct
> My understanding of the INPUT/OUTPUT direction in the Odroid-C1
> schematics (which you linked) above is that the arrow direction shows
> whether it's an input or output.
> For example (all on page one):
> - HDMI_HPD is an input to the Meson8b SoC, arrow direction is: HDMI => S805
> - IR_IN is an input to the Meson8b SoC, arrow direction is: S805 <=
> GPIOAO.BIT7 IR_IN
> - PWM is an output, arrow direction is: S805 => PWM.C VCCK_PWM
> - 3.3V/1.8V switch for the SD card is an output, arrow direction is:
> S805 => GPIOAO.BIT3 TF_3V3N_1V8_EN
>
> That tells me: the arrow direction shows which connections are inputs
> or outputs.
> Some pins can be input and output at the same time (HDMI_CEC). But
> let's keep it simple for now any only look at inputs/output.
>
> Based on this information I am looking at the arrow direction for
> USB_OTG: GPIOAO.BIT5 PWREN <= S805
> So this confirms that GPIOAO_5 is an output to the SoC.
> Please note though that this part is not linked with any USB host
> connector, it's only linked to the USB OTG path.
>
> For the next part the S805 SoC is not involved:
> USB1 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> USB2 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> This tells me that the PWREN signal for the two USB_HOST_PWR_SW (USB
> host power switches / current limiters) is driven by the GL852G USB
> hub.
Hardkernel team responded on the Odroid forums to the request from Anand:
"Power-Enable signal to the USB load switch ICs is connected to the
USB hub controller.
It is not connected the CPU GPIO."

The regulator from Anand's patch is therefore connected to the micro USB port.
This means that the patch needs updating in case Anand wants to have
it included.


Best regards,
Martin


[0] https://forum.odroid.com/viewtopic.php?p=332217#p332217


From baruch at tkos.co.il  Wed Aug  4 23:58:57 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 05 Aug 2021 09:58:57 +0300
Subject: [PATCH v2 0/6] arm64: IPQ6018 PCIe support
In-Reply-To: <cover.1620203062.git.baruch@tkos.co.il>
References: <cover.1620203062.git.baruch@tkos.co.il>
Message-ID: <87o8acxtqm.fsf@tarshish>

Hi Lorenzo, Rob, Krzysztof,

On Wed, May 05 2021, Baruch Siach wrote:
> This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
> ported from downstream Codeaurora v5.4 kernel. The main difference from 
> downstream code is the split of PCIe registers configuration from .init to 
> .post_init, since it requires phy_power_on().
>
> Tested on IPQ6010 based hardware.

It's been 3 months with no comment. Would you consider applying the dwc
part (patches #1 and #2) for the v5.15 merge window?

I tested the patches here successfully on top of v5.14-rc4.

Thanks,
baruch

>
> Changes in v2:
>
>   * Add patch moving GEN3_RELATED macros to a common header
>
>   * Drop ATU configuration from pcie-qcom
>
>   * Remove local definition of common registers
>
>   * Use bulk clk and reset APIs
>
>   * Remove msi-parent from device-tree
>
> Baruch Siach (3):
>   PCI: dwc: tegra: move GEN3_RELATED DBI register to common header
>   dt-bindings: phy: qcom,qmp: Add IPQ60xx PCIe PHY bindings
>   dt-bindings: pci: qcom: Document PCIe bindings for IPQ6018 SoC
>
> Selvam Sathappan Periakaruppan (3):
>   PCI: qcom: add support for IPQ60xx PCIe controller
>   phy: qcom-qmp: add QMP V2 PCIe PHY support for ipq60xx
>   arm64: dts: ipq6018: Add pcie support
>
>  .../devicetree/bindings/pci/qcom,pcie.txt     |  24 +++
>  .../devicetree/bindings/phy/qcom,qmp-phy.yaml |  25 +++
>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  99 ++++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |   7 +
>  drivers/pci/controller/dwc/pcie-qcom.c        | 150 ++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-tegra194.c    |   6 -
>  drivers/phy/qualcomm/phy-qcom-qmp.c           | 147 +++++++++++++++++
>  drivers/phy/qualcomm/phy-qcom-qmp.h           | 132 +++++++++++++++
>  8 files changed, 584 insertions(+), 6 deletions(-)


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From mchehab+huawei at kernel.org  Thu Aug  5 00:46:12 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Thu, 5 Aug 2021 09:46:12 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <YQrARd7wgYS1nywt@robh.at.kernel.org>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
Message-ID: <20210805094612.2bc2c78f@coco.lan>

Em Wed, 4 Aug 2021 10:28:53 -0600
Rob Herring <robh at kernel.org> escreveu:

> On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:
> > Em Tue, 3 Aug 2021 16:11:42 -0600
> > Rob Herring <robh+dt at kernel.org> escreveu:
> >   
> > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > <mchehab+huawei at kernel.org> wrote:  
> > > >
> > > > Hi Rob,
> > > >
> > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > corresponding PHY.
> > > >
> > > > It is identical to v2, except by:
> > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > >         +          pcie at 7,0 { // Lane 6: Ethernet    
> > > 
> > > Can you check whether you have DT node links in sysfs for the PCI
> > > devices? If you don't, then something is wrong still in the topology
> > > or the PCI core is failing to set the DT node pointer in struct
> > > device. Though you don't rely on that currently, we want the topology
> > > to match. It's possible this never worked on arm/arm64 as mainly
> > > powerpc relied on this.
> > >
> > > I'd like some way to validate the DT matches the PCI topology. We
> > > could have a tool that generates the DT structure based on the PCI
> > > topology.  
> > 
> > The of_node node link is on those places:
> > 
> > 	$ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > 	/sys/devices/platform/soc/f4000000.pcie/of_node
> > 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node  
> 
> Looks like we're missing some... 
> 
> It's not immediately obvious to me what's wrong here. Only the root 
> bus is getting it's DT node set. The relevant code is pci_scan_device(), 
> pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try 
> to reproduce and debug it.

I added a printk on both pci_set_*of_node() functions:

	[    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
	[    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
	[    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
	[    5.059263]  (null): pci_set_of_node: of_node: (null)
	[    5.085552]  (null): pci_set_of_node: of_node: (null)
	[    5.112073]  (null): pci_set_of_node: of_node: (null)
	[    5.138320]  (null): pci_set_of_node: of_node: (null)
	[    5.164673]  (null): pci_set_of_node: of_node: (null)
	[    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
	[    5.240539]  (null): pci_set_of_node: of_node: (null)
	[    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
	[    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
	[    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
	[    5.345516]  (null): pci_set_of_node: of_node: (null)
	[    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)

It sounds that the parent is missing when pci_set_bus_of_node() is
called on some places. I'll try to identify why.

Thanks,
Mauro


From mchehab+huawei at kernel.org  Thu Aug  5 00:58:48 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Thu, 5 Aug 2021 09:58:48 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <20210805094612.2bc2c78f@coco.lan>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan>
Message-ID: <20210805095848.464cf85c@coco.lan>

Em Thu, 5 Aug 2021 09:46:12 +0200
Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:

> Em Wed, 4 Aug 2021 10:28:53 -0600
> Rob Herring <robh at kernel.org> escreveu:
> 
> > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:  
> > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > Rob Herring <robh+dt at kernel.org> escreveu:
> > >     
> > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > <mchehab+huawei at kernel.org> wrote:    
> > > > >
> > > > > Hi Rob,
> > > > >
> > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > corresponding PHY.
> > > > >
> > > > > It is identical to v2, except by:
> > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > >         +          pcie at 7,0 { // Lane 6: Ethernet      
> > > > 
> > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > devices? If you don't, then something is wrong still in the topology
> > > > or the PCI core is failing to set the DT node pointer in struct
> > > > device. Though you don't rely on that currently, we want the topology
> > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > powerpc relied on this.
> > > >
> > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > could have a tool that generates the DT structure based on the PCI
> > > > topology.    
> > > 
> > > The of_node node link is on those places:
> > > 
> > > 	$ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > 	/sys/devices/platform/soc/f4000000.pcie/of_node
> > > 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > 	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node    
> > 
> > Looks like we're missing some... 
> > 
> > It's not immediately obvious to me what's wrong here. Only the root 
> > bus is getting it's DT node set. The relevant code is pci_scan_device(), 
> > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try 
> > to reproduce and debug it.  
> 
> I added a printk on both pci_set_*of_node() functions:
> 
> 	[    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> 	[    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> 	[    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> 	[    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> 	[    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> 	[    5.059263]  (null): pci_set_of_node: of_node: (null)
> 	[    5.085552]  (null): pci_set_of_node: of_node: (null)
> 	[    5.112073]  (null): pci_set_of_node: of_node: (null)
> 	[    5.138320]  (null): pci_set_of_node: of_node: (null)
> 	[    5.164673]  (null): pci_set_of_node: of_node: (null)
> 	[    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> 	[    5.240539]  (null): pci_set_of_node: of_node: (null)
> 	[    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> 	[    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> 	[    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> 	[    5.345516]  (null): pci_set_of_node: of_node: (null)
> 	[    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)

The enclosed patch makes the above a clearer:

	[    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
	[    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
	[    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
	[    4.968821] pci 0000:02:01.0: pci_set_of_node: of_node: (null)
	[    5.003538] pci 0000:02:04.0: pci_set_of_node: of_node: (null)
	[    5.041348] pci 0000:02:05.0: pci_set_of_node: of_node: (null)
	[    5.092770] pci 0000:02:07.0: pci_set_of_node: of_node: (null)
	[    5.118298] pci 0000:02:09.0: pci_set_of_node: of_node: (null)
	[    5.178215] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
	[    5.198433] pci 0000:03:00.0: pci_set_of_node: of_node: (null)
	[    5.233330] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
	[    5.247071] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
	[    5.260898] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
	[    5.293764] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
	[    5.332808] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)

> 
> It sounds that the parent is missing when pci_set_bus_of_node() is
> called on some places. I'll try to identify why.
> 
> Thanks,
> Mauro

Thanks,
Mauro

[PATCH] pci: setup PCI before setting the OF node

With this change, it is easier to add a debug printk at
pci_set_of_node() in order to address possible issues.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 79177ac37880..c5dfc1afb1d3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2374,15 +2374,14 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
 	dev->vendor = l & 0xffff;
 	dev->device = (l >> 16) & 0xffff;
 
-	pci_set_of_node(dev);
-
 	if (pci_setup_device(dev)) {
-		pci_release_of_node(dev);
 		pci_bus_put(dev->bus);
 		kfree(dev);
 		return NULL;
 	}
 
+	pci_set_of_node(dev);
+
 	return dev;
 }
 




From iskren.chernev at gmail.com  Thu Aug  5 02:17:25 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Thu,  5 Aug 2021 12:17:25 +0300
Subject: [PATCH v1 0/2] Add UFS PHY support for SM6115/4250
Message-ID: <20210805091727.942471-1-iskren.chernev@gmail.com>

The UFS PHY found on SM6115/4250 is named v3-660, found on cheaper qcom devices
(possibly starting with sdm660), but up until recently wasn't used much due to
prevalence of sdhc port for internal storage/sdcard.

The name is a bit misleading, because most of the registers found on v3-660
don't share much in common with v3.

The register values/sequences are taken from OnePlus repo [1].

[1] https://github.com/OnePlusOSS/android_kernel_oneplus_sm4250

Iskren Chernev (2):
  dt-bindings: phy: qcom,qmp: Add SM6115 UFS PHY bindings
  phy: qcom-qmp: Add support for SM6115 UFS phy

 .../devicetree/bindings/phy/qcom,qmp-phy.yaml |   1 +
 drivers/phy/qualcomm/phy-qcom-qmp.c           | 124 ++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h           | 153 ++++++++++++++++++
 3 files changed, 278 insertions(+)


base-commit: 8d4b477da1a807199ca60e0829357ce7aa6758d5
-- 
2.32.0



From iskren.chernev at gmail.com  Thu Aug  5 02:17:26 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Thu,  5 Aug 2021 12:17:26 +0300
Subject: [PATCH v1 1/2] dt-bindings: phy: qcom,
 qmp: Add SM6115 UFS PHY bindings
In-Reply-To: <20210805091727.942471-1-iskren.chernev@gmail.com>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
Message-ID: <20210805091727.942471-2-iskren.chernev@gmail.com>

Add the compatible strings for the UFS PHY found on SM4250/6115 SoC.

Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
---
 Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index 242560ff52a4..7c3c8710ab47 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -35,6 +35,7 @@ properties:
       - qcom,sdm845-qmp-ufs-phy
       - qcom,sdm845-qmp-usb3-phy
       - qcom,sdm845-qmp-usb3-uni-phy
+      - qcom,sm6115-qmp-ufs-phy
       - qcom,sm8150-qmp-ufs-phy
       - qcom,sm8150-qmp-usb3-phy
       - qcom,sm8150-qmp-usb3-uni-phy
-- 
2.32.0



From iskren.chernev at gmail.com  Thu Aug  5 02:17:27 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Thu,  5 Aug 2021 12:17:27 +0300
Subject: [PATCH v1 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <20210805091727.942471-1-iskren.chernev@gmail.com>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
Message-ID: <20210805091727.942471-3-iskren.chernev@gmail.com>

Add the tables and constants for init sequences for UFS QMP phy found in
SM4250/6115 SoC. The phy is a variation of the v3 phy found on sdm845
called v3-660 (possibly first occurrence in the sdm660).

There are a few similar registers with the v3 phy, but overall they are
different, so I haven't tried reusing the same constants where possible,
as it would make the tables harder to read and maintain.

Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 124 ++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h | 153 ++++++++++++++++++++++++++++
 2 files changed, 277 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2195f8ac393b..2b012bcff622 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -234,6 +234,11 @@ static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_READY_STATUS]		= 0x160,
 };
 
+static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_START_CTRL]		= 0x00,
+	[QPHY_PCS_READY_STATUS]		= 0x168,
+};
+
 static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_SW_RESET]			= 0x00,
 	[QPHY_START_CTRL]		= 0x44,
@@ -1329,6 +1334,97 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
 };
 
+static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CMN_CONFIG, 0x0e),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_SYSCLK_EN_SEL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_SYS_CLK_CTRL, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_HSCLK_SEL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CORECLK_DIV, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CORECLK_DIV_MODE1, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP_EN, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_CTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_RESETSM_CNTRL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP_CFG, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_TIMER1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_TIMER2, 0x3f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_MAP, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_SVS_MODE_CLK_SEL, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE1_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE2_MODE0, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP1_MODE0, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP2_MODE0, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DEC_START_MODE1, 0x98),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CP_CTRL_MODE1, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_CCTRL_MODE1, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE1_MODE1, 0xd6),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE2_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP1_MODE1, 0x32),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP2_MODE1, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP3_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_BG_TRIM, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_INITVAL1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_INITVAL2, 0x00),
+
+	/* Rate B */
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_TX_HIGHZ_TRANSCEIVER_BIAS_DRVR_EN, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_SIGDET_LVL, 0x24),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_SIGDET_CNTRL, 0x0F),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_INTERFACE_MODE, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_TERM_BW, 0x5B),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN1_LSB, 0xFF),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN1_MSB, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN2_LSB, 0xFF),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN2_MSB, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SO_SATURATION_ENABLE, 0x5B),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_PWM_GEAR_BAND, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_SIGDET_CTRL2, 0x6d),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_SYM_RESYNC_CTRL, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
+};
+
 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
@@ -3396,6 +3492,31 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
 	.no_pcs_sw_reset	= true,
 };
 
+static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
+	.type			= PHY_TYPE_UFS,
+	.nlanes			= 1,
+
+	.serdes_tbl		= sm6115_ufsphy_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
+	.tx_tbl			= sm6115_ufsphy_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
+	.rx_tbl			= sm6115_ufsphy_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
+	.pcs_tbl		= sm6115_ufsphy_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
+	.clk_list		= sdm845_ufs_phy_clk_l,
+	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= sm6115_ufsphy_regs_layout,
+
+	.start_ctrl		= SERDES_START,
+	.pwrdn_ctrl		= SW_PWRDN,
+
+	.is_dual_lane_phy	= false,
+	.no_pcs_sw_reset	= true,
+};
+
 static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
 	.type			= PHY_TYPE_PCIE,
 	.nlanes			= 1,
@@ -5395,6 +5516,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
 	}, {
 		.compatible = "qcom,msm8998-qmp-usb3-phy",
 		.data = &msm8998_usb3phy_cfg,
+	}, {
+		.compatible = "qcom,sm6115-qmp-ufs-phy",
+		.data = &sm6115_ufsphy_cfg,
 	}, {
 		.compatible = "qcom,sm8150-qmp-ufs-phy",
 		.data = &sm8150_ufsphy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index 6592b58b13f6..fffdd532bac4 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -280,6 +280,8 @@
 #define QSERDES_V3_COM_SSC_PER2				0x020
 #define QSERDES_V3_COM_SSC_STEP_SIZE1			0x024
 #define QSERDES_V3_COM_SSC_STEP_SIZE2			0x028
+#define QSERDES_V3_COM_POST_DIV				0x02c
+#define QSERDES_V3_COM_POST_DIV_MUX			0x030
 #define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN		0x034
 # define QSERDES_V3_COM_BIAS_EN				0x0001
 # define QSERDES_V3_COM_BIAS_EN_MUX			0x0002
@@ -291,6 +293,7 @@
 #define QSERDES_V3_COM_CLK_ENABLE1			0x038
 #define QSERDES_V3_COM_SYS_CLK_CTRL			0x03c
 #define QSERDES_V3_COM_SYSCLK_BUF_ENABLE		0x040
+#define QSERDES_V3_COM_PLL_EN				0x044
 #define QSERDES_V3_COM_PLL_IVCO				0x048
 #define QSERDES_V3_COM_LOCK_CMP1_MODE0			0x098
 #define QSERDES_V3_COM_LOCK_CMP2_MODE0			0x09c
@@ -348,6 +351,119 @@
 #define QSERDES_V3_COM_DEBUG_BUS_SEL			0x178
 #define QSERDES_V3_COM_CMN_MODE				0x184
 
+/* Only for QMP V3 660 PHY - QSERDES COM registers*/
+#define QSERDES_V3_660_COM_ATB_SEL1			0x000
+#define QSERDES_V3_660_COM_ATB_SEL2			0x004
+#define QSERDES_V3_660_COM_FREQ_UPDATE			0x008
+#define QSERDES_V3_660_COM_BG_TIMER			0x00c
+#define QSERDES_V3_660_COM_SSC_EN_CENTER		0x010
+#define QSERDES_V3_660_COM_SSC_ADJ_PER1			0x014
+#define QSERDES_V3_660_COM_SSC_ADJ_PER2			0x018
+#define QSERDES_V3_660_COM_SSC_PER1			0x01c
+#define QSERDES_V3_660_COM_SSC_PER2			0x020
+#define QSERDES_V3_660_COM_SSC_STEP_SIZE1		0x024
+#define QSERDES_V3_660_COM_SSC_STEP_SIZE2		0x028
+#define QSERDES_V3_660_COM_POST_DIV			0x02c
+#define QSERDES_V3_660_COM_POST_DIV_MUX			0x030
+#define QSERDES_V3_660_COM_BIAS_EN_CLKBUFLR_EN		0x034
+#define QSERDES_V3_660_COM_CLK_ENABLE1			0x038
+#define QSERDES_V3_660_COM_SYS_CLK_CTRL			0x03c
+#define QSERDES_V3_660_COM_SYSCLK_BUF_ENABLE		0x040
+#define QSERDES_V3_660_COM_PLL_EN			0x044
+#define QSERDES_V3_660_COM_PLL_IVCO			0x048
+#define QSERDES_V3_660_COM_LOCK_CMP1_MODE0		0x04c
+#define QSERDES_V3_660_COM_LOCK_CMP2_MODE0		0x050
+#define QSERDES_V3_660_COM_LOCK_CMP3_MODE0		0x054
+#define QSERDES_V3_660_COM_LOCK_CMP1_MODE1		0x058
+#define QSERDES_V3_660_COM_LOCK_CMP2_MODE1		0x05c
+#define QSERDES_V3_660_COM_LOCK_CMP3_MODE1		0x060
+#define QSERDES_V3_660_COM_CMD_RSVD0			0x064
+#define QSERDES_V3_660_COM_EP_CLOCK_DETECT_CTRL		0x068
+#define QSERDES_V3_660_COM_SYSCLK_DET_COMP_STATUS	0x06c
+#define QSERDES_V3_660_COM_BG_TRIM			0x070
+#define QSERDES_V3_660_COM_CLK_EP_DIV			0x074
+#define QSERDES_V3_660_COM_CP_CTRL_MODE0		0x078
+#define QSERDES_V3_660_COM_CP_CTRL_MODE1		0x07c
+#define QSERDES_V3_660_COM_CMN_RSVD1			0x080
+#define QSERDES_V3_660_COM_PLL_RCTRL_MODE0		0x084
+#define QSERDES_V3_660_COM_PLL_RCTRL_MODE1		0x088
+#define QSERDES_V3_660_COM_CMN_RSVD2			0x08c
+#define QSERDES_V3_660_COM_PLL_CCTRL_MODE0		0x090
+#define QSERDES_V3_660_COM_PLL_CCTRL_MODE1		0x094
+#define QSERDES_V3_660_COM_CMN_RSVD3			0x098
+#define QSERDES_V3_660_COM_PLL_CNTRL			0x09c
+#define QSERDES_V3_660_COM_PHASE_SEL_CTRL		0x0a0
+#define QSERDES_V3_660_COM_PHASE_SEL_DC			0x0a4
+#define QSERDES_V3_660_COM_BIAS_EN_CTRL_BY_PSM		0x0a8
+#define QSERDES_V3_660_COM_SYSCLK_EN_SEL		0x0ac
+#define QSERDES_V3_660_COM_CML_SYSCLK_SEL		0x0b0
+#define QSERDES_V3_660_COM_RESETSM_CNTRL		0x0b4
+#define QSERDES_V3_660_COM_RESETSM_CNTRL2		0x0b8
+#define QSERDES_V3_660_COM_RESTRIM_CTRL			0x0bc
+#define QSERDES_V3_660_COM_RESTRIM_CTRL2		0x0c0
+#define QSERDES_V3_660_COM_LOCK_CMP_EN			0x0c8
+#define QSERDES_V3_660_COM_LOCK_CMP_CFG			0x0cc
+#define QSERDES_V3_660_COM_DEC_START_MODE0		0x0d0
+#define QSERDES_V3_660_COM_DEC_START_MODE1		0x0d4
+#define QSERDES_V3_660_COM_VCOCAL_DEADMAN_CTRL		0x0d8
+#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0	0x0dc
+#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0	0x0e0
+#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0	0x0e4
+#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1	0x0e8
+#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1	0x0ec
+#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1	0x0f0
+#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL1		0x0f4
+#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL2		0x0f8
+#define QSERDES_V3_660_COM_CMN_RSVD4			0x0fc
+#define QSERDES_V3_660_COM_INTEGLOOP_INITVAL		0x100
+#define QSERDES_V3_660_COM_INTEGLOOP_EN			0x104
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0	0x108
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0	0x10c
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1	0x110
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1	0x114
+#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL1		0x118
+#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL2		0x11c
+#define QSERDES_V3_660_COM_RES_TRIM_CONTROL2		0x120
+#define QSERDES_V3_660_COM_VCO_TUNE_CTRL		0x124
+#define QSERDES_V3_660_COM_VCO_TUNE_MAP			0x128
+#define QSERDES_V3_660_COM_VCO_TUNE1_MODE0		0x12c
+#define QSERDES_V3_660_COM_VCO_TUNE2_MODE0		0x130
+#define QSERDES_V3_660_COM_VCO_TUNE1_MODE1		0x134
+#define QSERDES_V3_660_COM_VCO_TUNE2_MODE1		0x138
+#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL1		0x13c
+#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL2		0x140
+#define QSERDES_V3_660_COM_VCO_TUNE_TIMER1		0x144
+#define QSERDES_V3_660_COM_VCO_TUNE_TIMER2		0x148
+#define QSERDES_V3_660_COM_SAR				0x14c
+#define QSERDES_V3_660_COM_SAR_CLK			0x150
+#define QSERDES_V3_660_COM_SAR_CODE_OUT_STATUS		0x154
+#define QSERDES_V3_660_COM_SAR_CODE_READY_STATUS	0x158
+#define QSERDES_V3_660_COM_CMN_STATUS			0x15c
+#define QSERDES_V3_660_COM_RESET_SM_STATUS		0x160
+#define QSERDES_V3_660_COM_RESTRIM_CODE_STATUS		0x164
+#define QSERDES_V3_660_COM_PLLCAL_CODE1_STATUS		0x168
+#define QSERDES_V3_660_COM_PLLCAL_CODE2_STATUS		0x16c
+#define QSERDES_V3_660_COM_BG_CTRL			0x170
+#define QSERDES_V3_660_COM_CLK_SELECT			0x174
+#define QSERDES_V3_660_COM_HSCLK_SEL			0x178
+#define QSERDES_V3_660_COM_INTEGLOOP_BINCODE_STATUS	0x17c
+#define QSERDES_V3_660_COM_PLL_ANALOG			0x180
+#define QSERDES_V3_660_COM_CORECLK_DIV			0x184
+#define QSERDES_V3_660_COM_SW_RESET			0x188
+#define QSERDES_V3_660_COM_CORE_CLK_EN			0x18c
+#define QSERDES_V3_660_COM_C_READY_STATUS		0x190
+#define QSERDES_V3_660_COM_CMN_CONFIG			0x194
+#define QSERDES_V3_660_COM_CMN_RATE_OVERRIDE		0x198
+#define QSERDES_V3_660_COM_SVS_MODE_CLK_SEL		0x19c
+#define QSERDES_V3_660_COM_DEBUG_BUS0			0x1a0
+#define QSERDES_V3_660_COM_DEBUG_BUS1			0x1a4
+#define QSERDES_V3_660_COM_DEBUG_BUS2			0x1a8
+#define QSERDES_V3_660_COM_DEBUG_BUS3			0x1ac
+#define QSERDES_V3_660_COM_DEBUG_BUS_SEL		0x1b0
+#define QSERDES_V3_660_COM_CMN_MISC1			0x1b4
+#define QSERDES_V3_660_COM_CORECLK_DIV_MODE1		0x1bc
+#define QSERDES_V3_660_COM_CMN_RSVD5			0x1c0
+
 /* Only for QMP V3 PHY - TX registers */
 #define QSERDES_V3_TX_BIST_MODE_LANENO			0x000
 #define QSERDES_V3_TX_CLKBUF_ENABLE			0x008
@@ -380,6 +496,10 @@
 #define QSERDES_V3_TX_TX_INTERFACE_MODE			0x0c4
 #define QSERDES_V3_TX_VMODE_CTRL1			0x0f0
 
+/* Only for QMP V3 660 PHY - TX registers */
+#define QSERDES_V3_660_TX_HIGHZ_TRANSCEIVER_BIAS_DRVR_EN	0x068
+#define QSERDES_V3_660_TX_LANE_MODE				0x094
+
 /* Only for QMP V3 PHY - RX registers */
 #define QSERDES_V3_RX_UCDR_FO_GAIN			0x008
 #define QSERDES_V3_RX_UCDR_SO_GAIN_HALF			0x00c
@@ -411,6 +531,24 @@
 #define QSERDES_V3_RX_RX_MODE_00			0x164
 #define QSERDES_V3_RX_RX_MODE_01			0x168
 
+/* Only for QMP V3 660 PHY - RX registers */
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_HALF		0x030
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_QUARTER	0x034
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_EIGHTH	0x038
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN		0x03c
+#define QSERDES_V3_660_RX_UCDR_FASTLOCK_FO_GAIN		0x040
+#define QSERDES_V3_660_RX_UCDR_SO_SATURATION_ENABLE	0x048
+#define QSERDES_V3_660_RX_RX_TERM_BW			0x090
+#define QSERDES_V3_660_RX_RX_EQ_GAIN1_LSB		0x0c4
+#define QSERDES_V3_660_RX_RX_EQ_GAIN1_MSB		0x0c8
+#define QSERDES_V3_660_RX_RX_EQ_GAIN2_LSB		0x0cc
+#define QSERDES_V3_660_RX_RX_EQ_GAIN2_MSB		0x0d0
+#define QSERDES_V3_660_RX_RX_EQU_ADAPTOR_CNTRL2		0x0d8
+#define QSERDES_V3_660_RX_SIGDET_CNTRL			0x114
+#define QSERDES_V3_660_RX_SIGDET_LVL			0x118
+#define QSERDES_V3_660_RX_SIGDET_DEGLITCH_CNTRL		0x11c
+#define QSERDES_V3_660_RX_RX_INTERFACE_MODE		0x12c
+
 /* Only for QMP V3 PHY - PCS registers */
 #define QPHY_V3_PCS_POWER_DOWN_CONTROL			0x004
 #define QPHY_V3_PCS_TXMGN_V0				0x00c
@@ -473,6 +611,21 @@
 #define QPHY_V3_PCS_REFGEN_REQ_CONFIG1			0x20c
 #define QPHY_V3_PCS_REFGEN_REQ_CONFIG2			0x210
 
+/* Only for QMP V3 660 PHY - PCS registers */
+#define QPHY_V3_660_PCS_PHY_START			0x000
+#define QPHY_V3_660_PCS_POWER_DOWN_CONTROL		0x004
+#define QPHY_V3_660_PCS_TX_LARGE_AMP_DRV_LVL		0x034
+#define QPHY_V3_660_PCS_TX_LARGE_AMP_POST_EMP_LVL	0x038
+#define QPHY_V3_660_PCS_TX_SMALL_AMP_DRV_LVL		0x03c
+#define QPHY_V3_660_PCS_TX_SMALL_AMP_POST_EMP_LVL	0x040
+#define QPHY_V3_660_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP	0x0cc
+#define QPHY_V3_660_PCS_LINECFG_DISABLE			0x138
+#define QPHY_V3_660_PCS_RX_SYM_RESYNC_CTRL		0x13c
+#define QPHY_V3_660_PCS_RX_MIN_HIBERN8_TIME		0x140
+#define QPHY_V3_660_PCS_RX_SIGDET_CTRL2			0x148
+#define QPHY_V3_660_PCS_RX_PWM_GEAR_BAND		0x154
+#define QPHY_V3_660_PCS_PCS_READY_STATUS		0x168
+
 /* Only for QMP V3 PHY - PCS_MISC registers */
 #define QPHY_V3_PCS_MISC_CLAMP_ENABLE			0x0c
 #define QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2		0x2c
-- 
2.32.0



From lorenzo.pieralisi at arm.com  Thu Aug  5 02:42:37 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 5 Aug 2021 10:42:37 +0100
Subject: [PATCH v2 0/6] arm64: IPQ6018 PCIe support
In-Reply-To: <87o8acxtqm.fsf@tarshish>
References: <cover.1620203062.git.baruch@tkos.co.il> <87o8acxtqm.fsf@tarshish>
Message-ID: <20210805094237.GA18330@lpieralisi>

On Thu, Aug 05, 2021 at 09:58:57AM +0300, Baruch Siach wrote:
> Hi Lorenzo, Rob, Krzysztof,
> 
> On Wed, May 05 2021, Baruch Siach wrote:
> > This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
> > ported from downstream Codeaurora v5.4 kernel. The main difference from 
> > downstream code is the split of PCIe registers configuration from .init to 
> > .post_init, since it requires phy_power_on().
> >
> > Tested on IPQ6010 based hardware.
> 
> It's been 3 months with no comment. Would you consider applying the dwc
> part (patches #1 and #2) for the v5.15 merge window?
> 
> I tested the patches here successfully on top of v5.14-rc4.

You need an ACK from the respective drivers maintainers. We look into
overall pci/controller drivers structure and common code, it is up
to drivers maintainers to review and ACK your patches, I will certainly
pick them up when that's done.

Thanks,
Lorenzo

> Thanks,
> baruch
> 
> >
> > Changes in v2:
> >
> >   * Add patch moving GEN3_RELATED macros to a common header
> >
> >   * Drop ATU configuration from pcie-qcom
> >
> >   * Remove local definition of common registers
> >
> >   * Use bulk clk and reset APIs
> >
> >   * Remove msi-parent from device-tree
> >
> > Baruch Siach (3):
> >   PCI: dwc: tegra: move GEN3_RELATED DBI register to common header
> >   dt-bindings: phy: qcom,qmp: Add IPQ60xx PCIe PHY bindings
> >   dt-bindings: pci: qcom: Document PCIe bindings for IPQ6018 SoC
> >
> > Selvam Sathappan Periakaruppan (3):
> >   PCI: qcom: add support for IPQ60xx PCIe controller
> >   phy: qcom-qmp: add QMP V2 PCIe PHY support for ipq60xx
> >   arm64: dts: ipq6018: Add pcie support
> >
> >  .../devicetree/bindings/pci/qcom,pcie.txt     |  24 +++
> >  .../devicetree/bindings/phy/qcom,qmp-phy.yaml |  25 +++
> >  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  99 ++++++++++++
> >  drivers/pci/controller/dwc/pcie-designware.h  |   7 +
> >  drivers/pci/controller/dwc/pcie-qcom.c        | 150 ++++++++++++++++++
> >  drivers/pci/controller/dwc/pcie-tegra194.c    |   6 -
> >  drivers/phy/qualcomm/phy-qcom-qmp.c           | 147 +++++++++++++++++
> >  drivers/phy/qualcomm/phy-qcom-qmp.h           | 132 +++++++++++++++
> >  8 files changed, 584 insertions(+), 6 deletions(-)
> 
> 
> -- 
>                                                      ~. .~   Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
>    - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From linux.amoon at gmail.com  Thu Aug  5 11:18:20 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Thu, 5 Aug 2021 23:48:20 +0530
Subject: [PATCHv2 1/4] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>
References: <20210716103651.1455-1-linux.amoon@gmail.com>
 <20210716103651.1455-2-linux.amoon@gmail.com>
 <CAFBinCDeqauw_V-Vn9cat9HaCXj6HEMz6G+G+VbqCNtGEFGYzg@mail.gmail.com>
 <CANAwSgQ5PDGUWMH-jxnz5wwutUVniTn7RAe=4J=8-jbmqxYRRg@mail.gmail.com>
 <CAFBinCBhg+dije+3DvV_V_kqHv9q+r4EPxXCYFti6KuA4mK7KQ@mail.gmail.com>
 <CANAwSgT9-5zGr67aGzBmW6WDBfeiAvjv_zv2UbRC+YbgAGg==A@mail.gmail.com>
 <CAFBinCCGA0b=LVjbQood+iN+DHLodY0RJ-GrSOcgdzrDFJ25pQ@mail.gmail.com>
 <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
 <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>
Message-ID: <CANAwSgS2vi7hZqX0LWxNTvk-3aN=n1fEErj4Zt0_4CCpZGyRkg@mail.gmail.com>

Hi Martin,

On Thu, 5 Aug 2021 at 03:28, Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
>
> On Sun, Jul 18, 2021 at 9:09 PM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> >
> > Hi Anand,
> >
> > On Sun, Jul 18, 2021 at 4:01 PM Martin Blumenstingl
> > <martin.blumenstingl at googlemail.com> wrote:
> > [...]
> > > > From the schematics [1]
> > > > https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20160226.pdf
> > > >
> > > > You could find references to PWREN  <--- GPIOAO.BIT5
> > > > The second reference is USB HOST Power Switch
> > > > The third reference is USB HOST POWER.
> > > >
> > > > Hope I am clean in my thought process now.
> > > Can you please point out the page numbers for me?
> > >
> > > What I am seeing on page 1 is:
> > > GPIOAO_5 (called GPIOAO.BIT5) is connected as an INPUT to the USB_OTG
> > > PWREN signal (that's the green box with the label "USB_OTG.SchDoc"
> > > above it).
> > I unfortunately missed your question on IRC on this topic:
> > <armoon> xdarklight: just want to understand the confusion on PWREN,
> > either is INPUT / OTPUT to usb hub am I correct
> > My understanding of the INPUT/OUTPUT direction in the Odroid-C1
> > schematics (which you linked) above is that the arrow direction shows
> > whether it's an input or output.
> > For example (all on page one):
> > - HDMI_HPD is an input to the Meson8b SoC, arrow direction is: HDMI => S805
> > - IR_IN is an input to the Meson8b SoC, arrow direction is: S805 <=
> > GPIOAO.BIT7 IR_IN
> > - PWM is an output, arrow direction is: S805 => PWM.C VCCK_PWM
> > - 3.3V/1.8V switch for the SD card is an output, arrow direction is:
> > S805 => GPIOAO.BIT3 TF_3V3N_1V8_EN
> >
> > That tells me: the arrow direction shows which connections are inputs
> > or outputs.
> > Some pins can be input and output at the same time (HDMI_CEC). But
> > let's keep it simple for now any only look at inputs/output.
> >
> > Based on this information I am looking at the arrow direction for
> > USB_OTG: GPIOAO.BIT5 PWREN <= S805
> > So this confirms that GPIOAO_5 is an output to the SoC.
> > Please note though that this part is not linked with any USB host
> > connector, it's only linked to the USB OTG path.
> >
> > For the next part the S805 SoC is not involved:
> > USB1 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > USB2 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > This tells me that the PWREN signal for the two USB_HOST_PWR_SW (USB
> > host power switches / current limiters) is driven by the GL852G USB
> > hub.
> Hardkernel team responded on the Odroid forums to the request from Anand:
> "Power-Enable signal to the USB load switch ICs is connected to the
> USB hub controller.
> It is not connected the CPU GPIO."
>
> The regulator from Anand's patch is therefore connected to the micro USB port.
> This means that the patch needs updating in case Anand wants to have
> it included.
>

Yes, I will send a corrected version of the patches soon.

>
> Best regards,
> Martin
>
>
> [0] https://forum.odroid.com/viewtopic.php?p=332217#p332217

Thanks
-Anand


From vkoul at kernel.org  Fri Aug  6 03:18:14 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 15:48:14 +0530
Subject: [PATCH v3 2/7] phy: cdns-dphy: Prepare for Rx support
In-Reply-To: <20210624184108.21312-3-p.yadav@ti.com>
References: <20210624184108.21312-1-p.yadav@ti.com>
 <20210624184108.21312-3-p.yadav@ti.com>
Message-ID: <YQ0MZqI36bz1Jp87@matsya>

On 25-06-21, 00:11, Pratyush Yadav wrote:
> The Rx programming sequence differs from the Tx programming sequence.
> Currently only Tx mode is supported. Move all the Tx related parts into
> a set of Tx-specific hooks that are then called by the main PHY
> framework hooks. This way when Rx support is added all that is needed to
> be done is to plug in the Rx hooks.
> 
> The clocks "psm" and "pll_ref" are not used by the Rx path so make them
> optional in the probe and then check if they exist in the power_on()
> hook.
> 
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> ---
> 
> (no changes since v1)
> 
>  drivers/phy/cadence/cdns-dphy.c | 140 ++++++++++++++++++++++++--------
>  1 file changed, 104 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index ba042e39cfaf..8656f2102a91 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -75,6 +75,11 @@ struct cdns_dphy;
>  struct cdns_dphy_ops {
>  	int (*probe)(struct cdns_dphy *dphy);
>  	void (*remove)(struct cdns_dphy *dphy);
> +	int (*power_on)(struct cdns_dphy *dphy);
> +	int (*power_off)(struct cdns_dphy *dphy);
> +	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
> +			union phy_configure_opts *opts);
> +	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
>  	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
>  	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
>  				 enum cdns_dphy_clk_lane_cfg cfg);
> @@ -86,12 +91,18 @@ struct cdns_dphy_ops {
>  struct cdns_dphy {
>  	struct cdns_dphy_cfg cfg;
>  	void __iomem *regs;
> +	struct device *dev;
>  	struct clk *psm_clk;
>  	struct clk *pll_ref_clk;
>  	const struct cdns_dphy_ops *ops;
>  	struct phy *phy;
>  };
>  
> +struct cdns_dphy_driver_data {
> +	const struct cdns_dphy_ops *tx;
> +	const struct cdns_dphy_ops *rx;
> +};
> +
>  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>  				     struct cdns_dphy_cfg *cfg,
>  				     struct phy_configure_opts_mipi_dphy *opts,
> @@ -199,20 +210,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
>  	       dphy->regs + DPHY_PSM_CFG);
>  }
>  
> -/*
> - * This is the reference implementation of DPHY hooks. Specific integration of
> - * this IP may have to re-implement some of them depending on how they decided
> - * to wire things in the SoC.
> - */
> -static const struct cdns_dphy_ops ref_dphy_ops = {
> -	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> -	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> -	.set_psm_div = cdns_dphy_ref_set_psm_div,
> -};
> -
> -static int cdns_dphy_config_from_opts(struct phy *phy,
> -				      struct phy_configure_opts_mipi_dphy *opts,
> -				      struct cdns_dphy_cfg *cfg)
> +static int cdns_dphy_tx_config_from_opts(struct phy *phy,
> +					 struct phy_configure_opts_mipi_dphy *opts,
> +					 struct cdns_dphy_cfg *cfg)
>  {
>  	struct cdns_dphy *dphy = phy_get_drvdata(phy);
>  	unsigned int dsi_hfp_ext = 0;
> @@ -232,24 +232,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
>  	return 0;
>  }
>  
> -static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> -			      union phy_configure_opts *opts)
> +static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
> +				  union phy_configure_opts *opts)
>  {
>  	struct cdns_dphy_cfg cfg = { 0 };
> -
> -	if (mode != PHY_MODE_MIPI_DPHY)
> -		return -EINVAL;
> -
> -	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> -}
> -
> -static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> -{
> -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> -	struct cdns_dphy_cfg cfg = { 0 };
>  	int ret;
>  
> -	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> +	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
>  	if (ret)
>  		return ret;
>  
> @@ -279,9 +268,21 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
>  	return 0;
>  }
>  
> -static int cdns_dphy_power_on(struct phy *phy)
> +static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> +				 int submode, union phy_configure_opts *opts)
>  {
> -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +	struct cdns_dphy_cfg cfg = { 0 };
> +
> +	if (submode != PHY_MIPI_DPHY_SUBMODE_TX)
> +		return -EINVAL;
> +
> +	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
> +}
> +
> +static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
> +{
> +	if (!dphy->psm_clk || !dphy->pll_ref_clk)
> +		return -EINVAL;
>  
>  	clk_prepare_enable(dphy->psm_clk);
>  	clk_prepare_enable(dphy->pll_ref_clk);
> @@ -293,16 +294,77 @@ static int cdns_dphy_power_on(struct phy *phy)
>  	return 0;
>  }
>  
> -static int cdns_dphy_power_off(struct phy *phy)
> +static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
>  {
> -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> -
>  	clk_disable_unprepare(dphy->pll_ref_clk);
>  	clk_disable_unprepare(dphy->psm_clk);
>  
>  	return 0;
>  }
>  
> +static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> +	.power_on = cdns_dphy_tx_power_on,
> +	.power_off = cdns_dphy_tx_power_off,
> +	.validate = cdns_dphy_tx_validate,
> +	.configure = cdns_dphy_tx_configure,
> +	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> +	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> +	.set_psm_div = cdns_dphy_ref_set_psm_div,
> +};
> +
> +/*
> + * This is the reference implementation of DPHY hooks. Specific integration of
> + * this IP may have to re-implement some of them depending on how they decided
> + * to wire things in the SoC.
> + */
> +static const struct cdns_dphy_driver_data ref_dphy_ops = {
> +	.tx = &tx_ref_dphy_ops,
> +};
> +
> +static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> +			      union phy_configure_opts *opts)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (mode != PHY_MODE_MIPI_DPHY)
> +		return -EINVAL;
> +
> +	if (dphy->ops->validate)
> +		return dphy->ops->validate(dphy, mode, submode, opts);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_power_on(struct phy *phy)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (dphy->ops->power_on)
> +		return dphy->ops->power_on(dphy);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_power_off(struct phy *phy)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (dphy->ops->power_off)
> +		return dphy->ops->power_off(dphy);
> +
> +	return 0;
> +}

why do you need a dphy specific power_on/off only to call internal
ops..? If there is no additional logic lets drop this and continue the
phy ops for this

-- 
~Vinod


From paul.kocialkowski at bootlin.com  Fri Aug  6 04:11:30 2021
From: paul.kocialkowski at bootlin.com (Paul Kocialkowski)
Date: Fri, 6 Aug 2021 13:11:30 +0200
Subject: [PATCH v3 1/7] phy: Distinguish between Rx and Tx for MIPI D-PHY
 with submodes
In-Reply-To: <20210624184108.21312-2-p.yadav@ti.com>
References: <20210624184108.21312-1-p.yadav@ti.com>
 <20210624184108.21312-2-p.yadav@ti.com>
Message-ID: <YQ0Y4ueALPNEAoMI@aptenodytes>

Hi,

On Fri 25 Jun 21, 00:11, Pratyush Yadav wrote:
> From: Paul Kocialkowski <paul.kocialkowski at bootlin.com>
> 
> As some D-PHY controllers support both Rx and Tx mode, we need a way for
> users to explicitly request one or the other. For instance, Rx mode can
> be used along with MIPI CSI-2 while Tx mode can be used with MIPI DSI.
> 
> Introduce new MIPI D-PHY PHY submodes to use with PHY_MODE_MIPI_DPHY.
> The default (zero value) is kept to Tx so only the rkisp1 driver, which
> uses D-PHY in Rx mode, needs to be adapted.

After some thinking and discussions, it appears that using the submode is
probably not the best way to distinguish between rx and tx. This is because
rx/tx is more of a specification of the hardware component than a run-time
descision. Indeed the D-PHY blocks are usually dedicated to an associated
controller (DSI or CSI-2) and thus each instance is either meant for tx or
rx use.

As a result I will be using the allwinner,direction string property in
device-tree instead of the submode, with values of either "rx" or "tx".
I suppose you can do something similar if you agree it makes more sense.

Cheers,

Paul
 
> Signed-off-by: Paul Kocialkowski <paul.kocialkowski at bootlin.com>
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> ---
> 
> (no changes since v1)
> 
>  include/linux/phy/phy-mipi-dphy.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..0f57ef46a8b5 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -6,6 +6,19 @@
>  #ifndef __PHY_MIPI_DPHY_H_
>  #define __PHY_MIPI_DPHY_H_
>  
> +/**
> + * enum phy_mipi_dphy_submode - MIPI D-PHY sub-mode
> + *
> + * A MIPI D-PHY can be used to transmit or receive data.
> + * Since some controllers can support both, the direction to enable is specified
> + * with the PHY sub-mode. Transmit is assumed by default with phy_set_mode.
> + */
> +
> +enum phy_mipi_dphy_submode {
> +	PHY_MIPI_DPHY_SUBMODE_TX = 0,
> +	PHY_MIPI_DPHY_SUBMODE_RX,
> +};
> +
>  /**
>   * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
>   *
> -- 
> 2.30.0
> 

-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20210806/94c9f36d/attachment.sig>

From vkoul at kernel.org  Fri Aug  6 04:15:39 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 16:45:39 +0530
Subject: [PATCH v3 4/7] phy: cdns-dphy: Add Rx support
In-Reply-To: <20210624184108.21312-5-p.yadav@ti.com>
References: <20210624184108.21312-1-p.yadav@ti.com>
 <20210624184108.21312-5-p.yadav@ti.com>
Message-ID: <YQ0Z2wYQYAFn2KCY@matsya>

On 25-06-21, 00:11, Pratyush Yadav wrote:
> The Cadence DPHY can be used to receive image data over the CSI-2
> protocol. Add support for Rx mode. The programming sequence differs from
> the Tx mode so it is added as a separate set of hooks to isolate the two
> paths.
> 
> The PHY is in Tx mode by default and it needs to be set in Rx mode by
> setting the submode to PHY_MIPI_DPHY_SUBMODE_RX in the set_mode()
> callback.
> 
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> 
> ---
> 
> Changes in v3:
> - Use a table to select the band.
> - Use a table to poll the data lane ready bits.
> - Multiply the DPHY HS clock rate by 2 to get the bit rate since the
>   clock is DDR.
> 
>  drivers/phy/cadence/cdns-dphy.c | 174 ++++++++++++++++++++++++++++++++
>  1 file changed, 174 insertions(+)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index 7d5f7b333893..7534ec957dc5 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -1,11 +1,14 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  /*
>   * Copyright: 2017-2018 Cadence Design Systems, Inc.
> + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
>   */
>  
>  #include <linux/bitops.h>
> +#include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/io.h>
> +#include <linux/iopoll.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
>  #include <linux/of_device.h>
> @@ -25,10 +28,14 @@
>  #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
>  #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
>  #define DPHY_PCS(reg)			(0xb00 + (reg))
> +#define DPHY_ISO(reg)			(0xc00 + (reg))
>  
>  #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
>  #define DPHY_CMN_SSM_EN			BIT(0)
> +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
>  #define DPHY_CMN_TX_MODE_EN		BIT(9)
> +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
>  
>  #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
>  #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> @@ -45,10 +52,27 @@
>  #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
>  #define DPHY_CMN_OPDIV(x)		((x) << 7)
>  
> +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> +
>  #define DPHY_PSM_CFG			DPHY_PCS(0x4)
>  #define DPHY_PSM_CFG_FROM_REG		BIT(0)
>  #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
>  
> +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> +
> +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> +#define DPHY_ISO_LANE_READY_BIT		0
> +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> +
>  #define DSI_HBP_FRAME_OVERHEAD		12
>  #define DSI_HSA_FRAME_OVERHEAD		14
>  #define DSI_HFP_FRAME_OVERHEAD		6
> @@ -57,6 +81,9 @@
>  #define DSI_NULL_FRAME_OVERHEAD		6
>  #define DSI_EOT_PKT_SIZE		4
>  
> +#define DPHY_LANES_MIN			1
> +#define DPHY_LANES_MAX			4
> +
>  struct cdns_dphy_cfg {
>  	u8 pll_ipdiv;
>  	u8 pll_opdiv;
> @@ -103,6 +130,22 @@ struct cdns_dphy_driver_data {
>  	const struct cdns_dphy_ops *rx;
>  };
>  
> +struct cdns_dphy_rx_band {
> +	unsigned int min_rate;
> +	unsigned int max_rate;
> +};
> +
> +/* Order of bands is important since the index is the band number. */
> +struct cdns_dphy_rx_band bands[] = {
> +	{80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240},
> +	{240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480},
> +	{480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880},
> +	{880, 1040}, {1040, 1200}, {1200, 1350}, {1350, 1500}, {1500, 1750},
> +	{1750, 2000}, {2000, 2250}, {2250, 2500}
> +};
> +
> +int num_bands = ARRAY_SIZE(bands);
> +
>  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>  				     struct cdns_dphy_cfg *cfg,
>  				     struct phy_configure_opts_mipi_dphy *opts,
> @@ -312,6 +355,135 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
>  	.set_psm_div = cdns_dphy_ref_set_psm_div,
>  };
>  
> +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> +{
> +	/* Start RX state machine. */
> +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> +			  DPHY_CMN_RX_BANDGAP_TIMER),
> +	       dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> +{
> +	writel(0, dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> +{
> +	unsigned int rate;
> +	int i;
> +
> +	rate = hs_clk_rate / 1000000UL;
> +	/* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
> +	rate *= 2;
> +
> +	if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate)
> +		return -EOPNOTSUPP;
> +
> +	for (i = 0; i < num_bands; i++) {
> +		if (rate >= bands[i].min_rate && rate < bands[i].max_rate)
> +			return i;
> +	}
> +
> +	/* Unreachable. */
> +	WARN(1, "Reached unreachable code.");
> +	return -EINVAL;
> +}
> +
> +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> +{
> +	u32 val;
> +
> +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);

this looks wrong, val is not initialized, so what/when is condition to
be met..?
-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 04:30:01 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:00:01 +0530
Subject: [PATCH 4/7] dt-bindings: phy: imx8mq-usb-phy: convert to json
 schema
In-Reply-To: <20210715082536.1882077-5-aisheng.dong@nxp.com>
References: <20210715082536.1882077-1-aisheng.dong@nxp.com>
 <20210715082536.1882077-5-aisheng.dong@nxp.com>
Message-ID: <YQ0dOQteW4/2MPfZ@matsya>

On 15-07-21, 16:25, Dong Aisheng wrote:
> Convert to jason schema.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 04:44:47 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:14:47 +0530
Subject: [PATCH] phy: qmp: Provide unique clock names for DP clocks
In-Reply-To: <20210722030738.3385821-1-bjorn.andersson@linaro.org>
References: <20210722030738.3385821-1-bjorn.andersson@linaro.org>
Message-ID: <YQ0gr/DkhecbPKn9@matsya>

On 21-07-21, 20:07, Bjorn Andersson wrote:
> The USB/DP combo PHY exposes the "qmp_dp_phy_pll_link_clk" and
> "qmp_dp_phy_pll_vco_div_clk" clocks, that are consumed by the display
> clock controller. But for boards with multiple enabled QMP USB/DP combo
> instances the hard coded names collides - and hence only the first
> probed device is allowed to register.
> 
> Given that clocks are no longer reference globally by name and it's
> possible to replace the hard coded names by something unique, but still
> user friendly.
> 
> The two new clock names are based on dev_name() and results in names
> such as "88ee000.phy::link_clk" and "88ee000.phy::vco_div_clk".

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 04:45:38 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:15:38 +0530
Subject: [PATCH] phy: qualcomm: phy-qcom-usb-hs: repair non-kernel-doc
 comment
In-Reply-To: <20210723022548.25695-1-rdunlap@infradead.org>
References: <20210723022548.25695-1-rdunlap@infradead.org>
Message-ID: <YQ0g4ogGvb4piZcM@matsya>

On 22-07-21, 19:25, Randy Dunlap wrote:
> Fix errant use of "/**" to begin a comment although the comment
> is not kernel-doc notation. Just use "/*" instead.
> 
> Fixes this kernel-doc warning:
> 
> drivers/phy/qualcomm/phy-qcom-usb-hs.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>     * Copyright (C) 2016 Linaro Ltd

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 04:59:55 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:29:55 +0530
Subject: [PATCH v4 1/3] dt-bindings: phy: mediatek: tphy: add support
 hardware version 3
In-Reply-To: <1627028562-23584-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1627028562-23584-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQ0kO7ZWO3y0Xmne@matsya>

On 23-07-21, 16:22, Chunfeng Yun wrote:
> The PHYA architecture is updated, and doesn't support slew rate
> calibration anymore on 7nm or advanced process, add a new version
> number to support it.
> Due to the FreqMeter bank is not used but reserved, it's backward
> with v2 until now.
> For mt8195, no function changes when use generic v2 or v3 compatible,
> but prefer to use v3's compatible, it will not waste the time to
> calibrate the slew rate, and also correspond with hardware version.

Applied all, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:01:05 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:31:05 +0530
Subject: [PATCH v4 5/9] phy: pistachio-usb: Depend on MIPS || COMPILE_TEST
In-Reply-To: <20210723022543.4095-6-jiaxun.yang@flygoat.com>
References: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
 <20210723022543.4095-6-jiaxun.yang@flygoat.com>
Message-ID: <YQ0kgfzCFXoHKcsP@matsya>

On 23-07-21, 10:25, Jiaxun Yang wrote:
> So it will be avilable for generic MIPS kernel.

Acked-By: Vinod Koul <vkoul at kernel.org>

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:02:59 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:32:59 +0530
Subject: [PATCH] phy: phy-twl4030-usb: Disable PHY for suspend
In-Reply-To: <20210727104512.52968-1-tony@atomide.com>
References: <20210727104512.52968-1-tony@atomide.com>
Message-ID: <YQ0k8xd6wYkATubB@matsya>

On 27-07-21, 13:45, Tony Lindgren wrote:
> Since commit 88d26136a256 ("PM: Prevent runtime suspend during system
> resume"), PM runtime will not let devices idle during system suspend.
> 
> This is because of the pm_runtime_get_noresume() call done in
> device_prepare() that is not released until at device_complete() after
> resume.
> 
> We must now disable the USB PHY in suspend if no USB cable is connected.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:07:33 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:37:33 +0530
Subject: [PATCH 1/2] dt-bindings: phy: qcom,qmp-usb3-dp: Add support for
 sc8180x
In-Reply-To: <20210721225630.3035861-1-bjorn.andersson@linaro.org>
References: <20210721225630.3035861-1-bjorn.andersson@linaro.org>
Message-ID: <YQ0mBRBgjT6pE/HM@matsya>

On 21-07-21, 15:56, Bjorn Andersson wrote:
> The SC8180x has two instances of the QMP USB/DP combo PHYs, add a
> compatible for these.

Applied all, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:08:08 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:38:08 +0530
Subject: [PATCH] dt-bindings: phy: Convert AM654 SERDES bindings to YAML
In-Reply-To: <20210723135605.23572-1-kishon@ti.com>
References: <20210723135605.23572-1-kishon@ti.com>
Message-ID: <YQ0mKEfb22XcK7gl@matsya>

On 23-07-21, 19:26, Kishon Vijay Abraham I wrote:
> Convert SERDES dt-bindings for TI's AM654 SoC to YAML binding.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:39:19 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:09:19 +0530
Subject: [PATCH 3/3] phy: intel: Add Thunder Bay eMMC PHY support
In-Reply-To: <20210730063309.8194-4-rashmi.a@intel.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-4-rashmi.a@intel.com>
Message-ID: <YQ0td9y5+RNFxWZs@matsya>

On 30-07-21, 12:03, rashmi.a at intel.com wrote:

> diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig
> index ac42bb2fb394..18a3cc5b98c0 100644
> --- a/drivers/phy/intel/Kconfig
> +++ b/drivers/phy/intel/Kconfig
> @@ -46,3 +46,13 @@ config PHY_INTEL_LGM_EMMC
>  	select GENERIC_PHY
>  	help
>  	  Enable this to support the Intel EMMC PHY
> +
> +config PHY_INTEL_THUNDERBAY_EMMC

Alphabetical sort please

> +        tristate "Intel Thunder Bay eMMC PHY driver"
> +        depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST)
> +        select GENERIC_PHY
> +        help
> +	  This option enables support for Intel Thunder Bay SoC eMMC PHY.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called phy-intel-thunderbay-emmc.ko.
> diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile
> index 14550981a707..6a4db3ee7393 100644
> --- a/drivers/phy/intel/Makefile
> +++ b/drivers/phy/intel/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC)	+= phy-intel-keembay-emmc.o
> +obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC)	+= phy-intel-thunderbay-emmc.o

here as well

> +static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
> +{
> +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> +	unsigned int freqsel = FREQSEL_200M_170M;
> +	unsigned long rate;
> +	static int lock;
> +	u32 val;
> +	int ret;
> +
> +	/* Disable DLL */
> +	rate = clk_get_rate(tbh_phy->emmcclk);
> +	switch (rate) {
> +	case 200000000:
> +	/* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */
> +		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0);

pls keep the same indent for comment and code!

> +		break;
> +	/* dll lock not required for other frequencies */
> +	case 50000000 ... 52000000:
> +	case 400000:
> +	default:
> +		break;
> +	}
> +
> +	if (!power_on)
> +		return 0;

should this not be the first thing you check...

> +
> +	rate = clk_get_rate(tbh_phy->emmcclk);
> +	switch (rate) {
> +	case 170000001 ... 200000000:
> +		freqsel = FREQSEL_200M_170M;
> +		break;
> +	case 140000001 ... 170000000:
> +		freqsel = FREQSEL_170M_140M;
> +		break;
> +	case 110000001 ... 140000000:
> +		freqsel = FREQSEL_140M_110M;
> +		break;
> +	case 80000001 ... 110000000:
> +		freqsel = FREQSEL_110M_80M;
> +		break;
> +	case 50000000 ... 80000000:
> +		freqsel = FREQSEL_80M_50M;
> +		break;
> +	case 250000001 ... 275000000:
> +		freqsel = FREQSEL_275M_250M;
> +		break;
> +	case 225000001 ... 250000000:
> +		freqsel = FREQSEL_250M_225M;
> +		break;
> +	case 200000001 ... 225000000:
> +		freqsel = FREQSEL_225M_200M;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (rate > 200000000)
> +	/* only the upper limit is considered as the clock rate may fall low during init */
> +		dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);

here as well! (checkpatch --strict should have told you so)

> +static int thunderbay_emmc_phy_power_on(struct phy *phy)
> +{
> +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> +	unsigned long rate;
> +
> +	/* Overwrite capability bits configurable in bootloader */
> +	update_reg(tbh_phy, CTRL_CFG_0,
> +		   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_0,
> +		   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
> +
> +	if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
> +	/* Indicates initialization, so settings to be done for init , same as 400KHZ setting */
> +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1);

inconsistent indent here too!

> +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1);
> +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0);
> +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0);
> +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0);
> +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0);
> +		update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0);
> +		update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
> +
> +	} else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
> +		/* Indicates actual clock setting */
> +		rate = clk_get_rate(tbh_phy->emmcclk);
> +		switch (rate) {
> +		case 200000000:
> +			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
> +				   SEL_DLY_TXCLK_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
> +				   SEL_DLY_RXCLK_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
> +				   ITAP_DLY_ENA_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
> +				   ITAP_DLY_SEL_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
> +				   OTAP_DLY_ENA_SHIFT, 0x1);
> +			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
> +				   OTAP_DLY_SEL_SHIFT, 2);
> +			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
> +				   DLL_TRIM_ICP_SHIFT, 0x8);
> +			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
> +				   DR_TY_SHIFT, 0x1);
> +			/* For HS400 only */
> +			update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
> +				   SEL_STRB_SHIFT, STRB);
> +			break;

pls give a empty line after break, helps to read the code

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:42:39 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:12:39 +0530
Subject: [PATCH v5 2/6] dt-bindings: phy: renesas,usb2-phy: Document
 RZ/G2L phy bindings
In-Reply-To: <20210727185527.19907-3-biju.das.jz@bp.renesas.com>
References: <20210727185527.19907-1-biju.das.jz@bp.renesas.com>
 <20210727185527.19907-3-biju.das.jz@bp.renesas.com>
Message-ID: <YQ0uP0yjYe+jOe6W@matsya>

On 27-07-21, 19:55, Biju Das wrote:
> Document USB phy bindings for RZ/G2L SoC.
> 
> RZ/G2L USB2.0 phy uses line ctrl register for OTG_ID pin changes. It uses
> a different OTG-BC interrupt bit for device recognition. Apart from this,
> the PHY reset is controlled by USBPHY control IP and Document reset is a
> required property.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:43:03 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:13:03 +0530
Subject: [PATCH v5 3/6] phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY
 support for RZ/G2L
In-Reply-To: <20210727185527.19907-4-biju.das.jz@bp.renesas.com>
References: <20210727185527.19907-1-biju.das.jz@bp.renesas.com>
 <20210727185527.19907-4-biju.das.jz@bp.renesas.com>
Message-ID: <YQ0uVyBGYbvG4WTi@matsya>

On 27-07-21, 19:55, Biju Das wrote:
> This patch adds USB2.0 PHY support for RZ/G2L SoC.
> 
> We need to use a different compatible string due to some differences
> with R-Car Gen3 USB2.0 PHY. It uses line ctrl register for OTG_ID
> pin changes and different OTG-BC interrupt bit for device recognition.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:48:20 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:18:20 +0530
Subject: [PATCH v2 0/6] arm64: IPQ6018 PCIe support
In-Reply-To: <20210805094237.GA18330@lpieralisi>
References: <cover.1620203062.git.baruch@tkos.co.il> <87o8acxtqm.fsf@tarshish>
 <20210805094237.GA18330@lpieralisi>
Message-ID: <YQ0vlNekc289LqJl@matsya>

On 05-08-21, 10:42, Lorenzo Pieralisi wrote:
> On Thu, Aug 05, 2021 at 09:58:57AM +0300, Baruch Siach wrote:
> > Hi Lorenzo, Rob, Krzysztof,
> > 
> > On Wed, May 05 2021, Baruch Siach wrote:
> > > This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
> > > ported from downstream Codeaurora v5.4 kernel. The main difference from 
> > > downstream code is the split of PCIe registers configuration from .init to 
> > > .post_init, since it requires phy_power_on().
> > >
> > > Tested on IPQ6010 based hardware.
> > 
> > It's been 3 months with no comment. Would you consider applying the dwc
> > part (patches #1 and #2) for the v5.15 merge window?
> > 
> > I tested the patches here successfully on top of v5.14-rc4.
> 
> You need an ACK from the respective drivers maintainers. We look into
> overall pci/controller drivers structure and common code, it is up
> to drivers maintainers to review and ACK your patches, I will certainly
> pick them up when that's done.

Also is there any dependency b/w various pieces, if not consider sending
patches to respective subsystems...

Too many patch series these days are adding cross subsystem stuff even
if there are no dependencies. Yes it all needs to come together to work
but that does not require a common series to be posted!

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 05:57:18 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:27:18 +0530
Subject: [PATCH v1 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <20210805091727.942471-3-iskren.chernev@gmail.com>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
 <20210805091727.942471-3-iskren.chernev@gmail.com>
Message-ID: <YQ0xrgDjxXeNecAS@matsya>

On 05-08-21, 12:17, Iskren Chernev wrote:

> +/* Only for QMP V3 660 PHY - QSERDES COM registers*/
> +#define QSERDES_V3_660_COM_ATB_SEL1			0x000
> +#define QSERDES_V3_660_COM_ATB_SEL2			0x004
> +#define QSERDES_V3_660_COM_FREQ_UPDATE			0x008
> +#define QSERDES_V3_660_COM_BG_TIMER			0x00c
> +#define QSERDES_V3_660_COM_SSC_EN_CENTER		0x010
> +#define QSERDES_V3_660_COM_SSC_ADJ_PER1			0x014
> +#define QSERDES_V3_660_COM_SSC_ADJ_PER2			0x018
> +#define QSERDES_V3_660_COM_SSC_PER1			0x01c
> +#define QSERDES_V3_660_COM_SSC_PER2			0x020
> +#define QSERDES_V3_660_COM_SSC_STEP_SIZE1		0x024
> +#define QSERDES_V3_660_COM_SSC_STEP_SIZE2		0x028
> +#define QSERDES_V3_660_COM_POST_DIV			0x02c
> +#define QSERDES_V3_660_COM_POST_DIV_MUX			0x030
> +#define QSERDES_V3_660_COM_BIAS_EN_CLKBUFLR_EN		0x034
> +#define QSERDES_V3_660_COM_CLK_ENABLE1			0x038
> +#define QSERDES_V3_660_COM_SYS_CLK_CTRL			0x03c
> +#define QSERDES_V3_660_COM_SYSCLK_BUF_ENABLE		0x040
> +#define QSERDES_V3_660_COM_PLL_EN			0x044
> +#define QSERDES_V3_660_COM_PLL_IVCO			0x048
> +#define QSERDES_V3_660_COM_LOCK_CMP1_MODE0		0x04c
> +#define QSERDES_V3_660_COM_LOCK_CMP2_MODE0		0x050
> +#define QSERDES_V3_660_COM_LOCK_CMP3_MODE0		0x054
> +#define QSERDES_V3_660_COM_LOCK_CMP1_MODE1		0x058
> +#define QSERDES_V3_660_COM_LOCK_CMP2_MODE1		0x05c
> +#define QSERDES_V3_660_COM_LOCK_CMP3_MODE1		0x060
> +#define QSERDES_V3_660_COM_CMD_RSVD0			0x064
> +#define QSERDES_V3_660_COM_EP_CLOCK_DETECT_CTRL		0x068
> +#define QSERDES_V3_660_COM_SYSCLK_DET_COMP_STATUS	0x06c
> +#define QSERDES_V3_660_COM_BG_TRIM			0x070
> +#define QSERDES_V3_660_COM_CLK_EP_DIV			0x074
> +#define QSERDES_V3_660_COM_CP_CTRL_MODE0		0x078
> +#define QSERDES_V3_660_COM_CP_CTRL_MODE1		0x07c
> +#define QSERDES_V3_660_COM_CMN_RSVD1			0x080
> +#define QSERDES_V3_660_COM_PLL_RCTRL_MODE0		0x084
> +#define QSERDES_V3_660_COM_PLL_RCTRL_MODE1		0x088
> +#define QSERDES_V3_660_COM_CMN_RSVD2			0x08c
> +#define QSERDES_V3_660_COM_PLL_CCTRL_MODE0		0x090
> +#define QSERDES_V3_660_COM_PLL_CCTRL_MODE1		0x094
> +#define QSERDES_V3_660_COM_CMN_RSVD3			0x098
> +#define QSERDES_V3_660_COM_PLL_CNTRL			0x09c
> +#define QSERDES_V3_660_COM_PHASE_SEL_CTRL		0x0a0
> +#define QSERDES_V3_660_COM_PHASE_SEL_DC			0x0a4
> +#define QSERDES_V3_660_COM_BIAS_EN_CTRL_BY_PSM		0x0a8
> +#define QSERDES_V3_660_COM_SYSCLK_EN_SEL		0x0ac
> +#define QSERDES_V3_660_COM_CML_SYSCLK_SEL		0x0b0
> +#define QSERDES_V3_660_COM_RESETSM_CNTRL		0x0b4
> +#define QSERDES_V3_660_COM_RESETSM_CNTRL2		0x0b8
> +#define QSERDES_V3_660_COM_RESTRIM_CTRL			0x0bc
> +#define QSERDES_V3_660_COM_RESTRIM_CTRL2		0x0c0
> +#define QSERDES_V3_660_COM_LOCK_CMP_EN			0x0c8
> +#define QSERDES_V3_660_COM_LOCK_CMP_CFG			0x0cc
> +#define QSERDES_V3_660_COM_DEC_START_MODE0		0x0d0
> +#define QSERDES_V3_660_COM_DEC_START_MODE1		0x0d4
> +#define QSERDES_V3_660_COM_VCOCAL_DEADMAN_CTRL		0x0d8
> +#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0	0x0dc
> +#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0	0x0e0
> +#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0	0x0e4
> +#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1	0x0e8
> +#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1	0x0ec
> +#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1	0x0f0
> +#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL1		0x0f4
> +#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL2		0x0f8
> +#define QSERDES_V3_660_COM_CMN_RSVD4			0x0fc
> +#define QSERDES_V3_660_COM_INTEGLOOP_INITVAL		0x100
> +#define QSERDES_V3_660_COM_INTEGLOOP_EN			0x104
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0	0x108
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0	0x10c
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1	0x110
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1	0x114
> +#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL1		0x118
> +#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL2		0x11c
> +#define QSERDES_V3_660_COM_RES_TRIM_CONTROL2		0x120
> +#define QSERDES_V3_660_COM_VCO_TUNE_CTRL		0x124
> +#define QSERDES_V3_660_COM_VCO_TUNE_MAP			0x128
> +#define QSERDES_V3_660_COM_VCO_TUNE1_MODE0		0x12c
> +#define QSERDES_V3_660_COM_VCO_TUNE2_MODE0		0x130
> +#define QSERDES_V3_660_COM_VCO_TUNE1_MODE1		0x134
> +#define QSERDES_V3_660_COM_VCO_TUNE2_MODE1		0x138
> +#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL1		0x13c
> +#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL2		0x140
> +#define QSERDES_V3_660_COM_VCO_TUNE_TIMER1		0x144
> +#define QSERDES_V3_660_COM_VCO_TUNE_TIMER2		0x148
> +#define QSERDES_V3_660_COM_SAR				0x14c
> +#define QSERDES_V3_660_COM_SAR_CLK			0x150
> +#define QSERDES_V3_660_COM_SAR_CODE_OUT_STATUS		0x154
> +#define QSERDES_V3_660_COM_SAR_CODE_READY_STATUS	0x158
> +#define QSERDES_V3_660_COM_CMN_STATUS			0x15c
> +#define QSERDES_V3_660_COM_RESET_SM_STATUS		0x160
> +#define QSERDES_V3_660_COM_RESTRIM_CODE_STATUS		0x164
> +#define QSERDES_V3_660_COM_PLLCAL_CODE1_STATUS		0x168
> +#define QSERDES_V3_660_COM_PLLCAL_CODE2_STATUS		0x16c
> +#define QSERDES_V3_660_COM_BG_CTRL			0x170
> +#define QSERDES_V3_660_COM_CLK_SELECT			0x174
> +#define QSERDES_V3_660_COM_HSCLK_SEL			0x178
> +#define QSERDES_V3_660_COM_INTEGLOOP_BINCODE_STATUS	0x17c
> +#define QSERDES_V3_660_COM_PLL_ANALOG			0x180
> +#define QSERDES_V3_660_COM_CORECLK_DIV			0x184
> +#define QSERDES_V3_660_COM_SW_RESET			0x188
> +#define QSERDES_V3_660_COM_CORE_CLK_EN			0x18c
> +#define QSERDES_V3_660_COM_C_READY_STATUS		0x190
> +#define QSERDES_V3_660_COM_CMN_CONFIG			0x194
> +#define QSERDES_V3_660_COM_CMN_RATE_OVERRIDE		0x198
> +#define QSERDES_V3_660_COM_SVS_MODE_CLK_SEL		0x19c
> +#define QSERDES_V3_660_COM_DEBUG_BUS0			0x1a0
> +#define QSERDES_V3_660_COM_DEBUG_BUS1			0x1a4
> +#define QSERDES_V3_660_COM_DEBUG_BUS2			0x1a8
> +#define QSERDES_V3_660_COM_DEBUG_BUS3			0x1ac
> +#define QSERDES_V3_660_COM_DEBUG_BUS_SEL		0x1b0
> +#define QSERDES_V3_660_COM_CMN_MISC1			0x1b4
> +#define QSERDES_V3_660_COM_CORECLK_DIV_MODE1		0x1bc
> +#define QSERDES_V3_660_COM_CMN_RSVD5			0x1c0

why are these registers 660 specific and not V3 like we have for
other generations..? Quick looks with V3 regs tells me that seem
similar....

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 06:05:09 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:35:09 +0530
Subject: [PATCH v2 1/6] dt-bindings: phy: qcom,qmp: Add IPQ6018 USB3 PHY
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <YQ0zhaTVI8KVNpVR@matsya>

On 04-08-21, 17:05, Baruch Siach wrote:
> Add compatible string for USB3 PHY in Qualcomm IPQ6018 SoC.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 06:05:23 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:35:23 +0530
Subject: [PATCH v2 2/6] phy: qcom-qmp: add USB3 PHY support for IPQ6018
In-Reply-To: <6eec7ef4ecd1e8360ebe8e425151121684e997ed.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <6eec7ef4ecd1e8360ebe8e425151121684e997ed.1628085910.git.baruch@tkos.co.il>
Message-ID: <YQ0zk44peRTsbLnu@matsya>

On 04-08-21, 17:05, Baruch Siach wrote:
> Initialization is identical to the IPQ8074 USB3 PHY.

Applied, thanks

-- 
~Vinod


From ulf.hansson at linaro.org  Fri Aug  6 06:06:00 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri, 6 Aug 2021 15:06:00 +0200
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <20210730063309.8194-3-rashmi.a@intel.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
Message-ID: <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>

On Fri, 30 Jul 2021 at 08:33, <rashmi.a at intel.com> wrote:
>
> From: Rashmi A <rashmi.a at intel.com>
>
> Intel Thunder Bay SoC eMMC controller is based on Arasan
> eMMC 5.1 host controller IP
>
> Signed-off-by: Rashmi A <rashmi.a at intel.com>
> Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>

Rashmi, is it safe to apply this separately from the phy driver/dt
changes? Then I can queue this via my mmc tree, if you like.

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci-of-arasan.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
> index 839965f7c717..6f202fb7a546 100644
> --- a/drivers/mmc/host/sdhci-of-arasan.c
> +++ b/drivers/mmc/host/sdhci-of-arasan.c
> @@ -185,6 +185,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {
>         .hiword_update = false,
>  };
>
> +static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = {
> +       .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
> +       .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
> +       .support64b = { .reg = 0x4, .width = 1, .shift = 24 },
> +       .hiword_update = false,
> +};
> +
>  static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {
>         .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
>         .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
> @@ -430,6 +437,15 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {
>                         SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
>  };
>
> +static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = {
> +       .ops = &sdhci_arasan_cqe_ops,
> +       .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
> +       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
> +               SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
> +               SDHCI_QUIRK2_STOP_WITH_TC |
> +               SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400,
> +};
> +
>  #ifdef CONFIG_PM_SLEEP
>  /**
>   * sdhci_arasan_suspend - Suspend method for the driver
> @@ -1098,6 +1114,12 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {
>         .clk_ops = &arasan_clk_ops,
>  };
>
> +static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data = {
> +       .soc_ctl_map = &thunderbay_soc_ctl_map,
> +       .pdata = &sdhci_arasan_thunderbay_pdata,
> +       .clk_ops = &arasan_clk_ops,
> +};
> +
>  static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
>         .ops = &sdhci_arasan_cqe_ops,
>         .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
> @@ -1231,6 +1253,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
>                 .compatible = "intel,keembay-sdhci-5.1-sdio",
>                 .data = &intel_keembay_sdio_data,
>         },
> +       {
> +               .compatible = "intel,thunderbay-sdhci-5.1",
> +               .data = &sdhci_arasan_thunderbay_data,
> +       },
>         /* Generic compatible below here */
>         {
>                 .compatible = "arasan,sdhci-8.9a",
> @@ -1582,7 +1608,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
>
>         if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
>             of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
> -           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
> +           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") ||
> +           of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1")) {
>                 sdhci_arasan_update_clockmultiplier(host, 0x0);
>                 sdhci_arasan_update_support64b(host, 0x0);
>
> --
> 2.17.1
>


From vkoul at kernel.org  Fri Aug  6 06:17:37 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:47:37 +0530
Subject: [PATCH v9 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
In-Reply-To: <90aada2f51b58c162e199faf823ba887e50f1dc6.1628092716.git.mchehab+huawei@kernel.org>
References: <cover.1628092716.git.mchehab+huawei@kernel.org>
 <90aada2f51b58c162e199faf823ba887e50f1dc6.1628092716.git.mchehab+huawei@kernel.org>
Message-ID: <YQ02cc1dtqQBlT4/@matsya>

On 04-08-21, 18:02, Mauro Carvalho Chehab wrote:

> +/* define ie,oe cfg */
> +#define IO_IE_EN_HARD_BYPASS         (0x1 << 27)
> +#define IO_OE_EN_HARD_BYPASS         (0x1 << 11)
> +#define IO_HARD_CTRL_DEBOUNCE_BYPASS (0x1 << 10)
> +#define IO_OE_GT_MODE                (0x2 << 7)
> +#define DEBOUNCE_WAITCFG_IN          (0xf << 20)
> +#define DEBOUNCE_WAITCFG_OUT         (0xf << 13)

Why not use BIT() or GENMASK for these?

> +/* Registers in PCIePHY */
> +static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy,
> +					 u32 val, u32 reg)
> +{
> +	writel(val, phy->base + 0x40000 + reg);

magic 0x40000?

> +}
> +
> +static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
> +{
> +	return readl(phy->base + 0x40000 + reg);
> +}
> +
> +static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
> +						u32 val, u32 reg)
> +{
> +	writel(val, phy->base + reg * 4);

why * 4 ..?

> +static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
> +{
> +	u32 val;
> +
> +	val = kirin_apb_natural_phy_readl(phy, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
> +
> +	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
> +		val &= (~0xf00);
> +		val |= (phy->eye_param[1] << 8) | (0x1 << 12);
> +	}

again too many magic numbers, Do check FIELD_GET/PREP macros for these?
-- 
~Vinod


From iskren.chernev at gmail.com  Fri Aug  6 09:09:13 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Fri, 6 Aug 2021 19:09:13 +0300
Subject: [PATCH v1 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <YQ0xrgDjxXeNecAS@matsya>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
 <20210805091727.942471-3-iskren.chernev@gmail.com> <YQ0xrgDjxXeNecAS@matsya>
Message-ID: <86fcdc11-9f2c-0aa0-ebab-a26fa9ac2aca@gmail.com>



On 8/6/21 3:57 PM, Vinod Koul wrote:
> On 05-08-21, 12:17, Iskren Chernev wrote:
> 
>> +/* Only for QMP V3 660 PHY - QSERDES COM registers*/
>> +#define QSERDES_V3_660_COM_ATB_SEL1			0x000
>> +#define QSERDES_V3_660_COM_ATB_SEL2			0x004
>> +#define QSERDES_V3_660_COM_FREQ_UPDATE			0x008
>> +#define QSERDES_V3_660_COM_BG_TIMER			0x00c
>> +#define QSERDES_V3_660_COM_SSC_EN_CENTER		0x010
>> +#define QSERDES_V3_660_COM_SSC_ADJ_PER1			0x014
>> +#define QSERDES_V3_660_COM_SSC_ADJ_PER2			0x018
>> +#define QSERDES_V3_660_COM_SSC_PER1			0x01c
>> +#define QSERDES_V3_660_COM_SSC_PER2			0x020
>> +#define QSERDES_V3_660_COM_SSC_STEP_SIZE1		0x024
>> +#define QSERDES_V3_660_COM_SSC_STEP_SIZE2		0x028
>> +#define QSERDES_V3_660_COM_POST_DIV			0x02c
>> +#define QSERDES_V3_660_COM_POST_DIV_MUX			0x030
>> +#define QSERDES_V3_660_COM_BIAS_EN_CLKBUFLR_EN		0x034
>> +#define QSERDES_V3_660_COM_CLK_ENABLE1			0x038
>> +#define QSERDES_V3_660_COM_SYS_CLK_CTRL			0x03c
>> +#define QSERDES_V3_660_COM_SYSCLK_BUF_ENABLE		0x040
>> +#define QSERDES_V3_660_COM_PLL_EN			0x044
>> +#define QSERDES_V3_660_COM_PLL_IVCO			0x048
>> +#define QSERDES_V3_660_COM_LOCK_CMP1_MODE0		0x04c
>> +#define QSERDES_V3_660_COM_LOCK_CMP2_MODE0		0x050
>> +#define QSERDES_V3_660_COM_LOCK_CMP3_MODE0		0x054
>> +#define QSERDES_V3_660_COM_LOCK_CMP1_MODE1		0x058
>> +#define QSERDES_V3_660_COM_LOCK_CMP2_MODE1		0x05c
>> +#define QSERDES_V3_660_COM_LOCK_CMP3_MODE1		0x060
>> +#define QSERDES_V3_660_COM_CMD_RSVD0			0x064
>> +#define QSERDES_V3_660_COM_EP_CLOCK_DETECT_CTRL		0x068
>> +#define QSERDES_V3_660_COM_SYSCLK_DET_COMP_STATUS	0x06c
>> +#define QSERDES_V3_660_COM_BG_TRIM			0x070
>> +#define QSERDES_V3_660_COM_CLK_EP_DIV			0x074
>> +#define QSERDES_V3_660_COM_CP_CTRL_MODE0		0x078
>> +#define QSERDES_V3_660_COM_CP_CTRL_MODE1		0x07c
>> +#define QSERDES_V3_660_COM_CMN_RSVD1			0x080
>> +#define QSERDES_V3_660_COM_PLL_RCTRL_MODE0		0x084
>> +#define QSERDES_V3_660_COM_PLL_RCTRL_MODE1		0x088
>> +#define QSERDES_V3_660_COM_CMN_RSVD2			0x08c
>> +#define QSERDES_V3_660_COM_PLL_CCTRL_MODE0		0x090
>> +#define QSERDES_V3_660_COM_PLL_CCTRL_MODE1		0x094
>> +#define QSERDES_V3_660_COM_CMN_RSVD3			0x098
>> +#define QSERDES_V3_660_COM_PLL_CNTRL			0x09c
>> +#define QSERDES_V3_660_COM_PHASE_SEL_CTRL		0x0a0
>> +#define QSERDES_V3_660_COM_PHASE_SEL_DC			0x0a4
>> +#define QSERDES_V3_660_COM_BIAS_EN_CTRL_BY_PSM		0x0a8
>> +#define QSERDES_V3_660_COM_SYSCLK_EN_SEL		0x0ac
>> +#define QSERDES_V3_660_COM_CML_SYSCLK_SEL		0x0b0
>> +#define QSERDES_V3_660_COM_RESETSM_CNTRL		0x0b4
>> +#define QSERDES_V3_660_COM_RESETSM_CNTRL2		0x0b8
>> +#define QSERDES_V3_660_COM_RESTRIM_CTRL			0x0bc
>> +#define QSERDES_V3_660_COM_RESTRIM_CTRL2		0x0c0
>> +#define QSERDES_V3_660_COM_LOCK_CMP_EN			0x0c8
>> +#define QSERDES_V3_660_COM_LOCK_CMP_CFG			0x0cc
>> +#define QSERDES_V3_660_COM_DEC_START_MODE0		0x0d0
>> +#define QSERDES_V3_660_COM_DEC_START_MODE1		0x0d4
>> +#define QSERDES_V3_660_COM_VCOCAL_DEADMAN_CTRL		0x0d8
>> +#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0	0x0dc
>> +#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0	0x0e0
>> +#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0	0x0e4
>> +#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1	0x0e8
>> +#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1	0x0ec
>> +#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1	0x0f0
>> +#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL1		0x0f4
>> +#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL2		0x0f8
>> +#define QSERDES_V3_660_COM_CMN_RSVD4			0x0fc
>> +#define QSERDES_V3_660_COM_INTEGLOOP_INITVAL		0x100
>> +#define QSERDES_V3_660_COM_INTEGLOOP_EN			0x104
>> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0	0x108
>> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0	0x10c
>> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1	0x110
>> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1	0x114
>> +#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL1		0x118
>> +#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL2		0x11c
>> +#define QSERDES_V3_660_COM_RES_TRIM_CONTROL2		0x120
>> +#define QSERDES_V3_660_COM_VCO_TUNE_CTRL		0x124
>> +#define QSERDES_V3_660_COM_VCO_TUNE_MAP			0x128
>> +#define QSERDES_V3_660_COM_VCO_TUNE1_MODE0		0x12c
>> +#define QSERDES_V3_660_COM_VCO_TUNE2_MODE0		0x130
>> +#define QSERDES_V3_660_COM_VCO_TUNE1_MODE1		0x134
>> +#define QSERDES_V3_660_COM_VCO_TUNE2_MODE1		0x138
>> +#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL1		0x13c
>> +#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL2		0x140
>> +#define QSERDES_V3_660_COM_VCO_TUNE_TIMER1		0x144
>> +#define QSERDES_V3_660_COM_VCO_TUNE_TIMER2		0x148
>> +#define QSERDES_V3_660_COM_SAR				0x14c
>> +#define QSERDES_V3_660_COM_SAR_CLK			0x150
>> +#define QSERDES_V3_660_COM_SAR_CODE_OUT_STATUS		0x154
>> +#define QSERDES_V3_660_COM_SAR_CODE_READY_STATUS	0x158
>> +#define QSERDES_V3_660_COM_CMN_STATUS			0x15c
>> +#define QSERDES_V3_660_COM_RESET_SM_STATUS		0x160
>> +#define QSERDES_V3_660_COM_RESTRIM_CODE_STATUS		0x164
>> +#define QSERDES_V3_660_COM_PLLCAL_CODE1_STATUS		0x168
>> +#define QSERDES_V3_660_COM_PLLCAL_CODE2_STATUS		0x16c
>> +#define QSERDES_V3_660_COM_BG_CTRL			0x170
>> +#define QSERDES_V3_660_COM_CLK_SELECT			0x174
>> +#define QSERDES_V3_660_COM_HSCLK_SEL			0x178
>> +#define QSERDES_V3_660_COM_INTEGLOOP_BINCODE_STATUS	0x17c
>> +#define QSERDES_V3_660_COM_PLL_ANALOG			0x180
>> +#define QSERDES_V3_660_COM_CORECLK_DIV			0x184
>> +#define QSERDES_V3_660_COM_SW_RESET			0x188
>> +#define QSERDES_V3_660_COM_CORE_CLK_EN			0x18c
>> +#define QSERDES_V3_660_COM_C_READY_STATUS		0x190
>> +#define QSERDES_V3_660_COM_CMN_CONFIG			0x194
>> +#define QSERDES_V3_660_COM_CMN_RATE_OVERRIDE		0x198
>> +#define QSERDES_V3_660_COM_SVS_MODE_CLK_SEL		0x19c
>> +#define QSERDES_V3_660_COM_DEBUG_BUS0			0x1a0
>> +#define QSERDES_V3_660_COM_DEBUG_BUS1			0x1a4
>> +#define QSERDES_V3_660_COM_DEBUG_BUS2			0x1a8
>> +#define QSERDES_V3_660_COM_DEBUG_BUS3			0x1ac
>> +#define QSERDES_V3_660_COM_DEBUG_BUS_SEL		0x1b0
>> +#define QSERDES_V3_660_COM_CMN_MISC1			0x1b4
>> +#define QSERDES_V3_660_COM_CORECLK_DIV_MODE1		0x1bc
>> +#define QSERDES_V3_660_COM_CMN_RSVD5			0x1c0
> 
> why are these registers 660 specific and not V3 like we have for
> other generations..? Quick looks with V3 regs tells me that seem
> similar....
>

Well, I looked at them for a long time and the only thing that is similar
are the first few QSERDES registers from COM_ATB_SEL1=0x000 to
COM_BIAS_EN_CLKBUFLR_EN=0x034. Everything else is different. So I can re-use
the V3 for the similar regs, but they are 10%, so I figured instead of combing
through all of the sequences to save 10% of the constants and make it slightly
less readable just use new constants.

Let me know if I should reuse the 14 regs from V3.

Regards,
Iskren


From robh at kernel.org  Fri Aug  6 09:23:35 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 10:23:35 -0600
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <20210805095848.464cf85c@coco.lan>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan> <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan> <20210805095848.464cf85c@coco.lan>
Message-ID: <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>

On Thu, Aug 5, 2021 at 1:58 AM Mauro Carvalho Chehab
<mchehab+huawei at kernel.org> wrote:
>
> Em Thu, 5 Aug 2021 09:46:12 +0200
> Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:
>
> > Em Wed, 4 Aug 2021 10:28:53 -0600
> > Rob Herring <robh at kernel.org> escreveu:
> >
> > > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:
> > > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > > Rob Herring <robh+dt at kernel.org> escreveu:
> > > >
> > > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > > <mchehab+huawei at kernel.org> wrote:
> > > > > >
> > > > > > Hi Rob,
> > > > > >
> > > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > > corresponding PHY.
> > > > > >
> > > > > > It is identical to v2, except by:
> > > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > > >         +          pcie at 7,0 { // Lane 6: Ethernet
> > > > >
> > > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > > devices? If you don't, then something is wrong still in the topology
> > > > > or the PCI core is failing to set the DT node pointer in struct
> > > > > device. Though you don't rely on that currently, we want the topology
> > > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > > powerpc relied on this.
> > > > >
> > > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > > could have a tool that generates the DT structure based on the PCI
> > > > > topology.
> > > >
> > > > The of_node node link is on those places:
> > > >
> > > >   $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > >   /sys/devices/platform/soc/f4000000.pcie/of_node
> > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> > >
> > > Looks like we're missing some...
> > >
> > > It's not immediately obvious to me what's wrong here. Only the root
> > > bus is getting it's DT node set. The relevant code is pci_scan_device(),
> > > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try
> > > to reproduce and debug it.
> >
> > I added a printk on both pci_set_*of_node() functions:
> >
> >       [    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> >       [    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> >       [    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> >       [    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> >       [    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> >       [    5.059263]  (null): pci_set_of_node: of_node: (null)
> >       [    5.085552]  (null): pci_set_of_node: of_node: (null)
> >       [    5.112073]  (null): pci_set_of_node: of_node: (null)
> >       [    5.138320]  (null): pci_set_of_node: of_node: (null)
> >       [    5.164673]  (null): pci_set_of_node: of_node: (null)
> >       [    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> >       [    5.240539]  (null): pci_set_of_node: of_node: (null)
> >       [    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> >       [    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> >       [    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> >       [    5.345516]  (null): pci_set_of_node: of_node: (null)
> >       [    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
>
> The enclosed patch makes the above a clearer:
>
>         [    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
>         [    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
>         [    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
>         [    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
>         [    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)

I believe the issue is we need another bridge node in the DT
hierarchy. What we have is:

Bus 0 is node /soc/pcie at f4000000
Bus 1 is device 0 on bus 0 is node /soc/pcie at f4000000/pcie at 0,0
Bus 2 is device 0 on bus 1 in node ... whoops, there's no device 0
under /soc/pcie at f4000000/pcie at 0,0

So we need the hierarchy to be: /soc/pcie at f4000000/pcie at 0/pcie at 0/pcie@{1,5,7}

Rob


From robh+dt at kernel.org  Fri Aug  6 12:47:50 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 13:47:50 -0600
Subject: [PATCH v2 1/6] PCI: dwc: tegra: move GEN3_RELATED DBI register to
 common header
In-Reply-To: <c15ac1443ec765e32a2801241dcd8e924abc769b.1620203062.git.baruch@tkos.co.il>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <c15ac1443ec765e32a2801241dcd8e924abc769b.1620203062.git.baruch@tkos.co.il>
Message-ID: <CAL_Jsq+SBRP4n-0Q9RShxj2Od-EGpBURNUZo8fLnscOY-m7SmA@mail.gmail.com>

On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> These are common dwc macros that will be used for other platforms.
>
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  drivers/pci/controller/dwc/pcie-designware.h | 6 ++++++
>  drivers/pci/controller/dwc/pcie-tegra194.c   | 6 ------
>  2 files changed, 6 insertions(+), 6 deletions(-)

Reviewed-by: Rob Herring <robh at kernel.org>


From robh+dt at kernel.org  Fri Aug  6 12:59:44 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 13:59:44 -0600
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
Message-ID: <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>

On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>
> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> platform.
>
> The code is based on downstream Codeaurora kernel v5.4. Split out the
> DBI registers access part from .init into .post_init. DBI registers are
> only accessible after phy_power_on().
>
> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
> v2:
>   * Drop ATU configuration; rely on common code instead
>
>   * Use more common register macros
>
>   * Use bulk clk and reset APIs
> ---
>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>  drivers/pci/controller/dwc/pcie-qcom.c       | 150 +++++++++++++++++++
>  2 files changed, 151 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index ceb359b6e6a6..346462c74a3e 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -76,6 +76,7 @@
>
>  #define GEN3_RELATED_OFF                       0x890
>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL   BIT(0)
> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS    BIT(13)
>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 8a7a300163e5..93766aee3e7c 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -52,6 +52,10 @@
>  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
> +#define AHB_CLK_EN                             BIT(0)
> +#define MSTR_AXI_CLK_EN                                BIT(1)
> +#define BYPASS                                 BIT(4)
> +
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
>  #define PCIE20_PARF_LTSSM                      0x1B0
> @@ -94,6 +98,12 @@
>  #define SLV_ADDR_SPACE_SZ                      0x10000000
>
>  #define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
> +#define PCIE_CAP_CURR_DEEMPHASIS               BIT(16)

Isn't this a standard register field?

> +#define SPEED_GEN1                             0x1
> +#define SPEED_GEN2                             0x2
> +#define SPEED_GEN3                             0x3

And these?

There's already some common DWC code for setting the link speed.

> +#define AXI_CLK_RATE                           200000000
> +#define RCHNG_CLK_RATE                         100000000
>
>  #define DEVICE_TYPE_RC                         0x4
>
> @@ -168,6 +178,11 @@ struct qcom_pcie_resources_2_7_0 {
>         struct clk *pipe_clk;
>  };
>
> +struct qcom_pcie_resources_2_9_0 {
> +       struct clk_bulk_data clks[5];
> +       struct reset_control *rst;
> +};
> +
>  union qcom_pcie_resources {
>         struct qcom_pcie_resources_1_0_0 v1_0_0;
>         struct qcom_pcie_resources_2_1_0 v2_1_0;
> @@ -175,6 +190,7 @@ union qcom_pcie_resources {
>         struct qcom_pcie_resources_2_3_3 v2_3_3;
>         struct qcom_pcie_resources_2_4_0 v2_4_0;
>         struct qcom_pcie_resources_2_7_0 v2_7_0;
> +       struct qcom_pcie_resources_2_9_0 v2_9_0;
>  };
>
>  struct qcom_pcie;
> @@ -1266,6 +1282,130 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
>         clk_disable_unprepare(res->pipe_clk);
>  }
>
> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +       struct dw_pcie *pci = pcie->pci;
> +       struct device *dev = pci->dev;
> +       int ret;
> +
> +       res->clks[0].id = "iface";
> +       res->clks[1].id = "axi_m";
> +       res->clks[2].id = "axi_s";
> +       res->clks[3].id = "axi_bridge";
> +       res->clks[4].id = "rchng";
> +
> +       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
> +       if (ret < 0)
> +               return ret;
> +
> +       res->rst = devm_reset_control_array_get_exclusive(dev);
> +       if (IS_ERR(res->rst))
> +               return PTR_ERR(res->rst);
> +
> +       return 0;
> +}
> +
> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +
> +       clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
> +}
> +
> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +       struct device *dev = pcie->pci->dev;
> +       int ret;
> +
> +       ret = reset_control_assert(res->rst);
> +       if (ret) {
> +               dev_err(dev, "reset assert failed (%d)\n", ret);
> +               return ret;
> +       }
> +
> +       usleep_range(2000, 2500);
> +
> +       ret = reset_control_deassert(res->rst);
> +       if (ret) {
> +               dev_err(dev, "reset deassert failed (%d)\n", ret);
> +               return ret;
> +       }
> +
> +       /*
> +        * Don't have a way to see if the reset has completed.
> +        * Wait for some time.
> +        */
> +       usleep_range(2000, 2500);
> +
> +       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
> +       if (ret)
> +               goto err_reset;
> +
> +       return 0;
> +
> +       /*
> +        * Not checking for failure, will anyway return
> +        * the original failure in 'ret'.
> +        */
> +err_reset:
> +       reset_control_assert(res->rst);
> +
> +       return ret;
> +}
> +
> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct dw_pcie *pci = pcie->pci;
> +       u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> +       u32 val;
> +       int i;
> +
> +       writel(SLV_ADDR_SPACE_SZ,
> +               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> +
> +       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> +       val &= ~BIT(0);
> +       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> +
> +       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> +
> +       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> +       writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> +               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> +       writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> +               | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> +               pci->dbi_base + GEN3_RELATED_OFF);
> +
> +       writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> +               | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> +               AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> +               pcie->parf + PCIE20_PARF_SYS_CTRL);
> +
> +       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> +
> +       dw_pcie_dbi_ro_wr_en(pci);
> +       writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> +
> +       /* Configure PCIe link capabilities for ASPM */
> +       val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +       val &= ~PCI_EXP_LNKCAP_ASPMS;
> +       writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +
> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> +                       PCI_EXP_DEVCTL2);
> +
> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);

Doesn't this overwrite the prior register write?

> +
> +       for (i = 0;i < 256;i++)
> +               writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> +                               + (4 * i));
> +
> +       return 0;
> +}
> +
>  static int qcom_pcie_link_up(struct dw_pcie *pci)
>  {
>         u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> @@ -1456,6 +1596,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
>         .config_sid = qcom_pcie_config_sid_sm8250,
>  };
>
> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
> +static const struct qcom_pcie_ops ops_2_9_0 = {
> +       .get_resources = qcom_pcie_get_resources_2_9_0,
> +       .init = qcom_pcie_init_2_9_0,
> +       .post_init = qcom_pcie_post_init_2_9_0,
> +       .deinit = qcom_pcie_deinit_2_9_0,
> +       .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> +};
> +
>  static const struct dw_pcie_ops dw_pcie_ops = {
>         .link_up = qcom_pcie_link_up,
>         .start_link = qcom_pcie_start_link,
> @@ -1555,6 +1704,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>         { .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
>         { .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
>         { .compatible = "qcom,pcie-sm8250", .data = &ops_1_9_0 },
> +       { .compatible = "qcom,pcie-ipq6018", .data = &ops_2_9_0 },
>         { }
>  };
>
> --
> 2.30.2
>


From jiaxun.yang at flygoat.com  Fri Aug  6 20:06:12 2021
From: jiaxun.yang at flygoat.com (Jiaxun Yang)
Date: Sat, 7 Aug 2021 11:06:12 +0800
Subject: [PATCH v4 0/9] MIPS: Migrate pistachio to generic kernel
In-Reply-To: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
References: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
Message-ID: <1bb80cdf-f7d5-f99f-a4f3-635552df916b@flygoat.com>



? 2021/7/23 ??10:25, Jiaxun Yang ??:
> I'm lucky enough to get a Creator CI40 board from dusts.
> This patchset move it to gerneic kernel to reduce maintenance burden.
> It have been tested with SD Card boot.

Hi Thomas,

For the series, the pinctrl one have been applied by subsystem 
maintainer and
rests have been acked by subsystem maintainers, could you please apply them
to MIPS tree?

Thanks.

- Jiaxun

>
> --
> v2: Minor fixes
> v3: Typo fixes and 0day testbot warning fix (Thanks to Sergei!)
> v4: 01.org warning fix
>
> Jiaxun Yang (9):
>    MIPS: generic: Allow generating FIT image for Marduk board
>    MIPS: DTS: Pistachio add missing cpc and cdmm
>    clk: pistachio: Make it selectable for generic MIPS kernel
>    clocksource/drivers/pistachio: Make it selectable for MIPS
>    phy: pistachio-usb: Depend on MIPS || COMPILE_TEST
>    pinctrl: pistachio: Make it as an option
>    MIPS: config: generic: Add config for Marduk board
>    MIPS: Retire MACH_PISTACHIO
>    MIPS: Make a alias for pistachio_defconfig
>
>   arch/mips/Kbuild.platforms                    |   1 -
>   arch/mips/Kconfig                             |  30 --
>   arch/mips/Makefile                            |   3 +
>   arch/mips/boot/dts/Makefile                   |   2 +-
>   arch/mips/boot/dts/img/Makefile               |   3 +-
>   arch/mips/boot/dts/img/pistachio.dtsi         |  10 +
>   arch/mips/configs/generic/board-marduk.config |  53 +++
>   arch/mips/configs/pistachio_defconfig         | 316 ------------------
>   arch/mips/generic/Kconfig                     |   6 +
>   arch/mips/generic/Platform                    |   1 +
>   arch/mips/generic/board-marduk.its.S          |  22 ++
>   arch/mips/pistachio/Kconfig                   |  14 -
>   arch/mips/pistachio/Makefile                  |   2 -
>   arch/mips/pistachio/Platform                  |   6 -
>   arch/mips/pistachio/init.c                    | 125 -------
>   arch/mips/pistachio/irq.c                     |  24 --
>   arch/mips/pistachio/time.c                    |  55 ---
>   drivers/clk/Kconfig                           |   1 +
>   drivers/clk/Makefile                          |   2 +-
>   drivers/clk/pistachio/Kconfig                 |   8 +
>   drivers/clocksource/Kconfig                   |   3 +-
>   drivers/phy/Kconfig                           |   2 +-
>   drivers/pinctrl/Kconfig                       |   5 +-
>   23 files changed, 114 insertions(+), 580 deletions(-)
>   create mode 100644 arch/mips/configs/generic/board-marduk.config
>   delete mode 100644 arch/mips/configs/pistachio_defconfig
>   create mode 100644 arch/mips/generic/board-marduk.its.S
>   delete mode 100644 arch/mips/pistachio/Kconfig
>   delete mode 100644 arch/mips/pistachio/Makefile
>   delete mode 100644 arch/mips/pistachio/Platform
>   delete mode 100644 arch/mips/pistachio/init.c
>   delete mode 100644 arch/mips/pistachio/irq.c
>   delete mode 100644 arch/mips/pistachio/time.c
>   create mode 100644 drivers/clk/pistachio/Kconfig
>



From tsbogend at alpha.franken.de  Sat Aug  7 02:28:19 2021
From: tsbogend at alpha.franken.de (Thomas Bogendoerfer)
Date: Sat, 7 Aug 2021 11:28:19 +0200
Subject: [PATCH v4 0/9] MIPS: Migrate pistachio to generic kernel
In-Reply-To: <1bb80cdf-f7d5-f99f-a4f3-635552df916b@flygoat.com>
References: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
 <1bb80cdf-f7d5-f99f-a4f3-635552df916b@flygoat.com>
Message-ID: <20210807092819.GA4506@alpha.franken.de>

On Sat, Aug 07, 2021 at 11:06:12AM +0800, Jiaxun Yang wrote:
> 
> 
> ? 2021/7/23 ??10:25, Jiaxun Yang ??:
> > I'm lucky enough to get a Creator CI40 board from dusts.
> > This patchset move it to gerneic kernel to reduce maintenance burden.
> > It have been tested with SD Card boot.
> 
> Hi Thomas,
> 
> For the series, the pinctrl one have been applied by subsystem maintainer
> and
> rests have been acked by subsystem maintainers, could you please apply them
> to MIPS tree?

sure that's my plan.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]


From vkoul at kernel.org  Sun Aug  8 21:48:11 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 9 Aug 2021 10:18:11 +0530
Subject: [PATCH v1 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <86fcdc11-9f2c-0aa0-ebab-a26fa9ac2aca@gmail.com>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
 <20210805091727.942471-3-iskren.chernev@gmail.com>
 <YQ0xrgDjxXeNecAS@matsya>
 <86fcdc11-9f2c-0aa0-ebab-a26fa9ac2aca@gmail.com>
Message-ID: <YRCzi9tXsUVi5kHS@matsya>

On 06-08-21, 19:09, Iskren Chernev wrote:
> On 8/6/21 3:57 PM, Vinod Koul wrote:
> > On 05-08-21, 12:17, Iskren Chernev wrote:

> > why are these registers 660 specific and not V3 like we have for
> > other generations..? Quick looks with V3 regs tells me that seem
> > similar....
> >
> 
> Well, I looked at them for a long time and the only thing that is similar
> are the first few QSERDES registers from COM_ATB_SEL1=0x000 to
> COM_BIAS_EN_CLKBUFLR_EN=0x034. Everything else is different. So I can re-use

Is the offset different? I thought all Vn registers across chips do have
same offsets..

> the V3 for the similar regs, but they are 10%, so I figured instead of combing
> through all of the sequences to save 10% of the constants and make it slightly
> less readable just use new constants.
> 
> Let me know if I should reuse the 14 regs from V3.

reuse yes, but would like to understand more why offsets are different,

Can you point me to downstream code reference for this?

-- 
~Vinod


From rashmi.a at intel.com  Sun Aug  8 22:16:09 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Mon, 9 Aug 2021 05:16:09 +0000
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
Message-ID: <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Ulf Hansson <ulf.hansson at linaro.org>
> Sent: Friday, August 6, 2021 6:36 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: linux-drivers-review-request at eclists.intel.com; Michal Simek
> <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Vinod Koul
> <vkoul at kernel.org>; Andy Shevchenko
> <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> support to the arasan eMMC driver
> 
> On Fri, 30 Jul 2021 at 08:33, <rashmi.a at intel.com> wrote:
> >
> > From: Rashmi A <rashmi.a at intel.com>
> >
> > Intel Thunder Bay SoC eMMC controller is based on Arasan eMMC 5.1 host
> > controller IP
> >
> > Signed-off-by: Rashmi A <rashmi.a at intel.com>
> > Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>
> 
> Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> Then I can queue this via my mmc tree, if you like.
No, the phy driver/dt changes must go together with "mmc: sdhci-of-arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver" patch.

Regards
Rashmi
> 
> Kind regards
> Uffe
> 
> > ---
> >  drivers/mmc/host/sdhci-of-arasan.c | 29
> ++++++++++++++++++++++++++++-
> >  1 file changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-arasan.c
> > b/drivers/mmc/host/sdhci-of-arasan.c
> > index 839965f7c717..6f202fb7a546 100644
> > --- a/drivers/mmc/host/sdhci-of-arasan.c
> > +++ b/drivers/mmc/host/sdhci-of-arasan.c
> > @@ -185,6 +185,13 @@ static const struct sdhci_arasan_soc_ctl_map
> intel_lgm_sdxc_soc_ctl_map = {
> >         .hiword_update = false,
> >  };
> >
> > +static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = {
> > +       .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
> > +       .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
> > +       .support64b = { .reg = 0x4, .width = 1, .shift = 24 },
> > +       .hiword_update = false,
> > +};
> > +
> >  static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map
> = {
> >         .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
> >         .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, @@
> > -430,6 +437,15 @@ static const struct sdhci_pltfm_data
> sdhci_arasan_cqe_pdata = {
> >                         SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
> >  };
> >
> > +static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = {
> > +       .ops = &sdhci_arasan_cqe_ops,
> > +       .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
> SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
> > +       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
> > +               SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
> > +               SDHCI_QUIRK2_STOP_WITH_TC |
> > +               SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400,
> > +};
> > +
> >  #ifdef CONFIG_PM_SLEEP
> >  /**
> >   * sdhci_arasan_suspend - Suspend method for the driver @@ -1098,6
> > +1114,12 @@ static struct sdhci_arasan_of_data
> sdhci_arasan_generic_data = {
> >         .clk_ops = &arasan_clk_ops,
> >  };
> >
> > +static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data =
> {
> > +       .soc_ctl_map = &thunderbay_soc_ctl_map,
> > +       .pdata = &sdhci_arasan_thunderbay_pdata,
> > +       .clk_ops = &arasan_clk_ops,
> > +};
> > +
> >  static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
> >         .ops = &sdhci_arasan_cqe_ops,
> >         .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | @@ -1231,6
> > +1253,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
> >                 .compatible = "intel,keembay-sdhci-5.1-sdio",
> >                 .data = &intel_keembay_sdio_data,
> >         },
> > +       {
> > +               .compatible = "intel,thunderbay-sdhci-5.1",
> > +               .data = &sdhci_arasan_thunderbay_data,
> > +       },
> >         /* Generic compatible below here */
> >         {
> >                 .compatible = "arasan,sdhci-8.9a", @@ -1582,7 +1608,8
> > @@ static int sdhci_arasan_probe(struct platform_device *pdev)
> >
> >         if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
> >             of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
> > -           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
> > +           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") ||
> > +           of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1"))
> > + {
> >                 sdhci_arasan_update_clockmultiplier(host, 0x0);
> >                 sdhci_arasan_update_support64b(host, 0x0);
> >
> > --
> > 2.17.1
> >

From vkoul at kernel.org  Mon Aug  9 01:41:38 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 9 Aug 2021 14:11:38 +0530
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
Message-ID: <YRDqQvKQ71/824Lu@matsya>

On 09-08-21, 05:16, A, Rashmi wrote:

> > 
> > Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> > Then I can queue this via my mmc tree, if you like.
> No, the phy driver/dt changes must go together with "mmc: sdhci-of-arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver" patch.

Why is that?

What could happen, emmc driver will complain about phy not found and
bail right?

-- 
~Vinod


From rashmi.a at intel.com  Mon Aug  9 04:16:56 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Mon, 9 Aug 2021 11:16:56 +0000
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <YRDqQvKQ71/824Lu@matsya>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <YRDqQvKQ71/824Lu@matsya>
Message-ID: <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: Monday, August 9, 2021 2:12 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>; Michal Simek
> <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Andy Shevchenko
> <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> support to the arasan eMMC driver
> 
> On 09-08-21, 05:16, A, Rashmi wrote:
> 
> > >
> > > Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> > > Then I can queue this via my mmc tree, if you like.
> > No, the phy driver/dt changes must go together with "mmc: sdhci-of-
> arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver"
> patch.
> 
> Why is that?
> 
> What could happen, emmc driver will complain about phy not found and bail
> right?
This is right, but ideally both mmc:phy and mmc: sdhci-of-arasan driver code changes should go together
> 
> --
> ~Vinod


From ulf.hansson at linaro.org  Mon Aug  9 05:13:18 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 9 Aug 2021 14:13:18 +0200
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <YRDqQvKQ71/824Lu@matsya>
 <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
Message-ID: <CAPDyKFp5HcCfsoLgBc=D9RKOrVY2SuV3FKsFCVT2=WaxZBsNiA@mail.gmail.com>

On Mon, 9 Aug 2021 at 13:17, A, Rashmi <rashmi.a at intel.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Vinod Koul <vkoul at kernel.org>
> > Sent: Monday, August 9, 2021 2:12 PM
> > To: A, Rashmi <rashmi.a at intel.com>
> > Cc: Ulf Hansson <ulf.hansson at linaro.org>; Michal Simek
> > <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> > ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> > kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Andy Shevchenko
> > <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> > Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> > <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> > <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> > <adrian.hunter at intel.com>; Vaidya, Mahesh R
> > <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> > <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> > <kenchappa.demakkanavar at intel.com>
> > Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> > support to the arasan eMMC driver
> >
> > On 09-08-21, 05:16, A, Rashmi wrote:
> >
> > > >
> > > > Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> > > > Then I can queue this via my mmc tree, if you like.
> > > No, the phy driver/dt changes must go together with "mmc: sdhci-of-
> > arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver"
> > patch.
> >
> > Why is that?
> >
> > What could happen, emmc driver will complain about phy not found and bail
> > right?
> This is right, but ideally both mmc:phy and mmc: sdhci-of-arasan driver code changes should go together

If patches are well written and can be standalone, we (maintainers)
ideally prefer to queue things on a per subsystem basis, because it's
just easier.

That said, I also noticed that a new compatible string was added,
"intel,thunderbay-sdhci-5.1". This needs to be documented in
Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml, in a separate
patch, preceding $subject patch.

Kind regards
Uffe


From iskren.chernev at gmail.com  Mon Aug  9 07:20:45 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Mon, 9 Aug 2021 17:20:45 +0300
Subject: [PATCH v1 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <YRCzi9tXsUVi5kHS@matsya>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
 <20210805091727.942471-3-iskren.chernev@gmail.com> <YQ0xrgDjxXeNecAS@matsya>
 <86fcdc11-9f2c-0aa0-ebab-a26fa9ac2aca@gmail.com> <YRCzi9tXsUVi5kHS@matsya>
Message-ID: <c780ad2a-2292-6e06-fa89-4c8a5139c253@gmail.com>



On 8/9/21 7:48 AM, Vinod Koul wrote:
> On 06-08-21, 19:09, Iskren Chernev wrote:
>> On 8/6/21 3:57 PM, Vinod Koul wrote:
>>> On 05-08-21, 12:17, Iskren Chernev wrote:
> 
>>> why are these registers 660 specific and not V3 like we have for
>>> other generations..? Quick looks with V3 regs tells me that seem
>>> similar....
>>>
>>
>> Well, I looked at them for a long time and the only thing that is similar
>> are the first few QSERDES registers from COM_ATB_SEL1=0x000 to
>> COM_BIAS_EN_CLKBUFLR_EN=0x034. Everything else is different. So I can re-use
> 
> Is the offset different? I thought all Vn registers across chips do have
> same offsets..

Upon closer inspection, for the SERDES registers they are 19 common (the first
19), the others are different (different values, different names). About the
offsets that stay in DT -- they are the same for V3 and V3-660 (I haven't send
DT yet). Just to be clear, offset the is thing you add to each register to get
an actual register value, mainline uses relative offsets (base / offset in DT),
downstream uses a macro for each register group and the offset is hardcoded in
code. Link to the DT (will be submitted after core drivers are merged) [1]

[1] https://gitlab.com/ichernev/linux-postmarketos/-/blob/b44c853caf37dd73e059628a1831ad185356a33e/arch/arm64/boot/dts/qcom/sm4250.dtsi#L878

> 
>> the V3 for the similar regs, but they are 10%, so I figured instead of combing
>> through all of the sequences to save 10% of the constants and make it slightly
>> less readable just use new constants.
>>
>> Let me know if I should reuse the 14 regs from V3.
> 
> reuse yes, but would like to understand more why offsets are different,
> 
> Can you point me to downstream code reference for this?

As I said, the offsets are the same, the first 19 serdes relative
addresses/names are the same (can be reused), the rest is all different.
I wrote a tool to compare names and values, I can paste those as well if
needed.


This is a link to the downstream code (header) [2]


[2] https://github.com/OnePlusOSS/android_kernel_oneplus_sm4250/blob/oneplus/SM4250_Q_10.0/drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3-660.h

I will do a v2 with the 19 regs reused from the v3 bunch.

Regards,
Iskren


From Thinh.Nguyen at synopsys.com  Mon Aug  9 15:13:13 2021
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Mon, 9 Aug 2021 22:13:13 +0000
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87im0l5lj1.fsf@kernel.org>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
 <87im0l5lj1.fsf@kernel.org>
Message-ID: <33aaae91-3833-d88c-361f-ac9d62e26ccc@synopsys.com>

Felipe Balbi wrote:
> 
> Hi,
> 
> Baruch Siach <baruch at tkos.co.il> writes:
>> Hi Felipe,
>>
>> On Wed, Aug 04 2021, Felipe Balbi wrote:
>>> Baruch Siach <baruch at tkos.co.il> writes:
>>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>>>  				    &dwc->hsphy_interface);
>>>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>>>  				 &dwc->fladj);
>>>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>>>> +				 &dwc->ref_clk_per);
>>>
>>> I wonder if it would make more sense to pass an actual clock reference
>>> here. If valid, then reconfigure the period to the value returned by
>>> clk_get_rate(). It would avoid yet another DT binding. If we make the
>>> clock optional, then we won't affect any other platforms. The clock
>>> itself could be a regular fixed clock node.
>>
>> Thinh Nguyen asked to add a dedicated DT property. He explained that
>> clk_get_rate() does not work for PCI hosted dwc3. This is the most
>> complete summary of the discussion:
> 
> Hence the "optional" :-)
> 
> Or, perhaps, Thinh wants to use this for internal FPGA-based validation?
> 
> In that case, I'm okay with the property.
> 

We do use it for internal FPGA validation, but it should help for other
dwc3 PCI devices also.

BR,
Thinh

From sbillaka at codeaurora.org  Mon Aug  9 20:15:33 2021
From: sbillaka at codeaurora.org (sbillaka at codeaurora.org)
Date: Tue, 10 Aug 2021 08:45:33 +0530
Subject: [PATCH 2/2] phy: qcom: Introduce new eDP PHY driver
In-Reply-To: <20210511041930.592483-2-bjorn.andersson@linaro.org>
References: <20210511041930.592483-1-bjorn.andersson@linaro.org>
 <20210511041930.592483-2-bjorn.andersson@linaro.org>
Message-ID: <7708925ad4d973b4e5f291cdcbdbe406@codeaurora.org>

Hello Bjorn,

On 2021-05-11 09:49, Bjorn Andersson wrote:
> Many recent Qualcomm platforms comes with native DP and eDP support.
> This consists of a controller int he MDSS and a QMP-like PHY.
> 
> While similar to the well known QMP block, the eDP PHY only has TX 
> lanes
> and the programming sequences are slightly different. Rather than
> continuing the trend of parameterize the QMP driver to pieces, this
> introduces the support as a new driver.
> 
> The registration of link and pixel clocks are borrowed from the QMP
> driver. The non-DP link frequencies are omitted for now.
> 
> The eDP PHY is very similar to the dedicated (non-USB) DP PHY, but only
> the prior is supported for now.
> 
> Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
> ---
>  drivers/phy/qualcomm/Kconfig        |  10 +
>  drivers/phy/qualcomm/Makefile       |   1 +
>  drivers/phy/qualcomm/phy-qcom-edp.c | 750 ++++++++++++++++++++++++++++
>  3 files changed, 761 insertions(+)
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-edp.c
> 
> diff --git a/drivers/phy/qualcomm/Kconfig 
> b/drivers/phy/qualcomm/Kconfig
> index 7f6fcb8ec5ba..13ae6f4f3112 100644
> --- a/drivers/phy/qualcomm/Kconfig
> +++ b/drivers/phy/qualcomm/Kconfig
> @@ -114,3 +114,13 @@ config PHY_QCOM_IPQ806X_USB
>  	  This option enables support for the Synopsis PHYs present inside 
> the
>  	  Qualcomm USB3.0 DWC3 controller on ipq806x SoC. This driver 
> supports
>  	  both HS and SS PHY controllers.
> +
> +config PHY_QCOM_EDP
> +	tristate "Qualcomm eDP PHY driver"
> +	depends on ARCH_QCOM || COMPILE_TEST
> +	depends on OF
> +	depends on COMMON_CLK
> +	select GENERIC_PHY
> +	help
> +	  Enable this driver to support the Qualcomm eDP PHY found in various
> +	  Qualcomm chipsets.
> diff --git a/drivers/phy/qualcomm/Makefile 
> b/drivers/phy/qualcomm/Makefile
> index 47acbd7daa3a..1afd0882dbcc 100644
> --- a/drivers/phy/qualcomm/Makefile
> +++ b/drivers/phy/qualcomm/Makefile
> @@ -12,3 +12,4 @@ obj-$(CONFIG_PHY_QCOM_USB_HS_28NM)	+= 
> phy-qcom-usb-hs-28nm.o
>  obj-$(CONFIG_PHY_QCOM_USB_SS)		+= phy-qcom-usb-ss.o
>  obj-$(CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2)+= phy-qcom-snps-femto-v2.o
>  obj-$(CONFIG_PHY_QCOM_IPQ806X_USB)		+= phy-qcom-ipq806x-usb.o
> +obj-$(CONFIG_PHY_QCOM_EDP)		+= phy-qcom-edp.o
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c
> b/drivers/phy/qualcomm/phy-qcom-edp.c
> new file mode 100644
> index 000000000000..ff0508e49548
> --- /dev/null
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -0,0 +1,750 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2017, 2020, The Linux Foundation. All rights 
> reserved.
> + * Copyright (c) 2021, Linaro Ltd.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_address.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +
> +#include <dt-bindings/phy/phy.h>
> +
> +#define DP_PHY_PD_CTL_PWRDN			0x001
> +#define DP_PHY_PD_CTL_PSR_PWRDN			0x002
> +#define DP_PHY_PD_CTL_AUX_PWRDN			0x004
> +#define DP_PHY_PD_CTL_LANE_0_1_PWRDN		0x008
> +#define DP_PHY_PD_CTL_LANE_2_3_PWRDN		0x010
> +#define DP_PHY_PD_CTL_PLL_PWRDN			0x020
> +#define DP_PHY_PD_CTL_DP_CLAMP_EN		0x040
> +
> +#define DP_PHY_CFG                              0x0010
> +#define DP_PHY_CFG_1                            0x0014
> +#define DP_PHY_PD_CTL                           0x001C
> +#define DP_PHY_MODE                             0x0020
> +
> +#define DP_PHY_AUX_CFG0				0x0020
> +#define DP_PHY_AUX_CFG1				0x0024
> +#define DP_PHY_AUX_CFG2				0x0028
> +#define DP_PHY_AUX_CFG3				0x002c
> +#define DP_PHY_AUX_CFG4				0x0030
> +#define DP_PHY_AUX_CFG5				0x0034
> +#define DP_PHY_AUX_CFG6				0x0038
> +#define DP_PHY_AUX_CFG7				0x003c
> +#define DP_PHY_AUX_CFG8				0x0040
> +#define DP_PHY_AUX_CFG9				0x0044

The DP_PHY_AUX_CFG0 offset for sc8180x eDP phy is 0x0024.
Some of the eDP PHY offset addresses are shifted by 4 address locations, 
compared to the DP QMP PHY offset addresses for sc8180x.
The DP_PHY_AUX_CFG* offsets for this eDP phy driver are as below:

#define DP_PHY_AUX_CFG0                         0x0024
#define DP_PHY_AUX_CFG1                         0x0028
#define DP_PHY_AUX_CFG2                         0x002c
#define DP_PHY_AUX_CFG3                         0x0030
#define DP_PHY_AUX_CFG4                         0x0034
#define DP_PHY_AUX_CFG5                         0x0038
#define DP_PHY_AUX_CFG6                         0x003c
#define DP_PHY_AUX_CFG7                         0x0040
#define DP_PHY_AUX_CFG8                         0x0044
#define DP_PHY_AUX_CFG9                         0x0048

> +
> +#define DP_PHY_VCO_DIV                          0x0074
> +#define DP_PHY_TX0_TX1_LANE_CTL                 0x007C
> +#define DP_PHY_TX2_TX3_LANE_CTL                 0x00A0
> +
> +#define DP_PHY_SPARE0                           0x00CC
> +#define DP_PHY_STATUS                           0x00E0
> +
> +/* Tx registers */
> +#define TXn_CLKBUF_ENABLE                       0x0000
> +#define TXn_TX_EMP_POST1_LVL                    0x0004
> +
> +#define TXn_TX_DRV_LVL                          0x0014
> +#define TXn_TX_DRV_LVL_OFFSET                   0x0018
> +#define TXn_RESET_TSYNC_EN                      0x001C
> +//#define TXn_PRE_STALL_LDO_BOOST_EN            0x0020
> +#define TXn_LDO_CONFIG                          0x0084
> +#define TXn_TX_BAND                             0x0028
> +#define TXn_INTERFACE_SELECT                    0x0024
> +
> +#define TXn_RES_CODE_LANE_OFFSET_TX0            0x0044
> +#define TXn_RES_CODE_LANE_OFFSET_TX1            0x0048
> +//#define TXn_RES_CODE_LANE_OFFSET_RX           0x0040
> +
> +#define TXn_TRANSCEIVER_BIAS_EN                 0x0054
> +#define TXn_HIGHZ_DRVR_EN                       0x0058
> +#define TXn_TX_POL_INV                          0x005C
> +#define TXn_PARRATE_REC_DETECT_IDLE_EN          0x0060
> +#define TXn_LANE_MODE_1                         0x0064
> +
> +#define TXn_TRAN_DRVR_EMP_EN                    0x0078
> +//#define TXn_TX_INTERFACE_MODE                 0x00BC
> +
> +#define TXn_VMODE_CTRL1                         0x007C
> +
> +/* PLL register offset */
> +#define QSERDES_COM_BG_TIMER                    0x000C
> +#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN         0x0044
> +#define QSERDES_COM_CLK_ENABLE1                 0x0048
> +#define QSERDES_COM_SYS_CLK_CTRL                0x004C
> +#define QSERDES_COM_SYSCLK_BUF_ENABLE           0x0050
> +#define QSERDES_COM_PLL_IVCO                    0x0058
> +
> +#define QSERDES_COM_CP_CTRL_MODE0               0x0074
> +#define QSERDES_COM_PLL_RCTRL_MODE0             0x007C
> +#define QSERDES_COM_PLL_CCTRL_MODE0             0x0084
> +#define QSERDES_COM_SYSCLK_EN_SEL               0x0094
> +#define QSERDES_COM_RESETSM_CNTRL               0x009C
> +#define QSERDES_COM_LOCK_CMP_EN                 0x00A4
> +#define QSERDES_COM_LOCK_CMP1_MODE0             0x00AC
> +#define QSERDES_COM_LOCK_CMP2_MODE0             0x00B0
> +
> +#define QSERDES_COM_DEC_START_MODE0             0x00BC
> +#define QSERDES_COM_DIV_FRAC_START1_MODE0       0x00CC
> +#define QSERDES_COM_DIV_FRAC_START2_MODE0       0x00D0
> +#define QSERDES_COM_DIV_FRAC_START3_MODE0       0x00D4
> +#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0       0x00EC
> +#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0       0x00F0
> +#define QSERDES_COM_VCO_TUNE_CTRL               0x0108
> +#define QSERDES_COM_VCO_TUNE_MAP                0x010C
> +#define QSERDES_COM_VCO_TUNE1_MODE0             0x0110
> +#define QSERDES_COM_VCO_TUNE2_MODE0             0x0114
> +#define QSERDES_COM_CMN_STATUS                  0x0140
> +
> +#define QSERDES_COM_CLK_SEL                     0x0154
> +#define QSERDES_COM_HSCLK_SEL                   0x0158
> +
> +#define QSERDES_COM_CORECLK_DIV_MODE0           0x0168
> +
> +#define QSERDES_COM_CORE_CLK_EN                 0x0174
> +#define QSERDES_COM_C_READY_STATUS              0x0178
> +#define QSERDES_COM_CMN_CONFIG                  0x017C
> +
> +#define QSERDES_COM_SVS_MODE_CLK_SEL            0x0184
> +
> +#define QSERDES_COM_SSC_EN_CENTER               0x0010
> +#define QSERDES_COM_SSC_ADJ_PER1                0x0014
> +#define QSERDES_COM_SSC_ADJ_PER2                0x0018
> +#define QSERDES_COM_SSC_PER1                    0x001C
> +#define QSERDES_COM_SSC_PER2                    0x0020
> +#define QSERDES_COM_SSC_STEP_SIZE1_MODE0        0x0024
> +#define QSERDES_COM_SSC_STEP_SIZE2_MODE0        0x0028
> +
> +#define DP_PHY_PLL_POLL_SLEEP_US                500
> +#define DP_PHY_PLL_POLL_TIMEOUT_US              10000
> +
> +#define EDP_VCO_RATE_8100MHZDIV1000             8100000UL
> +#define EDP_VCO_RATE_8640MHZDIV1000             8640000UL
> +#define EDP_VCO_RATE_9720MHZDIV1000             9720000UL
> +#define EDP_VCO_RATE_10800MHZDIV1000            10800000UL
> +#define EDP_VCO_RATE_11880MHZDIV1000            11880000UL
> +
> +struct qcom_edp {
> +	struct device *dev;
> +
> +	struct phy *phy;
> +
> +	void __iomem *edp;
> +	void __iomem *tx0;
> +	void __iomem *tx1;
> +	void __iomem *pll;
> +
> +	struct clk_hw dp_link_hw;
> +	struct clk_hw dp_pixel_hw;
> +
> +	struct phy_configure_opts_dp dp_opts;
> +
> +	struct clk_bulk_data clks[2];
> +	struct regulator_bulk_data supplies[2];
> +} ;
> +
> +static int qcom_edp_phy_init(struct phy *phy)
> +{
> +	struct qcom_edp *edp = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), 
> edp->supplies);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> +	if (ret)
> +		goto out_disable_supplies;

I think the number of clk and regulator resources can vary based on 
platform.

> +
> +	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> +	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> +	       edp->edp + DP_PHY_PD_CTL);
> +
> +	writel(0x17, edp->pll + QSERDES_COM_BIAS_EN_CLKBUFLR_EN);
> +
> +	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
> +	msleep(20);
> +
> +	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> +	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
> +	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> +	       edp->edp + DP_PHY_PD_CTL);
> +
> +	writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
> +	writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
> +	writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
> +	writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
> +	writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
> +	writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
> +	writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
> +	writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
> +	writel(0x37, edp->edp + DP_PHY_AUX_CFG8);
> +	writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
> +
> +	writel(0x1f, edp->edp + 0x58);
> +
> +	msleep(20);
> +
> +	return 0;
> +
> +out_disable_supplies:
> +	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +
> +	return ret;
> +}
> +
> +static int qcom_edp_phy_configure(struct phy *phy, union
> phy_configure_opts *opts)
> +{
> +	const struct phy_configure_opts_dp *dp_opts = &opts->dp;
> +	struct qcom_edp *edp = phy_get_drvdata(phy);
> +
> +	memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts));
> +
> +	return 0;
> +}
> +
> +static int qcom_edp_configure_ssc(struct qcom_edp *edp)
> +{
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +	u32 step1;
> +	u32 step2;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +	case 2700:
> +	case 8100:
> +		step1 = 0x45;
> +		step2 = 0x06;
> +		break;
> +	case 5400:
> +		step1 = 0x5c;
> +		step2 = 0x08;
> +		break;
> +	default:
> +		/* Other link rates aren't supported */
> +		return -EINVAL;
> +	}
> +
> +	writel(0x01, edp->pll + QSERDES_COM_SSC_EN_CENTER);
> +	writel(0x00, edp->pll + QSERDES_COM_SSC_ADJ_PER1);
> +	writel(0x36, edp->pll + QSERDES_COM_SSC_PER1);
> +	writel(0x01, edp->pll + QSERDES_COM_SSC_PER2);
> +	writel(step1, edp->pll + QSERDES_COM_SSC_STEP_SIZE1_MODE0);
> +	writel(step2, edp->pll + QSERDES_COM_SSC_STEP_SIZE2_MODE0);
> +
> +	return 0;
> +}
> +
> +static int qcom_edp_configure_pll(struct qcom_edp *edp)
> +{
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +	u32 div_frac_start2_mode0;
> +	u32 div_frac_start3_mode0;
> +	u32 dec_start_mode0;
> +	u32 lock_cmp1_mode0;
> +	u32 lock_cmp2_mode0;
> +	u32 hsclk_sel;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +		hsclk_sel = 0x5;
> +		dec_start_mode0 = 0x69;
> +		div_frac_start2_mode0 = 0x80;
> +		div_frac_start3_mode0 = 0x07;
> +		lock_cmp1_mode0 = 0x6f;
> +		lock_cmp2_mode0 = 0x08;
> +		break;
> +	case 2700:
> +		hsclk_sel = 0x3;
> +		dec_start_mode0 = 0x69;
> +		div_frac_start2_mode0 = 0x80;
> +		div_frac_start3_mode0 = 0x07;
> +		lock_cmp1_mode0 = 0x0f;
> +		lock_cmp2_mode0 = 0x0e;
> +		break;
> +	case 5400:
> +		hsclk_sel = 0x1;
> +		dec_start_mode0 = 0x8c;
> +		div_frac_start2_mode0 = 0x00;
> +		div_frac_start3_mode0 = 0x0a;
> +		lock_cmp1_mode0 = 0x1f;
> +		lock_cmp2_mode0 = 0x1c;
> +		break;
> +	case 8100:
> +		hsclk_sel = 0x0;
> +		dec_start_mode0 = 0x69;
> +		div_frac_start2_mode0 = 0x80;
> +		div_frac_start3_mode0 = 0x07;
> +		lock_cmp1_mode0 = 0x2f;
> +		lock_cmp2_mode0 = 0x2a;
> +		break;
> +	default:
> +		/* Other link rates aren't supported */
> +		return -EINVAL;
> +	}
> +
> +	writel(0x01, edp->pll + QSERDES_COM_SVS_MODE_CLK_SEL);
> +	writel(0x0b, edp->pll + QSERDES_COM_SYSCLK_EN_SEL);
> +	writel(0x02, edp->pll + QSERDES_COM_SYS_CLK_CTRL);
> +	writel(0x0c, edp->pll + QSERDES_COM_CLK_ENABLE1);
> +	writel(0x06, edp->pll + QSERDES_COM_SYSCLK_BUF_ENABLE);
> +	writel(0x30, edp->pll + QSERDES_COM_CLK_SEL);
> +	writel(hsclk_sel, edp->pll + QSERDES_COM_HSCLK_SEL);
> +	writel(0x0f, edp->pll + QSERDES_COM_PLL_IVCO);
> +	writel(0x08, edp->pll + QSERDES_COM_LOCK_CMP_EN);
> +	writel(0x36, edp->pll + QSERDES_COM_PLL_CCTRL_MODE0);
> +	writel(0x16, edp->pll + QSERDES_COM_PLL_RCTRL_MODE0);
> +	writel(0x06, edp->pll + QSERDES_COM_CP_CTRL_MODE0);
> +	writel(dec_start_mode0, edp->pll + QSERDES_COM_DEC_START_MODE0);
> +	writel(0x00, edp->pll + QSERDES_COM_DIV_FRAC_START1_MODE0);
> +	writel(div_frac_start2_mode0, edp->pll + 
> QSERDES_COM_DIV_FRAC_START2_MODE0);
> +	writel(div_frac_start3_mode0, edp->pll + 
> QSERDES_COM_DIV_FRAC_START3_MODE0);
> +	writel(0x02, edp->pll + QSERDES_COM_CMN_CONFIG);
> +	writel(0x3f, edp->pll + QSERDES_COM_INTEGLOOP_GAIN0_MODE0);
> +	writel(0x00, edp->pll + QSERDES_COM_INTEGLOOP_GAIN1_MODE0);
> +	writel(0x00, edp->pll + QSERDES_COM_VCO_TUNE_MAP);
> +	writel(lock_cmp1_mode0, edp->pll + QSERDES_COM_LOCK_CMP1_MODE0);
> +	writel(lock_cmp2_mode0, edp->pll + QSERDES_COM_LOCK_CMP2_MODE0);
> +
> +	writel(0x0a, edp->pll + QSERDES_COM_BG_TIMER);
> +	writel(0x14, edp->pll + QSERDES_COM_CORECLK_DIV_MODE0);
> +	writel(0x00, edp->pll + QSERDES_COM_VCO_TUNE_CTRL);
> +	writel(0x17, edp->pll + QSERDES_COM_BIAS_EN_CLKBUFLR_EN);
> +	writel(0x0f, edp->pll + QSERDES_COM_CORE_CLK_EN);
> +	writel(0xa0, edp->pll + QSERDES_COM_VCO_TUNE1_MODE0);
> +	writel(0x03, edp->pll + QSERDES_COM_VCO_TUNE2_MODE0);
> +
> +	return 0;
> +}
> +
> +static int qcom_edp_set_vco_div(struct qcom_edp *edp)
> +{
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +	unsigned long pixel_freq;
> +	u32 vco_div;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +		vco_div = 0x1;
> +		pixel_freq = 1620000000UL / 2;
> +		break;
> +	case 2700:
> +		vco_div = 0x1;
> +		pixel_freq = 2700000000UL / 2;
> +		break;
> +	case 5400:
> +		vco_div = 0x2;
> +		pixel_freq = 5400000000UL / 4;
> +		break;
> +	case 8100:
> +		vco_div = 0x0;
> +		pixel_freq = 8100000000UL / 6;
> +		break;
> +	default:
> +		/* Other link rates aren't supported */
> +		return -EINVAL;
> +	}
> +
> +	writel(vco_div, edp->edp + DP_PHY_VCO_DIV);
> +
> +	clk_set_rate(edp->dp_link_hw.clk, dp_opts->link_rate * 100000);
> +	clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq);
> +
> +	return 0;
> +}
> +
> +static int qcom_edp_phy_power_on(struct phy *phy)
> +{
> +	struct qcom_edp *edp = phy_get_drvdata(phy);
> +	int timeout;
> +	int ret;
> +	u32 val;
> +
> +	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> +	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
> +	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> +	       edp->edp + DP_PHY_PD_CTL);
> +	writel(0xfc, edp->edp + DP_PHY_MODE);
> +
> +	timeout = readl_poll_timeout(edp->pll + QSERDES_COM_CMN_STATUS,
> +				     val, val & BIT(7), 5, 200);
> +	if (timeout)
> +		return timeout;
> +
> +	writel(0x01, edp->tx0 + TXn_LDO_CONFIG);
> +	writel(0x01, edp->tx1 + TXn_LDO_CONFIG);
> +	writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
> +	writel(0x00, edp->tx1 + TXn_LANE_MODE_1);
> +
> +	ret = qcom_edp_configure_ssc(edp);
> +	if (ret)
> +		return ret;
> +
> +	ret = qcom_edp_configure_pll(edp);
> +	if (ret)
> +		return ret;
> +
> +	/* TX Lane configuration */
> +	writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL);
> +	writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL);
> +
> +	/* TX-0 register configuration */
> +	writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
> +	writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE);
> +	writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN);
> +	writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN);
> +	writel(0x04, edp->tx0 + TXn_TX_BAND);
> +
> +	/* TX-1 register configuration */
> +	writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
> +	writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE);
> +	writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN);
> +	writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN);
> +	writel(0x04, edp->tx1 + TXn_TX_BAND);
> +
> +	ret = qcom_edp_set_vco_div(edp);
> +	if (ret)
> +		return ret;
> +
> +	writel(0x01, edp->edp + DP_PHY_CFG);
> +        writel(0x05, edp->edp + DP_PHY_CFG);
> +        writel(0x01, edp->edp + DP_PHY_CFG);
> +        writel(0x09, edp->edp + DP_PHY_CFG);
> +
> +        writel(0x20, edp->pll + QSERDES_COM_RESETSM_CNTRL);
> +
> +	timeout = readl_poll_timeout(edp->pll + QSERDES_COM_C_READY_STATUS,
> +				     val, val & BIT(0), 500, 10000);
> +	if (timeout)
> +		return timeout;
> +
> +	writel(0x19, edp->edp + DP_PHY_CFG);
> +	writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN);
> +	writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN);
> +	writel(0x00, edp->tx0 + TXn_TX_POL_INV);
> +	writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN);
> +	writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN);
> +	writel(0x00, edp->tx1 + TXn_TX_POL_INV);
> +	writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET);
> +	writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET);
> +	writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0);
> +	writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1);
> +	writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0);
> +	writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1);
> +
> +	writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL);
> +	writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL);
> +	writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL);
> +	writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL);
> +
> +	writel(0x4, edp->tx0 + TXn_HIGHZ_DRVR_EN);
> +	writel(0x3, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
> +	writel(0x4, edp->tx1 + TXn_HIGHZ_DRVR_EN);
> +	writel(0x0, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
> +	writel(0x3, edp->edp + DP_PHY_CFG_1);
> +
> +	writel(0x18, edp->edp + DP_PHY_CFG);
> +	udelay(100);
> +
> +	writel(0x19, edp->edp + DP_PHY_CFG);
> +
> +	return readl_poll_timeout(edp->edp + DP_PHY_STATUS,
> +				  val, val & BIT(1), 500, 10000);
> +}
> +
> +static int qcom_edp_phy_power_off(struct phy *phy)
> +{
> +	struct qcom_edp *edp = phy_get_drvdata(phy);
> +
> +	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
> +
> +	return 0;
> +}
> +
> +static int qcom_edp_phy_exit(struct phy *phy)
> +{
> +	struct qcom_edp *edp = phy_get_drvdata(phy);
> +
> +	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> +	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);

I think the number of regulator and clk resources can vary based on 
platform.

> +
> +	return 0;
> +}
> +
> +static const struct phy_ops qcom_edp_ops = {
> +	.init		= qcom_edp_phy_init,
> +	.configure	= qcom_edp_phy_configure,
> +	.power_on	= qcom_edp_phy_power_on,
> +	.power_off	= qcom_edp_phy_power_off,
> +	.exit		= qcom_edp_phy_exit,
> +	.owner		= THIS_MODULE,
> +};
> +
> +/*
> + * Display Port PLL driver block diagram for branch clocks
> + *
> + *              +------------------------------+
> + *              |         DP_VCO_CLK           |
> + *              |                              |
> + *              |    +-------------------+     |
> + *              |    |   (DP PLL/VCO)    |     |
> + *              |    +---------+---------+     |
> + *              |              v               |
> + *              |   +----------+-----------+   |
> + *              |   | hsclk_divsel_clk_src |   |
> + *              |   +----------+-----------+   |
> + *              +------------------------------+
> + *                              |
> + *          +---------<---------v------------>----------+
> + *          |                                           |
> + * +--------v----------------+                          |
> + * |    dp_phy_pll_link_clk  |                          |
> + * |     link_clk            |                          |
> + * +--------+----------------+                          |
> + *          |                                           |
> + *          |                                           |
> + *          v                                           v
> + * Input to DISPCC block                                |
> + * for link clk, crypto clk                             |
> + * and interface clock                                  |
> + *                                                      |
> + *                                                      |
> + *      +--------<------------+-----------------+---<---+
> + *      |                     |                 |
> + * +----v---------+  +--------v-----+  +--------v------+
> + * | vco_divided  |  | vco_divided  |  | vco_divided   |
> + * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
> + * |              |  |              |  |               |
> + * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
> + * +-------+------+  +-----+--------+  +--------+------+
> + *         |                 |                  |
> + *         v---->----------v-------------<------v
> + *                         |
> + *              +----------+-----------------+
> + *              |   dp_phy_pll_vco_div_clk   |
> + *              +---------+------------------+
> + *                        |
> + *                        v
> + *              Input to DISPCC block
> + *              for DP pixel clock
> + *
> + */
> +static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
> +						struct clk_rate_request *req)
> +{
> +	switch (req->rate) {
> +	case 1620000000UL / 2:
> +	case 2700000000UL / 2:
> +	/* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 
> */
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static unsigned long
> +qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long 
> parent_rate)
> +{
> +	const struct qcom_edp *edp = container_of(hw, struct qcom_edp, 
> dp_pixel_hw);
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +		return 1620000000UL / 2;
> +	case 2700:
> +		return 2700000000UL / 2;
> +	case 5400:
> +		return 5400000000UL / 4;
> +	case 8100:
> +		return 8100000000UL / 6;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static const struct clk_ops qcom_edp_dp_pixel_clk_ops = {
> +	.determine_rate = qcom_edp_dp_pixel_clk_determine_rate,
> +	.recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate,
> +};
> +
> +static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw,
> +					       struct clk_rate_request *req)
> +{
> +	switch (req->rate) {
> +	case 162000000:
> +	case 270000000:
> +	case 540000000:
> +	case 810000000:
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static unsigned long
> +qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long 
> parent_rate)
> +{
> +	const struct qcom_edp *edp = container_of(hw, struct qcom_edp, 
> dp_link_hw);
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +	case 2700:
> +	case 5400:
> +	case 8100:
> +		return dp_opts->link_rate * 100000;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static const struct clk_ops qcom_edp_dp_link_clk_ops = {
> +	.determine_rate = qcom_edp_dp_link_clk_determine_rate,
> +	.recalc_rate = qcom_edp_dp_link_clk_recalc_rate,
> +};
> +
> +static struct clk_hw *
> +qcom_edp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
> +{
> +	unsigned int idx = clkspec->args[0];
> +	struct qcom_edp *edp = data;
> +
> +	if (idx >= 2) {
> +		pr_err("%s: invalid index %u\n", __func__, idx);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (idx == 0)
> +		return &edp->dp_link_hw;
> +
> +	return &edp->dp_pixel_hw;
> +}
> +
> +static void phy_clk_release_provider(void *res)
> +{
> +	of_clk_del_provider(res);
> +}
> +
> +static int qcom_edp_clks_register(struct qcom_edp *edp, struct 
> device_node *np)
> +{
> +	struct clk_init_data init = { };
> +	int ret;
> +
> +	init.ops = &qcom_edp_dp_link_clk_ops;
> +	init.name = "edp_phy_pll_link_clk";
> +	edp->dp_link_hw.init = &init;
> +	ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw);
> +	if (ret)
> +		return ret;
> +
> +	init.ops = &qcom_edp_dp_pixel_clk_ops;
> +	init.name = "edp_phy_pll_vco_div_clk";
> +	edp->dp_pixel_hw.init = &init;
> +	ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw);
> +	if (ret)
> +		return ret;
> +
> +	ret = of_clk_add_hw_provider(np, qcom_edp_dp_clks_hw_get, edp);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * Roll a devm action because the clock provider is the child node, 
> but
> +	 * the child node is not actually a device.
> +	 */
> +	ret = devm_add_action(edp->dev, phy_clk_release_provider, np);
> +	if (ret)
> +		phy_clk_release_provider(np);
> +
> +	return ret;
> +}
> +
> +static int qcom_edp_phy_probe(struct platform_device *pdev)
> +{
> +	struct phy_provider *phy_provider;
> +	struct device *dev = &pdev->dev;
> +	struct qcom_edp *edp;
> +	int ret;
> +
> +	edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL);
> +	if (!edp)
> +		return -ENOMEM;
> +
> +	edp->dev = dev;
> +
> +	edp->edp = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(edp->edp))
> +		return PTR_ERR(edp->edp);
> +
> +	edp->tx0 = devm_platform_ioremap_resource(pdev, 1);
> +	if (IS_ERR(edp->tx0))
> +		return PTR_ERR(edp->tx0);
> +
> +	edp->tx1 = devm_platform_ioremap_resource(pdev, 2);
> +	if (IS_ERR(edp->tx1))
> +		return PTR_ERR(edp->tx1);
> +
> +	edp->pll = devm_platform_ioremap_resource(pdev, 3);
> +	if (IS_ERR(edp->pll))
> +		return PTR_ERR(edp->pll);
> +
> +	edp->clks[0].id = "aux";
> +	edp->clks[1].id = "cfg_ahb";
> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks);
> +	if (ret)
> +		return ret;
> +
> +	edp->supplies[0].supply = "vdda-phy";
> +	edp->supplies[1].supply = "vdda-pll";
> +	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), 
> edp->supplies);
> +	if (ret)
> +		return ret;

I believe, the combination of the number of regulator and clk resources 
may vary based on the platform.
I think we should not fail probe if all these resources are not present 
in the device tree file.
I think, these resources can be optional. We can get these resources if 
they are present in the device tree file and enable them as required.

> +
> +	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> +	if (ret)
> +		return ret;
> +
> +	edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
> +	if (IS_ERR(edp->phy)) {
> +		dev_err(dev, "failed to register phy\n");
> +		return PTR_ERR(edp->phy);
> +	}
> +
> +	phy_set_drvdata(edp->phy, edp);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, 
> of_phy_simple_xlate);
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id qcom_edp_phy_match_table[] = {
> +	{ .compatible = "qcom,sc8180x-edp-phy" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
> +
> +static struct platform_driver qcom_edp_phy_driver = {
> +	.probe		= qcom_edp_phy_probe,
> +	.driver = {
> +		.name	= "qcom-edp-phy",
> +		.of_match_table = qcom_edp_phy_match_table,
> +	},
> +};
> +
> +module_platform_driver(qcom_edp_phy_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm eDP PHY driver");
> +MODULE_LICENSE("GPL v2");

Thank you,
Sankeerth


From bjorn.andersson at linaro.org  Mon Aug  9 20:36:56 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 9 Aug 2021 22:36:56 -0500
Subject: [PATCH 2/2] phy: qcom: Introduce new eDP PHY driver
In-Reply-To: <7708925ad4d973b4e5f291cdcbdbe406@codeaurora.org>
References: <20210511041930.592483-1-bjorn.andersson@linaro.org>
 <20210511041930.592483-2-bjorn.andersson@linaro.org>
 <7708925ad4d973b4e5f291cdcbdbe406@codeaurora.org>
Message-ID: <YRH0WFvWmemHIHqc@builder.lan>

On Mon 09 Aug 22:15 CDT 2021, sbillaka at codeaurora.org wrote:
> On 2021-05-11 09:49, Bjorn Andersson wrote:
> > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c
[..]
> > +#define DP_PHY_AUX_CFG0				0x0020
> > +#define DP_PHY_AUX_CFG1				0x0024
> > +#define DP_PHY_AUX_CFG2				0x0028
> > +#define DP_PHY_AUX_CFG3				0x002c
> > +#define DP_PHY_AUX_CFG4				0x0030
> > +#define DP_PHY_AUX_CFG5				0x0034
> > +#define DP_PHY_AUX_CFG6				0x0038
> > +#define DP_PHY_AUX_CFG7				0x003c
> > +#define DP_PHY_AUX_CFG8				0x0040
> > +#define DP_PHY_AUX_CFG9				0x0044
> 
> The DP_PHY_AUX_CFG0 offset for sc8180x eDP phy is 0x0024.
> Some of the eDP PHY offset addresses are shifted by 4 address locations,
> compared to the DP QMP PHY offset addresses for sc8180x.
> The DP_PHY_AUX_CFG* offsets for this eDP phy driver are as below:
> 
> #define DP_PHY_AUX_CFG0                         0x0024
> #define DP_PHY_AUX_CFG1                         0x0028
> #define DP_PHY_AUX_CFG2                         0x002c
> #define DP_PHY_AUX_CFG3                         0x0030
> #define DP_PHY_AUX_CFG4                         0x0034
> #define DP_PHY_AUX_CFG5                         0x0038
> #define DP_PHY_AUX_CFG6                         0x003c
> #define DP_PHY_AUX_CFG7                         0x0040
> #define DP_PHY_AUX_CFG8                         0x0044
> #define DP_PHY_AUX_CFG9                         0x0048
> 

I noticed this as well. During development I just used the numbers
directly in the code and I must have screwed up as I replaced them with
defined - and somehow missed this in the testing before posting.

Sorry about that.

[..]
> > +static int qcom_edp_phy_init(struct phy *phy)
> > +{
> > +	struct qcom_edp *edp = phy_get_drvdata(phy);
> > +	int ret;
> > +
> > +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > +	if (ret)
> > +		goto out_disable_supplies;
> 
> I think the number of clk and regulator resources can vary based on
> platform.
> 

If that's the case we should replace the ARRAY_SIZE() with an integer.
But I prefer to wait with that until the number actually is variable.

[..]
> > +static int qcom_edp_phy_probe(struct platform_device *pdev)
> > +{
> > +	struct phy_provider *phy_provider;
> > +	struct device *dev = &pdev->dev;
> > +	struct qcom_edp *edp;
> > +	int ret;
> > +
> > +	edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL);
> > +	if (!edp)
> > +		return -ENOMEM;
> > +
> > +	edp->dev = dev;
> > +
> > +	edp->edp = devm_platform_ioremap_resource(pdev, 0);
> > +	if (IS_ERR(edp->edp))
> > +		return PTR_ERR(edp->edp);
> > +
> > +	edp->tx0 = devm_platform_ioremap_resource(pdev, 1);
> > +	if (IS_ERR(edp->tx0))
> > +		return PTR_ERR(edp->tx0);
> > +
> > +	edp->tx1 = devm_platform_ioremap_resource(pdev, 2);
> > +	if (IS_ERR(edp->tx1))
> > +		return PTR_ERR(edp->tx1);
> > +
> > +	edp->pll = devm_platform_ioremap_resource(pdev, 3);
> > +	if (IS_ERR(edp->pll))
> > +		return PTR_ERR(edp->pll);
> > +
> > +	edp->clks[0].id = "aux";
> > +	edp->clks[1].id = "cfg_ahb";
> > +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks);
> > +	if (ret)
> > +		return ret;
> > +
> > +	edp->supplies[0].supply = "vdda-phy";
> > +	edp->supplies[1].supply = "vdda-pll";
> > +	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies),
> > edp->supplies);
> > +	if (ret)
> > +		return ret;
> 
> I believe, the combination of the number of regulator and clk resources may
> vary based on the platform.
> I think we should not fail probe if all these resources are not present in
> the device tree file.
> I think, these resources can be optional. We can get these resources if they
> are present in the device tree file and enable them as required.
> 

It's quite helpful to the DTS writer to actually encode in the driver
which resources the driver expects and provide useful error messages
when these expectations aren't met - so I think in line with most other
drivers this should be decided based on the compatible.

What clocks and regulators do you have on sc7280?


Thanks for the feedback, I see that I have a few more pieces of feedback
from others that I need to incorporate. I'll make sure to do that and
repost this patch shortly.

Regards,
Bjorn


From rashmi.a at intel.com  Tue Aug 10 00:32:55 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Tue, 10 Aug 2021 07:32:55 +0000
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <CAPDyKFp5HcCfsoLgBc=D9RKOrVY2SuV3FKsFCVT2=WaxZBsNiA@mail.gmail.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <YRDqQvKQ71/824Lu@matsya>
 <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <CAPDyKFp5HcCfsoLgBc=D9RKOrVY2SuV3FKsFCVT2=WaxZBsNiA@mail.gmail.com>
Message-ID: <MWHPR11MB17898D0E3A0A4DD993AD7E948CF79@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Ulf Hansson <ulf.hansson at linaro.org>
> Sent: Monday, August 9, 2021 5:43 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: Vinod Koul <vkoul at kernel.org>; Michal Simek
> <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Andy Shevchenko
> <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> support to the arasan eMMC driver
> 
> On Mon, 9 Aug 2021 at 13:17, A, Rashmi <rashmi.a at intel.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Vinod Koul <vkoul at kernel.org>
> > > Sent: Monday, August 9, 2021 2:12 PM
> > > To: A, Rashmi <rashmi.a at intel.com>
> > > Cc: Ulf Hansson <ulf.hansson at linaro.org>; Michal Simek
> > > <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> > > Linux ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel
> > > Mailing List <linux- kernel at vger.kernel.org>; Kishon
> > > <kishon at ti.com>; Andy Shevchenko
> > > <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org;
> > > Mark Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou,
> > > Furong <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> > > <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> > > <adrian.hunter at intel.com>; Vaidya, Mahesh R
> > > <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> > > <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> > > <kenchappa.demakkanavar at intel.com>
> > > Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay
> > > SOC support to the arasan eMMC driver
> > >
> > > On 09-08-21, 05:16, A, Rashmi wrote:
> > >
> > > > >
> > > > > Rashmi, is it safe to apply this separately from the phy driver/dt
> changes?
> > > > > Then I can queue this via my mmc tree, if you like.
> > > > No, the phy driver/dt changes must go together with "mmc:
> > > > sdhci-of-
> > > arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver"
> > > patch.
> > >
> > > Why is that?
> > >
> > > What could happen, emmc driver will complain about phy not found and
> > > bail right?
> > This is right, but ideally both mmc:phy and mmc: sdhci-of-arasan
> > driver code changes should go together
> 
> If patches are well written and can be standalone, we (maintainers) ideally
> prefer to queue things on a per subsystem basis, because it's just easier.
> 
> That said, I also noticed that a new compatible string was added,
> "intel,thunderbay-sdhci-5.1". This needs to be documented in
> Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml, in a separate
> patch, preceding $subject patch.
> 
I acknowledge your comments. I will submit a separate patch to document device tree bindings. After that mmc: sdhci-of-arasan driver patch could be queued.

Regards
Rashmi

From rashmi.a at intel.com  Tue Aug 10 01:51:40 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Tue, 10 Aug 2021 08:51:40 +0000
Subject: [PATCH 3/3] phy: intel: Add Thunder Bay eMMC PHY support
In-Reply-To: <YQ0td9y5+RNFxWZs@matsya>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-4-rashmi.a@intel.com> <YQ0td9y5+RNFxWZs@matsya>
Message-ID: <MWHPR11MB1789393D5B868B0DBF6FC0A28CF79@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: Friday, August 6, 2021 6:09 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: linux-drivers-review-request at eclists.intel.com; michal.simek at xilinx.com;
> ulf.hansson at linaro.org; linux-mmc at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; kishon at ti.com;
> andriy.shevchenko at linux.intel.com; linux-phy at lists.infradead.org;
> mgross at linux.intel.com; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 3/3] phy: intel: Add Thunder Bay eMMC PHY support
> 
> On 30-07-21, 12:03, rashmi.a at intel.com wrote:
> 
> > diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig
> > index ac42bb2fb394..18a3cc5b98c0 100644
> > --- a/drivers/phy/intel/Kconfig
> > +++ b/drivers/phy/intel/Kconfig
> > @@ -46,3 +46,13 @@ config PHY_INTEL_LGM_EMMC
> >  	select GENERIC_PHY
> >  	help
> >  	  Enable this to support the Intel EMMC PHY
> > +
> > +config PHY_INTEL_THUNDERBAY_EMMC
> 
> Alphabetical sort please
> 
> > +        tristate "Intel Thunder Bay eMMC PHY driver"
> > +        depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST)
> > +        select GENERIC_PHY
> > +        help
> > +	  This option enables support for Intel Thunder Bay SoC eMMC PHY.
> > +
> > +	  To compile this driver as a module, choose M here: the module
> > +	  will be called phy-intel-thunderbay-emmc.ko.
> > diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile
> > index 14550981a707..6a4db3ee7393 100644
> > --- a/drivers/phy/intel/Makefile
> > +++ b/drivers/phy/intel/Makefile
> > @@ -1,5 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0
> >  obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC)	+= phy-intel-
> keembay-emmc.o
> > +obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC)	+= phy-intel-
> thunderbay-emmc.o
> 
> here as well
I will reorder the entry in Makefile. The Kconfig entries are in alphabetical order. Let me know if I am missing something.

-Rashmi
> 
> > +static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
> > +{
> > +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> > +	unsigned int freqsel = FREQSEL_200M_170M;
> > +	unsigned long rate;
> > +	static int lock;
> > +	u32 val;
> > +	int ret;
> > +
> > +	/* Disable DLL */
> > +	rate = clk_get_rate(tbh_phy->emmcclk);
> > +	switch (rate) {
> > +	case 200000000:
> > +	/* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0
> */
> > +		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK,
> DLL_EN_SHIFT, 0x0);
> 
> pls keep the same indent for comment and code!
Acknowledged

-Rashmi
> 
> > +		break;
> > +	/* dll lock not required for other frequencies */
> > +	case 50000000 ... 52000000:
> > +	case 400000:
> > +	default:
> > +		break;
> > +	}
> > +
> > +	if (!power_on)
> > +		return 0;
> 
> should this not be the first thing you check...
During phy power on/off condition, dll should be disabled first. So power_on check is made after disabling dll.

-Rashmi
> 
> > +
> > +	rate = clk_get_rate(tbh_phy->emmcclk);
> > +	switch (rate) {
> > +	case 170000001 ... 200000000:
> > +		freqsel = FREQSEL_200M_170M;
> > +		break;
> > +	case 140000001 ... 170000000:
> > +		freqsel = FREQSEL_170M_140M;
> > +		break;
> > +	case 110000001 ... 140000000:
> > +		freqsel = FREQSEL_140M_110M;
> > +		break;
> > +	case 80000001 ... 110000000:
> > +		freqsel = FREQSEL_110M_80M;
> > +		break;
> > +	case 50000000 ... 80000000:
> > +		freqsel = FREQSEL_80M_50M;
> > +		break;
> > +	case 250000001 ... 275000000:
> > +		freqsel = FREQSEL_275M_250M;
> > +		break;
> > +	case 225000001 ... 250000000:
> > +		freqsel = FREQSEL_250M_225M;
> > +		break;
> > +	case 200000001 ... 225000000:
> > +		freqsel = FREQSEL_225M_200M;
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	if (rate > 200000000)
> > +	/* only the upper limit is considered as the clock rate may fall low
> during init */
> > +		dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
> 
> here as well! (checkpatch --strict should have told you so)
I will follow the proper alignment, though check-patch script didn't show any warnings.

-Rashmi
> 
> > +static int thunderbay_emmc_phy_power_on(struct phy *phy) {
> > +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> > +	unsigned long rate;
> > +
> > +	/* Overwrite capability bits configurable in bootloader */
> > +	update_reg(tbh_phy, CTRL_CFG_0,
> > +		   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_0,
> > +		   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
> > +
> > +	if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
> > +	/* Indicates initialization, so settings to be done for init , same as
> 400KHZ setting */
> > +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
> > +SEL_DLY_TXCLK_SHIFT, 0x1);
> 
> inconsistent indent here too!
> 
> > +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
> SEL_DLY_RXCLK_SHIFT, 0x1);
> > +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
> ITAP_DLY_ENA_SHIFT, 0x0);
> > +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
> ITAP_DLY_SEL_SHIFT, 0x0);
> > +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
> OTAP_DLY_ENA_SHIFT, 0x0);
> > +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
> OTAP_DLY_SEL_SHIFT, 0);
> > +		update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
> DLL_TRIM_ICP_SHIFT, 0);
> > +		update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
> DR_TY_SHIFT, 0x1);
> > +
> > +	} else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
> > +		/* Indicates actual clock setting */
> > +		rate = clk_get_rate(tbh_phy->emmcclk);
> > +		switch (rate) {
> > +		case 200000000:
> > +			update_reg(tbh_phy, PHY_CFG_0,
> SEL_DLY_TXCLK_MASK,
> > +				   SEL_DLY_TXCLK_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> SEL_DLY_RXCLK_MASK,
> > +				   SEL_DLY_RXCLK_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> ITAP_DLY_ENA_MASK,
> > +				   ITAP_DLY_ENA_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> ITAP_DLY_SEL_MASK,
> > +				   ITAP_DLY_SEL_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> OTAP_DLY_ENA_MASK,
> > +				   OTAP_DLY_ENA_SHIFT, 0x1);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> OTAP_DLY_SEL_MASK,
> > +				   OTAP_DLY_SEL_SHIFT, 2);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> DLL_TRIM_ICP_MASK,
> > +				   DLL_TRIM_ICP_SHIFT, 0x8);
> > +			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
> > +				   DR_TY_SHIFT, 0x1);
> > +			/* For HS400 only */
> > +			update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
> > +				   SEL_STRB_SHIFT, STRB);
> > +			break;
> 
> pls give a empty line after break, helps to read the code
Acknowledged

-Rashmi


From mchehab+huawei at kernel.org  Tue Aug 10 02:42:11 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 10 Aug 2021 11:42:11 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan>
 <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
Message-ID: <20210810114211.01df0246@coco.lan>

Em Fri, 6 Aug 2021 10:23:35 -0600
Rob Herring <robh at kernel.org> escreveu:

> On Thu, Aug 5, 2021 at 1:58 AM Mauro Carvalho Chehab
> <mchehab+huawei at kernel.org> wrote:
> >
> > Em Thu, 5 Aug 2021 09:46:12 +0200
> > Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:
> >  
> > > Em Wed, 4 Aug 2021 10:28:53 -0600
> > > Rob Herring <robh at kernel.org> escreveu:
> > >  
> > > > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:  
> > > > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > > > Rob Herring <robh+dt at kernel.org> escreveu:
> > > > >  
> > > > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > > > <mchehab+huawei at kernel.org> wrote:  
> > > > > > >
> > > > > > > Hi Rob,
> > > > > > >
> > > > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > > > corresponding PHY.
> > > > > > >
> > > > > > > It is identical to v2, except by:
> > > > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > > > >         +          pcie at 7,0 { // Lane 6: Ethernet  
> > > > > >
> > > > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > > > devices? If you don't, then something is wrong still in the topology
> > > > > > or the PCI core is failing to set the DT node pointer in struct
> > > > > > device. Though you don't rely on that currently, we want the topology
> > > > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > > > powerpc relied on this.
> > > > > >
> > > > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > > > could have a tool that generates the DT structure based on the PCI
> > > > > > topology.  
> > > > >
> > > > > The of_node node link is on those places:
> > > > >
> > > > >   $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > > >   /sys/devices/platform/soc/f4000000.pcie/of_node
> > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node  
> > > >
> > > > Looks like we're missing some...
> > > >
> > > > It's not immediately obvious to me what's wrong here. Only the root
> > > > bus is getting it's DT node set. The relevant code is pci_scan_device(),
> > > > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try
> > > > to reproduce and debug it.  
> > >
> > > I added a printk on both pci_set_*of_node() functions:
> > >
> > >       [    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > >       [    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> > >       [    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > >       [    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > >       [    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > >       [    5.059263]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.085552]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.112073]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.138320]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.164673]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > >       [    5.240539]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > >       [    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > >       [    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > >       [    5.345516]  (null): pci_set_of_node: of_node: (null)
> > >       [    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)  
> >
> > The enclosed patch makes the above a clearer:
> >
> >         [    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> >         [    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> >         [    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> >         [    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> >         [    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)  
> 
> I believe the issue is we need another bridge node in the DT
> hierarchy. What we have is:
> 
> Bus 0 is node /soc/pcie at f4000000
> Bus 1 is device 0 on bus 0 is node /soc/pcie at f4000000/pcie at 0,0
> Bus 2 is device 0 on bus 1 in node ... whoops, there's no device 0
> under /soc/pcie at f4000000/pcie at 0,0
> 
> So we need the hierarchy to be: /soc/pcie at f4000000/pcie at 0/pcie at 0/pcie@{1,5,7}

Adding a child pcie at 0 produces the following output from my debug
patches:

[    4.984278]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
[    5.042992] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
[    5.083738] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
[    5.124377] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
[    5.168395] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    5.200719] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    5.247777] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    5.276768] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    5.305018] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    5.333093] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    5.395620] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
[    5.416333] pci 0000:03:00.0: pci_set_of_node: of_node: (null)
[    5.451353] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
[    5.473970] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
[    5.487765] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
[    5.530219] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
[    5.560896] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)

It produces the following sysfs nodes:

	$ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
	/sys/devices/platform/soc/f4000000.pcie/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
	/sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node


I'm enclosing the DT schema I'm using.



Thanks,
Mauro

---

		pcie at f4000000 {
			compatible = "hisilicon,kirin970-pcie";
			reg = <0x0 0xf4000000 0x0 0x1000000>,
			      <0x0 0xfc180000 0x0 0x1000>,
			      <0x0 0xf5000000 0x0 0x2000>;
			reg-names = "dbi", "apb", "config";
			bus-range = <0x00 0xff>;
			#address-cells = <3>;
			#size-cells = <2>;
			device_type = "pci";
			phys = <&pcie_phy>;
			ranges = <0x02000000 0x0 0x00000000
				  0x0 0xf6000000
				  0x0 0x02000000>;
			num-lanes = <1>;
			#interrupt-cells = <1>;
			interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
			interrupt-names = "msi";
			interrupt-map-mask = <0 0 0 7>;
			interrupt-map = <0x0 0 0 1
					 &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
					<0x0 0 0 2
					 &gic GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
					<0x0 0 0 3
					 &gic GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
					<0x0 0 0 4
					 &gic GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
			reset-gpios = <&gpio7 0 0>;
			hisilicon,clken-gpios = <&gpio27 3 0>, <&gpio17 0 0>,
						<&gpio20 6 0>;
			pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
				reg = <0x80 0 0 0 0>;
				compatible = "pciclass,0604";
				device_type = "pci";
				#address-cells = <3>;
				#size-cells = <2>;
				ranges;
				bus-range = <0x01 0xff>;
				msi-parent = <&its_pcie>;

				pcie at 0,0 { // Lane 0: upstream
					reg = <0x010000 0 0 0 0>;
					compatible = "pciclass,0604";
					device_type = "pci";
					#address-cells = <3>;
					#size-cells = <2>;
					ranges;
				};
				pcie at 1,0 { // Lane 4: M.2
					reg = <0x010800 0 0 0 0>;
					compatible = "pciclass,0604";
					device_type = "pci";
					reset-gpios = <&gpio3 1 0>;
					#address-cells = <3>;
					#size-cells = <2>;
					ranges;
				};

				pcie at 5,0 { // Lane 5: Mini PCIe
					reg = <0x012800 0 0 0 0>;
					compatible = "pciclass,0604";
					device_type = "pci";
					reset-gpios = <&gpio27 4 0 >;
					#address-cells = <3>;
					#size-cells = <2>;
					ranges;
				};

				pcie at 7,0 { // Lane 6: Ethernet
					reg = <0x013800 0 0 0 0>;
					compatible = "pciclass,0604";
					device_type = "pci";
					reset-gpios = <&gpio25 2 0 >;
					#address-cells = <3>;
					#size-cells = <2>;
					ranges;
				};
			};
		};





From mchehab+huawei at kernel.org  Tue Aug 10 02:55:31 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 10 Aug 2021 11:55:31 +0200
Subject: [PATCH v10 00/11] Add support for Hikey 970 PCIe
Message-ID: <cover.1628589155.git.mchehab+huawei@kernel.org>

The DT schema used by this series got merged at:

	https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=dt/next

The series should apply cleanly on the top of v5.14-rc1.

patch1 contains a PHY for Kirin 970 PCIe.

The remaining patches add support for Kirin 970 at the pcie-kirin driver, and
add the needed logic to compile it as module and to allow to dynamically
remove the driver in runtime.

Tested on HiKey970:

  # lspci -D -PP
  0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3670 (rev 01)
  0000:00:00.0/01:00.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:01.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:04.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:05.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:07.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:09.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:01.0/03:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a809
  0000:00:00.0/01:00.0/02:07.0/06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 07)

Tested on HiKey960:

  # lspci -D 
  0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3660 (rev 01)

---

v10:
  - patch 1: dropped magic numbers from PHY driver
  - patch 5: allow pcie child nodes without reset-gpios
  - remaining patches untouched.

v9:
  - Did some cleanups at patches 1 and 5


Mauro Carvalho Chehab (11):
  phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
  PCI: kirin: Reorganize the PHY logic inside the driver
  PCI: kirin: Add support for a PHY layer
  PCI: kirin: Use regmap for APB registers
  PCI: kirin: Add support for bridge slot DT schema
  PCI: kirin: Add Kirin 970 compatible
  PCI: kirin: Add MODULE_* macros
  PCI: kirin: Allow building it as a module
  PCI: kirin: Add power_off support for Kirin 960 PHY
  PCI: kirin: fix poweroff sequence
  PCI: kirin: Allow removing the driver

 drivers/pci/controller/dwc/Kconfig      |   2 +-
 drivers/pci/controller/dwc/pcie-kirin.c | 642 ++++++++++++++----
 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 857 ++++++++++++++++++++++++
 5 files changed, 1364 insertions(+), 148 deletions(-)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

-- 
2.31.1




From mchehab+huawei at kernel.org  Tue Aug 10 02:55:32 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 10 Aug 2021 11:55:32 +0200
Subject: [PATCH v10 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
In-Reply-To: <cover.1628589155.git.mchehab+huawei@kernel.org>
References: <cover.1628589155.git.mchehab+huawei@kernel.org>
Message-ID: <27949209dc3607637a930e9df64ccbf9243b09fa.1628589155.git.mchehab+huawei@kernel.org>

The Kirin 970 PHY is somewhat similar to the Kirin 960, but it
does a lot more. Add the needed bits for PCIe to start working on
HiKey 970 boards.

Co-developed-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 857 ++++++++++++++++++++++++
 3 files changed, 868 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 4d008cfc279c..d3b92c288554 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -33,6 +33,16 @@ config PHY_HI3670_USB
 
 	  To compile this driver as a module, choose M here.
 
+config PHY_HI3670_PCIE
+	tristate "hi3670 PCIe PHY support"
+	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+	select GENERIC_PHY
+	select MFD_SYSCON
+	help
+	  Enable this to support the HiSilicon hi3670 PCIe PHY.
+
+	  To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
 	tristate "HiSilicon STB SoCs COMBPHY support"
 	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 51729868145b..4029d3813b1e 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_HI6220_USB)		+= phy-hi6220-usb.o
 obj-$(CONFIG_PHY_HI3660_USB)		+= phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HI3670_USB)		+= phy-hi3670-usb3.o
+obj-$(CONFIG_PHY_HI3670_PCIE)		+= phy-hi3670-pcie.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)		+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)	+= phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
new file mode 100644
index 000000000000..2d2c35ed7652
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -0,0 +1,857 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe phy driver for Kirin 970
+ *
+ * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
+ *		https://www.huawei.com
+ * Copyright (C) 2021 Huawei Technologies Co., Ltd.
+ *		https://www.huawei.com
+ *
+ * Authors:
+ *	Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+ *	Manivannan Sadhasivam <mani at kernel.org>
+ *
+ * Based on:
+ *	https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei at kernel.org/
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AXI_CLK_FREQ				207500000
+#define REF_CLK_FREQ				100000000
+
+/* PCIe CTRL registers */
+#define SOC_PCIECTRL_CTRL0_ADDR			0x000
+#define SOC_PCIECTRL_CTRL1_ADDR			0x004
+#define SOC_PCIECTRL_CTRL7_ADDR			0x01c
+#define SOC_PCIECTRL_CTRL12_ADDR		0x030
+#define SOC_PCIECTRL_CTRL20_ADDR		0x050
+#define SOC_PCIECTRL_CTRL21_ADDR		0x054
+#define SOC_PCIECTRL_STATE0_ADDR		0x400
+
+#define PCIE_OUTPUT_PULL_BITS			GENMASK(3, 0)
+#define SOC_PCIECTRL_CTRL20_2P_MEM_CTRL		0x02605550
+#define SOC_PCIECTRL_CTRL21_DEFAULT		0x20000070
+#define PCIE_PULL_UP_SYS_AUX_PWR_DET		BIT(10)
+#define PCIE_OUTPUT_PULL_DOWN			BIT(1)
+
+/* PCIe PHY registers */
+#define SOC_PCIEPHY_CTRL0_ADDR			0x000
+#define SOC_PCIEPHY_CTRL1_ADDR			0x004
+#define SOC_PCIEPHY_CTRL2_ADDR			0x008
+#define SOC_PCIEPHY_CTRL3_ADDR			0x00c
+#define SOC_PCIEPHY_CTRL38_ADDR			0x0098
+#define SOC_PCIEPHY_STATE0_ADDR			0x400
+
+#define PORT_MSI_CTRL_ADDR			0x820
+#define PORT_MSI_CTRL_UPPER_ADDR		0x824
+#define PORT_MSI_CTRL_INT0_ENABLE		0x828
+
+#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1	0xc004
+#define SUP_DIG_LVL_OVRD_IN			0x003c
+#define LANEN_DIG_ASIC_TX_OVRD_IN_1		0x4008
+#define LANEN_DIG_ASIC_TX_OVRD_IN_2		0x400c
+
+#define PCIE_LINKUP_ENABLE			0x8020
+#define PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
+#define PCIE_LTSSM_ENABLE_BIT			BIT(11)
+#define PCIEPHY_RESET_BIT			BIT(17)
+#define PCIEPHY_PIPE_LINE0_RESET_BIT		BIT(19)
+#define PCIE_TXDETECT_RX_FAIL			BIT(2)
+#define PCIE_CLK_SOURCE				BIT(8)
+#define PCIE_IS_CLOCK_STABLE			BIT(19)
+#define PCIE_PULL_DOWN_PHY_TEST_POWERDOWN	BIT(22)
+#define PCIE_DEASSERT_CONTROLLER_PERST		BIT(2)
+
+#define EYEPARAM_NOCFG				0xffffffff
+#define EYE_PARM0_MASK				GENMASK(8, 6)
+#define EYE_PARM1_MASK				GENMASK(11, 8)
+#define EYE_PARM2_MASK				GENMASK(5, 0)
+#define EYE_PARM3_MASK				GENMASK(12, 7)
+#define EYE_PARM4_MASK				GENMASK(14, 9)
+#define EYE_PARM0_EN				BIT(9)
+#define EYE_PARM1_EN				BIT(12)
+#define EYE_PARM2_EN				BIT(6)
+#define EYE_PARM3_EN				BIT(13)
+#define EYE_PARM4_EN				BIT(15)
+
+/* hi3670 pciephy register */
+#define APB_PHY_START_ADDR			0x40000
+#define SOC_PCIEPHY_MMC1PLL_CTRL1		0xc04
+#define SOC_PCIEPHY_MMC1PLL_CTRL16		0xC40
+#define SOC_PCIEPHY_MMC1PLL_CTRL17		0xC44
+#define SOC_PCIEPHY_MMC1PLL_CTRL20		0xC50
+#define SOC_PCIEPHY_MMC1PLL_CTRL21		0xC54
+#define SOC_PCIEPHY_MMC1PLL_STAT0		0xE00
+
+#define CRGPERIPH_PEREN12			0x470
+#define CRGPERIPH_PERDIS12			0x474
+#define CRGPERIPH_PCIECTRL0			0x800
+
+#define PCIE_FNPLL_FBDIV_MASK			GENMASK(27, 16)
+#define PCIE_FNPLL_FRACDIV_MASK			GENMASK(23, 0)
+#define PCIE_FNPLL_POSTDIV1_MASK		GENMASK(10, 8)
+#define PCIE_FNPLL_POSTDIV2_MASK		GENMASK(14, 12)
+#define PCIE_FNPLL_PLL_MODE_MASK		BIT(25)
+
+#define PCIE_FNPLL_DLL_EN			BIT(27)
+#define PCIE_FNPLL_FBDIV			0xd0
+#define PCIE_FNPLL_FRACDIV			0x555555
+#define PCIE_FNPLL_POSTDIV1			0x5
+#define PCIE_FNPLL_POSTDIV2			0x4
+#define PCIE_FNPLL_PLL_MODE			0x0
+
+#define PCIE_PHY_MMC1PLL			0x20
+#define PCIE_PHY_CHOOSE_FNPLL			BIT(27)
+#define PCIE_PHY_MMC1PLL_DISABLE		BIT(0)
+#define PCIE_PHY_PCIEPL_BP			BIT(16)
+
+/* define ie,oe cfg */
+#define IO_OE_HARD_GT_MODE			BIT(1)
+#define IO_IE_EN_HARD_BYPASS			BIT(27)
+#define IO_OE_EN_HARD_BYPASS			BIT(11)
+#define IO_HARD_CTRL_DEBOUNCE_BYPASS		BIT(10)
+#define IO_OE_GT_MODE				BIT(8)
+#define DEBOUNCE_WAITCFG_IN			GENMASK(23, 20)
+#define DEBOUNCE_WAITCFG_OUT			GENMASK(16, 13)
+
+#define IO_HP_DEBOUNCE_GT			(BIT(12) | BIT(15))
+#define IO_PHYREF_SOFT_GT_MODE			BIT(14)
+#define IO_REF_SOFT_GT_MODE			BIT(13)
+#define IO_REF_HARD_GT_MODE			BIT(0)
+
+/* noc power domain */
+#define NOC_POWER_IDLEREQ_1			0x38c
+#define NOC_POWER_IDLE_1			0x394
+#define NOC_PW_MASK				0x10000
+#define NOC_PW_SET_BIT				0x1
+
+#define NUM_EYEPARAM				5
+
+/* info located in sysctrl */
+#define SCTRL_PCIE_CMOS_OFFSET			0x60
+#define SCTRL_PCIE_CMOS_BIT			0x10
+#define SCTRL_PCIE_ISO_OFFSET			0x44
+#define SCTRL_PCIE_ISO_BIT			0x30
+#define SCTRL_PCIE_HPCLK_OFFSET			0x190
+#define SCTRL_PCIE_HPCLK_BIT			0x184000
+#define SCTRL_PCIE_OE_OFFSET			0x14a
+#define PCIE_DEBOUNCE_PARAM			0xf0f400
+#define PCIE_OE_BYPASS				GENMASK(29, 28)
+
+/* peri_crg ctrl */
+#define CRGCTRL_PCIE_ASSERT_OFFSET		0x88
+#define CRGCTRL_PCIE_ASSERT_BIT			0x8c000000
+
+#define FNPLL_HAS_LOCKED			BIT(4)
+
+/* Time for delay */
+#define PIPE_CLK_WAIT_MIN	550
+#define PIPE_CLK_WAIT_MAX	600
+#define TIME_CMOS_MIN		100
+#define TIME_CMOS_MAX		105
+#define TIME_PHY_PD_MIN		10
+#define TIME_PHY_PD_MAX		11
+
+#define PIPE_CLK_STABLE_TIME	100
+#define PLL_CTRL_WAIT_TIME	200
+#define NOC_POWER_TIME		100
+
+struct hi3670_pcie_phy {
+	struct device	*dev;
+	void __iomem	*base;
+	struct regmap	*apb;
+	struct regmap	*crgctrl;
+	struct regmap	*sysctrl;
+	struct regmap	*pmctrl;
+	struct clk	*apb_sys_clk;
+	struct clk	*apb_phy_clk;
+	struct clk	*phy_ref_clk;
+	struct clk	*aclk;
+	struct clk	*aux_clk;
+	u32		eye_param[NUM_EYEPARAM];
+};
+
+/* Registers in PCIePHY */
+static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy, u32 val,
+					 u32 reg)
+{
+	writel(val, phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
+{
+	return readl(phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
+						u32 val, u32 reg)
+{
+	writel(val, phy->base + reg);
+}
+
+static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
+					      u32 reg)
+{
+	return readl(phy->base + reg);
+}
+
+static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
+{
+	u32 val;
+
+	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
+	val |= PCIE_DEBOUNCE_PARAM;
+	if (enable)
+		val &= ~PCIE_OE_BYPASS;
+	else
+		val |= PCIE_OE_BYPASS;
+	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
+}
+
+static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np;
+	int ret, i;
+
+	np = dev->of_node;
+
+	ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
+					 phy->eye_param, NUM_EYEPARAM);
+	if (!ret)
+		return;
+
+	/* There's no optional eye_param property. Set array to default */
+	for (i = 0; i < NUM_EYEPARAM; i++)
+		phy->eye_param[i] = EYEPARAM_NOCFG;
+}
+
+static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = kirin_apb_natural_phy_readl(phy,
+					  RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM1_MASK;
+		val |= FIELD_PREP(EYE_PARM1_MASK, phy->eye_param[1]);
+		val |= EYE_PARM1_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val,
+				     RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+	val &= ~(EYE_PARM2_MASK | EYE_PARM3_MASK);
+	if (phy->eye_param[2] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM2_MASK, phy->eye_param[2]);
+		val |= EYE_PARM2_EN;
+	}
+
+	if (phy->eye_param[3] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM3_MASK, phy->eye_param[3]);
+		val |= EYE_PARM3_EN;
+	}
+
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+
+	val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
+	if (phy->eye_param[0] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM0_MASK;
+		val |= FIELD_PREP(EYE_PARM0_MASK, phy->eye_param[0]);
+		val |= EYE_PARM0_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+	if (phy->eye_param[4] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM4_MASK;
+		val |= FIELD_PREP(EYE_PARM4_MASK, phy->eye_param[4]);
+		val |= EYE_PARM4_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+}
+
+static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* change 2p mem_ctrl */
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
+		     SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
+
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
+	val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
+
+	/* output, pull down */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val &= ~PCIE_OUTPUT_PULL_BITS;
+	val |= PCIE_OUTPUT_PULL_DOWN;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+
+	/* Handle phy_reset and lane0_reset to HW */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
+	val |= PCIEPHY_RESET_BIT;
+	val &= ~PCIEPHY_PIPE_LINE0_RESET_BIT;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
+
+	/* fix chip bug: TxDetectRx fail */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL38_ADDR);
+	val |= PCIE_TXDETECT_RX_FAIL;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL38_ADDR);
+}
+
+static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL1);
+	val |= PCIE_PHY_CHOOSE_FNPLL;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL1);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+	val &= ~PCIE_FNPLL_FBDIV_MASK;
+	val |= FIELD_PREP(PCIE_FNPLL_FBDIV_MASK, PCIE_FNPLL_FBDIV);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL17);
+	val &= PCIE_FNPLL_FRACDIV_MASK;
+	val |= FIELD_PREP(PCIE_FNPLL_FRACDIV_MASK, PCIE_FNPLL_FRACDIV);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL17);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+	val &= ~(PCIE_FNPLL_POSTDIV1_MASK | PCIE_FNPLL_POSTDIV2_MASK |
+		 PCIE_FNPLL_PLL_MODE_MASK | PCIE_FNPLL_DLL_EN);
+	val |= PCIE_FNPLL_DLL_EN;
+	val |= FIELD_PREP(PCIE_FNPLL_POSTDIV1_MASK, PCIE_FNPLL_POSTDIV1);
+	val |= FIELD_PREP(PCIE_FNPLL_POSTDIV2_MASK, PCIE_FNPLL_POSTDIV2);
+	val |= FIELD_PREP(PCIE_FNPLL_PLL_MODE_MASK, PCIE_FNPLL_PLL_MODE);
+
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	hi3670_apb_phy_writel(phy, PCIE_PHY_MMC1PLL,
+			      SOC_PCIEPHY_MMC1PLL_CTRL21);
+}
+
+static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int time = PLL_CTRL_WAIT_TIME;
+
+	if (enable) {
+		/* pd = 0 */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+		val &= ~PCIE_PHY_MMC1PLL_DISABLE;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+
+		/* choose FNPLL */
+		while (!(val & FNPLL_HAS_LOCKED)) {
+			if (!time) {
+				dev_err(dev, "wait for pll_lock timeout\n");
+				return -EINVAL;
+			}
+			time--;
+			udelay(1);
+			val = hi3670_apb_phy_readl(phy,
+						   SOC_PCIEPHY_MMC1PLL_STAT0);
+		}
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+		val &= ~PCIE_PHY_PCIEPL_BP;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	} else {
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+		val |= PCIE_PHY_MMC1PLL_DISABLE;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+		val |= PCIE_PHY_PCIEPL_BP;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+	}
+
+	return 0;
+}
+
+static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	if (open)
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
+		regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
+			     IO_HP_DEBOUNCE_GT);
+	else
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_HP_DEBOUNCE_GT);
+}
+
+static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	if (open)
+		val &= ~IO_OE_HARD_GT_MODE; // enable hard gt mode
+	else
+		val |= IO_OE_HARD_GT_MODE; // disable hard gt mode
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+	/* disable soft gt mode */
+	regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, IO_PHYREF_SOFT_GT_MODE);
+}
+
+static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	/* set ie cfg */
+	val |= IO_IE_EN_HARD_BYPASS;
+
+	/* set oe cfg */
+	val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
+
+	/* set phy_debounce in&out time */
+	val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
+
+	/* select oe_gt_mode */
+	val |= IO_OE_GT_MODE;
+
+	if (en_flag)
+		val &= ~IO_OE_EN_HARD_BYPASS;
+	else
+		val |= IO_OE_EN_HARD_BYPASS;
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+}
+
+static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	if (open) {
+		regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR,
+			     SOC_PCIECTRL_CTRL21_DEFAULT);
+
+		hi3670_pcie_oe_ctrl(phy, true);
+
+		/* en hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val &= ~IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+	} else {
+		/* disable hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val |= IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+		hi3670_pcie_oe_ctrl(phy, false);
+	}
+}
+
+static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int ret = 0;
+
+	if (!clk_on)
+		goto close_clocks;
+
+	/* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
+	val &= ~PCIE_CLK_SOURCE;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
+
+	hi3670_pcie_pll_init(phy);
+
+	ret = hi3670_pcie_pll_ctrl(phy, true);
+	if (ret) {
+		dev_err(dev, "Failed to enable pll\n");
+		return -EINVAL;
+	}
+	hi3670_pcie_hp_debounce_gt(phy, true);
+	hi3670_pcie_phyref_gt(phy, true);
+	hi3670_pcie_ioref_gt(phy, true);
+
+	ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
+	if (ret) {
+		dev_err(dev, "Failed to set rate\n");
+		goto close_clocks;
+	}
+
+	return 0;
+
+close_clocks:
+	hi3670_pcie_ioref_gt(phy, false);
+	hi3670_pcie_phyref_gt(phy, false);
+	hi3670_pcie_hp_debounce_gt(phy, false);
+
+	hi3670_pcie_pll_ctrl(phy, false);
+
+	return ret;
+}
+
+static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	u32 time = PIPE_CLK_STABLE_TIME;
+	u32 pipe_clk_stable = PCIE_IS_CLOCK_STABLE;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	while (val & pipe_clk_stable) {
+		mdelay(1);
+		if (!time) {
+			dev_err(dev, "PIPE clk is not stable\n");
+			return false;
+		}
+		time--;
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	}
+
+	return true;
+}
+
+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 time = NOC_POWER_TIME;
+	unsigned int val = NOC_PW_MASK;
+	int rst;
+
+	if (enable)
+		val = NOC_PW_MASK | NOC_PW_SET_BIT;
+	else
+		val = NOC_PW_MASK;
+	rst = enable ? 1 : 0;
+
+	regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
+
+	time = NOC_POWER_TIME;
+	regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	while ((val & NOC_PW_SET_BIT) != rst) {
+		udelay(10);
+		if (!time) {
+			dev_err(dev, "Failed to reverse noc power-status\n");
+			return -EINVAL;
+		}
+		time--;
+		regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	}
+
+	return 0;
+}
+
+static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
+{
+	struct device_node *pcie_port;
+	struct device *dev = phy->dev;
+	struct device *pcie_dev;
+
+	pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
+	if (!pcie_port) {
+		dev_err(dev, "no pcie node found in %s\n",
+			dev->parent->of_node->full_name);
+		return -ENODEV;
+	}
+
+	pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
+	if (!pcie_dev) {
+		dev_err(dev, "Didn't find pcie device\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * We might just use NULL instead of the APB name, as the
+	 * pcie-kirin currently registers directly just one regmap (although
+	 * the DWC driver register other regmaps).
+	 *
+	 * Yet, it sounds safer to warrant that it will be accessing the
+	 * right regmap. So, let's use the named version.
+	 */
+	phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
+	if (!phy->apb) {
+		dev_err(dev, "Failed to get APB regmap\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto close_clk;
+
+	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->phy_ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->apb_sys_clk);
+	if (ret)
+		goto apb_sys_fail;
+
+	ret = clk_prepare_enable(phy->apb_phy_clk);
+	if (ret)
+		goto apb_phy_fail;
+
+	ret = clk_prepare_enable(phy->aclk);
+	if (ret)
+		goto aclk_fail;
+
+	ret = clk_prepare_enable(phy->aux_clk);
+	if (ret)
+		goto aux_clk_fail;
+
+	return 0;
+
+close_clk:
+	clk_disable_unprepare(phy->aux_clk);
+aux_clk_fail:
+	clk_disable_unprepare(phy->aclk);
+aclk_fail:
+	clk_disable_unprepare(phy->apb_phy_clk);
+apb_phy_fail:
+	clk_disable_unprepare(phy->apb_sys_clk);
+apb_sys_fail:
+	clk_disable_unprepare(phy->phy_ref_clk);
+
+	return ret;
+}
+
+static int hi3670_pcie_phy_init(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int ret;
+
+	/*
+	 * The code under hi3670_pcie_get_resources_from_pcie() need to
+	 * access the reset-gpios and the APB registers, both from the
+	 * pcie-kirin driver.
+	 *
+	 * The APB is obtained via the pcie driver's regmap
+	 * Such kind of resource can only be obtained during the PCIe
+	 * power_on sequence, as the code inside pcie-kirin needs to
+	 * be already probed, as it needs to register the APB regmap.
+	 */
+
+	ret = hi3670_pcie_get_resources_from_pcie(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int val, ret;
+
+	/* Power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
+	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
+
+	hi3670_pcie_phy_oe_enable(phy, true);
+
+	ret = kirin_pcie_clk_ctrl(phy, true);
+	if (ret)
+		return ret;
+
+	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
+	regmap_write(phy->crgctrl, CRGCTRL_PCIE_ASSERT_OFFSET,
+		     CRGCTRL_PCIE_ASSERT_BIT);
+	regmap_write(phy->sysctrl, SCTRL_PCIE_HPCLK_OFFSET,
+		     SCTRL_PCIE_HPCLK_BIT);
+
+	hi3670_pcie_natural_cfg(phy);
+
+	ret = hi3670_pcie_allclk_ctrl(phy, true);
+	if (ret)
+		goto disable_clks;
+
+	/* pull down phy_test_powerdown signal */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL0_ADDR);
+	val &= ~PCIE_PULL_DOWN_PHY_TEST_POWERDOWN;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL0_ADDR);
+
+	/* deassert controller perst_n */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val |= PCIE_DEASSERT_CONTROLLER_PERST;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+	udelay(10);
+
+	ret = is_pipe_clk_stable(phy);
+	if (!ret)
+		goto disable_clks;
+
+	hi3670_pcie_set_eyeparam(phy);
+
+	ret = hi3670_pcie_noc_power(phy, false);
+	if (ret)
+		goto disable_clks;
+
+	return 0;
+
+disable_clks:
+	kirin_pcie_clk_ctrl(phy, false);
+	return ret;
+}
+
+static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+
+	hi3670_pcie_phy_oe_enable(phy, false);
+
+	hi3670_pcie_allclk_ctrl(phy, false);
+
+	/* Drop power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
+
+	/* FIXME: calling it causes an Asynchronous SError interrupt */
+//	kirin_pcie_clk_ctrl(phy, false);
+
+	return 0;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+	.init		= hi3670_pcie_phy_init,
+	.power_on	= hi3670_pcie_phy_power_on,
+	.power_off	= hi3670_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
+					 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* syscon */
+	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
+	if (IS_ERR(phy->crgctrl))
+		return PTR_ERR(phy->crgctrl);
+
+	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	/* clocks */
+	phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
+	if (IS_ERR(phy->phy_ref_clk))
+		return PTR_ERR(phy->phy_ref_clk);
+
+	phy->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(phy->aux_clk))
+		return PTR_ERR(phy->aux_clk);
+
+	phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
+	if (IS_ERR(phy->apb_phy_clk))
+		return PTR_ERR(phy->apb_phy_clk);
+
+	phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
+	if (IS_ERR(phy->apb_sys_clk))
+		return PTR_ERR(phy->apb_sys_clk);
+
+	phy->aclk = devm_clk_get(dev, "aclk");
+	if (IS_ERR(phy->aclk))
+		return PTR_ERR(phy->aclk);
+
+	/* registers */
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	hi3670_pcie_get_eyeparam(phy);
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct hi3670_pcie_phy *phy;
+	struct phy *generic_phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+
+	ret = hi3670_pcie_phy_get_resources(phy, pdev);
+	if (ret)
+		return ret;
+
+	generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_pcie_phy_match[] = {
+	{
+		.compatible = "hisilicon,hi970-pcie-phy",
+	},
+	{},
+};
+
+static struct platform_driver hi3670_pcie_phy_driver = {
+	.probe	= hi3670_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= hi3670_pcie_phy_match,
+		.name		= "hi3670_pcie_phy",
+		.suppress_bind_attrs = true,
+	}
+};
+builtin_platform_driver(hi3670_pcie_phy_driver);
+
+MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
+MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab at kernel.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <mani at kernel.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1



From linus.walleij at linaro.org  Tue Aug 10 06:27:15 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 15:27:15 +0200
Subject: [PATCH 6/9] pinctrl: pistachio: Make it as a option
In-Reply-To: <c7de97c3-196b-6bc3-a8b1-d6c6e6ab583d@flygoat.com>
References: <20210627045631.2882-1-jiaxun.yang@flygoat.com>
 <20210627045631.2882-7-jiaxun.yang@flygoat.com>
 <CACRpkdZkvSg___ZxdE639SMbTs5rJbjHBq-HkTCuv0e645Rssg@mail.gmail.com>
 <c7de97c3-196b-6bc3-a8b1-d6c6e6ab583d@flygoat.com>
Message-ID: <CACRpkdZjdNasty5g1K5nL+fztN+LPgwYog91bi-UvVH39TXMkg@mail.gmail.com>

On Sun, Jul 25, 2021 at 4:49 AM Jiaxun Yang <jiaxun.yang at flygoat.com> wrote:
> ? 2021/7/24 ??12:13, Linus Walleij ??:
> > On Sun, Jun 27, 2021 at 6:57 AM Jiaxun Yang <jiaxun.yang at flygoat.com> wrote:
> >
> >> So it will be avilable for generic MIPS kernel.
> >>
> >> Signed-off-by: Jiaxun Yang <jiaxun.yang at flygoat.com>
> > Is this solved, or should I apply this patch?
>
> I guess so, btw I think it should go via MIPS tree to avoid troubles.

OK feel free to merge this in the MIPS tree then:
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Aug 10 06:27:56 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 15:27:56 +0200
Subject: [PATCH v4 6/9] pinctrl: pistachio: Make it as an option
In-Reply-To: <20210723022543.4095-7-jiaxun.yang@flygoat.com>
References: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
 <20210723022543.4095-7-jiaxun.yang@flygoat.com>
Message-ID: <CACRpkdYVcCW2yD_Xva+cog7i5C=YokMw+52i7iq0Nj2vVbWacA@mail.gmail.com>

On Fri, Jul 23, 2021 at 4:26 AM Jiaxun Yang <jiaxun.yang at flygoat.com> wrote:

> So it will be avilable for generic MIPS kernel.
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang at flygoat.com>
> --
> v3: Depend on OF as well

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From robh at kernel.org  Tue Aug 10 06:44:50 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Aug 2021 07:44:50 -0600
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <20210810114211.01df0246@coco.lan>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan> <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan> <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
Message-ID: <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>

On Tue, Aug 10, 2021 at 3:42 AM Mauro Carvalho Chehab
<mchehab+huawei at kernel.org> wrote:
>
> Em Fri, 6 Aug 2021 10:23:35 -0600
> Rob Herring <robh at kernel.org> escreveu:
>
> > On Thu, Aug 5, 2021 at 1:58 AM Mauro Carvalho Chehab
> > <mchehab+huawei at kernel.org> wrote:
> > >
> > > Em Thu, 5 Aug 2021 09:46:12 +0200
> > > Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:
> > >
> > > > Em Wed, 4 Aug 2021 10:28:53 -0600
> > > > Rob Herring <robh at kernel.org> escreveu:
> > > >
> > > > > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:
> > > > > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > > > > Rob Herring <robh+dt at kernel.org> escreveu:
> > > > > >
> > > > > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > > > > <mchehab+huawei at kernel.org> wrote:
> > > > > > > >
> > > > > > > > Hi Rob,
> > > > > > > >
> > > > > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > > > > corresponding PHY.
> > > > > > > >
> > > > > > > > It is identical to v2, except by:
> > > > > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > > > > >         +          pcie at 7,0 { // Lane 6: Ethernet
> > > > > > >
> > > > > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > > > > devices? If you don't, then something is wrong still in the topology
> > > > > > > or the PCI core is failing to set the DT node pointer in struct
> > > > > > > device. Though you don't rely on that currently, we want the topology
> > > > > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > > > > powerpc relied on this.
> > > > > > >
> > > > > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > > > > could have a tool that generates the DT structure based on the PCI
> > > > > > > topology.
> > > > > >
> > > > > > The of_node node link is on those places:
> > > > > >
> > > > > >   $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > > > >   /sys/devices/platform/soc/f4000000.pcie/of_node
> > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> > > > >
> > > > > Looks like we're missing some...
> > > > >
> > > > > It's not immediately obvious to me what's wrong here. Only the root
> > > > > bus is getting it's DT node set. The relevant code is pci_scan_device(),
> > > > > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try
> > > > > to reproduce and debug it.
> > > >
> > > > I added a printk on both pci_set_*of_node() functions:
> > > >
> > > >       [    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > >       [    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> > > >       [    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > >       [    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > >       [    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > > >       [    5.059263]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.085552]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.112073]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.138320]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.164673]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > > >       [    5.240539]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > > >       [    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > > >       [    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > > >       [    5.345516]  (null): pci_set_of_node: of_node: (null)
> > > >       [    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
> > >
> > > The enclosed patch makes the above a clearer:
> > >
> > >         [    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > >         [    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > >         [    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > >         [    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > >         [    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> >
> > I believe the issue is we need another bridge node in the DT
> > hierarchy. What we have is:
> >
> > Bus 0 is node /soc/pcie at f4000000
> > Bus 1 is device 0 on bus 0 is node /soc/pcie at f4000000/pcie at 0,0
> > Bus 2 is device 0 on bus 1 in node ... whoops, there's no device 0
> > under /soc/pcie at f4000000/pcie at 0,0
> >
> > So we need the hierarchy to be: /soc/pcie at f4000000/pcie at 0/pcie at 0/pcie@{1,5,7}
>
> Adding a child pcie at 0 produces the following output from my debug
> patches:

You removed your changes to the PCI code other than the debug print?
>
> [    4.984278]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> [    5.042992] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> [    5.083738] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> [    5.124377] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> [    5.168395] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> [    5.200719] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0

This should not happen. The devfn doesn't match.

> [    5.247777] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> [    5.276768] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> [    5.305018] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> [    5.333093] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> [    5.395620] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> [    5.416333] pci 0000:03:00.0: pci_set_of_node: of_node: (null)
> [    5.451353] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> [    5.473970] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> [    5.487765] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> [    5.530219] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
> [    5.560896] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
>
> It produces the following sysfs nodes:
>
>         $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
>         /sys/devices/platform/soc/f4000000.pcie/of_node
>         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
>         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node
>         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node
>         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
>         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
>
>
> I'm enclosing the DT schema I'm using.
>
>
>
> Thanks,
> Mauro
>
> ---
>
>                 pcie at f4000000 {
>                         compatible = "hisilicon,kirin970-pcie";
>                         reg = <0x0 0xf4000000 0x0 0x1000000>,
>                               <0x0 0xfc180000 0x0 0x1000>,
>                               <0x0 0xf5000000 0x0 0x2000>;
>                         reg-names = "dbi", "apb", "config";
>                         bus-range = <0x00 0xff>;
>                         #address-cells = <3>;
>                         #size-cells = <2>;
>                         device_type = "pci";
>                         phys = <&pcie_phy>;
>                         ranges = <0x02000000 0x0 0x00000000
>                                   0x0 0xf6000000
>                                   0x0 0x02000000>;
>                         num-lanes = <1>;
>                         #interrupt-cells = <1>;
>                         interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
>                         interrupt-names = "msi";
>                         interrupt-map-mask = <0 0 0 7>;
>                         interrupt-map = <0x0 0 0 1
>                                          &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
>                                         <0x0 0 0 2
>                                          &gic GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
>                                         <0x0 0 0 3
>                                          &gic GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
>                                         <0x0 0 0 4
>                                          &gic GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
>                         reset-gpios = <&gpio7 0 0>;
>                         hisilicon,clken-gpios = <&gpio27 3 0>, <&gpio17 0 0>,
>                                                 <&gpio20 6 0>;
>                         pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
>                                 reg = <0x80 0 0 0 0>;

s/0x80/0/

>                                 compatible = "pciclass,0604";
>                                 device_type = "pci";
>                                 #address-cells = <3>;
>                                 #size-cells = <2>;
>                                 ranges;
>                                 bus-range = <0x01 0xff>;
>                                 msi-parent = <&its_pcie>;
>
>                                 pcie at 0,0 { // Lane 0: upstream
>                                         reg = <0x010000 0 0 0 0>;

While technically correct having the bus# in the address, that doesn't
work for FDT since we don't know the bus assignment. So we should just
use 0.

>                                         compatible = "pciclass,0604";
>                                         device_type = "pci";
>                                         #address-cells = <3>;
>                                         #size-cells = <2>;
>                                         ranges;
>                                 };
>                                 pcie at 1,0 { // Lane 4: M.2

These 3 nodes (1, 5, 7) need to be child nodes of the above node.

>                                         reg = <0x010800 0 0 0 0>;

Just 0x800

>                                         compatible = "pciclass,0604";
>                                         device_type = "pci";
>                                         reset-gpios = <&gpio3 1 0>;
>                                         #address-cells = <3>;
>                                         #size-cells = <2>;
>                                         ranges;
>                                 };
>
>                                 pcie at 5,0 { // Lane 5: Mini PCIe
>                                         reg = <0x012800 0 0 0 0>;

0x2800

>                                         compatible = "pciclass,0604";
>                                         device_type = "pci";
>                                         reset-gpios = <&gpio27 4 0 >;
>                                         #address-cells = <3>;
>                                         #size-cells = <2>;
>                                         ranges;
>                                 };
>
>                                 pcie at 7,0 { // Lane 6: Ethernet
>                                         reg = <0x013800 0 0 0 0>;

0x3800

>                                         compatible = "pciclass,0604";
>                                         device_type = "pci";
>                                         reset-gpios = <&gpio25 2 0 >;
>                                         #address-cells = <3>;
>                                         #size-cells = <2>;
>                                         ranges;
>                                 };
>                         };
>                 };
>
>
>


From mchehab+huawei at kernel.org  Tue Aug 10 07:20:54 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 10 Aug 2021 16:20:54 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan>
 <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
Message-ID: <20210810162054.1aa84b84@coco.lan>

Em Tue, 10 Aug 2021 07:44:50 -0600
Rob Herring <robh at kernel.org> escreveu:

> On Tue, Aug 10, 2021 at 3:42 AM Mauro Carvalho Chehab
> <mchehab+huawei at kernel.org> wrote:
> >
> > Em Fri, 6 Aug 2021 10:23:35 -0600
> > Rob Herring <robh at kernel.org> escreveu:
> >  
> > > On Thu, Aug 5, 2021 at 1:58 AM Mauro Carvalho Chehab
> > > <mchehab+huawei at kernel.org> wrote:  
> > > >
> > > > Em Thu, 5 Aug 2021 09:46:12 +0200
> > > > Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:
> > > >  
> > > > > Em Wed, 4 Aug 2021 10:28:53 -0600
> > > > > Rob Herring <robh at kernel.org> escreveu:
> > > > >  
> > > > > > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:  
> > > > > > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > > > > > Rob Herring <robh+dt at kernel.org> escreveu:
> > > > > > >  
> > > > > > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > > > > > <mchehab+huawei at kernel.org> wrote:  
> > > > > > > > >
> > > > > > > > > Hi Rob,
> > > > > > > > >
> > > > > > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > > > > > corresponding PHY.
> > > > > > > > >
> > > > > > > > > It is identical to v2, except by:
> > > > > > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > > > > > >         +          pcie at 7,0 { // Lane 6: Ethernet  
> > > > > > > >
> > > > > > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > > > > > devices? If you don't, then something is wrong still in the topology
> > > > > > > > or the PCI core is failing to set the DT node pointer in struct
> > > > > > > > device. Though you don't rely on that currently, we want the topology
> > > > > > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > > > > > powerpc relied on this.
> > > > > > > >
> > > > > > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > > > > > could have a tool that generates the DT structure based on the PCI
> > > > > > > > topology.  
> > > > > > >
> > > > > > > The of_node node link is on those places:
> > > > > > >
> > > > > > >   $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > > > > >   /sys/devices/platform/soc/f4000000.pcie/of_node
> > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node  
> > > > > >
> > > > > > Looks like we're missing some...
> > > > > >
> > > > > > It's not immediately obvious to me what's wrong here. Only the root
> > > > > > bus is getting it's DT node set. The relevant code is pci_scan_device(),
> > > > > > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try
> > > > > > to reproduce and debug it.  
> > > > >
> > > > > I added a printk on both pci_set_*of_node() functions:
> > > > >
> > > > >       [    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > > >       [    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> > > > >       [    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > >       [    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > >       [    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > > > >       [    5.059263]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.085552]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.112073]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.138320]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.164673]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > > > >       [    5.240539]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > > > >       [    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > > > >       [    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > > > >       [    5.345516]  (null): pci_set_of_node: of_node: (null)
> > > > >       [    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)  
> > > >
> > > > The enclosed patch makes the above a clearer:
> > > >
> > > >         [    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > >         [    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > > >         [    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > >         [    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > >         [    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)  
> > >
> > > I believe the issue is we need another bridge node in the DT
> > > hierarchy. What we have is:
> > >
> > > Bus 0 is node /soc/pcie at f4000000
> > > Bus 1 is device 0 on bus 0 is node /soc/pcie at f4000000/pcie at 0,0
> > > Bus 2 is device 0 on bus 1 in node ... whoops, there's no device 0
> > > under /soc/pcie at f4000000/pcie at 0,0
> > >
> > > So we need the hierarchy to be: /soc/pcie at f4000000/pcie at 0/pcie at 0/pcie@{1,5,7}  
> >
> > Adding a child pcie at 0 produces the following output from my debug
> > patches:  
> 
> You removed your changes to the PCI code other than the debug print?

Yes.

> >
> > [    4.984278]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > [    5.042992] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > [    5.083738] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > [    5.124377] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > [    5.168395] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > [    5.200719] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0  
> 
> This should not happen. The devfn doesn't match.
> 
> > [    5.247777] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > [    5.276768] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > [    5.305018] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > [    5.333093] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > [    5.395620] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > [    5.416333] pci 0000:03:00.0: pci_set_of_node: of_node: (null)
> > [    5.451353] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > [    5.473970] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > [    5.487765] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > [    5.530219] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
> > [    5.560896] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
> >
> > It produces the following sysfs nodes:
> >
> >         $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> >         /sys/devices/platform/soc/f4000000.pcie/of_node
> >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node
> >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node
> >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> >
> >
> > I'm enclosing the DT schema I'm using.
> >
> >
> >
> > Thanks,
> > Mauro
> >
> > ---
> >
> >                 pcie at f4000000 {
> >                         compatible = "hisilicon,kirin970-pcie";
> >                         reg = <0x0 0xf4000000 0x0 0x1000000>,
> >                               <0x0 0xfc180000 0x0 0x1000>,
> >                               <0x0 0xf5000000 0x0 0x2000>;
> >                         reg-names = "dbi", "apb", "config";
> >                         bus-range = <0x00 0xff>;
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> >                         device_type = "pci";
> >                         phys = <&pcie_phy>;
> >                         ranges = <0x02000000 0x0 0x00000000
> >                                   0x0 0xf6000000
> >                                   0x0 0x02000000>;
> >                         num-lanes = <1>;
> >                         #interrupt-cells = <1>;
> >                         interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "msi";
> >                         interrupt-map-mask = <0 0 0 7>;
> >                         interrupt-map = <0x0 0 0 1
> >                                          &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0x0 0 0 2
> >                                          &gic GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0x0 0 0 3
> >                                          &gic GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0x0 0 0 4
> >                                          &gic GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
> >                         reset-gpios = <&gpio7 0 0>;
> >                         hisilicon,clken-gpios = <&gpio27 3 0>, <&gpio17 0 0>,
> >                                                 <&gpio20 6 0>;
> >                         pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
> >                                 reg = <0x80 0 0 0 0>;  
> 
> s/0x80/0/
> 
> >                                 compatible = "pciclass,0604";
> >                                 device_type = "pci";
> >                                 #address-cells = <3>;
> >                                 #size-cells = <2>;
> >                                 ranges;
> >                                 bus-range = <0x01 0xff>;
> >                                 msi-parent = <&its_pcie>;
> >
> >                                 pcie at 0,0 { // Lane 0: upstream
> >                                         reg = <0x010000 0 0 0 0>;  
> 
> While technically correct having the bus# in the address, that doesn't
> work for FDT since we don't know the bus assignment. So we should just
> use 0.

Using 0 causes DTB compilation to produce a warning, due to the
bus-range. Without the bus-range, there will be runtime warnings,
as this will be assigned as bus 1.

> 
> >                                         compatible = "pciclass,0604";
> >                                         device_type = "pci";
> >                                         #address-cells = <3>;
> >                                         #size-cells = <2>;
> >                                         ranges;
> >                                 };
> >                                 pcie at 1,0 { // Lane 4: M.2  
> 
> These 3 nodes (1, 5, 7) need to be child nodes of the above node.
> 
> >                                         reg = <0x010800 0 0 0 0>;  
> 
> Just 0x800

The same applies here and to all the other nodes: they all need to have
the bus number on it, as otherwise either DTB compilation warnings
are generated, or runtime ones are produced, like:


            [    4.986196] kirin-pcie f4000000.pcie: PCI host bridge to bus 0000:00
            [    4.992572] pci_bus 0000:00: root bus resource [bus 00-01]
    ...
            [    5.065566] pci_bus 0000:01: busn_res: can not insert [bus 01-ff] under [bus 00-01] (conflicts with (null) [bus 00-01])
    
> 
> >                                         compatible = "pciclass,0604";
> >                                         device_type = "pci";
> >                                         reset-gpios = <&gpio3 1 0>;
> >                                         #address-cells = <3>;
> >                                         #size-cells = <2>;
> >                                         ranges;
> >                                 };
> >
> >                                 pcie at 5,0 { // Lane 5: Mini PCIe
> >                                         reg = <0x012800 0 0 0 0>;  
> 
> 0x2800
> 
> >                                         compatible = "pciclass,0604";
> >                                         device_type = "pci";
> >                                         reset-gpios = <&gpio27 4 0 >;
> >                                         #address-cells = <3>;
> >                                         #size-cells = <2>;
> >                                         ranges;
> >                                 };
> >
> >                                 pcie at 7,0 { // Lane 6: Ethernet
> >                                         reg = <0x013800 0 0 0 0>;  
> 
> 0x3800
> 
> >                                         compatible = "pciclass,0604";
> >                                         device_type = "pci";
> >                                         reset-gpios = <&gpio25 2 0 >;
> >                                         #address-cells = <3>;
> >                                         #size-cells = <2>;
> >                                         ranges;
> >                                 };
> >                         };
> >                 };
> >
> >
> >  



Thanks,
Mauro


From robh at kernel.org  Tue Aug 10 10:13:48 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Aug 2021 11:13:48 -0600
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <20210810162054.1aa84b84@coco.lan>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan> <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan> <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
 <20210810162054.1aa84b84@coco.lan>
Message-ID: <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>

On Tue, Aug 10, 2021 at 8:21 AM Mauro Carvalho Chehab
<mchehab+huawei at kernel.org> wrote:
>
> Em Tue, 10 Aug 2021 07:44:50 -0600
> Rob Herring <robh at kernel.org> escreveu:
>
> > On Tue, Aug 10, 2021 at 3:42 AM Mauro Carvalho Chehab
> > <mchehab+huawei at kernel.org> wrote:
> > >
> > > Em Fri, 6 Aug 2021 10:23:35 -0600
> > > Rob Herring <robh at kernel.org> escreveu:
> > >
> > > > On Thu, Aug 5, 2021 at 1:58 AM Mauro Carvalho Chehab
> > > > <mchehab+huawei at kernel.org> wrote:
> > > > >
> > > > > Em Thu, 5 Aug 2021 09:46:12 +0200
> > > > > Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:
> > > > >
> > > > > > Em Wed, 4 Aug 2021 10:28:53 -0600
> > > > > > Rob Herring <robh at kernel.org> escreveu:
> > > > > >
> > > > > > > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:
> > > > > > > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > > > > > > Rob Herring <robh+dt at kernel.org> escreveu:
> > > > > > > >
> > > > > > > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > > > > > > <mchehab+huawei at kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > Hi Rob,
> > > > > > > > > >
> > > > > > > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > > > > > > corresponding PHY.
> > > > > > > > > >
> > > > > > > > > > It is identical to v2, except by:
> > > > > > > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > > > > > > >         +          pcie at 7,0 { // Lane 6: Ethernet
> > > > > > > > >
> > > > > > > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > > > > > > devices? If you don't, then something is wrong still in the topology
> > > > > > > > > or the PCI core is failing to set the DT node pointer in struct
> > > > > > > > > device. Though you don't rely on that currently, we want the topology
> > > > > > > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > > > > > > powerpc relied on this.
> > > > > > > > >
> > > > > > > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > > > > > > could have a tool that generates the DT structure based on the PCI
> > > > > > > > > topology.
> > > > > > > >
> > > > > > > > The of_node node link is on those places:
> > > > > > > >
> > > > > > > >   $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/of_node
> > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> > > > > > >
> > > > > > > Looks like we're missing some...
> > > > > > >
> > > > > > > It's not immediately obvious to me what's wrong here. Only the root
> > > > > > > bus is getting it's DT node set. The relevant code is pci_scan_device(),
> > > > > > > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try
> > > > > > > to reproduce and debug it.
> > > > > >
> > > > > > I added a printk on both pci_set_*of_node() functions:
> > > > > >
> > > > > >       [    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > > > >       [    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> > > > > >       [    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > > >       [    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > > >       [    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > > > > >       [    5.059263]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.085552]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.112073]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.138320]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.164673]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > > > > >       [    5.240539]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > > > > >       [    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > > > > >       [    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > > > > >       [    5.345516]  (null): pci_set_of_node: of_node: (null)
> > > > > >       [    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
> > > > >
> > > > > The enclosed patch makes the above a clearer:
> > > > >
> > > > >         [    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > > >         [    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > > > >         [    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > >         [    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > >         [    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > > >
> > > > I believe the issue is we need another bridge node in the DT
> > > > hierarchy. What we have is:
> > > >
> > > > Bus 0 is node /soc/pcie at f4000000
> > > > Bus 1 is device 0 on bus 0 is node /soc/pcie at f4000000/pcie at 0,0
> > > > Bus 2 is device 0 on bus 1 in node ... whoops, there's no device 0
> > > > under /soc/pcie at f4000000/pcie at 0,0
> > > >
> > > > So we need the hierarchy to be: /soc/pcie at f4000000/pcie at 0/pcie at 0/pcie@{1,5,7}
> > >
> > > Adding a child pcie at 0 produces the following output from my debug
> > > patches:
> >
> > You removed your changes to the PCI code other than the debug print?
>
> Yes.
>
> > >
> > > [    4.984278]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > [    5.042992] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > > [    5.083738] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > [    5.124377] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > [    5.168395] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > [    5.200719] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >
> > This should not happen. The devfn doesn't match.
> >
> > > [    5.247777] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > [    5.276768] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > [    5.305018] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > [    5.333093] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > [    5.395620] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > > [    5.416333] pci 0000:03:00.0: pci_set_of_node: of_node: (null)
> > > [    5.451353] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > > [    5.473970] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > > [    5.487765] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > > [    5.530219] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
> > > [    5.560896] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
> > >
> > > It produces the following sysfs nodes:
> > >
> > >         $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > >         /sys/devices/platform/soc/f4000000.pcie/of_node
> > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node
> > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node
> > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> > >
> > >
> > > I'm enclosing the DT schema I'm using.
> > >
> > >
> > >
> > > Thanks,
> > > Mauro
> > >
> > > ---
> > >
> > >                 pcie at f4000000 {
> > >                         compatible = "hisilicon,kirin970-pcie";
> > >                         reg = <0x0 0xf4000000 0x0 0x1000000>,
> > >                               <0x0 0xfc180000 0x0 0x1000>,
> > >                               <0x0 0xf5000000 0x0 0x2000>;
> > >                         reg-names = "dbi", "apb", "config";
> > >                         bus-range = <0x00 0xff>;
> > >                         #address-cells = <3>;
> > >                         #size-cells = <2>;
> > >                         device_type = "pci";
> > >                         phys = <&pcie_phy>;
> > >                         ranges = <0x02000000 0x0 0x00000000
> > >                                   0x0 0xf6000000
> > >                                   0x0 0x02000000>;
> > >                         num-lanes = <1>;
> > >                         #interrupt-cells = <1>;
> > >                         interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
> > >                         interrupt-names = "msi";
> > >                         interrupt-map-mask = <0 0 0 7>;
> > >                         interrupt-map = <0x0 0 0 1
> > >                                          &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0x0 0 0 2
> > >                                          &gic GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0x0 0 0 3
> > >                                          &gic GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0x0 0 0 4
> > >                                          &gic GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
> > >                         reset-gpios = <&gpio7 0 0>;
> > >                         hisilicon,clken-gpios = <&gpio27 3 0>, <&gpio17 0 0>,
> > >                                                 <&gpio20 6 0>;
> > >                         pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
> > >                                 reg = <0x80 0 0 0 0>;
> >
> > s/0x80/0/
> >
> > >                                 compatible = "pciclass,0604";
> > >                                 device_type = "pci";
> > >                                 #address-cells = <3>;
> > >                                 #size-cells = <2>;
> > >                                 ranges;
> > >                                 bus-range = <0x01 0xff>;
> > >                                 msi-parent = <&its_pcie>;
> > >
> > >                                 pcie at 0,0 { // Lane 0: upstream
> > >                                         reg = <0x010000 0 0 0 0>;
> >
> > While technically correct having the bus# in the address, that doesn't
> > work for FDT since we don't know the bus assignment. So we should just
> > use 0.
>
> Using 0 causes DTB compilation to produce a warning, due to the
> bus-range. Without the bus-range, there will be runtime warnings,
> as this will be assigned as bus 1.

Okay, that might be something we need to fix.


> > >                                         compatible = "pciclass,0604";
> > >                                         device_type = "pci";
> > >                                         #address-cells = <3>;
> > >                                         #size-cells = <2>;
> > >                                         ranges;
> > >                                 };
> > >                                 pcie at 1,0 { // Lane 4: M.2
> >
> > These 3 nodes (1, 5, 7) need to be child nodes of the above node.

This was the main issue.

Rob


From robh at kernel.org  Tue Aug 10 10:52:34 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Aug 2021 11:52:34 -0600
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan> <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan> <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
 <20210810162054.1aa84b84@coco.lan>
 <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
Message-ID: <CAL_JsqKr9csV5fPZxD=kRRB5W6RCjHz0VsP6-nx0RQt8mgVJ5w@mail.gmail.com>

On Tue, Aug 10, 2021 at 11:13 AM Rob Herring <robh at kernel.org> wrote:
>
> On Tue, Aug 10, 2021 at 8:21 AM Mauro Carvalho Chehab
> <mchehab+huawei at kernel.org> wrote:
> >
> > Em Tue, 10 Aug 2021 07:44:50 -0600
> > Rob Herring <robh at kernel.org> escreveu:
> >
> > > On Tue, Aug 10, 2021 at 3:42 AM Mauro Carvalho Chehab
> > > <mchehab+huawei at kernel.org> wrote:
> > > >
> > > > Em Fri, 6 Aug 2021 10:23:35 -0600
> > > > Rob Herring <robh at kernel.org> escreveu:
> > > >
> > > > > On Thu, Aug 5, 2021 at 1:58 AM Mauro Carvalho Chehab
> > > > > <mchehab+huawei at kernel.org> wrote:
> > > > > >
> > > > > > Em Thu, 5 Aug 2021 09:46:12 +0200
> > > > > > Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:
> > > > > >
> > > > > > > Em Wed, 4 Aug 2021 10:28:53 -0600
> > > > > > > Rob Herring <robh at kernel.org> escreveu:
> > > > > > >
> > > > > > > > On Wed, Aug 04, 2021 at 08:50:45AM +0200, Mauro Carvalho Chehab wrote:
> > > > > > > > > Em Tue, 3 Aug 2021 16:11:42 -0600
> > > > > > > > > Rob Herring <robh+dt at kernel.org> escreveu:
> > > > > > > > >
> > > > > > > > > > On Mon, Aug 2, 2021 at 10:39 PM Mauro Carvalho Chehab
> > > > > > > > > > <mchehab+huawei at kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > Hi Rob,
> > > > > > > > > > >
> > > > > > > > > > > That's the third version of the DT bindings for Kirin 970 PCIE and its
> > > > > > > > > > > corresponding PHY.
> > > > > > > > > > >
> > > > > > > > > > > It is identical to v2, except by:
> > > > > > > > > > >         -          pcie at 7,0 { // Lane 7: Ethernet
> > > > > > > > > > >         +          pcie at 7,0 { // Lane 6: Ethernet
> > > > > > > > > >
> > > > > > > > > > Can you check whether you have DT node links in sysfs for the PCI
> > > > > > > > > > devices? If you don't, then something is wrong still in the topology
> > > > > > > > > > or the PCI core is failing to set the DT node pointer in struct
> > > > > > > > > > device. Though you don't rely on that currently, we want the topology
> > > > > > > > > > to match. It's possible this never worked on arm/arm64 as mainly
> > > > > > > > > > powerpc relied on this.
> > > > > > > > > >
> > > > > > > > > > I'd like some way to validate the DT matches the PCI topology. We
> > > > > > > > > > could have a tool that generates the DT structure based on the PCI
> > > > > > > > > > topology.
> > > > > > > > >
> > > > > > > > > The of_node node link is on those places:
> > > > > > > > >
> > > > > > > > >   $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/of_node
> > > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > > > > > > >   /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> > > > > > > >
> > > > > > > > Looks like we're missing some...
> > > > > > > >
> > > > > > > > It's not immediately obvious to me what's wrong here. Only the root
> > > > > > > > bus is getting it's DT node set. The relevant code is pci_scan_device(),
> > > > > > > > pci_set_of_node() and pci_set_bus_of_node(). Give me a few days to try
> > > > > > > > to reproduce and debug it.
> > > > > > >
> > > > > > > I added a printk on both pci_set_*of_node() functions:
> > > > > > >
> > > > > > >       [    4.872991]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > > > > >       [    4.913806]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000
> > > > > > >       [    4.978102] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > > > >       [    4.990622]  (null): pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > > > >       [    5.052383] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > > > > > >       [    5.059263]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.085552]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.112073]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.138320]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.164673]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.233759] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > > > > > >       [    5.240539]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.310545] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > > > > > >       [    5.324719] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > > > > > >       [    5.338914] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > > > > > >       [    5.345516]  (null): pci_set_of_node: of_node: (null)
> > > > > > >       [    5.415795] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
> > > > > >
> > > > > > The enclosed patch makes the above a clearer:
> > > > > >
> > > > > >         [    4.800975]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > > > >         [    4.855983] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > > > > >         [    4.879169] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > > >         [    4.900602] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > > >         [    4.953086] pci_bus 0000:02: pci_set_bus_of_node: of_node: (null)
> > > > >
> > > > > I believe the issue is we need another bridge node in the DT
> > > > > hierarchy. What we have is:
> > > > >
> > > > > Bus 0 is node /soc/pcie at f4000000
> > > > > Bus 1 is device 0 on bus 0 is node /soc/pcie at f4000000/pcie at 0,0
> > > > > Bus 2 is device 0 on bus 1 in node ... whoops, there's no device 0
> > > > > under /soc/pcie at f4000000/pcie at 0,0
> > > > >
> > > > > So we need the hierarchy to be: /soc/pcie at f4000000/pcie at 0/pcie at 0/pcie@{1,5,7}
> > > >
> > > > Adding a child pcie at 0 produces the following output from my debug
> > > > patches:
> > >
> > > You removed your changes to the PCI code other than the debug print?
> >
> > Yes.
> >
> > > >
> > > > [    4.984278]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> > > > [    5.042992] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> > > > [    5.083738] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > [    5.124377] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> > > > [    5.168395] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > > [    5.200719] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > >
> > > This should not happen. The devfn doesn't match.
> > >
> > > > [    5.247777] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > > [    5.276768] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > > [    5.305018] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > > [    5.333093] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> > > > [    5.395620] pci_bus 0000:03: pci_set_bus_of_node: of_node: (null)
> > > > [    5.416333] pci 0000:03:00.0: pci_set_of_node: of_node: (null)
> > > > [    5.451353] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
> > > > [    5.473970] pci_bus 0000:05: pci_set_bus_of_node: of_node: (null)
> > > > [    5.487765] pci_bus 0000:06: pci_set_bus_of_node: of_node: (null)
> > > > [    5.530219] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
> > > > [    5.560896] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
> > > >
> > > > It produces the following sysfs nodes:
> > > >
> > > >         $ find /sys/devices/platform/soc/f4000000.pcie/ -name of_node
> > > >         /sys/devices/platform/soc/f4000000.pcie/of_node
> > > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node
> > > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node
> > > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node
> > > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node
> > > >         /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node
> > > >
> > > >
> > > > I'm enclosing the DT schema I'm using.
> > > >
> > > >
> > > >
> > > > Thanks,
> > > > Mauro
> > > >
> > > > ---
> > > >
> > > >                 pcie at f4000000 {
> > > >                         compatible = "hisilicon,kirin970-pcie";
> > > >                         reg = <0x0 0xf4000000 0x0 0x1000000>,
> > > >                               <0x0 0xfc180000 0x0 0x1000>,
> > > >                               <0x0 0xf5000000 0x0 0x2000>;
> > > >                         reg-names = "dbi", "apb", "config";
> > > >                         bus-range = <0x00 0xff>;
> > > >                         #address-cells = <3>;
> > > >                         #size-cells = <2>;
> > > >                         device_type = "pci";
> > > >                         phys = <&pcie_phy>;
> > > >                         ranges = <0x02000000 0x0 0x00000000
> > > >                                   0x0 0xf6000000
> > > >                                   0x0 0x02000000>;
> > > >                         num-lanes = <1>;
> > > >                         #interrupt-cells = <1>;
> > > >                         interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
> > > >                         interrupt-names = "msi";
> > > >                         interrupt-map-mask = <0 0 0 7>;
> > > >                         interrupt-map = <0x0 0 0 1
> > > >                                          &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
> > > >                                         <0x0 0 0 2
> > > >                                          &gic GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
> > > >                                         <0x0 0 0 3
> > > >                                          &gic GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
> > > >                                         <0x0 0 0 4
> > > >                                          &gic GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
> > > >                         reset-gpios = <&gpio7 0 0>;
> > > >                         hisilicon,clken-gpios = <&gpio27 3 0>, <&gpio17 0 0>,
> > > >                                                 <&gpio20 6 0>;
> > > >                         pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
> > > >                                 reg = <0x80 0 0 0 0>;
> > >
> > > s/0x80/0/
> > >
> > > >                                 compatible = "pciclass,0604";
> > > >                                 device_type = "pci";
> > > >                                 #address-cells = <3>;
> > > >                                 #size-cells = <2>;
> > > >                                 ranges;
> > > >                                 bus-range = <0x01 0xff>;
> > > >                                 msi-parent = <&its_pcie>;
> > > >
> > > >                                 pcie at 0,0 { // Lane 0: upstream
> > > >                                         reg = <0x010000 0 0 0 0>;
> > >
> > > While technically correct having the bus# in the address, that doesn't
> > > work for FDT since we don't know the bus assignment. So we should just
> > > use 0.
> >
> > Using 0 causes DTB compilation to produce a warning, due to the
> > bus-range.

What's the warning? 'bus-range' should be optional.

> > Without the bus-range, there will be runtime warnings,
> > as this will be assigned as bus 1.
>
> Okay, that might be something we need to fix.

Actually, I don't see how there's a problem. First, the only place we
read 'bus-range' is of_pci_parse_bus_range() and that's only called
for the host bridge. Any other occurrence of 'bus-range' should be
ignored. The only place we read 'reg' is of_pci_get_devfn() and we
mask just the devfn bits.

>            [    4.992572] pci_bus 0000:00: root bus resource [bus 00-01]

I don't see any way this can happen other than pcie at f4000000 node
containing 'bus-range = <0 1>;'. It comes from
pci_host_bridge.windows.

Rob


From mchehab+huawei at kernel.org  Tue Aug 10 23:46:48 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 11 Aug 2021 08:46:48 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan>
 <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
 <20210810162054.1aa84b84@coco.lan>
 <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
Message-ID: <20210811084648.66ddff29@coco.lan>

Em Tue, 10 Aug 2021 11:13:48 -0600
Rob Herring <robh at kernel.org> escreveu:

> > > >                                         compatible = "pciclass,0604";
> > > >                                         device_type = "pci";
> > > >                                         #address-cells = <3>;
> > > >                                         #size-cells = <2>;
> > > >                                         ranges;
> > > >                                 };
> > > >                                 pcie at 1,0 { // Lane 4: M.2  
> > >
> > > These 3 nodes (1, 5, 7) need to be child nodes of the above node.  
> 
> This was the main issue.

Ok, placing 1, 5, 7 as child nodes of 0 worked, with the attached
DT schema:


	$ ls -l $(find /sys/devices/platform/soc/f4000000.pcie/ -name of_node)
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/of_node -> ../../../../firmware/devicetree/base/soc/pcie at f4000000
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:01.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:01.0/pci_bus/0000:03/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:05.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:05.0/pci_bus/0000:05/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:07.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:07.0/pci_bus/0000:06/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node -> ../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node -> ../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
	lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000

The logs also seem OK on my eyes:

	[    3.911082]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
	[    4.001104] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
	[    4.043609] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.076756] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.120652] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.150766] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.196413] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.238896] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.280116] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.309821] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.370830] pci_bus 0000:03: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
	[    4.382345] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
	[    4.411966] pci_bus 0000:05: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
	[    4.439898] pci_bus 0000:06: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
	[    4.491616] pci 0000:06:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
	[    4.519907] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)

Thanks,
Mauro


		pcie at f4000000 {
			compatible = "hisilicon,kirin970-pcie";
			reg = <0x0 0xf4000000 0x0 0x1000000>,
			      <0x0 0xfc180000 0x0 0x1000>,
			      <0x0 0xf5000000 0x0 0x2000>;
			reg-names = "dbi", "apb", "config";
			bus-range = <0x00 0xff>;
			#address-cells = <3>;
			#size-cells = <2>;
			device_type = "pci";
			phys = <&pcie_phy>;
			ranges = <0x02000000 0x0 0x00000000
				  0x0 0xf6000000
				  0x0 0x02000000>;
			num-lanes = <1>;
			#interrupt-cells = <1>;
			interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
			interrupt-names = "msi";
			interrupt-map-mask = <0 0 0 7>;
			interrupt-map = <0x0 0 0 1
					 &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
					<0x0 0 0 2
					 &gic GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
					<0x0 0 0 3
					 &gic GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
					<0x0 0 0 4
					 &gic GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
			reset-gpios = <&gpio7 0 0>;
			hisilicon,clken-gpios = <&gpio27 3 0>, <&gpio17 0 0>,
						<&gpio20 6 0>;
			pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
				reg = <0x80 0 0 0 0>;
				compatible = "pciclass,0604";
				device_type = "pci";
				#address-cells = <3>;
				#size-cells = <2>;
				ranges;
				bus-range = <0x01 0xff>;
				msi-parent = <&its_pcie>;

				pcie at 0,0 { // Lane 0: upstream
					reg = <0x010000 0 0 0 0>;
					compatible = "pciclass,0604";
					device_type = "pci";
					#address-cells = <3>;
					#size-cells = <2>;
					ranges;

					pcie at 1,0 { // Lane 4: M.2
						reg = <0x010800 0 0 0 0>;
						compatible = "pciclass,0604";
						device_type = "pci";
						reset-gpios = <&gpio3 1 0>;
						#address-cells = <3>;
						#size-cells = <2>;
						ranges;
					};

					pcie at 5,0 { // Lane 5: Mini PCIe
						reg = <0x012800 0 0 0 0>;
						compatible = "pciclass,0604";
						device_type = "pci";
						reset-gpios = <&gpio27 4 0 >;
						#address-cells = <3>;
						#size-cells = <2>;
						ranges;
					};

					pcie at 7,0 { // Lane 6: Ethernet
						reg = <0x013800 0 0 0 0>;
						compatible = "pciclass,0604";
						device_type = "pci";
						reset-gpios = <&gpio25 2 0 >;
						#address-cells = <3>;
						#size-cells = <2>;
						ranges;
					};
				};
			};
		};


From mchehab+huawei at kernel.org  Wed Aug 11 00:11:15 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 11 Aug 2021 09:11:15 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqKr9csV5fPZxD=kRRB5W6RCjHz0VsP6-nx0RQt8mgVJ5w@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan>
 <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
 <20210810162054.1aa84b84@coco.lan>
 <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
 <CAL_JsqKr9csV5fPZxD=kRRB5W6RCjHz0VsP6-nx0RQt8mgVJ5w@mail.gmail.com>
Message-ID: <20210811091115.03b36daa@coco.lan>

Em Tue, 10 Aug 2021 11:52:34 -0600
Rob Herring <robh at kernel.org> escreveu:

> > > > >                         pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
> > > > >                                 reg = <0x80 0 0 0 0>;  
> > > >
> > > > s/0x80/0/
> > > >  
> > > > >                                 compatible = "pciclass,0604";
> > > > >                                 device_type = "pci";
> > > > >                                 #address-cells = <3>;
> > > > >                                 #size-cells = <2>;
> > > > >                                 ranges;
> > > > >                                 bus-range = <0x01 0xff>;
> > > > >                                 msi-parent = <&its_pcie>;
> > > > >
> > > > >                                 pcie at 0,0 { // Lane 0: upstream
> > > > >                                         reg = <0x010000 0 0 0 0>;  
> > > >
> > > > While technically correct having the bus# in the address, that doesn't
> > > > work for FDT since we don't know the bus assignment. So we should just
> > > > use 0.  
> > >
> > > Using 0 causes DTB compilation to produce a warning, due to the
> > > bus-range.  
> 
> What's the warning? 'bus-range' should be optional.

With this DT schema (simplified to show only relevant bits):

		pcie at f4000000 {
			bus-range = <0x00 0xff>;
			pcie at 0,0 { // Lane 0: PCIe switch: Bus 1, Device 0
				bus-range = <0x01 0xff>;
				pcie at 0,0 { // Lane 0: upstream
					reg = <0x0000 0 0 0 0>;
					pcie at 1,0 { // Lane 4: M.2
						reg = <0x0800 0 0 0 0>;
					};

					pcie at 5,0 { // Lane 5: Mini PCIe
						reg = <0x2800 0 0 0 0>;
					};

					pcie at 7,0 { // Lane 6: Ethernet
						reg = <0x3800 0 0 0 0>;
					};
				};
			};
		};


This is the compilation warning:
	$ make dtbs
	arch/arm64/boot/dts/hisilicon/hi3670.dtsi:735.5-29: Warning (pci_device_bus_num): /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0:bus-range: PCI bus number 0 out of range, expected (1 - 1)

This is solved by changing:
				pcie at 0,0 { // Lane 0: upstream
					reg = <0x0000 0 0 0 0>;
to:
				pcie at 0,0 { // Lane 0: upstream
					reg = <0x010000 0 0 0 0>;



> 
> > > Without the bus-range, there will be runtime warnings,
> > > as this will be assigned as bus 1.  
> >
> > Okay, that might be something we need to fix.  
> 
> Actually, I don't see how there's a problem. First, the only place we
> read 'bus-range' is of_pci_parse_bus_range() and that's only called
> for the host bridge. Any other occurrence of 'bus-range' should be
> ignored. The only place we read 'reg' is of_pci_get_devfn() and we
> mask just the devfn bits.
> 
> >            [    4.992572] pci_bus 0000:00: root bus resource [bus 00-01]  
> 
> I don't see any way this can happen other than pcie at f4000000 node
> containing 'bus-range = <0 1>;'. It comes from
> pci_host_bridge.windows.

Yeah, you're right. On the first versions, 'bus-range = <0 1>;' was used,
just like:
	arch/arm64/boot/dts/hisilicon/hi3660.dtsi

(I have a fixup patch fixing the warning on Kirin 960 due to that)

Ok, I did another test here: if I drop both dma-range, it will output:

	[    3.778028] kirin-pcie f4000000.pcie:   No bus range found for /soc/pcie at f4000000, using [bus 00-ff]

But no conflict warnings. So, I guess dropping bus-range and the explicit
bus 1 setting at "reg" is a clean approach.

As a reference, this is the dmesg log here (with OF debug turned on):

# dmesg|grep -i pci
[    0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.14.0-rc1+ root=UUID=646147e1-d186-44cc-b0d2-60c42f8dcc6d ro drm.debug=0x6 earlycon=pl011,0xfff32000,115200 console=tty0 console=ttyAMA6,115200n8 root=/dev/sdd12 rootwait rw quiet efi=noruntime drm.debug=0x06 "dyndbg=file drivers/pci/of.c +p;  drivers/gpu/* +p; file drivers/pci/of.c +p;  drivers/spmi/* +p; file drivers/pci/of.c +p;  drivers/mfd/* +p; file drivers/pci/of.c +p;  drivers/regulator/* +p; file drivers/pci/of.c +p;  drivers/usb/core/hub.c +p" no_console_suspend loglevel=9 kernel.panic=5
[    0.000000] Unknown command line parameters: BOOT_IMAGE=/boot/vmlinuz-5.14.0-rc1+ dyndbg=file drivers/pci/of.c +p;  drivers/gpu/* +p; file drivers/pci/of.c +p;  drivers/spmi/* +p; file drivers/pci/of.c +p;  drivers/mfd/* +p; file drivers/pci/of.c +p;  drivers/regulator/* +p; file drivers/pci/of.c +p;  drivers/usb/core/hub.c +p
[    0.725101] PCI: CLS 0 bytes, default 64
[    1.520828] ehci-pci: EHCI PCI platform driver
[    1.521022] ohci-pci: OHCI PCI platform driver
[    2.204793]     dyndbg=file drivers/pci/of.c +p;  drivers/gpu/* +p; file drivers/pci/of.c +p;  drivers/spmi/* +p; file drivers/pci/of.c +p;  drivers/mfd/* +p; file drivers/pci/of.c +p;  drivers/regulator/* +p; file drivers/pci/of.c +p;  drivers/usb/core/hub.c +p
[    3.767252] kirin-pcie f4000000.pcie: host bridge /soc/pcie at f4000000 ranges:
[    3.778028] kirin-pcie f4000000.pcie:   No bus range found for /soc/pcie at f4000000, using [bus 00-ff]
[    3.792466] kirin-pcie f4000000.pcie: Parsing ranges property...
[    3.801919] kirin-pcie f4000000.pcie:      MEM 0x00f6000000..0x00f7ffffff -> 0x0000000000
[    3.813680] kirin-pcie f4000000.pcie: invalid resource
[    3.822189] kirin-pcie f4000000.pcie: iATU unroll: enabled
[    3.831159] kirin-pcie f4000000.pcie: Detected iATU regions: 8 outbound, 8 inbound
[    3.943155] kirin-pcie f4000000.pcie: Link up
[    3.956821]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
[    3.979143] kirin-pcie f4000000.pcie: PCI host bridge to bus 0000:00
[    3.989441] pci_bus 0000:00: root bus resource [bus 00-ff]
[    3.998050] pci_bus 0000:00: root bus resource [mem 0xf6000000-0xf7ffffff] (bus address [0x00000000-0x01ffffff])
[    4.011965] pci 0000:00:00.0: [19e5:3670] type 01 class 0x060400
[    4.021177] pci 0000:00:00.0: reg 0x10: [mem 0xf6000000-0xf6ffffff]
[    4.031041] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
[    4.041362] pci 0000:00:00.0: supports D1 D2
[    4.049191] pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
[    4.059554] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
[    4.071133] pci 0000:01:00.0: [10b5:8606] type 01 class 0x060400
[    4.080831] pci 0000:01:00.0: reg 0x10: [mem 0xf6000000-0xf601ffff]
[    4.103511] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
[    4.115403] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
[    4.139816] pci 0000:01:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    4.157297] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    4.172380] pci 0000:02:01.0: [10b5:8606] type 01 class 0x060400
[    4.182279] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    4.197047] pci 0000:02:01.0: PME# supported from D0 D3hot D3cold
[    4.207583] pci 0000:02:04.0: [10b5:8606] type 01 class 0x060400
[    4.217659] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    4.234551] pci 0000:02:04.0: PME# supported from D0 D3hot D3cold
[    4.254284] pci 0000:02:05.0: [10b5:8606] type 01 class 0x060400
[    4.267668] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    4.282530] pci 0000:02:05.0: PME# supported from D0 D3hot D3cold
[    4.295077] pci 0000:02:07.0: [10b5:8606] type 01 class 0x060400
[    4.306032] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    4.320927] pci 0000:02:07.0: PME# supported from D0 D3hot D3cold
[    4.333414] pci 0000:02:09.0: [10b5:8606] type 01 class 0x060400
[    4.340439] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
[    4.350084] pci 0000:02:09.0: PME# supported from D0 D3hot D3cold
[    4.358150] pci 0000:02:01.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    4.366379] pci 0000:02:04.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    4.374515] pci 0000:02:05.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    4.382682] pci 0000:02:07.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    4.390834] pci 0000:02:09.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    4.399079] pci_bus 0000:03: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
[    4.409309] pci 0000:03:00.0: [144d:a809] type 00 class 0x010802
[    4.415564] pci 0000:03:00.0: reg 0x10: [mem 0xf6000000-0xf6003fff 64bit]
[    4.422769] pci 0000:03:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
[    4.433782] pci 0000:03:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
[    4.449954] pci_bus 0000:03: busn_res: [bus 03-ff] end is updated to 03
[    4.456836] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
[    4.457918] pci_bus 0000:04: busn_res: [bus 04-ff] end is updated to 04
[    4.478895] pci_bus 0000:05: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
[    4.491772] pci_bus 0000:05: busn_res: [bus 05-ff] end is updated to 05
[    4.503438] pci_bus 0000:06: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
[    4.529140] pci 0000:06:00.0: [10ec:8168] type 00 class 0x020000
[    4.535374] pci 0000:06:00.0: reg 0x10: [io  0x0000-0x00ff]
[    4.541229] pci 0000:06:00.0: reg 0x18: [mem 0xf7000000-0xf7000fff 64bit]
[    4.548194] pci 0000:06:00.0: reg 0x20: [mem 0xf7200000-0xf7203fff 64bit pref]
[    4.561063] pci 0000:06:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
[    4.582075] pci 0000:06:00.0: supports D1 D2
[    4.586357] pci 0000:06:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    4.594727] pci_bus 0000:06: busn_res: [bus 06-ff] end is updated to 06
[    4.601538] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)
[    4.608473] pci_bus 0000:07: busn_res: [bus 07-ff] end is updated to 07
[    4.615124] pci_bus 0000:02: busn_res: [bus 02-ff] end is updated to 07
[    4.621810] pci 0000:00:00.0: BAR 0: assigned [mem 0xf6000000-0xf6ffffff]
[    4.628606] pci 0000:00:00.0: BAR 14: assigned [mem 0xf7000000-0xf72fffff]
[    4.628610] pci 0000:00:00.0: BAR 15: assigned [mem 0xf7300000-0xf73fffff pref]
[    4.642813] pci 0000:00:00.0: BAR 13: no space for [io  size 0x1000]
[    4.649174] pci 0000:00:00.0: BAR 13: failed to assign [io  size 0x1000]
[    4.661518] pci 0000:01:00.0: BAR 14: assigned [mem 0xf7000000-0xf71fffff]
[    4.669074] pci 0000:01:00.0: BAR 15: assigned [mem 0xf7300000-0xf73fffff 64bit pref]
[    4.677066] pci 0000:01:00.0: BAR 0: assigned [mem 0xf7200000-0xf721ffff]
[    4.683891] pci 0000:01:00.0: BAR 13: no space for [io  size 0x1000]
[    4.690252] pci 0000:01:00.0: BAR 13: failed to assign [io  size 0x1000]
[    4.690266] pci 0000:02:01.0: BAR 14: assigned [mem 0xf7000000-0xf70fffff]
[    4.690270] pci 0000:02:07.0: BAR 14: assigned [mem 0xf7100000-0xf71fffff]
[    4.710728] pci 0000:02:07.0: BAR 15: assigned [mem 0xf7300000-0xf73fffff 64bit pref]
[    4.727780] pci 0000:02:07.0: BAR 13: no space for [io  size 0x1000]
[    4.727783] pci 0000:02:07.0: BAR 13: failed to assign [io  size 0x1000]
[    4.727790] pci 0000:03:00.0: BAR 0: assigned [mem 0xf7000000-0xf7003fff 64bit]
[    4.727904] pci 0000:02:01.0: PCI bridge to [bus 03]
[    4.753165] pci 0000:02:01.0:   bridge window [mem 0xf7000000-0xf70fffff]
[    4.769738] pci 0000:02:04.0: PCI bridge to [bus 04]
[    4.774843] pci 0000:02:05.0: PCI bridge to [bus 05]
[    4.779959] pci 0000:06:00.0: BAR 4: assigned [mem 0xf7300000-0xf7303fff 64bit pref]
[    4.787839] pci 0000:06:00.0: BAR 2: assigned [mem 0xf7100000-0xf7100fff 64bit]
[    4.795273] pci 0000:06:00.0: BAR 0: no space for [io  size 0x0100]
[    4.801543] pci 0000:06:00.0: BAR 0: failed to assign [io  size 0x0100]
[    4.808159] pci 0000:02:07.0: PCI bridge to [bus 06]
[    4.813166] pci 0000:02:07.0:   bridge window [mem 0xf7100000-0xf71fffff]
[    4.819981] pci 0000:02:07.0:   bridge window [mem 0xf7300000-0xf73fffff 64bit pref]
[    4.827782] pci 0000:02:09.0: PCI bridge to [bus 07]
[    4.832871] pci 0000:01:00.0: PCI bridge to [bus 02-07]
[    4.838138] pci 0000:01:00.0:   bridge window [mem 0xf7000000-0xf71fffff]
[    4.844952] pci 0000:01:00.0:   bridge window [mem 0xf7300000-0xf73fffff 64bit pref]
[    4.852751] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
[    4.857980] pci 0000:00:00.0:   bridge window [mem 0xf7000000-0xf72fffff]
[    4.864770] pci 0000:00:00.0:   bridge window [mem 0xf7300000-0xf73fffff pref]
[    4.881547] pcieport 0000:00:00.0: PME: Signaling with IRQ 58
[    4.888905] pcieport 0000:00:00.0: AER: enabled with IRQ 58
[    4.895013] pcieport 0000:01:00.0: enabling device (0000 -> 0002)
[    4.903260] pcieport 0000:02:01.0: enabling device (0000 -> 0002)
[    4.914761] pcieport 0000:02:07.0: enabling device (0000 -> 0002)
[    4.928984] nvme nvme0: pci function 0000:03:00.0

Thanks,
Mauro


From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:38 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:38 +0800
Subject: [PATCH v2 7/9] phy: phy-mtk-hdmi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-7-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 8ad8f717ef43..5fb4217fb8e0 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -100,7 +100,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_hdmi_phy *hdmi_phy;
-	struct resource *mem;
 	struct clk *ref_clk;
 	const char *ref_clk_name;
 	struct clk_init_data clk_init = {
@@ -116,11 +115,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 	if (!hdmi_phy)
 		return -ENOMEM;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi_phy->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(hdmi_phy->regs)) {
+	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(hdmi_phy->regs))
 		return PTR_ERR(hdmi_phy->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, "pll_ref");
 	if (IS_ERR(ref_clk)) {
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:40 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:40 +0800
Subject: [PATCH v2 9/9] phy: phy-mtk-mipi-dsi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-9-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 61c942fbf4a1..28ad9403c441 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -130,7 +130,6 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mipi_tx *mipi_tx;
-	struct resource *mem;
 	const char *ref_clk_name;
 	struct clk *ref_clk;
 	struct clk_init_data clk_init = {
@@ -148,11 +147,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mipi_tx->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(mipi_tx->regs)) {
+	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mipi_tx->regs))
 		return PTR_ERR(mipi_tx->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(ref_clk)) {
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:36 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:36 +0800
Subject: [PATCH v2 5/9] phy: phy-mtk-tphy: remove error log of ioremap failure
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-5-git-send-email-chunfeng.yun@mediatek.com>

devm_ioremap_resource() will print log if error happens.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 9d4b34298137..cdcef865fe9e 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1306,7 +1306,6 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 
 		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:33 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:33 +0800
Subject: [PATCH v2 2/9] phy: phy-mtk-tphy: use clock bulk to get clocks
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-2-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 43 +++++++++--------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 33000b38fd1b..3259210f08a1 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -280,6 +280,8 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+#define TPHY_CLKS_CNT	2
+
 enum mtk_phy_version {
 	MTK_PHY_V1 = 1,
 	MTK_PHY_V2,
@@ -318,8 +320,7 @@ struct mtk_phy_instance {
 		struct u2phy_banks u2_banks;
 		struct u3phy_banks u3_banks;
 	};
-	struct clk *ref_clk;	/* reference clock of (digital) phy */
-	struct clk *da_ref_clk;	/* reference clock of analog phy */
+	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
 	u8 type;
 	int eye_src;
@@ -974,18 +975,9 @@ static int mtk_phy_init(struct phy *phy)
 	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
 	int ret;
 
-	ret = clk_prepare_enable(instance->ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable ref_clk\n");
+	ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, instance->clks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_prepare_enable(instance->da_ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable da_ref\n");
-		clk_disable_unprepare(instance->ref_clk);
-		return ret;
-	}
 
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
@@ -1003,8 +995,7 @@ static int mtk_phy_init(struct phy *phy)
 		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
-		clk_disable_unprepare(instance->ref_clk);
-		clk_disable_unprepare(instance->da_ref_clk);
+		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 		return -EINVAL;
 	}
 
@@ -1047,8 +1038,7 @@ static int mtk_phy_exit(struct phy *phy)
 	if (instance->type == PHY_TYPE_USB2)
 		u2_phy_instance_exit(tphy, instance);
 
-	clk_disable_unprepare(instance->ref_clk);
-	clk_disable_unprepare(instance->da_ref_clk);
+	clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 	return 0;
 }
 
@@ -1211,6 +1201,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	port = 0;
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
+		struct clk_bulk_data *clks;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1247,20 +1238,12 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		phy_set_drvdata(phy, instance);
 		port++;
 
-		instance->ref_clk = devm_clk_get_optional(&phy->dev, "ref");
-		if (IS_ERR(instance->ref_clk)) {
-			dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->ref_clk);
+		clks = instance->clks;
+		clks[0].id = "ref";     /* digital (& analog) clock */
+		clks[1].id = "da_ref";  /* analog clock */
+		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		if (retval)
 			goto put_child;
-		}
-
-		instance->da_ref_clk =
-			devm_clk_get_optional(&phy->dev, "da_ref");
-		if (IS_ERR(instance->da_ref_clk)) {
-			dev_err(dev, "failed to get da_ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->da_ref_clk);
-			goto put_child;
-		}
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:37 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:37 +0800
Subject: [PATCH v2 6/9] phy: phy-mtk-ufs: use clock bulk to get clocks
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-6-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-ufs.c | 44 ++++++++----------------------
 1 file changed, 11 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c
index 769b00b038d8..a6af06941203 100644
--- a/drivers/phy/mediatek/phy-mtk-ufs.c
+++ b/drivers/phy/mediatek/phy-mtk-ufs.c
@@ -31,11 +31,12 @@
 #define FRC_CDR_ISO_EN              BIT(19)
 #define CDR_ISO_EN                  BIT(20)
 
+#define UFSPHY_CLKS_CNT    2
+
 struct ufs_mtk_phy {
 	struct device *dev;
 	void __iomem *mmio;
-	struct clk *mp_clk;
-	struct clk *unipro_clk;
+	struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
 };
 
 static inline u32 mphy_readl(struct ufs_mtk_phy *phy, u32 reg)
@@ -74,20 +75,11 @@ static struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy)
 static int ufs_mtk_phy_clk_init(struct ufs_mtk_phy *phy)
 {
 	struct device *dev = phy->dev;
+	struct clk_bulk_data *clks = phy->clks;
 
-	phy->unipro_clk = devm_clk_get(dev, "unipro");
-	if (IS_ERR(phy->unipro_clk)) {
-		dev_err(dev, "failed to get clock: unipro");
-		return PTR_ERR(phy->unipro_clk);
-	}
-
-	phy->mp_clk = devm_clk_get(dev, "mp");
-	if (IS_ERR(phy->mp_clk)) {
-		dev_err(dev, "failed to get clock: mp");
-		return PTR_ERR(phy->mp_clk);
-	}
-
-	return 0;
+	clks[0].id = "unipro";
+	clks[1].id = "mp";
+	return devm_clk_bulk_get(dev, UFSPHY_CLKS_CNT, clks);
 }
 
 static void ufs_mtk_phy_set_active(struct ufs_mtk_phy *phy)
@@ -150,26 +142,13 @@ static int ufs_mtk_phy_power_on(struct phy *generic_phy)
 	struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
 	int ret;
 
-	ret = clk_prepare_enable(phy->unipro_clk);
-	if (ret) {
-		dev_err(phy->dev, "unipro_clk enable failed %d\n", ret);
-		goto out;
-	}
-
-	ret = clk_prepare_enable(phy->mp_clk);
-	if (ret) {
-		dev_err(phy->dev, "mp_clk enable failed %d\n", ret);
-		goto out_unprepare_unipro_clk;
-	}
+	ret = clk_bulk_prepare_enable(UFSPHY_CLKS_CNT, phy->clks);
+	if (ret)
+		return ret;
 
 	ufs_mtk_phy_set_active(phy);
 
 	return 0;
-
-out_unprepare_unipro_clk:
-	clk_disable_unprepare(phy->unipro_clk);
-out:
-	return ret;
 }
 
 static int ufs_mtk_phy_power_off(struct phy *generic_phy)
@@ -178,8 +157,7 @@ static int ufs_mtk_phy_power_off(struct phy *generic_phy)
 
 	ufs_mtk_phy_set_deep_hibern(phy);
 
-	clk_disable_unprepare(phy->unipro_clk);
-	clk_disable_unprepare(phy->mp_clk);
+	clk_bulk_disable_unprepare(UFSPHY_CLKS_CNT, phy->clks);
 
 	return 0;
 }
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:32 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:32 +0800
Subject: [PATCH v2 1/9] dt-bindings: phy: mediatek: tphy: support type switch
 by pericfg
Message-ID: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch by pericfg register between USB3, PCIe,
SATA, SGMII, this is used to replace the way through efuse or
jumper.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add reviewed-by Rob
---
 .../devicetree/bindings/phy/mediatek,tphy.yaml   | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 838852cb8527..9e6c0f43f1c6 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -201,6 +201,22 @@ patternProperties:
           Specify the flag to enable BC1.2 if support it
         type: boolean
 
+      mediatek,syscon-type:
+        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
+        description:
+          A phandle to syscon used to access the register of type switch,
+          the field should always be 3 cells long.
+        items:
+          items:
+            - description:
+                The first cell represents a phandle to syscon
+            - description:
+                The second cell represents the register offset
+            - description:
+                The third cell represents the index of config segment
+              enum: [0, 1, 2, 3]
+
     required:
       - reg
       - "#phy-cells"
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:34 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:34 +0800
Subject: [PATCH v2 3/9] phy: phy-mtk-tphy: support type switch by pericfg
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-3-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch between USB3, PCIe, SATA and SGMII by
pericfg register, this is used to take the place of efuse or
jumper.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 84 ++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 3259210f08a1..a6502058a1a5 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -10,11 +10,13 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 /* version V1 sub-banks offset base address */
 /* banks shared by multiple phys */
@@ -280,6 +282,14 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+/* PHY switch between pcie/usb3/sgmii/sata */
+#define USB_PHY_SWITCH_CTRL	0x0
+#define RG_PHY_SW_TYPE		GENMASK(3, 0)
+#define RG_PHY_SW_PCIE		0x0
+#define RG_PHY_SW_USB3		0x1
+#define RG_PHY_SW_SGMII		0x2
+#define RG_PHY_SW_SATA		0x3
+
 #define TPHY_CLKS_CNT	2
 
 enum mtk_phy_version {
@@ -322,7 +332,10 @@ struct mtk_phy_instance {
 	};
 	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
-	u8 type;
+	u32 type;
+	struct regmap *type_sw;
+	u32 type_sw_reg;
+	u32 type_sw_index;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
@@ -969,6 +982,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
 	}
 }
 
+/* type switch for usb3/pcie/sgmii/sata */
+static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+			       struct device_node *dn)
+{
+	struct of_phandle_args args;
+	int ret;
+
+	/* type switch function is optional */
+	if (!of_property_read_bool(dn, "mediatek,syscon-type"))
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
+					       2, 0, &args);
+	if (ret)
+		return ret;
+
+	instance->type_sw_reg = args.args[0];
+	instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
+	instance->type_sw = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
+		 instance->type_sw_reg, instance->type_sw_index);
+
+	return PTR_ERR_OR_ZERO(instance->type_sw);
+}
+
+static int phy_type_set(struct mtk_phy_instance *instance)
+{
+	int type;
+	u32 mask;
+
+	if (!instance->type_sw)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB3:
+		type = RG_PHY_SW_USB3;
+		break;
+	case PHY_TYPE_PCIE:
+		type = RG_PHY_SW_PCIE;
+		break;
+	case PHY_TYPE_SGMII:
+		type = RG_PHY_SW_SGMII;
+		break;
+	case PHY_TYPE_SATA:
+		type = RG_PHY_SW_SATA;
+		break;
+	case PHY_TYPE_USB2:
+	default:
+		return 0;
+	}
+
+	mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+	regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
+
+	return 0;
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -993,6 +1064,9 @@ static int mtk_phy_init(struct phy *phy)
 	case PHY_TYPE_SATA:
 		sata_phy_instance_init(tphy, instance);
 		break;
+	case PHY_TYPE_SGMII:
+		/* nothing to do, only used to set type */
+		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
 		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
@@ -1081,7 +1155,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	if (!(instance->type == PHY_TYPE_USB2 ||
 	      instance->type == PHY_TYPE_USB3 ||
 	      instance->type == PHY_TYPE_PCIE ||
-	      instance->type == PHY_TYPE_SATA)) {
+	      instance->type == PHY_TYPE_SATA ||
+	      instance->type == PHY_TYPE_SGMII)) {
 		dev_err(dev, "unsupported device type: %d\n", instance->type);
 		return ERR_PTR(-EINVAL);
 	}
@@ -1100,6 +1175,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	}
 
 	phy_parse_property(tphy, instance);
+	phy_type_set(instance);
 
 	return instance->phy;
 }
@@ -1244,6 +1320,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
+
+		retval = phy_type_syscon_get(instance, child_np);
+		if (retval)
+			goto put_child;
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:35 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:35 +0800
Subject: [PATCH v2 4/9] phy: phy-mtk-tphy: print error log using child device
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-4-git-send-email-chunfeng.yun@mediatek.com>

Print error log using child devices instead of parent device.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index a6502058a1a5..9d4b34298137 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1278,6 +1278,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
 		struct clk_bulk_data *clks;
+		struct device *subdev;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1295,16 +1296,17 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 			goto put_child;
 		}
 
+		subdev = &phy->dev;
 		retval = of_address_to_resource(child_np, 0, &res);
 		if (retval) {
-			dev_err(dev, "failed to get address resource(id-%d)\n",
+			dev_err(subdev, "failed to get address resource(id-%d)\n",
 				port);
 			goto put_child;
 		}
 
-		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(dev, "failed to remap phy regs\n");
+			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
@@ -1317,7 +1319,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		clks = instance->clks;
 		clks[0].id = "ref";     /* digital (& analog) clock */
 		clks[1].id = "da_ref";  /* analog clock */
-		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		retval = devm_clk_bulk_get_optional(subdev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
 
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:39 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:39 +0800
Subject: [PATCH v2 8/9] phy: phy-mtk-mipi-dsi: remove dummy assignment of
 error number
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-8-git-send-email-chunfeng.yun@mediatek.com>

Return the error number directly without assignment

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 01cf31633019..61c942fbf4a1 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -203,10 +203,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy, mipi_tx);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	if (IS_ERR(phy_provider)) {
-		ret = PTR_ERR(phy_provider);
-		return ret;
-	}
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
 
 	mipi_tx->dev = dev;
 
-- 
2.25.1

From p.yadav at ti.com  Wed Aug 11 10:33:37 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 11 Aug 2021 23:03:37 +0530
Subject: [PATCH v3 4/7] phy: cdns-dphy: Add Rx support
In-Reply-To: <YQ0Z2wYQYAFn2KCY@matsya>
References: <20210624184108.21312-1-p.yadav@ti.com>
 <20210624184108.21312-5-p.yadav@ti.com> <YQ0Z2wYQYAFn2KCY@matsya>
Message-ID: <20210811173335.ndrlzgepradfj4ij@ti.com>

On 06/08/21 04:45PM, Vinod Koul wrote:
> On 25-06-21, 00:11, Pratyush Yadav wrote:
> > The Cadence DPHY can be used to receive image data over the CSI-2
> > protocol. Add support for Rx mode. The programming sequence differs from
> > the Tx mode so it is added as a separate set of hooks to isolate the two
> > paths.
> > 
> > The PHY is in Tx mode by default and it needs to be set in Rx mode by
> > setting the submode to PHY_MIPI_DPHY_SUBMODE_RX in the set_mode()
> > callback.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > 
> > ---
> > 
> > Changes in v3:
> > - Use a table to select the band.
> > - Use a table to poll the data lane ready bits.
> > - Multiply the DPHY HS clock rate by 2 to get the bit rate since the
> >   clock is DDR.
> > 
> >  drivers/phy/cadence/cdns-dphy.c | 174 ++++++++++++++++++++++++++++++++
> >  1 file changed, 174 insertions(+)
> > 
> > diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> > index 7d5f7b333893..7534ec957dc5 100644
> > --- a/drivers/phy/cadence/cdns-dphy.c
> > +++ b/drivers/phy/cadence/cdns-dphy.c
> > @@ -1,11 +1,14 @@
> >  // SPDX-License-Identifier: GPL-2.0+
> >  /*
> >   * Copyright: 2017-2018 Cadence Design Systems, Inc.
> > + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
> >   */
> >  
> >  #include <linux/bitops.h>
> > +#include <linux/bitfield.h>
> >  #include <linux/clk.h>
> >  #include <linux/io.h>
> > +#include <linux/iopoll.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> >  #include <linux/of_device.h>
> > @@ -25,10 +28,14 @@
> >  #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
> >  #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
> >  #define DPHY_PCS(reg)			(0xb00 + (reg))
> > +#define DPHY_ISO(reg)			(0xc00 + (reg))
> >  
> >  #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
> >  #define DPHY_CMN_SSM_EN			BIT(0)
> > +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
> >  #define DPHY_CMN_TX_MODE_EN		BIT(9)
> > +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> > +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
> >  
> >  #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
> >  #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> > @@ -45,10 +52,27 @@
> >  #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
> >  #define DPHY_CMN_OPDIV(x)		((x) << 7)
> >  
> > +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> > +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> > +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> > +
> >  #define DPHY_PSM_CFG			DPHY_PCS(0x4)
> >  #define DPHY_PSM_CFG_FROM_REG		BIT(0)
> >  #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
> >  
> > +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> > +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> > +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> > +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> > +
> > +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> > +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> > +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> > +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> > +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> > +#define DPHY_ISO_LANE_READY_BIT		0
> > +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> > +
> >  #define DSI_HBP_FRAME_OVERHEAD		12
> >  #define DSI_HSA_FRAME_OVERHEAD		14
> >  #define DSI_HFP_FRAME_OVERHEAD		6
> > @@ -57,6 +81,9 @@
> >  #define DSI_NULL_FRAME_OVERHEAD		6
> >  #define DSI_EOT_PKT_SIZE		4
> >  
> > +#define DPHY_LANES_MIN			1
> > +#define DPHY_LANES_MAX			4
> > +
> >  struct cdns_dphy_cfg {
> >  	u8 pll_ipdiv;
> >  	u8 pll_opdiv;
> > @@ -103,6 +130,22 @@ struct cdns_dphy_driver_data {
> >  	const struct cdns_dphy_ops *rx;
> >  };
> >  
> > +struct cdns_dphy_rx_band {
> > +	unsigned int min_rate;
> > +	unsigned int max_rate;
> > +};
> > +
> > +/* Order of bands is important since the index is the band number. */
> > +struct cdns_dphy_rx_band bands[] = {
> > +	{80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240},
> > +	{240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480},
> > +	{480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880},
> > +	{880, 1040}, {1040, 1200}, {1200, 1350}, {1350, 1500}, {1500, 1750},
> > +	{1750, 2000}, {2000, 2250}, {2250, 2500}
> > +};
> > +
> > +int num_bands = ARRAY_SIZE(bands);
> > +
> >  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
> >  				     struct cdns_dphy_cfg *cfg,
> >  				     struct phy_configure_opts_mipi_dphy *opts,
> > @@ -312,6 +355,135 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> >  	.set_psm_div = cdns_dphy_ref_set_psm_div,
> >  };
> >  
> > +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> > +{
> > +	/* Start RX state machine. */
> > +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> > +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> > +			  DPHY_CMN_RX_BANDGAP_TIMER),
> > +	       dphy->regs + DPHY_CMN_SSM);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> > +{
> > +	writel(0, dphy->regs + DPHY_CMN_SSM);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> > +{
> > +	unsigned int rate;
> > +	int i;
> > +
> > +	rate = hs_clk_rate / 1000000UL;
> > +	/* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
> > +	rate *= 2;
> > +
> > +	if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate)
> > +		return -EOPNOTSUPP;
> > +
> > +	for (i = 0; i < num_bands; i++) {
> > +		if (rate >= bands[i].min_rate && rate < bands[i].max_rate)
> > +			return i;
> > +	}
> > +
> > +	/* Unreachable. */
> > +	WARN(1, "Reached unreachable code.");
> > +	return -EINVAL;
> > +}
> > +
> > +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> > +{
> > +	u32 val;
> > +
> > +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> > +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
> 
> this looks wrong, val is not initialized, so what/when is condition to
> be met..?

The readl_relaxed_poll_timeout() macro puts the value returned by 
readl() into val. That value is then used for testing the condition. See 
read_poll_timeout() in iopoll.h to see what the macro eventually expands 
to.

> -- 
> ~Vinod

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Wed Aug 11 10:36:31 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 11 Aug 2021 23:06:31 +0530
Subject: [PATCH v3 1/7] phy: Distinguish between Rx and Tx for MIPI D-PHY
 with submodes
In-Reply-To: <YQ0Y4ueALPNEAoMI@aptenodytes>
References: <20210624184108.21312-1-p.yadav@ti.com>
 <20210624184108.21312-2-p.yadav@ti.com>
 <YQ0Y4ueALPNEAoMI@aptenodytes>
Message-ID: <20210811173629.gse5qmzezlh2ua7g@ti.com>

On 06/08/21 01:11PM, Paul Kocialkowski wrote:
> Hi,
> 
> On Fri 25 Jun 21, 00:11, Pratyush Yadav wrote:
> > From: Paul Kocialkowski <paul.kocialkowski at bootlin.com>
> > 
> > As some D-PHY controllers support both Rx and Tx mode, we need a way for
> > users to explicitly request one or the other. For instance, Rx mode can
> > be used along with MIPI CSI-2 while Tx mode can be used with MIPI DSI.
> > 
> > Introduce new MIPI D-PHY PHY submodes to use with PHY_MODE_MIPI_DPHY.
> > The default (zero value) is kept to Tx so only the rkisp1 driver, which
> > uses D-PHY in Rx mode, needs to be adapted.
> 
> After some thinking and discussions, it appears that using the submode is
> probably not the best way to distinguish between rx and tx. This is because
> rx/tx is more of a specification of the hardware component than a run-time
> descision. Indeed the D-PHY blocks are usually dedicated to an associated
> controller (DSI or CSI-2) and thus each instance is either meant for tx or
> rx use.

Ok. IIRC Laurent also brought this point up earlier as well. At that 
time I took the allwinner DPHY as an example of a DPHY that can run in 
both modes.

The Cadence DPHY also supports both Rx and Tx modes but I don't know if 
both can be implemented at the same time, if that would even make any 
sense.

> 
> As a result I will be using the allwinner,direction string property in
> device-tree instead of the submode, with values of either "rx" or "tx".
> I suppose you can do something similar if you agree it makes more sense.

Wouldn't a different compatible a better idea?

> 
> Cheers,
> 
> Paul
>  
> > Signed-off-by: Paul Kocialkowski <paul.kocialkowski at bootlin.com>
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > ---
> > 
> > (no changes since v1)
> > 
> >  include/linux/phy/phy-mipi-dphy.h | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> > index a877ffee845d..0f57ef46a8b5 100644
> > --- a/include/linux/phy/phy-mipi-dphy.h
> > +++ b/include/linux/phy/phy-mipi-dphy.h
> > @@ -6,6 +6,19 @@
> >  #ifndef __PHY_MIPI_DPHY_H_
> >  #define __PHY_MIPI_DPHY_H_
> >  
> > +/**
> > + * enum phy_mipi_dphy_submode - MIPI D-PHY sub-mode
> > + *
> > + * A MIPI D-PHY can be used to transmit or receive data.
> > + * Since some controllers can support both, the direction to enable is specified
> > + * with the PHY sub-mode. Transmit is assumed by default with phy_set_mode.
> > + */
> > +
> > +enum phy_mipi_dphy_submode {
> > +	PHY_MIPI_DPHY_SUBMODE_TX = 0,
> > +	PHY_MIPI_DPHY_SUBMODE_RX,
> > +};
> > +
> >  /**
> >   * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
> >   *
> > -- 
> > 2.30.0
> > 
> 
> -- 
> Paul Kocialkowski, Bootlin
> Embedded Linux and kernel engineering
> https://bootlin.com



-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Wed Aug 11 10:39:50 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 11 Aug 2021 23:09:50 +0530
Subject: [PATCH v3 2/7] phy: cdns-dphy: Prepare for Rx support
In-Reply-To: <YQ0MZqI36bz1Jp87@matsya>
References: <20210624184108.21312-1-p.yadav@ti.com>
 <20210624184108.21312-3-p.yadav@ti.com> <YQ0MZqI36bz1Jp87@matsya>
Message-ID: <20210811173948.cezk6zu366c3huhw@ti.com>

On 06/08/21 03:48PM, Vinod Koul wrote:
> On 25-06-21, 00:11, Pratyush Yadav wrote:
> > The Rx programming sequence differs from the Tx programming sequence.
> > Currently only Tx mode is supported. Move all the Tx related parts into
> > a set of Tx-specific hooks that are then called by the main PHY
> > framework hooks. This way when Rx support is added all that is needed to
> > be done is to plug in the Rx hooks.
> > 
> > The clocks "psm" and "pll_ref" are not used by the Rx path so make them
> > optional in the probe and then check if they exist in the power_on()
> > hook.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > ---
> > 
> > (no changes since v1)
> > 
> >  drivers/phy/cadence/cdns-dphy.c | 140 ++++++++++++++++++++++++--------
> >  1 file changed, 104 insertions(+), 36 deletions(-)
> > 
> > diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> > index ba042e39cfaf..8656f2102a91 100644
> > --- a/drivers/phy/cadence/cdns-dphy.c
> > +++ b/drivers/phy/cadence/cdns-dphy.c
> > @@ -75,6 +75,11 @@ struct cdns_dphy;
> >  struct cdns_dphy_ops {
> >  	int (*probe)(struct cdns_dphy *dphy);
> >  	void (*remove)(struct cdns_dphy *dphy);
> > +	int (*power_on)(struct cdns_dphy *dphy);
> > +	int (*power_off)(struct cdns_dphy *dphy);
> > +	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
> > +			union phy_configure_opts *opts);
> > +	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
> >  	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
> >  	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
> >  				 enum cdns_dphy_clk_lane_cfg cfg);
> > @@ -86,12 +91,18 @@ struct cdns_dphy_ops {
> >  struct cdns_dphy {
> >  	struct cdns_dphy_cfg cfg;
> >  	void __iomem *regs;
> > +	struct device *dev;
> >  	struct clk *psm_clk;
> >  	struct clk *pll_ref_clk;
> >  	const struct cdns_dphy_ops *ops;
> >  	struct phy *phy;
> >  };
> >  
> > +struct cdns_dphy_driver_data {
> > +	const struct cdns_dphy_ops *tx;
> > +	const struct cdns_dphy_ops *rx;
> > +};
> > +
> >  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
> >  				     struct cdns_dphy_cfg *cfg,
> >  				     struct phy_configure_opts_mipi_dphy *opts,
> > @@ -199,20 +210,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
> >  	       dphy->regs + DPHY_PSM_CFG);
> >  }
> >  
> > -/*
> > - * This is the reference implementation of DPHY hooks. Specific integration of
> > - * this IP may have to re-implement some of them depending on how they decided
> > - * to wire things in the SoC.
> > - */
> > -static const struct cdns_dphy_ops ref_dphy_ops = {
> > -	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> > -	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> > -	.set_psm_div = cdns_dphy_ref_set_psm_div,
> > -};
> > -
> > -static int cdns_dphy_config_from_opts(struct phy *phy,
> > -				      struct phy_configure_opts_mipi_dphy *opts,
> > -				      struct cdns_dphy_cfg *cfg)
> > +static int cdns_dphy_tx_config_from_opts(struct phy *phy,
> > +					 struct phy_configure_opts_mipi_dphy *opts,
> > +					 struct cdns_dphy_cfg *cfg)
> >  {
> >  	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> >  	unsigned int dsi_hfp_ext = 0;
> > @@ -232,24 +232,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
> >  	return 0;
> >  }
> >  
> > -static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> > -			      union phy_configure_opts *opts)
> > +static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
> > +				  union phy_configure_opts *opts)
> >  {
> >  	struct cdns_dphy_cfg cfg = { 0 };
> > -
> > -	if (mode != PHY_MODE_MIPI_DPHY)
> > -		return -EINVAL;
> > -
> > -	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> > -}
> > -
> > -static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> > -{
> > -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > -	struct cdns_dphy_cfg cfg = { 0 };
> >  	int ret;
> >  
> > -	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> > +	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -279,9 +268,21 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> >  	return 0;
> >  }
> >  
> > -static int cdns_dphy_power_on(struct phy *phy)
> > +static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> > +				 int submode, union phy_configure_opts *opts)
> >  {
> > -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +	struct cdns_dphy_cfg cfg = { 0 };
> > +
> > +	if (submode != PHY_MIPI_DPHY_SUBMODE_TX)
> > +		return -EINVAL;
> > +
> > +	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
> > +}
> > +
> > +static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
> > +{
> > +	if (!dphy->psm_clk || !dphy->pll_ref_clk)
> > +		return -EINVAL;
> >  
> >  	clk_prepare_enable(dphy->psm_clk);
> >  	clk_prepare_enable(dphy->pll_ref_clk);
> > @@ -293,16 +294,77 @@ static int cdns_dphy_power_on(struct phy *phy)
> >  	return 0;
> >  }
> >  
> > -static int cdns_dphy_power_off(struct phy *phy)
> > +static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
> >  {
> > -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > -
> >  	clk_disable_unprepare(dphy->pll_ref_clk);
> >  	clk_disable_unprepare(dphy->psm_clk);
> >  
> >  	return 0;
> >  }
> >  
> > +static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> > +	.power_on = cdns_dphy_tx_power_on,
> > +	.power_off = cdns_dphy_tx_power_off,
> > +	.validate = cdns_dphy_tx_validate,
> > +	.configure = cdns_dphy_tx_configure,
> > +	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> > +	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> > +	.set_psm_div = cdns_dphy_ref_set_psm_div,
> > +};
> > +
> > +/*
> > + * This is the reference implementation of DPHY hooks. Specific integration of
> > + * this IP may have to re-implement some of them depending on how they decided
> > + * to wire things in the SoC.
> > + */
> > +static const struct cdns_dphy_driver_data ref_dphy_ops = {
> > +	.tx = &tx_ref_dphy_ops,
> > +};
> > +
> > +static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> > +			      union phy_configure_opts *opts)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (mode != PHY_MODE_MIPI_DPHY)
> > +		return -EINVAL;
> > +
> > +	if (dphy->ops->validate)
> > +		return dphy->ops->validate(dphy, mode, submode, opts);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_power_on(struct phy *phy)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (dphy->ops->power_on)
> > +		return dphy->ops->power_on(dphy);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_power_off(struct phy *phy)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (dphy->ops->power_off)
> > +		return dphy->ops->power_off(dphy);
> > +
> > +	return 0;
> > +}
> 
> why do you need a dphy specific power_on/off only to call internal
> ops..? If there is no additional logic lets drop this and continue the
> phy ops for this

I don't clearly understand what you are trying to say. The internal ops 
(dphy->ops) are DPHY-specific. So for example, you might have different 
power on/off sequences for Rx and Tx mode DPHYs. You would then 
implement different power_on() and power_off() hooks for those and store 
them in dphy->ops. How else would you handle this?

> 
> -- 
> ~Vinod

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From sbillaka at codeaurora.org  Wed Aug 11 17:23:43 2021
From: sbillaka at codeaurora.org (sbillaka at codeaurora.org)
Date: Thu, 12 Aug 2021 05:53:43 +0530
Subject: [PATCH 2/2] phy: qcom: Introduce new eDP PHY driver
In-Reply-To: <YRH0WFvWmemHIHqc@builder.lan>
References: <20210511041930.592483-1-bjorn.andersson@linaro.org>
 <20210511041930.592483-2-bjorn.andersson@linaro.org>
 <7708925ad4d973b4e5f291cdcbdbe406@codeaurora.org>
 <YRH0WFvWmemHIHqc@builder.lan>
Message-ID: <04267264ac7904733552d6ca02a6797b@codeaurora.org>

On 2021-08-10 09:06, Bjorn Andersson wrote:
> On Mon 09 Aug 22:15 CDT 2021, sbillaka at codeaurora.org wrote:
>> On 2021-05-11 09:49, Bjorn Andersson wrote:
>> > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c
> [..]
>> > +#define DP_PHY_AUX_CFG0				0x0020
>> > +#define DP_PHY_AUX_CFG1				0x0024
>> > +#define DP_PHY_AUX_CFG2				0x0028
>> > +#define DP_PHY_AUX_CFG3				0x002c
>> > +#define DP_PHY_AUX_CFG4				0x0030
>> > +#define DP_PHY_AUX_CFG5				0x0034
>> > +#define DP_PHY_AUX_CFG6				0x0038
>> > +#define DP_PHY_AUX_CFG7				0x003c
>> > +#define DP_PHY_AUX_CFG8				0x0040
>> > +#define DP_PHY_AUX_CFG9				0x0044
>> 
>> The DP_PHY_AUX_CFG0 offset for sc8180x eDP phy is 0x0024.
>> Some of the eDP PHY offset addresses are shifted by 4 address 
>> locations,
>> compared to the DP QMP PHY offset addresses for sc8180x.
>> The DP_PHY_AUX_CFG* offsets for this eDP phy driver are as below:
>> 
>> #define DP_PHY_AUX_CFG0                         0x0024
>> #define DP_PHY_AUX_CFG1                         0x0028
>> #define DP_PHY_AUX_CFG2                         0x002c
>> #define DP_PHY_AUX_CFG3                         0x0030
>> #define DP_PHY_AUX_CFG4                         0x0034
>> #define DP_PHY_AUX_CFG5                         0x0038
>> #define DP_PHY_AUX_CFG6                         0x003c
>> #define DP_PHY_AUX_CFG7                         0x0040
>> #define DP_PHY_AUX_CFG8                         0x0044
>> #define DP_PHY_AUX_CFG9                         0x0048
>> 
> 
> I noticed this as well. During development I just used the numbers
> directly in the code and I must have screwed up as I replaced them with
> defined - and somehow missed this in the testing before posting.
> 
> Sorry about that.
> 
> [..]
>> > +static int qcom_edp_phy_init(struct phy *phy)
>> > +{
>> > +	struct qcom_edp *edp = phy_get_drvdata(phy);
>> > +	int ret;
>> > +
>> > +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>> > +	if (ret)
>> > +		return ret;
>> > +
>> > +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
>> > +	if (ret)
>> > +		goto out_disable_supplies;
>> 
>> I think the number of clk and regulator resources can vary based on
>> platform.
>> 
> 
> If that's the case we should replace the ARRAY_SIZE() with an integer.
> But I prefer to wait with that until the number actually is variable.
> 
> [..]
>> > +static int qcom_edp_phy_probe(struct platform_device *pdev)
>> > +{
>> > +	struct phy_provider *phy_provider;
>> > +	struct device *dev = &pdev->dev;
>> > +	struct qcom_edp *edp;
>> > +	int ret;
>> > +
>> > +	edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL);
>> > +	if (!edp)
>> > +		return -ENOMEM;
>> > +
>> > +	edp->dev = dev;
>> > +
>> > +	edp->edp = devm_platform_ioremap_resource(pdev, 0);
>> > +	if (IS_ERR(edp->edp))
>> > +		return PTR_ERR(edp->edp);
>> > +
>> > +	edp->tx0 = devm_platform_ioremap_resource(pdev, 1);
>> > +	if (IS_ERR(edp->tx0))
>> > +		return PTR_ERR(edp->tx0);
>> > +
>> > +	edp->tx1 = devm_platform_ioremap_resource(pdev, 2);
>> > +	if (IS_ERR(edp->tx1))
>> > +		return PTR_ERR(edp->tx1);
>> > +
>> > +	edp->pll = devm_platform_ioremap_resource(pdev, 3);
>> > +	if (IS_ERR(edp->pll))
>> > +		return PTR_ERR(edp->pll);
>> > +
>> > +	edp->clks[0].id = "aux";
>> > +	edp->clks[1].id = "cfg_ahb";
>> > +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks);
>> > +	if (ret)
>> > +		return ret;
>> > +
>> > +	edp->supplies[0].supply = "vdda-phy";
>> > +	edp->supplies[1].supply = "vdda-pll";
>> > +	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies),
>> > edp->supplies);
>> > +	if (ret)
>> > +		return ret;
>> 
>> I believe, the combination of the number of regulator and clk 
>> resources may
>> vary based on the platform.
>> I think we should not fail probe if all these resources are not 
>> present in
>> the device tree file.
>> I think, these resources can be optional. We can get these resources 
>> if they
>> are present in the device tree file and enable them as required.
>> 
> 
> It's quite helpful to the DTS writer to actually encode in the driver
> which resources the driver expects and provide useful error messages
> when these expectations aren't met - so I think in line with most other
> drivers this should be decided based on the compatible.
> 
> What clocks and regulators do you have on sc7280?

We have only one clock (edp refclk) and one regulator (phy-0p9) for 
sc7280.

> 
> 
> Thanks for the feedback, I see that I have a few more pieces of 
> feedback
> from others that I need to incorporate. I'll make sure to do that and
> repost this patch shortly.

Okay. Thank you.

> 
> Regards,
> Bjorn


From robh at kernel.org  Wed Aug 11 20:13:32 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 22:13:32 -0500
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <20210811084648.66ddff29@coco.lan>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan> <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan> <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
 <20210810162054.1aa84b84@coco.lan>
 <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
 <20210811084648.66ddff29@coco.lan>
Message-ID: <CAL_JsqLg-jD1P3oGDocMaeHWQc+9kLr3gEdantRNUScUq5xsQw@mail.gmail.com>

On Wed, Aug 11, 2021 at 1:46 AM Mauro Carvalho Chehab
<mchehab+huawei at kernel.org> wrote:
>
> Em Tue, 10 Aug 2021 11:13:48 -0600
> Rob Herring <robh at kernel.org> escreveu:
>
> > > > >                                         compatible = "pciclass,0604";
> > > > >                                         device_type = "pci";
> > > > >                                         #address-cells = <3>;
> > > > >                                         #size-cells = <2>;
> > > > >                                         ranges;
> > > > >                                 };
> > > > >                                 pcie at 1,0 { // Lane 4: M.2
> > > >
> > > > These 3 nodes (1, 5, 7) need to be child nodes of the above node.
> >
> > This was the main issue.
>
> Ok, placing 1, 5, 7 as child nodes of 0 worked, with the attached
> DT schema:
>
>
>         $ ls -l $(find /sys/devices/platform/soc/f4000000.pcie/ -name of_node)
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/of_node -> ../../../../firmware/devicetree/base/soc/pcie at f4000000
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:01.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:01.0/pci_bus/0000:03/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:05.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:05.0/pci_bus/0000:05/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:07.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:07.0/pci_bus/0000:06/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node -> ../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node -> ../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
>         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000

This all looks right to me, but...

> The logs also seem OK on my eyes:
>
>         [    3.911082]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
>         [    4.001104] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
>         [    4.043609] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
>         [    4.076756] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
>         [    4.120652] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         [    4.150766] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         [    4.196413] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         [    4.238896] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         [    4.280116] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
>         [    4.309821] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0

...these do not.

>         [    4.370830] pci_bus 0000:03: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
>         [    4.382345] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
>         [    4.411966] pci_bus 0000:05: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
>         [    4.439898] pci_bus 0000:06: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
>         [    4.491616] pci 0000:06:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
>         [    4.519907] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)


From mchehab+huawei at kernel.org  Thu Aug 12 00:48:06 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Thu, 12 Aug 2021 09:48:06 +0200
Subject: [PATCH v3 0/4] DT schema changes for HiKey970 PCIe hardware to
 work
In-Reply-To: <CAL_JsqLg-jD1P3oGDocMaeHWQc+9kLr3gEdantRNUScUq5xsQw@mail.gmail.com>
References: <cover.1627965261.git.mchehab+huawei@kernel.org>
 <CAL_JsqLjw=+szXWJjGe86tMc51NA-5j=jVSXUAWuKeZRuJNJUg@mail.gmail.com>
 <20210804085045.3dddbb9c@coco.lan>
 <YQrARd7wgYS1nywt@robh.at.kernel.org>
 <20210805094612.2bc2c78f@coco.lan>
 <20210805095848.464cf85c@coco.lan>
 <CAL_JsqKso=z8LG3ViaggyS1k+1T2F5aAhP3_RNhumQoUUD+bbg@mail.gmail.com>
 <20210810114211.01df0246@coco.lan>
 <CAL_JsqKtXoFeJO6_13U+VsSXNGX_1TQvwOyQYRk5JUgBhvQChA@mail.gmail.com>
 <20210810162054.1aa84b84@coco.lan>
 <CAL_JsqL-R=kTugNAC-C1gfSm6Xnb0Nw_iLcRki8aQMNQjcLN6A@mail.gmail.com>
 <20210811084648.66ddff29@coco.lan>
 <CAL_JsqLg-jD1P3oGDocMaeHWQc+9kLr3gEdantRNUScUq5xsQw@mail.gmail.com>
Message-ID: <20210812094806.3a6de2a5@coco.lan>

Em Wed, 11 Aug 2021 22:13:32 -0500
Rob Herring <robh at kernel.org> escreveu:

> On Wed, Aug 11, 2021 at 1:46 AM Mauro Carvalho Chehab
> <mchehab+huawei at kernel.org> wrote:
> >
> > Em Tue, 10 Aug 2021 11:13:48 -0600
> > Rob Herring <robh at kernel.org> escreveu:
> >  
> > > > > >                                         compatible = "pciclass,0604";
> > > > > >                                         device_type = "pci";
> > > > > >                                         #address-cells = <3>;
> > > > > >                                         #size-cells = <2>;
> > > > > >                                         ranges;
> > > > > >                                 };
> > > > > >                                 pcie at 1,0 { // Lane 4: M.2  
> > > > >
> > > > > These 3 nodes (1, 5, 7) need to be child nodes of the above node.  
> > >
> > > This was the main issue.  
> >
> > Ok, placing 1, 5, 7 as child nodes of 0 worked, with the attached
> > DT schema:
> >
> >
> >         $ ls -l $(find /sys/devices/platform/soc/f4000000.pcie/ -name of_node)
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/of_node -> ../../../../firmware/devicetree/base/soc/pcie at f4000000
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:01.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:01.0/pci_bus/0000:03/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:05.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:05.0/pci_bus/0000:05/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:07.0/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:07.0/pci_bus/0000:06/of_node -> ../../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/pci_bus/0000:02/of_node -> ../../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/of_node -> ../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/0000:00:00.0/pci_bus/0000:01/of_node -> ../../../../../../../../firmware/devicetree/base/soc/pcie at f4000000/pcie at 0,0
> >         lrwxrwxrwx 1 root root 0 ago 11 08:43 /sys/devices/platform/soc/f4000000.pcie/pci0000:00/pci_bus/0000:00/of_node -> ../../../../../../../firmware/devicetree/base/soc/pcie at f4000000  
> 
> This all looks right to me, but...
> 
> > The logs also seem OK on my eyes:
> >
> >         [    3.911082]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
> >         [    4.001104] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000
> >         [    4.043609] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> >         [    4.076756] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
> >         [    4.120652] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         [    4.150766] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         [    4.196413] pci 0000:02:04.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         [    4.238896] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         [    4.280116] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
> >         [    4.309821] pci 0000:02:09.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0  
> 
> ...these do not.

For the above:

	s/of_node:/BUS of_node:/

The debug printk is misleading. It is actually printing the BUS of_node:

	void pci_set_of_node(struct pci_dev *dev)
	{
		dev_dbg(&dev->dev, "%s: of_node: %pOF\n",
			__func__, dev->bus->dev.of_node);

		if (!dev->bus->dev.of_node)
			return;
	...

If I move it to the right place, e. g.:

	void pci_set_of_node(struct pci_dev *dev)
	{
		if (!dev->bus->dev.of_node) {
			dev_dbg(&dev->dev, "%s: BUS of_node is null\n",
				__func__, dev->bus->dev.of_node);
			return;
		}
		dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node,
							    dev->devfn);
		if (dev->dev.of_node)
			dev->dev.fwnode = &dev->dev.of_node->fwnode;

		dev_dbg(&dev->dev, "%s: of_node: %pOF\n",
			__func__, dev->dev.of_node);
	}

It will produce:

	[    4.155771]  (null): pci_set_bus_of_node: of_node: /soc/pcie at f4000000
	[    4.208740] pci 0000:00:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.236759] pci_bus 0000:01: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0
	[    4.257899] pci 0000:01:00.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.310350] pci_bus 0000:02: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0
	[    4.337784] pci 0000:02:01.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
	[    4.370998] pci 0000:02:04.0: pci_set_of_node: of_node: (null)
	[    4.391459] pci 0000:02:05.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
	[    4.415378] pci 0000:02:07.0: pci_set_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
	[    4.439420] pci 0000:02:09.0: pci_set_of_node: of_node: (null)
	[    4.494288] pci_bus 0000:03: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 1,0
	[    4.511394] pci_bus 0000:04: pci_set_bus_of_node: of_node: (null)
	[    4.525084] pci_bus 0000:05: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 5,0
	[    4.542173] pci_bus 0000:06: pci_set_bus_of_node: of_node: /soc/pcie at f4000000/pcie at 0,0/pcie at 0,0/pcie at 7,0
	[    4.578575] pci 0000:06:00.0: pci_set_of_node: of_node: (null)
	[    4.612159] pci_bus 0000:07: pci_set_bus_of_node: of_node: (null)

Which reflects the PCIe topology.

Thanks,
Mauro


From mchehab+huawei at kernel.org  Thu Aug 12 01:02:11 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Thu, 12 Aug 2021 10:02:11 +0200
Subject: [PATCH v11 00/11] Add support for Hikey 970 PCIe
Message-ID: <cover.1628755058.git.mchehab+huawei@kernel.org>

The DT schema used by this series got merged at:

	https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=dt/next

Version 11 was modified to reflect this patch:

	https://lore.kernel.org/lkml/655e21422a14620ae2d55335eb72bcaa66f5384d.1628754620.git.mchehab+huawei at kernel.org/T/#u

Which contains a fix to the DT schema meant to make it produce the right sysfs
of_node devnodes.

The series should apply cleanly on the top of v5.14-rc1.

patch1 contains a PHY for Kirin 970 PCIe.

The remaining patches add support for Kirin 970 at the pcie-kirin driver, and
add the needed logic to compile it as module and to allow to dynamically
remove the driver in runtime.

Tested on HiKey970:

  # lspci -D -PP
  0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3670 (rev 01)
  0000:00:00.0/01:00.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:01.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:04.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:05.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:07.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:09.0 PCI bridge: PLX Technology, Inc. PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch (rev ba)
  0000:00:00.0/01:00.0/02:01.0/03:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a809
  0000:00:00.0/01:00.0/02:07.0/06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 07)

Tested on HiKey960:

  # lspci -D 
  0000:00:00.0 PCI bridge: Huawei Technologies Co., Ltd. Device 3660 (rev 01)

---

v11:
  - patch 5 changed to use the right PCIe topology
  - all other patches are identical to v10.

v10:
  - patch 1: dropped magic numbers from PHY driver
  - patch 5: allow pcie child nodes without reset-gpios
  - all other patches are identical to v9.

v9:
  - Did some cleanups at patches 1 and 5

Mauro Carvalho Chehab (11):
  phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
  PCI: kirin: Reorganize the PHY logic inside the driver
  PCI: kirin: Add support for a PHY layer
  PCI: kirin: Use regmap for APB registers
  PCI: kirin: Add support for bridge slot DT schema
  PCI: kirin: Add Kirin 970 compatible
  PCI: kirin: Add MODULE_* macros
  PCI: kirin: Allow building it as a module
  PCI: kirin: Add power_off support for Kirin 960 PHY
  PCI: kirin: fix poweroff sequence
  PCI: kirin: Allow removing the driver

 drivers/pci/controller/dwc/Kconfig      |   2 +-
 drivers/pci/controller/dwc/pcie-kirin.c | 644 ++++++++++++++----
 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 857 ++++++++++++++++++++++++
 5 files changed, 1366 insertions(+), 148 deletions(-)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

-- 
2.31.1




From mchehab+huawei at kernel.org  Thu Aug 12 01:02:12 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Thu, 12 Aug 2021 10:02:12 +0200
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
In-Reply-To: <cover.1628755058.git.mchehab+huawei@kernel.org>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
Message-ID: <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>

The Kirin 970 PHY is somewhat similar to the Kirin 960, but it
does a lot more. Add the needed bits for PCIe to start working on
HiKey 970 boards.

Co-developed-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 857 ++++++++++++++++++++++++
 3 files changed, 868 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 4d008cfc279c..d3b92c288554 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -33,6 +33,16 @@ config PHY_HI3670_USB
 
 	  To compile this driver as a module, choose M here.
 
+config PHY_HI3670_PCIE
+	tristate "hi3670 PCIe PHY support"
+	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+	select GENERIC_PHY
+	select MFD_SYSCON
+	help
+	  Enable this to support the HiSilicon hi3670 PCIe PHY.
+
+	  To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
 	tristate "HiSilicon STB SoCs COMBPHY support"
 	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 51729868145b..4029d3813b1e 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_HI6220_USB)		+= phy-hi6220-usb.o
 obj-$(CONFIG_PHY_HI3660_USB)		+= phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HI3670_USB)		+= phy-hi3670-usb3.o
+obj-$(CONFIG_PHY_HI3670_PCIE)		+= phy-hi3670-pcie.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)		+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)	+= phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
new file mode 100644
index 000000000000..2d2c35ed7652
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -0,0 +1,857 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe phy driver for Kirin 970
+ *
+ * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
+ *		https://www.huawei.com
+ * Copyright (C) 2021 Huawei Technologies Co., Ltd.
+ *		https://www.huawei.com
+ *
+ * Authors:
+ *	Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+ *	Manivannan Sadhasivam <mani at kernel.org>
+ *
+ * Based on:
+ *	https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei at kernel.org/
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AXI_CLK_FREQ				207500000
+#define REF_CLK_FREQ				100000000
+
+/* PCIe CTRL registers */
+#define SOC_PCIECTRL_CTRL0_ADDR			0x000
+#define SOC_PCIECTRL_CTRL1_ADDR			0x004
+#define SOC_PCIECTRL_CTRL7_ADDR			0x01c
+#define SOC_PCIECTRL_CTRL12_ADDR		0x030
+#define SOC_PCIECTRL_CTRL20_ADDR		0x050
+#define SOC_PCIECTRL_CTRL21_ADDR		0x054
+#define SOC_PCIECTRL_STATE0_ADDR		0x400
+
+#define PCIE_OUTPUT_PULL_BITS			GENMASK(3, 0)
+#define SOC_PCIECTRL_CTRL20_2P_MEM_CTRL		0x02605550
+#define SOC_PCIECTRL_CTRL21_DEFAULT		0x20000070
+#define PCIE_PULL_UP_SYS_AUX_PWR_DET		BIT(10)
+#define PCIE_OUTPUT_PULL_DOWN			BIT(1)
+
+/* PCIe PHY registers */
+#define SOC_PCIEPHY_CTRL0_ADDR			0x000
+#define SOC_PCIEPHY_CTRL1_ADDR			0x004
+#define SOC_PCIEPHY_CTRL2_ADDR			0x008
+#define SOC_PCIEPHY_CTRL3_ADDR			0x00c
+#define SOC_PCIEPHY_CTRL38_ADDR			0x0098
+#define SOC_PCIEPHY_STATE0_ADDR			0x400
+
+#define PORT_MSI_CTRL_ADDR			0x820
+#define PORT_MSI_CTRL_UPPER_ADDR		0x824
+#define PORT_MSI_CTRL_INT0_ENABLE		0x828
+
+#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1	0xc004
+#define SUP_DIG_LVL_OVRD_IN			0x003c
+#define LANEN_DIG_ASIC_TX_OVRD_IN_1		0x4008
+#define LANEN_DIG_ASIC_TX_OVRD_IN_2		0x400c
+
+#define PCIE_LINKUP_ENABLE			0x8020
+#define PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
+#define PCIE_LTSSM_ENABLE_BIT			BIT(11)
+#define PCIEPHY_RESET_BIT			BIT(17)
+#define PCIEPHY_PIPE_LINE0_RESET_BIT		BIT(19)
+#define PCIE_TXDETECT_RX_FAIL			BIT(2)
+#define PCIE_CLK_SOURCE				BIT(8)
+#define PCIE_IS_CLOCK_STABLE			BIT(19)
+#define PCIE_PULL_DOWN_PHY_TEST_POWERDOWN	BIT(22)
+#define PCIE_DEASSERT_CONTROLLER_PERST		BIT(2)
+
+#define EYEPARAM_NOCFG				0xffffffff
+#define EYE_PARM0_MASK				GENMASK(8, 6)
+#define EYE_PARM1_MASK				GENMASK(11, 8)
+#define EYE_PARM2_MASK				GENMASK(5, 0)
+#define EYE_PARM3_MASK				GENMASK(12, 7)
+#define EYE_PARM4_MASK				GENMASK(14, 9)
+#define EYE_PARM0_EN				BIT(9)
+#define EYE_PARM1_EN				BIT(12)
+#define EYE_PARM2_EN				BIT(6)
+#define EYE_PARM3_EN				BIT(13)
+#define EYE_PARM4_EN				BIT(15)
+
+/* hi3670 pciephy register */
+#define APB_PHY_START_ADDR			0x40000
+#define SOC_PCIEPHY_MMC1PLL_CTRL1		0xc04
+#define SOC_PCIEPHY_MMC1PLL_CTRL16		0xC40
+#define SOC_PCIEPHY_MMC1PLL_CTRL17		0xC44
+#define SOC_PCIEPHY_MMC1PLL_CTRL20		0xC50
+#define SOC_PCIEPHY_MMC1PLL_CTRL21		0xC54
+#define SOC_PCIEPHY_MMC1PLL_STAT0		0xE00
+
+#define CRGPERIPH_PEREN12			0x470
+#define CRGPERIPH_PERDIS12			0x474
+#define CRGPERIPH_PCIECTRL0			0x800
+
+#define PCIE_FNPLL_FBDIV_MASK			GENMASK(27, 16)
+#define PCIE_FNPLL_FRACDIV_MASK			GENMASK(23, 0)
+#define PCIE_FNPLL_POSTDIV1_MASK		GENMASK(10, 8)
+#define PCIE_FNPLL_POSTDIV2_MASK		GENMASK(14, 12)
+#define PCIE_FNPLL_PLL_MODE_MASK		BIT(25)
+
+#define PCIE_FNPLL_DLL_EN			BIT(27)
+#define PCIE_FNPLL_FBDIV			0xd0
+#define PCIE_FNPLL_FRACDIV			0x555555
+#define PCIE_FNPLL_POSTDIV1			0x5
+#define PCIE_FNPLL_POSTDIV2			0x4
+#define PCIE_FNPLL_PLL_MODE			0x0
+
+#define PCIE_PHY_MMC1PLL			0x20
+#define PCIE_PHY_CHOOSE_FNPLL			BIT(27)
+#define PCIE_PHY_MMC1PLL_DISABLE		BIT(0)
+#define PCIE_PHY_PCIEPL_BP			BIT(16)
+
+/* define ie,oe cfg */
+#define IO_OE_HARD_GT_MODE			BIT(1)
+#define IO_IE_EN_HARD_BYPASS			BIT(27)
+#define IO_OE_EN_HARD_BYPASS			BIT(11)
+#define IO_HARD_CTRL_DEBOUNCE_BYPASS		BIT(10)
+#define IO_OE_GT_MODE				BIT(8)
+#define DEBOUNCE_WAITCFG_IN			GENMASK(23, 20)
+#define DEBOUNCE_WAITCFG_OUT			GENMASK(16, 13)
+
+#define IO_HP_DEBOUNCE_GT			(BIT(12) | BIT(15))
+#define IO_PHYREF_SOFT_GT_MODE			BIT(14)
+#define IO_REF_SOFT_GT_MODE			BIT(13)
+#define IO_REF_HARD_GT_MODE			BIT(0)
+
+/* noc power domain */
+#define NOC_POWER_IDLEREQ_1			0x38c
+#define NOC_POWER_IDLE_1			0x394
+#define NOC_PW_MASK				0x10000
+#define NOC_PW_SET_BIT				0x1
+
+#define NUM_EYEPARAM				5
+
+/* info located in sysctrl */
+#define SCTRL_PCIE_CMOS_OFFSET			0x60
+#define SCTRL_PCIE_CMOS_BIT			0x10
+#define SCTRL_PCIE_ISO_OFFSET			0x44
+#define SCTRL_PCIE_ISO_BIT			0x30
+#define SCTRL_PCIE_HPCLK_OFFSET			0x190
+#define SCTRL_PCIE_HPCLK_BIT			0x184000
+#define SCTRL_PCIE_OE_OFFSET			0x14a
+#define PCIE_DEBOUNCE_PARAM			0xf0f400
+#define PCIE_OE_BYPASS				GENMASK(29, 28)
+
+/* peri_crg ctrl */
+#define CRGCTRL_PCIE_ASSERT_OFFSET		0x88
+#define CRGCTRL_PCIE_ASSERT_BIT			0x8c000000
+
+#define FNPLL_HAS_LOCKED			BIT(4)
+
+/* Time for delay */
+#define PIPE_CLK_WAIT_MIN	550
+#define PIPE_CLK_WAIT_MAX	600
+#define TIME_CMOS_MIN		100
+#define TIME_CMOS_MAX		105
+#define TIME_PHY_PD_MIN		10
+#define TIME_PHY_PD_MAX		11
+
+#define PIPE_CLK_STABLE_TIME	100
+#define PLL_CTRL_WAIT_TIME	200
+#define NOC_POWER_TIME		100
+
+struct hi3670_pcie_phy {
+	struct device	*dev;
+	void __iomem	*base;
+	struct regmap	*apb;
+	struct regmap	*crgctrl;
+	struct regmap	*sysctrl;
+	struct regmap	*pmctrl;
+	struct clk	*apb_sys_clk;
+	struct clk	*apb_phy_clk;
+	struct clk	*phy_ref_clk;
+	struct clk	*aclk;
+	struct clk	*aux_clk;
+	u32		eye_param[NUM_EYEPARAM];
+};
+
+/* Registers in PCIePHY */
+static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy, u32 val,
+					 u32 reg)
+{
+	writel(val, phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
+{
+	return readl(phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
+						u32 val, u32 reg)
+{
+	writel(val, phy->base + reg);
+}
+
+static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
+					      u32 reg)
+{
+	return readl(phy->base + reg);
+}
+
+static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
+{
+	u32 val;
+
+	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
+	val |= PCIE_DEBOUNCE_PARAM;
+	if (enable)
+		val &= ~PCIE_OE_BYPASS;
+	else
+		val |= PCIE_OE_BYPASS;
+	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
+}
+
+static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np;
+	int ret, i;
+
+	np = dev->of_node;
+
+	ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
+					 phy->eye_param, NUM_EYEPARAM);
+	if (!ret)
+		return;
+
+	/* There's no optional eye_param property. Set array to default */
+	for (i = 0; i < NUM_EYEPARAM; i++)
+		phy->eye_param[i] = EYEPARAM_NOCFG;
+}
+
+static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = kirin_apb_natural_phy_readl(phy,
+					  RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM1_MASK;
+		val |= FIELD_PREP(EYE_PARM1_MASK, phy->eye_param[1]);
+		val |= EYE_PARM1_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val,
+				     RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+	val &= ~(EYE_PARM2_MASK | EYE_PARM3_MASK);
+	if (phy->eye_param[2] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM2_MASK, phy->eye_param[2]);
+		val |= EYE_PARM2_EN;
+	}
+
+	if (phy->eye_param[3] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM3_MASK, phy->eye_param[3]);
+		val |= EYE_PARM3_EN;
+	}
+
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+
+	val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
+	if (phy->eye_param[0] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM0_MASK;
+		val |= FIELD_PREP(EYE_PARM0_MASK, phy->eye_param[0]);
+		val |= EYE_PARM0_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+	if (phy->eye_param[4] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM4_MASK;
+		val |= FIELD_PREP(EYE_PARM4_MASK, phy->eye_param[4]);
+		val |= EYE_PARM4_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+}
+
+static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* change 2p mem_ctrl */
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
+		     SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
+
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
+	val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
+
+	/* output, pull down */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val &= ~PCIE_OUTPUT_PULL_BITS;
+	val |= PCIE_OUTPUT_PULL_DOWN;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+
+	/* Handle phy_reset and lane0_reset to HW */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
+	val |= PCIEPHY_RESET_BIT;
+	val &= ~PCIEPHY_PIPE_LINE0_RESET_BIT;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
+
+	/* fix chip bug: TxDetectRx fail */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL38_ADDR);
+	val |= PCIE_TXDETECT_RX_FAIL;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL38_ADDR);
+}
+
+static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL1);
+	val |= PCIE_PHY_CHOOSE_FNPLL;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL1);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+	val &= ~PCIE_FNPLL_FBDIV_MASK;
+	val |= FIELD_PREP(PCIE_FNPLL_FBDIV_MASK, PCIE_FNPLL_FBDIV);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL17);
+	val &= PCIE_FNPLL_FRACDIV_MASK;
+	val |= FIELD_PREP(PCIE_FNPLL_FRACDIV_MASK, PCIE_FNPLL_FRACDIV);
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL17);
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+	val &= ~(PCIE_FNPLL_POSTDIV1_MASK | PCIE_FNPLL_POSTDIV2_MASK |
+		 PCIE_FNPLL_PLL_MODE_MASK | PCIE_FNPLL_DLL_EN);
+	val |= PCIE_FNPLL_DLL_EN;
+	val |= FIELD_PREP(PCIE_FNPLL_POSTDIV1_MASK, PCIE_FNPLL_POSTDIV1);
+	val |= FIELD_PREP(PCIE_FNPLL_POSTDIV2_MASK, PCIE_FNPLL_POSTDIV2);
+	val |= FIELD_PREP(PCIE_FNPLL_PLL_MODE_MASK, PCIE_FNPLL_PLL_MODE);
+
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	hi3670_apb_phy_writel(phy, PCIE_PHY_MMC1PLL,
+			      SOC_PCIEPHY_MMC1PLL_CTRL21);
+}
+
+static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int time = PLL_CTRL_WAIT_TIME;
+
+	if (enable) {
+		/* pd = 0 */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+		val &= ~PCIE_PHY_MMC1PLL_DISABLE;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+
+		/* choose FNPLL */
+		while (!(val & FNPLL_HAS_LOCKED)) {
+			if (!time) {
+				dev_err(dev, "wait for pll_lock timeout\n");
+				return -EINVAL;
+			}
+			time--;
+			udelay(1);
+			val = hi3670_apb_phy_readl(phy,
+						   SOC_PCIEPHY_MMC1PLL_STAT0);
+		}
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+		val &= ~PCIE_PHY_PCIEPL_BP;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	} else {
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
+		val |= PCIE_PHY_MMC1PLL_DISABLE;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL20);
+		val |= PCIE_PHY_PCIEPL_BP;
+		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL20);
+	}
+
+	return 0;
+}
+
+static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	if (open)
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
+		regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
+			     IO_HP_DEBOUNCE_GT);
+	else
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_HP_DEBOUNCE_GT);
+}
+
+static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	if (open)
+		val &= ~IO_OE_HARD_GT_MODE; // enable hard gt mode
+	else
+		val |= IO_OE_HARD_GT_MODE; // disable hard gt mode
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+	/* disable soft gt mode */
+	regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, IO_PHYREF_SOFT_GT_MODE);
+}
+
+static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	/* set ie cfg */
+	val |= IO_IE_EN_HARD_BYPASS;
+
+	/* set oe cfg */
+	val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
+
+	/* set phy_debounce in&out time */
+	val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
+
+	/* select oe_gt_mode */
+	val |= IO_OE_GT_MODE;
+
+	if (en_flag)
+		val &= ~IO_OE_EN_HARD_BYPASS;
+	else
+		val |= IO_OE_EN_HARD_BYPASS;
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+}
+
+static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	if (open) {
+		regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR,
+			     SOC_PCIECTRL_CTRL21_DEFAULT);
+
+		hi3670_pcie_oe_ctrl(phy, true);
+
+		/* en hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val &= ~IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+	} else {
+		/* disable hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val |= IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+		hi3670_pcie_oe_ctrl(phy, false);
+	}
+}
+
+static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int ret = 0;
+
+	if (!clk_on)
+		goto close_clocks;
+
+	/* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
+	val &= ~PCIE_CLK_SOURCE;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
+
+	hi3670_pcie_pll_init(phy);
+
+	ret = hi3670_pcie_pll_ctrl(phy, true);
+	if (ret) {
+		dev_err(dev, "Failed to enable pll\n");
+		return -EINVAL;
+	}
+	hi3670_pcie_hp_debounce_gt(phy, true);
+	hi3670_pcie_phyref_gt(phy, true);
+	hi3670_pcie_ioref_gt(phy, true);
+
+	ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
+	if (ret) {
+		dev_err(dev, "Failed to set rate\n");
+		goto close_clocks;
+	}
+
+	return 0;
+
+close_clocks:
+	hi3670_pcie_ioref_gt(phy, false);
+	hi3670_pcie_phyref_gt(phy, false);
+	hi3670_pcie_hp_debounce_gt(phy, false);
+
+	hi3670_pcie_pll_ctrl(phy, false);
+
+	return ret;
+}
+
+static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	u32 time = PIPE_CLK_STABLE_TIME;
+	u32 pipe_clk_stable = PCIE_IS_CLOCK_STABLE;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	while (val & pipe_clk_stable) {
+		mdelay(1);
+		if (!time) {
+			dev_err(dev, "PIPE clk is not stable\n");
+			return false;
+		}
+		time--;
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	}
+
+	return true;
+}
+
+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 time = NOC_POWER_TIME;
+	unsigned int val = NOC_PW_MASK;
+	int rst;
+
+	if (enable)
+		val = NOC_PW_MASK | NOC_PW_SET_BIT;
+	else
+		val = NOC_PW_MASK;
+	rst = enable ? 1 : 0;
+
+	regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
+
+	time = NOC_POWER_TIME;
+	regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	while ((val & NOC_PW_SET_BIT) != rst) {
+		udelay(10);
+		if (!time) {
+			dev_err(dev, "Failed to reverse noc power-status\n");
+			return -EINVAL;
+		}
+		time--;
+		regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	}
+
+	return 0;
+}
+
+static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
+{
+	struct device_node *pcie_port;
+	struct device *dev = phy->dev;
+	struct device *pcie_dev;
+
+	pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
+	if (!pcie_port) {
+		dev_err(dev, "no pcie node found in %s\n",
+			dev->parent->of_node->full_name);
+		return -ENODEV;
+	}
+
+	pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
+	if (!pcie_dev) {
+		dev_err(dev, "Didn't find pcie device\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * We might just use NULL instead of the APB name, as the
+	 * pcie-kirin currently registers directly just one regmap (although
+	 * the DWC driver register other regmaps).
+	 *
+	 * Yet, it sounds safer to warrant that it will be accessing the
+	 * right regmap. So, let's use the named version.
+	 */
+	phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
+	if (!phy->apb) {
+		dev_err(dev, "Failed to get APB regmap\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto close_clk;
+
+	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->phy_ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->apb_sys_clk);
+	if (ret)
+		goto apb_sys_fail;
+
+	ret = clk_prepare_enable(phy->apb_phy_clk);
+	if (ret)
+		goto apb_phy_fail;
+
+	ret = clk_prepare_enable(phy->aclk);
+	if (ret)
+		goto aclk_fail;
+
+	ret = clk_prepare_enable(phy->aux_clk);
+	if (ret)
+		goto aux_clk_fail;
+
+	return 0;
+
+close_clk:
+	clk_disable_unprepare(phy->aux_clk);
+aux_clk_fail:
+	clk_disable_unprepare(phy->aclk);
+aclk_fail:
+	clk_disable_unprepare(phy->apb_phy_clk);
+apb_phy_fail:
+	clk_disable_unprepare(phy->apb_sys_clk);
+apb_sys_fail:
+	clk_disable_unprepare(phy->phy_ref_clk);
+
+	return ret;
+}
+
+static int hi3670_pcie_phy_init(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int ret;
+
+	/*
+	 * The code under hi3670_pcie_get_resources_from_pcie() need to
+	 * access the reset-gpios and the APB registers, both from the
+	 * pcie-kirin driver.
+	 *
+	 * The APB is obtained via the pcie driver's regmap
+	 * Such kind of resource can only be obtained during the PCIe
+	 * power_on sequence, as the code inside pcie-kirin needs to
+	 * be already probed, as it needs to register the APB regmap.
+	 */
+
+	ret = hi3670_pcie_get_resources_from_pcie(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int val, ret;
+
+	/* Power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
+	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
+
+	hi3670_pcie_phy_oe_enable(phy, true);
+
+	ret = kirin_pcie_clk_ctrl(phy, true);
+	if (ret)
+		return ret;
+
+	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
+	regmap_write(phy->crgctrl, CRGCTRL_PCIE_ASSERT_OFFSET,
+		     CRGCTRL_PCIE_ASSERT_BIT);
+	regmap_write(phy->sysctrl, SCTRL_PCIE_HPCLK_OFFSET,
+		     SCTRL_PCIE_HPCLK_BIT);
+
+	hi3670_pcie_natural_cfg(phy);
+
+	ret = hi3670_pcie_allclk_ctrl(phy, true);
+	if (ret)
+		goto disable_clks;
+
+	/* pull down phy_test_powerdown signal */
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL0_ADDR);
+	val &= ~PCIE_PULL_DOWN_PHY_TEST_POWERDOWN;
+	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL0_ADDR);
+
+	/* deassert controller perst_n */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val |= PCIE_DEASSERT_CONTROLLER_PERST;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+	udelay(10);
+
+	ret = is_pipe_clk_stable(phy);
+	if (!ret)
+		goto disable_clks;
+
+	hi3670_pcie_set_eyeparam(phy);
+
+	ret = hi3670_pcie_noc_power(phy, false);
+	if (ret)
+		goto disable_clks;
+
+	return 0;
+
+disable_clks:
+	kirin_pcie_clk_ctrl(phy, false);
+	return ret;
+}
+
+static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+
+	hi3670_pcie_phy_oe_enable(phy, false);
+
+	hi3670_pcie_allclk_ctrl(phy, false);
+
+	/* Drop power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
+
+	/* FIXME: calling it causes an Asynchronous SError interrupt */
+//	kirin_pcie_clk_ctrl(phy, false);
+
+	return 0;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+	.init		= hi3670_pcie_phy_init,
+	.power_on	= hi3670_pcie_phy_power_on,
+	.power_off	= hi3670_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
+					 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* syscon */
+	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
+	if (IS_ERR(phy->crgctrl))
+		return PTR_ERR(phy->crgctrl);
+
+	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	/* clocks */
+	phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
+	if (IS_ERR(phy->phy_ref_clk))
+		return PTR_ERR(phy->phy_ref_clk);
+
+	phy->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(phy->aux_clk))
+		return PTR_ERR(phy->aux_clk);
+
+	phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
+	if (IS_ERR(phy->apb_phy_clk))
+		return PTR_ERR(phy->apb_phy_clk);
+
+	phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
+	if (IS_ERR(phy->apb_sys_clk))
+		return PTR_ERR(phy->apb_sys_clk);
+
+	phy->aclk = devm_clk_get(dev, "aclk");
+	if (IS_ERR(phy->aclk))
+		return PTR_ERR(phy->aclk);
+
+	/* registers */
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	hi3670_pcie_get_eyeparam(phy);
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct hi3670_pcie_phy *phy;
+	struct phy *generic_phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+
+	ret = hi3670_pcie_phy_get_resources(phy, pdev);
+	if (ret)
+		return ret;
+
+	generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_pcie_phy_match[] = {
+	{
+		.compatible = "hisilicon,hi970-pcie-phy",
+	},
+	{},
+};
+
+static struct platform_driver hi3670_pcie_phy_driver = {
+	.probe	= hi3670_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= hi3670_pcie_phy_match,
+		.name		= "hi3670_pcie_phy",
+		.suppress_bind_attrs = true,
+	}
+};
+builtin_platform_driver(hi3670_pcie_phy_driver);
+
+MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
+MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab at kernel.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <mani at kernel.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1



From tsbogend at alpha.franken.de  Thu Aug 12 07:09:34 2021
From: tsbogend at alpha.franken.de (Thomas Bogendoerfer)
Date: Thu, 12 Aug 2021 16:09:34 +0200
Subject: [PATCH v4 0/9] MIPS: Migrate pistachio to generic kernel
In-Reply-To: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
References: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
Message-ID: <20210812140934.GA9924@alpha.franken.de>

On Fri, Jul 23, 2021 at 10:25:34AM +0800, Jiaxun Yang wrote:
> I'm lucky enough to get a Creator CI40 board from dusts.
> This patchset move it to gerneic kernel to reduce maintenance burden.
> It have been tested with SD Card boot.
> 
> --
> v2: Minor fixes
> v3: Typo fixes and 0day testbot warning fix (Thanks to Sergei!)
> v4: 01.org warning fix
> 
> Jiaxun Yang (9):
>   MIPS: generic: Allow generating FIT image for Marduk board
>   MIPS: DTS: Pistachio add missing cpc and cdmm
>   clk: pistachio: Make it selectable for generic MIPS kernel
>   clocksource/drivers/pistachio: Make it selectable for MIPS
>   phy: pistachio-usb: Depend on MIPS || COMPILE_TEST
>   pinctrl: pistachio: Make it as an option
>   MIPS: config: generic: Add config for Marduk board
>   MIPS: Retire MACH_PISTACHIO
>   MIPS: Make a alias for pistachio_defconfig
> 
>  arch/mips/Kbuild.platforms                    |   1 -
>  arch/mips/Kconfig                             |  30 --
>  arch/mips/Makefile                            |   3 +
>  arch/mips/boot/dts/Makefile                   |   2 +-
>  arch/mips/boot/dts/img/Makefile               |   3 +-
>  arch/mips/boot/dts/img/pistachio.dtsi         |  10 +
>  arch/mips/configs/generic/board-marduk.config |  53 +++
>  arch/mips/configs/pistachio_defconfig         | 316 ------------------
>  arch/mips/generic/Kconfig                     |   6 +
>  arch/mips/generic/Platform                    |   1 +
>  arch/mips/generic/board-marduk.its.S          |  22 ++
>  arch/mips/pistachio/Kconfig                   |  14 -
>  arch/mips/pistachio/Makefile                  |   2 -
>  arch/mips/pistachio/Platform                  |   6 -
>  arch/mips/pistachio/init.c                    | 125 -------
>  arch/mips/pistachio/irq.c                     |  24 --
>  arch/mips/pistachio/time.c                    |  55 ---
>  drivers/clk/Kconfig                           |   1 +
>  drivers/clk/Makefile                          |   2 +-
>  drivers/clk/pistachio/Kconfig                 |   8 +
>  drivers/clocksource/Kconfig                   |   3 +-
>  drivers/phy/Kconfig                           |   2 +-
>  drivers/pinctrl/Kconfig                       |   5 +-
>  23 files changed, 114 insertions(+), 580 deletions(-)
>  create mode 100644 arch/mips/configs/generic/board-marduk.config
>  delete mode 100644 arch/mips/configs/pistachio_defconfig
>  create mode 100644 arch/mips/generic/board-marduk.its.S
>  delete mode 100644 arch/mips/pistachio/Kconfig
>  delete mode 100644 arch/mips/pistachio/Makefile
>  delete mode 100644 arch/mips/pistachio/Platform
>  delete mode 100644 arch/mips/pistachio/init.c
>  delete mode 100644 arch/mips/pistachio/irq.c
>  delete mode 100644 arch/mips/pistachio/time.c
>  create mode 100644 drivers/clk/pistachio/Kconfig

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]


From pgwipeout at gmail.com  Thu Aug 12 13:41:08 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:08 -0400
Subject: [PATCH v2 0/8] phy-rockchip-inno-usb2: support rk356x usb2phy
Message-ID: <20210812204116.2303617-1-pgwipeout@gmail.com>

Good Afternoon,

This is my series to support the usb2 phy devices on the rk356x.
The rk356x phy has a single muxed interrupt and has moved the usb2phy
nodes out of the grf and into their own nodes.
The phy needs to tie back into the grf for register control, similar to
the rv1108.
By moving the phys into their own nodes, they now have full
#address_cells = 2 register addresses, but they still reside below the 32bit
mmio range.

This driver series only supports the host configuration for the rk356x.
I have have tested it on the following:
rk3566 - Pine64 Quartz64 Model A
rk3399 - Pine64 Rockpro64

Please provide feedback and comments as you see fit.

Changelog:
v2:
- correct the order of the usb2phy-grf dt-bindings patch, thanks Johan
- correct the conditional requirements of phy-rockchip-inno-usb2, thanks
  Johan
- drop increase generic-ohci clocks patch, thanks Heiko
- correct rk356x.dtsi ordering
- fix a dtbs-check callout

Peter Geis (8):
  dt-bindings: soc: rockchip: add rk3568-usb2phy-grf
  dt-bindings: phy: phy-rockchip-inno-usb2: add rk3568 documentation
  phy: phy-rockchip-inno-usb2: support #address_cells = 2
  phy: phy-rockchip-inno-usb2: support standalone phy nodes
  phy: phy-rockchip-inno-usb2: support muxed interrupts
  phy: phy-rockchip-inno-usb2: add rk3568 support
  arm64: dts: rockchip: add usb2 nodes to rk3568 device tree
  arm64: dts: rockchip: add Quartz64-A usb2 support

 .../bindings/phy/phy-rockchip-inno-usb2.yaml  |  31 ++-
 .../devicetree/bindings/soc/rockchip/grf.yaml |   1 +
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |  52 ++++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |  98 +++++++
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 259 ++++++++++++++----
 5 files changed, 383 insertions(+), 58 deletions(-)

-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:10 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:10 -0400
Subject: [PATCH v2 2/8] dt-bindings: phy: phy-rockchip-inno-usb2: add rk3568
 documentation
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-3-pgwipeout@gmail.com>

The rk3568 usb2phy node is a standalone node with a single muxed
interrupt.
Add documentation for it to phy-rockchip-inno-usb2.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 .../bindings/phy/phy-rockchip-inno-usb2.yaml  | 31 ++++++++++++++++---
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
index 5bebd86bf8b6..d2a749c3f9a3 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
@@ -18,6 +18,7 @@ properties:
       - rockchip,rk3328-usb2phy
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
+      - rockchip,rk3568-usb2phy
       - rockchip,rv1108-usb2phy
 
   reg:
@@ -50,6 +51,9 @@ properties:
     description:
       Phandle to the extcon device providing the cable state for the otg phy.
 
+  interrupts:
+    description: Muxed interrupt for both ports
+
   rockchip,usbgrf:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
@@ -78,8 +82,6 @@ properties:
 
     required:
       - "#phy-cells"
-      - interrupts
-      - interrupt-names
 
   otg-port:
     type: object
@@ -109,8 +111,6 @@ properties:
 
     required:
       - "#phy-cells"
-      - interrupts
-      - interrupt-names
 
 required:
   - compatible
@@ -120,6 +120,29 @@ required:
   - host-port
   - otg-port
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,rk3568-usb2phy
+      then:
+        properties:
+          interrupts:
+            maxItems: 1
+        required:
+          - interrupts
+      else:
+        properties:
+          host-port:
+            required:
+              - interrupts
+              - interrupt-names
+          otg-port:
+            required:
+              - interrupts
+              - interrupt-names
+
 additionalProperties: false
 
 examples:
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:11 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:11 -0400
Subject: [PATCH v2 3/8] phy: phy-rockchip-inno-usb2: support #address_cells = 2
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-4-pgwipeout@gmail.com>

New Rockchip devices have the usb phy nodes as standalone devices.
These nodes have register nodes with #address_cells = 2, but only use 32
bit addresses.

Adjust the driver to check if the returned address is "0", and adjust
the index in that case.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index beacac1dd253..5d2916143df7 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1098,12 +1098,21 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 		rphy->usbgrf = NULL;
 	}
 
-	if (of_property_read_u32(np, "reg", &reg)) {
+	if (of_property_read_u32_index(np, "reg", 0, &reg)) {
 		dev_err(dev, "the reg property is not assigned in %pOFn node\n",
 			np);
 		return -EINVAL;
 	}
 
+	/* support address_cells=2 */
+	if (reg == 0) {
+		if (of_property_read_u32_index(np, "reg", 1, &reg)) {
+			dev_err(dev, "the reg property is not assigned in %pOFn node\n",
+				np);
+			return -EINVAL;
+		}
+	}
+
 	rphy->dev = dev;
 	phy_cfgs = match->data;
 	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:12 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:12 -0400
Subject: [PATCH v2 4/8] phy: phy-rockchip-inno-usb2: support standalone phy
 nodes
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-5-pgwipeout@gmail.com>

New Rockchip devices have the usb2 phy devices as standalone nodes
instead of children of the grf node.
Allow the driver to find the grf node from a phandle.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 5d2916143df7..84a0c1d697da 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1081,12 +1081,19 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	if (!dev->parent || !dev->parent->of_node)
-		return -EINVAL;
+	if (!dev->parent || !dev->parent->of_node) {
+		rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
+		if (IS_ERR(rphy->grf)) {
+			dev_err(dev, "failed to locate usbgrf\n");
+			return PTR_ERR(rphy->grf);
+		}
+	}
 
-	rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
-	if (IS_ERR(rphy->grf))
-		return PTR_ERR(rphy->grf);
+	else {
+		rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
+			if (IS_ERR(rphy->grf))
+				return PTR_ERR(rphy->grf);
+	}
 
 	if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
 		rphy->usbgrf =
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:13 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:13 -0400
Subject: [PATCH v2 5/8] phy: phy-rockchip-inno-usb2: support muxed interrupts
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-6-pgwipeout@gmail.com>

The rk3568 usb2phy has a single muxed interrupt that handles all
interrupts.
Allow the driver to plug in only a single interrupt as necessary.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 168 +++++++++++++-----
 1 file changed, 119 insertions(+), 49 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 84a0c1d697da..fdeb2e7c937a 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -204,6 +204,7 @@ struct rockchip_usb2phy_port {
  * @dcd_retries: The retry count used to track Data contact
  *		 detection process.
  * @edev: extcon device for notification registration
+ * @irq: muxed interrupt for single irq configuration
  * @phy_cfg: phy register configuration, assigned by driver data.
  * @ports: phy port instance.
  */
@@ -218,6 +219,7 @@ struct rockchip_usb2phy {
 	enum power_supply_type	chg_type;
 	u8			dcd_retries;
 	struct extcon_dev	*edev;
+	int			irq;
 	const struct rockchip_usb2phy_cfg	*phy_cfg;
 	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
 };
@@ -934,6 +936,102 @@ static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
 		return IRQ_NONE;
 }
 
+static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
+{
+	struct rockchip_usb2phy *rphy = data;
+	struct rockchip_usb2phy_port *rport;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned int index;
+
+	for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
+		rport = &rphy->ports[index];
+		if (!rport->phy)
+			continue;
+
+		/* Handle linestate irq for both otg port and host port */
+		ret = rockchip_usb2phy_linestate_irq(irq, rport);
+	}
+
+	return ret;
+}
+
+static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
+					  struct rockchip_usb2phy_port *rport,
+					  struct device_node *child_np)
+{
+	int ret;
+
+	/*
+	 * If the usb2 phy used combined irq for otg and host port,
+	 * don't need to init otg and host port irq separately.
+	 */
+	if (rphy->irq > 0)
+		return 0;
+
+	switch (rport->port_id) {
+	case USB2PHY_PORT_HOST:
+		rport->ls_irq = of_irq_get_byname(child_np, "linestate");
+		if (rport->ls_irq < 0) {
+			dev_err(rphy->dev, "no linestate irq provided\n");
+			return rport->ls_irq;
+		}
+
+		ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
+						rockchip_usb2phy_linestate_irq,
+						IRQF_ONESHOT,
+						"rockchip_usb2phy", rport);
+		if (ret) {
+			dev_err(rphy->dev, "failed to request linestate irq handle\n");
+			return ret;
+		}
+		break;
+	case USB2PHY_PORT_OTG:
+		/*
+		 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
+		 * interrupts muxed together, so probe the otg-mux interrupt first,
+		 * if not found, then look for the regular interrupts one by one.
+		 */
+		rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
+		if (rport->otg_mux_irq > 0) {
+			ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
+							NULL,
+							rockchip_usb2phy_otg_mux_irq,
+							IRQF_ONESHOT,
+							"rockchip_usb2phy_otg",
+							rport);
+			if (ret) {
+				dev_err(rphy->dev,
+					"failed to request otg-mux irq handle\n");
+				return ret;
+			}
+		} else {
+			rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
+			if (rport->bvalid_irq < 0) {
+				dev_err(rphy->dev, "no vbus valid irq provided\n");
+				ret = rport->bvalid_irq;
+				return ret;
+			}
+
+			ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
+							NULL,
+							rockchip_usb2phy_bvalid_irq,
+							IRQF_ONESHOT,
+							"rockchip_usb2phy_bvalid",
+							rport);
+			if (ret) {
+				dev_err(rphy->dev,
+					"failed to request otg-bvalid irq handle\n");
+				return ret;
+			}
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
 					   struct rockchip_usb2phy_port *rport,
 					   struct device_node *child_np)
@@ -947,18 +1045,9 @@ static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
 	mutex_init(&rport->mutex);
 	INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
 
-	rport->ls_irq = of_irq_get_byname(child_np, "linestate");
-	if (rport->ls_irq < 0) {
-		dev_err(rphy->dev, "no linestate irq provided\n");
-		return rport->ls_irq;
-	}
-
-	ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
-					rockchip_usb2phy_linestate_irq,
-					IRQF_ONESHOT,
-					"rockchip_usb2phy", rport);
+	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
 	if (ret) {
-		dev_err(rphy->dev, "failed to request linestate irq handle\n");
+		dev_err(rphy->dev, "failed to setup host irq\n");
 		return ret;
 	}
 
@@ -1007,44 +1096,10 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
 	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
 	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
 
-	/*
-	 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
-	 * interrupts muxed together, so probe the otg-mux interrupt first,
-	 * if not found, then look for the regular interrupts one by one.
-	 */
-	rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
-	if (rport->otg_mux_irq > 0) {
-		ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
-						NULL,
-						rockchip_usb2phy_otg_mux_irq,
-						IRQF_ONESHOT,
-						"rockchip_usb2phy_otg",
-						rport);
-		if (ret) {
-			dev_err(rphy->dev,
-				"failed to request otg-mux irq handle\n");
-			goto out;
-		}
-	} else {
-		rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
-		if (rport->bvalid_irq < 0) {
-			dev_err(rphy->dev, "no vbus valid irq provided\n");
-			ret = rport->bvalid_irq;
-			goto out;
-		}
-
-		ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
-						NULL,
-						rockchip_usb2phy_bvalid_irq,
-						IRQF_ONESHOT,
-						"rockchip_usb2phy_bvalid",
-						rport);
-		if (ret) {
-			dev_err(rphy->dev,
-				"failed to request otg-bvalid irq handle\n");
-			goto out;
-		}
-	}
+	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
+	if (ret) {
+		dev_err(rphy->dev, "failed to init irq for host port\n");
+		goto out;
 
 	if (!IS_ERR(rphy->edev)) {
 		rport->event_nb.notifier_call = rockchip_otg_event;
@@ -1124,6 +1179,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	phy_cfgs = match->data;
 	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
 	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
+	rphy->irq = platform_get_irq(pdev, 0);
 	platform_set_drvdata(pdev, rphy);
 
 	ret = rockchip_usb2phy_extcon_register(rphy);
@@ -1201,6 +1257,20 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	}
 
 	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	if (rphy->irq > 0) {
+		ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
+						rockchip_usb2phy_irq,
+						IRQF_ONESHOT,
+						"rockchip_usb2phy",
+						rphy);
+		if (ret) {
+			dev_err(rphy->dev,
+				"failed to request usb2phy irq handle\n");
+			goto put_child;
+		}
+	}
+
 	return PTR_ERR_OR_ZERO(provider);
 
 put_child:
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:14 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:14 -0400
Subject: [PATCH v2 6/8] phy: phy-rockchip-inno-usb2: add rk3568 support
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-7-pgwipeout@gmail.com>

The rk3568 usb2phy is a standalone device with a single muxed interrupt.
Add support for the registers to the usb2phy driver.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 65 +++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index fdeb2e7c937a..74420c439a07 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1100,6 +1100,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
 	if (ret) {
 		dev_err(rphy->dev, "failed to init irq for host port\n");
 		goto out;
+	}
 
 	if (!IS_ERR(rphy->edev)) {
 		rport->event_nb.notifier_call = rockchip_otg_event;
@@ -1509,6 +1510,69 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
+	{
+		.reg = 0xfe8a0000,
+		.num_ports	= 2,
+		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x0080, 2, 2, 0, 1 },
+				.bvalid_det_st	= { 0x0084, 2, 2, 0, 1 },
+				.bvalid_det_clr = { 0x0088, 2, 2, 0, 1 },
+				.utmi_avalid	= { 0x00c0, 10, 10, 0, 1 },
+				.utmi_bvalid	= { 0x00c0, 9, 9, 0, 1 },
+			},
+			[USB2PHY_PORT_HOST] = {
+				/* Select suspend control from controller */
+				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d2 },
+				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
+				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
+				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
+				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
+			}
+		},
+		.chg_det = {
+			.opmode		= { 0x0000, 3, 0, 5, 1 },
+			.cp_det		= { 0x00c0, 24, 24, 0, 1 },
+			.dcp_det	= { 0x00c0, 23, 23, 0, 1 },
+			.dp_det		= { 0x00c0, 25, 25, 0, 1 },
+			.idm_sink_en	= { 0x0008, 8, 8, 0, 1 },
+			.idp_sink_en	= { 0x0008, 7, 7, 0, 1 },
+			.idp_src_en	= { 0x0008, 9, 9, 0, 1 },
+			.rdm_pdwn_en	= { 0x0008, 10, 10, 0, 1 },
+			.vdm_src_en	= { 0x0008, 12, 12, 0, 1 },
+			.vdp_src_en	= { 0x0008, 11, 11, 0, 1 },
+		},
+	},
+	{
+		.reg = 0xfe8b0000,
+		.num_ports	= 2,
+		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 7, 7, 0, 1 }
+			},
+			[USB2PHY_PORT_HOST] = {
+				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
+				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
+				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
+				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
+			}
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
 	{
 		.reg = 0x100,
@@ -1558,6 +1622,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
+	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
 };
-- 
2.25.1



From daniel.lezcano at linaro.org  Fri Aug 13 09:03:21 2021
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 13 Aug 2021 18:03:21 +0200
Subject: [PATCH v4 4/9] clocksource/drivers/pistachio: Make it selectable
 for MIPS
In-Reply-To: <20210723022543.4095-5-jiaxun.yang@flygoat.com>
References: <20210723022543.4095-1-jiaxun.yang@flygoat.com>
 <20210723022543.4095-5-jiaxun.yang@flygoat.com>
Message-ID: <9db45153-d4d6-aab9-8cf8-12fdb76be249@linaro.org>

On 23/07/2021 04:25, Jiaxun Yang wrote:
> So it will be avilable for generic MIPS kernel.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang at flygoat.com>
> ---
>  drivers/clocksource/Kconfig | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 39aa21d01e05..58ad7af8c673 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -234,8 +234,9 @@ config CLKSRC_LPC32XX
>  	  Support for the LPC32XX clocksource.
>  
>  config CLKSRC_PISTACHIO
> -	bool "Clocksource for Pistachio SoC" if COMPILE_TEST
> +	bool "Clocksource for Pistachio SoC"
>  	depends on HAS_IOMEM
> +	depends on MIPS || COMPILE_TEST

The dependency on the platform is only required if the COMPILE_TEST
fails on other platforms.

The selection is done from arch/mips/Kconfig directly otherwise.

>  	select TIMER_OF
>  	help
>  	  Enables the clocksource for the Pistachio SoC.
> 


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From robh at kernel.org  Fri Aug 13 10:22:34 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:22:34 -0500
Subject: [PATCH v2 3/6] dt-bindings: usb: dwc3: add reference clock period
In-Reply-To: <22f62c59471e128b681a731997a9416ab2e91acf.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <22f62c59471e128b681a731997a9416ab2e91acf.1628085910.git.baruch@tkos.co.il>
Message-ID: <YRaqWtSK7zNhKxSN@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 05:05:07PM +0300, Baruch Siach wrote:
> Document the snps,ref-clock-period property that describes reference
> clock period when it deviates from the default set value.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> index 41416fbd92aa..c8027d2852cd 100644
> --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> @@ -252,6 +252,15 @@ properties:
>      minimum: 0
>      maximum: 0x3f
>  
> +  snps,ref-clock-period:
> +    description:
> +      Value for REFCLKPER field of GUCTL register for post-silicon reference

Why is post-silicon relevant here? Everything upstream should be for 
post-silicon. I've seen and done the hacks to make pre-silicon testing 
work and we don't need those upstream.

> +      clock period in nanoseconds, when the hardware set default does not match

If you have units, then use property unit suffix in the name.

> +      the actual clock.
> +    $ref: /schemas/types.yaml#/definitions/uint32

And then you can drop the type.

However, if the h/w block gets a ref clock why isn't it described in 
'clocks' and then you can just read why the frequency is and calculate 
the period.


From robh at kernel.org  Fri Aug 13 10:27:54 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:27:54 -0500
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87v94lxpb0.fsf@tarshish>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
Message-ID: <YRarmizUtzIunV1P@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 05:22:27PM +0300, Baruch Siach wrote:
> Hi Felipe,
> 
> On Wed, Aug 04 2021, Felipe Balbi wrote:
> > Baruch Siach <baruch at tkos.co.il> writes:
> >> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> >>  				    &dwc->hsphy_interface);
> >>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
> >>  				 &dwc->fladj);
> >> +	device_property_read_u32(dev, "snps,ref-clock-period",
> >> +				 &dwc->ref_clk_per);
> >
> > I wonder if it would make more sense to pass an actual clock reference
> > here. If valid, then reconfigure the period to the value returned by
> > clk_get_rate(). It would avoid yet another DT binding. If we make the
> > clock optional, then we won't affect any other platforms. The clock
> > itself could be a regular fixed clock node.
> 
> Thinh Nguyen asked to add a dedicated DT property. He explained that
> clk_get_rate() does not work for PCI hosted dwc3. This is the most
> complete summary of the discussion:
> 
>   https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32 at synopsys.com

PCI devices can have DT nodes with clock properties too. Or use the 
VID/PID to infer the frequency. Or use 'clock-frequency' property.

It boils down to we have lots of standard properties for clocks and 
clock configuration, so custom properties are a NAK.

Rob


From robh at kernel.org  Fri Aug 13 10:28:56 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:28:56 -0500
Subject: [PATCH v2 5/6] dt-bindings: usb: qcom,dwc3: add binding for
 IPQ6018
In-Reply-To: <24ce7c1258790b35a08e14a1e79a9447c3fed354.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <24ce7c1258790b35a08e14a1e79a9447c3fed354.1628085910.git.baruch@tkos.co.il>
Message-ID: <YRar2LbE52HGr8J3@robh.at.kernel.org>

On Wed, 04 Aug 2021 17:05:09 +0300, Baruch Siach wrote:
> Add compatible string for Qualcomm IPQ6018 SoC.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Fri Aug 13 11:38:33 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:38:33 -0500
Subject: [PATCH v1 1/2] dt-bindings: phy: qcom,qmp: Add SM6115 UFS PHY
 bindings
In-Reply-To: <20210805091727.942471-2-iskren.chernev@gmail.com>
References: <20210805091727.942471-1-iskren.chernev@gmail.com>
 <20210805091727.942471-2-iskren.chernev@gmail.com>
Message-ID: <YRa8KfZ6kbMlp3ff@robh.at.kernel.org>

On Thu, 05 Aug 2021 12:17:26 +0300, Iskren Chernev wrote:
> Add the compatible strings for the UFS PHY found on SM4250/6115 SoC.
> 
> Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
> ---
>  Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From linux.amoon at gmail.com  Fri Aug 13 12:35:40 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Sat, 14 Aug 2021 01:05:40 +0530
Subject: [PATCHv2 1/4] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CANAwSgS2vi7hZqX0LWxNTvk-3aN=n1fEErj4Zt0_4CCpZGyRkg@mail.gmail.com>
References: <20210716103651.1455-1-linux.amoon@gmail.com>
 <20210716103651.1455-2-linux.amoon@gmail.com>
 <CAFBinCDeqauw_V-Vn9cat9HaCXj6HEMz6G+G+VbqCNtGEFGYzg@mail.gmail.com>
 <CANAwSgQ5PDGUWMH-jxnz5wwutUVniTn7RAe=4J=8-jbmqxYRRg@mail.gmail.com>
 <CAFBinCBhg+dije+3DvV_V_kqHv9q+r4EPxXCYFti6KuA4mK7KQ@mail.gmail.com>
 <CANAwSgT9-5zGr67aGzBmW6WDBfeiAvjv_zv2UbRC+YbgAGg==A@mail.gmail.com>
 <CAFBinCCGA0b=LVjbQood+iN+DHLodY0RJ-GrSOcgdzrDFJ25pQ@mail.gmail.com>
 <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
 <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>
 <CANAwSgS2vi7hZqX0LWxNTvk-3aN=n1fEErj4Zt0_4CCpZGyRkg@mail.gmail.com>
Message-ID: <CANAwSgTw-aY16NOcQhgPcN+Tkz-OXdioDEAM2q0OPhvbf2TwaQ@mail.gmail.com>

Hi Martin,

On Thu, 5 Aug 2021 at 23:48, Anand Moon <linux.amoon at gmail.com> wrote:
>
> Hi Martin,
>
> On Thu, 5 Aug 2021 at 03:28, Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> >
> > On Sun, Jul 18, 2021 at 9:09 PM Martin Blumenstingl
> > <martin.blumenstingl at googlemail.com> wrote:
> > >
> > > Hi Anand,
> > >
> > > On Sun, Jul 18, 2021 at 4:01 PM Martin Blumenstingl
> > > <martin.blumenstingl at googlemail.com> wrote:
> > > [...]
> > > > > From the schematics [1]
> > > > > https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20160226.pdf
> > > > >
> > > > > You could find references to PWREN  <--- GPIOAO.BIT5
> > > > > The second reference is USB HOST Power Switch
> > > > > The third reference is USB HOST POWER.
> > > > >
> > > > > Hope I am clean in my thought process now.
> > > > Can you please point out the page numbers for me?
> > > >
> > > > What I am seeing on page 1 is:
> > > > GPIOAO_5 (called GPIOAO.BIT5) is connected as an INPUT to the USB_OTG
> > > > PWREN signal (that's the green box with the label "USB_OTG.SchDoc"
> > > > above it).
> > > I unfortunately missed your question on IRC on this topic:
> > > <armoon> xdarklight: just want to understand the confusion on PWREN,
> > > either is INPUT / OTPUT to usb hub am I correct
> > > My understanding of the INPUT/OUTPUT direction in the Odroid-C1
> > > schematics (which you linked) above is that the arrow direction shows
> > > whether it's an input or output.
> > > For example (all on page one):
> > > - HDMI_HPD is an input to the Meson8b SoC, arrow direction is: HDMI => S805
> > > - IR_IN is an input to the Meson8b SoC, arrow direction is: S805 <=
> > > GPIOAO.BIT7 IR_IN
> > > - PWM is an output, arrow direction is: S805 => PWM.C VCCK_PWM
> > > - 3.3V/1.8V switch for the SD card is an output, arrow direction is:
> > > S805 => GPIOAO.BIT3 TF_3V3N_1V8_EN
> > >
> > > That tells me: the arrow direction shows which connections are inputs
> > > or outputs.
> > > Some pins can be input and output at the same time (HDMI_CEC). But
> > > let's keep it simple for now any only look at inputs/output.
> > >
> > > Based on this information I am looking at the arrow direction for
> > > USB_OTG: GPIOAO.BIT5 PWREN <= S805
> > > So this confirms that GPIOAO_5 is an output to the SoC.
> > > Please note though that this part is not linked with any USB host
> > > connector, it's only linked to the USB OTG path.
> > >
> > > For the next part the S805 SoC is not involved:
> > > USB1 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > > USB2 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > > This tells me that the PWREN signal for the two USB_HOST_PWR_SW (USB
> > > host power switches / current limiters) is driven by the GL852G USB
> > > hub.
> > Hardkernel team responded on the Odroid forums to the request from Anand:
> > "Power-Enable signal to the USB load switch ICs is connected to the
> > USB hub controller.
> > It is not connected the CPU GPIO."
> >
> > The regulator from Anand's patch is therefore connected to the micro USB port.
> > This means that the patch needs updating in case Anand wants to have
> > it included.
> >
>
> Yes, I will send a corrected version of the patches soon.

I have a small query regarding GPIO polarity

As per the datasheet of *MP62551DGT-LF-Z*
[0] https://www.mouser.in/datasheet/2/277/MP62550-1384050.pdf

USB power enables EN signal need to be Active High.

PIN Fucntion > Enable input. Active Low: (MP62550), Active High: (MP62551).

So the correct option in dts
+               /*
+                * signal name from schematics: PWREN - GPIOAO.BIT5
+                */
+               gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;

which gives me the below output.

$  sudo cat /sys/kernel/debug/gpio | grep USB
 gpio-1953 (USB_HUB_RST_N       |usb-hub-reset       ) out hi
 gpio-1954 (USB_OTG_PWREN       |regulator-usb-pwr-en) out hi

Please clear this small query so that I can send the update patch.

Thanks
-Anand

>
> >
> > Best regards,
> > Martin
> >
> >
> > [0] https://forum.odroid.com/viewtopic.php?p=332217#p332217
>
> Thanks
> -Anand


From Thinh.Nguyen at synopsys.com  Fri Aug 13 12:52:03 2021
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Fri, 13 Aug 2021 19:52:03 +0000
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <YRarmizUtzIunV1P@robh.at.kernel.org>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
 <YRarmizUtzIunV1P@robh.at.kernel.org>
Message-ID: <53784e58-6da4-ad61-6b9e-46697fb3d695@synopsys.com>

Rob Herring wrote:
> On Wed, Aug 04, 2021 at 05:22:27PM +0300, Baruch Siach wrote:
>> Hi Felipe,
>>
>> On Wed, Aug 04 2021, Felipe Balbi wrote:
>>> Baruch Siach <baruch at tkos.co.il> writes:
>>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>>>  				    &dwc->hsphy_interface);
>>>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>>>  				 &dwc->fladj);
>>>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>>>> +				 &dwc->ref_clk_per);
>>>
>>> I wonder if it would make more sense to pass an actual clock reference
>>> here. If valid, then reconfigure the period to the value returned by
>>> clk_get_rate(). It would avoid yet another DT binding. If we make the
>>> clock optional, then we won't affect any other platforms. The clock
>>> itself could be a regular fixed clock node.
>>
>> Thinh Nguyen asked to add a dedicated DT property. He explained that
>> clk_get_rate() does not work for PCI hosted dwc3. This is the most
>> complete summary of the discussion:
>>
>>   https://urldefense.com/v3/__https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32 at synopsys.com__;!!A4F2R9G_pg!Nh6rqp_aOd8XIvqELvDRQe5ooZf13UZKwmn9lWcRgdbyMKpTMzL8HasrB1X2Ojvumo8g$ 
> 
> PCI devices can have DT nodes with clock properties too. Or use the 
> VID/PID to infer the frequency. Or use 'clock-frequency' property.
> 
> It boils down to we have lots of standard properties for clocks and 
> clock configuration, so custom properties are a NAK.
> 

Do we have DT node for the PCI device before discovering the device from
PCI bus enumeration? I don't think we can find the clock properties from
its configuration space. For our HAPS devices, we can't use VID/PID to
infer the frequency since our phy and ref clock may change.

Does "clock-frequency" mean ref clock? If so, let's use that?

Thanks,
Thinh

From iskren.chernev at gmail.com  Fri Aug 13 13:11:49 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Fri, 13 Aug 2021 23:11:49 +0300
Subject: [PATCH v2 0/2] Add UFS PHY support for SM6115/4250
Message-ID: <20210813201151.974512-1-iskren.chernev@gmail.com>

The UFS PHY found on SM6115/4250 is named v3-660, found on cheaper qcom devices
(possibly starting with sdm660), but up until recently wasn't used much due to
prevalence of sdhc port for internal storage/sdcard.

The name is a bit misleading, because most of the registers found on v3-660
don't share much in common with v3.

The register values/sequences are taken from OnePlus repo [1].

[1] https://github.com/OnePlusOSS/android_kernel_oneplus_sm4250

v1: https://lkml.org/lkml/2021/8/5/235

Changes from v1:
- Suggested by Vinod
  - removed v3-660 constants for regs with same name and value as v3 regs

Iskren Chernev (2):
  dt-bindings: phy: qcom,qmp: Add SM6115 UFS PHY bindings
  phy: qcom-qmp: Add support for SM6115 UFS phy

 .../devicetree/bindings/phy/qcom,qmp-phy.yaml |   1 +
 drivers/phy/qualcomm/phy-qcom-qmp.c           | 124 ++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h           | 134 ++++++++++++++++++
 3 files changed, 259 insertions(+)


base-commit: 8d4b477da1a807199ca60e0829357ce7aa6758d5
-- 
2.32.0



From iskren.chernev at gmail.com  Fri Aug 13 13:11:50 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Fri, 13 Aug 2021 23:11:50 +0300
Subject: [PATCH v2 1/2] dt-bindings: phy: qcom,
 qmp: Add SM6115 UFS PHY bindings
In-Reply-To: <20210813201151.974512-1-iskren.chernev@gmail.com>
References: <20210813201151.974512-1-iskren.chernev@gmail.com>
Message-ID: <20210813201151.974512-2-iskren.chernev@gmail.com>

Add the compatible strings for the UFS PHY found on SM4250/6115 SoC.

Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index 242560ff52a4..7c3c8710ab47 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -35,6 +35,7 @@ properties:
       - qcom,sdm845-qmp-ufs-phy
       - qcom,sdm845-qmp-usb3-phy
       - qcom,sdm845-qmp-usb3-uni-phy
+      - qcom,sm6115-qmp-ufs-phy
       - qcom,sm8150-qmp-ufs-phy
       - qcom,sm8150-qmp-usb3-phy
       - qcom,sm8150-qmp-usb3-uni-phy
-- 
2.32.0



From iskren.chernev at gmail.com  Fri Aug 13 13:11:51 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Fri, 13 Aug 2021 23:11:51 +0300
Subject: [PATCH v2 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <20210813201151.974512-1-iskren.chernev@gmail.com>
References: <20210813201151.974512-1-iskren.chernev@gmail.com>
Message-ID: <20210813201151.974512-3-iskren.chernev@gmail.com>

Add the tables and constants for init sequences for UFS QMP phy found in
SM4250/6115 SoC. The phy is a variation of the v3 phy found on sdm845
called v3-660 (possibly first occurrence in the sdm660).

There are a few similar registers with the v3 phy (notably the first
SERDES ones), the rest are different.

Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 124 +++++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h | 134 ++++++++++++++++++++++++++++
 2 files changed, 258 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2195f8ac393b..a7f6c281f035 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -234,6 +234,11 @@ static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_READY_STATUS]		= 0x160,
 };
 
+static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_START_CTRL]		= 0x00,
+	[QPHY_PCS_READY_STATUS]		= 0x168,
+};
+
 static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_SW_RESET]			= 0x00,
 	[QPHY_START_CTRL]		= 0x44,
@@ -1329,6 +1334,97 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
 };
 
+static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CMN_CONFIG, 0x0e),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_SYSCLK_EN_SEL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_HSCLK_SEL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CORECLK_DIV, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CORECLK_DIV_MODE1, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP_EN, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_CTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_RESETSM_CNTRL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP_CFG, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_TIMER1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_TIMER2, 0x3f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_MAP, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_SVS_MODE_CLK_SEL, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE1_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE2_MODE0, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP1_MODE0, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP2_MODE0, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DEC_START_MODE1, 0x98),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_CP_CTRL_MODE1, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_PLL_CCTRL_MODE1, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE1_MODE1, 0xd6),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE2_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP1_MODE1, 0x32),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP2_MODE1, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_LOCK_CMP3_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_BG_TRIM, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_INITVAL1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_INITVAL2, 0x00),
+
+	/* Rate B */
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_TX_HIGHZ_TRANSCEIVER_BIAS_DRVR_EN, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_SIGDET_LVL, 0x24),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_SIGDET_CNTRL, 0x0F),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_INTERFACE_MODE, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_TERM_BW, 0x5B),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN1_LSB, 0xFF),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN1_MSB, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN2_LSB, 0xFF),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQ_GAIN2_MSB, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V3_660_RX_UCDR_SO_SATURATION_ENABLE, 0x5B),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_PWM_GEAR_BAND, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_SIGDET_CTRL2, 0x6d),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_SYM_RESYNC_CTRL, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_V3_660_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
+};
+
 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
@@ -3396,6 +3492,31 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
 	.no_pcs_sw_reset	= true,
 };
 
+static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
+	.type			= PHY_TYPE_UFS,
+	.nlanes			= 1,
+
+	.serdes_tbl		= sm6115_ufsphy_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
+	.tx_tbl			= sm6115_ufsphy_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
+	.rx_tbl			= sm6115_ufsphy_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
+	.pcs_tbl		= sm6115_ufsphy_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
+	.clk_list		= sdm845_ufs_phy_clk_l,
+	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= sm6115_ufsphy_regs_layout,
+
+	.start_ctrl		= SERDES_START,
+	.pwrdn_ctrl		= SW_PWRDN,
+
+	.is_dual_lane_phy	= false,
+	.no_pcs_sw_reset	= true,
+};
+
 static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
 	.type			= PHY_TYPE_PCIE,
 	.nlanes			= 1,
@@ -5395,6 +5516,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
 	}, {
 		.compatible = "qcom,msm8998-qmp-usb3-phy",
 		.data = &msm8998_usb3phy_cfg,
+	}, {
+		.compatible = "qcom,sm6115-qmp-ufs-phy",
+		.data = &sm6115_ufsphy_cfg,
 	}, {
 		.compatible = "qcom,sm8150-qmp-ufs-phy",
 		.data = &sm8150_ufsphy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index 6592b58b13f6..fde1bff16e27 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -280,6 +280,8 @@
 #define QSERDES_V3_COM_SSC_PER2				0x020
 #define QSERDES_V3_COM_SSC_STEP_SIZE1			0x024
 #define QSERDES_V3_COM_SSC_STEP_SIZE2			0x028
+#define QSERDES_V3_COM_POST_DIV				0x02c
+#define QSERDES_V3_COM_POST_DIV_MUX			0x030
 #define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN		0x034
 # define QSERDES_V3_COM_BIAS_EN				0x0001
 # define QSERDES_V3_COM_BIAS_EN_MUX			0x0002
@@ -291,6 +293,7 @@
 #define QSERDES_V3_COM_CLK_ENABLE1			0x038
 #define QSERDES_V3_COM_SYS_CLK_CTRL			0x03c
 #define QSERDES_V3_COM_SYSCLK_BUF_ENABLE		0x040
+#define QSERDES_V3_COM_PLL_EN				0x044
 #define QSERDES_V3_COM_PLL_IVCO				0x048
 #define QSERDES_V3_COM_LOCK_CMP1_MODE0			0x098
 #define QSERDES_V3_COM_LOCK_CMP2_MODE0			0x09c
@@ -348,6 +351,100 @@
 #define QSERDES_V3_COM_DEBUG_BUS_SEL			0x178
 #define QSERDES_V3_COM_CMN_MODE				0x184
 
+/* Only for QMP V3 660 PHY - QSERDES COM registers*/
+#define QSERDES_V3_660_COM_LOCK_CMP1_MODE0		0x04c
+#define QSERDES_V3_660_COM_LOCK_CMP2_MODE0		0x050
+#define QSERDES_V3_660_COM_LOCK_CMP3_MODE0		0x054
+#define QSERDES_V3_660_COM_LOCK_CMP1_MODE1		0x058
+#define QSERDES_V3_660_COM_LOCK_CMP2_MODE1		0x05c
+#define QSERDES_V3_660_COM_LOCK_CMP3_MODE1		0x060
+#define QSERDES_V3_660_COM_CMD_RSVD0			0x064
+#define QSERDES_V3_660_COM_EP_CLOCK_DETECT_CTRL		0x068
+#define QSERDES_V3_660_COM_SYSCLK_DET_COMP_STATUS	0x06c
+#define QSERDES_V3_660_COM_BG_TRIM			0x070
+#define QSERDES_V3_660_COM_CLK_EP_DIV			0x074
+#define QSERDES_V3_660_COM_CP_CTRL_MODE0		0x078
+#define QSERDES_V3_660_COM_CP_CTRL_MODE1		0x07c
+#define QSERDES_V3_660_COM_CMN_RSVD1			0x080
+#define QSERDES_V3_660_COM_PLL_RCTRL_MODE0		0x084
+#define QSERDES_V3_660_COM_PLL_RCTRL_MODE1		0x088
+#define QSERDES_V3_660_COM_CMN_RSVD2			0x08c
+#define QSERDES_V3_660_COM_PLL_CCTRL_MODE0		0x090
+#define QSERDES_V3_660_COM_PLL_CCTRL_MODE1		0x094
+#define QSERDES_V3_660_COM_CMN_RSVD3			0x098
+#define QSERDES_V3_660_COM_PLL_CNTRL			0x09c
+#define QSERDES_V3_660_COM_PHASE_SEL_CTRL		0x0a0
+#define QSERDES_V3_660_COM_PHASE_SEL_DC			0x0a4
+#define QSERDES_V3_660_COM_BIAS_EN_CTRL_BY_PSM		0x0a8
+#define QSERDES_V3_660_COM_SYSCLK_EN_SEL		0x0ac
+#define QSERDES_V3_660_COM_CML_SYSCLK_SEL		0x0b0
+#define QSERDES_V3_660_COM_RESETSM_CNTRL		0x0b4
+#define QSERDES_V3_660_COM_RESETSM_CNTRL2		0x0b8
+#define QSERDES_V3_660_COM_RESTRIM_CTRL			0x0bc
+#define QSERDES_V3_660_COM_RESTRIM_CTRL2		0x0c0
+#define QSERDES_V3_660_COM_LOCK_CMP_EN			0x0c8
+#define QSERDES_V3_660_COM_LOCK_CMP_CFG			0x0cc
+#define QSERDES_V3_660_COM_DEC_START_MODE0		0x0d0
+#define QSERDES_V3_660_COM_DEC_START_MODE1		0x0d4
+#define QSERDES_V3_660_COM_VCOCAL_DEADMAN_CTRL		0x0d8
+#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0	0x0dc
+#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0	0x0e0
+#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0	0x0e4
+#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1	0x0e8
+#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1	0x0ec
+#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1	0x0f0
+#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL1		0x0f4
+#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL2		0x0f8
+#define QSERDES_V3_660_COM_CMN_RSVD4			0x0fc
+#define QSERDES_V3_660_COM_INTEGLOOP_INITVAL		0x100
+#define QSERDES_V3_660_COM_INTEGLOOP_EN			0x104
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0	0x108
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0	0x10c
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1	0x110
+#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1	0x114
+#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL1		0x118
+#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL2		0x11c
+#define QSERDES_V3_660_COM_RES_TRIM_CONTROL2		0x120
+#define QSERDES_V3_660_COM_VCO_TUNE_CTRL		0x124
+#define QSERDES_V3_660_COM_VCO_TUNE_MAP			0x128
+#define QSERDES_V3_660_COM_VCO_TUNE1_MODE0		0x12c
+#define QSERDES_V3_660_COM_VCO_TUNE2_MODE0		0x130
+#define QSERDES_V3_660_COM_VCO_TUNE1_MODE1		0x134
+#define QSERDES_V3_660_COM_VCO_TUNE2_MODE1		0x138
+#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL1		0x13c
+#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL2		0x140
+#define QSERDES_V3_660_COM_VCO_TUNE_TIMER1		0x144
+#define QSERDES_V3_660_COM_VCO_TUNE_TIMER2		0x148
+#define QSERDES_V3_660_COM_SAR				0x14c
+#define QSERDES_V3_660_COM_SAR_CLK			0x150
+#define QSERDES_V3_660_COM_SAR_CODE_OUT_STATUS		0x154
+#define QSERDES_V3_660_COM_SAR_CODE_READY_STATUS	0x158
+#define QSERDES_V3_660_COM_CMN_STATUS			0x15c
+#define QSERDES_V3_660_COM_RESET_SM_STATUS		0x160
+#define QSERDES_V3_660_COM_RESTRIM_CODE_STATUS		0x164
+#define QSERDES_V3_660_COM_PLLCAL_CODE1_STATUS		0x168
+#define QSERDES_V3_660_COM_PLLCAL_CODE2_STATUS		0x16c
+#define QSERDES_V3_660_COM_BG_CTRL			0x170
+#define QSERDES_V3_660_COM_CLK_SELECT			0x174
+#define QSERDES_V3_660_COM_HSCLK_SEL			0x178
+#define QSERDES_V3_660_COM_INTEGLOOP_BINCODE_STATUS	0x17c
+#define QSERDES_V3_660_COM_PLL_ANALOG			0x180
+#define QSERDES_V3_660_COM_CORECLK_DIV			0x184
+#define QSERDES_V3_660_COM_SW_RESET			0x188
+#define QSERDES_V3_660_COM_CORE_CLK_EN			0x18c
+#define QSERDES_V3_660_COM_C_READY_STATUS		0x190
+#define QSERDES_V3_660_COM_CMN_CONFIG			0x194
+#define QSERDES_V3_660_COM_CMN_RATE_OVERRIDE		0x198
+#define QSERDES_V3_660_COM_SVS_MODE_CLK_SEL		0x19c
+#define QSERDES_V3_660_COM_DEBUG_BUS0			0x1a0
+#define QSERDES_V3_660_COM_DEBUG_BUS1			0x1a4
+#define QSERDES_V3_660_COM_DEBUG_BUS2			0x1a8
+#define QSERDES_V3_660_COM_DEBUG_BUS3			0x1ac
+#define QSERDES_V3_660_COM_DEBUG_BUS_SEL		0x1b0
+#define QSERDES_V3_660_COM_CMN_MISC1			0x1b4
+#define QSERDES_V3_660_COM_CORECLK_DIV_MODE1		0x1bc
+#define QSERDES_V3_660_COM_CMN_RSVD5			0x1c0
+
 /* Only for QMP V3 PHY - TX registers */
 #define QSERDES_V3_TX_BIST_MODE_LANENO			0x000
 #define QSERDES_V3_TX_CLKBUF_ENABLE			0x008
@@ -380,6 +477,10 @@
 #define QSERDES_V3_TX_TX_INTERFACE_MODE			0x0c4
 #define QSERDES_V3_TX_VMODE_CTRL1			0x0f0
 
+/* Only for QMP V3 660 PHY - TX registers */
+#define QSERDES_V3_660_TX_HIGHZ_TRANSCEIVER_BIAS_DRVR_EN	0x068
+#define QSERDES_V3_660_TX_LANE_MODE				0x094
+
 /* Only for QMP V3 PHY - RX registers */
 #define QSERDES_V3_RX_UCDR_FO_GAIN			0x008
 #define QSERDES_V3_RX_UCDR_SO_GAIN_HALF			0x00c
@@ -411,6 +512,24 @@
 #define QSERDES_V3_RX_RX_MODE_00			0x164
 #define QSERDES_V3_RX_RX_MODE_01			0x168
 
+/* Only for QMP V3 660 PHY - RX registers */
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_HALF		0x030
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_QUARTER	0x034
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_EIGHTH	0x038
+#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN		0x03c
+#define QSERDES_V3_660_RX_UCDR_FASTLOCK_FO_GAIN		0x040
+#define QSERDES_V3_660_RX_UCDR_SO_SATURATION_ENABLE	0x048
+#define QSERDES_V3_660_RX_RX_TERM_BW			0x090
+#define QSERDES_V3_660_RX_RX_EQ_GAIN1_LSB		0x0c4
+#define QSERDES_V3_660_RX_RX_EQ_GAIN1_MSB		0x0c8
+#define QSERDES_V3_660_RX_RX_EQ_GAIN2_LSB		0x0cc
+#define QSERDES_V3_660_RX_RX_EQ_GAIN2_MSB		0x0d0
+#define QSERDES_V3_660_RX_RX_EQU_ADAPTOR_CNTRL2		0x0d8
+#define QSERDES_V3_660_RX_SIGDET_CNTRL			0x114
+#define QSERDES_V3_660_RX_SIGDET_LVL			0x118
+#define QSERDES_V3_660_RX_SIGDET_DEGLITCH_CNTRL		0x11c
+#define QSERDES_V3_660_RX_RX_INTERFACE_MODE		0x12c
+
 /* Only for QMP V3 PHY - PCS registers */
 #define QPHY_V3_PCS_POWER_DOWN_CONTROL			0x004
 #define QPHY_V3_PCS_TXMGN_V0				0x00c
@@ -473,6 +592,21 @@
 #define QPHY_V3_PCS_REFGEN_REQ_CONFIG1			0x20c
 #define QPHY_V3_PCS_REFGEN_REQ_CONFIG2			0x210
 
+/* Only for QMP V3 660 PHY - PCS registers */
+#define QPHY_V3_660_PCS_PHY_START			0x000
+#define QPHY_V3_660_PCS_POWER_DOWN_CONTROL		0x004
+#define QPHY_V3_660_PCS_TX_LARGE_AMP_DRV_LVL		0x034
+#define QPHY_V3_660_PCS_TX_LARGE_AMP_POST_EMP_LVL	0x038
+#define QPHY_V3_660_PCS_TX_SMALL_AMP_DRV_LVL		0x03c
+#define QPHY_V3_660_PCS_TX_SMALL_AMP_POST_EMP_LVL	0x040
+#define QPHY_V3_660_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP	0x0cc
+#define QPHY_V3_660_PCS_LINECFG_DISABLE			0x138
+#define QPHY_V3_660_PCS_RX_SYM_RESYNC_CTRL		0x13c
+#define QPHY_V3_660_PCS_RX_MIN_HIBERN8_TIME		0x140
+#define QPHY_V3_660_PCS_RX_SIGDET_CTRL2			0x148
+#define QPHY_V3_660_PCS_RX_PWM_GEAR_BAND		0x154
+#define QPHY_V3_660_PCS_PCS_READY_STATUS		0x168
+
 /* Only for QMP V3 PHY - PCS_MISC registers */
 #define QPHY_V3_PCS_MISC_CLAMP_ENABLE			0x0c
 #define QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2		0x2c
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:34 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:34 +0530
Subject: [PATCHv3 0/6] Meson-8b and Meson-gxbb Fix some missing code
Message-ID: <20210817041548.1276-1-linux.amoon@gmail.com>

On Odroid C1+ and Odroid C2 USB feature is broken

It's being observed the after initiation of USB phy
the USB port goes in to suspend state, If we pass usbcore.autosuspend=-1
via command line USB hotplug seen to be working.

Another issue I observed is increase of USB interrupts event
even if there is not much activity on USB ports.

$ cat /proc/interrupts | grep usb
 35:   26462800          0          0          0     GIC-0  63 Level
			c90c0000.usb, dwc2_hsotg:usb1
8
Changes added power node to usb phy and small code cleanup
in usb phy.


Previous version RFC.
[0] https://patchwork.kernel.org/project/linux-amlogic/cover/20210617194154.2397-1-linux.amoon at gmail.com/
Dopped the reorder of code changes as of now.

V1 > changes Fixed the GPIO input signal on Odroid C1+/C2
     New patch added to fix Odroid C2.

[1] https://lore.kernel.org/linux-devicetree/20210716103651.1455-1-linux.amoon at gmail.com/

V2 > changes Fixed the GPIO polarity for Odroid C1
     fix the power source from phy-supply to vbus-supply 
     added new patches to fix resolve some issues.

Thanks
-Anand

Anand Moon (6):
  ARM: dts: meson8b: odroidc1: Add usb phy power node
  ARM: dts: meson8b: odroidc1: Set usb power source to always on
  arm64: dts: amlogic: odroidc2: Fix the chip enable signal for usb
    power
  arm64: dts: amlogic: odroidc2: use vbus-supply for power source for
    usb nodes
  phy: amlogic: meson8b-usb2: Power off the PHY by putting it into reset
    mode
  phy: amlogic: meson8b-usb2: don't log an error on -EPROBE_DEFER

 arch/arm/boot/dts/meson8b-odroidc1.dts        | 21 ++++++++++++++++++-
 .../boot/dts/amlogic/meson-gxbb-odroidc2.dts  | 10 ++++-----
 drivers/phy/amlogic/phy-meson8b-usb2.c        |  8 +++++--
 3 files changed, 30 insertions(+), 9 deletions(-)

-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:35 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:35 +0530
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-2-linux.amoon@gmail.com>

Add missing usb phy power node for usb node fix below warning.
P5V0 regulator supply input voltage range to USB host controller.
As described in the C1+ schematics, GPIO GPIOAO_5 is used to
enable input power to USB ports, set it to Active Low.

[    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
[    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
		mode /soc/usb at c90c0000 failed

Fixes: 2eb79a4d15ff (ARM: dts: meson: enabling the USB Host
		controller on Odroid-C1/C1+ board)

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
V2 > changes gpio polarity ACTIVE_HIGH to ACTIVE_LOW.
     Fix the source power from phy-supply to vbus-supply.

[1] https://lore.kernel.org/linux-devicetree/20210716103651.1455-2-linux.amoon at gmail.com/

V1 > Fix the Input GPIO polarity from HIGH to LOW.

previous version
[0] https://patchwork.kernel.org/project/linux-amlogic/patch/20190113181808.5768-1-linux.amoon at gmail.com

changes fix the vbus-suppy to phy-supply, drop enable usb0

    USB_PWR                       2    1      0 unknown  5000mV     0mA  5000mV  5000mV
       phy-c1108820.phy.0-phy     2                                 0mA     0mV     0mV
---
 arch/arm/boot/dts/meson8b-odroidc1.dts | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
index c440ef94e082..30ec6a7f20c7 100644
--- a/arch/arm/boot/dts/meson8b-odroidc1.dts
+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
@@ -32,6 +32,23 @@ emmc_pwrseq: emmc-pwrseq {
 		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
 	};
 
+	usb_pwr_en: regulator-usb-pwr-en {
+		compatible = "regulator-fixed";
+
+		regulator-name = "USB_OTG_PWR";
+
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		/*
+		 * signal name from schematics: USB_POWER - P5V0
+		 */
+		vin-supply = <&p5v0>;
+		/*
+		 * signal name from schematics: PWREN - GPIOAO.BIT5
+		 */
+		gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		blue {
@@ -119,7 +136,6 @@ vcc_3v3: regulator-vcc-3v3 {
 		regulator-name = "VCC3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
-
 		vin-supply = <&p5v0>;
 	};
 
@@ -382,4 +398,5 @@ &usb1_phy {
 
 &usb1 {
 	status = "okay";
+	vbus-supply = <&usb_pwr_en>;
 };
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:36 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:36 +0530
Subject: [PATCHv3 2/6] ARM: dts: meson8b: odroidc1: Set usb power source to
 always on
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-3-linux.amoon@gmail.com>

Set P5V0 and vcc_3v3 power source to USB to always on
so that regulator should not enter in suspend state.

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
New patch in this series.
---
 arch/arm/boot/dts/meson8b-odroidc1.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
index 30ec6a7f20c7..5e5953152452 100644
--- a/arch/arm/boot/dts/meson8b-odroidc1.dts
+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
@@ -65,6 +65,7 @@ p5v0: regulator-p5v0 {
 		regulator-name = "P5V0";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
 	};
 
 	tflash_vdd: regulator-tflash_vdd {
@@ -136,6 +137,7 @@ vcc_3v3: regulator-vcc-3v3 {
 		regulator-name = "VCC3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
 		vin-supply = <&p5v0>;
 	};
 
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:37 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:37 +0530
Subject: [PATCHv3 3/6] arm64: dts: amlogic: odroidc2: Fix the chip enable
 signal for usb power
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-4-linux.amoon@gmail.com>

Fix the chip enable signal changing from Active High to Active Low
to enable input power to USB power. Also updated signal name as per
the schematics.

Fixes: 5a0803bd5ae2 ("ARM64: dts: meson-gxbb-odroidc2: Enable USB Nodes")

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v2:
Fix the typo: shematics -> schematics
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 201596247fd9..3f4f16a5dedd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -38,12 +38,11 @@ usb_otg_pwr: regulator-usb-pwrs {
 		regulator-max-microvolt = <5000000>;
 
 		/*
-		 * signal name from schematics: PWREN
+		 * signal name from schematics: PWREN - GPIOAO.BIT5
 		 */
-		gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
+		gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>;
 		/*
-		 * signal name from schematics: USB_POWER
+		 * signal name from schematics: USB_POWER - P5V0
 		 */
 		vin-supply = <&p5v0>;
 	};
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:38 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:38 +0530
Subject: [PATCHv3 4/6] arm64: dts: amlogic: odroidc2: use vbus-supply for
 power source for usb nodes
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-5-linux.amoon@gmail.com>

Use vbus-supply instead of phy-supply as power source for dwc2
nodes. Drop vbus-supply for usb0 node, as it will handle later.

Fixes: e841ec956e53 ("ARM64: dts: meson-gxbb-odroidc2:
       fix usb1 power supply")

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
New patch in this series.
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 3f4f16a5dedd..01bbfc4c091e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -400,12 +400,10 @@ &uart_AO {
 
 &usb0_phy {
 	status = "disabled";
-	phy-supply = <&usb_otg_pwr>;
 };
 
 &usb1_phy {
 	status = "okay";
-	phy-supply = <&usb_otg_pwr>;
 };
 
 &usb0 {
@@ -414,4 +412,5 @@ &usb0 {
 
 &usb1 {
 	status = "okay";
+	vbus-supply = <&usb_otg_pwr>;
 };
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:39 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:39 +0530
Subject: [PATCHv3 5/6] phy: amlogic: meson8b-usb2: Power off the PHY by
 putting it into reset mode
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-6-linux.amoon@gmail.com>

Power off the PHY by putting it into reset mode.

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v2 - None
---
 drivers/phy/amlogic/phy-meson8b-usb2.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index 03c061dd5f0d..2aad45c55494 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -219,6 +219,10 @@ static int phy_meson8b_usb2_power_off(struct phy *phy)
 	clk_disable_unprepare(priv->clk_usb);
 	clk_disable_unprepare(priv->clk_usb_general);
 
+	/* power off the PHY by putting it into reset mode */
+	regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
+			   REG_CTRL_POWER_ON_RESET);
+
 	return 0;
 }
 
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:40 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:40 +0530
Subject: [PATCHv3 6/6] phy: amlogic: meson8b-usb2: don't log an error on
 -EPROBE_DEFER
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-7-linux.amoon@gmail.com>

devm_phy_create can return -EPROBE_DEFER if the vbus-supply is not ready
yet. Silence this warning as the driver framework will re-attempt
registering the PHY. Use dev_err_probe() for phy resources to indicate
the deferral reason when waiting for the resource to come up.

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
None.
---
 drivers/phy/amlogic/phy-meson8b-usb2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index 2aad45c55494..cf10bed40528 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -277,8 +277,8 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
 
 	phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops);
 	if (IS_ERR(phy)) {
-		dev_err(&pdev->dev, "failed to create PHY\n");
-		return PTR_ERR(phy);
+		return dev_err_probe(&pdev->dev, PTR_ERR(phy),
+				     "failed to create PHY\n");
 	}
 
 	phy_set_drvdata(phy, priv);
-- 
2.32.0



From vkoul at kernel.org  Mon Aug 16 22:34:57 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 11:04:57 +0530
Subject: [PATCH v2 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <20210813201151.974512-3-iskren.chernev@gmail.com>
References: <20210813201151.974512-1-iskren.chernev@gmail.com>
 <20210813201151.974512-3-iskren.chernev@gmail.com>
Message-ID: <YRtKgf/iXV6bND8w@matsya>

On 13-08-21, 23:11, Iskren Chernev wrote:

> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
> index 6592b58b13f6..fde1bff16e27 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
> @@ -280,6 +280,8 @@
>  #define QSERDES_V3_COM_SSC_PER2				0x020
>  #define QSERDES_V3_COM_SSC_STEP_SIZE1			0x024
>  #define QSERDES_V3_COM_SSC_STEP_SIZE2			0x028
> +#define QSERDES_V3_COM_POST_DIV				0x02c
> +#define QSERDES_V3_COM_POST_DIV_MUX			0x030
>  #define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN		0x034
>  # define QSERDES_V3_COM_BIAS_EN				0x0001
>  # define QSERDES_V3_COM_BIAS_EN_MUX			0x0002
> @@ -291,6 +293,7 @@
>  #define QSERDES_V3_COM_CLK_ENABLE1			0x038
>  #define QSERDES_V3_COM_SYS_CLK_CTRL			0x03c
>  #define QSERDES_V3_COM_SYSCLK_BUF_ENABLE		0x040
> +#define QSERDES_V3_COM_PLL_EN				0x044
>  #define QSERDES_V3_COM_PLL_IVCO				0x048
>  #define QSERDES_V3_COM_LOCK_CMP1_MODE0			0x098
>  #define QSERDES_V3_COM_LOCK_CMP2_MODE0			0x09c
> @@ -348,6 +351,100 @@
>  #define QSERDES_V3_COM_DEBUG_BUS_SEL			0x178
>  #define QSERDES_V3_COM_CMN_MODE				0x184
>  
> +/* Only for QMP V3 660 PHY - QSERDES COM registers*/
> +#define QSERDES_V3_660_COM_LOCK_CMP1_MODE0		0x04c
> +#define QSERDES_V3_660_COM_LOCK_CMP2_MODE0		0x050
> +#define QSERDES_V3_660_COM_LOCK_CMP3_MODE0		0x054
> +#define QSERDES_V3_660_COM_LOCK_CMP1_MODE1		0x058
> +#define QSERDES_V3_660_COM_LOCK_CMP2_MODE1		0x05c
> +#define QSERDES_V3_660_COM_LOCK_CMP3_MODE1		0x060
> +#define QSERDES_V3_660_COM_CMD_RSVD0			0x064

Are you sure this is v3, this looks like V2 offsets:

#define QSERDES_COM_LOCK_CMP1_MODE0                     0x04c
#define QSERDES_COM_LOCK_CMP2_MODE0                     0x050
#define QSERDES_COM_LOCK_CMP3_MODE0                     0x054
#define QSERDES_COM_LOCK_CMP1_MODE1                     0x058
#define QSERDES_COM_LOCK_CMP2_MODE1                     0x05c
#define QSERDES_COM_LOCK_CMP3_MODE1                     0x060

> +#define QSERDES_V3_660_COM_EP_CLOCK_DETECT_CTRL		0x068
> +#define QSERDES_V3_660_COM_SYSCLK_DET_COMP_STATUS	0x06c

This is new

> +#define QSERDES_V3_660_COM_BG_TRIM			0x070
> +#define QSERDES_V3_660_COM_CLK_EP_DIV			0x074
> +#define QSERDES_V3_660_COM_CP_CTRL_MODE0		0x078

Same as v2

So can you run these offsets against v2 and recheck... there is some
confusion always with version numbers with this IP!

> +#define QSERDES_V3_660_COM_CP_CTRL_MODE1		0x07c
> +#define QSERDES_V3_660_COM_CMN_RSVD1			0x080
> +#define QSERDES_V3_660_COM_PLL_RCTRL_MODE0		0x084
> +#define QSERDES_V3_660_COM_PLL_RCTRL_MODE1		0x088
> +#define QSERDES_V3_660_COM_CMN_RSVD2			0x08c
> +#define QSERDES_V3_660_COM_PLL_CCTRL_MODE0		0x090
> +#define QSERDES_V3_660_COM_PLL_CCTRL_MODE1		0x094
> +#define QSERDES_V3_660_COM_CMN_RSVD3			0x098
> +#define QSERDES_V3_660_COM_PLL_CNTRL			0x09c
> +#define QSERDES_V3_660_COM_PHASE_SEL_CTRL		0x0a0
> +#define QSERDES_V3_660_COM_PHASE_SEL_DC			0x0a4
> +#define QSERDES_V3_660_COM_BIAS_EN_CTRL_BY_PSM		0x0a8
> +#define QSERDES_V3_660_COM_SYSCLK_EN_SEL		0x0ac
> +#define QSERDES_V3_660_COM_CML_SYSCLK_SEL		0x0b0
> +#define QSERDES_V3_660_COM_RESETSM_CNTRL		0x0b4
> +#define QSERDES_V3_660_COM_RESETSM_CNTRL2		0x0b8
> +#define QSERDES_V3_660_COM_RESTRIM_CTRL			0x0bc
> +#define QSERDES_V3_660_COM_RESTRIM_CTRL2		0x0c0
> +#define QSERDES_V3_660_COM_LOCK_CMP_EN			0x0c8
> +#define QSERDES_V3_660_COM_LOCK_CMP_CFG			0x0cc
> +#define QSERDES_V3_660_COM_DEC_START_MODE0		0x0d0
> +#define QSERDES_V3_660_COM_DEC_START_MODE1		0x0d4
> +#define QSERDES_V3_660_COM_VCOCAL_DEADMAN_CTRL		0x0d8
> +#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE0	0x0dc
> +#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE0	0x0e0
> +#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE0	0x0e4
> +#define QSERDES_V3_660_COM_DIV_FRAC_START1_MODE1	0x0e8
> +#define QSERDES_V3_660_COM_DIV_FRAC_START2_MODE1	0x0ec
> +#define QSERDES_V3_660_COM_DIV_FRAC_START3_MODE1	0x0f0
> +#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL1		0x0f4
> +#define QSERDES_V3_660_COM_VCO_TUNE_MINVAL2		0x0f8
> +#define QSERDES_V3_660_COM_CMN_RSVD4			0x0fc
> +#define QSERDES_V3_660_COM_INTEGLOOP_INITVAL		0x100
> +#define QSERDES_V3_660_COM_INTEGLOOP_EN			0x104
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE0	0x108
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE0	0x10c
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN0_MODE1	0x110
> +#define QSERDES_V3_660_COM_INTEGLOOP_GAIN1_MODE1	0x114
> +#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL1		0x118
> +#define QSERDES_V3_660_COM_VCO_TUNE_MAXVAL2		0x11c
> +#define QSERDES_V3_660_COM_RES_TRIM_CONTROL2		0x120
> +#define QSERDES_V3_660_COM_VCO_TUNE_CTRL		0x124
> +#define QSERDES_V3_660_COM_VCO_TUNE_MAP			0x128
> +#define QSERDES_V3_660_COM_VCO_TUNE1_MODE0		0x12c
> +#define QSERDES_V3_660_COM_VCO_TUNE2_MODE0		0x130
> +#define QSERDES_V3_660_COM_VCO_TUNE1_MODE1		0x134
> +#define QSERDES_V3_660_COM_VCO_TUNE2_MODE1		0x138
> +#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL1		0x13c
> +#define QSERDES_V3_660_COM_VCO_TUNE_INITVAL2		0x140
> +#define QSERDES_V3_660_COM_VCO_TUNE_TIMER1		0x144
> +#define QSERDES_V3_660_COM_VCO_TUNE_TIMER2		0x148
> +#define QSERDES_V3_660_COM_SAR				0x14c
> +#define QSERDES_V3_660_COM_SAR_CLK			0x150
> +#define QSERDES_V3_660_COM_SAR_CODE_OUT_STATUS		0x154
> +#define QSERDES_V3_660_COM_SAR_CODE_READY_STATUS	0x158
> +#define QSERDES_V3_660_COM_CMN_STATUS			0x15c
> +#define QSERDES_V3_660_COM_RESET_SM_STATUS		0x160
> +#define QSERDES_V3_660_COM_RESTRIM_CODE_STATUS		0x164
> +#define QSERDES_V3_660_COM_PLLCAL_CODE1_STATUS		0x168
> +#define QSERDES_V3_660_COM_PLLCAL_CODE2_STATUS		0x16c
> +#define QSERDES_V3_660_COM_BG_CTRL			0x170
> +#define QSERDES_V3_660_COM_CLK_SELECT			0x174
> +#define QSERDES_V3_660_COM_HSCLK_SEL			0x178
> +#define QSERDES_V3_660_COM_INTEGLOOP_BINCODE_STATUS	0x17c
> +#define QSERDES_V3_660_COM_PLL_ANALOG			0x180
> +#define QSERDES_V3_660_COM_CORECLK_DIV			0x184
> +#define QSERDES_V3_660_COM_SW_RESET			0x188
> +#define QSERDES_V3_660_COM_CORE_CLK_EN			0x18c
> +#define QSERDES_V3_660_COM_C_READY_STATUS		0x190
> +#define QSERDES_V3_660_COM_CMN_CONFIG			0x194
> +#define QSERDES_V3_660_COM_CMN_RATE_OVERRIDE		0x198
> +#define QSERDES_V3_660_COM_SVS_MODE_CLK_SEL		0x19c
> +#define QSERDES_V3_660_COM_DEBUG_BUS0			0x1a0
> +#define QSERDES_V3_660_COM_DEBUG_BUS1			0x1a4
> +#define QSERDES_V3_660_COM_DEBUG_BUS2			0x1a8
> +#define QSERDES_V3_660_COM_DEBUG_BUS3			0x1ac
> +#define QSERDES_V3_660_COM_DEBUG_BUS_SEL		0x1b0
> +#define QSERDES_V3_660_COM_CMN_MISC1			0x1b4
> +#define QSERDES_V3_660_COM_CORECLK_DIV_MODE1		0x1bc
> +#define QSERDES_V3_660_COM_CMN_RSVD5			0x1c0
> +
>  /* Only for QMP V3 PHY - TX registers */
>  #define QSERDES_V3_TX_BIST_MODE_LANENO			0x000
>  #define QSERDES_V3_TX_CLKBUF_ENABLE			0x008
> @@ -380,6 +477,10 @@
>  #define QSERDES_V3_TX_TX_INTERFACE_MODE			0x0c4
>  #define QSERDES_V3_TX_VMODE_CTRL1			0x0f0
>  
> +/* Only for QMP V3 660 PHY - TX registers */
> +#define QSERDES_V3_660_TX_HIGHZ_TRANSCEIVER_BIAS_DRVR_EN	0x068
> +#define QSERDES_V3_660_TX_LANE_MODE				0x094
> +
>  /* Only for QMP V3 PHY - RX registers */
>  #define QSERDES_V3_RX_UCDR_FO_GAIN			0x008
>  #define QSERDES_V3_RX_UCDR_SO_GAIN_HALF			0x00c
> @@ -411,6 +512,24 @@
>  #define QSERDES_V3_RX_RX_MODE_00			0x164
>  #define QSERDES_V3_RX_RX_MODE_01			0x168
>  
> +/* Only for QMP V3 660 PHY - RX registers */
> +#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_HALF		0x030
> +#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_QUARTER	0x034
> +#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN_EIGHTH	0x038
> +#define QSERDES_V3_660_RX_UCDR_SVS_SO_GAIN		0x03c
> +#define QSERDES_V3_660_RX_UCDR_FASTLOCK_FO_GAIN		0x040
> +#define QSERDES_V3_660_RX_UCDR_SO_SATURATION_ENABLE	0x048
> +#define QSERDES_V3_660_RX_RX_TERM_BW			0x090
> +#define QSERDES_V3_660_RX_RX_EQ_GAIN1_LSB		0x0c4
> +#define QSERDES_V3_660_RX_RX_EQ_GAIN1_MSB		0x0c8
> +#define QSERDES_V3_660_RX_RX_EQ_GAIN2_LSB		0x0cc
> +#define QSERDES_V3_660_RX_RX_EQ_GAIN2_MSB		0x0d0
> +#define QSERDES_V3_660_RX_RX_EQU_ADAPTOR_CNTRL2		0x0d8
> +#define QSERDES_V3_660_RX_SIGDET_CNTRL			0x114
> +#define QSERDES_V3_660_RX_SIGDET_LVL			0x118
> +#define QSERDES_V3_660_RX_SIGDET_DEGLITCH_CNTRL		0x11c
> +#define QSERDES_V3_660_RX_RX_INTERFACE_MODE		0x12c
> +
>  /* Only for QMP V3 PHY - PCS registers */
>  #define QPHY_V3_PCS_POWER_DOWN_CONTROL			0x004
>  #define QPHY_V3_PCS_TXMGN_V0				0x00c
> @@ -473,6 +592,21 @@
>  #define QPHY_V3_PCS_REFGEN_REQ_CONFIG1			0x20c
>  #define QPHY_V3_PCS_REFGEN_REQ_CONFIG2			0x210
>  
> +/* Only for QMP V3 660 PHY - PCS registers */
> +#define QPHY_V3_660_PCS_PHY_START			0x000
> +#define QPHY_V3_660_PCS_POWER_DOWN_CONTROL		0x004
> +#define QPHY_V3_660_PCS_TX_LARGE_AMP_DRV_LVL		0x034
> +#define QPHY_V3_660_PCS_TX_LARGE_AMP_POST_EMP_LVL	0x038
> +#define QPHY_V3_660_PCS_TX_SMALL_AMP_DRV_LVL		0x03c
> +#define QPHY_V3_660_PCS_TX_SMALL_AMP_POST_EMP_LVL	0x040
> +#define QPHY_V3_660_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP	0x0cc
> +#define QPHY_V3_660_PCS_LINECFG_DISABLE			0x138
> +#define QPHY_V3_660_PCS_RX_SYM_RESYNC_CTRL		0x13c
> +#define QPHY_V3_660_PCS_RX_MIN_HIBERN8_TIME		0x140
> +#define QPHY_V3_660_PCS_RX_SIGDET_CTRL2			0x148
> +#define QPHY_V3_660_PCS_RX_PWM_GEAR_BAND		0x154
> +#define QPHY_V3_660_PCS_PCS_READY_STATUS		0x168
> +
>  /* Only for QMP V3 PHY - PCS_MISC registers */
>  #define QPHY_V3_PCS_MISC_CLAMP_ENABLE			0x0c
>  #define QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2		0x2c
> -- 
> 2.32.0

-- 
~Vinod


From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:39 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:39 +0800
Subject: [PATCH v3 1/9] dt-bindings: phy: mediatek: tphy: support type switch
 by pericfg
Message-ID: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch by pericfg register between USB3, PCIe,
SATA, SGMII, this is used to replace the way through efuse or
jumper.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add reviewed-by Rob
---
 .../devicetree/bindings/phy/mediatek,tphy.yaml   | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 838852cb8527..9e6c0f43f1c6 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -201,6 +201,22 @@ patternProperties:
           Specify the flag to enable BC1.2 if support it
         type: boolean
 
+      mediatek,syscon-type:
+        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
+        description:
+          A phandle to syscon used to access the register of type switch,
+          the field should always be 3 cells long.
+        items:
+          items:
+            - description:
+                The first cell represents a phandle to syscon
+            - description:
+                The second cell represents the register offset
+            - description:
+                The third cell represents the index of config segment
+              enum: [0, 1, 2, 3]
+
     required:
       - reg
       - "#phy-cells"
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:40 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:40 +0800
Subject: [PATCH v3 2/9] phy: phy-mtk-tphy: use clock bulk to get clocks
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-2-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 43 +++++++++--------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 33000b38fd1b..3259210f08a1 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -280,6 +280,8 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+#define TPHY_CLKS_CNT	2
+
 enum mtk_phy_version {
 	MTK_PHY_V1 = 1,
 	MTK_PHY_V2,
@@ -318,8 +320,7 @@ struct mtk_phy_instance {
 		struct u2phy_banks u2_banks;
 		struct u3phy_banks u3_banks;
 	};
-	struct clk *ref_clk;	/* reference clock of (digital) phy */
-	struct clk *da_ref_clk;	/* reference clock of analog phy */
+	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
 	u8 type;
 	int eye_src;
@@ -974,18 +975,9 @@ static int mtk_phy_init(struct phy *phy)
 	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
 	int ret;
 
-	ret = clk_prepare_enable(instance->ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable ref_clk\n");
+	ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, instance->clks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_prepare_enable(instance->da_ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable da_ref\n");
-		clk_disable_unprepare(instance->ref_clk);
-		return ret;
-	}
 
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
@@ -1003,8 +995,7 @@ static int mtk_phy_init(struct phy *phy)
 		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
-		clk_disable_unprepare(instance->ref_clk);
-		clk_disable_unprepare(instance->da_ref_clk);
+		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 		return -EINVAL;
 	}
 
@@ -1047,8 +1038,7 @@ static int mtk_phy_exit(struct phy *phy)
 	if (instance->type == PHY_TYPE_USB2)
 		u2_phy_instance_exit(tphy, instance);
 
-	clk_disable_unprepare(instance->ref_clk);
-	clk_disable_unprepare(instance->da_ref_clk);
+	clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 	return 0;
 }
 
@@ -1211,6 +1201,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	port = 0;
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
+		struct clk_bulk_data *clks;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1247,20 +1238,12 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		phy_set_drvdata(phy, instance);
 		port++;
 
-		instance->ref_clk = devm_clk_get_optional(&phy->dev, "ref");
-		if (IS_ERR(instance->ref_clk)) {
-			dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->ref_clk);
+		clks = instance->clks;
+		clks[0].id = "ref";     /* digital (& analog) clock */
+		clks[1].id = "da_ref";  /* analog clock */
+		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		if (retval)
 			goto put_child;
-		}
-
-		instance->da_ref_clk =
-			devm_clk_get_optional(&phy->dev, "da_ref");
-		if (IS_ERR(instance->da_ref_clk)) {
-			dev_err(dev, "failed to get da_ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->da_ref_clk);
-			goto put_child;
-		}
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:42 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:42 +0800
Subject: [PATCH v3 4/9] phy: phy-mtk-tphy: print error log using child device
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-4-git-send-email-chunfeng.yun@mediatek.com>

Print error log using child devices instead of parent device.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index a6502058a1a5..9d4b34298137 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1278,6 +1278,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
 		struct clk_bulk_data *clks;
+		struct device *subdev;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1295,16 +1296,17 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 			goto put_child;
 		}
 
+		subdev = &phy->dev;
 		retval = of_address_to_resource(child_np, 0, &res);
 		if (retval) {
-			dev_err(dev, "failed to get address resource(id-%d)\n",
+			dev_err(subdev, "failed to get address resource(id-%d)\n",
 				port);
 			goto put_child;
 		}
 
-		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(dev, "failed to remap phy regs\n");
+			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
@@ -1317,7 +1319,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		clks = instance->clks;
 		clks[0].id = "ref";     /* digital (& analog) clock */
 		clks[1].id = "da_ref";  /* analog clock */
-		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		retval = devm_clk_bulk_get_optional(subdev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:41 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:41 +0800
Subject: [PATCH v3 3/9] phy: phy-mtk-tphy: support type switch by pericfg
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-3-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch between USB3, PCIe, SATA and SGMII by
pericfg register, this is used to take the place of efuse or
jumper.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 84 ++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 3259210f08a1..a6502058a1a5 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -10,11 +10,13 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 /* version V1 sub-banks offset base address */
 /* banks shared by multiple phys */
@@ -280,6 +282,14 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+/* PHY switch between pcie/usb3/sgmii/sata */
+#define USB_PHY_SWITCH_CTRL	0x0
+#define RG_PHY_SW_TYPE		GENMASK(3, 0)
+#define RG_PHY_SW_PCIE		0x0
+#define RG_PHY_SW_USB3		0x1
+#define RG_PHY_SW_SGMII		0x2
+#define RG_PHY_SW_SATA		0x3
+
 #define TPHY_CLKS_CNT	2
 
 enum mtk_phy_version {
@@ -322,7 +332,10 @@ struct mtk_phy_instance {
 	};
 	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
-	u8 type;
+	u32 type;
+	struct regmap *type_sw;
+	u32 type_sw_reg;
+	u32 type_sw_index;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
@@ -969,6 +982,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
 	}
 }
 
+/* type switch for usb3/pcie/sgmii/sata */
+static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+			       struct device_node *dn)
+{
+	struct of_phandle_args args;
+	int ret;
+
+	/* type switch function is optional */
+	if (!of_property_read_bool(dn, "mediatek,syscon-type"))
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
+					       2, 0, &args);
+	if (ret)
+		return ret;
+
+	instance->type_sw_reg = args.args[0];
+	instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
+	instance->type_sw = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
+		 instance->type_sw_reg, instance->type_sw_index);
+
+	return PTR_ERR_OR_ZERO(instance->type_sw);
+}
+
+static int phy_type_set(struct mtk_phy_instance *instance)
+{
+	int type;
+	u32 mask;
+
+	if (!instance->type_sw)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB3:
+		type = RG_PHY_SW_USB3;
+		break;
+	case PHY_TYPE_PCIE:
+		type = RG_PHY_SW_PCIE;
+		break;
+	case PHY_TYPE_SGMII:
+		type = RG_PHY_SW_SGMII;
+		break;
+	case PHY_TYPE_SATA:
+		type = RG_PHY_SW_SATA;
+		break;
+	case PHY_TYPE_USB2:
+	default:
+		return 0;
+	}
+
+	mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+	regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
+
+	return 0;
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -993,6 +1064,9 @@ static int mtk_phy_init(struct phy *phy)
 	case PHY_TYPE_SATA:
 		sata_phy_instance_init(tphy, instance);
 		break;
+	case PHY_TYPE_SGMII:
+		/* nothing to do, only used to set type */
+		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
 		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
@@ -1081,7 +1155,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	if (!(instance->type == PHY_TYPE_USB2 ||
 	      instance->type == PHY_TYPE_USB3 ||
 	      instance->type == PHY_TYPE_PCIE ||
-	      instance->type == PHY_TYPE_SATA)) {
+	      instance->type == PHY_TYPE_SATA ||
+	      instance->type == PHY_TYPE_SGMII)) {
 		dev_err(dev, "unsupported device type: %d\n", instance->type);
 		return ERR_PTR(-EINVAL);
 	}
@@ -1100,6 +1175,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	}
 
 	phy_parse_property(tphy, instance);
+	phy_type_set(instance);
 
 	return instance->phy;
 }
@@ -1244,6 +1320,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
+
+		retval = phy_type_syscon_get(instance, child_np);
+		if (retval)
+			goto put_child;
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:47 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:47 +0800
Subject: [PATCH v3 9/9] phy: phy-mtk-mipi-dsi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-9-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 61c942fbf4a1..28ad9403c441 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -130,7 +130,6 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mipi_tx *mipi_tx;
-	struct resource *mem;
 	const char *ref_clk_name;
 	struct clk *ref_clk;
 	struct clk_init_data clk_init = {
@@ -148,11 +147,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mipi_tx->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(mipi_tx->regs)) {
+	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mipi_tx->regs))
 		return PTR_ERR(mipi_tx->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(ref_clk)) {
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:46 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:46 +0800
Subject: [PATCH v3 8/9] phy: phy-mtk-mipi-dsi: remove dummy assignment of
 error number
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-8-git-send-email-chunfeng.yun@mediatek.com>

Return the error number directly without assignment

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 01cf31633019..61c942fbf4a1 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -203,10 +203,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy, mipi_tx);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	if (IS_ERR(phy_provider)) {
-		ret = PTR_ERR(phy_provider);
-		return ret;
-	}
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
 
 	mipi_tx->dev = dev;
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:45 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:45 +0800
Subject: [PATCH v3 7/9] phy: phy-mtk-hdmi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-7-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 8ad8f717ef43..5fb4217fb8e0 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -100,7 +100,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_hdmi_phy *hdmi_phy;
-	struct resource *mem;
 	struct clk *ref_clk;
 	const char *ref_clk_name;
 	struct clk_init_data clk_init = {
@@ -116,11 +115,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 	if (!hdmi_phy)
 		return -ENOMEM;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi_phy->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(hdmi_phy->regs)) {
+	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(hdmi_phy->regs))
 		return PTR_ERR(hdmi_phy->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, "pll_ref");
 	if (IS_ERR(ref_clk)) {
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:44 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:44 +0800
Subject: [PATCH v3 6/9] phy: phy-mtk-ufs: use clock bulk to get clocks
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-6-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Reviewed-by: Stanley Chu <stanley.chu at mediatek.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: add reviewed-by Stanley
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-ufs.c | 44 ++++++++----------------------
 1 file changed, 11 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c
index 769b00b038d8..a6af06941203 100644
--- a/drivers/phy/mediatek/phy-mtk-ufs.c
+++ b/drivers/phy/mediatek/phy-mtk-ufs.c
@@ -31,11 +31,12 @@
 #define FRC_CDR_ISO_EN              BIT(19)
 #define CDR_ISO_EN                  BIT(20)
 
+#define UFSPHY_CLKS_CNT    2
+
 struct ufs_mtk_phy {
 	struct device *dev;
 	void __iomem *mmio;
-	struct clk *mp_clk;
-	struct clk *unipro_clk;
+	struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
 };
 
 static inline u32 mphy_readl(struct ufs_mtk_phy *phy, u32 reg)
@@ -74,20 +75,11 @@ static struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy)
 static int ufs_mtk_phy_clk_init(struct ufs_mtk_phy *phy)
 {
 	struct device *dev = phy->dev;
+	struct clk_bulk_data *clks = phy->clks;
 
-	phy->unipro_clk = devm_clk_get(dev, "unipro");
-	if (IS_ERR(phy->unipro_clk)) {
-		dev_err(dev, "failed to get clock: unipro");
-		return PTR_ERR(phy->unipro_clk);
-	}
-
-	phy->mp_clk = devm_clk_get(dev, "mp");
-	if (IS_ERR(phy->mp_clk)) {
-		dev_err(dev, "failed to get clock: mp");
-		return PTR_ERR(phy->mp_clk);
-	}
-
-	return 0;
+	clks[0].id = "unipro";
+	clks[1].id = "mp";
+	return devm_clk_bulk_get(dev, UFSPHY_CLKS_CNT, clks);
 }
 
 static void ufs_mtk_phy_set_active(struct ufs_mtk_phy *phy)
@@ -150,26 +142,13 @@ static int ufs_mtk_phy_power_on(struct phy *generic_phy)
 	struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
 	int ret;
 
-	ret = clk_prepare_enable(phy->unipro_clk);
-	if (ret) {
-		dev_err(phy->dev, "unipro_clk enable failed %d\n", ret);
-		goto out;
-	}
-
-	ret = clk_prepare_enable(phy->mp_clk);
-	if (ret) {
-		dev_err(phy->dev, "mp_clk enable failed %d\n", ret);
-		goto out_unprepare_unipro_clk;
-	}
+	ret = clk_bulk_prepare_enable(UFSPHY_CLKS_CNT, phy->clks);
+	if (ret)
+		return ret;
 
 	ufs_mtk_phy_set_active(phy);
 
 	return 0;
-
-out_unprepare_unipro_clk:
-	clk_disable_unprepare(phy->unipro_clk);
-out:
-	return ret;
 }
 
 static int ufs_mtk_phy_power_off(struct phy *generic_phy)
@@ -178,8 +157,7 @@ static int ufs_mtk_phy_power_off(struct phy *generic_phy)
 
 	ufs_mtk_phy_set_deep_hibern(phy);
 
-	clk_disable_unprepare(phy->unipro_clk);
-	clk_disable_unprepare(phy->mp_clk);
+	clk_bulk_disable_unprepare(UFSPHY_CLKS_CNT, phy->clks);
 
 	return 0;
 }
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:43 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:43 +0800
Subject: [PATCH v3 5/9] phy: phy-mtk-tphy: remove error log of ioremap failure
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-5-git-send-email-chunfeng.yun@mediatek.com>

devm_ioremap_resource() will print log if error happens.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 9d4b34298137..cdcef865fe9e 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1306,7 +1306,6 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 
 		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
-- 
2.18.0

From vkoul at kernel.org  Tue Aug 17 03:12:56 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 15:42:56 +0530
Subject: [PATCH v3 0/9] PHY: Prepare Cadence Torrent PHY driver to
 support multilink DP
In-Reply-To: <20210728145454.15945-1-sjakhade@cadence.com>
References: <20210728145454.15945-1-sjakhade@cadence.com>
Message-ID: <YRuLqAH12Llvbqti@matsya>

On 28-07-21, 16:54, Swapnil Jakhade wrote:
> This patch series enables Torrent PHY driver to support different input
> reference clock frequencies. It also does the basic cleanup in order to
> add support for multilink DP configurations. The multilink DP series at
> [1] will be split in 2 parts and sent separately. This is part 1 of the
> series.
> 
> Support for DP multilink configurations with register sequences will be
> added in part 2 as a separate patch series after validation.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Tue Aug 17 03:22:18 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 15:52:18 +0530
Subject: [PATCH v3 1/9] dt-bindings: phy: mediatek: tphy: support type
 switch by pericfg
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YRuN2tvQtO294+sE@matsya>

On 17-08-21, 17:19, Chunfeng Yun wrote:
> Add support type switch by pericfg register between USB3, PCIe,
> SATA, SGMII, this is used to replace the way through efuse or
> jumper.

Applied all, thanks

-- 
~Vinod


From vkoul at kernel.org  Tue Aug 17 03:30:52 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 16:00:52 +0530
Subject: [PATCHv3 5/6] phy: amlogic: meson8b-usb2: Power off the PHY by
 putting it into reset mode
In-Reply-To: <20210817041548.1276-6-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-6-linux.amoon@gmail.com>
Message-ID: <YRuP3D6EMlaKJOx7@matsya>

On 17-08-21, 09:45, Anand Moon wrote:
> Power off the PHY by putting it into reset mode.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Tue Aug 17 03:31:04 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 16:01:04 +0530
Subject: [PATCHv3 6/6] phy: amlogic: meson8b-usb2: don't log an error on
 -EPROBE_DEFER
In-Reply-To: <20210817041548.1276-7-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-7-linux.amoon@gmail.com>
Message-ID: <YRuP6JfdEZNL8tXt@matsya>

On 17-08-21, 09:45, Anand Moon wrote:
> devm_phy_create can return -EPROBE_DEFER if the vbus-supply is not ready
> yet. Silence this warning as the driver framework will re-attempt
> registering the PHY. Use dev_err_probe() for phy resources to indicate
> the deferral reason when waiting for the resource to come up.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Tue Aug 17 03:42:37 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 16:12:37 +0530
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe
 PHY
In-Reply-To: <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
 <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
Message-ID: <YRuSnXHSZHhBC40r@matsya>

On 12-08-21, 10:02, Mauro Carvalho Chehab wrote:

> +static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
> +{
> +	u32 val;
> +
> +	val = kirin_apb_natural_phy_readl(phy,
> +					  RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);

Maybe use one line for this (hint: we can go beyong 80 now)

> +static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
> +{
> +	u32 val;
> +
> +	/* change 2p mem_ctrl */
> +	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
> +		     SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
> +
> +	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
> +	val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
> +	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
> +
> +	/* output, pull down */
> +	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
> +	val &= ~PCIE_OUTPUT_PULL_BITS;
> +	val |= PCIE_OUTPUT_PULL_DOWN;
> +	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
> +
> +	/* Handle phy_reset and lane0_reset to HW */
> +	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL1_ADDR);
> +	val |= PCIEPHY_RESET_BIT;
> +	val &= ~PCIEPHY_PIPE_LINE0_RESET_BIT;
> +	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL1_ADDR);
> +
> +	/* fix chip bug: TxDetectRx fail */
> +	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_CTRL38_ADDR);
> +	val |= PCIE_TXDETECT_RX_FAIL;
> +	hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_CTRL38_ADDR);

maybe add a hi3670_apb_phy_updatel() so that above would become:

        hi3670_apb_phy_updatel(phy, val, mask);

> +static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
> +{
> +	struct device *dev = phy->dev;
> +	u32 val;
> +	int time = PLL_CTRL_WAIT_TIME;
> +
> +	if (enable) {
> +		/* pd = 0 */
> +		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_CTRL16);
> +		val &= ~PCIE_PHY_MMC1PLL_DISABLE;
> +		hi3670_apb_phy_writel(phy, val, SOC_PCIEPHY_MMC1PLL_CTRL16);
> +
> +		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
> +
> +		/* choose FNPLL */
> +		while (!(val & FNPLL_HAS_LOCKED)) {
> +			if (!time) {
> +				dev_err(dev, "wait for pll_lock timeout\n");
> +				return -EINVAL;
> +			}
> +			time--;
> +			udelay(1);
> +			val = hi3670_apb_phy_readl(phy,
> +						   SOC_PCIEPHY_MMC1PLL_STAT0);

single line here too

> +static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
> +{
> +	unsigned int val;
> +
> +	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
> +
> +	if (open)
> +		val &= ~IO_OE_HARD_GT_MODE; // enable hard gt mode
> +	else
> +		val |= IO_OE_HARD_GT_MODE; // disable hard gt mode

pls change the comment style here and above, we dont use c99 style!

> +static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
> +{
> +	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
> +
> +	hi3670_pcie_phy_oe_enable(phy, false);
> +
> +	hi3670_pcie_allclk_ctrl(phy, false);
> +
> +	/* Drop power supply for Host */
> +	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
> +
> +	/* FIXME: calling it causes an Asynchronous SError interrupt */
> +//	kirin_pcie_clk_ctrl(phy, false);

when will you fix the fixme and pls remove the deadcode
-- 
~Vinod


From jbx6244 at gmail.com  Tue Aug 17 09:52:15 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 17 Aug 2021 18:52:15 +0200
Subject: [PATCH v2 2/8] dt-bindings: phy: phy-rockchip-inno-usb2: add
 rk3568 documentation
In-Reply-To: <20210812204116.2303617-3-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
 <20210812204116.2303617-3-pgwipeout@gmail.com>
Message-ID: <c7ff9234-cc3b-3679-bc63-73c5eb825269@gmail.com>

Hi Peter,

Some comments. Have a look if it's useful.

On 8/12/21 10:41 PM, Peter Geis wrote:
> The rk3568 usb2phy node is a standalone node with a single muxed
> interrupt.
> Add documentation for it to phy-rockchip-inno-usb2.
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>  .../bindings/phy/phy-rockchip-inno-usb2.yaml  | 31 ++++++++++++++++---
>  1 file changed, 27 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> index 5bebd86bf8b6..d2a749c3f9a3 100644
> --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> @@ -18,6 +18,7 @@ properties:
>        - rockchip,rk3328-usb2phy
>        - rockchip,rk3366-usb2phy
>        - rockchip,rk3399-usb2phy
> +      - rockchip,rk3568-usb2phy
>        - rockchip,rv1108-usb2phy
>  
>    reg:
> @@ -50,6 +51,9 @@ properties:
>      description:
>        Phandle to the extcon device providing the cable state for the otg phy.
>  

> +  interrupts:
> +    description: Muxed interrupt for both ports
> +

This allows every Rockchip SoC dtsi to add an interrupt here.
You have only restricted the requirements.
The goal is to restrict things and filter bogus properties.
If it was done because it doesn't compile, maybe could you try/test/use
something like the rockchip-io-domain.yaml $defs format.

===

unevaluatedProperties: false

allOf:
  - $ref: "#/$defs/rk3568"

$defs:
  rk3568:
    if:
      properties:
        compatible:
          contains:
            const: rockchip,rk3568-usb2phy

    then:
      properties:
        interrupts:
          maxItems: 1

      required:
        - interrupts

    else:
      properties:
        host-port:
          properties:
            interrupts:
              description: host linestate interrupt

            interrupt-names:
              const: linestate

          required:
            - interrupts
            - interrupt-names

        otg-port:
          properties:

           interrupts:
             minItems: 1
             maxItems: 3

           interrupt-names:
             oneOf:
               - const: linestate
               - const: otg-mux
               - items:
                   - const: otg-bvalid
                   - const: otg-id
                   - const: linestate

          required:
            - interrupts
            - interrupt-names

>    rockchip,usbgrf:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description:
> @@ -78,8 +82,6 @@ properties:
>  
>      required:
>        - "#phy-cells"

> -      - interrupts
> -      - interrupt-names

Also remove them as properties in this part when a separate $defs is used.

>  
>    otg-port:
>      type: object
> @@ -109,8 +111,6 @@ properties:
>  
>      required:
>        - "#phy-cells"

> -      - interrupts
> -      - interrupt-names

dito

>  
>  required:
>    - compatible
> @@ -120,6 +120,29 @@ required:
>    - host-port
>    - otg-port
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: rockchip,rk3568-usb2phy

> +      then:

Test "if then else" alignment with yamllint

> +        properties:
> +          interrupts:
> +            maxItems: 1
> +        required:
> +          - interrupts

> +      else:

alignment

> +        properties:
> +          host-port:
> +            required:
> +              - interrupts
> +              - interrupt-names
> +          otg-port:
> +            required:
> +              - interrupts
> +              - interrupt-names
> +

>  additionalProperties: false

additionalProperties does workn't with allOf: - $ref. Use
unevaluatedProperties.

>  
>  examples:
> 


From robh at kernel.org  Tue Aug 17 14:43:59 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:43:59 -0500
Subject: [PATCH v2 2/8] dt-bindings: phy: phy-rockchip-inno-usb2: add
 rk3568 documentation
In-Reply-To: <c7ff9234-cc3b-3679-bc63-73c5eb825269@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
 <20210812204116.2303617-3-pgwipeout@gmail.com>
 <c7ff9234-cc3b-3679-bc63-73c5eb825269@gmail.com>
Message-ID: <YRwtnxucxIeq+ayx@robh.at.kernel.org>

On Tue, Aug 17, 2021 at 06:52:15PM +0200, Johan Jonker wrote:
> Hi Peter,
> 
> Some comments. Have a look if it's useful.
> 
> On 8/12/21 10:41 PM, Peter Geis wrote:
> > The rk3568 usb2phy node is a standalone node with a single muxed
> > interrupt.
> > Add documentation for it to phy-rockchip-inno-usb2.
> > 
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >  .../bindings/phy/phy-rockchip-inno-usb2.yaml  | 31 ++++++++++++++++---
> >  1 file changed, 27 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> > index 5bebd86bf8b6..d2a749c3f9a3 100644
> > --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> > +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> > @@ -18,6 +18,7 @@ properties:
> >        - rockchip,rk3328-usb2phy
> >        - rockchip,rk3366-usb2phy
> >        - rockchip,rk3399-usb2phy
> > +      - rockchip,rk3568-usb2phy
> >        - rockchip,rv1108-usb2phy
> >  
> >    reg:
> > @@ -50,6 +51,9 @@ properties:
> >      description:
> >        Phandle to the extcon device providing the cable state for the otg phy.
> >  
> 
> > +  interrupts:
> > +    description: Muxed interrupt for both ports
> > +
> 
> This allows every Rockchip SoC dtsi to add an interrupt here.
> You have only restricted the requirements.
> The goal is to restrict things and filter bogus properties.
> If it was done because it doesn't compile, maybe could you try/test/use
> something like the rockchip-io-domain.yaml $defs format.

Don't use $defs unless there's more than 1 copy needed of something. If 
it happens to bypass some checks, it's only a matter of time til I fix 
that.

This may be better solved with another schema file rather than a long 
if/then schema. It's a judgement call.

> 
> ===
> 
> unevaluatedProperties: false
> 
> allOf:
>   - $ref: "#/$defs/rk3568"
> 
> $defs:
>   rk3568:
>     if:
>       properties:
>         compatible:
>           contains:
>             const: rockchip,rk3568-usb2phy
> 
>     then:
>       properties:
>         interrupts:
>           maxItems: 1
> 
>       required:
>         - interrupts
> 
>     else:
>       properties:
>         host-port:
>           properties:
>             interrupts:
>               description: host linestate interrupt
> 
>             interrupt-names:
>               const: linestate
> 
>           required:
>             - interrupts
>             - interrupt-names
> 
>         otg-port:
>           properties:
> 
>            interrupts:
>              minItems: 1
>              maxItems: 3
> 
>            interrupt-names:
>              oneOf:
>                - const: linestate
>                - const: otg-mux
>                - items:
>                    - const: otg-bvalid
>                    - const: otg-id
>                    - const: linestate
> 
>           required:
>             - interrupts
>             - interrupt-names
> 
> >    rockchip,usbgrf:
> >      $ref: /schemas/types.yaml#/definitions/phandle
> >      description:
> > @@ -78,8 +82,6 @@ properties:
> >  
> >      required:
> >        - "#phy-cells"
> 
> > -      - interrupts
> > -      - interrupt-names
> 
> Also remove them as properties in this part when a separate $defs is used.
> 
> >  
> >    otg-port:
> >      type: object
> > @@ -109,8 +111,6 @@ properties:
> >  
> >      required:
> >        - "#phy-cells"
> 
> > -      - interrupts
> > -      - interrupt-names
> 
> dito
> 
> >  
> >  required:
> >    - compatible
> > @@ -120,6 +120,29 @@ required:
> >    - host-port
> >    - otg-port
> >  
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: rockchip,rk3568-usb2phy
> 
> > +      then:
> 
> Test "if then else" alignment with yamllint

yamllint is not going to help there. What's needed is a meta-schema that 
adds the dependencies.

> 
> > +        properties:
> > +          interrupts:
> > +            maxItems: 1
> > +        required:
> > +          - interrupts
> 
> > +      else:
> 
> alignment
> 
> > +        properties:
> > +          host-port:
> > +            required:
> > +              - interrupts
> > +              - interrupt-names
> > +          otg-port:
> > +            required:
> > +              - interrupts
> > +              - interrupt-names
> > +
> 
> >  additionalProperties: false
> 
> additionalProperties does workn't with allOf: - $ref. Use
> unevaluatedProperties.
> 
> >  
> >  examples:
> > 
> 


From piyush.mehta at xilinx.com  Wed Aug 18 01:43:11 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 14:13:11 +0530
Subject: [PATCH] phy: xilinx: zynqmp: skip PHY initialization and PLL lock for
 USB
Message-ID: <20210818084311.2643986-1-piyush.mehta@xilinx.com>

PHY initialization for USB is required on linux boot or when
gt lane is changed from the current one and it is applicable
on PLL lock too.

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
---
 drivers/phy/xilinx/phy-zynqmp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c
index 35652152ce5d..f478d8a17115 100644
--- a/drivers/phy/xilinx/phy-zynqmp.c
+++ b/drivers/phy/xilinx/phy-zynqmp.c
@@ -626,6 +626,9 @@ static int xpsgtr_phy_power_on(struct phy *phy)
 	struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy);
 	int ret = 0;
 
+	/* Skip initialization if not required. */
+	if (!xpsgtr_phy_init_required(gtr_phy))
+		return ret;
 	/*
 	 * Wait for the PLL to lock. For DP, only wait on DP0 to avoid
 	 * cumulating waits for both lanes. The user is expected to initialize
-- 
2.25.1



From mchehab+huawei at kernel.org  Wed Aug 18 02:01:23 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 18 Aug 2021 11:01:23 +0200
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe
 PHY
In-Reply-To: <YRuSnXHSZHhBC40r@matsya>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
 <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
 <YRuSnXHSZHhBC40r@matsya>
Message-ID: <20210818110123.33eba838@coco.lan>

Hi Vinod,

Em Tue, 17 Aug 2021 16:12:37 +0530
Vinod Koul <vkoul at kernel.org> escreveu:

> > +	/* FIXME: calling it causes an Asynchronous SError interrupt */
> > +//	kirin_pcie_clk_ctrl(phy, false);  
> 
> when will you fix the fixme and pls remove the deadcode

Working with clocks on this SoC is very tricky: there are lots of clock
lines (~70) that are critical for this device to work. Such lines are
enabled via the Device's firmware, and are supposed to be always
powered. Powering off such clock lines cause a SError.

Most clocks on this device are managed by the clk-hikey3670 driver.
At the current state of clk-hi3670, the only way for HiKey 970
to even boot is to add:

	clk_ignore_unused=true

as a Kernel boot parameter. That is the solution given by the downstream
official distributions for HiKey970 at 96boards.

The fix is to flag the critical clocks with CLK_IS_CRITICAL at the
clk-hi3670 driver, but finding the right clock set has been a challenge.

I spent the last couple of weeks trying to identify the critical ones,
as I'm aiming to be able to use a Kernel built with a default arm64
one of my goals is to have this device working fine with a
"make defconfig" Kernel.

So, I added this patch:

	https://lore.kernel.org/lkml/2d2de5e902ced072bcfd5e5311d6b10326b9245b.1627041240.git.mchehab+huawei at kernel.org/

to my tree (which reduces the set of clocks using CLK_IGNORE_UNUSED
from 308 to 163 clocks). Than I ran script that was dropping the
flag one by one, boots the new Kernel and do a sanity check. When it 
fails to boot, I manually dropped the patch, and re-run the script
to test the remaining clocks. After a couple of weeks, I reached a patch
with 78 clock lines that seemed critical, but the resulting patch was
not stable, as, depending on the day I boot the Kernel with such patch,
it crashes with SError in a couple of seconds after booting, or 
cause the Ethernet firmware to not load.

I intend to keep trying to find the clock lines that can't be disabled,
but this is very time consuming, as I couldn't find any documentation
about that. So, it has to be done empirically.

-

In any case, fixing it doesn't sound a critical issue for the PHY
driver. I mean, right now, this patchset allows removing and 
re-inseting the PCIe driver, which is already an improvement over the
original upstream driver, which was missing the power-off logic for
Kirin 960.

With this patchset, both power-off/power-on logic for both HiKey960
(where the PHY is inside the pcie-kirin driver) and for HiKey970,
which uses this PHY driver. On both devices, I tested an endless loop 
with rmmod/modprobe for the PCIe.

Besides that, in practice, removing PCIe in runtime is something that
people usually don't do.

So, while it would be cool to balance the clock disable logic,
I don't think this is a critical issue in this particular case.

Thanks,
Mauro


From mchehab+huawei at kernel.org  Wed Aug 18 03:08:02 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 18 Aug 2021 12:08:02 +0200
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe
 PHY
In-Reply-To: <20210818110123.33eba838@coco.lan>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
 <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
 <YRuSnXHSZHhBC40r@matsya> <20210818110123.33eba838@coco.lan>
Message-ID: <20210818120802.3ba5fd59@coco.lan>

Em Wed, 18 Aug 2021 11:01:23 +0200
Mauro Carvalho Chehab <mchehab+huawei at kernel.org> escreveu:

> Hi Vinod,
> 
> Em Tue, 17 Aug 2021 16:12:37 +0530
> Vinod Koul <vkoul at kernel.org> escreveu:
> 
> > > +	/* FIXME: calling it causes an Asynchronous SError interrupt */
> > > +//	kirin_pcie_clk_ctrl(phy, false);    
> > 
> > when will you fix the fixme and pls remove the deadcode  
> 
> Working with clocks on this SoC is very tricky: there are lots of clock
> lines (~70) that are critical for this device to work. Such lines are
> enabled via the Device's firmware, and are supposed to be always
> powered. Powering off such clock lines cause a SError.
> 
> Most clocks on this device are managed by the clk-hikey3670 driver.
> At the current state of clk-hi3670, the only way for HiKey 970
> to even boot is to add:
> 
> 	clk_ignore_unused=true
> 
> as a Kernel boot parameter. That is the solution given by the downstream
> official distributions for HiKey970 at 96boards.
> 
> The fix is to flag the critical clocks with CLK_IS_CRITICAL at the
> clk-hi3670 driver, but finding the right clock set has been a challenge.
> 
> I spent the last couple of weeks trying to identify the critical ones,
> as I'm aiming to be able to use a Kernel built with a default arm64
> one of my goals is to have this device working fine with a
> "make defconfig" Kernel.
> 
> So, I added this patch:
> 
> 	https://lore.kernel.org/lkml/2d2de5e902ced072bcfd5e5311d6b10326b9245b.1627041240.git.mchehab+huawei at kernel.org/
> 
> to my tree (which reduces the set of clocks using CLK_IGNORE_UNUSED
> from 308 to 163 clocks). Than I ran script that was dropping the
> flag one by one, boots the new Kernel and do a sanity check. When it 
> fails to boot, I manually dropped the patch, and re-run the script
> to test the remaining clocks. After a couple of weeks, I reached a patch
> with 78 clock lines that seemed critical, but the resulting patch was
> not stable, as, depending on the day I boot the Kernel with such patch,
> it crashes with SError in a couple of seconds after booting, or 
> cause the Ethernet firmware to not load.
> 
> I intend to keep trying to find the clock lines that can't be disabled,
> but this is very time consuming, as I couldn't find any documentation
> about that. So, it has to be done empirically.
> 
> -
> 
> In any case, fixing it doesn't sound a critical issue for the PHY
> driver. I mean, right now, this patchset allows removing and 
> re-inseting the PCIe driver, which is already an improvement over the
> original upstream driver, which was missing the power-off logic for
> Kirin 960.
> 
> With this patchset, both power-off/power-on logic for both HiKey960
> (where the PHY is inside the pcie-kirin driver) and for HiKey970,
> which uses this PHY driver. On both devices, I tested an endless loop 
> with rmmod/modprobe for the PCIe.
> 
> Besides that, in practice, removing PCIe in runtime is something that
> people usually don't do.
> 
> So, while it would be cool to balance the clock disable logic,
> I don't think this is a critical issue in this particular case.
> 
> Thanks,
> Mauro

Btw, this is one of such panic errors:

[    4.468948] hi3670_pcie_phy fc000000.pcie-phy: PIPE clk is not stable
[    4.522530] SError Interrupt on CPU4, code 0xbf000002 -- SError
[    4.522535] CPU: 4 PID: 223 Comm: systemd-udevd Not tainted 5.14.0-rc1+ #370
[    4.522537] Hardware name: HiKey970 (DT)
[    4.522539] pstate: 400000c5 (nZcv daIF -PAN -UAO -TCO BTYPE=--)
[    4.522540] pc : el1_interrupt+0x20/0x80
[    4.522542] lr : el1h_64_irq_handler+0x18/0x24
[    4.522543] sp : ffff800012903610
[    4.522543] x29: ffff800012903610 x28: ffff000108410e40 x27: ffff0001bf3e4100
[    4.522551] x26: 0000000000000000 x25: 0000000000000000 x24: ffff0001009dec10
[    4.522554] x23: 0000000040000005 x22: ffff800010ed1330 x21: ffff800012903790
[    4.522556] x20: ffff8000104e42e0 x19: ffff800012903640 x18: 0000000000000000
[    4.522559] x17: 0000000000000000 x16: 0000000000000000 x15: 0763072007450750
[    4.522563] x14: 074907500720073a x13: ffff0001b87e0000 x12: 000000000000053a
[    4.522565] x11: 00000000000001be x10: ffff0001bf2386c0 x9 : 00000000ffff0000
[    4.522568] x8 : ffff0001b87e0000 x7 : ffff0001bf2386c0 x6 : 0000000000000000
[    4.522571] x5 : ffff00010370aac0 x4 : ffff000108410e40 x3 : ffff800011f20cd8
[    4.522573] x2 : ffff000108410e40 x1 : 00000000000000c0 x0 : ffff800012903640
[    4.522577] Kernel panic - not syncing: Asynchronous SError Interrupt
[    4.522578] CPU: 4 PID: 223 Comm: systemd-udevd Not tainted 5.14.0-rc1+ #370
[    4.522579] Hardware name: HiKey970 (DT)
[    4.522579] Call trace:
[    4.522580]  dump_backtrace+0x0/0x1e0
[    4.522581]  show_stack+0x18/0x24
[    4.522581]  dump_stack_lvl+0x68/0x84
[    4.522582]  dump_stack+0x18/0x34
[    4.522583]  panic+0x16c/0x334
[    4.522583]  nmi_panic+0x8c/0x90
[    4.522584]  arm64_serror_panic+0x78/0x84
[    4.522585]  do_serror+0x58/0x5c
[    4.522586]  el1h_64_error_handler+0x30/0x50
[    4.522586]  el1h_64_error+0x78/0x7c
[    4.522588]  el1_interrupt+0x20/0x80
[    4.522588]  el1h_64_irq_handler+0x18/0x24
[    4.522589]  el1h_64_irq+0x78/0x7c
[    4.522590]  mutex_lock_io+0xf0/0x370
[    4.522591]  clk_unprepare+0x28/0x50
[    4.522591]  kirin_pcie_clk_ctrl+0x164/0x1a0 [phy_hi3670_pcie]
[    4.522592]  hi3670_pcie_phy_power_on+0x720/0xb00 [phy_hi3670_pcie]
[    4.522593]  phy_power_on+0x78/0x130
[    4.522594]  kirin_pcie_probe+0x6a8/0x88c [pcie_kirin]
[    4.522595]  platform_probe+0x68/0xe0
[    4.522596]  really_probe+0x1b0/0x42c
[    4.522596]  __driver_probe_device+0x114/0x190
[    4.522597]  driver_probe_device+0x40/0x100
[    4.522598]  __driver_attach+0xcc/0x1e0
[    4.522599]  bus_for_each_dev+0x70/0xd0
[    4.522600]  driver_attach+0x24/0x30
[    4.522601]  bus_add_driver+0x140/0x234
[    4.522601]  driver_register+0x78/0x130
[    4.522602]  __platform_driver_register+0x28/0x34
[    4.522603]  kirin_pcie_driver_init+0x24/0x1000 [pcie_kirin]
[    4.522604]  do_one_initcall+0x50/0x1b0
[    4.522605]  do_init_module+0x5c/0x254
[    4.522605]  load_module+0x21cc/0x2820
[    4.522606]  __do_sys_finit_module+0xbc/0x130
[    4.522607]  __arm64_sys_finit_module+0x24/0x30
[    4.522608]  invoke_syscall+0x48/0x114
[    4.522608]  el0_svc_common+0xc4/0xdc
[    4.522609]  do_el0_svc+0x28/0x90
[    4.522610]  el0_svc+0x2c/0x54
[    4.522610]  el0t_64_sync_handler+0x1a4/0x1b0
[    4.522611]  el0t_64_sync+0x198/0x19c
[    4.522633] SMP: stopping secondary CPUs
[    4.522634] Kernel Offset: disabled
[    4.522635] CPU features: 0x00003051,00000846
[    4.522636] Memory Limit: none

Thanks,
Mauro


From vkoul at kernel.org  Wed Aug 18 03:10:27 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 18 Aug 2021 15:40:27 +0530
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe
 PHY
In-Reply-To: <20210818110123.33eba838@coco.lan>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
 <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
 <YRuSnXHSZHhBC40r@matsya> <20210818110123.33eba838@coco.lan>
Message-ID: <YRzck9WqerFtu846@matsya>

On 18-08-21, 11:01, Mauro Carvalho Chehab wrote:
> Hi Vinod,
> 
> Em Tue, 17 Aug 2021 16:12:37 +0530
> Vinod Koul <vkoul at kernel.org> escreveu:
> 
> > > +	/* FIXME: calling it causes an Asynchronous SError interrupt */
> > > +//	kirin_pcie_clk_ctrl(phy, false);  
> > 
> > when will you fix the fixme and pls remove the deadcode
> 
> Working with clocks on this SoC is very tricky: there are lots of clock
> lines (~70) that are critical for this device to work. Such lines are
> enabled via the Device's firmware, and are supposed to be always
> powered. Powering off such clock lines cause a SError.
> 
> Most clocks on this device are managed by the clk-hikey3670 driver.
> At the current state of clk-hi3670, the only way for HiKey 970
> to even boot is to add:
> 
> 	clk_ignore_unused=true
> 
> as a Kernel boot parameter. That is the solution given by the downstream
> official distributions for HiKey970 at 96boards.
> 
> The fix is to flag the critical clocks with CLK_IS_CRITICAL at the
> clk-hi3670 driver, but finding the right clock set has been a challenge.
> 
> I spent the last couple of weeks trying to identify the critical ones,
> as I'm aiming to be able to use a Kernel built with a default arm64
> one of my goals is to have this device working fine with a
> "make defconfig" Kernel.
> 
> So, I added this patch:
> 
> 	https://lore.kernel.org/lkml/2d2de5e902ced072bcfd5e5311d6b10326b9245b.1627041240.git.mchehab+huawei at kernel.org/
> 
> to my tree (which reduces the set of clocks using CLK_IGNORE_UNUSED
> from 308 to 163 clocks). Than I ran script that was dropping the
> flag one by one, boots the new Kernel and do a sanity check. When it 
> fails to boot, I manually dropped the patch, and re-run the script
> to test the remaining clocks. After a couple of weeks, I reached a patch
> with 78 clock lines that seemed critical, but the resulting patch was
> not stable, as, depending on the day I boot the Kernel with such patch,
> it crashes with SError in a couple of seconds after booting, or 
> cause the Ethernet firmware to not load.
> 
> I intend to keep trying to find the clock lines that can't be disabled,
> but this is very time consuming, as I couldn't find any documentation
> about that. So, it has to be done empirically.
> 
> -
> 
> In any case, fixing it doesn't sound a critical issue for the PHY
> driver. I mean, right now, this patchset allows removing and 
> re-inseting the PCIe driver, which is already an improvement over the
> original upstream driver, which was missing the power-off logic for
> Kirin 960.
> 
> With this patchset, both power-off/power-on logic for both HiKey960
> (where the PHY is inside the pcie-kirin driver) and for HiKey970,
> which uses this PHY driver. On both devices, I tested an endless loop 
> with rmmod/modprobe for the PCIe.
> 
> Besides that, in practice, removing PCIe in runtime is something that
> people usually don't do.
> 
> So, while it would be cool to balance the clock disable logic,
> I don't think this is a critical issue in this particular case.

Okay sounds fair to me, I think fixme should be left but the c99 style
code commented out can be removed

-- 
~Vinod


From vkoul at kernel.org  Wed Aug 18 03:14:22 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 18 Aug 2021 15:44:22 +0530
Subject: [PATCH] phy: xilinx: zynqmp: skip PHY initialization and PLL
 lock for USB
In-Reply-To: <20210818084311.2643986-1-piyush.mehta@xilinx.com>
References: <20210818084311.2643986-1-piyush.mehta@xilinx.com>
Message-ID: <YRzdfsnntGf9ebU/@matsya>

On 18-08-21, 14:13, Piyush Mehta wrote:
> PHY initialization for USB is required on linux boot or when
> gt lane is changed from the current one and it is applicable
> on PLL lock too.

Applied, thanks

-- 
~Vinod


From mchehab+huawei at kernel.org  Wed Aug 18 03:30:37 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 18 Aug 2021 12:30:37 +0200
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe
 PHY
In-Reply-To: <YRzck9WqerFtu846@matsya>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
 <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
 <YRuSnXHSZHhBC40r@matsya> <20210818110123.33eba838@coco.lan>
 <YRzck9WqerFtu846@matsya>
Message-ID: <20210818123037.2adef2de@coco.lan>

Em Wed, 18 Aug 2021 15:40:27 +0530
Vinod Koul <vkoul at kernel.org> escreveu:

> On 18-08-21, 11:01, Mauro Carvalho Chehab wrote:
> > Hi Vinod,
> > 
> > Em Tue, 17 Aug 2021 16:12:37 +0530
> > Vinod Koul <vkoul at kernel.org> escreveu:
> >   
> > > > +	/* FIXME: calling it causes an Asynchronous SError interrupt */
> > > > +//	kirin_pcie_clk_ctrl(phy, false);    
> > > 
> > > when will you fix the fixme and pls remove the deadcode  
> > 
> > Working with clocks on this SoC is very tricky: there are lots of clock
> > lines (~70) that are critical for this device to work. Such lines are
> > enabled via the Device's firmware, and are supposed to be always
> > powered. Powering off such clock lines cause a SError.
> > 
> > Most clocks on this device are managed by the clk-hikey3670 driver.
> > At the current state of clk-hi3670, the only way for HiKey 970
> > to even boot is to add:
> > 
> > 	clk_ignore_unused=true
> > 
> > as a Kernel boot parameter. That is the solution given by the downstream
> > official distributions for HiKey970 at 96boards.
> > 
> > The fix is to flag the critical clocks with CLK_IS_CRITICAL at the
> > clk-hi3670 driver, but finding the right clock set has been a challenge.
> > 
> > I spent the last couple of weeks trying to identify the critical ones,
> > as I'm aiming to be able to use a Kernel built with a default arm64
> > one of my goals is to have this device working fine with a
> > "make defconfig" Kernel.
> > 
> > So, I added this patch:
> > 
> > 	https://lore.kernel.org/lkml/2d2de5e902ced072bcfd5e5311d6b10326b9245b.1627041240.git.mchehab+huawei at kernel.org/
> > 
> > to my tree (which reduces the set of clocks using CLK_IGNORE_UNUSED
> > from 308 to 163 clocks). Than I ran script that was dropping the
> > flag one by one, boots the new Kernel and do a sanity check. When it 
> > fails to boot, I manually dropped the patch, and re-run the script
> > to test the remaining clocks. After a couple of weeks, I reached a patch
> > with 78 clock lines that seemed critical, but the resulting patch was
> > not stable, as, depending on the day I boot the Kernel with such patch,
> > it crashes with SError in a couple of seconds after booting, or 
> > cause the Ethernet firmware to not load.
> > 
> > I intend to keep trying to find the clock lines that can't be disabled,
> > but this is very time consuming, as I couldn't find any documentation
> > about that. So, it has to be done empirically.
> > 
> > -
> > 
> > In any case, fixing it doesn't sound a critical issue for the PHY
> > driver. I mean, right now, this patchset allows removing and 
> > re-inseting the PCIe driver, which is already an improvement over the
> > original upstream driver, which was missing the power-off logic for
> > Kirin 960.
> > 
> > With this patchset, both power-off/power-on logic for both HiKey960
> > (where the PHY is inside the pcie-kirin driver) and for HiKey970,
> > which uses this PHY driver. On both devices, I tested an endless loop 
> > with rmmod/modprobe for the PCIe.
> > 
> > Besides that, in practice, removing PCIe in runtime is something that
> > people usually don't do.
> > 
> > So, while it would be cool to balance the clock disable logic,
> > I don't think this is a critical issue in this particular case.  
> 
> Okay sounds fair to me, I think fixme should be left but the c99 style
> code commented out can be removed

Agreed. I'll replace it with:

+       /*
+        * FIXME: The enabled clocks should be disabled here by calling
+        * kirin_pcie_clk_ctrl(phy, false);
+        * However, some clocks used at Kirin 970 should be marked as
+        * CLK_IS_CRITICAL at clk-hi3670 driver, as powering such clocks off
+        * cause an Asynchronous SError interrupt, which produces panic().
+        * While clk-hi3670 is not fixed, we cannot risk disabling clocks here.
+        */

Thanks,
Mauro


From vkoul at kernel.org  Wed Aug 18 03:37:56 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 18 Aug 2021 16:07:56 +0530
Subject: [PATCH v11 01/11] phy: HiSilicon: Add driver for Kirin 970 PCIe
 PHY
In-Reply-To: <20210818123037.2adef2de@coco.lan>
References: <cover.1628755058.git.mchehab+huawei@kernel.org>
 <7788c5ead6d6f5a6f9e5faaee4460eb2149967c4.1628755058.git.mchehab+huawei@kernel.org>
 <YRuSnXHSZHhBC40r@matsya> <20210818110123.33eba838@coco.lan>
 <YRzck9WqerFtu846@matsya> <20210818123037.2adef2de@coco.lan>
Message-ID: <YRzjBOGsehbHAGJv@matsya>

On 18-08-21, 12:30, Mauro Carvalho Chehab wrote:
> Em Wed, 18 Aug 2021 15:40:27 +0530
> Vinod Koul <vkoul at kernel.org> escreveu:

> > Okay sounds fair to me, I think fixme should be left but the c99 style
> > code commented out can be removed
> 
> Agreed. I'll replace it with:
> 
> +       /*
> +        * FIXME: The enabled clocks should be disabled here by calling
> +        * kirin_pcie_clk_ctrl(phy, false);
> +        * However, some clocks used at Kirin 970 should be marked as
> +        * CLK_IS_CRITICAL at clk-hi3670 driver, as powering such clocks off
> +        * cause an Asynchronous SError interrupt, which produces panic().
> +        * While clk-hi3670 is not fixed, we cannot risk disabling clocks here.
> +        */

sounds good!

-- 
~Vinod


From mchehab+huawei at kernel.org  Wed Aug 18 04:04:07 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 18 Aug 2021 13:04:07 +0200
Subject: [PATCH v12] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
In-Reply-To: <YRzck9WqerFtu846@matsya>
References: <YRzck9WqerFtu846@matsya>
Message-ID: <ecf443314ca05bd29fd247fc1cf37f4d94799325.1629284470.git.mchehab+huawei@kernel.org>

The Kirin 970 PHY is somewhat similar to the Kirin 960, but it
does a lot more. Add the needed bits for PCIe to start working on
HiKey 970 boards.

Co-developed-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---

PS.:
   As the PCIe patches aren't untouched, I'm sending just the PHY
   driver patch on v12.

v12:
  - removed c99-style comments;
  - added hi3670_apb_phy_updatel() to update bits;
  - allowed a couple of lines to be bigger than 80 columns.

 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 861 ++++++++++++++++++++++++
 3 files changed, 872 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 4d008cfc279c..d3b92c288554 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -33,6 +33,16 @@ config PHY_HI3670_USB
 
 	  To compile this driver as a module, choose M here.
 
+config PHY_HI3670_PCIE
+	tristate "hi3670 PCIe PHY support"
+	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+	select GENERIC_PHY
+	select MFD_SYSCON
+	help
+	  Enable this to support the HiSilicon hi3670 PCIe PHY.
+
+	  To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
 	tristate "HiSilicon STB SoCs COMBPHY support"
 	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 51729868145b..4029d3813b1e 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_HI6220_USB)		+= phy-hi6220-usb.o
 obj-$(CONFIG_PHY_HI3660_USB)		+= phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HI3670_USB)		+= phy-hi3670-usb3.o
+obj-$(CONFIG_PHY_HI3670_PCIE)		+= phy-hi3670-pcie.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)		+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)	+= phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
new file mode 100644
index 000000000000..f0c66e8e155d
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -0,0 +1,861 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe phy driver for Kirin 970
+ *
+ * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
+ *		https://www.huawei.com
+ * Copyright (C) 2021 Huawei Technologies Co., Ltd.
+ *		https://www.huawei.com
+ *
+ * Authors:
+ *	Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+ *	Manivannan Sadhasivam <mani at kernel.org>
+ *
+ * Based on:
+ *	https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei at kernel.org/
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AXI_CLK_FREQ				207500000
+#define REF_CLK_FREQ				100000000
+
+/* PCIe CTRL registers */
+#define SOC_PCIECTRL_CTRL0_ADDR			0x000
+#define SOC_PCIECTRL_CTRL1_ADDR			0x004
+#define SOC_PCIECTRL_CTRL7_ADDR			0x01c
+#define SOC_PCIECTRL_CTRL12_ADDR		0x030
+#define SOC_PCIECTRL_CTRL20_ADDR		0x050
+#define SOC_PCIECTRL_CTRL21_ADDR		0x054
+#define SOC_PCIECTRL_STATE0_ADDR		0x400
+
+#define PCIE_OUTPUT_PULL_BITS			GENMASK(3, 0)
+#define SOC_PCIECTRL_CTRL20_2P_MEM_CTRL		0x02605550
+#define SOC_PCIECTRL_CTRL21_DEFAULT		0x20000070
+#define PCIE_PULL_UP_SYS_AUX_PWR_DET		BIT(10)
+#define PCIE_OUTPUT_PULL_DOWN			BIT(1)
+
+/* PCIe PHY registers */
+#define SOC_PCIEPHY_CTRL0_ADDR			0x000
+#define SOC_PCIEPHY_CTRL1_ADDR			0x004
+#define SOC_PCIEPHY_CTRL2_ADDR			0x008
+#define SOC_PCIEPHY_CTRL3_ADDR			0x00c
+#define SOC_PCIEPHY_CTRL38_ADDR			0x0098
+#define SOC_PCIEPHY_STATE0_ADDR			0x400
+
+#define PORT_MSI_CTRL_ADDR			0x820
+#define PORT_MSI_CTRL_UPPER_ADDR		0x824
+#define PORT_MSI_CTRL_INT0_ENABLE		0x828
+
+#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1	0xc004
+#define SUP_DIG_LVL_OVRD_IN			0x003c
+#define LANEN_DIG_ASIC_TX_OVRD_IN_1		0x4008
+#define LANEN_DIG_ASIC_TX_OVRD_IN_2		0x400c
+
+#define PCIE_LINKUP_ENABLE			0x8020
+#define PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
+#define PCIE_LTSSM_ENABLE_BIT			BIT(11)
+#define PCIEPHY_RESET_BIT			BIT(17)
+#define PCIEPHY_PIPE_LINE0_RESET_BIT		BIT(19)
+#define PCIE_TXDETECT_RX_FAIL			BIT(2)
+#define PCIE_CLK_SOURCE				BIT(8)
+#define PCIE_IS_CLOCK_STABLE			BIT(19)
+#define PCIE_PULL_DOWN_PHY_TEST_POWERDOWN	BIT(22)
+#define PCIE_DEASSERT_CONTROLLER_PERST		BIT(2)
+
+#define EYEPARAM_NOCFG				0xffffffff
+#define EYE_PARM0_MASK				GENMASK(8, 6)
+#define EYE_PARM1_MASK				GENMASK(11, 8)
+#define EYE_PARM2_MASK				GENMASK(5, 0)
+#define EYE_PARM3_MASK				GENMASK(12, 7)
+#define EYE_PARM4_MASK				GENMASK(14, 9)
+#define EYE_PARM0_EN				BIT(9)
+#define EYE_PARM1_EN				BIT(12)
+#define EYE_PARM2_EN				BIT(6)
+#define EYE_PARM3_EN				BIT(13)
+#define EYE_PARM4_EN				BIT(15)
+
+/* hi3670 pciephy register */
+#define APB_PHY_START_ADDR			0x40000
+#define SOC_PCIEPHY_MMC1PLL_CTRL1		0xc04
+#define SOC_PCIEPHY_MMC1PLL_CTRL16		0xC40
+#define SOC_PCIEPHY_MMC1PLL_CTRL17		0xC44
+#define SOC_PCIEPHY_MMC1PLL_CTRL20		0xC50
+#define SOC_PCIEPHY_MMC1PLL_CTRL21		0xC54
+#define SOC_PCIEPHY_MMC1PLL_STAT0		0xE00
+
+#define CRGPERIPH_PEREN12			0x470
+#define CRGPERIPH_PERDIS12			0x474
+#define CRGPERIPH_PCIECTRL0			0x800
+
+#define PCIE_FNPLL_FBDIV_MASK			GENMASK(27, 16)
+#define PCIE_FNPLL_FRACDIV_MASK			GENMASK(23, 0)
+#define PCIE_FNPLL_POSTDIV1_MASK		GENMASK(10, 8)
+#define PCIE_FNPLL_POSTDIV2_MASK		GENMASK(14, 12)
+#define PCIE_FNPLL_PLL_MODE_MASK		BIT(25)
+
+#define PCIE_FNPLL_DLL_EN			BIT(27)
+#define PCIE_FNPLL_FBDIV			0xd0
+#define PCIE_FNPLL_FRACDIV			0x555555
+#define PCIE_FNPLL_POSTDIV1			0x5
+#define PCIE_FNPLL_POSTDIV2			0x4
+#define PCIE_FNPLL_PLL_MODE			0x0
+
+#define PCIE_PHY_MMC1PLL			0x20
+#define PCIE_PHY_CHOOSE_FNPLL			BIT(27)
+#define PCIE_PHY_MMC1PLL_DISABLE		BIT(0)
+#define PCIE_PHY_PCIEPL_BP			BIT(16)
+
+/* define ie,oe cfg */
+#define IO_OE_HARD_GT_MODE			BIT(1)
+#define IO_IE_EN_HARD_BYPASS			BIT(27)
+#define IO_OE_EN_HARD_BYPASS			BIT(11)
+#define IO_HARD_CTRL_DEBOUNCE_BYPASS		BIT(10)
+#define IO_OE_GT_MODE				BIT(8)
+#define DEBOUNCE_WAITCFG_IN			GENMASK(23, 20)
+#define DEBOUNCE_WAITCFG_OUT			GENMASK(16, 13)
+
+#define IO_HP_DEBOUNCE_GT			(BIT(12) | BIT(15))
+#define IO_PHYREF_SOFT_GT_MODE			BIT(14)
+#define IO_REF_SOFT_GT_MODE			BIT(13)
+#define IO_REF_HARD_GT_MODE			BIT(0)
+
+/* noc power domain */
+#define NOC_POWER_IDLEREQ_1			0x38c
+#define NOC_POWER_IDLE_1			0x394
+#define NOC_PW_MASK				0x10000
+#define NOC_PW_SET_BIT				0x1
+
+#define NUM_EYEPARAM				5
+
+/* info located in sysctrl */
+#define SCTRL_PCIE_CMOS_OFFSET			0x60
+#define SCTRL_PCIE_CMOS_BIT			0x10
+#define SCTRL_PCIE_ISO_OFFSET			0x44
+#define SCTRL_PCIE_ISO_BIT			0x30
+#define SCTRL_PCIE_HPCLK_OFFSET			0x190
+#define SCTRL_PCIE_HPCLK_BIT			0x184000
+#define SCTRL_PCIE_OE_OFFSET			0x14a
+#define PCIE_DEBOUNCE_PARAM			0xf0f400
+#define PCIE_OE_BYPASS				GENMASK(29, 28)
+
+/* peri_crg ctrl */
+#define CRGCTRL_PCIE_ASSERT_OFFSET		0x88
+#define CRGCTRL_PCIE_ASSERT_BIT			0x8c000000
+
+#define FNPLL_HAS_LOCKED			BIT(4)
+
+/* Time for delay */
+#define PIPE_CLK_WAIT_MIN	550
+#define PIPE_CLK_WAIT_MAX	600
+#define TIME_CMOS_MIN		100
+#define TIME_CMOS_MAX		105
+#define TIME_PHY_PD_MIN		10
+#define TIME_PHY_PD_MAX		11
+
+#define PIPE_CLK_STABLE_TIME	100
+#define PLL_CTRL_WAIT_TIME	200
+#define NOC_POWER_TIME		100
+
+struct hi3670_pcie_phy {
+	struct device	*dev;
+	void __iomem	*base;
+	struct regmap	*apb;
+	struct regmap	*crgctrl;
+	struct regmap	*sysctrl;
+	struct regmap	*pmctrl;
+	struct clk	*apb_sys_clk;
+	struct clk	*apb_phy_clk;
+	struct clk	*phy_ref_clk;
+	struct clk	*aclk;
+	struct clk	*aux_clk;
+	u32		eye_param[NUM_EYEPARAM];
+};
+
+/* Registers in PCIePHY */
+static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy, u32 val,
+					 u32 reg)
+{
+	writel(val, phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
+{
+	return readl(phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline void hi3670_apb_phy_updatel(struct hi3670_pcie_phy *phy,
+					  u32 val, u32 mask, u32 reg)
+{
+	u32 regval;
+
+	regval = hi3670_apb_phy_readl(phy, reg);
+	regval &= ~mask;
+	regval |= val;
+	hi3670_apb_phy_writel(phy, regval, reg);
+}
+
+static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
+						u32 val, u32 reg)
+{
+	writel(val, phy->base + reg);
+}
+
+static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
+					      u32 reg)
+{
+	return readl(phy->base + reg);
+}
+
+static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
+{
+	u32 val;
+
+	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
+	val |= PCIE_DEBOUNCE_PARAM;
+	if (enable)
+		val &= ~PCIE_OE_BYPASS;
+	else
+		val |= PCIE_OE_BYPASS;
+	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
+}
+
+static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np;
+	int ret, i;
+
+	np = dev->of_node;
+
+	ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
+					 phy->eye_param, NUM_EYEPARAM);
+	if (!ret)
+		return;
+
+	/* There's no optional eye_param property. Set array to default */
+	for (i = 0; i < NUM_EYEPARAM; i++)
+		phy->eye_param[i] = EYEPARAM_NOCFG;
+}
+
+static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = kirin_apb_natural_phy_readl(phy, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM1_MASK;
+		val |= FIELD_PREP(EYE_PARM1_MASK, phy->eye_param[1]);
+		val |= EYE_PARM1_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val,
+				     RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+	val &= ~(EYE_PARM2_MASK | EYE_PARM3_MASK);
+	if (phy->eye_param[2] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM2_MASK, phy->eye_param[2]);
+		val |= EYE_PARM2_EN;
+	}
+
+	if (phy->eye_param[3] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM3_MASK, phy->eye_param[3]);
+		val |= EYE_PARM3_EN;
+	}
+
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+
+	val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
+	if (phy->eye_param[0] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM0_MASK;
+		val |= FIELD_PREP(EYE_PARM0_MASK, phy->eye_param[0]);
+		val |= EYE_PARM0_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+	if (phy->eye_param[4] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM4_MASK;
+		val |= FIELD_PREP(EYE_PARM4_MASK, phy->eye_param[4]);
+		val |= EYE_PARM4_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+}
+
+static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* change 2p mem_ctrl */
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
+		     SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
+
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
+	val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
+
+	/* output, pull down */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val &= ~PCIE_OUTPUT_PULL_BITS;
+	val |= PCIE_OUTPUT_PULL_DOWN;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+
+	/* Handle phy_reset and lane0_reset to HW */
+	hi3670_apb_phy_updatel(phy, PCIEPHY_RESET_BIT,
+			       PCIEPHY_PIPE_LINE0_RESET_BIT | PCIEPHY_RESET_BIT,
+			       SOC_PCIEPHY_CTRL1_ADDR);
+
+	/* fix chip bug: TxDetectRx fail */
+	hi3670_apb_phy_updatel(phy, PCIE_TXDETECT_RX_FAIL, PCIE_TXDETECT_RX_FAIL,
+			       SOC_PCIEPHY_CTRL38_ADDR);
+}
+
+static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
+{
+	hi3670_apb_phy_updatel(phy, PCIE_PHY_CHOOSE_FNPLL, PCIE_PHY_CHOOSE_FNPLL,
+			       SOC_PCIEPHY_MMC1PLL_CTRL1);
+
+
+	hi3670_apb_phy_updatel(phy,
+			       FIELD_PREP(PCIE_FNPLL_FBDIV_MASK, PCIE_FNPLL_FBDIV),
+			       PCIE_FNPLL_FBDIV_MASK,
+			       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+	hi3670_apb_phy_updatel(phy,
+			       FIELD_PREP(PCIE_FNPLL_FRACDIV_MASK, PCIE_FNPLL_FRACDIV),
+			       PCIE_FNPLL_FRACDIV_MASK, SOC_PCIEPHY_MMC1PLL_CTRL17);
+
+	hi3670_apb_phy_updatel(phy,
+			       PCIE_FNPLL_DLL_EN |
+			       FIELD_PREP(PCIE_FNPLL_POSTDIV1_MASK, PCIE_FNPLL_POSTDIV1) |
+			       FIELD_PREP(PCIE_FNPLL_POSTDIV2_MASK, PCIE_FNPLL_POSTDIV2) |
+			       FIELD_PREP(PCIE_FNPLL_PLL_MODE_MASK, PCIE_FNPLL_PLL_MODE),
+			       PCIE_FNPLL_POSTDIV1_MASK |
+			       PCIE_FNPLL_POSTDIV2_MASK |
+			       PCIE_FNPLL_PLL_MODE_MASK | PCIE_FNPLL_DLL_EN,
+			       SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	hi3670_apb_phy_writel(phy, PCIE_PHY_MMC1PLL,
+			      SOC_PCIEPHY_MMC1PLL_CTRL21);
+}
+
+static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int time = PLL_CTRL_WAIT_TIME;
+
+	if (enable) {
+		/* pd = 0 */
+		hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_MMC1PLL_DISABLE,
+				       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		/* choose FNPLL */
+		while (!(val & FNPLL_HAS_LOCKED)) {
+			if (!time) {
+				dev_err(dev, "wait for pll_lock timeout\n");
+				return -EINVAL;
+			}
+			time--;
+			udelay(1);
+			val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+		}
+
+		hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_PCIEPL_BP,
+				       SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	} else {
+		hi3670_apb_phy_updatel(phy,
+				       PCIE_PHY_MMC1PLL_DISABLE,
+				       PCIE_PHY_MMC1PLL_DISABLE,
+				       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		hi3670_apb_phy_updatel(phy, PCIE_PHY_PCIEPL_BP,
+				       PCIE_PHY_PCIEPL_BP,
+				       SOC_PCIEPHY_MMC1PLL_CTRL20);
+	}
+
+	return 0;
+}
+
+static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	if (open)
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
+		regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
+			     IO_HP_DEBOUNCE_GT);
+	else
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_HP_DEBOUNCE_GT);
+}
+
+static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	if (open)
+		val &= ~IO_OE_HARD_GT_MODE; /* enable hard gt mode */
+	else
+		val |= IO_OE_HARD_GT_MODE; /* disable hard gt mode */
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+	/* disable soft gt mode */
+	regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, IO_PHYREF_SOFT_GT_MODE);
+}
+
+static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	/* set ie cfg */
+	val |= IO_IE_EN_HARD_BYPASS;
+
+	/* set oe cfg */
+	val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
+
+	/* set phy_debounce in&out time */
+	val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
+
+	/* select oe_gt_mode */
+	val |= IO_OE_GT_MODE;
+
+	if (en_flag)
+		val &= ~IO_OE_EN_HARD_BYPASS;
+	else
+		val |= IO_OE_EN_HARD_BYPASS;
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+}
+
+static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	if (open) {
+		regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR,
+			     SOC_PCIECTRL_CTRL21_DEFAULT);
+
+		hi3670_pcie_oe_ctrl(phy, true);
+
+		/* en hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val &= ~IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+	} else {
+		/* disable hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val |= IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+		hi3670_pcie_oe_ctrl(phy, false);
+	}
+}
+
+static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
+{
+	struct device *dev = phy->dev;
+	int ret = 0;
+
+	if (!clk_on)
+		goto close_clocks;
+
+	/* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
+	hi3670_apb_phy_updatel(phy, 0, PCIE_CLK_SOURCE,
+			       SOC_PCIEPHY_CTRL1_ADDR);
+
+	hi3670_pcie_pll_init(phy);
+
+	ret = hi3670_pcie_pll_ctrl(phy, true);
+	if (ret) {
+		dev_err(dev, "Failed to enable pll\n");
+		return -EINVAL;
+	}
+	hi3670_pcie_hp_debounce_gt(phy, true);
+	hi3670_pcie_phyref_gt(phy, true);
+	hi3670_pcie_ioref_gt(phy, true);
+
+	ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
+	if (ret) {
+		dev_err(dev, "Failed to set rate\n");
+		goto close_clocks;
+	}
+
+	return 0;
+
+close_clocks:
+	hi3670_pcie_ioref_gt(phy, false);
+	hi3670_pcie_phyref_gt(phy, false);
+	hi3670_pcie_hp_debounce_gt(phy, false);
+
+	hi3670_pcie_pll_ctrl(phy, false);
+
+	return ret;
+}
+
+static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	u32 time = PIPE_CLK_STABLE_TIME;
+	u32 pipe_clk_stable = PCIE_IS_CLOCK_STABLE;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	while (val & pipe_clk_stable) {
+		mdelay(1);
+		if (!time) {
+			dev_err(dev, "PIPE clk is not stable\n");
+			return false;
+		}
+		time--;
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	}
+
+	return true;
+}
+
+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 time = NOC_POWER_TIME;
+	unsigned int val = NOC_PW_MASK;
+	int rst;
+
+	if (enable)
+		val = NOC_PW_MASK | NOC_PW_SET_BIT;
+	else
+		val = NOC_PW_MASK;
+	rst = enable ? 1 : 0;
+
+	regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
+
+	time = NOC_POWER_TIME;
+	regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	while ((val & NOC_PW_SET_BIT) != rst) {
+		udelay(10);
+		if (!time) {
+			dev_err(dev, "Failed to reverse noc power-status\n");
+			return -EINVAL;
+		}
+		time--;
+		regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	}
+
+	return 0;
+}
+
+static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
+{
+	struct device_node *pcie_port;
+	struct device *dev = phy->dev;
+	struct device *pcie_dev;
+
+	pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
+	if (!pcie_port) {
+		dev_err(dev, "no pcie node found in %s\n",
+			dev->parent->of_node->full_name);
+		return -ENODEV;
+	}
+
+	pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
+	if (!pcie_dev) {
+		dev_err(dev, "Didn't find pcie device\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * We might just use NULL instead of the APB name, as the
+	 * pcie-kirin currently registers directly just one regmap (although
+	 * the DWC driver register other regmaps).
+	 *
+	 * Yet, it sounds safer to warrant that it will be accessing the
+	 * right regmap. So, let's use the named version.
+	 */
+	phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
+	if (!phy->apb) {
+		dev_err(dev, "Failed to get APB regmap\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto close_clk;
+
+	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->phy_ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->apb_sys_clk);
+	if (ret)
+		goto apb_sys_fail;
+
+	ret = clk_prepare_enable(phy->apb_phy_clk);
+	if (ret)
+		goto apb_phy_fail;
+
+	ret = clk_prepare_enable(phy->aclk);
+	if (ret)
+		goto aclk_fail;
+
+	ret = clk_prepare_enable(phy->aux_clk);
+	if (ret)
+		goto aux_clk_fail;
+
+	return 0;
+
+close_clk:
+	clk_disable_unprepare(phy->aux_clk);
+aux_clk_fail:
+	clk_disable_unprepare(phy->aclk);
+aclk_fail:
+	clk_disable_unprepare(phy->apb_phy_clk);
+apb_phy_fail:
+	clk_disable_unprepare(phy->apb_sys_clk);
+apb_sys_fail:
+	clk_disable_unprepare(phy->phy_ref_clk);
+
+	return ret;
+}
+
+static int hi3670_pcie_phy_init(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int ret;
+
+	/*
+	 * The code under hi3670_pcie_get_resources_from_pcie() need to
+	 * access the reset-gpios and the APB registers, both from the
+	 * pcie-kirin driver.
+	 *
+	 * The APB is obtained via the pcie driver's regmap
+	 * Such kind of resource can only be obtained during the PCIe
+	 * power_on sequence, as the code inside pcie-kirin needs to
+	 * be already probed, as it needs to register the APB regmap.
+	 */
+
+	ret = hi3670_pcie_get_resources_from_pcie(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int val, ret;
+
+	/* Power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
+	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
+
+	hi3670_pcie_phy_oe_enable(phy, true);
+
+	ret = kirin_pcie_clk_ctrl(phy, true);
+	if (ret)
+		return ret;
+
+	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
+	regmap_write(phy->crgctrl, CRGCTRL_PCIE_ASSERT_OFFSET,
+		     CRGCTRL_PCIE_ASSERT_BIT);
+	regmap_write(phy->sysctrl, SCTRL_PCIE_HPCLK_OFFSET,
+		     SCTRL_PCIE_HPCLK_BIT);
+
+	hi3670_pcie_natural_cfg(phy);
+
+	ret = hi3670_pcie_allclk_ctrl(phy, true);
+	if (ret)
+		goto disable_clks;
+
+	/* pull down phy_test_powerdown signal */
+	hi3670_apb_phy_updatel(phy, 0, PCIE_PULL_DOWN_PHY_TEST_POWERDOWN,
+			      SOC_PCIEPHY_CTRL0_ADDR);
+
+	/* deassert controller perst_n */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val |= PCIE_DEASSERT_CONTROLLER_PERST;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+	udelay(10);
+
+	ret = is_pipe_clk_stable(phy);
+	if (!ret)
+		goto disable_clks;
+
+	hi3670_pcie_set_eyeparam(phy);
+
+	ret = hi3670_pcie_noc_power(phy, false);
+	if (ret)
+		goto disable_clks;
+
+	return 0;
+
+disable_clks:
+	kirin_pcie_clk_ctrl(phy, false);
+	return ret;
+}
+
+static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+
+	hi3670_pcie_phy_oe_enable(phy, false);
+
+	hi3670_pcie_allclk_ctrl(phy, false);
+
+	/* Drop power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
+
+	/*
+	 * FIXME: The enabled clocks should be disabled here by calling
+	 * kirin_pcie_clk_ctrl(phy, false);
+	 * However, some clocks used at Kirin 970 should be marked as
+	 * CLK_IS_CRITICAL at clk-hi3670 driver, as powering such clocks off
+	 * cause an Asynchronous SError interrupt, which produces panic().
+	 * While clk-hi3670 is not fixed, we cannot risk disabling clocks here.
+	 */
+
+	return 0;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+	.init		= hi3670_pcie_phy_init,
+	.power_on	= hi3670_pcie_phy_power_on,
+	.power_off	= hi3670_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
+					 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* syscon */
+	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
+	if (IS_ERR(phy->crgctrl))
+		return PTR_ERR(phy->crgctrl);
+
+	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	/* clocks */
+	phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
+	if (IS_ERR(phy->phy_ref_clk))
+		return PTR_ERR(phy->phy_ref_clk);
+
+	phy->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(phy->aux_clk))
+		return PTR_ERR(phy->aux_clk);
+
+	phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
+	if (IS_ERR(phy->apb_phy_clk))
+		return PTR_ERR(phy->apb_phy_clk);
+
+	phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
+	if (IS_ERR(phy->apb_sys_clk))
+		return PTR_ERR(phy->apb_sys_clk);
+
+	phy->aclk = devm_clk_get(dev, "aclk");
+	if (IS_ERR(phy->aclk))
+		return PTR_ERR(phy->aclk);
+
+	/* registers */
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	hi3670_pcie_get_eyeparam(phy);
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct hi3670_pcie_phy *phy;
+	struct phy *generic_phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+
+	ret = hi3670_pcie_phy_get_resources(phy, pdev);
+	if (ret)
+		return ret;
+
+	generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_pcie_phy_match[] = {
+	{
+		.compatible = "hisilicon,hi970-pcie-phy",
+	},
+	{},
+};
+
+static struct platform_driver hi3670_pcie_phy_driver = {
+	.probe	= hi3670_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= hi3670_pcie_phy_match,
+		.name		= "hi3670_pcie_phy",
+		.suppress_bind_attrs = true,
+	}
+};
+builtin_platform_driver(hi3670_pcie_phy_driver);
+
+MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
+MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab at kernel.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <mani at kernel.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1




From cgel.zte at gmail.com  Thu Aug 19 19:46:33 2021
From: cgel.zte at gmail.com (jing yangyang)
Date: Thu, 19 Aug 2021 19:46:33 -0700
Subject: [PATCH linux-next] phy/tegra: add put_device() after
 of_find_device_by_node()
Message-ID: <20210820024633.11757-1-jing.yangyang@zte.com.cn>

This was found by coccicheck:
./drivers/phy/tegra/xusb-tegra210.c:3174: 2-8:ERROR:
missing put_device;call of_find_device_by_node on line 3167,
but without a corresponding object release within this function.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
---
 drivers/phy/tegra/xusb-tegra210.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
index eedfc7c..f26eb5a 100644
--- a/drivers/phy/tegra/xusb-tegra210.c
+++ b/drivers/phy/tegra/xusb-tegra210.c
@@ -3170,8 +3170,10 @@ static int tegra210_utmi_port_reset(struct phy *phy)
 		goto out;
 	}
 
-	if (!platform_get_drvdata(pdev))
+	if (!platform_get_drvdata(pdev)) {
+		put_device(&pdev->dev);
 		return ERR_PTR(-EPROBE_DEFER);
+	}
 
 	padctl->regmap = dev_get_regmap(&pdev->dev, "usb_sleepwalk");
 	if (!padctl->regmap)
-- 
1.8.3.1




From thierry.reding at gmail.com  Fri Aug 20 04:34:24 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 20 Aug 2021 13:34:24 +0200
Subject: [PATCH linux-next] phy/tegra: add put_device() after
 of_find_device_by_node()
In-Reply-To: <20210820024633.11757-1-jing.yangyang@zte.com.cn>
References: <20210820024633.11757-1-jing.yangyang@zte.com.cn>
Message-ID: <YR+TQP3wWV+91fn2@orome.fritz.box>

On Thu, Aug 19, 2021 at 07:46:33PM -0700, jing yangyang wrote:
> This was found by coccicheck:
> ./drivers/phy/tegra/xusb-tegra210.c:3174: 2-8:ERROR:
> missing put_device;call of_find_device_by_node on line 3167,
> but without a corresponding object release within this function.
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
> ---
>  drivers/phy/tegra/xusb-tegra210.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
> index eedfc7c..f26eb5a 100644
> --- a/drivers/phy/tegra/xusb-tegra210.c
> +++ b/drivers/phy/tegra/xusb-tegra210.c
> @@ -3170,8 +3170,10 @@ static int tegra210_utmi_port_reset(struct phy *phy)
>  		goto out;
>  	}
>  
> -	if (!platform_get_drvdata(pdev))
> +	if (!platform_get_drvdata(pdev)) {
> +		put_device(&pdev->dev);
>  		return ERR_PTR(-EPROBE_DEFER);
> +	}
>  
>  	padctl->regmap = dev_get_regmap(&pdev->dev, "usb_sleepwalk");
>  	if (!padctl->regmap)

I think we also need that put_device() after getting the regmap because
we loose the reference to the platform device after that.

On the other hand, I suppose we might have to hang on to the reference
until tegra210_xusb_padctl_remove() so that the platform device that the
regmap is provided by doesn't suddenly go away.

Mark, I couldn't find how the lifetime of regmaps is getting tracked.
dev_get_regmap() seems to only return a pointer to the regmap if it
exists, but doesn't actually increment a reference or anything. So do we
need to hold on to the struct device that we get it from until we no
longer need the reference? Or is there some other way to make sure the
regmap doesn't disappear on us?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20210820/e94eac9a/attachment.sig>

From mchehab+huawei at kernel.org  Fri Aug 20 06:43:49 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Fri, 20 Aug 2021 15:43:49 +0200
Subject: [PATCH v13] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
In-Reply-To: <YRzjBOGsehbHAGJv@matsya>
References: <YRzjBOGsehbHAGJv@matsya>
Message-ID: <2272f7c5be332b089ad8dd1b4e7eca3c17a617f7.1629466922.git.mchehab+huawei@kernel.org>

The Kirin 970 PHY is somewhat similar to the Kirin 960, but it
does a lot more. Add the needed bits for PCIe to start working on
HiKey 970 boards.

Co-developed-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---

PS.:
   As the PCIe patches aren't untouched, I'm sending just the PHY
   driver patch on v12.

v13:
  - add missing include bitfield.h

v12:
  - removed c99-style comments;
  - added hi3670_apb_phy_updatel() to update bits;
  - allowed a couple of lines to be bigger than 80 columns.


 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 862 ++++++++++++++++++++++++
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 4d008cfc279c..d3b92c288554 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -33,6 +33,16 @@ config PHY_HI3670_USB
 
 	  To compile this driver as a module, choose M here.
 
+config PHY_HI3670_PCIE
+	tristate "hi3670 PCIe PHY support"
+	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+	select GENERIC_PHY
+	select MFD_SYSCON
+	help
+	  Enable this to support the HiSilicon hi3670 PCIe PHY.
+
+	  To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
 	tristate "HiSilicon STB SoCs COMBPHY support"
 	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 51729868145b..4029d3813b1e 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_HI6220_USB)		+= phy-hi6220-usb.o
 obj-$(CONFIG_PHY_HI3660_USB)		+= phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HI3670_USB)		+= phy-hi3670-usb3.o
+obj-$(CONFIG_PHY_HI3670_PCIE)		+= phy-hi3670-pcie.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)		+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)	+= phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
new file mode 100644
index 000000000000..7403484f7141
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -0,0 +1,862 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe phy driver for Kirin 970
+ *
+ * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
+ *		https://www.huawei.com
+ * Copyright (C) 2021 Huawei Technologies Co., Ltd.
+ *		https://www.huawei.com
+ *
+ * Authors:
+ *	Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+ *	Manivannan Sadhasivam <mani at kernel.org>
+ *
+ * Based on:
+ *	https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei at kernel.org/
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AXI_CLK_FREQ				207500000
+#define REF_CLK_FREQ				100000000
+
+/* PCIe CTRL registers */
+#define SOC_PCIECTRL_CTRL0_ADDR			0x000
+#define SOC_PCIECTRL_CTRL1_ADDR			0x004
+#define SOC_PCIECTRL_CTRL7_ADDR			0x01c
+#define SOC_PCIECTRL_CTRL12_ADDR		0x030
+#define SOC_PCIECTRL_CTRL20_ADDR		0x050
+#define SOC_PCIECTRL_CTRL21_ADDR		0x054
+#define SOC_PCIECTRL_STATE0_ADDR		0x400
+
+#define PCIE_OUTPUT_PULL_BITS			GENMASK(3, 0)
+#define SOC_PCIECTRL_CTRL20_2P_MEM_CTRL		0x02605550
+#define SOC_PCIECTRL_CTRL21_DEFAULT		0x20000070
+#define PCIE_PULL_UP_SYS_AUX_PWR_DET		BIT(10)
+#define PCIE_OUTPUT_PULL_DOWN			BIT(1)
+
+/* PCIe PHY registers */
+#define SOC_PCIEPHY_CTRL0_ADDR			0x000
+#define SOC_PCIEPHY_CTRL1_ADDR			0x004
+#define SOC_PCIEPHY_CTRL2_ADDR			0x008
+#define SOC_PCIEPHY_CTRL3_ADDR			0x00c
+#define SOC_PCIEPHY_CTRL38_ADDR			0x0098
+#define SOC_PCIEPHY_STATE0_ADDR			0x400
+
+#define PORT_MSI_CTRL_ADDR			0x820
+#define PORT_MSI_CTRL_UPPER_ADDR		0x824
+#define PORT_MSI_CTRL_INT0_ENABLE		0x828
+
+#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1	0xc004
+#define SUP_DIG_LVL_OVRD_IN			0x003c
+#define LANEN_DIG_ASIC_TX_OVRD_IN_1		0x4008
+#define LANEN_DIG_ASIC_TX_OVRD_IN_2		0x400c
+
+#define PCIE_LINKUP_ENABLE			0x8020
+#define PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
+#define PCIE_LTSSM_ENABLE_BIT			BIT(11)
+#define PCIEPHY_RESET_BIT			BIT(17)
+#define PCIEPHY_PIPE_LINE0_RESET_BIT		BIT(19)
+#define PCIE_TXDETECT_RX_FAIL			BIT(2)
+#define PCIE_CLK_SOURCE				BIT(8)
+#define PCIE_IS_CLOCK_STABLE			BIT(19)
+#define PCIE_PULL_DOWN_PHY_TEST_POWERDOWN	BIT(22)
+#define PCIE_DEASSERT_CONTROLLER_PERST		BIT(2)
+
+#define EYEPARAM_NOCFG				0xffffffff
+#define EYE_PARM0_MASK				GENMASK(8, 6)
+#define EYE_PARM1_MASK				GENMASK(11, 8)
+#define EYE_PARM2_MASK				GENMASK(5, 0)
+#define EYE_PARM3_MASK				GENMASK(12, 7)
+#define EYE_PARM4_MASK				GENMASK(14, 9)
+#define EYE_PARM0_EN				BIT(9)
+#define EYE_PARM1_EN				BIT(12)
+#define EYE_PARM2_EN				BIT(6)
+#define EYE_PARM3_EN				BIT(13)
+#define EYE_PARM4_EN				BIT(15)
+
+/* hi3670 pciephy register */
+#define APB_PHY_START_ADDR			0x40000
+#define SOC_PCIEPHY_MMC1PLL_CTRL1		0xc04
+#define SOC_PCIEPHY_MMC1PLL_CTRL16		0xC40
+#define SOC_PCIEPHY_MMC1PLL_CTRL17		0xC44
+#define SOC_PCIEPHY_MMC1PLL_CTRL20		0xC50
+#define SOC_PCIEPHY_MMC1PLL_CTRL21		0xC54
+#define SOC_PCIEPHY_MMC1PLL_STAT0		0xE00
+
+#define CRGPERIPH_PEREN12			0x470
+#define CRGPERIPH_PERDIS12			0x474
+#define CRGPERIPH_PCIECTRL0			0x800
+
+#define PCIE_FNPLL_FBDIV_MASK			GENMASK(27, 16)
+#define PCIE_FNPLL_FRACDIV_MASK			GENMASK(23, 0)
+#define PCIE_FNPLL_POSTDIV1_MASK		GENMASK(10, 8)
+#define PCIE_FNPLL_POSTDIV2_MASK		GENMASK(14, 12)
+#define PCIE_FNPLL_PLL_MODE_MASK		BIT(25)
+
+#define PCIE_FNPLL_DLL_EN			BIT(27)
+#define PCIE_FNPLL_FBDIV			0xd0
+#define PCIE_FNPLL_FRACDIV			0x555555
+#define PCIE_FNPLL_POSTDIV1			0x5
+#define PCIE_FNPLL_POSTDIV2			0x4
+#define PCIE_FNPLL_PLL_MODE			0x0
+
+#define PCIE_PHY_MMC1PLL			0x20
+#define PCIE_PHY_CHOOSE_FNPLL			BIT(27)
+#define PCIE_PHY_MMC1PLL_DISABLE		BIT(0)
+#define PCIE_PHY_PCIEPL_BP			BIT(16)
+
+/* define ie,oe cfg */
+#define IO_OE_HARD_GT_MODE			BIT(1)
+#define IO_IE_EN_HARD_BYPASS			BIT(27)
+#define IO_OE_EN_HARD_BYPASS			BIT(11)
+#define IO_HARD_CTRL_DEBOUNCE_BYPASS		BIT(10)
+#define IO_OE_GT_MODE				BIT(8)
+#define DEBOUNCE_WAITCFG_IN			GENMASK(23, 20)
+#define DEBOUNCE_WAITCFG_OUT			GENMASK(16, 13)
+
+#define IO_HP_DEBOUNCE_GT			(BIT(12) | BIT(15))
+#define IO_PHYREF_SOFT_GT_MODE			BIT(14)
+#define IO_REF_SOFT_GT_MODE			BIT(13)
+#define IO_REF_HARD_GT_MODE			BIT(0)
+
+/* noc power domain */
+#define NOC_POWER_IDLEREQ_1			0x38c
+#define NOC_POWER_IDLE_1			0x394
+#define NOC_PW_MASK				0x10000
+#define NOC_PW_SET_BIT				0x1
+
+#define NUM_EYEPARAM				5
+
+/* info located in sysctrl */
+#define SCTRL_PCIE_CMOS_OFFSET			0x60
+#define SCTRL_PCIE_CMOS_BIT			0x10
+#define SCTRL_PCIE_ISO_OFFSET			0x44
+#define SCTRL_PCIE_ISO_BIT			0x30
+#define SCTRL_PCIE_HPCLK_OFFSET			0x190
+#define SCTRL_PCIE_HPCLK_BIT			0x184000
+#define SCTRL_PCIE_OE_OFFSET			0x14a
+#define PCIE_DEBOUNCE_PARAM			0xf0f400
+#define PCIE_OE_BYPASS				GENMASK(29, 28)
+
+/* peri_crg ctrl */
+#define CRGCTRL_PCIE_ASSERT_OFFSET		0x88
+#define CRGCTRL_PCIE_ASSERT_BIT			0x8c000000
+
+#define FNPLL_HAS_LOCKED			BIT(4)
+
+/* Time for delay */
+#define PIPE_CLK_WAIT_MIN	550
+#define PIPE_CLK_WAIT_MAX	600
+#define TIME_CMOS_MIN		100
+#define TIME_CMOS_MAX		105
+#define TIME_PHY_PD_MIN		10
+#define TIME_PHY_PD_MAX		11
+
+#define PIPE_CLK_STABLE_TIME	100
+#define PLL_CTRL_WAIT_TIME	200
+#define NOC_POWER_TIME		100
+
+struct hi3670_pcie_phy {
+	struct device	*dev;
+	void __iomem	*base;
+	struct regmap	*apb;
+	struct regmap	*crgctrl;
+	struct regmap	*sysctrl;
+	struct regmap	*pmctrl;
+	struct clk	*apb_sys_clk;
+	struct clk	*apb_phy_clk;
+	struct clk	*phy_ref_clk;
+	struct clk	*aclk;
+	struct clk	*aux_clk;
+	u32		eye_param[NUM_EYEPARAM];
+};
+
+/* Registers in PCIePHY */
+static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy, u32 val,
+					 u32 reg)
+{
+	writel(val, phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
+{
+	return readl(phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline void hi3670_apb_phy_updatel(struct hi3670_pcie_phy *phy,
+					  u32 val, u32 mask, u32 reg)
+{
+	u32 regval;
+
+	regval = hi3670_apb_phy_readl(phy, reg);
+	regval &= ~mask;
+	regval |= val;
+	hi3670_apb_phy_writel(phy, regval, reg);
+}
+
+static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
+						u32 val, u32 reg)
+{
+	writel(val, phy->base + reg);
+}
+
+static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
+					      u32 reg)
+{
+	return readl(phy->base + reg);
+}
+
+static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
+{
+	u32 val;
+
+	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
+	val |= PCIE_DEBOUNCE_PARAM;
+	if (enable)
+		val &= ~PCIE_OE_BYPASS;
+	else
+		val |= PCIE_OE_BYPASS;
+	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
+}
+
+static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np;
+	int ret, i;
+
+	np = dev->of_node;
+
+	ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
+					 phy->eye_param, NUM_EYEPARAM);
+	if (!ret)
+		return;
+
+	/* There's no optional eye_param property. Set array to default */
+	for (i = 0; i < NUM_EYEPARAM; i++)
+		phy->eye_param[i] = EYEPARAM_NOCFG;
+}
+
+static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = kirin_apb_natural_phy_readl(phy, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM1_MASK;
+		val |= FIELD_PREP(EYE_PARM1_MASK, phy->eye_param[1]);
+		val |= EYE_PARM1_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val,
+				     RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+	val &= ~(EYE_PARM2_MASK | EYE_PARM3_MASK);
+	if (phy->eye_param[2] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM2_MASK, phy->eye_param[2]);
+		val |= EYE_PARM2_EN;
+	}
+
+	if (phy->eye_param[3] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM3_MASK, phy->eye_param[3]);
+		val |= EYE_PARM3_EN;
+	}
+
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+
+	val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
+	if (phy->eye_param[0] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM0_MASK;
+		val |= FIELD_PREP(EYE_PARM0_MASK, phy->eye_param[0]);
+		val |= EYE_PARM0_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+	if (phy->eye_param[4] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM4_MASK;
+		val |= FIELD_PREP(EYE_PARM4_MASK, phy->eye_param[4]);
+		val |= EYE_PARM4_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+}
+
+static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* change 2p mem_ctrl */
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
+		     SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
+
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
+	val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
+
+	/* output, pull down */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val &= ~PCIE_OUTPUT_PULL_BITS;
+	val |= PCIE_OUTPUT_PULL_DOWN;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+
+	/* Handle phy_reset and lane0_reset to HW */
+	hi3670_apb_phy_updatel(phy, PCIEPHY_RESET_BIT,
+			       PCIEPHY_PIPE_LINE0_RESET_BIT | PCIEPHY_RESET_BIT,
+			       SOC_PCIEPHY_CTRL1_ADDR);
+
+	/* fix chip bug: TxDetectRx fail */
+	hi3670_apb_phy_updatel(phy, PCIE_TXDETECT_RX_FAIL, PCIE_TXDETECT_RX_FAIL,
+			       SOC_PCIEPHY_CTRL38_ADDR);
+}
+
+static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
+{
+	hi3670_apb_phy_updatel(phy, PCIE_PHY_CHOOSE_FNPLL, PCIE_PHY_CHOOSE_FNPLL,
+			       SOC_PCIEPHY_MMC1PLL_CTRL1);
+
+
+	hi3670_apb_phy_updatel(phy,
+			       FIELD_PREP(PCIE_FNPLL_FBDIV_MASK, PCIE_FNPLL_FBDIV),
+			       PCIE_FNPLL_FBDIV_MASK,
+			       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+	hi3670_apb_phy_updatel(phy,
+			       FIELD_PREP(PCIE_FNPLL_FRACDIV_MASK, PCIE_FNPLL_FRACDIV),
+			       PCIE_FNPLL_FRACDIV_MASK, SOC_PCIEPHY_MMC1PLL_CTRL17);
+
+	hi3670_apb_phy_updatel(phy,
+			       PCIE_FNPLL_DLL_EN |
+			       FIELD_PREP(PCIE_FNPLL_POSTDIV1_MASK, PCIE_FNPLL_POSTDIV1) |
+			       FIELD_PREP(PCIE_FNPLL_POSTDIV2_MASK, PCIE_FNPLL_POSTDIV2) |
+			       FIELD_PREP(PCIE_FNPLL_PLL_MODE_MASK, PCIE_FNPLL_PLL_MODE),
+			       PCIE_FNPLL_POSTDIV1_MASK |
+			       PCIE_FNPLL_POSTDIV2_MASK |
+			       PCIE_FNPLL_PLL_MODE_MASK | PCIE_FNPLL_DLL_EN,
+			       SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	hi3670_apb_phy_writel(phy, PCIE_PHY_MMC1PLL,
+			      SOC_PCIEPHY_MMC1PLL_CTRL21);
+}
+
+static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int time = PLL_CTRL_WAIT_TIME;
+
+	if (enable) {
+		/* pd = 0 */
+		hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_MMC1PLL_DISABLE,
+				       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		/* choose FNPLL */
+		while (!(val & FNPLL_HAS_LOCKED)) {
+			if (!time) {
+				dev_err(dev, "wait for pll_lock timeout\n");
+				return -EINVAL;
+			}
+			time--;
+			udelay(1);
+			val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+		}
+
+		hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_PCIEPL_BP,
+				       SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	} else {
+		hi3670_apb_phy_updatel(phy,
+				       PCIE_PHY_MMC1PLL_DISABLE,
+				       PCIE_PHY_MMC1PLL_DISABLE,
+				       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		hi3670_apb_phy_updatel(phy, PCIE_PHY_PCIEPL_BP,
+				       PCIE_PHY_PCIEPL_BP,
+				       SOC_PCIEPHY_MMC1PLL_CTRL20);
+	}
+
+	return 0;
+}
+
+static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	if (open)
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
+		regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
+			     IO_HP_DEBOUNCE_GT);
+	else
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_HP_DEBOUNCE_GT);
+}
+
+static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	if (open)
+		val &= ~IO_OE_HARD_GT_MODE; /* enable hard gt mode */
+	else
+		val |= IO_OE_HARD_GT_MODE; /* disable hard gt mode */
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+	/* disable soft gt mode */
+	regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, IO_PHYREF_SOFT_GT_MODE);
+}
+
+static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	/* set ie cfg */
+	val |= IO_IE_EN_HARD_BYPASS;
+
+	/* set oe cfg */
+	val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
+
+	/* set phy_debounce in&out time */
+	val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
+
+	/* select oe_gt_mode */
+	val |= IO_OE_GT_MODE;
+
+	if (en_flag)
+		val &= ~IO_OE_EN_HARD_BYPASS;
+	else
+		val |= IO_OE_EN_HARD_BYPASS;
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+}
+
+static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	if (open) {
+		regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR,
+			     SOC_PCIECTRL_CTRL21_DEFAULT);
+
+		hi3670_pcie_oe_ctrl(phy, true);
+
+		/* en hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val &= ~IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+	} else {
+		/* disable hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val |= IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+		hi3670_pcie_oe_ctrl(phy, false);
+	}
+}
+
+static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
+{
+	struct device *dev = phy->dev;
+	int ret = 0;
+
+	if (!clk_on)
+		goto close_clocks;
+
+	/* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
+	hi3670_apb_phy_updatel(phy, 0, PCIE_CLK_SOURCE,
+			       SOC_PCIEPHY_CTRL1_ADDR);
+
+	hi3670_pcie_pll_init(phy);
+
+	ret = hi3670_pcie_pll_ctrl(phy, true);
+	if (ret) {
+		dev_err(dev, "Failed to enable pll\n");
+		return -EINVAL;
+	}
+	hi3670_pcie_hp_debounce_gt(phy, true);
+	hi3670_pcie_phyref_gt(phy, true);
+	hi3670_pcie_ioref_gt(phy, true);
+
+	ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
+	if (ret) {
+		dev_err(dev, "Failed to set rate\n");
+		goto close_clocks;
+	}
+
+	return 0;
+
+close_clocks:
+	hi3670_pcie_ioref_gt(phy, false);
+	hi3670_pcie_phyref_gt(phy, false);
+	hi3670_pcie_hp_debounce_gt(phy, false);
+
+	hi3670_pcie_pll_ctrl(phy, false);
+
+	return ret;
+}
+
+static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	u32 time = PIPE_CLK_STABLE_TIME;
+	u32 pipe_clk_stable = PCIE_IS_CLOCK_STABLE;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	while (val & pipe_clk_stable) {
+		mdelay(1);
+		if (!time) {
+			dev_err(dev, "PIPE clk is not stable\n");
+			return false;
+		}
+		time--;
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	}
+
+	return true;
+}
+
+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 time = NOC_POWER_TIME;
+	unsigned int val = NOC_PW_MASK;
+	int rst;
+
+	if (enable)
+		val = NOC_PW_MASK | NOC_PW_SET_BIT;
+	else
+		val = NOC_PW_MASK;
+	rst = enable ? 1 : 0;
+
+	regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
+
+	time = NOC_POWER_TIME;
+	regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	while ((val & NOC_PW_SET_BIT) != rst) {
+		udelay(10);
+		if (!time) {
+			dev_err(dev, "Failed to reverse noc power-status\n");
+			return -EINVAL;
+		}
+		time--;
+		regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	}
+
+	return 0;
+}
+
+static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
+{
+	struct device_node *pcie_port;
+	struct device *dev = phy->dev;
+	struct device *pcie_dev;
+
+	pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
+	if (!pcie_port) {
+		dev_err(dev, "no pcie node found in %s\n",
+			dev->parent->of_node->full_name);
+		return -ENODEV;
+	}
+
+	pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
+	if (!pcie_dev) {
+		dev_err(dev, "Didn't find pcie device\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * We might just use NULL instead of the APB name, as the
+	 * pcie-kirin currently registers directly just one regmap (although
+	 * the DWC driver register other regmaps).
+	 *
+	 * Yet, it sounds safer to warrant that it will be accessing the
+	 * right regmap. So, let's use the named version.
+	 */
+	phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
+	if (!phy->apb) {
+		dev_err(dev, "Failed to get APB regmap\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto close_clk;
+
+	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->phy_ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->apb_sys_clk);
+	if (ret)
+		goto apb_sys_fail;
+
+	ret = clk_prepare_enable(phy->apb_phy_clk);
+	if (ret)
+		goto apb_phy_fail;
+
+	ret = clk_prepare_enable(phy->aclk);
+	if (ret)
+		goto aclk_fail;
+
+	ret = clk_prepare_enable(phy->aux_clk);
+	if (ret)
+		goto aux_clk_fail;
+
+	return 0;
+
+close_clk:
+	clk_disable_unprepare(phy->aux_clk);
+aux_clk_fail:
+	clk_disable_unprepare(phy->aclk);
+aclk_fail:
+	clk_disable_unprepare(phy->apb_phy_clk);
+apb_phy_fail:
+	clk_disable_unprepare(phy->apb_sys_clk);
+apb_sys_fail:
+	clk_disable_unprepare(phy->phy_ref_clk);
+
+	return ret;
+}
+
+static int hi3670_pcie_phy_init(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int ret;
+
+	/*
+	 * The code under hi3670_pcie_get_resources_from_pcie() need to
+	 * access the reset-gpios and the APB registers, both from the
+	 * pcie-kirin driver.
+	 *
+	 * The APB is obtained via the pcie driver's regmap
+	 * Such kind of resource can only be obtained during the PCIe
+	 * power_on sequence, as the code inside pcie-kirin needs to
+	 * be already probed, as it needs to register the APB regmap.
+	 */
+
+	ret = hi3670_pcie_get_resources_from_pcie(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int val, ret;
+
+	/* Power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
+	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
+
+	hi3670_pcie_phy_oe_enable(phy, true);
+
+	ret = kirin_pcie_clk_ctrl(phy, true);
+	if (ret)
+		return ret;
+
+	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
+	regmap_write(phy->crgctrl, CRGCTRL_PCIE_ASSERT_OFFSET,
+		     CRGCTRL_PCIE_ASSERT_BIT);
+	regmap_write(phy->sysctrl, SCTRL_PCIE_HPCLK_OFFSET,
+		     SCTRL_PCIE_HPCLK_BIT);
+
+	hi3670_pcie_natural_cfg(phy);
+
+	ret = hi3670_pcie_allclk_ctrl(phy, true);
+	if (ret)
+		goto disable_clks;
+
+	/* pull down phy_test_powerdown signal */
+	hi3670_apb_phy_updatel(phy, 0, PCIE_PULL_DOWN_PHY_TEST_POWERDOWN,
+			      SOC_PCIEPHY_CTRL0_ADDR);
+
+	/* deassert controller perst_n */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val |= PCIE_DEASSERT_CONTROLLER_PERST;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+	udelay(10);
+
+	ret = is_pipe_clk_stable(phy);
+	if (!ret)
+		goto disable_clks;
+
+	hi3670_pcie_set_eyeparam(phy);
+
+	ret = hi3670_pcie_noc_power(phy, false);
+	if (ret)
+		goto disable_clks;
+
+	return 0;
+
+disable_clks:
+	kirin_pcie_clk_ctrl(phy, false);
+	return ret;
+}
+
+static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+
+	hi3670_pcie_phy_oe_enable(phy, false);
+
+	hi3670_pcie_allclk_ctrl(phy, false);
+
+	/* Drop power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
+
+	/*
+	 * FIXME: The enabled clocks should be disabled here by calling
+	 * kirin_pcie_clk_ctrl(phy, false);
+	 * However, some clocks used at Kirin 970 should be marked as
+	 * CLK_IS_CRITICAL at clk-hi3670 driver, as powering such clocks off
+	 * cause an Asynchronous SError interrupt, which produces panic().
+	 * While clk-hi3670 is not fixed, we cannot risk disabling clocks here.
+	 */
+
+	return 0;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+	.init		= hi3670_pcie_phy_init,
+	.power_on	= hi3670_pcie_phy_power_on,
+	.power_off	= hi3670_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
+					 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* syscon */
+	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
+	if (IS_ERR(phy->crgctrl))
+		return PTR_ERR(phy->crgctrl);
+
+	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	/* clocks */
+	phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
+	if (IS_ERR(phy->phy_ref_clk))
+		return PTR_ERR(phy->phy_ref_clk);
+
+	phy->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(phy->aux_clk))
+		return PTR_ERR(phy->aux_clk);
+
+	phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
+	if (IS_ERR(phy->apb_phy_clk))
+		return PTR_ERR(phy->apb_phy_clk);
+
+	phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
+	if (IS_ERR(phy->apb_sys_clk))
+		return PTR_ERR(phy->apb_sys_clk);
+
+	phy->aclk = devm_clk_get(dev, "aclk");
+	if (IS_ERR(phy->aclk))
+		return PTR_ERR(phy->aclk);
+
+	/* registers */
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	hi3670_pcie_get_eyeparam(phy);
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct hi3670_pcie_phy *phy;
+	struct phy *generic_phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+
+	ret = hi3670_pcie_phy_get_resources(phy, pdev);
+	if (ret)
+		return ret;
+
+	generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_pcie_phy_match[] = {
+	{
+		.compatible = "hisilicon,hi970-pcie-phy",
+	},
+	{},
+};
+
+static struct platform_driver hi3670_pcie_phy_driver = {
+	.probe	= hi3670_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= hi3670_pcie_phy_match,
+		.name		= "hi3670_pcie_phy",
+		.suppress_bind_attrs = true,
+	}
+};
+builtin_platform_driver(hi3670_pcie_phy_driver);
+
+MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
+MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab at kernel.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <mani at kernel.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1




From p.yadav at ti.com  Fri Aug 20 12:03:40 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:40 +0530
Subject: [PATCH v4 0/6] Rx mode support for Cadence DPHY
Message-ID: <20210820190346.18550-1-p.yadav@ti.com>

Hi,

This series adds support for Rx mode on Cadence DPHY driver. It has been
split off from [0] to facilitate easier merging. I have still kept the
version number to maintain continuity with the previous patches. This
series also includes conversion to YAML binding.

Tested on TI's J721E with OV5640 sensor.

[0] https://patchwork.linuxtv.org/project/linux-media/list/?series=5526&state=%2A&archive=both

Changes in v4:
- Instead of having both Rx and Tx modes in the same driver data, keep
  them separate since the op selection is based on compatible now. For
  that reason, the cdns_dphy_driver_data struct is no longer needed.
- Rename ref_dphy_ops to tx_ref_dphy_ops to clarify their purpose.
- Drop submode checks in validate() hook.
- Drop the submode parts. Use a different compatible for the Rx ops.
- Make bands and num_bands static.

Changes in v3:
- Use a table to select the band.
- Use a table to poll the data lane ready bits.
- Multiply the DPHY HS clock rate by 2 to get the bit rate since the
  clock is DDR.
- Add Rob's R-by.

Changes in v2:
- Drop reg description.
- Add a description for each DPHY clock.
- Rename dphy at ... to phy at ... in example.
- Add Laurent's R-by.
- Re-order subject prefixes.
- Re-order subject prefixes.
- Add power-domain to the example.
- Add Laurent's R-by.
- Re-order subject prefixes.

Pratyush Yadav (6):
  phy: cdns-dphy: Prepare for Rx support
  phy: cdns-dphy: Add Rx support
  phy: dt-bindings: Convert Cadence DPHY binding to YAML
  phy: dt-bindings: cdns,dphy: make clocks optional
  phy: dt-bindings: cdns,dphy: add power-domains property
  phy: dt-bindings: cdns,dphy: add Rx DPHY compatible

 .../devicetree/bindings/phy/cdns,dphy.txt     |  20 --
 .../devicetree/bindings/phy/cdns,dphy.yaml    |  55 ++++
 drivers/phy/cadence/cdns-dphy.c               | 294 +++++++++++++++---
 3 files changed, 313 insertions(+), 56 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml

--
2.30.0



From p.yadav at ti.com  Fri Aug 20 12:03:41 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:41 +0530
Subject: [PATCH v4 1/6] phy: cdns-dphy: Prepare for Rx support
In-Reply-To: <20210820190346.18550-1-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
Message-ID: <20210820190346.18550-2-p.yadav@ti.com>

The Rx programming sequence differs from the Tx programming sequence.
Currently only Tx mode is supported. For example, the power on and off,
validation, and configuration procedures are all different between Rx
and Tx DPHYs. Currently they are only written from a Tx point of view
and they won't work with an Rx DPHY. Move them to cdns_dphy_ops so they
can be defined by the implementation, accommodating both Rx and Tx mode
DPHYs.

The clocks "psm" and "pll_ref" are not used by the Rx path so make them
optional in the probe and then check if they exist in the Tx power_on()
hook.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>

---

Changes in v4:
- Instead of having both Rx and Tx modes in the same driver data, keep
  them separate since the op selection is based on compatible now. For
  that reason, the cdns_dphy_driver_data struct is no longer needed.
- Rename ref_dphy_ops to tx_ref_dphy_ops to clarify their purpose.
- Drop submode checks in validate() hook.

 drivers/phy/cadence/cdns-dphy.c | 123 ++++++++++++++++++++++----------
 1 file changed, 87 insertions(+), 36 deletions(-)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index ba042e39cfaf..0a169d649216 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -75,6 +75,11 @@ struct cdns_dphy;
 struct cdns_dphy_ops {
 	int (*probe)(struct cdns_dphy *dphy);
 	void (*remove)(struct cdns_dphy *dphy);
+	int (*power_on)(struct cdns_dphy *dphy);
+	int (*power_off)(struct cdns_dphy *dphy);
+	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
+			union phy_configure_opts *opts);
+	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
 	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
 	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
 				 enum cdns_dphy_clk_lane_cfg cfg);
@@ -86,6 +91,7 @@ struct cdns_dphy_ops {
 struct cdns_dphy {
 	struct cdns_dphy_cfg cfg;
 	void __iomem *regs;
+	struct device *dev;
 	struct clk *psm_clk;
 	struct clk *pll_ref_clk;
 	const struct cdns_dphy_ops *ops;
@@ -199,20 +205,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
 	       dphy->regs + DPHY_PSM_CFG);
 }
 
-/*
- * This is the reference implementation of DPHY hooks. Specific integration of
- * this IP may have to re-implement some of them depending on how they decided
- * to wire things in the SoC.
- */
-static const struct cdns_dphy_ops ref_dphy_ops = {
-	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
-	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
-	.set_psm_div = cdns_dphy_ref_set_psm_div,
-};
-
-static int cdns_dphy_config_from_opts(struct phy *phy,
-				      struct phy_configure_opts_mipi_dphy *opts,
-				      struct cdns_dphy_cfg *cfg)
+static int cdns_dphy_tx_config_from_opts(struct phy *phy,
+					 struct phy_configure_opts_mipi_dphy *opts,
+					 struct cdns_dphy_cfg *cfg)
 {
 	struct cdns_dphy *dphy = phy_get_drvdata(phy);
 	unsigned int dsi_hfp_ext = 0;
@@ -232,24 +227,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
 	return 0;
 }
 
-static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
-			      union phy_configure_opts *opts)
+static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
+				  union phy_configure_opts *opts)
 {
 	struct cdns_dphy_cfg cfg = { 0 };
-
-	if (mode != PHY_MODE_MIPI_DPHY)
-		return -EINVAL;
-
-	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
-}
-
-static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
-{
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-	struct cdns_dphy_cfg cfg = { 0 };
 	int ret;
 
-	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
+	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
 	if (ret)
 		return ret;
 
@@ -279,9 +263,18 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 	return 0;
 }
 
-static int cdns_dphy_power_on(struct phy *phy)
+static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts)
 {
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+	struct cdns_dphy_cfg cfg = { 0 };
+
+	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
+}
+
+static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
+{
+	if (!dphy->psm_clk || !dphy->pll_ref_clk)
+		return -EINVAL;
 
 	clk_prepare_enable(dphy->psm_clk);
 	clk_prepare_enable(dphy->pll_ref_clk);
@@ -293,16 +286,73 @@ static int cdns_dphy_power_on(struct phy *phy)
 	return 0;
 }
 
-static int cdns_dphy_power_off(struct phy *phy)
+static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
 {
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-
 	clk_disable_unprepare(dphy->pll_ref_clk);
 	clk_disable_unprepare(dphy->psm_clk);
 
 	return 0;
 }
 
+/*
+ * This is the reference implementation of DPHY hooks. Specific integration of
+ * this IP may have to re-implement some of them depending on how they decided
+ * to wire things in the SoC.
+ */
+static const struct cdns_dphy_ops tx_ref_dphy_ops = {
+	.power_on = cdns_dphy_tx_power_on,
+	.power_off = cdns_dphy_tx_power_off,
+	.validate = cdns_dphy_tx_validate,
+	.configure = cdns_dphy_tx_configure,
+	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
+	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
+	.set_psm_div = cdns_dphy_ref_set_psm_div,
+};
+
+static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
+			      union phy_configure_opts *opts)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_MIPI_DPHY)
+		return -EINVAL;
+
+	if (dphy->ops->validate)
+		return dphy->ops->validate(dphy, mode, submode, opts);
+
+	return 0;
+}
+
+static int cdns_dphy_power_on(struct phy *phy)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->power_on)
+		return dphy->ops->power_on(dphy);
+
+	return 0;
+}
+
+static int cdns_dphy_power_off(struct phy *phy)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->power_off)
+		return dphy->ops->power_off(dphy);
+
+	return 0;
+}
+
+static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->configure)
+		return dphy->ops->configure(dphy, opts);
+
+	return 0;
+}
+
 static const struct phy_ops cdns_dphy_ops = {
 	.configure	= cdns_dphy_configure,
 	.validate	= cdns_dphy_validate,
@@ -320,6 +370,7 @@ static int cdns_dphy_probe(struct platform_device *pdev)
 	if (!dphy)
 		return -ENOMEM;
 	dev_set_drvdata(&pdev->dev, dphy);
+	dphy->dev = &pdev->dev;
 
 	dphy->ops = of_device_get_match_data(&pdev->dev);
 	if (!dphy->ops)
@@ -329,11 +380,11 @@ static int cdns_dphy_probe(struct platform_device *pdev)
 	if (IS_ERR(dphy->regs))
 		return PTR_ERR(dphy->regs);
 
-	dphy->psm_clk = devm_clk_get(&pdev->dev, "psm");
+	dphy->psm_clk = devm_clk_get_optional(dphy->dev, "psm");
 	if (IS_ERR(dphy->psm_clk))
 		return PTR_ERR(dphy->psm_clk);
 
-	dphy->pll_ref_clk = devm_clk_get(&pdev->dev, "pll_ref");
+	dphy->pll_ref_clk = devm_clk_get_optional(dphy->dev, "pll_ref");
 	if (IS_ERR(dphy->pll_ref_clk))
 		return PTR_ERR(dphy->pll_ref_clk);
 
@@ -369,7 +420,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id cdns_dphy_of_match[] = {
-	{ .compatible = "cdns,dphy", .data = &ref_dphy_ops },
+	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
-- 
2.30.0



From p.yadav at ti.com  Fri Aug 20 12:03:42 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:42 +0530
Subject: [PATCH v4 2/6] phy: cdns-dphy: Add Rx support
In-Reply-To: <20210820190346.18550-1-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
Message-ID: <20210820190346.18550-3-p.yadav@ti.com>

The Cadence DPHY can be used to receive image data over the CSI-2
protocol. Add support for Rx mode. The programming sequence differs from
the Tx mode so it is added as a separate set of hooks to isolate the two
paths. The mode in which the DPHY has to be used is selected based on
the compatible.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>

---

Changes in v4:
- Drop the submode parts. Use a different compatible for the Rx ops.
- Make bands and num_bands static.

Changes in v3:
- Use a table to select the band.
- Use a table to poll the data lane ready bits.
- Multiply the DPHY HS clock rate by 2 to get the bit rate since the
  clock is DDR.

 drivers/phy/cadence/cdns-dphy.c | 171 ++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index 0a169d649216..149fccdfad38 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -1,11 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright: 2017-2018 Cadence Design Systems, Inc.
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -25,10 +28,14 @@
 #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
 #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
 #define DPHY_PCS(reg)			(0xb00 + (reg))
+#define DPHY_ISO(reg)			(0xc00 + (reg))
 
 #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
 #define DPHY_CMN_SSM_EN			BIT(0)
+#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
 #define DPHY_CMN_TX_MODE_EN		BIT(9)
+#define DPHY_CMN_RX_MODE_EN		BIT(10)
+#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
 
 #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
 #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
@@ -45,10 +52,27 @@
 #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
 #define DPHY_CMN_OPDIV(x)		((x) << 7)
 
+#define DPHY_BAND_CFG			DPHY_PCS(0x0)
+#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
+#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
+
 #define DPHY_PSM_CFG			DPHY_PCS(0x4)
 #define DPHY_PSM_CFG_FROM_REG		BIT(0)
 #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
 
+#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
+#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
+#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
+#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
+
+#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
+#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
+#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
+#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
+#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
+#define DPHY_ISO_LANE_READY_BIT		0
+#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
+
 #define DSI_HBP_FRAME_OVERHEAD		12
 #define DSI_HSA_FRAME_OVERHEAD		14
 #define DSI_HFP_FRAME_OVERHEAD		6
@@ -57,6 +81,9 @@
 #define DSI_NULL_FRAME_OVERHEAD		6
 #define DSI_EOT_PKT_SIZE		4
 
+#define DPHY_LANES_MIN			1
+#define DPHY_LANES_MAX			4
+
 struct cdns_dphy_cfg {
 	u8 pll_ipdiv;
 	u8 pll_opdiv;
@@ -98,6 +125,22 @@ struct cdns_dphy {
 	struct phy *phy;
 };
 
+struct cdns_dphy_rx_band {
+	unsigned int min_rate;
+	unsigned int max_rate;
+};
+
+/* Order of bands is important since the index is the band number. */
+static struct cdns_dphy_rx_band bands[] = {
+	{80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240},
+	{240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480},
+	{480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880},
+	{880, 1040}, {1040, 1200}, {1200, 1350}, {1350, 1500}, {1500, 1750},
+	{1750, 2000}, {2000, 2250}, {2250, 2500}
+};
+
+static int num_bands = ARRAY_SIZE(bands);
+
 static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 				     struct cdns_dphy_cfg *cfg,
 				     struct phy_configure_opts_mipi_dphy *opts,
@@ -309,6 +352,132 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
 	.set_psm_div = cdns_dphy_ref_set_psm_div,
 };
 
+static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
+{
+	/* Start RX state machine. */
+	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
+	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
+			  DPHY_CMN_RX_BANDGAP_TIMER),
+	       dphy->regs + DPHY_CMN_SSM);
+
+	return 0;
+}
+
+static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
+{
+	writel(0, dphy->regs + DPHY_CMN_SSM);
+
+	return 0;
+}
+
+static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
+{
+	unsigned int rate;
+	int i;
+
+	rate = hs_clk_rate / 1000000UL;
+	/* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
+	rate *= 2;
+
+	if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate)
+		return -EOPNOTSUPP;
+
+	for (i = 0; i < num_bands; i++) {
+		if (rate >= bands[i].min_rate && rate < bands[i].max_rate)
+			return i;
+	}
+
+	/* Unreachable. */
+	WARN(1, "Reached unreachable code.");
+	return -EINVAL;
+}
+
+static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
+{
+	u32 val;
+
+	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
+					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
+}
+
+static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
+{
+	void __iomem *reg = dphy->regs;
+	u32 data_lane_ctrl[] = {DPHY_ISO_DL_CTRL_L0, DPHY_ISO_DL_CTRL_L1,
+				DPHY_ISO_DL_CTRL_L2, DPHY_ISO_DL_CTRL_L3};
+	int ret, i;
+
+	/* Data lanes. Minimum one lane is mandatory. */
+	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
+		return -EINVAL;
+
+	/* Clock lane */
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < lanes; i++) {
+		ret = cdns_dphy_rx_wait_for_bit(reg + data_lane_ctrl[i],
+						DPHY_ISO_LANE_READY_BIT);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int cdns_dphy_rx_configure(struct cdns_dphy *dphy,
+				  union phy_configure_opts *opts)
+{
+	unsigned int reg;
+	int band_ctrl, ret;
+
+	band_ctrl = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
+	if (band_ctrl < 0)
+		return band_ctrl;
+
+	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
+	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
+	writel(reg, dphy->regs + DPHY_BAND_CFG);
+
+	/*
+	 * Set the required power island phase 2 time. This is mandated by DPHY
+	 * specs.
+	 */
+	reg = DPHY_POWER_ISLAND_EN_DATA_VAL;
+	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_DATA);
+	reg = DPHY_POWER_ISLAND_EN_CLK_VAL;
+	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_CLK);
+
+	ret = cdns_dphy_rx_wait_lane_ready(dphy, opts->mipi_dphy.lanes);
+	if (ret) {
+		dev_err(dphy->dev, "DPHY wait for lane ready timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cdns_dphy_rx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts)
+{
+	int ret;
+
+	ret = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
+	if (ret < 0)
+		return ret;
+
+	return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
+}
+
+static const struct cdns_dphy_ops rx_ref_dphy_ops = {
+	.power_on = cdns_dphy_rx_power_on,
+	.power_off = cdns_dphy_rx_power_off,
+	.configure = cdns_dphy_rx_configure,
+	.validate = cdns_dphy_rx_validate,
+};
+
 static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
 			      union phy_configure_opts *opts)
 {
@@ -421,6 +590,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
 
 static const struct of_device_id cdns_dphy_of_match[] = {
 	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
+	{ .compatible = "cdns,dphy-rx", .data = &rx_ref_dphy_ops },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
@@ -436,5 +606,6 @@ static struct platform_driver cdns_dphy_platform_driver = {
 module_platform_driver(cdns_dphy_platform_driver);
 
 MODULE_AUTHOR("Maxime Ripard <maxime.ripard at bootlin.com>");
+MODULE_AUTHOR("Pratyush Yadav <p.yadav at ti.com>");
 MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
 MODULE_LICENSE("GPL");
-- 
2.30.0



From p.yadav at ti.com  Fri Aug 20 12:03:43 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:43 +0530
Subject: [PATCH v4 3/6] phy: dt-bindings: Convert Cadence DPHY binding to YAML
In-Reply-To: <20210820190346.18550-1-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
Message-ID: <20210820190346.18550-4-p.yadav@ti.com>

Convert Cadence DPHY binding to YAML.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Rob Herring <robh at kernel.org>

---

(no changes since v3)

Changes in v3:
- Add Rob's R-by.

Changes in v2:
- Drop reg description.
- Add a description for each DPHY clock.
- Rename dphy at ... to phy at ... in example.
- Add Laurent's R-by.
- Re-order subject prefixes.

 .../devicetree/bindings/phy/cdns,dphy.txt     | 20 --------
 .../devicetree/bindings/phy/cdns,dphy.yaml    | 51 +++++++++++++++++++
 2 files changed, 51 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.txt b/Documentation/devicetree/bindings/phy/cdns,dphy.txt
deleted file mode 100644
index 1095bc4e72d9..000000000000
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Cadence DPHY
-============
-
-Cadence DPHY block.
-
-Required properties:
-- compatible: should be set to "cdns,dphy".
-- reg: physical base address and length of the DPHY registers.
-- clocks: DPHY reference clocks.
-- clock-names: must contain "psm" and "pll_ref".
-- #phy-cells: must be set to 0.
-
-Example:
-	dphy0: dphy at fd0e0000{
-		compatible = "cdns,dphy";
-		reg = <0x0 0xfd0e0000 0x0 0x1000>;
-		clocks = <&psm_clk>, <&pll_ref_clk>;
-		clock-names = "psm", "pll_ref";
-		#phy-cells = <0>;
-	};
diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
new file mode 100644
index 000000000000..b90a58773bf2
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/cdns,dphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence DPHY Device Tree Bindings
+
+maintainers:
+  - Pratyush Yadav <p.yadav at ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: cdns,dphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PMA state machine clock
+      - description: PLL reference clock
+
+  clock-names:
+    items:
+      - const: psm
+      - const: pll_ref
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dphy0: phy at fd0e0000{
+        compatible = "cdns,dphy";
+        reg = <0xfd0e0000 0x1000>;
+        clocks = <&psm_clk>, <&pll_ref_clk>;
+        clock-names = "psm", "pll_ref";
+        #phy-cells = <0>;
+    };
-- 
2.30.0



From p.yadav at ti.com  Fri Aug 20 12:03:44 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:44 +0530
Subject: [PATCH v4 4/6] phy: dt-bindings: cdns,dphy: make clocks optional
In-Reply-To: <20210820190346.18550-1-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
Message-ID: <20210820190346.18550-5-p.yadav@ti.com>

The clocks are not used by the DPHY when used in Rx mode so make them
optional.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
Acked-by: Rob Herring <robh at kernel.org>

---

(no changes since v3)

Changes in v3:
- Add Rob's Ack.

Changes in v2:
- Re-order subject prefixes.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index b90a58773bf2..3bb5be05e825 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -33,8 +33,6 @@ properties:
 required:
   - compatible
   - reg
-  - clocks
-  - clock-names
   - "#phy-cells"
 
 additionalProperties: false
-- 
2.30.0



From p.yadav at ti.com  Fri Aug 20 12:03:45 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:45 +0530
Subject: [PATCH v4 5/6] phy: dt-bindings: cdns,
 dphy: add power-domains property
In-Reply-To: <20210820190346.18550-1-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
Message-ID: <20210820190346.18550-6-p.yadav@ti.com>

This property is needed on TI platforms to enable the PD of the DPHY
before it can be used.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Rob Herring <robh at kernel.org>

---

(no changes since v3)

Changes in v3:
- Add Rob's Ack.

Changes in v2:
- Add power-domain to the example.
- Add Laurent's R-by.
- Re-order subject prefixes.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index 3bb5be05e825..d5a5e1f0b671 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -30,6 +30,9 @@ properties:
   "#phy-cells":
     const: 0
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -39,11 +42,13 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
 
     dphy0: phy at fd0e0000{
         compatible = "cdns,dphy";
         reg = <0xfd0e0000 0x1000>;
         clocks = <&psm_clk>, <&pll_ref_clk>;
         clock-names = "psm", "pll_ref";
+        power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
         #phy-cells = <0>;
     };
-- 
2.30.0



From p.yadav at ti.com  Fri Aug 20 12:03:46 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Sat, 21 Aug 2021 00:33:46 +0530
Subject: [PATCH v4 6/6] phy: dt-bindings: cdns,dphy: add Rx DPHY compatible
In-Reply-To: <20210820190346.18550-1-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
Message-ID: <20210820190346.18550-7-p.yadav@ti.com>

The DPHY is treated to be in Tx mode by default. Add a new compatible
for Rx mode DPHYs.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>

---

Changes in v4:
- New in v4.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index d5a5e1f0b671..48b6a841152e 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -11,8 +11,9 @@ maintainers:
 
 properties:
   compatible:
-    items:
+    oneOf:
       - const: cdns,dphy
+      - const: cdns,dphy-rx
 
   reg:
     maxItems: 1
-- 
2.30.0



From iskren.chernev at gmail.com  Sat Aug 21 08:56:55 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Sat, 21 Aug 2021 18:56:55 +0300
Subject: [PATCH v3 1/2] dt-bindings: phy: qcom,
 qmp: Add SM6115 UFS PHY bindings
In-Reply-To: <20210821155657.893165-1-iskren.chernev@gmail.com>
References: <20210821155657.893165-1-iskren.chernev@gmail.com>
Message-ID: <20210821155657.893165-2-iskren.chernev@gmail.com>

Add the compatible strings for the UFS PHY found on SM4250/6115 SoC.

Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index 47d99001d2dd..75be5650a198 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -36,6 +36,7 @@ properties:
       - qcom,sdm845-qmp-ufs-phy
       - qcom,sdm845-qmp-usb3-phy
       - qcom,sdm845-qmp-usb3-uni-phy
+      - qcom,sm6115-qmp-ufs-phy
       - qcom,sm8150-qmp-ufs-phy
       - qcom,sm8150-qmp-usb3-phy
       - qcom,sm8150-qmp-usb3-uni-phy
-- 
2.32.0



From iskren.chernev at gmail.com  Sat Aug 21 08:56:54 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Sat, 21 Aug 2021 18:56:54 +0300
Subject: [PATCH v3 0/2] Add UFS PHY support for SM6115/4250
Message-ID: <20210821155657.893165-1-iskren.chernev@gmail.com>

The UFS PHY found on SM6115/4250 has a lot of common registers with ufs phy v2,
even though in downstream it is named v3-660. Due to register similarity with
v2, the few extra registers that are needed are added as v2 registers.

The register values/sequences are taken from OnePlus repo [1].

[1] https://github.com/OnePlusOSS/android_kernel_oneplus_sm4250

v1: https://lkml.org/lkml/2021/8/5/235
v2: https://lkml.org/lkml/2021/8/13/889

Changes from v2:
- Suggested by Vinod
  - the 6115 registers had a lot in common with v2 registers (and not v3, as
    was initially assumed), so those were reused whenever possible, and new
    regs were added along other v2 registers.

Changes from v1:
- Suggested by Vinod
  - removed v3-660 constants for regs with same name and value as v3 regs

Iskren Chernev (2):
  dt-bindings: phy: qcom,qmp: Add SM6115 UFS PHY bindings
  phy: qcom-qmp: Add support for SM6115 UFS phy

 .../devicetree/bindings/phy/qcom,qmp-phy.yaml |   1 +
 drivers/phy/qualcomm/phy-qcom-qmp.c           | 124 ++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h           |  18 +++
 3 files changed, 143 insertions(+)


base-commit: 86ed57fd8c93fdfaabb4f58e78455180fa7d8a84
-- 
2.32.0



From iskren.chernev at gmail.com  Sat Aug 21 08:56:56 2021
From: iskren.chernev at gmail.com (Iskren Chernev)
Date: Sat, 21 Aug 2021 18:56:56 +0300
Subject: [PATCH v3 2/2] phy: qcom-qmp: Add support for SM6115 UFS phy
In-Reply-To: <20210821155657.893165-1-iskren.chernev@gmail.com>
References: <20210821155657.893165-1-iskren.chernev@gmail.com>
Message-ID: <20210821155657.893165-3-iskren.chernev@gmail.com>

Add the tables and constants for init sequences for UFS QMP phy found in
SM4250/6115 SoC. The phy is a variation of the v2 phy, but is mistakenly
labeled as v3-660 in downstream sources.

QSERDES COM, RX, TX registers match fully existing v2 registers, with
a few additions. PCS registers don't have much in common, but there are
no clashes with existing ones so new registers were added to existing v2
PCS pack.

Signed-off-by: Iskren Chernev <iskren.chernev at gmail.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 124 ++++++++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h |  18 ++++
 2 files changed, 142 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index a8c4368f984b..f14032170b1c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -234,6 +234,11 @@ static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_READY_STATUS]		= 0x160,
 };
 
+static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_START_CTRL]		= 0x00,
+	[QPHY_PCS_READY_STATUS]		= 0x168,
+};
+
 static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_SW_RESET]			= 0x00,
 	[QPHY_START_CTRL]		= 0x44,
@@ -1329,6 +1334,97 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
 };
 
+static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
+
+	/* Rate B */
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
+};
+
+static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
+	QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
+	QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
+	QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
+	QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
+	QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
+};
+
 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
@@ -3396,6 +3492,31 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
 	.no_pcs_sw_reset	= true,
 };
 
+static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
+	.type			= PHY_TYPE_UFS,
+	.nlanes			= 1,
+
+	.serdes_tbl		= sm6115_ufsphy_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
+	.tx_tbl			= sm6115_ufsphy_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
+	.rx_tbl			= sm6115_ufsphy_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
+	.pcs_tbl		= sm6115_ufsphy_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
+	.clk_list		= sdm845_ufs_phy_clk_l,
+	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= sm6115_ufsphy_regs_layout,
+
+	.start_ctrl		= SERDES_START,
+	.pwrdn_ctrl		= SW_PWRDN,
+
+	.is_dual_lane_phy	= false,
+	.no_pcs_sw_reset	= true,
+};
+
 static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
 	.type			= PHY_TYPE_PCIE,
 	.nlanes			= 1,
@@ -5444,6 +5565,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
 	}, {
 		.compatible = "qcom,msm8998-qmp-usb3-phy",
 		.data = &msm8998_usb3phy_cfg,
+	}, {
+		.compatible = "qcom,sm6115-qmp-ufs-phy",
+		.data = &sm6115_ufsphy_cfg,
 	}, {
 		.compatible = "qcom,sm8150-qmp-ufs-phy",
 		.data = &sm8150_ufsphy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index 6592b58b13f6..bebeac2c091c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -191,6 +191,8 @@
 #define QSERDES_COM_VCO_TUNE2_MODE0			0x130
 #define QSERDES_COM_VCO_TUNE1_MODE1			0x134
 #define QSERDES_COM_VCO_TUNE2_MODE1			0x138
+#define QSERDES_COM_VCO_TUNE_INITVAL1			0x13c
+#define QSERDES_COM_VCO_TUNE_INITVAL2			0x140
 #define QSERDES_COM_VCO_TUNE_TIMER1			0x144
 #define QSERDES_COM_VCO_TUNE_TIMER2			0x148
 #define QSERDES_COM_BG_CTRL				0x170
@@ -220,6 +222,10 @@
 /* Only for QMP V2 PHY - RX registers */
 #define QSERDES_RX_UCDR_SO_GAIN_HALF			0x010
 #define QSERDES_RX_UCDR_SO_GAIN				0x01c
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_HALF		0x030
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER		0x034
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_EIGHTH		0x038
+#define QSERDES_RX_UCDR_SVS_SO_GAIN			0x03c
 #define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN		0x040
 #define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE	0x048
 #define QSERDES_RX_RX_TERM_BW				0x090
@@ -243,6 +249,10 @@
 #define QPHY_POWER_DOWN_CONTROL				0x04
 #define QPHY_TXDEEMPH_M6DB_V0				0x24
 #define QPHY_TXDEEMPH_M3P5DB_V0				0x28
+#define QPHY_TX_LARGE_AMP_DRV_LVL			0x34
+#define QPHY_TX_LARGE_AMP_POST_EMP_LVL			0x38
+#define QPHY_TX_SMALL_AMP_DRV_LVL			0x3c
+#define QPHY_TX_SMALL_AMP_POST_EMP_LVL			0x40
 #define QPHY_ENDPOINT_REFCLK_DRIVE			0x54
 #define QPHY_RX_IDLE_DTCT_CNTRL				0x58
 #define QPHY_POWER_STATE_CONFIG1			0x60
@@ -253,6 +263,11 @@
 #define QPHY_LOCK_DETECT_CONFIG3			0x88
 #define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK		0xa0
 #define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK			0xa4
+#define QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP		0xcc
+#define QPHY_RX_SYM_RESYNC_CTRL				0x13c
+#define QPHY_RX_MIN_HIBERN8_TIME			0x140
+#define QPHY_RX_SIGDET_CTRL2				0x148
+#define QPHY_RX_PWM_GEAR_BAND				0x154
 #define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB		0x1A8
 #define QPHY_OSC_DTCT_ACTIONS				0x1AC
 #define QPHY_RX_SIGDET_LVL				0x1D8
@@ -280,6 +295,8 @@
 #define QSERDES_V3_COM_SSC_PER2				0x020
 #define QSERDES_V3_COM_SSC_STEP_SIZE1			0x024
 #define QSERDES_V3_COM_SSC_STEP_SIZE2			0x028
+#define QSERDES_V3_COM_POST_DIV				0x02c
+#define QSERDES_V3_COM_POST_DIV_MUX			0x030
 #define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN		0x034
 # define QSERDES_V3_COM_BIAS_EN				0x0001
 # define QSERDES_V3_COM_BIAS_EN_MUX			0x0002
@@ -291,6 +308,7 @@
 #define QSERDES_V3_COM_CLK_ENABLE1			0x038
 #define QSERDES_V3_COM_SYS_CLK_CTRL			0x03c
 #define QSERDES_V3_COM_SYSCLK_BUF_ENABLE		0x040
+#define QSERDES_V3_COM_PLL_EN				0x044
 #define QSERDES_V3_COM_PLL_IVCO				0x048
 #define QSERDES_V3_COM_LOCK_CMP1_MODE0			0x098
 #define QSERDES_V3_COM_LOCK_CMP2_MODE0			0x09c
-- 
2.32.0



From laurent.pinchart at ideasonboard.com  Sun Aug 22 18:25:05 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 23 Aug 2021 04:25:05 +0300
Subject: [PATCH v4 1/6] phy: cdns-dphy: Prepare for Rx support
In-Reply-To: <20210820190346.18550-2-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-2-p.yadav@ti.com>
Message-ID: <YSL48RA2ksldoCyX@pendragon.ideasonboard.com>

Hi Pratyush,

Thank you for the patch.

On Sat, Aug 21, 2021 at 12:33:41AM +0530, Pratyush Yadav wrote:
> The Rx programming sequence differs from the Tx programming sequence.
> Currently only Tx mode is supported. For example, the power on and off,
> validation, and configuration procedures are all different between Rx
> and Tx DPHYs. Currently they are only written from a Tx point of view
> and they won't work with an Rx DPHY. Move them to cdns_dphy_ops so they
> can be defined by the implementation, accommodating both Rx and Tx mode
> DPHYs.
> 
> The clocks "psm" and "pll_ref" are not used by the Rx path so make them
> optional in the probe and then check if they exist in the Tx power_on()
> hook.

I think it would be better to check them at probe time.

> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> 
> ---
> 
> Changes in v4:
> - Instead of having both Rx and Tx modes in the same driver data, keep
>   them separate since the op selection is based on compatible now. For
>   that reason, the cdns_dphy_driver_data struct is no longer needed.
> - Rename ref_dphy_ops to tx_ref_dphy_ops to clarify their purpose.
> - Drop submode checks in validate() hook.
> 
>  drivers/phy/cadence/cdns-dphy.c | 123 ++++++++++++++++++++++----------
>  1 file changed, 87 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index ba042e39cfaf..0a169d649216 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -75,6 +75,11 @@ struct cdns_dphy;
>  struct cdns_dphy_ops {
>  	int (*probe)(struct cdns_dphy *dphy);
>  	void (*remove)(struct cdns_dphy *dphy);
> +	int (*power_on)(struct cdns_dphy *dphy);
> +	int (*power_off)(struct cdns_dphy *dphy);
> +	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
> +			union phy_configure_opts *opts);
> +	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
>  	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
>  	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
>  				 enum cdns_dphy_clk_lane_cfg cfg);
> @@ -86,6 +91,7 @@ struct cdns_dphy_ops {
>  struct cdns_dphy {
>  	struct cdns_dphy_cfg cfg;
>  	void __iomem *regs;
> +	struct device *dev;
>  	struct clk *psm_clk;
>  	struct clk *pll_ref_clk;
>  	const struct cdns_dphy_ops *ops;
> @@ -199,20 +205,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
>  	       dphy->regs + DPHY_PSM_CFG);
>  }
>  
> -/*
> - * This is the reference implementation of DPHY hooks. Specific integration of
> - * this IP may have to re-implement some of them depending on how they decided
> - * to wire things in the SoC.
> - */
> -static const struct cdns_dphy_ops ref_dphy_ops = {
> -	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> -	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> -	.set_psm_div = cdns_dphy_ref_set_psm_div,
> -};
> -
> -static int cdns_dphy_config_from_opts(struct phy *phy,
> -				      struct phy_configure_opts_mipi_dphy *opts,
> -				      struct cdns_dphy_cfg *cfg)
> +static int cdns_dphy_tx_config_from_opts(struct phy *phy,
> +					 struct phy_configure_opts_mipi_dphy *opts,
> +					 struct cdns_dphy_cfg *cfg)
>  {
>  	struct cdns_dphy *dphy = phy_get_drvdata(phy);
>  	unsigned int dsi_hfp_ext = 0;
> @@ -232,24 +227,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
>  	return 0;
>  }
>  
> -static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> -			      union phy_configure_opts *opts)
> +static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
> +				  union phy_configure_opts *opts)
>  {
>  	struct cdns_dphy_cfg cfg = { 0 };
> -
> -	if (mode != PHY_MODE_MIPI_DPHY)
> -		return -EINVAL;
> -
> -	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> -}
> -
> -static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> -{
> -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> -	struct cdns_dphy_cfg cfg = { 0 };
>  	int ret;
>  
> -	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> +	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
>  	if (ret)
>  		return ret;
>  
> @@ -279,9 +263,18 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
>  	return 0;
>  }
>  
> -static int cdns_dphy_power_on(struct phy *phy)
> +static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> +				 int submode, union phy_configure_opts *opts)
>  {
> -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +	struct cdns_dphy_cfg cfg = { 0 };
> +
> +	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
> +}
> +
> +static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
> +{
> +	if (!dphy->psm_clk || !dphy->pll_ref_clk)
> +		return -EINVAL;
>  
>  	clk_prepare_enable(dphy->psm_clk);
>  	clk_prepare_enable(dphy->pll_ref_clk);
> @@ -293,16 +286,73 @@ static int cdns_dphy_power_on(struct phy *phy)
>  	return 0;
>  }
>  
> -static int cdns_dphy_power_off(struct phy *phy)
> +static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
>  {
> -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> -
>  	clk_disable_unprepare(dphy->pll_ref_clk);
>  	clk_disable_unprepare(dphy->psm_clk);
>  
>  	return 0;
>  }
>  
> +/*
> + * This is the reference implementation of DPHY hooks. Specific integration of
> + * this IP may have to re-implement some of them depending on how they decided
> + * to wire things in the SoC.
> + */
> +static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> +	.power_on = cdns_dphy_tx_power_on,
> +	.power_off = cdns_dphy_tx_power_off,
> +	.validate = cdns_dphy_tx_validate,
> +	.configure = cdns_dphy_tx_configure,
> +	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> +	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> +	.set_psm_div = cdns_dphy_ref_set_psm_div,
> +};
> +
> +static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> +			      union phy_configure_opts *opts)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (mode != PHY_MODE_MIPI_DPHY)
> +		return -EINVAL;
> +
> +	if (dphy->ops->validate)
> +		return dphy->ops->validate(dphy, mode, submode, opts);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_power_on(struct phy *phy)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (dphy->ops->power_on)
> +		return dphy->ops->power_on(dphy);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_power_off(struct phy *phy)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (dphy->ops->power_off)
> +		return dphy->ops->power_off(dphy);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> +
> +	if (dphy->ops->configure)
> +		return dphy->ops->configure(dphy, opts);
> +
> +	return 0;
> +}
> +

Given that all of these are essentially pass-through operations, how
about getting rid of the indirection ? I would create a new structure:

struct cdns_dphy_info {
	const struct phy_ops *phy_ops;
	const struct cdns_dphy_ops *dphy_ops;
};

and reference it in cdns_dphy_of_match. The cdns_dphy structure would
then store a pointer to cdns_dphy_info. That way you won't have to
extend cdns_dphy_ops, which could possibly be renamed to
cdns_dphy_tx_ops as you don't use those operations for rx.

>  static const struct phy_ops cdns_dphy_ops = {
>  	.configure	= cdns_dphy_configure,
>  	.validate	= cdns_dphy_validate,
> @@ -320,6 +370,7 @@ static int cdns_dphy_probe(struct platform_device *pdev)
>  	if (!dphy)
>  		return -ENOMEM;
>  	dev_set_drvdata(&pdev->dev, dphy);
> +	dphy->dev = &pdev->dev;
>  
>  	dphy->ops = of_device_get_match_data(&pdev->dev);
>  	if (!dphy->ops)
> @@ -329,11 +380,11 @@ static int cdns_dphy_probe(struct platform_device *pdev)
>  	if (IS_ERR(dphy->regs))
>  		return PTR_ERR(dphy->regs);
>  
> -	dphy->psm_clk = devm_clk_get(&pdev->dev, "psm");
> +	dphy->psm_clk = devm_clk_get_optional(dphy->dev, "psm");
>  	if (IS_ERR(dphy->psm_clk))
>  		return PTR_ERR(dphy->psm_clk);
>  
> -	dphy->pll_ref_clk = devm_clk_get(&pdev->dev, "pll_ref");
> +	dphy->pll_ref_clk = devm_clk_get_optional(dphy->dev, "pll_ref");
>  	if (IS_ERR(dphy->pll_ref_clk))
>  		return PTR_ERR(dphy->pll_ref_clk);
>  
> @@ -369,7 +420,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id cdns_dphy_of_match[] = {
> -	{ .compatible = "cdns,dphy", .data = &ref_dphy_ops },
> +	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Aug 22 18:37:58 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 23 Aug 2021 04:37:58 +0300
Subject: [PATCH v4 2/6] phy: cdns-dphy: Add Rx support
In-Reply-To: <20210820190346.18550-3-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-3-p.yadav@ti.com>
Message-ID: <YSL79vtTGsK+zwTQ@pendragon.ideasonboard.com>

Hi Pratyush,

Thank you for the patch.

On Sat, Aug 21, 2021 at 12:33:42AM +0530, Pratyush Yadav wrote:
> The Cadence DPHY can be used to receive image data over the CSI-2
> protocol. Add support for Rx mode. The programming sequence differs from
> the Tx mode so it is added as a separate set of hooks to isolate the two
> paths. The mode in which the DPHY has to be used is selected based on
> the compatible.
> 
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> 
> ---
> 
> Changes in v4:
> - Drop the submode parts. Use a different compatible for the Rx ops.
> - Make bands and num_bands static.
> 
> Changes in v3:
> - Use a table to select the band.
> - Use a table to poll the data lane ready bits.
> - Multiply the DPHY HS clock rate by 2 to get the bit rate since the
>   clock is DDR.
> 
>  drivers/phy/cadence/cdns-dphy.c | 171 ++++++++++++++++++++++++++++++++
>  1 file changed, 171 insertions(+)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index 0a169d649216..149fccdfad38 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -1,11 +1,14 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  /*
>   * Copyright: 2017-2018 Cadence Design Systems, Inc.
> + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
>   */
>  
>  #include <linux/bitops.h>
> +#include <linux/bitfield.h>

Alphabetical order please.

>  #include <linux/clk.h>
>  #include <linux/io.h>
> +#include <linux/iopoll.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
>  #include <linux/of_device.h>
> @@ -25,10 +28,14 @@
>  #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
>  #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
>  #define DPHY_PCS(reg)			(0xb00 + (reg))
> +#define DPHY_ISO(reg)			(0xc00 + (reg))
>  
>  #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
>  #define DPHY_CMN_SSM_EN			BIT(0)
> +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
>  #define DPHY_CMN_TX_MODE_EN		BIT(9)
> +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
>  
>  #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
>  #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> @@ -45,10 +52,27 @@
>  #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
>  #define DPHY_CMN_OPDIV(x)		((x) << 7)
>  
> +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> +
>  #define DPHY_PSM_CFG			DPHY_PCS(0x4)
>  #define DPHY_PSM_CFG_FROM_REG		BIT(0)
>  #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
>  
> +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> +
> +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> +#define DPHY_ISO_LANE_READY_BIT		0
> +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> +
>  #define DSI_HBP_FRAME_OVERHEAD		12
>  #define DSI_HSA_FRAME_OVERHEAD		14
>  #define DSI_HFP_FRAME_OVERHEAD		6
> @@ -57,6 +81,9 @@
>  #define DSI_NULL_FRAME_OVERHEAD		6
>  #define DSI_EOT_PKT_SIZE		4
>  
> +#define DPHY_LANES_MIN			1
> +#define DPHY_LANES_MAX			4
> +
>  struct cdns_dphy_cfg {
>  	u8 pll_ipdiv;
>  	u8 pll_opdiv;
> @@ -98,6 +125,22 @@ struct cdns_dphy {
>  	struct phy *phy;
>  };
>  
> +struct cdns_dphy_rx_band {
> +	unsigned int min_rate;
> +	unsigned int max_rate;
> +};
> +
> +/* Order of bands is important since the index is the band number. */
> +static struct cdns_dphy_rx_band bands[] = {

static const

> +	{80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240},
> +	{240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480},
> +	{480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880},
> +	{880, 1040}, {1040, 1200}, {1200, 1350}, {1350, 1500}, {1500, 1750},
> +	{1750, 2000}, {2000, 2250}, {2250, 2500}
> +};
> +
> +static int num_bands = ARRAY_SIZE(bands);

No need for a variable (which should be const otherwise), you can use
ARRAY_SIZE(bands) where needed.

> +
>  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>  				     struct cdns_dphy_cfg *cfg,
>  				     struct phy_configure_opts_mipi_dphy *opts,
> @@ -309,6 +352,132 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
>  	.set_psm_div = cdns_dphy_ref_set_psm_div,
>  };
>  
> +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> +{
> +	/* Start RX state machine. */
> +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> +			  DPHY_CMN_RX_BANDGAP_TIMER),
> +	       dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> +{
> +	writel(0, dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> +{
> +	unsigned int rate;
> +	int i;

i is never negative, you can make it an unsigned int.

> +
> +	rate = hs_clk_rate / 1000000UL;
> +	/* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
> +	rate *= 2;
> +
> +	if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate)
> +		return -EOPNOTSUPP;
> +
> +	for (i = 0; i < num_bands; i++) {
> +		if (rate >= bands[i].min_rate && rate < bands[i].max_rate)

You can replace this with

		if (rate < bands[i].max_rate)

as the bands are in increasing order.

> +			return i;
> +	}
> +
> +	/* Unreachable. */
> +	WARN(1, "Reached unreachable code.");
> +	return -EINVAL;

That's not very nice.

As a clock rate higher than the maximum isn't supposed to happen, you
could drop that initial check (it won't affect performance) and return
-EOPNOTSUPP here without a WARN().

> +}
> +
> +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> +{
> +	u32 val;
> +
> +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);

A busy wait for one second is quite long. How long does it typically
take for the condition to be true ?

> +}
> +
> +static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)

lanes should be an unsigned int.

> +{
> +	void __iomem *reg = dphy->regs;

You can use dphy->regs directly in the code below.

> +	u32 data_lane_ctrl[] = {DPHY_ISO_DL_CTRL_L0, DPHY_ISO_DL_CTRL_L1,
> +				DPHY_ISO_DL_CTRL_L2, DPHY_ISO_DL_CTRL_L3};

static const, and move it first in the function.

> +	int ret, i;

i is never negative here either.

> +
> +	/* Data lanes. Minimum one lane is mandatory. */
> +	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
> +		return -EINVAL;
> +
> +	/* Clock lane */
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < lanes; i++) {
> +		ret = cdns_dphy_rx_wait_for_bit(reg + data_lane_ctrl[i],
> +						DPHY_ISO_LANE_READY_BIT);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_configure(struct cdns_dphy *dphy,
> +				  union phy_configure_opts *opts)
> +{
> +	unsigned int reg;
> +	int band_ctrl, ret;
> +
> +	band_ctrl = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
> +	if (band_ctrl < 0)
> +		return band_ctrl;
> +
> +	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
> +	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
> +	writel(reg, dphy->regs + DPHY_BAND_CFG);
> +
> +	/*
> +	 * Set the required power island phase 2 time. This is mandated by DPHY
> +	 * specs.
> +	 */
> +	reg = DPHY_POWER_ISLAND_EN_DATA_VAL;
> +	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_DATA);
> +	reg = DPHY_POWER_ISLAND_EN_CLK_VAL;
> +	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_CLK);
> +
> +	ret = cdns_dphy_rx_wait_lane_ready(dphy, opts->mipi_dphy.lanes);
> +	if (ret) {
> +		dev_err(dphy->dev, "DPHY wait for lane ready timeout\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> +				 int submode, union phy_configure_opts *opts)
> +{
> +	int ret;
> +
> +	ret = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
> +	if (ret < 0)
> +		return ret;
> +
> +	return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
> +}
> +
> +static const struct cdns_dphy_ops rx_ref_dphy_ops = {
> +	.power_on = cdns_dphy_rx_power_on,
> +	.power_off = cdns_dphy_rx_power_off,
> +	.configure = cdns_dphy_rx_configure,
> +	.validate = cdns_dphy_rx_validate,
> +};
> +
>  static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
>  			      union phy_configure_opts *opts)
>  {
> @@ -421,6 +590,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
>  
>  static const struct of_device_id cdns_dphy_of_match[] = {
>  	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
> +	{ .compatible = "cdns,dphy-rx", .data = &rx_ref_dphy_ops },
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
> @@ -436,5 +606,6 @@ static struct platform_driver cdns_dphy_platform_driver = {
>  module_platform_driver(cdns_dphy_platform_driver);
>  
>  MODULE_AUTHOR("Maxime Ripard <maxime.ripard at bootlin.com>");
> +MODULE_AUTHOR("Pratyush Yadav <p.yadav at ti.com>");
>  MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
>  MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Aug 22 18:40:40 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 23 Aug 2021 04:40:40 +0300
Subject: [PATCH v4 4/6] phy: dt-bindings: cdns,dphy: make clocks optional
In-Reply-To: <20210820190346.18550-5-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-5-p.yadav@ti.com>
Message-ID: <YSL8mH8hd/PzyRRo@pendragon.ideasonboard.com>

Hi Pratyush,

Thank you for the patch.

On Sat, Aug 21, 2021 at 12:33:44AM +0530, Pratyush Yadav wrote:
> The clocks are not used by the DPHY when used in Rx mode so make them
> optional.
> 
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> Acked-by: Rob Herring <robh at kernel.org>
> 
> ---
> 
> (no changes since v3)
> 
> Changes in v3:
> - Add Rob's Ack.
> 
> Changes in v2:
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> index b90a58773bf2..3bb5be05e825 100644
> --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> @@ -33,8 +33,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - clocks
> -  - clock-names

Could you turn this into a conditional requirement based on the compat
string, as the clocks are needed in the TX case ?

>    - "#phy-cells"
>  
>  additionalProperties: false

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Aug 22 18:44:54 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 23 Aug 2021 04:44:54 +0300
Subject: [PATCH v4 6/6] phy: dt-bindings: cdns,dphy: add Rx DPHY compatible
In-Reply-To: <20210820190346.18550-7-p.yadav@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-7-p.yadav@ti.com>
Message-ID: <YSL9lkLB0wKk9sem@pendragon.ideasonboard.com>

Hi Pratyush,

Thank you for the patch.

On Sat, Aug 21, 2021 at 12:33:46AM +0530, Pratyush Yadav wrote:
> The DPHY is treated to be in Tx mode by default. Add a new compatible
> for Rx mode DPHYs.
> 
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> 
> ---
> 
> Changes in v4:
> - New in v4.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> index d5a5e1f0b671..48b6a841152e 100644
> --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> @@ -11,8 +11,9 @@ maintainers:
>  
>  properties:
>    compatible:
> -    items:
> +    oneOf:
>        - const: cdns,dphy
> +      - const: cdns,dphy-rx

It's customary to use an enum instead:

  compatibles:
    enum:
      - cdns,dphy
      - cdns,dphy-tx

I don't know if Rob has a preference for consistency (or for any other
reason). In either case,

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

>  
>    reg:
>      maxItems: 1

-- 
Regards,

Laurent Pinchart


From vkoul at kernel.org  Sun Aug 22 22:43:04 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 23 Aug 2021 11:13:04 +0530
Subject: [PATCH v3 0/2] Add UFS PHY support for SM6115/4250
In-Reply-To: <20210821155657.893165-1-iskren.chernev@gmail.com>
References: <20210821155657.893165-1-iskren.chernev@gmail.com>
Message-ID: <YSM1aBktwKqMUxXe@matsya>

On 21-08-21, 18:56, Iskren Chernev wrote:
> The UFS PHY found on SM6115/4250 has a lot of common registers with ufs phy v2,
> even though in downstream it is named v3-660. Due to register similarity with
> v2, the few extra registers that are needed are added as v2 registers.
> 
> The register values/sequences are taken from OnePlus repo [1].

This looks very good, thanks for cleaning it up

Applied now

-- 
~Vinod


From p.yadav at ti.com  Mon Aug 23 01:57:12 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Mon, 23 Aug 2021 14:27:12 +0530
Subject: [PATCH v4 4/6] phy: dt-bindings: cdns,dphy: make clocks optional
In-Reply-To: <YSL8mH8hd/PzyRRo@pendragon.ideasonboard.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-5-p.yadav@ti.com>
 <YSL8mH8hd/PzyRRo@pendragon.ideasonboard.com>
Message-ID: <20210823085710.mr4iz3fop62efcyj@ti.com>

On 23/08/21 04:40AM, Laurent Pinchart wrote:
> Hi Pratyush,
> 
> Thank you for the patch.
> 
> On Sat, Aug 21, 2021 at 12:33:44AM +0530, Pratyush Yadav wrote:
> > The clocks are not used by the DPHY when used in Rx mode so make them
> > optional.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > Acked-by: Rob Herring <robh at kernel.org>
> > 
> > ---
> > 
> > (no changes since v3)
> > 
> > Changes in v3:
> > - Add Rob's Ack.
> > 
> > Changes in v2:
> > - Re-order subject prefixes.
> > 
> >  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > index b90a58773bf2..3bb5be05e825 100644
> > --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > @@ -33,8 +33,6 @@ properties:
> >  required:
> >    - compatible
> >    - reg
> > -  - clocks
> > -  - clock-names
> 
> Could you turn this into a conditional requirement based on the compat
> string, as the clocks are needed in the TX case ?

Ok, will do.

> 
> >    - "#phy-cells"
> >  
> >  additionalProperties: false
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From robh at kernel.org  Mon Aug 23 15:43:45 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 17:43:45 -0500
Subject: [PATCH v4 6/6] phy: dt-bindings: cdns,dphy: add Rx DPHY compatible
In-Reply-To: <YSL9lkLB0wKk9sem@pendragon.ideasonboard.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-7-p.yadav@ti.com>
 <YSL9lkLB0wKk9sem@pendragon.ideasonboard.com>
Message-ID: <YSQkoVTjemx+nFpS@robh.at.kernel.org>

On Mon, Aug 23, 2021 at 04:44:54AM +0300, Laurent Pinchart wrote:
> Hi Pratyush,
> 
> Thank you for the patch.
> 
> On Sat, Aug 21, 2021 at 12:33:46AM +0530, Pratyush Yadav wrote:
> > The DPHY is treated to be in Tx mode by default. Add a new compatible
> > for Rx mode DPHYs.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > 
> > ---
> > 
> > Changes in v4:
> > - New in v4.
> > 
> >  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > index d5a5e1f0b671..48b6a841152e 100644
> > --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > @@ -11,8 +11,9 @@ maintainers:
> >  
> >  properties:
> >    compatible:
> > -    items:
> > +    oneOf:
> >        - const: cdns,dphy
> > +      - const: cdns,dphy-rx
> 
> It's customary to use an enum instead:
> 
>   compatibles:
>     enum:
>       - cdns,dphy
>       - cdns,dphy-tx
> 
> I don't know if Rob has a preference for consistency (or for any other
> reason). In either case,

Yes, use enum.

Rob


From vkoul at kernel.org  Mon Aug 23 22:10:40 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 24 Aug 2021 10:40:40 +0530
Subject: [GIT PULL]: Generic phy updates for v5.15
Message-ID: <YSR/UHNxE6iu3GBc@matsya>

Hello Greg,

Here is the update for v5.15, sorry this time it is bit late than
normal. Will make sure this hits early next time.

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git tags/phy-for-5.15

for you to fetch changes up to 152a810eae03f16e982444ffe3b0eca933a750cd:

  phy: qcom-qmp: Add support for SM6115 UFS phy (2021-08-23 11:12:30 +0530)

----------------------------------------------------------------
phy-for-5.15

  - Updates:
        - Yaml conversion for Freescale imx8mq usb phy, TI AM654 SERDES phy,
          Cadence torrent phy
        - Updates for Amlogic Meson8b-usb2 phy, Samsung ufs phy

  - New support:
        - UFS phy for Qualcomm SM6115
	- PCIe & USB/DP phy for Qualcomm sc8180x
	- USB3 PHY support for Qualcomm IPQ6018
	- Renesas USB2.0 PHY for RZ/G2L

----------------------------------------------------------------
Anand Moon (2):
      phy: amlogic: meson8b-usb2: Power off the PHY by putting it into reset mode
      phy: amlogic: meson8b-usb2: don't log an error on -EPROBE_DEFER

Arnd Bergmann (1):
      phy: tegra: xusb: mark PM functions as __maybe_unused

Baruch Siach (2):
      dt-bindings: phy: qcom,qmp: Add IPQ6018 USB3 PHY
      phy: qcom-qmp: add USB3 PHY support for IPQ6018

Biju Das (2):
      dt-bindings: phy: renesas,usb2-phy: Document RZ/G2L phy bindings
      phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY support for RZ/G2L

Bjorn Andersson (6):
      dt-bindings: phy: qcom,qmp: Add sc8180x PCIe compatible
      phy: qcom-qmp: Add sc8180x PCIe support
      phy: qcom-qmp: Fix sc8180x PCIe definition
      dt-bindings: phy: qcom,qmp-usb3-dp: Add support for sc8180x
      phy: qcom: qmp: Add SC8180x USB/DP combo
      phy: qmp: Provide unique clock names for DP clocks

Chanho Park (2):
      phy: samsung-ufs: move phy-exynos7-ufs header
      phy: samsung-ufs: support exynosauto ufs phy driver

Chunfeng Yun (12):
      dt-bindings: phy: mediatek: tphy: add support hardware version 3
      phy: phy-mtk-tphy: support new hardware version
      phy: phy-mtk-tphy: add support mt8195
      dt-bindings: phy: mediatek: tphy: support type switch by pericfg
      phy: phy-mtk-tphy: use clock bulk to get clocks
      phy: phy-mtk-tphy: support type switch by pericfg
      phy: phy-mtk-tphy: print error log using child device
      phy: phy-mtk-tphy: remove error log of ioremap failure
      phy: phy-mtk-ufs: use clock bulk to get clocks
      phy: phy-mtk-hdmi: convert to devm_platform_ioremap_resource
      phy: phy-mtk-mipi-dsi: remove dummy assignment of error number
      phy: phy-mtk-mipi-dsi: convert to devm_platform_ioremap_resource

Dong Aisheng (1):
      dt-bindings: phy: imx8mq-usb-phy: convert to json schema

Geert Uytterhoeven (1):
      dt-bindings: phy: Rename Intel Keem Bay USB PHY bindings

Iskren Chernev (2):
      dt-bindings: phy: qcom,qmp: Add SM6115 UFS PHY bindings
      phy: qcom-qmp: Add support for SM6115 UFS phy

Kishon Vijay Abraham I (1):
      dt-bindings: phy: Convert AM654 SERDES bindings to YAML

Piyush Mehta (1):
      phy: xilinx: zynqmp: skip PHY initialization and PLL lock for USB

Randy Dunlap (1):
      phy: qualcomm: phy-qcom-usb-hs: repair non-kernel-doc comment

Swapnil Jakhade (9):
      phy: cadence-torrent: Remove use of CamelCase to fix checkpatch CHECK message
      phy: cadence-torrent: Reorder few functions to remove function declarations
      phy: cadence-torrent: Add enum for supported input reference clock frequencies
      phy: cadence-torrent: Configure PHY registers as a function of input reference clock rate
      phy: cadence-torrent: Add PHY registers for DP in array format
      phy: cadence-torrent: Add PHY configuration for DP with 100MHz ref clock
      phy: cadence-torrent: Add separate functions for reusable code
      phy: cadence-torrent: Add debug information for PHY configuration
      phy: cadence-torrent: Check PIPE mode PHY status to be ready for operation

Tony Lindgren (1):
      phy: phy-twl4030-usb: Disable PHY for suspend

kernel test robot (1):
      phy: rockchip-inno-usb2: fix for_each_child.cocci warnings

 .../devicetree/bindings/phy/fsl,imx8mq-usb-phy.txt |   20 -
 .../bindings/phy/fsl,imx8mq-usb-phy.yaml           |   53 +
 ...keembay-usb.yaml => intel,keembay-phy-usb.yaml} |    2 +-
 .../devicetree/bindings/phy/mediatek,tphy.yaml     |   30 +-
 .../devicetree/bindings/phy/qcom,qmp-phy.yaml      |    4 +
 .../bindings/phy/qcom,qmp-usb3-dp-phy.yaml         |    1 +
 .../devicetree/bindings/phy/renesas,usb2-phy.yaml  |   15 +
 .../devicetree/bindings/phy/samsung,ufs-phy.yaml   |    1 +
 .../bindings/phy/ti,phy-am654-serdes.txt           |   82 -
 .../bindings/phy/ti,phy-am654-serdes.yaml          |  103 +
 drivers/phy/amlogic/phy-meson8b-usb2.c             |    8 +-
 drivers/phy/cadence/phy-cadence-torrent.c          | 3181 +++++++++++---------
 drivers/phy/mediatek/phy-mtk-hdmi.c                |    7 +-
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c            |   13 +-
 drivers/phy/mediatek/phy-mtk-tphy.c                |  224 +-
 drivers/phy/mediatek/phy-mtk-ufs.c                 |   44 +-
 drivers/phy/qualcomm/phy-qcom-qmp.c                |  321 +-
 drivers/phy/qualcomm/phy-qcom-qmp.h                |   18 +
 drivers/phy/qualcomm/phy-qcom-usb-hs.c             |    2 +-
 drivers/phy/renesas/phy-rcar-gen3-usb2.c           |   97 +-
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c      |    4 +-
 drivers/phy/samsung/Makefile                       |    5 +-
 .../{phy-exynos7-ufs.h => phy-exynos7-ufs.c}       |    8 +-
 drivers/phy/samsung/phy-exynosautov9-ufs.c         |   67 +
 drivers/phy/samsung/phy-samsung-ufs.c              |    3 +
 drivers/phy/samsung/phy-samsung-ufs.h              |   13 +-
 drivers/phy/tegra/xusb.c                           |    4 +-
 drivers/phy/ti/phy-twl4030-usb.c                   |   15 +
 drivers/phy/xilinx/phy-zynqmp.c                    |    3 +
 29 files changed, 2676 insertions(+), 1672 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
 rename Documentation/devicetree/bindings/phy/{intel,phy-keembay-usb.yaml => intel,keembay-phy-usb.yaml} (93%)
 delete mode 100644 Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.txt
 create mode 100644 Documentation/devicetree/bindings/phy/ti,phy-am654-serdes.yaml
 rename drivers/phy/samsung/{phy-exynos7-ufs.h => phy-exynos7-ufs.c} (93%)
 create mode 100644 drivers/phy/samsung/phy-exynosautov9-ufs.c

Thanks
-- 
~Vinod
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20210824/028da1bf/attachment.sig>

From mchehab+huawei at kernel.org  Tue Aug 24 04:54:23 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 24 Aug 2021 13:54:23 +0200
Subject: [PATCH v14] phy: HiSilicon: Add driver for Kirin 970 PCIe PHY
Message-ID: <96ed280aafa43c83a1bc4aabc1d290faa7f29ec3.1629805852.git.mchehab+huawei@kernel.org>

The Kirin 970 PHY is somewhat similar to the Kirin 960, but it
does a lot more. Add the needed bits for PCIe to start working on
HiKey 970 boards.

Co-developed-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---

PS.:
   As the PCIe patches aren't untouched, I'm sending just the PHY
   driver patch from v12.

v14:
  - re-added a line removed by mistake at v12, producing a build warning;
  - did a couple of cleanups with W=2;
  - addressed a couple minor checkpatch warnings (identation/removed extra line).

v13:
  - add missing include bitfield.h

v12:
  - removed c99-style comments;
  - added hi3670_apb_phy_updatel() to update bits;
  - allowed a couple of lines to be bigger than 80 columns.

 drivers/phy/hisilicon/Kconfig           |  10 +
 drivers/phy/hisilicon/Makefile          |   1 +
 drivers/phy/hisilicon/phy-hi3670-pcie.c | 845 ++++++++++++++++++++++++
 3 files changed, 856 insertions(+)
 create mode 100644 drivers/phy/hisilicon/phy-hi3670-pcie.c

diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 4d008cfc279c..d3b92c288554 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -33,6 +33,16 @@ config PHY_HI3670_USB
 
 	  To compile this driver as a module, choose M here.
 
+config PHY_HI3670_PCIE
+	tristate "hi3670 PCIe PHY support"
+	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+	select GENERIC_PHY
+	select MFD_SYSCON
+	help
+	  Enable this to support the HiSilicon hi3670 PCIe PHY.
+
+	  To compile this driver as a module, choose M here.
+
 config PHY_HISTB_COMBPHY
 	tristate "HiSilicon STB SoCs COMBPHY support"
 	depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 51729868145b..4029d3813b1e 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_HI6220_USB)		+= phy-hi6220-usb.o
 obj-$(CONFIG_PHY_HI3660_USB)		+= phy-hi3660-usb3.o
 obj-$(CONFIG_PHY_HI3670_USB)		+= phy-hi3670-usb3.o
+obj-$(CONFIG_PHY_HI3670_PCIE)		+= phy-hi3670-pcie.o
 obj-$(CONFIG_PHY_HISTB_COMBPHY)		+= phy-histb-combphy.o
 obj-$(CONFIG_PHY_HISI_INNO_USB2)	+= phy-hisi-inno-usb2.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
new file mode 100644
index 000000000000..c64c6679b1b9
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -0,0 +1,845 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe phy driver for Kirin 970
+ *
+ * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
+ *		https://www.huawei.com
+ * Copyright (C) 2021 Huawei Technologies Co., Ltd.
+ *		https://www.huawei.com
+ *
+ * Authors:
+ *	Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
+ *	Manivannan Sadhasivam <mani at kernel.org>
+ *
+ * Based on:
+ *	https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei at kernel.org/
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AXI_CLK_FREQ				207500000
+#define REF_CLK_FREQ				100000000
+
+/* PCIe CTRL registers */
+#define SOC_PCIECTRL_CTRL7_ADDR			0x01c
+#define SOC_PCIECTRL_CTRL12_ADDR		0x030
+#define SOC_PCIECTRL_CTRL20_ADDR		0x050
+#define SOC_PCIECTRL_CTRL21_ADDR		0x054
+
+#define PCIE_OUTPUT_PULL_BITS			GENMASK(3, 0)
+#define SOC_PCIECTRL_CTRL20_2P_MEM_CTRL		0x02605550
+#define SOC_PCIECTRL_CTRL21_DEFAULT		0x20000070
+#define PCIE_PULL_UP_SYS_AUX_PWR_DET		BIT(10)
+#define PCIE_OUTPUT_PULL_DOWN			BIT(1)
+
+/* PCIe PHY registers */
+#define SOC_PCIEPHY_CTRL0_ADDR			0x000
+#define SOC_PCIEPHY_CTRL1_ADDR			0x004
+#define SOC_PCIEPHY_CTRL38_ADDR			0x0098
+#define SOC_PCIEPHY_STATE0_ADDR			0x400
+
+#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1	0xc004
+#define SUP_DIG_LVL_OVRD_IN			0x003c
+#define LANEN_DIG_ASIC_TX_OVRD_IN_1		0x4008
+#define LANEN_DIG_ASIC_TX_OVRD_IN_2		0x400c
+
+#define PCIEPHY_RESET_BIT			BIT(17)
+#define PCIEPHY_PIPE_LINE0_RESET_BIT		BIT(19)
+#define PCIE_TXDETECT_RX_FAIL			BIT(2)
+#define PCIE_CLK_SOURCE				BIT(8)
+#define PCIE_IS_CLOCK_STABLE			BIT(19)
+#define PCIE_PULL_DOWN_PHY_TEST_POWERDOWN	BIT(22)
+#define PCIE_DEASSERT_CONTROLLER_PERST		BIT(2)
+
+#define EYEPARAM_NOCFG				0xffffffff
+#define EYE_PARM0_MASK				GENMASK(8, 6)
+#define EYE_PARM1_MASK				GENMASK(11, 8)
+#define EYE_PARM2_MASK				GENMASK(5, 0)
+#define EYE_PARM3_MASK				GENMASK(12, 7)
+#define EYE_PARM4_MASK				GENMASK(14, 9)
+#define EYE_PARM0_EN				BIT(9)
+#define EYE_PARM1_EN				BIT(12)
+#define EYE_PARM2_EN				BIT(6)
+#define EYE_PARM3_EN				BIT(13)
+#define EYE_PARM4_EN				BIT(15)
+
+/* hi3670 pciephy register */
+#define APB_PHY_START_ADDR			0x40000
+#define SOC_PCIEPHY_MMC1PLL_CTRL1		0xc04
+#define SOC_PCIEPHY_MMC1PLL_CTRL16		0xC40
+#define SOC_PCIEPHY_MMC1PLL_CTRL17		0xC44
+#define SOC_PCIEPHY_MMC1PLL_CTRL20		0xC50
+#define SOC_PCIEPHY_MMC1PLL_CTRL21		0xC54
+#define SOC_PCIEPHY_MMC1PLL_STAT0		0xE00
+
+#define CRGPERIPH_PEREN12			0x470
+#define CRGPERIPH_PERDIS12			0x474
+#define CRGPERIPH_PCIECTRL0			0x800
+
+#define PCIE_FNPLL_FBDIV_MASK			GENMASK(27, 16)
+#define PCIE_FNPLL_FRACDIV_MASK			GENMASK(23, 0)
+#define PCIE_FNPLL_POSTDIV1_MASK		GENMASK(10, 8)
+#define PCIE_FNPLL_POSTDIV2_MASK		GENMASK(14, 12)
+#define PCIE_FNPLL_PLL_MODE_MASK		BIT(25)
+
+#define PCIE_FNPLL_DLL_EN			BIT(27)
+#define PCIE_FNPLL_FBDIV			0xd0
+#define PCIE_FNPLL_FRACDIV			0x555555
+#define PCIE_FNPLL_POSTDIV1			0x5
+#define PCIE_FNPLL_POSTDIV2			0x4
+#define PCIE_FNPLL_PLL_MODE			0x0
+
+#define PCIE_PHY_MMC1PLL			0x20
+#define PCIE_PHY_CHOOSE_FNPLL			BIT(27)
+#define PCIE_PHY_MMC1PLL_DISABLE		BIT(0)
+#define PCIE_PHY_PCIEPL_BP			BIT(16)
+
+/* define ie,oe cfg */
+#define IO_OE_HARD_GT_MODE			BIT(1)
+#define IO_IE_EN_HARD_BYPASS			BIT(27)
+#define IO_OE_EN_HARD_BYPASS			BIT(11)
+#define IO_HARD_CTRL_DEBOUNCE_BYPASS		BIT(10)
+#define IO_OE_GT_MODE				BIT(8)
+#define DEBOUNCE_WAITCFG_IN			GENMASK(23, 20)
+#define DEBOUNCE_WAITCFG_OUT			GENMASK(16, 13)
+
+#define IO_HP_DEBOUNCE_GT			(BIT(12) | BIT(15))
+#define IO_PHYREF_SOFT_GT_MODE			BIT(14)
+#define IO_REF_SOFT_GT_MODE			BIT(13)
+#define IO_REF_HARD_GT_MODE			BIT(0)
+
+/* noc power domain */
+#define NOC_POWER_IDLEREQ_1			0x38c
+#define NOC_POWER_IDLE_1			0x394
+#define NOC_PW_MASK				0x10000
+#define NOC_PW_SET_BIT				0x1
+
+#define NUM_EYEPARAM				5
+
+/* info located in sysctrl */
+#define SCTRL_PCIE_CMOS_OFFSET			0x60
+#define SCTRL_PCIE_CMOS_BIT			0x10
+#define SCTRL_PCIE_ISO_OFFSET			0x44
+#define SCTRL_PCIE_ISO_BIT			0x30
+#define SCTRL_PCIE_HPCLK_OFFSET			0x190
+#define SCTRL_PCIE_HPCLK_BIT			0x184000
+#define SCTRL_PCIE_OE_OFFSET			0x14a
+#define PCIE_DEBOUNCE_PARAM			0xf0f400
+#define PCIE_OE_BYPASS				GENMASK(29, 28)
+
+/* peri_crg ctrl */
+#define CRGCTRL_PCIE_ASSERT_OFFSET		0x88
+#define CRGCTRL_PCIE_ASSERT_BIT			0x8c000000
+
+#define FNPLL_HAS_LOCKED			BIT(4)
+
+/* Time for delay */
+#define TIME_CMOS_MIN		100
+#define TIME_CMOS_MAX		105
+#define PIPE_CLK_STABLE_TIME	100
+#define PLL_CTRL_WAIT_TIME	200
+#define NOC_POWER_TIME		100
+
+struct hi3670_pcie_phy {
+	struct device	*dev;
+	void __iomem	*base;
+	struct regmap	*apb;
+	struct regmap	*crgctrl;
+	struct regmap	*sysctrl;
+	struct regmap	*pmctrl;
+	struct clk	*apb_sys_clk;
+	struct clk	*apb_phy_clk;
+	struct clk	*phy_ref_clk;
+	struct clk	*aclk;
+	struct clk	*aux_clk;
+	u32		eye_param[NUM_EYEPARAM];
+};
+
+/* Registers in PCIePHY */
+static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy, u32 val,
+					 u32 reg)
+{
+	writel(val, phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
+{
+	return readl(phy->base + APB_PHY_START_ADDR + reg);
+}
+
+static inline void hi3670_apb_phy_updatel(struct hi3670_pcie_phy *phy,
+					  u32 val, u32 mask, u32 reg)
+{
+	u32 regval;
+
+	regval = hi3670_apb_phy_readl(phy, reg);
+	regval &= ~mask;
+	regval |= val;
+	hi3670_apb_phy_writel(phy, regval, reg);
+}
+
+static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
+						u32 val, u32 reg)
+{
+	writel(val, phy->base + reg);
+}
+
+static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
+					      u32 reg)
+{
+	return readl(phy->base + reg);
+}
+
+static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
+{
+	u32 val;
+
+	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
+	val |= PCIE_DEBOUNCE_PARAM;
+	if (enable)
+		val &= ~PCIE_OE_BYPASS;
+	else
+		val |= PCIE_OE_BYPASS;
+	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
+}
+
+static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np;
+	int ret, i;
+
+	np = dev->of_node;
+
+	ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
+					 phy->eye_param, NUM_EYEPARAM);
+	if (!ret)
+		return;
+
+	/* There's no optional eye_param property. Set array to default */
+	for (i = 0; i < NUM_EYEPARAM; i++)
+		phy->eye_param[i] = EYEPARAM_NOCFG;
+}
+
+static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	val = kirin_apb_natural_phy_readl(phy, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	if (phy->eye_param[1] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM1_MASK;
+		val |= FIELD_PREP(EYE_PARM1_MASK, phy->eye_param[1]);
+		val |= EYE_PARM1_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val,
+				     RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+	val &= ~(EYE_PARM2_MASK | EYE_PARM3_MASK);
+	if (phy->eye_param[2] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM2_MASK, phy->eye_param[2]);
+		val |= EYE_PARM2_EN;
+	}
+
+	if (phy->eye_param[3] != EYEPARAM_NOCFG) {
+		val |= FIELD_PREP(EYE_PARM3_MASK, phy->eye_param[3]);
+		val |= EYE_PARM3_EN;
+	}
+
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
+
+	val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
+	if (phy->eye_param[0] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM0_MASK;
+		val |= FIELD_PREP(EYE_PARM0_MASK, phy->eye_param[0]);
+		val |= EYE_PARM0_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
+
+	val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+	if (phy->eye_param[4] != EYEPARAM_NOCFG) {
+		val &= ~EYE_PARM4_MASK;
+		val |= FIELD_PREP(EYE_PARM4_MASK, phy->eye_param[4]);
+		val |= EYE_PARM4_EN;
+	}
+	kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
+}
+
+static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
+{
+	u32 val;
+
+	/* change 2p mem_ctrl */
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
+		     SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
+
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
+	val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
+
+	/* output, pull down */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val &= ~PCIE_OUTPUT_PULL_BITS;
+	val |= PCIE_OUTPUT_PULL_DOWN;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+
+	/* Handle phy_reset and lane0_reset to HW */
+	hi3670_apb_phy_updatel(phy, PCIEPHY_RESET_BIT,
+			       PCIEPHY_PIPE_LINE0_RESET_BIT | PCIEPHY_RESET_BIT,
+			       SOC_PCIEPHY_CTRL1_ADDR);
+
+	/* fix chip bug: TxDetectRx fail */
+	hi3670_apb_phy_updatel(phy, PCIE_TXDETECT_RX_FAIL, PCIE_TXDETECT_RX_FAIL,
+			       SOC_PCIEPHY_CTRL38_ADDR);
+}
+
+static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
+{
+	hi3670_apb_phy_updatel(phy, PCIE_PHY_CHOOSE_FNPLL, PCIE_PHY_CHOOSE_FNPLL,
+			       SOC_PCIEPHY_MMC1PLL_CTRL1);
+
+	hi3670_apb_phy_updatel(phy,
+			       FIELD_PREP(PCIE_FNPLL_FBDIV_MASK, PCIE_FNPLL_FBDIV),
+			       PCIE_FNPLL_FBDIV_MASK,
+			       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+	hi3670_apb_phy_updatel(phy,
+			       FIELD_PREP(PCIE_FNPLL_FRACDIV_MASK, PCIE_FNPLL_FRACDIV),
+			       PCIE_FNPLL_FRACDIV_MASK, SOC_PCIEPHY_MMC1PLL_CTRL17);
+
+	hi3670_apb_phy_updatel(phy,
+			       PCIE_FNPLL_DLL_EN |
+			       FIELD_PREP(PCIE_FNPLL_POSTDIV1_MASK, PCIE_FNPLL_POSTDIV1) |
+			       FIELD_PREP(PCIE_FNPLL_POSTDIV2_MASK, PCIE_FNPLL_POSTDIV2) |
+			       FIELD_PREP(PCIE_FNPLL_PLL_MODE_MASK, PCIE_FNPLL_PLL_MODE),
+			       PCIE_FNPLL_POSTDIV1_MASK |
+			       PCIE_FNPLL_POSTDIV2_MASK |
+			       PCIE_FNPLL_PLL_MODE_MASK | PCIE_FNPLL_DLL_EN,
+			       SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	hi3670_apb_phy_writel(phy, PCIE_PHY_MMC1PLL,
+			      SOC_PCIEPHY_MMC1PLL_CTRL21);
+}
+
+static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	int time = PLL_CTRL_WAIT_TIME;
+
+	if (enable) {
+		/* pd = 0 */
+		hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_MMC1PLL_DISABLE,
+				       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		/* choose FNPLL */
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+		while (!(val & FNPLL_HAS_LOCKED)) {
+			if (!time) {
+				dev_err(dev, "wait for pll_lock timeout\n");
+				return -EINVAL;
+			}
+			time--;
+			udelay(1);
+			val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
+		}
+
+		hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_PCIEPL_BP,
+				       SOC_PCIEPHY_MMC1PLL_CTRL20);
+
+	} else {
+		hi3670_apb_phy_updatel(phy,
+				       PCIE_PHY_MMC1PLL_DISABLE,
+				       PCIE_PHY_MMC1PLL_DISABLE,
+				       SOC_PCIEPHY_MMC1PLL_CTRL16);
+
+		hi3670_apb_phy_updatel(phy, PCIE_PHY_PCIEPL_BP,
+				       PCIE_PHY_PCIEPL_BP,
+				       SOC_PCIEPHY_MMC1PLL_CTRL20);
+	}
+
+	return 0;
+}
+
+static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	if (open)
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
+		regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
+			     IO_HP_DEBOUNCE_GT);
+	else
+		/* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_HP_DEBOUNCE_GT);
+}
+
+static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	if (open)
+		val &= ~IO_OE_HARD_GT_MODE; /* enable hard gt mode */
+	else
+		val |= IO_OE_HARD_GT_MODE; /* disable hard gt mode */
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+	/* disable soft gt mode */
+	regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, IO_PHYREF_SOFT_GT_MODE);
+}
+
+static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
+{
+	unsigned int val;
+
+	regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+
+	/* set ie cfg */
+	val |= IO_IE_EN_HARD_BYPASS;
+
+	/* set oe cfg */
+	val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
+
+	/* set phy_debounce in&out time */
+	val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
+
+	/* select oe_gt_mode */
+	val |= IO_OE_GT_MODE;
+
+	if (en_flag)
+		val &= ~IO_OE_EN_HARD_BYPASS;
+	else
+		val |= IO_OE_EN_HARD_BYPASS;
+
+	regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+}
+
+static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
+{
+	unsigned int val;
+
+	if (open) {
+		regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR,
+			     SOC_PCIECTRL_CTRL21_DEFAULT);
+
+		hi3670_pcie_oe_ctrl(phy, true);
+
+		/* en hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val &= ~IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+	} else {
+		/* disable hard gt mode */
+		regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
+		val |= IO_REF_HARD_GT_MODE;
+		regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
+
+		/* disable soft gt mode */
+		regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
+			     IO_REF_SOFT_GT_MODE);
+
+		hi3670_pcie_oe_ctrl(phy, false);
+	}
+}
+
+static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
+{
+	struct device *dev = phy->dev;
+	int ret = 0;
+
+	if (!clk_on)
+		goto close_clocks;
+
+	/* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
+	hi3670_apb_phy_updatel(phy, 0, PCIE_CLK_SOURCE,
+			       SOC_PCIEPHY_CTRL1_ADDR);
+
+	hi3670_pcie_pll_init(phy);
+
+	ret = hi3670_pcie_pll_ctrl(phy, true);
+	if (ret) {
+		dev_err(dev, "Failed to enable pll\n");
+		return -EINVAL;
+	}
+	hi3670_pcie_hp_debounce_gt(phy, true);
+	hi3670_pcie_phyref_gt(phy, true);
+	hi3670_pcie_ioref_gt(phy, true);
+
+	ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
+	if (ret) {
+		dev_err(dev, "Failed to set rate\n");
+		goto close_clocks;
+	}
+
+	return 0;
+
+close_clocks:
+	hi3670_pcie_ioref_gt(phy, false);
+	hi3670_pcie_phyref_gt(phy, false);
+	hi3670_pcie_hp_debounce_gt(phy, false);
+
+	hi3670_pcie_pll_ctrl(phy, false);
+
+	return ret;
+}
+
+static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
+{
+	struct device *dev = phy->dev;
+	u32 val;
+	u32 time = PIPE_CLK_STABLE_TIME;
+	u32 pipe_clk_stable = PCIE_IS_CLOCK_STABLE;
+
+	val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	while (val & pipe_clk_stable) {
+		mdelay(1);
+		if (!time) {
+			dev_err(dev, "PIPE clk is not stable\n");
+			return false;
+		}
+		time--;
+		val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
+	}
+
+	return true;
+}
+
+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
+{
+	struct device *dev = phy->dev;
+	u32 time = NOC_POWER_TIME;
+	unsigned int val = NOC_PW_MASK;
+	int rst;
+
+	if (enable)
+		val = NOC_PW_MASK | NOC_PW_SET_BIT;
+	else
+		val = NOC_PW_MASK;
+	rst = enable ? 1 : 0;
+
+	regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
+
+	time = NOC_POWER_TIME;
+	regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	while ((val & NOC_PW_SET_BIT) != rst) {
+		udelay(10);
+		if (!time) {
+			dev_err(dev, "Failed to reverse noc power-status\n");
+			return -EINVAL;
+		}
+		time--;
+		regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
+	}
+
+	return 0;
+}
+
+static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
+{
+	struct device_node *pcie_port;
+	struct device *dev = phy->dev;
+	struct device *pcie_dev;
+
+	pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
+	if (!pcie_port) {
+		dev_err(dev, "no pcie node found in %s\n",
+			dev->parent->of_node->full_name);
+		return -ENODEV;
+	}
+
+	pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
+	if (!pcie_dev) {
+		dev_err(dev, "Didn't find pcie device\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * We might just use NULL instead of the APB name, as the
+	 * pcie-kirin currently registers directly just one regmap (although
+	 * the DWC driver register other regmaps).
+	 *
+	 * Yet, it sounds safer to warrant that it will be accessing the
+	 * right regmap. So, let's use the named version.
+	 */
+	phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
+	if (!phy->apb) {
+		dev_err(dev, "Failed to get APB regmap\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto close_clk;
+
+	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->phy_ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->apb_sys_clk);
+	if (ret)
+		goto apb_sys_fail;
+
+	ret = clk_prepare_enable(phy->apb_phy_clk);
+	if (ret)
+		goto apb_phy_fail;
+
+	ret = clk_prepare_enable(phy->aclk);
+	if (ret)
+		goto aclk_fail;
+
+	ret = clk_prepare_enable(phy->aux_clk);
+	if (ret)
+		goto aux_clk_fail;
+
+	return 0;
+
+close_clk:
+	clk_disable_unprepare(phy->aux_clk);
+aux_clk_fail:
+	clk_disable_unprepare(phy->aclk);
+aclk_fail:
+	clk_disable_unprepare(phy->apb_phy_clk);
+apb_phy_fail:
+	clk_disable_unprepare(phy->apb_sys_clk);
+apb_sys_fail:
+	clk_disable_unprepare(phy->phy_ref_clk);
+
+	return ret;
+}
+
+static int hi3670_pcie_phy_init(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int ret;
+
+	/*
+	 * The code under hi3670_pcie_get_resources_from_pcie() need to
+	 * access the reset-gpios and the APB registers, both from the
+	 * pcie-kirin driver.
+	 *
+	 * The APB is obtained via the pcie driver's regmap
+	 * Such kind of resource can only be obtained during the PCIe
+	 * power_on sequence, as the code inside pcie-kirin needs to
+	 * be already probed, as it needs to register the APB regmap.
+	 */
+
+	ret = hi3670_pcie_get_resources_from_pcie(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+	int val, ret;
+
+	/* Power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
+	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
+
+	hi3670_pcie_phy_oe_enable(phy, true);
+
+	ret = kirin_pcie_clk_ctrl(phy, true);
+	if (ret)
+		return ret;
+
+	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
+	regmap_write(phy->crgctrl, CRGCTRL_PCIE_ASSERT_OFFSET,
+		     CRGCTRL_PCIE_ASSERT_BIT);
+	regmap_write(phy->sysctrl, SCTRL_PCIE_HPCLK_OFFSET,
+		     SCTRL_PCIE_HPCLK_BIT);
+
+	hi3670_pcie_natural_cfg(phy);
+
+	ret = hi3670_pcie_allclk_ctrl(phy, true);
+	if (ret)
+		goto disable_clks;
+
+	/* pull down phy_test_powerdown signal */
+	hi3670_apb_phy_updatel(phy, 0, PCIE_PULL_DOWN_PHY_TEST_POWERDOWN,
+			       SOC_PCIEPHY_CTRL0_ADDR);
+
+	/* deassert controller perst_n */
+	regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
+	val |= PCIE_DEASSERT_CONTROLLER_PERST;
+	regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
+	udelay(10);
+
+	ret = is_pipe_clk_stable(phy);
+	if (!ret)
+		goto disable_clks;
+
+	hi3670_pcie_set_eyeparam(phy);
+
+	ret = hi3670_pcie_noc_power(phy, false);
+	if (ret)
+		goto disable_clks;
+
+	return 0;
+
+disable_clks:
+	kirin_pcie_clk_ctrl(phy, false);
+	return ret;
+}
+
+static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
+{
+	struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
+
+	hi3670_pcie_phy_oe_enable(phy, false);
+
+	hi3670_pcie_allclk_ctrl(phy, false);
+
+	/* Drop power supply for Host */
+	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
+
+	/*
+	 * FIXME: The enabled clocks should be disabled here by calling
+	 * kirin_pcie_clk_ctrl(phy, false);
+	 * However, some clocks used at Kirin 970 should be marked as
+	 * CLK_IS_CRITICAL at clk-hi3670 driver, as powering such clocks off
+	 * cause an Asynchronous SError interrupt, which produces panic().
+	 * While clk-hi3670 is not fixed, we cannot risk disabling clocks here.
+	 */
+
+	return 0;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+	.init		= hi3670_pcie_phy_init,
+	.power_on	= hi3670_pcie_phy_power_on,
+	.power_off	= hi3670_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
+					 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* syscon */
+	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
+	if (IS_ERR(phy->crgctrl))
+		return PTR_ERR(phy->crgctrl);
+
+	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
+	if (IS_ERR(phy->sysctrl))
+		return PTR_ERR(phy->sysctrl);
+
+	/* clocks */
+	phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
+	if (IS_ERR(phy->phy_ref_clk))
+		return PTR_ERR(phy->phy_ref_clk);
+
+	phy->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(phy->aux_clk))
+		return PTR_ERR(phy->aux_clk);
+
+	phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
+	if (IS_ERR(phy->apb_phy_clk))
+		return PTR_ERR(phy->apb_phy_clk);
+
+	phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
+	if (IS_ERR(phy->apb_sys_clk))
+		return PTR_ERR(phy->apb_sys_clk);
+
+	phy->aclk = devm_clk_get(dev, "aclk");
+	if (IS_ERR(phy->aclk))
+		return PTR_ERR(phy->aclk);
+
+	/* registers */
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	hi3670_pcie_get_eyeparam(phy);
+
+	return 0;
+}
+
+static int hi3670_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct hi3670_pcie_phy *phy;
+	struct phy *generic_phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+
+	ret = hi3670_pcie_phy_get_resources(phy, pdev);
+	if (ret)
+		return ret;
+
+	generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_pcie_phy_match[] = {
+	{
+		.compatible = "hisilicon,hi970-pcie-phy",
+	},
+	{},
+};
+
+static struct platform_driver hi3670_pcie_phy_driver = {
+	.probe	= hi3670_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= hi3670_pcie_phy_match,
+		.name		= "hi3670_pcie_phy",
+		.suppress_bind_attrs = true,
+	}
+};
+builtin_platform_driver(hi3670_pcie_phy_driver);
+
+MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
+MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab at kernel.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <mani at kernel.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1




From gregkh at linuxfoundation.org  Tue Aug 24 06:36:02 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 24 Aug 2021 15:36:02 +0200
Subject: [GIT PULL]: Generic phy updates for v5.15
In-Reply-To: <YSR/UHNxE6iu3GBc@matsya>
References: <YSR/UHNxE6iu3GBc@matsya>
Message-ID: <YST1wr4RGKnt9RDK@kroah.com>

On Tue, Aug 24, 2021 at 10:40:40AM +0530, Vinod Koul wrote:
> Hello Greg,
> 
> Here is the update for v5.15, sorry this time it is bit late than
> normal. Will make sure this hits early next time.
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git tags/phy-for-5.15

Pulled and pushed out, thanks.

greg k-h


From robh at kernel.org  Tue Aug 24 13:20:14 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 15:20:14 -0500
Subject: [PATCH] dt-bindings: Use 'enum' instead of 'oneOf' plus 'const'
 entries
Message-ID: <20210824202014.978922-1-robh@kernel.org>

'enum' is equivalent to 'oneOf' with a list of 'const' entries, but 'enum'
is more concise and yields better error messages.

Cc: Vinod Koul <vkoul at kernel.org>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Vignesh R <vigneshr at ti.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab at kernel.org>
Cc: Lee Jones <lee.jones at linaro.org>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Jakub Kicinski <kuba at kernel.org>
Cc: Bjorn Helgaas <bhelgaas at google.com>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Mark Brown <broonie at kernel.org>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: dmaengine at vger.kernel.org
Cc: linux-i2c at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: linux-phy at lists.infradead.org
Cc: linux-serial at vger.kernel.org
Cc: alsa-devel at alsa-project.org
Cc: linux-spi at vger.kernel.org
Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../bindings/display/msm/dsi-phy-10nm.yaml           |  6 +++---
 .../bindings/display/msm/dsi-phy-14nm.yaml           |  6 +++---
 .../bindings/display/msm/dsi-phy-28nm.yaml           |  8 ++++----
 .../bindings/dma/allwinner,sun6i-a31-dma.yaml        | 12 ++++++------
 .../devicetree/bindings/firmware/arm,scpi.yaml       |  6 +++---
 .../devicetree/bindings/i2c/ti,omap4-i2c.yaml        | 10 +++++-----
 .../interrupt-controller/loongson,liointc.yaml       |  8 ++++----
 .../devicetree/bindings/media/i2c/mipi-ccs.yaml      |  8 ++++----
 .../devicetree/bindings/mfd/ti,lp87565-q1.yaml       |  6 +++---
 .../devicetree/bindings/net/realtek-bluetooth.yaml   |  8 ++++----
 .../bindings/net/ti,k3-am654-cpsw-nuss.yaml          |  8 ++++----
 .../devicetree/bindings/net/ti,k3-am654-cpts.yaml    |  6 +++---
 Documentation/devicetree/bindings/pci/loongson.yaml  |  8 ++++----
 .../devicetree/bindings/phy/intel,lgm-emmc-phy.yaml  |  6 +++---
 .../devicetree/bindings/serial/8250_omap.yaml        |  9 +++++----
 .../devicetree/bindings/sound/qcom,sm8250.yaml       |  6 +++---
 .../devicetree/bindings/sound/tlv320adcx140.yaml     |  8 ++++----
 .../devicetree/bindings/spi/realtek,rtl-spi.yaml     | 12 ++++++------
 .../devicetree/bindings/timer/arm,sp804.yaml         |  6 +++---
 19 files changed, 74 insertions(+), 73 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
index 4a26bef19360..4399715953e1 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
@@ -14,9 +14,9 @@ allOf:
 
 properties:
   compatible:
-    oneOf:
-      - const: qcom,dsi-phy-10nm
-      - const: qcom,dsi-phy-10nm-8998
+    enum:
+      - qcom,dsi-phy-10nm
+      - qcom,dsi-phy-10nm-8998
 
   reg:
     items:
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml
index 72a00cce0147..064df50e21a5 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml
@@ -14,9 +14,9 @@ allOf:
 
 properties:
   compatible:
-    oneOf:
-      - const: qcom,dsi-phy-14nm
-      - const: qcom,dsi-phy-14nm-660
+    enum:
+      - qcom,dsi-phy-14nm
+      - qcom,dsi-phy-14nm-660
 
   reg:
     items:
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
index b106007116b4..69eecaa64b18 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
@@ -14,10 +14,10 @@ allOf:
 
 properties:
   compatible:
-    oneOf:
-      - const: qcom,dsi-phy-28nm-hpm
-      - const: qcom,dsi-phy-28nm-lp
-      - const: qcom,dsi-phy-28nm-8960
+    enum:
+      - qcom,dsi-phy-28nm-hpm
+      - qcom,dsi-phy-28nm-lp
+      - qcom,dsi-phy-28nm-8960
 
   reg:
     items:
diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
index c1676b96daac..a6df6f8b54db 100644
--- a/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
@@ -19,12 +19,12 @@ properties:
     description: The cell is the request line number.
 
   compatible:
-    oneOf:
-      - const: allwinner,sun6i-a31-dma
-      - const: allwinner,sun8i-a23-dma
-      - const: allwinner,sun8i-a83t-dma
-      - const: allwinner,sun8i-h3-dma
-      - const: allwinner,sun8i-v3s-dma
+    enum:
+      - allwinner,sun6i-a31-dma
+      - allwinner,sun8i-a23-dma
+      - allwinner,sun8i-a83t-dma
+      - allwinner,sun8i-h3-dma
+      - allwinner,sun8i-v3s-dma
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/firmware/arm,scpi.yaml b/Documentation/devicetree/bindings/firmware/arm,scpi.yaml
index d7113b06454b..23b346bd1252 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scpi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scpi.yaml
@@ -131,9 +131,9 @@ properties:
 
         properties:
           compatible:
-            oneOf:
-              - const: arm,scpi-dvfs-clocks
-              - const: arm,scpi-variable-clocks
+            enum:
+              - arm,scpi-dvfs-clocks
+              - arm,scpi-variable-clocks
 
           '#clock-cells':
             const: 1
diff --git a/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
index ff165ad1bee8..db0843be91c5 100644
--- a/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
@@ -72,11 +72,11 @@ additionalProperties: false
 if:
   properties:
     compatible:
-      oneOf:
-        - const: ti,omap2420-i2c
-        - const: ti,omap2430-i2c
-        - const: ti,omap3-i2c
-        - const: ti,omap4-i2c
+      enum:
+        - ti,omap2420-i2c
+        - ti,omap2430-i2c
+        - ti,omap3-i2c
+        - ti,omap4-i2c
 
 then:
   properties:
diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
index edf26452dc72..750cc44628e9 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
@@ -19,10 +19,10 @@ allOf:
 
 properties:
   compatible:
-    oneOf:
-      - const: loongson,liointc-1.0
-      - const: loongson,liointc-1.0a
-      - const: loongson,liointc-2.0
+    enum:
+      - loongson,liointc-1.0
+      - loongson,liointc-1.0a
+      - loongson,liointc-2.0
 
   reg:
     minItems: 1
diff --git a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml
index 701f4e0d138f..39395ea8c318 100644
--- a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml
@@ -83,10 +83,10 @@ properties:
           link-frequencies: true
           data-lanes: true
           bus-type:
-            oneOf:
-              - const: 1 # CSI-2 C-PHY
-              - const: 3 # CCP2
-              - const: 4 # CSI-2 D-PHY
+            enum:
+              - 1 # CSI-2 C-PHY
+              - 3 # CCP2
+              - 4 # CSI-2 D-PHY
 
         required:
           - link-frequencies
diff --git a/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml b/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
index 48d4d53c25f9..012d25111054 100644
--- a/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
@@ -11,9 +11,9 @@ maintainers:
 
 properties:
   compatible:
-    oneOf:
-      - const: ti,lp87565
-      - const: ti,lp87565-q1
+    enum:
+      - ti,lp87565
+      - ti,lp87565-q1
 
   reg:
     description: I2C slave address
diff --git a/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml b/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml
index 4f485df69ac3..0634e69dd9a6 100644
--- a/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml
+++ b/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml
@@ -17,10 +17,10 @@ description:
 
 properties:
   compatible:
-    oneOf:
-      - const: "realtek,rtl8723bs-bt"
-      - const: "realtek,rtl8723cs-bt"
-      - const: "realtek,rtl8822cs-bt"
+    enum:
+      - realtek,rtl8723bs-bt
+      - realtek,rtl8723cs-bt
+      - realtek,rtl8822cs-bt
 
   device-wake-gpios:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml
index 783b9e32cf66..4b97a0f1175b 100644
--- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml
+++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml
@@ -53,10 +53,10 @@ properties:
   "#size-cells": true
 
   compatible:
-    oneOf:
-      - const: ti,am654-cpsw-nuss
-      - const: ti,j721e-cpsw-nuss
-      - const: ti,am642-cpsw-nuss
+    enum:
+      - ti,am654-cpsw-nuss
+      - ti,j721e-cpsw-nuss
+      - ti,am642-cpsw-nuss
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml
index 4317eba503ca..1a81bf70c88c 100644
--- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml
+++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml
@@ -45,9 +45,9 @@ properties:
     pattern: "^cpts@[0-9a-f]+$"
 
   compatible:
-    oneOf:
-      - const: ti,am65-cpts
-      - const: ti,j721e-cpts
+    enum:
+      - ti,am65-cpts
+      - ti,j721e-cpts
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/pci/loongson.yaml b/Documentation/devicetree/bindings/pci/loongson.yaml
index 82bc6c486ca3..a8324a9bd002 100644
--- a/Documentation/devicetree/bindings/pci/loongson.yaml
+++ b/Documentation/devicetree/bindings/pci/loongson.yaml
@@ -17,10 +17,10 @@ allOf:
 
 properties:
   compatible:
-    oneOf:
-      - const: loongson,ls2k-pci
-      - const: loongson,ls7a-pci
-      - const: loongson,rs780e-pci
+    enum:
+      - loongson,ls2k-pci
+      - loongson,ls7a-pci
+      - loongson,rs780e-pci
 
   reg:
     minItems: 1
diff --git a/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml b/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
index edd9d70a672a..954e67571dfd 100644
--- a/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
@@ -23,9 +23,9 @@ description: |+
 
 properties:
   compatible:
-    oneOf:
-      - const: intel,lgm-emmc-phy
-      - const: intel,keembay-emmc-phy
+    enum:
+      - intel,lgm-emmc-phy
+      - intel,keembay-emmc-phy
 
   "#phy-cells":
     const: 0
diff --git a/Documentation/devicetree/bindings/serial/8250_omap.yaml b/Documentation/devicetree/bindings/serial/8250_omap.yaml
index 1c826fcf5828..c987fb648c3c 100644
--- a/Documentation/devicetree/bindings/serial/8250_omap.yaml
+++ b/Documentation/devicetree/bindings/serial/8250_omap.yaml
@@ -90,10 +90,11 @@ additionalProperties: false
 if:
   properties:
     compatible:
-      oneOf:
-        - const: ti,omap2-uart
-        - const: ti,omap3-uart
-        - const: ti,omap4-uart
+      contains:
+        enum:
+          - ti,omap2-uart
+          - ti,omap3-uart
+          - ti,omap4-uart
 
 then:
   properties:
diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
index 72ad9ab91832..7d57eb91657a 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -15,9 +15,9 @@ description:
 
 properties:
   compatible:
-    oneOf:
-      - const: qcom,sm8250-sndcard
-      - const: qcom,qrb5165-rb5-sndcard
+    enum:
+      - qcom,sm8250-sndcard
+      - qcom,qrb5165-rb5-sndcard
 
   audio-routing:
     $ref: /schemas/types.yaml#/definitions/non-unique-string-array
diff --git a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
index 54d64785aad2..d77c8283526d 100644
--- a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
+++ b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
@@ -24,10 +24,10 @@ description: |
 
 properties:
   compatible:
-    oneOf:
-      - const: ti,tlv320adc3140
-      - const: ti,tlv320adc5140
-      - const: ti,tlv320adc6140
+    enum:
+      - ti,tlv320adc3140
+      - ti,tlv320adc5140
+      - ti,tlv320adc6140
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml b/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml
index 30a62a211984..2f938c293f70 100644
--- a/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml
+++ b/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml
@@ -15,12 +15,12 @@ allOf:
 
 properties:
   compatible:
-    oneOf:
-      - const: realtek,rtl8380-spi
-      - const: realtek,rtl8382-spi
-      - const: realtek,rtl8391-spi
-      - const: realtek,rtl8392-spi
-      - const: realtek,rtl8393-spi
+    enum:
+      - realtek,rtl8380-spi
+      - realtek,rtl8382-spi
+      - realtek,rtl8391-spi
+      - realtek,rtl8392-spi
+      - realtek,rtl8393-spi
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/timer/arm,sp804.yaml b/Documentation/devicetree/bindings/timer/arm,sp804.yaml
index 960e2bd66a97..41be7cdab2ec 100644
--- a/Documentation/devicetree/bindings/timer/arm,sp804.yaml
+++ b/Documentation/devicetree/bindings/timer/arm,sp804.yaml
@@ -23,9 +23,9 @@ select:
   properties:
     compatible:
       contains:
-        oneOf:
-          - const: arm,sp804
-          - const: hisilicon,sp804
+        enum:
+          - arm,sp804
+          - hisilicon,sp804
   required:
     - compatible
 
-- 
2.30.2



From sakari.ailus at linux.intel.com  Wed Aug 25 01:17:47 2021
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Wed, 25 Aug 2021 11:17:47 +0300
Subject: [PATCH] dt-bindings: Use 'enum' instead of 'oneOf' plus 'const'
 entries
In-Reply-To: <20210824202014.978922-1-robh@kernel.org>
References: <20210824202014.978922-1-robh@kernel.org>
Message-ID: <20210825081747.GO3@paasikivi.fi.intel.com>

Hi Rob,

Thanks for the patch.

On Tue, Aug 24, 2021 at 03:20:14PM -0500, Rob Herring wrote:
> 'enum' is equivalent to 'oneOf' with a list of 'const' entries, but 'enum'
> is more concise and yields better error messages.
> 
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Vignesh R <vigneshr at ti.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
> Cc: Mauro Carvalho Chehab <mchehab at kernel.org>
> Cc: Lee Jones <lee.jones at linaro.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: Jakub Kicinski <kuba at kernel.org>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: dmaengine at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: linux-pci at vger.kernel.org
> Cc: linux-phy at lists.infradead.org
> Cc: linux-serial at vger.kernel.org
> Cc: alsa-devel at alsa-project.org
> Cc: linux-spi at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>

Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com> (mipi-ccs)

-- 
Sakari Ailus


From broonie at kernel.org  Wed Aug 25 03:27:01 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed, 25 Aug 2021 11:27:01 +0100
Subject: [PATCH] dt-bindings: Use 'enum' instead of 'oneOf' plus 'const'
 entries
In-Reply-To: <20210824202014.978922-1-robh@kernel.org>
References: <20210824202014.978922-1-robh@kernel.org>
Message-ID: <20210825102701.GB5186@sirena.org.uk>

On Tue, Aug 24, 2021 at 03:20:14PM -0500, Rob Herring wrote:

> 'enum' is equivalent to 'oneOf' with a list of 'const' entries, but 'enum'
> is more concise and yields better error messages.

Acked-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20210825/2ead9d42/attachment.sig>

From baruch at tkos.co.il  Wed Aug 25 04:15:38 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 14:15:38 +0300
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
Message-ID: <87o89lahqp.fsf@tarshish>

Hi Rob,

On Fri, Aug 06 2021, Rob Herring wrote:
> On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>>
>> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>>
>> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
>> platform.
>>
>> The code is based on downstream Codeaurora kernel v5.4. Split out the
>> DBI registers access part from .init into .post_init. DBI registers are
>> only accessible after phy_power_on().
>>
>> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
>> ---
>> v2:
>>   * Drop ATU configuration; rely on common code instead
>>
>>   * Use more common register macros
>>
>>   * Use bulk clk and reset APIs
>> ---
>>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>>  drivers/pci/controller/dwc/pcie-qcom.c       | 150 +++++++++++++++++++
>>  2 files changed, 151 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index ceb359b6e6a6..346462c74a3e 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -76,6 +76,7 @@
>>
>>  #define GEN3_RELATED_OFF                       0x890
>>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL   BIT(0)
>> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS    BIT(13)
>>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 8a7a300163e5..93766aee3e7c 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -52,6 +52,10 @@
>>  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
>>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
>>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
>> +#define AHB_CLK_EN                             BIT(0)
>> +#define MSTR_AXI_CLK_EN                                BIT(1)
>> +#define BYPASS                                 BIT(4)
>> +
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
>>  #define PCIE20_PARF_LTSSM                      0x1B0
>> @@ -94,6 +98,12 @@
>>  #define SLV_ADDR_SPACE_SZ                      0x10000000
>>
>>  #define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
>> +#define PCIE_CAP_CURR_DEEMPHASIS               BIT(16)
>
> Isn't this a standard register field?

I don't know. I could not find any reference to this field or the
registers it's part of.
n
>> +#define SPEED_GEN1                             0x1
>> +#define SPEED_GEN2                             0x2
>> +#define SPEED_GEN3                             0x3
>
> And these?
>
> There's already some common DWC code for setting the link speed.

dw_pcie_link_set_max_speed() deals with other registers, as far as I can
see.

>> +#define AXI_CLK_RATE                           200000000
>> +#define RCHNG_CLK_RATE                         100000000
>>
>>  #define DEVICE_TYPE_RC                         0x4

[snip]

>> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +       struct dw_pcie *pci = pcie->pci;
>> +       u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>> +       u32 val;
>> +       int i;
>> +
>> +       writel(SLV_ADDR_SPACE_SZ,
>> +               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
>> +
>> +       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +       val &= ~BIT(0);
>> +       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +
>> +       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
>> +
>> +       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
>> +       writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
>> +               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
>> +       writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
>> +               | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
>> +               pci->dbi_base + GEN3_RELATED_OFF);
>> +
>> +       writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
>> +               | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
>> +               AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
>> +               pcie->parf + PCIE20_PARF_SYS_CTRL);
>> +
>> +       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
>> +
>> +       dw_pcie_dbi_ro_wr_en(pci);
>> +       writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
>> +
>> +       /* Configure PCIe link capabilities for ASPM */
>> +       val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +       val &= ~PCI_EXP_LNKCAP_ASPMS;
>> +       writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +
>> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
>> +                       PCI_EXP_DEVCTL2);
>> +
>> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
>> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
>
> Doesn't this overwrite the prior register write?

It does. There are two mistakes here. The writel() above should set
PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98). This writel() should set
PCIE20_LNK_CONTROL2_LINK_STATUS2 (offset 0xa0). So both are wrong.

>> +
>> +       for (i = 0;i < 256;i++)
>> +               writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
>> +                               + (4 * i));
>> +
>> +       return 0;
>> +}

Thanks,
baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From robh+dt at kernel.org  Wed Aug 25 06:38:24 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 08:38:24 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <87o89lahqp.fsf@tarshish>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
 <87o89lahqp.fsf@tarshish>
Message-ID: <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>

On Wed, Aug 25, 2021 at 6:25 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> Hi Rob,
>
> On Fri, Aug 06 2021, Rob Herring wrote:
> > On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
> >>
> >> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> >>
> >> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> >> platform.
> >>
> >> The code is based on downstream Codeaurora kernel v5.4. Split out the
> >> DBI registers access part from .init into .post_init. DBI registers are
> >> only accessible after phy_power_on().
> >>
> >> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> >> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> >> ---
> >> v2:
> >>   * Drop ATU configuration; rely on common code instead
> >>
> >>   * Use more common register macros
> >>
> >>   * Use bulk clk and reset APIs
> >> ---
> >>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
> >>  drivers/pci/controller/dwc/pcie-qcom.c       | 150 +++++++++++++++++++
> >>  2 files changed, 151 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> >> index ceb359b6e6a6..346462c74a3e 100644
> >> --- a/drivers/pci/controller/dwc/pcie-designware.h
> >> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> >> @@ -76,6 +76,7 @@
> >>
> >>  #define GEN3_RELATED_OFF                       0x890
> >>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL   BIT(0)
> >> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS    BIT(13)
> >>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
> >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
> >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
> >> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> >> index 8a7a300163e5..93766aee3e7c 100644
> >> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> >> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> >> @@ -52,6 +52,10 @@
> >>  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
> >>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
> >>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
> >> +#define AHB_CLK_EN                             BIT(0)
> >> +#define MSTR_AXI_CLK_EN                                BIT(1)
> >> +#define BYPASS                                 BIT(4)
> >> +
> >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
> >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
> >>  #define PCIE20_PARF_LTSSM                      0x1B0
> >> @@ -94,6 +98,12 @@
> >>  #define SLV_ADDR_SPACE_SZ                      0x10000000
> >>
> >>  #define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
> >> +#define PCIE_CAP_CURR_DEEMPHASIS               BIT(16)
> >
> > Isn't this a standard register field?
>
> I don't know. I could not find any reference to this field or the
> registers it's part of.

It is. I found it in the spec. But it's not in pci_reg.h and it is a
read-only status bit (though some in DWC can be written).

> n
> >> +#define SPEED_GEN1                             0x1
> >> +#define SPEED_GEN2                             0x2
> >> +#define SPEED_GEN3                             0x3
> >
> > And these?

#define PCI_EXP_LNKCTL2         48      /* Link Control 2 */
#define  PCI_EXP_LNKCTL2_TLS            0x000f
#define  PCI_EXP_LNKCTL2_TLS_2_5GT      0x0001 /* Supported Speed 2.5GT/s */
#define  PCI_EXP_LNKCTL2_TLS_5_0GT      0x0002 /* Supported Speed 5GT/s */
#define  PCI_EXP_LNKCTL2_TLS_8_0GT      0x0003 /* Supported Speed 8GT/s */
#define  PCI_EXP_LNKCTL2_TLS_16_0GT     0x0004 /* Supported Speed 16GT/s */
#define  PCI_EXP_LNKCTL2_TLS_32_0GT     0x0005 /* Supported Speed 32GT/s */
#define  PCI_EXP_LNKCTL2_TLS_64_0GT     0x0006 /* Supported Speed 64GT/s */
#define  PCI_EXP_LNKCTL2_ENTER_COMP     0x0010 /* Enter Compliance */
#define  PCI_EXP_LNKCTL2_TX_MARGIN      0x0380 /* Transmit Margin */
#define  PCI_EXP_LNKCTL2_HASD           0x0020 /* HW Autonomous Speed Disable */
#define PCI_EXP_LNKSTA2         50      /* Link Status 2 */

> >
> > There's already some common DWC code for setting the link speed.
>
> dw_pcie_link_set_max_speed() deals with other registers, as far as I can
> see.

Link Control2 which is what the above function configures appears to
be the same register to me. Your definition is combining 2 registers.

>
> >> +#define AXI_CLK_RATE                           200000000
> >> +#define RCHNG_CLK_RATE                         100000000
> >>
> >>  #define DEVICE_TYPE_RC                         0x4
>
> [snip]
>
> >> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +       struct dw_pcie *pci = pcie->pci;
> >> +       u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> >> +       u32 val;
> >> +       int i;
> >> +
> >> +       writel(SLV_ADDR_SPACE_SZ,
> >> +               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> >> +
> >> +       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> >> +       val &= ~BIT(0);
> >> +       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> >> +
> >> +       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> >> +
> >> +       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> >> +       writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> >> +               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> >> +       writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> >> +               | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> >> +               pci->dbi_base + GEN3_RELATED_OFF);
> >> +
> >> +       writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> >> +               | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> >> +               AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> >> +               pcie->parf + PCIE20_PARF_SYS_CTRL);
> >> +
> >> +       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> >> +
> >> +       dw_pcie_dbi_ro_wr_en(pci);
> >> +       writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> >> +
> >> +       /* Configure PCIe link capabilities for ASPM */
> >> +       val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> >> +       val &= ~PCI_EXP_LNKCAP_ASPMS;
> >> +       writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> >> +
> >> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> >> +                       PCI_EXP_DEVCTL2);
> >> +
> >> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
> >> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
> >
> > Doesn't this overwrite the prior register write?
>
> It does. There are two mistakes here. The writel() above should set
> PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98).

No. Did you check what 'offset' is? PCIE20_DEVICE_CONTROL2_STATUS2 is
PCI_EXP_DEVCTL2 plus the status reg. What's wrong is it should be a
16-bit write.

> This writel() should set
> PCIE20_LNK_CONTROL2_LINK_STATUS2 (offset 0xa0). So both are wrong.
>
> >> +
> >> +       for (i = 0;i < 256;i++)
> >> +               writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> >> +                               + (4 * i));
> >> +
> >> +       return 0;
> >> +}
>
> Thanks,
> baruch
>
> --
>                                                      ~. .~   Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
>    - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From vkoul at kernel.org  Wed Aug 25 07:02:58 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 25 Aug 2021 19:32:58 +0530
Subject: [PATCH] dt-bindings: Use 'enum' instead of 'oneOf' plus 'const'
 entries
In-Reply-To: <20210824202014.978922-1-robh@kernel.org>
References: <20210824202014.978922-1-robh@kernel.org>
Message-ID: <YSZNkraWdMGXsjbf@matsya>

On 24-08-21, 15:20, Rob Herring wrote:
> 'enum' is equivalent to 'oneOf' with a list of 'const' entries, but 'enum'
> is more concise and yields better error messages.
> 
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Vignesh R <vigneshr at ti.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
> Cc: Mauro Carvalho Chehab <mchehab at kernel.org>
> Cc: Lee Jones <lee.jones at linaro.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: Jakub Kicinski <kuba at kernel.org>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: dmaengine at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: linux-pci at vger.kernel.org
> Cc: linux-phy at lists.infradead.org
> Cc: linux-serial at vger.kernel.org
> Cc: alsa-devel at alsa-project.org
> Cc: linux-spi at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../bindings/display/msm/dsi-phy-10nm.yaml           |  6 +++---
>  .../bindings/display/msm/dsi-phy-14nm.yaml           |  6 +++---
>  .../bindings/display/msm/dsi-phy-28nm.yaml           |  8 ++++----

Reviewed-by: Vinod Koul <vkoul at kernel.org>

>  .../bindings/dma/allwinner,sun6i-a31-dma.yaml        | 12 ++++++------
>  .../devicetree/bindings/phy/intel,lgm-emmc-phy.yaml  |  6 +++---

Acked-By: Vinod Koul <vkoul at kernel.org>

-- 
~Vinod


From baruch at tkos.co.il  Wed Aug 25 07:09:49 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 17:09:49 +0300
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
 <87o89lahqp.fsf@tarshish>
 <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>
Message-ID: <87lf4pa9i0.fsf@tarshish>

Hi Rob,

On Wed, Aug 25 2021, Rob Herring wrote:
> On Wed, Aug 25, 2021 at 6:25 AM Baruch Siach <baruch at tkos.co.il> wrote:
>> On Fri, Aug 06 2021, Rob Herring wrote:
>> > On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>> >> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
>> >> +                       PCI_EXP_DEVCTL2);
>> >> +
>> >> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
>> >> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
>> >
>> > Doesn't this overwrite the prior register write?
>>
>> It does. There are two mistakes here. The writel() above should set
>> PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98).
>
> No. Did you check what 'offset' is? PCIE20_DEVICE_CONTROL2_STATUS2 is
> PCI_EXP_DEVCTL2 plus the status reg. What's wrong is it should be a
> 16-bit write.

Thanks for enlightening me. 'offset' is 0x70 here. So PCI_EXP_DEVCTL2 is
at 0x98, and PCI_EXP_LNKCTL2 is at 0xa0. Only the second writel() is
wrong. But since generic code handles speed, I can drop it entirely.

I see that dw_pcie_link_set_max_speed() uses dw_pcie_writel_dbi() to
write to PCI_EXP_LNKCTL2. Is that 16-bit write?

Why are pci_regs.h register offsets in decimal?

>> This writel() should set
>> PCIE20_LNK_CONTROL2_LINK_STATUS2 (offset 0xa0). So both are wrong.

Thanks,
baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From robh+dt at kernel.org  Wed Aug 25 08:03:51 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 10:03:51 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <87lf4pa9i0.fsf@tarshish>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
 <87o89lahqp.fsf@tarshish>
 <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>
 <87lf4pa9i0.fsf@tarshish>
Message-ID: <CAL_JsqKLijW0H-f0Ptd3EKrE5mRwtQK5StOTzs3b5UesuuVKdg@mail.gmail.com>

On Wed, Aug 25, 2021 at 9:23 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> Hi Rob,
>
> On Wed, Aug 25 2021, Rob Herring wrote:
> > On Wed, Aug 25, 2021 at 6:25 AM Baruch Siach <baruch at tkos.co.il> wrote:
> >> On Fri, Aug 06 2021, Rob Herring wrote:
> >> > On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
> >> >> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> >> >> +                       PCI_EXP_DEVCTL2);
> >> >> +
> >> >> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
> >> >> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
> >> >
> >> > Doesn't this overwrite the prior register write?
> >>
> >> It does. There are two mistakes here. The writel() above should set
> >> PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98).
> >
> > No. Did you check what 'offset' is? PCIE20_DEVICE_CONTROL2_STATUS2 is
> > PCI_EXP_DEVCTL2 plus the status reg. What's wrong is it should be a
> > 16-bit write.
>
> Thanks for enlightening me. 'offset' is 0x70 here. So PCI_EXP_DEVCTL2 is
> at 0x98, and PCI_EXP_LNKCTL2 is at 0xa0. Only the second writel() is
> wrong. But since generic code handles speed, I can drop it entirely.
>
> I see that dw_pcie_link_set_max_speed() uses dw_pcie_writel_dbi() to
> write to PCI_EXP_LNKCTL2. Is that 16-bit write?

No, that may be because some platforms can only do 32-bit accesses and
dw_pcie_writew_dbi would be a RMW in that case. Or maybe there's some
reliance on clearing the status register.

> Why are pci_regs.h register offsets in decimal?

No idea...

Rob


From helgaas at kernel.org  Wed Aug 25 09:05:16 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 25 Aug 2021 11:05:16 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <CAL_JsqKLijW0H-f0Ptd3EKrE5mRwtQK5StOTzs3b5UesuuVKdg@mail.gmail.com>
Message-ID: <20210825160516.GA3576414@bjorn-Precision-5520>

On Wed, Aug 25, 2021 at 10:03:51AM -0500, Rob Herring wrote:
> On Wed, Aug 25, 2021 at 9:23 AM Baruch Siach <baruch at tkos.co.il> wrote:

> > Why are pci_regs.h register offsets in decimal?
> 
> No idea...

That does seem confusing and error prone.  I'd merge a patch that made
them hex to match the spec.


From helgaas at kernel.org  Wed Aug 25 09:37:38 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 25 Aug 2021 11:37:38 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
Message-ID: <20210825163738.GA3576149@bjorn-Precision-5520>

In subject:

s/add support/Add support/ to match previous history.

On Wed, May 05, 2021 at 12:18:30PM +0300, Baruch Siach wrote:
> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> 
> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> platform.
> 
> The code is based on downstream Codeaurora kernel v5.4. Split out the
> DBI registers access part from .init into .post_init. DBI registers are
> only accessible after phy_power_on().

The "downstream Codeaurora kernel v5.4" reference would be more useful
if there were a URL reference to that driver.

> +#define AXI_CLK_RATE				200000000
> +#define RCHNG_CLK_RATE				100000000

These are unused.

> +	for (i = 0;i < 256;i++)

Add spaces after semicolons.


From wsa at kernel.org  Wed Aug 25 13:55:21 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Wed, 25 Aug 2021 22:55:21 +0200
Subject: [PATCH] dt-bindings: Use 'enum' instead of 'oneOf' plus 'const'
 entries
In-Reply-To: <20210824202014.978922-1-robh@kernel.org>
References: <20210824202014.978922-1-robh@kernel.org>
Message-ID: <YSauOeE4lBfeDiGw@kunai>

On Tue, Aug 24, 2021 at 03:20:14PM -0500, Rob Herring wrote:
> 'enum' is equivalent to 'oneOf' with a list of 'const' entries, but 'enum'
> is more concise and yields better error messages.
> 
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Vignesh R <vigneshr at ti.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
> Cc: Mauro Carvalho Chehab <mchehab at kernel.org>
> Cc: Lee Jones <lee.jones at linaro.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: Jakub Kicinski <kuba at kernel.org>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: dmaengine at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: linux-pci at vger.kernel.org
> Cc: linux-phy at lists.infradead.org
> Cc: linux-serial at vger.kernel.org
> Cc: alsa-devel at alsa-project.org
> Cc: linux-spi at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>

Acked-by: Wolfram Sang <wsa at kernel.org> # for I2C

Thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20210825/1d7b0a53/attachment.sig>

From gregkh at linuxfoundation.org  Thu Aug 26 04:57:44 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 26 Aug 2021 13:57:44 +0200
Subject: [PATCH] dt-bindings: Use 'enum' instead of 'oneOf' plus 'const'
 entries
In-Reply-To: <20210824202014.978922-1-robh@kernel.org>
References: <20210824202014.978922-1-robh@kernel.org>
Message-ID: <YSeBuMtUa77AR7Tn@kroah.com>

On Tue, Aug 24, 2021 at 03:20:14PM -0500, Rob Herring wrote:
> 'enum' is equivalent to 'oneOf' with a list of 'const' entries, but 'enum'
> is more concise and yields better error messages.
> 
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Vignesh R <vigneshr at ti.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
> Cc: Mauro Carvalho Chehab <mchehab at kernel.org>
> Cc: Lee Jones <lee.jones at linaro.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: Jakub Kicinski <kuba at kernel.org>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: dmaengine at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: linux-pci at vger.kernel.org
> Cc: linux-phy at lists.infradead.org
> Cc: linux-serial at vger.kernel.org
> Cc: alsa-devel at alsa-project.org
> Cc: linux-spi at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>

Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From yifeng.zhao at rock-chips.com  Thu Aug 26 05:38:41 2021
From: yifeng.zhao at rock-chips.com (Yifeng Zhao)
Date: Thu, 26 Aug 2021 20:38:41 +0800
Subject: [PATCH v1 0/3] 
Message-ID: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>

Add Naneng combo PHY support for RK3568

This phy can be used as pcie-phy, usb3-phy, sata-phy or sgmii-phy.



Yifeng Zhao (3):
  dt-bindings: phy: rockchip: Add Naneng combo PHY bindings
  phy/rockchip: add naneng combo phy for RK3568
  arm64: dts: rockchip: add naneng combo phy nodes for rk3568

 .../phy/phy-rockchip-naneng-combphy.yaml      | 100 +++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |  68 ++
 drivers/phy/rockchip/Kconfig                  |   8 +
 drivers/phy/rockchip/Makefile                 |   1 +
 .../rockchip/phy-rockchip-naneng-combphy.c    | 646 ++++++++++++++++++
 5 files changed, 823 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
 create mode 100644 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c

-- 
2.17.1





From yifeng.zhao at rock-chips.com  Thu Aug 26 05:38:44 2021
From: yifeng.zhao at rock-chips.com (Yifeng Zhao)
Date: Thu, 26 Aug 2021 20:38:44 +0800
Subject: [PATCH v1 3/3] arm64: dts: rockchip: add naneng combo phy nodes for
 rk3568
In-Reply-To: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
References: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
Message-ID: <20210826123844.8464-4-yifeng.zhao@rock-chips.com>

Add the core dt-node for the rk3568's naneng combo phys.

Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
---

 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 68 ++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index d89831bee1eb..b421e3d52412 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -214,11 +214,31 @@
 		};
 	};
 
+	pipegrf: syscon at fdc50000 {
+		compatible = "rockchip,rk3568-pipegrf", "syscon";
+		reg = <0x0 0xfdc50000 0x0 0x1000>;
+	};
+
 	grf: syscon at fdc60000 {
 		compatible = "rockchip,rk3568-grf", "syscon", "simple-mfd";
 		reg = <0x0 0xfdc60000 0x0 0x10000>;
 	};
 
+	pipe_phy_grf0: syscon at fdc70000 {
+		compatible = "rockchip,pipe-phy-grf", "syscon";
+		reg = <0x0 0xfdc70000 0x0 0x1000>;
+	};
+
+	pipe_phy_grf1: syscon at fdc80000 {
+		compatible = "rockchip,pipe-phy-grf", "syscon";
+		reg = <0x0 0xfdc80000 0x0 0x1000>;
+	};
+
+	pipe_phy_grf2: syscon at fdc90000 {
+		compatible = "rockchip,pipe-phy-grf", "syscon";
+		reg = <0x0 0xfdc90000 0x0 0x1000>;
+	};
+
 	pmucru: clock-controller at fdd00000 {
 		compatible = "rockchip,rk3568-pmucru";
 		reg = <0x0 0xfdd00000 0x0 0x1000>;
@@ -862,6 +882,54 @@
 		status = "disabled";
 	};
 
+	combphy0_us: phy at fe820000 {
+		compatible = "rockchip,rk3568-naneng-combphy";
+		reg = <0x0 0xfe820000 0x0 0x100>;
+		#phy-cells = <1>;
+		clocks = <&pmucru CLK_PCIEPHY0_REF>, <&cru PCLK_PIPEPHY0>,
+			 <&cru PCLK_PIPE>;
+		clock-names = "ref", "apb", "pipe";
+		assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+		assigned-clock-rates = <100000000>;
+		resets = <&cru SRST_P_PIPEPHY0>, <&cru SRST_PIPEPHY0>;
+		reset-names = "combphy-apb", "combphy";
+		rockchip,pipe-grf = <&pipegrf>;
+		rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+		status = "disabled";
+	};
+
+	combphy1_usq: phy at fe830000 {
+		compatible = "rockchip,rk3568-naneng-combphy";
+		reg = <0x0 0xfe830000 0x0 0x100>;
+		#phy-cells = <1>;
+		clocks = <&pmucru CLK_PCIEPHY1_REF>, <&cru PCLK_PIPEPHY1>,
+			 <&cru PCLK_PIPE>;
+		clock-names = "ref", "apb", "pipe";
+		assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>;
+		assigned-clock-rates = <100000000>;
+		resets = <&cru SRST_P_PIPEPHY1>, <&cru SRST_PIPEPHY1>;
+		reset-names = "combphy-apb", "combphy";
+		rockchip,pipe-grf = <&pipegrf>;
+		rockchip,pipe-phy-grf = <&pipe_phy_grf1>;
+		status = "disabled";
+	};
+
+	combphy2_psq: phy at fe840000 {
+		compatible = "rockchip,rk3568-naneng-combphy";
+		reg = <0x0 0xfe840000 0x0 0x100>;
+		#phy-cells = <1>;
+		clocks = <&pmucru CLK_PCIEPHY2_REF>, <&cru PCLK_PIPEPHY2>,
+			 <&cru PCLK_PIPE>;
+		clock-names = "ref", "apb", "pipe";
+		assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>;
+		assigned-clock-rates = <100000000>;
+		resets = <&cru SRST_P_PIPEPHY2>, <&cru SRST_PIPEPHY2>;
+		reset-names = "combphy-apb", "combphy";
+		rockchip,pipe-grf = <&pipegrf>;
+		rockchip,pipe-phy-grf = <&pipe_phy_grf2>;
+		status = "disabled";
+	};
+
 	pinctrl: pinctrl {
 		compatible = "rockchip,rk3568-pinctrl";
 		rockchip,grf = <&grf>;
-- 
2.17.1





From yifeng.zhao at rock-chips.com  Thu Aug 26 05:38:42 2021
From: yifeng.zhao at rock-chips.com (Yifeng Zhao)
Date: Thu, 26 Aug 2021 20:38:42 +0800
Subject: [PATCH v1 1/3] dt-bindings: phy: rockchip: Add Naneng combo PHY
 bindings
In-Reply-To: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
References: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
Message-ID: <20210826123844.8464-2-yifeng.zhao@rock-chips.com>

Add the compatible strings for the Naneng combo PHY found on rockchip SoC.

Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
---

 .../phy/phy-rockchip-naneng-combphy.yaml      | 100 ++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
new file mode 100644
index 000000000000..69908614609c
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/phy-rockchip-naneng-combphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC Naneng Combo Phy Device Tree Bindings
+
+maintainers:
+  - Heiko Stuebner <heiko at sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3568-naneng-combphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    items:
+      - description: reference clock
+      - description: apb clock
+      - description: pipe clock
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: ref
+      - const: apb
+      - const: pipe
+
+  '#phy-cells':
+    const: 1
+
+  resets:
+    minItems: 1
+    items:
+      - description: exclusive apb reset line
+      - description: exclusive PHY reset line
+
+  reset-names:
+    minItems: 1
+    items:
+      - const: combphy-apb
+      - const: combphy
+
+  rockchip,pipe-grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Some additional phy settings are access through GRF regs.
+
+  rockchip,pipe-phy-grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Some additional pipe settings are access through GRF regs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#phy-cells'
+  - resets
+  - reset-names
+  - rockchip,pipe-grf
+  - rockchip,pipe-phy-grf
+
+additionalProperties: false
+
+examples:
+  - |
+
+    #include <dt-bindings/clock/rk3568-cru.h>
+
+    pipegrf: syscon at fdc50000 {
+      compatible = "rockchip,rk3568-pipegrf", "syscon";
+      reg = <0xfdc50000 0x1000>;
+    };
+
+    pipe_phy_grf0: syscon at fdc70000 {
+      compatible = "rockchip,pipe-phy-grf", "syscon";
+      reg = <0xfdc70000 0x1000>;
+    };
+
+    combphy0_us: phy at fe820000 {
+      compatible = "rockchip,rk3568-naneng-combphy";
+      reg = <0xfe820000 0x100>;
+      #phy-cells = <1>;
+      clocks = <&pmucru CLK_PCIEPHY0_REF>, <&cru PCLK_PIPEPHY0>,
+        <&cru PCLK_PIPE>;
+      clock-names = "ref", "apb", "pipe";
+      assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+      assigned-clock-rates = <100000000>;
+      resets = <&cru SRST_P_PIPEPHY0>, <&cru SRST_PIPEPHY0>;
+      reset-names = "combphy-apb", "combphy";
+      rockchip,pipe-grf = <&pipegrf>;
+      rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+    };
-- 
2.17.1





From robh at kernel.org  Thu Aug 26 06:26:01 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 26 Aug 2021 08:26:01 -0500
Subject: [PATCH v1 1/3] dt-bindings: phy: rockchip: Add Naneng combo PHY
 bindings
In-Reply-To: <20210826123844.8464-2-yifeng.zhao@rock-chips.com>
References: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
 <20210826123844.8464-2-yifeng.zhao@rock-chips.com>
Message-ID: <1629984361.449016.1033391.nullmailer@robh.at.kernel.org>

On Thu, 26 Aug 2021 20:38:42 +0800, Yifeng Zhao wrote:
> Add the compatible strings for the Naneng combo PHY found on rockchip SoC.
> 
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> ---
> 
>  .../phy/phy-rockchip-naneng-combphy.yaml      | 100 ++++++++++++++++++
>  1 file changed, 100 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.example.dt.yaml:0:0: /example-0/syscon at fdc50000: failed to match any schema with compatible: ['rockchip,rk3568-pipegrf', 'syscon']
Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.example.dt.yaml:0:0: /example-0/syscon at fdc70000: failed to match any schema with compatible: ['rockchip,pipe-phy-grf', 'syscon']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1521096

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From p.yadav at ti.com  Thu Aug 26 11:49:25 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Fri, 27 Aug 2021 00:19:25 +0530
Subject: [PATCH v4 2/6] phy: cdns-dphy: Add Rx support
In-Reply-To: <YSL79vtTGsK+zwTQ@pendragon.ideasonboard.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-3-p.yadav@ti.com>
 <YSL79vtTGsK+zwTQ@pendragon.ideasonboard.com>
Message-ID: <20210826184923.zgevk33rmdq6g3uo@ti.com>

Hi Laurent,

Thanks for reviewing.

On 23/08/21 04:37AM, Laurent Pinchart wrote:
> Hi Pratyush,
> 
> Thank you for the patch.
> 
> On Sat, Aug 21, 2021 at 12:33:42AM +0530, Pratyush Yadav wrote:
> > The Cadence DPHY can be used to receive image data over the CSI-2
> > protocol. Add support for Rx mode. The programming sequence differs from
> > the Tx mode so it is added as a separate set of hooks to isolate the two
> > paths. The mode in which the DPHY has to be used is selected based on
> > the compatible.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > 
> > ---
> > 
> > Changes in v4:
> > - Drop the submode parts. Use a different compatible for the Rx ops.
> > - Make bands and num_bands static.
> > 
> > Changes in v3:
> > - Use a table to select the band.
> > - Use a table to poll the data lane ready bits.
> > - Multiply the DPHY HS clock rate by 2 to get the bit rate since the
> >   clock is DDR.
> > 
> >  drivers/phy/cadence/cdns-dphy.c | 171 ++++++++++++++++++++++++++++++++
> >  1 file changed, 171 insertions(+)
> > 
> > diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> > index 0a169d649216..149fccdfad38 100644
> > --- a/drivers/phy/cadence/cdns-dphy.c
> > +++ b/drivers/phy/cadence/cdns-dphy.c
> > @@ -1,11 +1,14 @@
> >  // SPDX-License-Identifier: GPL-2.0+
> >  /*
> >   * Copyright: 2017-2018 Cadence Design Systems, Inc.
> > + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
> >   */
> >  
> >  #include <linux/bitops.h>
> > +#include <linux/bitfield.h>
> 
> Alphabetical order please.
> 
> >  #include <linux/clk.h>
> >  #include <linux/io.h>
> > +#include <linux/iopoll.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> >  #include <linux/of_device.h>
> > @@ -25,10 +28,14 @@
> >  #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
> >  #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
> >  #define DPHY_PCS(reg)			(0xb00 + (reg))
> > +#define DPHY_ISO(reg)			(0xc00 + (reg))
> >  
> >  #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
> >  #define DPHY_CMN_SSM_EN			BIT(0)
> > +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
> >  #define DPHY_CMN_TX_MODE_EN		BIT(9)
> > +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> > +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
> >  
> >  #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
> >  #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> > @@ -45,10 +52,27 @@
> >  #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
> >  #define DPHY_CMN_OPDIV(x)		((x) << 7)
> >  
> > +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> > +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> > +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> > +
> >  #define DPHY_PSM_CFG			DPHY_PCS(0x4)
> >  #define DPHY_PSM_CFG_FROM_REG		BIT(0)
> >  #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
> >  
> > +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> > +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> > +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> > +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> > +
> > +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> > +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> > +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> > +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> > +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> > +#define DPHY_ISO_LANE_READY_BIT		0
> > +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> > +
> >  #define DSI_HBP_FRAME_OVERHEAD		12
> >  #define DSI_HSA_FRAME_OVERHEAD		14
> >  #define DSI_HFP_FRAME_OVERHEAD		6
> > @@ -57,6 +81,9 @@
> >  #define DSI_NULL_FRAME_OVERHEAD		6
> >  #define DSI_EOT_PKT_SIZE		4
> >  
> > +#define DPHY_LANES_MIN			1
> > +#define DPHY_LANES_MAX			4
> > +
> >  struct cdns_dphy_cfg {
> >  	u8 pll_ipdiv;
> >  	u8 pll_opdiv;
> > @@ -98,6 +125,22 @@ struct cdns_dphy {
> >  	struct phy *phy;
> >  };
> >  
> > +struct cdns_dphy_rx_band {
> > +	unsigned int min_rate;
> > +	unsigned int max_rate;
> > +};
> > +
> > +/* Order of bands is important since the index is the band number. */
> > +static struct cdns_dphy_rx_band bands[] = {
> 
> static const
> 
> > +	{80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240},
> > +	{240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480},
> > +	{480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880},
> > +	{880, 1040}, {1040, 1200}, {1200, 1350}, {1350, 1500}, {1500, 1750},
> > +	{1750, 2000}, {2000, 2250}, {2250, 2500}
> > +};
> > +
> > +static int num_bands = ARRAY_SIZE(bands);
> 
> No need for a variable (which should be const otherwise), you can use
> ARRAY_SIZE(bands) where needed.
> 
> > +
> >  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
> >  				     struct cdns_dphy_cfg *cfg,
> >  				     struct phy_configure_opts_mipi_dphy *opts,
> > @@ -309,6 +352,132 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> >  	.set_psm_div = cdns_dphy_ref_set_psm_div,
> >  };
> >  
> > +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> > +{
> > +	/* Start RX state machine. */
> > +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> > +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> > +			  DPHY_CMN_RX_BANDGAP_TIMER),
> > +	       dphy->regs + DPHY_CMN_SSM);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> > +{
> > +	writel(0, dphy->regs + DPHY_CMN_SSM);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> > +{
> > +	unsigned int rate;
> > +	int i;
> 
> i is never negative, you can make it an unsigned int.
> 
> > +
> > +	rate = hs_clk_rate / 1000000UL;
> > +	/* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
> > +	rate *= 2;
> > +
> > +	if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate)
> > +		return -EOPNOTSUPP;
> > +
> > +	for (i = 0; i < num_bands; i++) {
> > +		if (rate >= bands[i].min_rate && rate < bands[i].max_rate)
> 
> You can replace this with
> 
> 		if (rate < bands[i].max_rate)
> 
> as the bands are in increasing order.
> 
> > +			return i;
> > +	}
> > +
> > +	/* Unreachable. */
> > +	WARN(1, "Reached unreachable code.");
> > +	return -EINVAL;
> 
> That's not very nice.
> 
> As a clock rate higher than the maximum isn't supposed to happen, you
> could drop that initial check (it won't affect performance) and return
> -EOPNOTSUPP here without a WARN().

Ok.

> 
> > +}
> > +
> > +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> > +{
> > +	u32 val;
> > +
> > +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> > +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
> 
> A busy wait for one second is quite long. How long does it typically
> take for the condition to be true ?

I have not measured. I don't see any timing information in the 
datasheet.

But the timeout is 100 miliseconds not 1 second. 
readl_relaxed_poll_timeout() expects microseconds, so we multiply by 
1000. The value of DPHY_ISO_LANE_READY_TIMEOUT_MS is 100, so it will be 
a 100 ms timeout, which I think is reasonable.

> 
> > +}
> > +
> > +static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
> 
> lanes should be an unsigned int.
> 
> > +{
> > +	void __iomem *reg = dphy->regs;
> 
> You can use dphy->regs directly in the code below.
> 
> > +	u32 data_lane_ctrl[] = {DPHY_ISO_DL_CTRL_L0, DPHY_ISO_DL_CTRL_L1,
> > +				DPHY_ISO_DL_CTRL_L2, DPHY_ISO_DL_CTRL_L3};
> 
> static const, and move it first in the function.

Ok. But out of curiosity, why?

> 
> > +	int ret, i;
> 
> i is never negative here either.

Yes. Will change to unsigned.

> 
> > +
> > +	/* Data lanes. Minimum one lane is mandatory. */
> > +	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
> > +		return -EINVAL;
> > +
> > +	/* Clock lane */
> > +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
> > +					DPHY_ISO_LANE_READY_BIT);
> > +	if (ret)
> > +		return ret;
> > +
> > +	for (i = 0; i < lanes; i++) {
> > +		ret = cdns_dphy_rx_wait_for_bit(reg + data_lane_ctrl[i],
> > +						DPHY_ISO_LANE_READY_BIT);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_rx_configure(struct cdns_dphy *dphy,
> > +				  union phy_configure_opts *opts)
> > +{
> > +	unsigned int reg;
> > +	int band_ctrl, ret;
> > +
> > +	band_ctrl = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
> > +	if (band_ctrl < 0)
> > +		return band_ctrl;
> > +
> > +	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
> > +	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
> > +	writel(reg, dphy->regs + DPHY_BAND_CFG);
> > +
> > +	/*
> > +	 * Set the required power island phase 2 time. This is mandated by DPHY
> > +	 * specs.
> > +	 */
> > +	reg = DPHY_POWER_ISLAND_EN_DATA_VAL;
> > +	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_DATA);
> > +	reg = DPHY_POWER_ISLAND_EN_CLK_VAL;
> > +	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_CLK);
> > +
> > +	ret = cdns_dphy_rx_wait_lane_ready(dphy, opts->mipi_dphy.lanes);
> > +	if (ret) {
> > +		dev_err(dphy->dev, "DPHY wait for lane ready timeout\n");
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_rx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> > +				 int submode, union phy_configure_opts *opts)
> > +{
> > +	int ret;
> > +
> > +	ret = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
> > +}
> > +
> > +static const struct cdns_dphy_ops rx_ref_dphy_ops = {
> > +	.power_on = cdns_dphy_rx_power_on,
> > +	.power_off = cdns_dphy_rx_power_off,
> > +	.configure = cdns_dphy_rx_configure,
> > +	.validate = cdns_dphy_rx_validate,
> > +};
> > +
> >  static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> >  			      union phy_configure_opts *opts)
> >  {
> > @@ -421,6 +590,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
> >  
> >  static const struct of_device_id cdns_dphy_of_match[] = {
> >  	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
> > +	{ .compatible = "cdns,dphy-rx", .data = &rx_ref_dphy_ops },
> >  	{ /* sentinel */ },
> >  };
> >  MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
> > @@ -436,5 +606,6 @@ static struct platform_driver cdns_dphy_platform_driver = {
> >  module_platform_driver(cdns_dphy_platform_driver);
> >  
> >  MODULE_AUTHOR("Maxime Ripard <maxime.ripard at bootlin.com>");
> > +MODULE_AUTHOR("Pratyush Yadav <p.yadav at ti.com>");
> >  MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
> >  MODULE_LICENSE("GPL");
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Thu Aug 26 12:14:51 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Fri, 27 Aug 2021 00:44:51 +0530
Subject: [PATCH v4 1/6] phy: cdns-dphy: Prepare for Rx support
In-Reply-To: <YSL48RA2ksldoCyX@pendragon.ideasonboard.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-2-p.yadav@ti.com>
 <YSL48RA2ksldoCyX@pendragon.ideasonboard.com>
Message-ID: <20210826191449.utd37kj5xkl762gx@ti.com>

On 23/08/21 04:25AM, Laurent Pinchart wrote:
> Hi Pratyush,
> 
> Thank you for the patch.
> 
> On Sat, Aug 21, 2021 at 12:33:41AM +0530, Pratyush Yadav wrote:
> > The Rx programming sequence differs from the Tx programming sequence.
> > Currently only Tx mode is supported. For example, the power on and off,
> > validation, and configuration procedures are all different between Rx
> > and Tx DPHYs. Currently they are only written from a Tx point of view
> > and they won't work with an Rx DPHY. Move them to cdns_dphy_ops so they
> > can be defined by the implementation, accommodating both Rx and Tx mode
> > DPHYs.
> > 
> > The clocks "psm" and "pll_ref" are not used by the Rx path so make them
> > optional in the probe and then check if they exist in the Tx power_on()
> > hook.
> 
> I think it would be better to check them at probe time.

Right. Now that we no longer switch mode dynamically, this can be done.

> 
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > 
> > ---
> > 
> > Changes in v4:
> > - Instead of having both Rx and Tx modes in the same driver data, keep
> >   them separate since the op selection is based on compatible now. For
> >   that reason, the cdns_dphy_driver_data struct is no longer needed.
> > - Rename ref_dphy_ops to tx_ref_dphy_ops to clarify their purpose.
> > - Drop submode checks in validate() hook.
> > 
> >  drivers/phy/cadence/cdns-dphy.c | 123 ++++++++++++++++++++++----------
> >  1 file changed, 87 insertions(+), 36 deletions(-)
> > 
> > diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> > index ba042e39cfaf..0a169d649216 100644
> > --- a/drivers/phy/cadence/cdns-dphy.c
> > +++ b/drivers/phy/cadence/cdns-dphy.c
> > @@ -75,6 +75,11 @@ struct cdns_dphy;
> >  struct cdns_dphy_ops {
> >  	int (*probe)(struct cdns_dphy *dphy);
> >  	void (*remove)(struct cdns_dphy *dphy);
> > +	int (*power_on)(struct cdns_dphy *dphy);
> > +	int (*power_off)(struct cdns_dphy *dphy);
> > +	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
> > +			union phy_configure_opts *opts);
> > +	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
> >  	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
> >  	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
> >  				 enum cdns_dphy_clk_lane_cfg cfg);
> > @@ -86,6 +91,7 @@ struct cdns_dphy_ops {
> >  struct cdns_dphy {
> >  	struct cdns_dphy_cfg cfg;
> >  	void __iomem *regs;
> > +	struct device *dev;
> >  	struct clk *psm_clk;
> >  	struct clk *pll_ref_clk;
> >  	const struct cdns_dphy_ops *ops;
> > @@ -199,20 +205,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
> >  	       dphy->regs + DPHY_PSM_CFG);
> >  }
> >  
> > -/*
> > - * This is the reference implementation of DPHY hooks. Specific integration of
> > - * this IP may have to re-implement some of them depending on how they decided
> > - * to wire things in the SoC.
> > - */
> > -static const struct cdns_dphy_ops ref_dphy_ops = {
> > -	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> > -	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> > -	.set_psm_div = cdns_dphy_ref_set_psm_div,
> > -};
> > -
> > -static int cdns_dphy_config_from_opts(struct phy *phy,
> > -				      struct phy_configure_opts_mipi_dphy *opts,
> > -				      struct cdns_dphy_cfg *cfg)
> > +static int cdns_dphy_tx_config_from_opts(struct phy *phy,
> > +					 struct phy_configure_opts_mipi_dphy *opts,
> > +					 struct cdns_dphy_cfg *cfg)
> >  {
> >  	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> >  	unsigned int dsi_hfp_ext = 0;
> > @@ -232,24 +227,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
> >  	return 0;
> >  }
> >  
> > -static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> > -			      union phy_configure_opts *opts)
> > +static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
> > +				  union phy_configure_opts *opts)
> >  {
> >  	struct cdns_dphy_cfg cfg = { 0 };
> > -
> > -	if (mode != PHY_MODE_MIPI_DPHY)
> > -		return -EINVAL;
> > -
> > -	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> > -}
> > -
> > -static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> > -{
> > -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > -	struct cdns_dphy_cfg cfg = { 0 };
> >  	int ret;
> >  
> > -	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
> > +	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -279,9 +263,18 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> >  	return 0;
> >  }
> >  
> > -static int cdns_dphy_power_on(struct phy *phy)
> > +static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> > +				 int submode, union phy_configure_opts *opts)
> >  {
> > -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +	struct cdns_dphy_cfg cfg = { 0 };
> > +
> > +	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
> > +}
> > +
> > +static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
> > +{
> > +	if (!dphy->psm_clk || !dphy->pll_ref_clk)
> > +		return -EINVAL;
> >  
> >  	clk_prepare_enable(dphy->psm_clk);
> >  	clk_prepare_enable(dphy->pll_ref_clk);
> > @@ -293,16 +286,73 @@ static int cdns_dphy_power_on(struct phy *phy)
> >  	return 0;
> >  }
> >  
> > -static int cdns_dphy_power_off(struct phy *phy)
> > +static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
> >  {
> > -	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > -
> >  	clk_disable_unprepare(dphy->pll_ref_clk);
> >  	clk_disable_unprepare(dphy->psm_clk);
> >  
> >  	return 0;
> >  }
> >  
> > +/*
> > + * This is the reference implementation of DPHY hooks. Specific integration of
> > + * this IP may have to re-implement some of them depending on how they decided
> > + * to wire things in the SoC.
> > + */
> > +static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> > +	.power_on = cdns_dphy_tx_power_on,
> > +	.power_off = cdns_dphy_tx_power_off,
> > +	.validate = cdns_dphy_tx_validate,
> > +	.configure = cdns_dphy_tx_configure,
> > +	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
> > +	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
> > +	.set_psm_div = cdns_dphy_ref_set_psm_div,
> > +};
> > +
> > +static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> > +			      union phy_configure_opts *opts)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (mode != PHY_MODE_MIPI_DPHY)
> > +		return -EINVAL;
> > +
> > +	if (dphy->ops->validate)
> > +		return dphy->ops->validate(dphy, mode, submode, opts);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_power_on(struct phy *phy)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (dphy->ops->power_on)
> > +		return dphy->ops->power_on(dphy);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_power_off(struct phy *phy)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (dphy->ops->power_off)
> > +		return dphy->ops->power_off(dphy);
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> > +{
> > +	struct cdns_dphy *dphy = phy_get_drvdata(phy);
> > +
> > +	if (dphy->ops->configure)
> > +		return dphy->ops->configure(dphy, opts);
> > +
> > +	return 0;
> > +}
> > +
> 
> Given that all of these are essentially pass-through operations, how
> about getting rid of the indirection ? I would create a new structure:
> 
> struct cdns_dphy_info {
> 	const struct phy_ops *phy_ops;
> 	const struct cdns_dphy_ops *dphy_ops;
> };
> 
> and reference it in cdns_dphy_of_match. The cdns_dphy structure would
> then store a pointer to cdns_dphy_info. That way you won't have to
> extend cdns_dphy_ops, which could possibly be renamed to
> cdns_dphy_tx_ops as you don't use those operations for rx.

Ok, sounds like a good idea.

> 
> >  static const struct phy_ops cdns_dphy_ops = {
> >  	.configure	= cdns_dphy_configure,
> >  	.validate	= cdns_dphy_validate,
> > @@ -320,6 +370,7 @@ static int cdns_dphy_probe(struct platform_device *pdev)
> >  	if (!dphy)
> >  		return -ENOMEM;
> >  	dev_set_drvdata(&pdev->dev, dphy);
> > +	dphy->dev = &pdev->dev;
> >  
> >  	dphy->ops = of_device_get_match_data(&pdev->dev);
> >  	if (!dphy->ops)
> > @@ -329,11 +380,11 @@ static int cdns_dphy_probe(struct platform_device *pdev)
> >  	if (IS_ERR(dphy->regs))
> >  		return PTR_ERR(dphy->regs);
> >  
> > -	dphy->psm_clk = devm_clk_get(&pdev->dev, "psm");
> > +	dphy->psm_clk = devm_clk_get_optional(dphy->dev, "psm");
> >  	if (IS_ERR(dphy->psm_clk))
> >  		return PTR_ERR(dphy->psm_clk);
> >  
> > -	dphy->pll_ref_clk = devm_clk_get(&pdev->dev, "pll_ref");
> > +	dphy->pll_ref_clk = devm_clk_get_optional(dphy->dev, "pll_ref");
> >  	if (IS_ERR(dphy->pll_ref_clk))
> >  		return PTR_ERR(dphy->pll_ref_clk);
> >  
> > @@ -369,7 +420,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
> >  }
> >  
> >  static const struct of_device_id cdns_dphy_of_match[] = {
> > -	{ .compatible = "cdns,dphy", .data = &ref_dphy_ops },
> > +	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
> >  	{ /* sentinel */ },
> >  };
> >  MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From laurent.pinchart at ideasonboard.com  Thu Aug 26 12:34:32 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Thu, 26 Aug 2021 22:34:32 +0300
Subject: [PATCH v4 2/6] phy: cdns-dphy: Add Rx support
In-Reply-To: <20210826184923.zgevk33rmdq6g3uo@ti.com>
References: <20210820190346.18550-1-p.yadav@ti.com>
 <20210820190346.18550-3-p.yadav@ti.com>
 <YSL79vtTGsK+zwTQ@pendragon.ideasonboard.com>
 <20210826184923.zgevk33rmdq6g3uo@ti.com>
Message-ID: <YSfsyOlYHorct2R1@pendragon.ideasonboard.com>

Hi Pratyush,

On Fri, Aug 27, 2021 at 12:19:25AM +0530, Pratyush Yadav wrote:
> On 23/08/21 04:37AM, Laurent Pinchart wrote:
> > On Sat, Aug 21, 2021 at 12:33:42AM +0530, Pratyush Yadav wrote:
> > > The Cadence DPHY can be used to receive image data over the CSI-2
> > > protocol. Add support for Rx mode. The programming sequence differs from
> > > the Tx mode so it is added as a separate set of hooks to isolate the two
> > > paths. The mode in which the DPHY has to be used is selected based on
> > > the compatible.
> > > 
> > > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > > 
> > > ---
> > > 
> > > Changes in v4:
> > > - Drop the submode parts. Use a different compatible for the Rx ops.
> > > - Make bands and num_bands static.
> > > 
> > > Changes in v3:
> > > - Use a table to select the band.
> > > - Use a table to poll the data lane ready bits.
> > > - Multiply the DPHY HS clock rate by 2 to get the bit rate since the
> > >   clock is DDR.
> > > 
> > >  drivers/phy/cadence/cdns-dphy.c | 171 ++++++++++++++++++++++++++++++++
> > >  1 file changed, 171 insertions(+)
> > > 
> > > diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> > > index 0a169d649216..149fccdfad38 100644
> > > --- a/drivers/phy/cadence/cdns-dphy.c
> > > +++ b/drivers/phy/cadence/cdns-dphy.c
> > > @@ -1,11 +1,14 @@
> > >  // SPDX-License-Identifier: GPL-2.0+
> > >  /*
> > >   * Copyright: 2017-2018 Cadence Design Systems, Inc.
> > > + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
> > >   */
> > >  
> > >  #include <linux/bitops.h>
> > > +#include <linux/bitfield.h>
> > 
> > Alphabetical order please.
> > 
> > >  #include <linux/clk.h>
> > >  #include <linux/io.h>
> > > +#include <linux/iopoll.h>
> > >  #include <linux/module.h>
> > >  #include <linux/of_address.h>
> > >  #include <linux/of_device.h>
> > > @@ -25,10 +28,14 @@
> > >  #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
> > >  #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
> > >  #define DPHY_PCS(reg)			(0xb00 + (reg))
> > > +#define DPHY_ISO(reg)			(0xc00 + (reg))
> > >  
> > >  #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
> > >  #define DPHY_CMN_SSM_EN			BIT(0)
> > > +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
> > >  #define DPHY_CMN_TX_MODE_EN		BIT(9)
> > > +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> > > +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
> > >  
> > >  #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
> > >  #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> > > @@ -45,10 +52,27 @@
> > >  #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
> > >  #define DPHY_CMN_OPDIV(x)		((x) << 7)
> > >  
> > > +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> > > +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> > > +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> > > +
> > >  #define DPHY_PSM_CFG			DPHY_PCS(0x4)
> > >  #define DPHY_PSM_CFG_FROM_REG		BIT(0)
> > >  #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
> > >  
> > > +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> > > +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> > > +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> > > +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> > > +
> > > +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> > > +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> > > +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> > > +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> > > +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> > > +#define DPHY_ISO_LANE_READY_BIT		0
> > > +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> > > +
> > >  #define DSI_HBP_FRAME_OVERHEAD		12
> > >  #define DSI_HSA_FRAME_OVERHEAD		14
> > >  #define DSI_HFP_FRAME_OVERHEAD		6
> > > @@ -57,6 +81,9 @@
> > >  #define DSI_NULL_FRAME_OVERHEAD		6
> > >  #define DSI_EOT_PKT_SIZE		4
> > >  
> > > +#define DPHY_LANES_MIN			1
> > > +#define DPHY_LANES_MAX			4
> > > +
> > >  struct cdns_dphy_cfg {
> > >  	u8 pll_ipdiv;
> > >  	u8 pll_opdiv;
> > > @@ -98,6 +125,22 @@ struct cdns_dphy {
> > >  	struct phy *phy;
> > >  };
> > >  
> > > +struct cdns_dphy_rx_band {
> > > +	unsigned int min_rate;
> > > +	unsigned int max_rate;
> > > +};
> > > +
> > > +/* Order of bands is important since the index is the band number. */
> > > +static struct cdns_dphy_rx_band bands[] = {
> > 
> > static const
> > 
> > > +	{80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240},
> > > +	{240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480},
> > > +	{480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880},
> > > +	{880, 1040}, {1040, 1200}, {1200, 1350}, {1350, 1500}, {1500, 1750},
> > > +	{1750, 2000}, {2000, 2250}, {2250, 2500}
> > > +};
> > > +
> > > +static int num_bands = ARRAY_SIZE(bands);
> > 
> > No need for a variable (which should be const otherwise), you can use
> > ARRAY_SIZE(bands) where needed.
> > 
> > > +
> > >  static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
> > >  				     struct cdns_dphy_cfg *cfg,
> > >  				     struct phy_configure_opts_mipi_dphy *opts,
> > > @@ -309,6 +352,132 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
> > >  	.set_psm_div = cdns_dphy_ref_set_psm_div,
> > >  };
> > >  
> > > +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> > > +{
> > > +	/* Start RX state machine. */
> > > +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> > > +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> > > +			  DPHY_CMN_RX_BANDGAP_TIMER),
> > > +	       dphy->regs + DPHY_CMN_SSM);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> > > +{
> > > +	writel(0, dphy->regs + DPHY_CMN_SSM);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> > > +{
> > > +	unsigned int rate;
> > > +	int i;
> > 
> > i is never negative, you can make it an unsigned int.
> > 
> > > +
> > > +	rate = hs_clk_rate / 1000000UL;
> > > +	/* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
> > > +	rate *= 2;
> > > +
> > > +	if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate)
> > > +		return -EOPNOTSUPP;
> > > +
> > > +	for (i = 0; i < num_bands; i++) {
> > > +		if (rate >= bands[i].min_rate && rate < bands[i].max_rate)
> > 
> > You can replace this with
> > 
> > 		if (rate < bands[i].max_rate)
> > 
> > as the bands are in increasing order.
> > 
> > > +			return i;
> > > +	}
> > > +
> > > +	/* Unreachable. */
> > > +	WARN(1, "Reached unreachable code.");
> > > +	return -EINVAL;
> > 
> > That's not very nice.
> > 
> > As a clock rate higher than the maximum isn't supposed to happen, you
> > could drop that initial check (it won't affect performance) and return
> > -EOPNOTSUPP here without a WARN().
> 
> Ok.
> 
> > > +}
> > > +
> > > +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> > > +{
> > > +	u32 val;
> > > +
> > > +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> > > +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
> > 
> > A busy wait for one second is quite long. How long does it typically
> > take for the condition to be true ?
> 
> I have not measured. I don't see any timing information in the 
> datasheet.
> 
> But the timeout is 100 miliseconds not 1 second. 
> readl_relaxed_poll_timeout() expects microseconds, so we multiply by 
> 1000. The value of DPHY_ISO_LANE_READY_TIMEOUT_MS is 100, so it will be 
> a 100 ms timeout, which I think is reasonable.
> 
> > > +}
> > > +
> > > +static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
> > 
> > lanes should be an unsigned int.
> > 
> > > +{
> > > +	void __iomem *reg = dphy->regs;
> > 
> > You can use dphy->regs directly in the code below.
> > 
> > > +	u32 data_lane_ctrl[] = {DPHY_ISO_DL_CTRL_L0, DPHY_ISO_DL_CTRL_L1,
> > > +				DPHY_ISO_DL_CTRL_L2, DPHY_ISO_DL_CTRL_L3};
> > 
> > static const, and move it first in the function.
> 
> Ok. But out of curiosity, why?

static const because it will then be allocated as global read-only data,
instead of being created on the stack every time the function is called
(the const also lets the compiler catch unintented modifications by
buggy code). Moving it to the beginning of the function, that's just a
coding style rule, and it may very well be personal to prefer grouping
static const data at the beginning :-) I find that it gets it out of the
way, especially as static const data needs to be initialized, and thus
results in longer lines or multi-line statements. If you prefer a
different style, that's fine too as long as the array is static const.

> > > +	int ret, i;
> > 
> > i is never negative here either.
> 
> Yes. Will change to unsigned.
> 
> > > +
> > > +	/* Data lanes. Minimum one lane is mandatory. */
> > > +	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
> > > +		return -EINVAL;
> > > +
> > > +	/* Clock lane */
> > > +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
> > > +					DPHY_ISO_LANE_READY_BIT);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	for (i = 0; i < lanes; i++) {
> > > +		ret = cdns_dphy_rx_wait_for_bit(reg + data_lane_ctrl[i],
> > > +						DPHY_ISO_LANE_READY_BIT);
> > > +		if (ret)
> > > +			return ret;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int cdns_dphy_rx_configure(struct cdns_dphy *dphy,
> > > +				  union phy_configure_opts *opts)
> > > +{
> > > +	unsigned int reg;
> > > +	int band_ctrl, ret;
> > > +
> > > +	band_ctrl = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
> > > +	if (band_ctrl < 0)
> > > +		return band_ctrl;
> > > +
> > > +	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
> > > +	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
> > > +	writel(reg, dphy->regs + DPHY_BAND_CFG);
> > > +
> > > +	/*
> > > +	 * Set the required power island phase 2 time. This is mandated by DPHY
> > > +	 * specs.
> > > +	 */
> > > +	reg = DPHY_POWER_ISLAND_EN_DATA_VAL;
> > > +	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_DATA);
> > > +	reg = DPHY_POWER_ISLAND_EN_CLK_VAL;
> > > +	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_CLK);
> > > +
> > > +	ret = cdns_dphy_rx_wait_lane_ready(dphy, opts->mipi_dphy.lanes);
> > > +	if (ret) {
> > > +		dev_err(dphy->dev, "DPHY wait for lane ready timeout\n");
> > > +		return ret;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int cdns_dphy_rx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
> > > +				 int submode, union phy_configure_opts *opts)
> > > +{
> > > +	int ret;
> > > +
> > > +	ret = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
> > > +}
> > > +
> > > +static const struct cdns_dphy_ops rx_ref_dphy_ops = {
> > > +	.power_on = cdns_dphy_rx_power_on,
> > > +	.power_off = cdns_dphy_rx_power_off,
> > > +	.configure = cdns_dphy_rx_configure,
> > > +	.validate = cdns_dphy_rx_validate,
> > > +};
> > > +
> > >  static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
> > >  			      union phy_configure_opts *opts)
> > >  {
> > > @@ -421,6 +590,7 @@ static int cdns_dphy_remove(struct platform_device *pdev)
> > >  
> > >  static const struct of_device_id cdns_dphy_of_match[] = {
> > >  	{ .compatible = "cdns,dphy", .data = &tx_ref_dphy_ops },
> > > +	{ .compatible = "cdns,dphy-rx", .data = &rx_ref_dphy_ops },
> > >  	{ /* sentinel */ },
> > >  };
> > >  MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
> > > @@ -436,5 +606,6 @@ static struct platform_driver cdns_dphy_platform_driver = {
> > >  module_platform_driver(cdns_dphy_platform_driver);
> > >  
> > >  MODULE_AUTHOR("Maxime Ripard <maxime.ripard at bootlin.com>");
> > > +MODULE_AUTHOR("Pratyush Yadav <p.yadav at ti.com>");
> > >  MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
> > >  MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart


From pali at kernel.org  Fri Aug 27 02:27:51 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Fri, 27 Aug 2021 11:27:51 +0200
Subject: [PATCH 1/3] phy: marvell: phy-mvebu-cp110-comphy: Rename HS-SGMMI to
 2500Base-X
Message-ID: <20210827092753.2359-1-pali@kernel.org>

Comphy phy mode 0x3 is incorrectly named. It is not SGMII but rather
2500Base-X mode which runs at 3.125 Gbps speed.

Rename macro names and comments to 2500Base-X.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Fixes: eb6a1fcb53e2 ("phy: mvebu-cp110-comphy: Add SMC call support")
Fixes: c2afb2fef595 ("phy: mvebu-cp110-comphy: Rename the macro handling only Ethernet modes")
---
 drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index 53ad127b100f..bbd6f2ad6f24 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -167,7 +167,7 @@
 
 #define COMPHY_FW_MODE_SATA		0x1
 #define COMPHY_FW_MODE_SGMII		0x2 /* SGMII 1G */
-#define COMPHY_FW_MODE_HS_SGMII		0x3 /* SGMII 2.5G */
+#define COMPHY_FW_MODE_2500BASEX	0x3 /* 2500BASE-X */
 #define COMPHY_FW_MODE_USB3H		0x4
 #define COMPHY_FW_MODE_USB3D		0x5
 #define COMPHY_FW_MODE_PCIE		0x6
@@ -207,7 +207,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
 	/* lane 0 */
 	GEN_CONF(0, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
 	ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
 	GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
 	/* lane 1 */
 	GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
@@ -215,10 +215,10 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
 	GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
 	GEN_CONF(1, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
 	ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
 	/* lane 2 */
 	ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
 	ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
 	ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GBASER, 0x1, COMPHY_FW_MODE_XFI),
 	GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
@@ -227,26 +227,26 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
 	/* lane 3 */
 	GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
 	ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX),
 	ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
 	GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
 	GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
 	/* lane 4 */
 	ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX),
 	ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GBASER, 0x2, COMPHY_FW_MODE_XFI),
 	ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
 	GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
 	GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
 	GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
 	ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_2500BASEX),
 	ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GBASER, -1, COMPHY_FW_MODE_XFI),
 	/* lane 5 */
 	ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
 	GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
 	ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
-	ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
+	ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
 	GEN_CONF(5, 2, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
 };
 
-- 
2.20.1



From pali at kernel.org  Fri Aug 27 02:27:52 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Fri, 27 Aug 2021 11:27:52 +0200
Subject: [PATCH 2/3] phy: marvell: phy-mvebu-a3700-comphy: Rename HS-SGMMI to
 2500Base-X
In-Reply-To: <20210827092753.2359-1-pali@kernel.org>
References: <20210827092753.2359-1-pali@kernel.org>
Message-ID: <20210827092753.2359-2-pali@kernel.org>

Comphy phy mode 0x3 is incorrectly named. It is not SGMII but rather
2500Base-X mode which runs at 3.125 Gbps speed.

Rename macro names and comments to 2500Base-X.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Fixes: 9695375a3f4a ("phy: add A3700 COMPHY support")
---
 drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
index 810f25a47632..cc534a5c4b3b 100644
--- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
@@ -29,7 +29,7 @@
 
 #define COMPHY_FW_MODE_SATA			0x1
 #define COMPHY_FW_MODE_SGMII			0x2
-#define COMPHY_FW_MODE_HS_SGMII			0x3
+#define COMPHY_FW_MODE_2500BASEX		0x3
 #define COMPHY_FW_MODE_USB3H			0x4
 #define COMPHY_FW_MODE_USB3D			0x5
 #define COMPHY_FW_MODE_PCIE			0x6
@@ -40,7 +40,7 @@
 
 #define COMPHY_FW_SPEED_1_25G			0 /* SGMII 1G */
 #define COMPHY_FW_SPEED_2_5G			1
-#define COMPHY_FW_SPEED_3_125G			2 /* SGMII 2.5G */
+#define COMPHY_FW_SPEED_3_125G			2 /* 2500BASE-X */
 #define COMPHY_FW_SPEED_5G			3
 #define COMPHY_FW_SPEED_5_15625G		4 /* XFI 5G */
 #define COMPHY_FW_SPEED_6G			5
@@ -84,14 +84,14 @@ static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = {
 	MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1,
 				    COMPHY_FW_MODE_SGMII),
 	MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1,
-				    COMPHY_FW_MODE_HS_SGMII),
+				    COMPHY_FW_MODE_2500BASEX),
 	/* lane 1 */
 	MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0,
 				    COMPHY_FW_MODE_PCIE),
 	MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0,
 				    COMPHY_FW_MODE_SGMII),
 	MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0,
-				    COMPHY_FW_MODE_HS_SGMII),
+				    COMPHY_FW_MODE_2500BASEX),
 	/* lane 2 */
 	MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0,
 				    COMPHY_FW_MODE_SATA),
@@ -205,7 +205,7 @@ static int mvebu_a3700_comphy_power_on(struct phy *phy)
 						 COMPHY_FW_SPEED_1_25G);
 			break;
 		case PHY_INTERFACE_MODE_2500BASEX:
-			dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n",
+			dev_dbg(lane->dev, "set lane %d to 2500BASEX mode\n",
 				lane->id);
 			fw_param = COMPHY_FW_NET(fw_mode, lane->port,
 						 COMPHY_FW_SPEED_3_125G);
-- 
2.20.1



From pali at kernel.org  Fri Aug 27 02:27:53 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Fri, 27 Aug 2021 11:27:53 +0200
Subject: [PATCH 3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove unsupported
 modes
In-Reply-To: <20210827092753.2359-1-pali@kernel.org>
References: <20210827092753.2359-1-pali@kernel.org>
Message-ID: <20210827092753.2359-3-pali@kernel.org>

Armada 3700 does not support RXAUI, XFI and neither SFI. Remove unused
macros for these unsupported modes.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Fixes: 9695375a3f4a ("phy: add A3700 COMPHY support")
---
 drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
index cc534a5c4b3b..6781488cfc58 100644
--- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
@@ -33,18 +33,12 @@
 #define COMPHY_FW_MODE_USB3H			0x4
 #define COMPHY_FW_MODE_USB3D			0x5
 #define COMPHY_FW_MODE_PCIE			0x6
-#define COMPHY_FW_MODE_RXAUI			0x7
-#define COMPHY_FW_MODE_XFI			0x8
-#define COMPHY_FW_MODE_SFI			0x9
 #define COMPHY_FW_MODE_USB3			0xa
 
 #define COMPHY_FW_SPEED_1_25G			0 /* SGMII 1G */
 #define COMPHY_FW_SPEED_2_5G			1
 #define COMPHY_FW_SPEED_3_125G			2 /* 2500BASE-X */
 #define COMPHY_FW_SPEED_5G			3
-#define COMPHY_FW_SPEED_5_15625G		4 /* XFI 5G */
-#define COMPHY_FW_SPEED_6G			5
-#define COMPHY_FW_SPEED_10_3125G		6 /* XFI 10G */
 #define COMPHY_FW_SPEED_MAX			0x3F
 
 #define COMPHY_FW_MODE(mode)			((mode) << 12)
-- 
2.20.1



From kabel at kernel.org  Fri Aug 27 04:27:13 2021
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Fri, 27 Aug 2021 13:27:13 +0200
Subject: [PATCH 3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove
 unsupported modes
In-Reply-To: <20210827092753.2359-3-pali@kernel.org>
References: <20210827092753.2359-1-pali@kernel.org>
 <20210827092753.2359-3-pali@kernel.org>
Message-ID: <20210827132713.61ef86f0@thinkpad>

On Fri, 27 Aug 2021 11:27:53 +0200
Pali Roh?r <pali at kernel.org> wrote:

> Armada 3700 does not support RXAUI, XFI and neither SFI. Remove unused
> macros for these unsupported modes.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Fixes: 9695375a3f4a ("phy: add A3700 COMPHY support")

BTW I was thinking about merging some parts of these 2 drivers into
common code. Not entirely sure if I should follow, though.


From patchwork-bot+netdevbpf at kernel.org  Fri Aug 27 04:30:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 27 Aug 2021 11:30:06 +0000
Subject: [PATCH 1/3] phy: marvell: phy-mvebu-cp110-comphy: Rename HS-SGMMI
 to 2500Base-X
In-Reply-To: <20210827092753.2359-1-pali@kernel.org>
References: <20210827092753.2359-1-pali@kernel.org>
Message-ID: <163006380609.3583.7131431178247172365.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Fri, 27 Aug 2021 11:27:51 +0200 you wrote:
> Comphy phy mode 0x3 is incorrectly named. It is not SGMII but rather
> 2500Base-X mode which runs at 3.125 Gbps speed.
> 
> Rename macro names and comments to 2500Base-X.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Fixes: eb6a1fcb53e2 ("phy: mvebu-cp110-comphy: Add SMC call support")
> Fixes: c2afb2fef595 ("phy: mvebu-cp110-comphy: Rename the macro handling only Ethernet modes")
> 
> [...]

Here is the summary with links:
  - [1/3] phy: marvell: phy-mvebu-cp110-comphy: Rename HS-SGMMI to 2500Base-X
    https://git.kernel.org/netdev/net-next/c/3f141ad61745
  - [2/3] phy: marvell: phy-mvebu-a3700-comphy: Rename HS-SGMMI to 2500Base-X
    https://git.kernel.org/netdev/net-next/c/b756bbec9cdd
  - [3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove unsupported modes
    https://git.kernel.org/netdev/net-next/c/0c1f5f2a5581

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From pali at kernel.org  Fri Aug 27 11:25:02 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 27 Aug 2021 20:25:02 +0200
Subject: [PATCH 3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove
 unsupported modes
In-Reply-To: <20210827132713.61ef86f0@thinkpad>
References: <20210827092753.2359-1-pali@kernel.org>
 <20210827092753.2359-3-pali@kernel.org>
 <20210827132713.61ef86f0@thinkpad>
Message-ID: <20210827182502.vdapjcqimq4ulkg2@pali>

On Friday 27 August 2021 13:27:13 Marek Beh?n wrote:
> On Fri, 27 Aug 2021 11:27:53 +0200
> Pali Roh?r <pali at kernel.org> wrote:
> 
> > Armada 3700 does not support RXAUI, XFI and neither SFI. Remove unused
> > macros for these unsupported modes.
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > Fixes: 9695375a3f4a ("phy: add A3700 COMPHY support")
> 
> BTW I was thinking about merging some parts of these 2 drivers into
> common code. Not entirely sure if I should follow, though.

cp110-comphy and a3700-comphy are just RPC drivers which calls SMC and
relay on firmware support which implements real work. And both uses same
RPC / SMC API. So merging drivers into one is possible.

But I do not think that it is a good idea that Linux kernel depends on
some external firmware which implements RPC API for configuring HW.

Rather kernel should implements its native drivers without dependency on
external firmware.

We know from history that kernel tried to avoid using x86 BIOS/firmware
due to bugs and all functionality (re)-implemented itself without using
firmware RPC functionality.

Kernel has already "hacks" in other drivers which are using these comphy
drivers, just because older versions of firmware do not support all
necessary functionality and upgrading this firmware is not easy step
(and sometimes even not possible; e.g. when is cryptographically
signed).


From linux at armlinux.org.uk  Fri Aug 27 11:33:55 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 27 Aug 2021 19:33:55 +0100
Subject: [PATCH 3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove
 unsupported modes
In-Reply-To: <20210827182502.vdapjcqimq4ulkg2@pali>
References: <20210827092753.2359-1-pali@kernel.org>
 <20210827092753.2359-3-pali@kernel.org>
 <20210827132713.61ef86f0@thinkpad>
 <20210827182502.vdapjcqimq4ulkg2@pali>
Message-ID: <20210827183355.GV22278@shell.armlinux.org.uk>

On Fri, Aug 27, 2021 at 08:25:02PM +0200, Pali Roh?r wrote:
> cp110-comphy and a3700-comphy are just RPC drivers which calls SMC and
> relay on firmware support which implements real work. And both uses same
> RPC / SMC API. So merging drivers into one is possible.
> 
> But I do not think that it is a good idea that Linux kernel depends on
> some external firmware which implements RPC API for configuring HW.
> 
> Rather kernel should implements its native drivers without dependency on
> external firmware.
> 
> We know from history that kernel tried to avoid using x86 BIOS/firmware
> due to bugs and all functionality (re)-implemented itself without using
> firmware RPC functionality.

Not really an argument in this case. We're not talking about closed
source firmware.

> Kernel has already "hacks" in other drivers which are using these comphy
> drivers, just because older versions of firmware do not support all
> necessary functionality and upgrading this firmware is not easy step
> (and sometimes even not possible; e.g. when is cryptographically
> signed).

The kernel used to (and probably still does) contain code to configure
the comphys. Having worked on trying to get the 10G lanes stable on
Macchiatobin, I much prefer the existing solution where it's in the
ATF firmware. I've rebuilt the firmware several times during the course
of that.

The advantage is that fixing the setup of the COMPHY is done in one
place, and it fixes it not only for the kernel, but also for u-boot
and UEFI too. So rather than having to maintain three different
places for a particular board, we can maintain the parameters in one
place - in the ATF firmware.

The problem with the past has been that stuff gets accepted into the
kernel without the "full system" view and without regard for "should
this actually be done in the firmware". Then, when it's decided that
it really should be done in the firmware, we end up needing to keep
the old stuff in the kernel for compatibility with older firmware,
which incidentally may not be up to date.

If we were to drop the comphy setup from firmware, then we will need
a lot of additional properties in the kernel's DT and u-boot DT for
the comphy to configure it appropriately. And ACPI. I don't think
that scales very well, and is a recipe for things getting out of
step.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From pali at kernel.org  Fri Aug 27 12:02:34 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 27 Aug 2021 21:02:34 +0200
Subject: [PATCH 3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove
 unsupported modes
In-Reply-To: <20210827183355.GV22278@shell.armlinux.org.uk>
References: <20210827092753.2359-1-pali@kernel.org>
 <20210827092753.2359-3-pali@kernel.org>
 <20210827132713.61ef86f0@thinkpad>
 <20210827182502.vdapjcqimq4ulkg2@pali>
 <20210827183355.GV22278@shell.armlinux.org.uk>
Message-ID: <20210827190234.72eakdvbgojscpkm@pali>

On Friday 27 August 2021 19:33:55 Russell King (Oracle) wrote:
> On Fri, Aug 27, 2021 at 08:25:02PM +0200, Pali Roh?r wrote:
> > cp110-comphy and a3700-comphy are just RPC drivers which calls SMC and
> > relay on firmware support which implements real work. And both uses same
> > RPC / SMC API. So merging drivers into one is possible.
> > 
> > But I do not think that it is a good idea that Linux kernel depends on
> > some external firmware which implements RPC API for configuring HW.
> > 
> > Rather kernel should implements its native drivers without dependency on
> > external firmware.
> > 
> > We know from history that kernel tried to avoid using x86 BIOS/firmware
> > due to bugs and all functionality (re)-implemented itself without using
> > firmware RPC functionality.
> 
> Not really an argument in this case. We're not talking about closed
> source firmware.
> 
> > Kernel has already "hacks" in other drivers which are using these comphy
> > drivers, just because older versions of firmware do not support all
> > necessary functionality and upgrading this firmware is not easy step
> > (and sometimes even not possible; e.g. when is cryptographically
> > signed).
> 
> The kernel used to (and probably still does) contain code to configure
> the comphys.

Kernel does not have code for A3700. Hence reason why there are hacks in
other drivers, like libata/ahci or usb/xhci.

> Having worked on trying to get the 10G lanes stable on
> Macchiatobin, I much prefer the existing solution where it's in the
> ATF firmware. I've rebuilt the firmware several times during the course
> of that.

In some cases rebuilt of firmware does not have to be possible (e.g.
when it it signed).

> The advantage is that fixing the setup of the COMPHY is done in one
> place, and it fixes it not only for the kernel, but also for u-boot

U-Boot for A3720 has its own implementation and does not use firmware
implementation (yet). So currently the only consumer of firmware
implementation is just Linux kernel.

> and UEFI too. So rather than having to maintain three different
> places for a particular board, we can maintain the parameters in one
> place - in the ATF firmware.

Same argument can be used for any other driver which is implemented in
both bootloader and kernel... But I understand also your argument.

> The problem with the past has been that stuff gets accepted into the
> kernel without the "full system" view and without regard for "should
> this actually be done in the firmware". Then, when it's decided that
> it really should be done in the firmware, we end up needing to keep
> the old stuff in the kernel for compatibility with older firmware,
> which incidentally may not be up to date.
> 
> If we were to drop the comphy setup from firmware, then we will need
> a lot of additional properties in the kernel's DT and u-boot DT for
> the comphy to configure it appropriately. And ACPI. I don't think
> that scales very well, and is a recipe for things getting out of
> step.

I think that whatever is used (firmware code, kernel code, ...), DT
should always contains full HW description with all nodes, and not only
some "subset". DT should be independent of current driver / firmware
implementation.


From linux at armlinux.org.uk  Fri Aug 27 14:10:51 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 27 Aug 2021 22:10:51 +0100
Subject: [PATCH 3/3] phy: marvell: phy-mvebu-a3700-comphy: Remove
 unsupported modes
In-Reply-To: <20210827190234.72eakdvbgojscpkm@pali>
References: <20210827092753.2359-1-pali@kernel.org>
 <20210827092753.2359-3-pali@kernel.org>
 <20210827132713.61ef86f0@thinkpad>
 <20210827182502.vdapjcqimq4ulkg2@pali>
 <20210827183355.GV22278@shell.armlinux.org.uk>
 <20210827190234.72eakdvbgojscpkm@pali>
Message-ID: <20210827211051.GW22278@shell.armlinux.org.uk>

On Fri, Aug 27, 2021 at 09:02:34PM +0200, Pali Roh?r wrote:
> I think that whatever is used (firmware code, kernel code, ...), DT
> should always contains full HW description with all nodes, and not only
> some "subset". DT should be independent of current driver / firmware
> implementation.

A "full" description of the hardware settings for the comphy on Armada
8040 would be very big if we included every single setting. There are
about a thousand settings - and that is likely an under-estimate. I
know, I've a shell script that decodes around a thousand settings from
the registers for a _single_ lane, and that's incomplete.

With many of the settings not very well documented in the manual, we
would struggle to describe it sufficiently well to get it past the DT
maintainers.

So, "full hardware description" is impractical. Sorry.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From jbx6244 at gmail.com  Sat Aug 28 04:12:17 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 13:12:17 +0200
Subject: [PATCH 1/2] dt-bindings: phy: rockchip: remove usb-phy fallback
 string for rk3066a/rk3188
Message-ID: <20210828111218.10026-1-jbx6244@gmail.com>

With the conversion of rockchip-usb-phy.yaml a long time used fallback
string for rk3066a/rk3188 was added. The linux driver doesn't do much with
the GRF phy address range, however the u-boot driver rockchip_usb2_phy.c
does. The bits in GRF_UOC0_CON2 for rk3066a/rk3188 and rk3288 for example
don't match. Remove the usb-phy fallback string for rk3066a/rk3188
to prevent possible strange side effects.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 .../devicetree/bindings/phy/rockchip-usb-phy.yaml     | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
index f0fc8275d..499d55131 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
@@ -11,13 +11,10 @@ maintainers:
 
 properties:
   compatible:
-    oneOf:
-      - const: rockchip,rk3288-usb-phy
-      - items:
-          - enum:
-              - rockchip,rk3066a-usb-phy
-              - rockchip,rk3188-usb-phy
-          - const: rockchip,rk3288-usb-phy
+    enum:
+      - rockchip,rk3066a-usb-phy
+      - rockchip,rk3188-usb-phy
+      - rockchip,rk3288-usb-phy
 
   "#address-cells":
     const: 1
-- 
2.20.1



From jbx6244 at gmail.com  Sat Aug 28 04:12:18 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 13:12:18 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: remove usb-phy fallback string for
 rk3066a/rk3188
In-Reply-To: <20210828111218.10026-1-jbx6244@gmail.com>
References: <20210828111218.10026-1-jbx6244@gmail.com>
Message-ID: <20210828111218.10026-2-jbx6244@gmail.com>

With the conversion of rockchip-usb-phy.yaml a long time used fallback
string for rk3066a/rk3188 was added. The linux driver doesn't do much with
the GRF phy address range, however the u-boot driver rockchip_usb2_phy.c
does. The bits in GRF_UOC0_CON2 for rk3066a/rk3188 and rk3288 for example
don't match. Remove the usb-phy fallback string for rk3066a/rk3188
to prevent possible strange side effects.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3066a.dtsi | 3 +--
 arch/arm/boot/dts/rk3188.dtsi  | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index cc701a4e0..10392e096 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -681,8 +681,7 @@
 	compatible = "rockchip,rk3066-grf", "syscon", "simple-mfd";
 
 	usbphy: usbphy {
-		compatible = "rockchip,rk3066a-usb-phy",
-			     "rockchip,rk3288-usb-phy";
+		compatible = "rockchip,rk3066a-usb-phy";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index d6a946a2a..922290892 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -647,8 +647,7 @@
 	};
 
 	usbphy: usbphy {
-		compatible = "rockchip,rk3188-usb-phy",
-			     "rockchip,rk3288-usb-phy";
+		compatible = "rockchip,rk3188-usb-phy";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
-- 
2.20.1



From martin.blumenstingl at googlemail.com  Sat Aug 28 08:53:54 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 17:53:54 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <20210817041548.1276-2-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
Message-ID: <CAFBinCBnH1UqaiuHgTXZTH+RPOwCWiWLVheU=bydS4mfkxTP3g@mail.gmail.com>

Hi Anand,

sorry for the late reply
I have three very small comments below, apart from these, this is looking good!

On Tue, Aug 17, 2021 at 6:17 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Add missing usb phy power node for usb node fix below warning.
> P5V0 regulator supply input voltage range to USB host controller.
> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> enable input power to USB ports, set it to Active Low.
I would phrase this last sentence as:
"enable USB VBUS on the Micro-USB port using an active high signal"
My idea here is to 1) clarify that it's about enabling USB VBUS only
on the Micro-USB port and 2) use "active high" like the changes inside
the patch itself

> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
>                 mode /soc/usb at c90c0000 failed
>
> Fixes: 2eb79a4d15ff (ARM: dts: meson: enabling the USB Host
>                 controller on Odroid-C1/C1+ board)
>
please drop this empty line

[...]
> @@ -119,7 +136,6 @@ vcc_3v3: regulator-vcc-3v3 {
>                 regulator-name = "VCC3V3";
>                 regulator-min-microvolt = <3300000>;
>                 regulator-max-microvolt = <3300000>;
> -
I don't think that we should make any VCC3V3 regulator changes in this patch
so please keep this empty line as-is.


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Sat Aug 28 08:56:08 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 17:56:08 +0200
Subject: [PATCHv3 2/6] ARM: dts: meson8b: odroidc1: Set usb power source
 to always on
In-Reply-To: <20210817041548.1276-3-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-3-linux.amoon@gmail.com>
Message-ID: <CAFBinCB8CK8Bn2xKpiAToQQ4K1_W1XZjND9pOGZRZeMp-grs3Q@mail.gmail.com>

Hi Anand,

On Tue, Aug 17, 2021 at 6:17 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Set P5V0 and vcc_3v3 power source to USB to always on
> so that regulator should not enter in suspend state.
Neither of these two regulators can be controlled by Linux in any way
(there's no GPIO to turn them off, no PWM signal to change the output
voltage, etc.).
So can you please explain what this patch changes from a functional perspective?


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Sat Aug 28 09:00:28 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 18:00:28 +0200
Subject: [PATCHv3 3/6] arm64: dts: amlogic: odroidc2: Fix the chip enable
 signal for usb power
In-Reply-To: <20210817041548.1276-4-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-4-linux.amoon@gmail.com>
Message-ID: <CAFBinCAx33SnuL8n1GF8nz2Q4giNR8tsWxjU32X0wsb6kR_nhw@mail.gmail.com>

Hi Anand,

On Tue, Aug 17, 2021 at 6:17 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Fix the chip enable signal changing from Active High to Active Low
> to enable input power to USB power. Also updated signal name as per
> the schematics.
according to [0] (page 12) Odroid-C2 uses an "RT9715EGB" for USB OTG power
The datasheet for that power switch [1] mentions on page page 1 that
the "E" stands for "E : 1.1A/Active High"

Can you please elaborate how you have tested this to confirm that
active low is the correct polarity?


Best regards,
Martin


[0] https://dn.odroid.com/S905/Schematic/odroid-c2_rev0.1_20150930.pdf
[1] https://www.richtek.com/assets/product_file/RT9715/DS9715-03.pdf


From martin.blumenstingl at googlemail.com  Sat Aug 28 09:06:55 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 18:06:55 +0200
Subject: [PATCHv3 4/6] arm64: dts: amlogic: odroidc2: use vbus-supply for
 power source for usb nodes
In-Reply-To: <20210817041548.1276-5-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-5-linux.amoon@gmail.com>
Message-ID: <CAFBinCDDASbbwBWdPnzq4352yepamD-ziG09Ki=BvjZ9xMLXdQ@mail.gmail.com>

Hi Anand,

On Tue, Aug 17, 2021 at 6:18 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Use vbus-supply instead of phy-supply as power source for dwc2
> nodes. Drop vbus-supply for usb0 node, as it will handle later.
This is more of a question than a review comment:
Do you think that the USB power setup on Odroid-C1 and Odroid-C2 is
different or the same?
On Odroid-C1 we know that only the PWREN signal which goes to the
Micro-USB connector is configurable while VBUS for the USB host ports
is always enabled.

> Fixes: e841ec956e53 ("ARM64: dts: meson-gxbb-odroidc2:
>        fix usb1 power supply")
>
most Linux commits which I have seen don't use a blank line here
Also I think it's recommended not to break the "Fixes" tag into
multiple lines, even if the text is long
see [0] for example


Best regards,
Martin


[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=425bec0032f59eeee12520085cd054fac09cc66e


From rashmi.a at intel.com  Sun Aug 29 11:24:39 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:39 +0530
Subject: [PATCH v2 0/4] Add support of eMMC PHY for Intel Thunder Bay
Message-ID: <20210829182443.30802-1-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

This patch set enables the support for eMMC PHY on the Intel Thunder 
Bay SoC. eMMC PHY is based on arasan phy.
 
Patch 1 Adds arasan sdhci support for eMMC in Intel Thunder Bay.
Patch 2 Adds arasan sdhci dt bindings.
Patch 3 Holds the device tree binding documentation for eMMC PHY
	and listings of new files in MAINTAINERS file.
Patch 4 Holds the eMMC PHY driver.


Rashmi A (4):
  mmc: sdhci-of-arasan: Add intel Thunder Bay SOC support to the arasan
    eMMC driver
  dt-bindings: mmc: Add bindings for Intel Thunder Bay SoC
  dt-bindings: phy: intel: Add Thunder Bay eMMC PHY bindings
  phy: intel: Add Thunder Bay eMMC PHY support

 .../devicetree/bindings/mmc/arasan,sdhci.yaml |  25 +
 .../phy/intel,phy-thunderbay-emmc.yaml        |  46 ++
 MAINTAINERS                                   |   7 +
 drivers/mmc/host/sdhci-of-arasan.c            |  29 +-
 drivers/phy/intel/Kconfig                     |  10 +
 drivers/phy/intel/Makefile                    |   1 +
 drivers/phy/intel/phy-intel-thunderbay-emmc.c | 512 ++++++++++++++++++
 7 files changed, 629 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
 create mode 100644 drivers/phy/intel/phy-intel-thunderbay-emmc.c

-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:40 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:40 +0530
Subject: [PATCH v2 1/4] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-2-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Intel Thunder Bay SoC eMMC controller is based on Arasan
eMMC 5.1 host controller IP

Signed-off-by: Rashmi A <rashmi.a at intel.com>
Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>
---
 drivers/mmc/host/sdhci-of-arasan.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 839965f7c717..6f202fb7a546 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -185,6 +185,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {
 	.hiword_update = false,
 };
 
+static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = {
+	.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
+	.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
+	.support64b = { .reg = 0x4, .width = 1, .shift = 24 },
+	.hiword_update = false,
+};
+
 static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {
 	.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
 	.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
@@ -430,6 +437,15 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {
 			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
 };
 
+static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = {
+	.ops = &sdhci_arasan_cqe_ops,
+	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+		SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
+		SDHCI_QUIRK2_STOP_WITH_TC |
+		SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400,
+};
+
 #ifdef CONFIG_PM_SLEEP
 /**
  * sdhci_arasan_suspend - Suspend method for the driver
@@ -1098,6 +1114,12 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {
 	.clk_ops = &arasan_clk_ops,
 };
 
+static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data = {
+	.soc_ctl_map = &thunderbay_soc_ctl_map,
+	.pdata = &sdhci_arasan_thunderbay_pdata,
+	.clk_ops = &arasan_clk_ops,
+};
+
 static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
 	.ops = &sdhci_arasan_cqe_ops,
 	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
@@ -1231,6 +1253,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
 		.compatible = "intel,keembay-sdhci-5.1-sdio",
 		.data = &intel_keembay_sdio_data,
 	},
+	{
+		.compatible = "intel,thunderbay-sdhci-5.1",
+		.data = &sdhci_arasan_thunderbay_data,
+	},
 	/* Generic compatible below here */
 	{
 		.compatible = "arasan,sdhci-8.9a",
@@ -1582,7 +1608,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
 
 	if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
 	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
-	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
+	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") ||
+	    of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1")) {
 		sdhci_arasan_update_clockmultiplier(host, 0x0);
 		sdhci_arasan_update_support64b(host, 0x0);
 
-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:41 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:41 +0530
Subject: [PATCH v2 2/4] dt-bindings: mmc: Add bindings for Intel Thunder Bay
 SoC
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-3-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Add documentation for Arasan SDHCI controller in Thunder Bay SOC.

Signed-off-by: Rashmi A <rashmi.a at intel.com>
---
 .../devicetree/bindings/mmc/arasan,sdhci.yaml | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml b/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
index 37a5fe7b26dc..23abb7e8b9d8 100644
--- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
+++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
@@ -88,6 +88,12 @@ properties:
         description:
           For this device it is strongly suggested to include
           arasan,soc-ctl-syscon.
+      - items:
+          - const: intel,thunderbay-sdhci-5.1   # Intel Thunder Bay eMMC PHY
+          - const: arasan,sdhci-5.1
+        description:
+          For this device it is strongly suggested to include
+          clock-output-names and '#clock-cells'.
 
   reg:
     maxItems: 1
@@ -301,3 +307,22 @@ examples:
                    <&scmi_clk KEEM_BAY_PSS_SD0>;
           arasan,soc-ctl-syscon = <&sd0_phy_syscon>;
     };
+
+  - |
+    #define EMMC_XIN_CLK
+    #define EMMC_AXI_CLK
+    #define TBH_PSS_EMMC_RST_N
+    mmc at 80420000 {
+          compatible = "intel,thunderbay-sdhci-5.1", "arasan,sdhci-5.1";
+          interrupts = <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>;
+          reg = <0x80420000 0x400>;
+          clocks = <&scmi_clk EMMC_XIN_CLK>,
+                   <&scmi_clk EMMC_AXI_CLK>;
+          clock-names = "clk_xin", "clk_ahb";
+          phys = <&emmc_phy>;
+          phy-names = "phy_arasan";
+          assigned-clocks = <&scmi_clk EMMC_XIN_CLK>;
+          clock-output-names = "emmc_cardclock";
+          resets = <&rst_pss1 TBH_PSS_EMMC_RST_N>;
+          #clock-cells = <0x0>;
+    };
-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:42 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:42 +0530
Subject: [PATCH v2 3/4] dt-bindings: phy: intel: Add Thunder Bay eMMC PHY
 bindings
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-4-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Binding description for Intel Thunder Bay eMMC PHY.
Added the newly introduced files into MAINTAINERS file-list

Signed-off-by: Rashmi A <rashmi.a at intel.com>
---
 .../phy/intel,phy-thunderbay-emmc.yaml        | 46 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++
 2 files changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml

diff --git a/Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml b/Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
new file mode 100644
index 000000000000..34bdb5c4cae8
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/intel,phy-thunderbay-emmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel Thunder Bay eMMC PHY bindings
+
+maintainers:
+  - Srikandan Nandhini <nandhini.srikandan at intel.com>
+
+properties:
+  compatible:
+    const: intel,thunderbay-emmc-phy
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: emmcclk
+
+required:
+  - "#phy-cells"
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+     mmc_phy at 80440800 {
+     #phy-cells = <0x0>;
+     compatible = "intel,thunderbay-emmc-phy";
+     status = "okay";
+     reg = <0x80440800 0x100>;
+     clocks = <&emmc>;
+     clock-names = "emmcclk";
+     };
diff --git a/MAINTAINERS b/MAINTAINERS
index bd7aff0c120f..44533319c900 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9278,6 +9278,13 @@ F:	drivers/crypto/keembay/keembay-ocs-hcu-core.c
 F:	drivers/crypto/keembay/ocs-hcu.c
 F:	drivers/crypto/keembay/ocs-hcu.h
 
+INTEL THUNDER BAY EMMC PHY DRIVER
+M:	Nandhini Srikandan <nandhini.srikandan at intel.com>
+M:	Rashmi A <rashmi.a at intel.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
+F:	drivers/phy/intel/phy-intel-thunderbay-emmc.c
+
 INTEL MANAGEMENT ENGINE (mei)
 M:	Tomas Winkler <tomas.winkler at intel.com>
 L:	linux-kernel at vger.kernel.org
-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:43 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:43 +0530
Subject: [PATCH v2 4/4] phy: intel: Add Thunder Bay eMMC PHY support
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-5-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Add support of eMMC PHY for Intel Thunder Bay SoC,
uses the Arasan eMMC phy

Signed-off-by: Rashmi A <rashmi.a at intel.com>
Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>
---
 drivers/phy/intel/Kconfig                     |  10 +
 drivers/phy/intel/Makefile                    |   1 +
 drivers/phy/intel/phy-intel-thunderbay-emmc.c | 512 ++++++++++++++++++
 3 files changed, 523 insertions(+)
 create mode 100644 drivers/phy/intel/phy-intel-thunderbay-emmc.c

diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig
index ac42bb2fb394..18a3cc5b98c0 100644
--- a/drivers/phy/intel/Kconfig
+++ b/drivers/phy/intel/Kconfig
@@ -46,3 +46,13 @@ config PHY_INTEL_LGM_EMMC
 	select GENERIC_PHY
 	help
 	  Enable this to support the Intel EMMC PHY
+
+config PHY_INTEL_THUNDERBAY_EMMC
+        tristate "Intel Thunder Bay eMMC PHY driver"
+        depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST)
+        select GENERIC_PHY
+        help
+	  This option enables support for Intel Thunder Bay SoC eMMC PHY.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called phy-intel-thunderbay-emmc.ko.
diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile
index 14550981a707..b7321d56b0bb 100644
--- a/drivers/phy/intel/Makefile
+++ b/drivers/phy/intel/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC)	+= phy-intel-keembay-emmc.o
 obj-$(CONFIG_PHY_INTEL_KEEMBAY_USB)	+= phy-intel-keembay-usb.o
 obj-$(CONFIG_PHY_INTEL_LGM_COMBO)	+= phy-intel-lgm-combo.o
 obj-$(CONFIG_PHY_INTEL_LGM_EMMC)	+= phy-intel-lgm-emmc.o
+obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC) += phy-intel-thunderbay-emmc.o
diff --git a/drivers/phy/intel/phy-intel-thunderbay-emmc.c b/drivers/phy/intel/phy-intel-thunderbay-emmc.c
new file mode 100644
index 000000000000..385659dd87be
--- /dev/null
+++ b/drivers/phy/intel/phy-intel-thunderbay-emmc.c
@@ -0,0 +1,512 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel ThunderBay eMMC PHY driver
+ *
+ * Copyright (C) 2021 Intel Corporation
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* eMMC/SD/SDIO core/phy configuration registers */
+#define CTRL_CFG_0	0x00
+#define CTRL_CFG_1	0x04
+#define CTRL_PRESET_0	0x08
+#define CTRL_PRESET_1	0x0c
+#define CTRL_PRESET_2	0x10
+#define CTRL_PRESET_3	0x14
+#define CTRL_PRESET_4	0x18
+#define CTRL_CFG_2	0x1c
+#define CTRL_CFG_3	0x20
+#define PHY_CFG_0	0x24
+#define PHY_CFG_1	0x28
+#define PHY_CFG_2	0x2c
+#define PHYBIST_CTRL	0x30
+#define SDHC_STAT3	0x34
+#define PHY_STAT	0x38
+#define PHYBIST_STAT_0	0x3c
+#define PHYBIST_STAT_1	0x40
+#define EMMC_AXI        0x44
+
+/* CTRL_PRESET_3 */
+#define CTRL_PRESET3_MASK	GENMASK(31, 0)
+#define CTRL_PRESET3_SHIFT	0
+
+/* CTRL_CFG_0 bit fields */
+#define SUPPORT_HS_MASK		BIT(26)
+#define SUPPORT_HS_SHIFT	26
+
+#define SUPPORT_8B_MASK		BIT(24)
+#define SUPPORT_8B_SHIFT	24
+
+/* CTRL_CFG_1 bit fields */
+#define SUPPORT_SDR50_MASK	BIT(28)
+#define SUPPORT_SDR50_SHIFT	28
+#define SLOT_TYPE_MASK		GENMASK(27, 26)
+#define SLOT_TYPE_OFFSET	26
+#define SUPPORT_64B_MASK	BIT(24)
+#define SUPPORT_64B_SHIFT	24
+#define SUPPORT_HS400_MASK	BIT(2)
+#define SUPPORT_HS400_SHIFT	2
+#define SUPPORT_DDR50_MASK	BIT(1)
+#define SUPPORT_DDR50_SHIFT	1
+#define SUPPORT_SDR104_MASK	BIT(0)
+#define SUPPORT_SDR104_SHIFT	0
+
+/* PHY_CFG_0 bit fields */
+#define SEL_DLY_TXCLK_MASK      BIT(29)
+#define SEL_DLY_TXCLK_SHIFT	29
+#define SEL_DLY_RXCLK_MASK      BIT(28)
+#define SEL_DLY_RXCLK_SHIFT	28
+
+#define OTAP_DLY_ENA_MASK	BIT(27)
+#define OTAP_DLY_ENA_SHIFT	27
+#define OTAP_DLY_SEL_MASK	GENMASK(26, 23)
+#define OTAP_DLY_SEL_SHIFT	23
+#define ITAP_CHG_WIN_MASK	BIT(22)
+#define ITAP_CHG_WIN_SHIFT	22
+#define ITAP_DLY_ENA_MASK	BIT(21)
+#define ITAP_DLY_ENA_SHIFT	21
+#define ITAP_DLY_SEL_MASK	GENMASK(20, 16)
+#define ITAP_DLY_SEL_SHIFT	16
+#define RET_ENB_MASK		BIT(15)
+#define RET_ENB_SHIFT		15
+#define RET_EN_MASK		BIT(14)
+#define RET_EN_SHIFT		14
+#define DLL_IFF_MASK		GENMASK(13, 11)
+#define DLL_IFF_SHIFT		11
+#define DLL_EN_MASK		BIT(10)
+#define DLL_EN_SHIFT		10
+#define DLL_TRIM_ICP_MASK	GENMASK(9, 6)
+#define DLL_TRIM_ICP_SHIFT	6
+#define RETRIM_EN_MASK		BIT(5)
+#define RETRIM_EN_SHIFT		5
+#define RETRIM_MASK		BIT(4)
+#define RETRIM_SHIFT		4
+#define DR_TY_MASK		GENMASK(3, 1)
+#define DR_TY_SHIFT		1
+#define PWR_DOWN_MASK		BIT(0)
+#define PWR_DOWN_SHIFT		0
+
+/* PHY_CFG_1 bit fields */
+#define REN_DAT_MASK		GENMASK(19, 12)
+#define REN_DAT_SHIFT		12
+#define REN_CMD_MASK		BIT(11)
+#define REN_CMD_SHIFT		11
+#define REN_STRB_MASK		BIT(10)
+#define REN_STRB_SHIFT		10
+#define PU_STRB_MASK		BIT(20)
+#define PU_STRB_SHIFT		20
+
+/* PHY_CFG_2 bit fields */
+#define CLKBUF_MASK		GENMASK(24, 21)
+#define CLKBUF_SHIFT		21
+#define SEL_STRB_MASK		GENMASK(20, 13)
+#define SEL_STRB_SHIFT		13
+#define SEL_FREQ_MASK		GENMASK(12, 10)
+#define SEL_FREQ_SHIFT		10
+
+/* PHY_STAT bit fields */
+#define CAL_DONE		BIT(6)
+#define DLL_RDY			BIT(5)
+
+#define OTAP_DLY		0x0
+#define ITAP_DLY		0x0
+#define STRB			0x33
+
+/* From ACS_eMMC51_16nFFC_RO1100_Userguide_v1p0.pdf p17 */
+#define FREQSEL_200M_170M	0x0
+#define FREQSEL_170M_140M	0x1
+#define FREQSEL_140M_110M	0x2
+#define FREQSEL_110M_80M	0x3
+#define FREQSEL_80M_50M		0x4
+#define FREQSEL_275M_250M	0x5
+#define FREQSEL_250M_225M	0x6
+#define FREQSEL_225M_200M	0x7
+
+/* Phy power status */
+#define PHY_UNINITIALIZED	0
+#define PHY_INITIALIZED		1
+
+/*
+ * During init(400KHz) phy_settings will be called with 200MHZ clock
+ * To avoid incorrectly setting the phy for init(400KHZ) "phy_power_sts" is used.
+ * When actual clock is set always phy is powered off once and then powered on.
+ * (sdhci_arasan_set_clock). That feature will be used to identify whether the
+ * settings are for init phy_power_on or actual clock phy_power_on
+ * 0 --> init settings
+ * 1 --> actual settings
+ */
+
+struct thunderbay_emmc_phy {
+	void __iomem    *reg_base;
+	struct clk      *emmcclk;
+	int phy_power_sts;
+};
+
+static inline void update_reg(struct thunderbay_emmc_phy *tbh_phy, u32 offset,
+			      u32 mask, u32 shift, u32 val)
+{
+	u32 tmp;
+
+	tmp = readl(tbh_phy->reg_base + offset);
+	tmp &= ~mask;
+	tmp |= val << shift;
+	writel(tmp, tbh_phy->reg_base + offset);
+}
+
+static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+	unsigned int freqsel = FREQSEL_200M_170M;
+	unsigned long rate;
+	static int lock;
+	u32 val;
+	int ret;
+
+	/* Disable DLL */
+	rate = clk_get_rate(tbh_phy->emmcclk);
+	switch (rate) {
+	case 200000000:
+		/* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */
+		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0);
+		break;
+
+	/* dll lock not required for other frequencies */
+	case 50000000 ... 52000000:
+	case 400000:
+	default:
+		break;
+	}
+
+	if (!power_on)
+		return 0;
+
+	rate = clk_get_rate(tbh_phy->emmcclk);
+	switch (rate) {
+	case 170000001 ... 200000000:
+		freqsel = FREQSEL_200M_170M;
+		break;
+
+	case 140000001 ... 170000000:
+		freqsel = FREQSEL_170M_140M;
+		break;
+
+	case 110000001 ... 140000000:
+		freqsel = FREQSEL_140M_110M;
+		break;
+
+	case 80000001 ... 110000000:
+		freqsel = FREQSEL_110M_80M;
+		break;
+
+	case 50000000 ... 80000000:
+		freqsel = FREQSEL_80M_50M;
+		break;
+
+	case 250000001 ... 275000000:
+		freqsel = FREQSEL_275M_250M;
+		break;
+
+	case 225000001 ... 250000000:
+		freqsel = FREQSEL_250M_225M;
+		break;
+
+	case 200000001 ... 225000000:
+		freqsel = FREQSEL_225M_200M;
+		break;
+	default:
+		break;
+	}
+	/* Clock rate is checked against upper limit. It may fall low during init */
+	if (rate > 200000000)
+		dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
+
+	udelay(5);
+
+	if (lock == 0) {
+		/* PDB will be done only once per boot */
+		update_reg(tbh_phy, PHY_CFG_0, PWR_DOWN_MASK,
+			   PWR_DOWN_SHIFT, 0x1);
+		lock = 1;
+		/*
+		 * According to the user manual, it asks driver to wait 5us for
+		 * calpad busy trimming. However it is documented that this value is
+		 * PVT(A.K.A. process, voltage and temperature) relevant, so some
+		 * failure cases are found which indicates we should be more tolerant
+		 * to calpad busy trimming.
+		 */
+		ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT,
+					 val, (val & CAL_DONE), 10, 50);
+		if (ret) {
+			dev_err(&phy->dev, "caldone failed, ret=%d\n", ret);
+			return ret;
+		}
+	}
+	rate = clk_get_rate(tbh_phy->emmcclk);
+	switch (rate) {
+	case 200000000:
+		/* Set frequency of the DLL operation */
+		update_reg(tbh_phy, PHY_CFG_2, SEL_FREQ_MASK, SEL_FREQ_SHIFT, freqsel);
+
+		/* Enable DLL */
+		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x1);
+
+		/*
+		 * After enabling analog DLL circuits docs say that we need 10.2 us if
+		 * our source clock is at 50 MHz and that lock time scales linearly
+		 * with clock speed. If we are powering on the PHY and the card clock
+		 * is super slow (like 100kHz) this could take as long as 5.1 ms as
+		 * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms
+		 * hopefully we won't be running at 100 kHz, but we should still make
+		 * sure we wait long enough.
+		 *
+		 * NOTE: There appear to be corner cases where the DLL seems to take
+		 * extra long to lock for reasons that aren't understood. In some
+		 * extreme cases we've seen it take up to over 10ms (!). We'll be
+		 * generous and give it 50ms.
+		 */
+		ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT,
+					 val, (val & DLL_RDY), 10, 50 * USEC_PER_MSEC);
+		if (ret) {
+			dev_err(&phy->dev, "dllrdy failed, ret=%d\n", ret);
+			return ret;
+		}
+		break;
+
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int thunderbay_emmc_phy_init(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+
+	tbh_phy->emmcclk = clk_get(&phy->dev, "emmcclk");
+
+	return PTR_ERR_OR_ZERO(tbh_phy->emmcclk);
+}
+
+static int thunderbay_emmc_phy_exit(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+
+	clk_put(tbh_phy->emmcclk);
+
+	return 0;
+}
+
+static int thunderbay_emmc_phy_power_on(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+	unsigned long rate;
+
+	/* Overwrite capability bits configurable in bootloader */
+	update_reg(tbh_phy, CTRL_CFG_0,
+		   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_0,
+		   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
+
+	if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
+		/* Indicates initialization, settings for init, same as 400KHZ setting */
+		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1);
+		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1);
+		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0);
+		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0);
+		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0);
+		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0);
+		update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0);
+		update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
+
+	} else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
+		/* Indicates actual clock setting */
+		rate = clk_get_rate(tbh_phy->emmcclk);
+		switch (rate) {
+		case 200000000:
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 2);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0x8);
+			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
+				   DR_TY_SHIFT, 0x1);
+			/* For HS400 only */
+			update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
+				   SEL_STRB_SHIFT, STRB);
+			break;
+
+		case 50000000 ... 52000000:
+			/* For both HS and DDR52 this setting works */
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 4);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0x8);
+			update_reg(tbh_phy, PHY_CFG_0,
+				   DR_TY_MASK, DR_TY_SHIFT, 0x1);
+			break;
+
+		case 400000:
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 0);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0);
+			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
+			break;
+
+		default:
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 2);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0x8);
+			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
+				   DR_TY_SHIFT, 0x1);
+			break;
+		}
+		/* Reset, init seq called without phy_power_off, this indicates init seq */
+		tbh_phy->phy_power_sts = PHY_UNINITIALIZED;
+	}
+
+	update_reg(tbh_phy, PHY_CFG_0, RETRIM_EN_MASK, RETRIM_EN_SHIFT, 0x1);
+	update_reg(tbh_phy, PHY_CFG_0, RETRIM_MASK, RETRIM_SHIFT, 0x0);
+
+	return thunderbay_emmc_phy_power(phy, 1);
+}
+
+static int thunderbay_emmc_phy_power_off(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+
+	tbh_phy->phy_power_sts = PHY_INITIALIZED;
+
+	return thunderbay_emmc_phy_power(phy, 0);
+}
+
+static const struct phy_ops thunderbay_emmc_phy_ops = {
+	.init		= thunderbay_emmc_phy_init,
+	.exit		= thunderbay_emmc_phy_exit,
+	.power_on	= thunderbay_emmc_phy_power_on,
+	.power_off	= thunderbay_emmc_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct of_device_id thunderbay_emmc_phy_of_match[] = {
+	{ .compatible = "intel,thunderbay-emmc-phy",
+		(void *)&thunderbay_emmc_phy_ops },
+	{}
+};
+MODULE_DEVICE_TABLE(of, thunderbay_emmc_phy_of_match);
+
+static int thunderbay_emmc_phy_probe(struct platform_device *pdev)
+{
+	struct thunderbay_emmc_phy *tbh_phy;
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *id;
+	struct phy *generic_phy;
+	struct resource *res;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	tbh_phy = devm_kzalloc(dev, sizeof(*tbh_phy), GFP_KERNEL);
+	if (!tbh_phy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tbh_phy->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tbh_phy->reg_base)) {
+		dev_err(&pdev->dev, "region map failed\n");
+		return PTR_ERR(tbh_phy->reg_base);
+	}
+
+	tbh_phy->phy_power_sts = PHY_UNINITIALIZED;
+	id = of_match_node(thunderbay_emmc_phy_of_match, pdev->dev.of_node);
+	if (!id) {
+		dev_err(dev, "failed to get match_node\n");
+		return -EINVAL;
+	}
+
+	generic_phy = devm_phy_create(dev, dev->of_node, id->data);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, tbh_phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver thunderbay_emmc_phy_driver = {
+	.probe		 = thunderbay_emmc_phy_probe,
+	.driver		 = {
+		.name	 = "thunderbay-emmc-phy",
+		.of_match_table = thunderbay_emmc_phy_of_match,
+	},
+};
+module_platform_driver(thunderbay_emmc_phy_driver);
+
+MODULE_AUTHOR("Nandhini S <nandhini.srikandan at intel.com>");
+MODULE_AUTHOR("Rashmi A <rashmi.a at intel.com>");
+MODULE_DESCRIPTION("Intel Thunder Bay eMMC PHY driver");
+MODULE_LICENSE("GPL v2");
+
-- 
2.17.1



From narmstrong at baylibre.com  Mon Aug 30 00:45:26 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 30 Aug 2021 09:45:26 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <20210817041548.1276-2-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
Message-ID: <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>

Hi,

On 17/08/2021 06:15, Anand Moon wrote:
> Add missing usb phy power node for usb node fix below warning.
> P5V0 regulator supply input voltage range to USB host controller.
> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> enable input power to USB ports, set it to Active Low.
> 
> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
> 		mode /soc/usb at c90c0000 failed

First of all, DT is not here to fix boot message.

Secondly, if the vbus-supply is optional, the message should be removed from
the driver/regulator core instead.

Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
should not be added at all.

Neil

> 
> Fixes: 2eb79a4d15ff (ARM: dts: meson: enabling the USB Host
> 		controller on Odroid-C1/C1+ board)
> 
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
> V2 > changes gpio polarity ACTIVE_HIGH to ACTIVE_LOW.
>      Fix the source power from phy-supply to vbus-supply.
> 
> [1] https://lore.kernel.org/linux-devicetree/20210716103651.1455-2-linux.amoon at gmail.com/
> 
> V1 > Fix the Input GPIO polarity from HIGH to LOW.
> 
> previous version
> [0] https://patchwork.kernel.org/project/linux-amlogic/patch/20190113181808.5768-1-linux.amoon at gmail.com
> 
> changes fix the vbus-suppy to phy-supply, drop enable usb0
> 
>     USB_PWR                       2    1      0 unknown  5000mV     0mA  5000mV  5000mV
>        phy-c1108820.phy.0-phy     2                                 0mA     0mV     0mV
> ---
>  arch/arm/boot/dts/meson8b-odroidc1.dts | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
> index c440ef94e082..30ec6a7f20c7 100644
> --- a/arch/arm/boot/dts/meson8b-odroidc1.dts
> +++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
> @@ -32,6 +32,23 @@ emmc_pwrseq: emmc-pwrseq {
>  		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
>  	};
>  
> +	usb_pwr_en: regulator-usb-pwr-en {
> +		compatible = "regulator-fixed";
> +
> +		regulator-name = "USB_OTG_PWR";
> +
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		/*
> +		 * signal name from schematics: USB_POWER - P5V0
> +		 */
> +		vin-supply = <&p5v0>;
> +		/*
> +		 * signal name from schematics: PWREN - GPIOAO.BIT5
> +		 */
> +		gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>;
> +	};
> +
>  	leds {
>  		compatible = "gpio-leds";
>  		blue {
> @@ -119,7 +136,6 @@ vcc_3v3: regulator-vcc-3v3 {
>  		regulator-name = "VCC3V3";
>  		regulator-min-microvolt = <3300000>;
>  		regulator-max-microvolt = <3300000>;
> -
>  		vin-supply = <&p5v0>;

As martin said, only a single functional change per patch please, this line removal should go in another patch.

>  	};
>  
> @@ -382,4 +398,5 @@ &usb1_phy {
>  
>  &usb1 {
>  	status = "okay";
> +	vbus-supply = <&usb_pwr_en>;
>  };
> 



From mike.rudenko at gmail.com  Mon Aug 30 11:07:49 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:49 +0300
Subject: [PATCH v1 0/5] phy: phy-rockchip-dphy-rx0: add support for tx1rx1 rx
 mode
Message-ID: <20210830180758.251390-1-mike.rudenko@gmail.com>

Implement support for RX mode of TX1RX1 D-PHY on RK3399. Code is based
on Rockchip BSP kernel branch 4.4. These patches have been tested on
FriendlyElec NanoPi M4 with OmniVision 4689-based sensor.


Mikhail Rudenko (5):
  phy: phy-rockchip-dphy-rx0: refactor for tx1rx1 addition
  phy: phy-rockchip-dphy-rx0: add support for tx1rx1 in receive mode
  phy: rename phy-rockchip-dphy-rx0 to phy-rockchip-dphy-rx
  dt-bindings: phy: phy-rockchip-dphy-rx0: add support for tx1rx1 phy
  arm64: dts: rockchip: add mipi-dphy-tx1rx1 for rk3399

 ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} |  39 ++-
 arch/arm64/boot/dts/rockchip/rk3399.dtsi      |  15 ++
 drivers/phy/rockchip/Kconfig                  |   8 +-
 drivers/phy/rockchip/Makefile                 |   2 +-
 ...chip-dphy-rx0.c => phy-rockchip-dphy-rx.c} | 231 +++++++++++++++---
 5 files changed, 252 insertions(+), 43 deletions(-)
 rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)
 rename drivers/phy/rockchip/{phy-rockchip-dphy-rx0.c => phy-rockchip-dphy-rx.c} (63%)

--
2.33.0


From mike.rudenko at gmail.com  Mon Aug 30 11:07:50 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:50 +0300
Subject: [PATCH v1 1/5] phy: phy-rockchip-dphy-rx0: refactor for tx1rx1
 addition
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-2-mike.rudenko@gmail.com>

In order to accommodate for rk3399 tx1rx1 addition, make
enable/disable function calls indirect via function pointers in
rk_dphy_drv_data. Also rename rk_dphy_write and rk_dphy_enable to
avoid naming clashes.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 38 +++++++++++++-------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
index 4df9476ef2a9..72145cdfb036 100644
--- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
+++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
@@ -138,12 +138,17 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
 	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
 };
 
+struct rk_dphy;
+
 struct rk_dphy_drv_data {
 	const char * const *clks;
 	unsigned int num_clks;
 	const struct hsfreq_range *hsfreq_ranges;
 	unsigned int num_hsfreq_ranges;
 	const struct dphy_reg *regs;
+
+	void (*enable)(struct rk_dphy *priv);
+	void (*disable)(struct rk_dphy *priv);
 };
 
 struct rk_dphy {
@@ -170,7 +175,7 @@ static inline void rk_dphy_write_grf(struct rk_dphy *priv,
 	regmap_write(priv->grf, reg->offset, val);
 }
 
-static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
+static void rk_dphy_write_mipi_rx(struct rk_dphy *priv, u8 test_code, u8 test_data)
 {
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_code);
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 1);
@@ -186,7 +191,7 @@ static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
 }
 
-static void rk_dphy_enable(struct rk_dphy *priv)
+static void rk_dphy_enable_rx(struct rk_dphy *priv)
 {
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
@@ -206,22 +211,27 @@ static void rk_dphy_enable(struct rk_dphy *priv)
 	usleep_range(100, 150);
 
 	/* set clock lane */
-	/* HS hsfreq_range & lane 0  settle bypass */
-	rk_dphy_write(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
+	/* HS hsfreq_range & lane 0	 settle bypass */
+	rk_dphy_write_mipi_rx(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
 	/* HS RX Control of lane0 */
-	rk_dphy_write(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Control of lane1 */
-	rk_dphy_write(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Control of lane2 */
-	rk_dphy_write(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Control of lane3 */
-	rk_dphy_write(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Data Lanes Settle State Time Control */
-	rk_dphy_write(priv, LANES_THS_SETTLE_CONTROL,
-		      THS_SETTLE_COUNTER_THRESHOLD);
+	rk_dphy_write_mipi_rx(priv, LANES_THS_SETTLE_CONTROL,
+			  THS_SETTLE_COUNTER_THRESHOLD);
 
 	/* Normal operation */
-	rk_dphy_write(priv, 0x0, 0);
+	rk_dphy_write_mipi_rx(priv, 0x0, 0);
+}
+
+static void rk_dphy_disable_rx(struct rk_dphy *priv)
+{
+	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
 }
 
 static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
@@ -266,7 +276,7 @@ static int rk_dphy_power_on(struct phy *phy)
 	if (ret)
 		return ret;
 
-	rk_dphy_enable(priv);
+	priv->drv_data->enable(priv);
 
 	return 0;
 }
@@ -275,7 +285,7 @@ static int rk_dphy_power_off(struct phy *phy)
 {
 	struct rk_dphy *priv = phy_get_drvdata(phy);
 
-	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
+	priv->drv_data->disable(priv);
 	clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
 	return 0;
 }
@@ -310,6 +320,8 @@ static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
 	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
 	.regs = rk3399_grf_dphy_regs,
+	.enable = rk_dphy_enable_rx,
+	.disable = rk_dphy_disable_rx,
 };
 
 static const struct of_device_id rk_dphy_dt_ids[] = {
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:51 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:51 +0300
Subject: [PATCH v1 2/5] phy: phy-rockchip-dphy-rx0: add support for tx1rx1 in
 receive mode
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-3-mike.rudenko@gmail.com>

Implement RX mode of RK3399 TX1RX1 MIPI D-PHY. Unlike RX0 phy, it uses
both mmio registers and grf for configuration. Add necessary register
definitions, mmio register access functions, enable/disable functions,
rk_dphy_drv_data instance and compatible string for tx1rx1. Probe
function is adjusted accordingly.

Additionally, individual init function is implemented, since,
according to the comments in Rockchip BSP kernel, "According to the
sequence of RK3399_TXRX_DPHY, the setting of isp0 mipi will affect
txrx dphy in default state of grf_soc_con24."

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 193 +++++++++++++++++--
 1 file changed, 172 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
index 72145cdfb036..3ce307b49e51 100644
--- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
+++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
@@ -34,6 +34,12 @@
 #define RK3399_GRF_SOC_CON24		0x6260
 #define RK3399_GRF_SOC_CON25		0x6264
 #define RK3399_GRF_SOC_STATUS1		0xe2a4
+#define RK3399_GRF_IO_VSEL			0x0900
+
+#define RK3399_PHY_TEST_CTRL0	0xb4
+#define RK3399_PHY_TEST_CTRL1	0xb8
+#define RK3399_PHY_SHUTDOWNZ	0xa0
+#define RK3399_PHY_RSTZ		0xa0
 
 #define CLOCK_LANE_HS_RX_CONTROL	0x34
 #define LANE0_HS_RX_CONTROL		0x44
@@ -43,6 +49,11 @@
 #define LANES_THS_SETTLE_CONTROL	0x75
 #define THS_SETTLE_COUNTER_THRESHOLD	0x04
 
+#define PHY_TESTEN_ADDR			(0x1 << 16)
+#define PHY_TESTEN_DATA			(0x0 << 16)
+#define PHY_TESTCLK			(0x1 << 1)
+#define PHY_TESTCLR			(0x1 << 0)
+
 struct hsfreq_range {
 	u16 range_h;
 	u8 cfg_bit;
@@ -61,12 +72,6 @@ static const struct hsfreq_range rk3399_mipidphy_hsfreq_ranges[] = {
 	{ 1399, 0x1c }, { 1449, 0x2c }, { 1500, 0x3c }
 };
 
-static const char * const rk3399_mipidphy_clks[] = {
-	"dphy-ref",
-	"dphy-cfg",
-	"grf",
-};
-
 enum dphy_reg_id {
 	GRF_DPHY_RX0_TURNDISABLE = 0,
 	GRF_DPHY_RX0_FORCERXMODE,
@@ -99,6 +104,14 @@ enum dphy_reg_id {
 	/* below is for rk3399 only */
 	GRF_DPHY_RX0_CLK_INV_SEL,
 	GRF_DPHY_RX1_CLK_INV_SEL,
+	GRF_DPHY_TX1RX1_SRC_SEL,
+};
+
+enum txrx_reg_id {
+	TXRX_PHY_TEST_CTRL0 = 0,
+	TXRX_PHY_TEST_CTRL1,
+	TXRX_PHY_SHUTDOWNZ,
+	TXRX_PHY_RSTZ,
 };
 
 struct dphy_reg {
@@ -127,7 +140,7 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
 	[GRF_DPHY_TX1RX1_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 8),
 	[GRF_DPHY_TX1RX1_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 12),
 	[GRF_DPHY_TX1RX1_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON24, 4, 0),
-	[GRF_DPHY_RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
+	[GRF_DPHY_TX1RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
 	[GRF_DPHY_TX1RX1_BASEDIR] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 5),
 	[GRF_DPHY_TX1RX1_ENABLECLK] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 6),
 	[GRF_DPHY_TX1RX1_MASTERSLAVEZ] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 7),
@@ -136,6 +149,21 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
 	[GRF_DPHY_RX0_TESTCLK] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 9),
 	[GRF_DPHY_RX0_TESTCLR] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 10),
 	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
+	[GRF_DVP_V18SEL] = PHY_REG(RK3399_GRF_IO_VSEL, 1, 1),
+};
+
+struct txrx_reg {
+	u32 offset;
+};
+
+#define TXRX_REG(_offset) \
+	{ .offset = _offset, }
+
+static const struct txrx_reg rk3399_txrx_regs[] = {
+	[TXRX_PHY_TEST_CTRL0] = TXRX_REG(RK3399_PHY_TEST_CTRL0),
+	[TXRX_PHY_TEST_CTRL1] = TXRX_REG(RK3399_PHY_TEST_CTRL1),
+	[TXRX_PHY_SHUTDOWNZ] = TXRX_REG(RK3399_PHY_SHUTDOWNZ),
+	[TXRX_PHY_RSTZ] = TXRX_REG(RK3399_PHY_RSTZ),
 };
 
 struct rk_dphy;
@@ -146,15 +174,18 @@ struct rk_dphy_drv_data {
 	const struct hsfreq_range *hsfreq_ranges;
 	unsigned int num_hsfreq_ranges;
 	const struct dphy_reg *regs;
+	const struct txrx_reg *txrx_regs;
 
 	void (*enable)(struct rk_dphy *priv);
 	void (*disable)(struct rk_dphy *priv);
+	void (*individual_init)(struct rk_dphy *priv);
 };
 
 struct rk_dphy {
 	struct device *dev;
 	struct regmap *grf;
 	struct clk_bulk_data *clks;
+	void __iomem *txrx_base_addr;
 
 	const struct rk_dphy_drv_data *drv_data;
 	struct phy_configure_opts_mipi_dphy config;
@@ -234,6 +265,74 @@ static void rk_dphy_disable_rx(struct rk_dphy *priv)
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
 }
 
+static inline void rk_dphy_write_tx1rx1(struct rk_dphy *priv,
+				  int index, u32 value)
+{
+	const struct txrx_reg *reg = &priv->drv_data->txrx_regs[index];
+
+	if (reg->offset)
+		writel(value, priv->txrx_base_addr + reg->offset);
+}
+
+static void rk_dphy_write_mipi_tx1rx1(struct rk_dphy *priv, unsigned char addr,
+				 unsigned char data)
+{
+	/*
+	 * TESTEN =1,TESTDIN=addr
+	 * TESTCLK=0
+	 * TESTEN =0,TESTDIN=data
+	 * TESTCLK=1
+	 */
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL1, PHY_TESTEN_ADDR | addr);
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, 0x00);
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL1, PHY_TESTEN_DATA | data);
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, 0x02);
+}
+
+static void rk_dphy_enable_txrx(struct rk_dphy *priv)
+{
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, PHY_TESTCLR | PHY_TESTCLK);
+	usleep_range(100, 150);
+
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_MASTERSLAVEZ, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_BASEDIR, 1);
+
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_FORCERXMODE, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_FORCETXSTOPMODE, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_TURNREQUEST, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_TURNDISABLE, 0xf);
+	usleep_range(100, 150);
+
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, PHY_TESTCLK);
+	usleep_range(100, 150);
+
+	rk_dphy_write_mipi_tx1rx1(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE1_HS_RX_CONTROL, 0);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE2_HS_RX_CONTROL, 0);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE3_HS_RX_CONTROL, 0);
+
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_ENABLE, GENMASK(priv->config.lanes - 1, 0));
+	usleep_range(100, 150);
+}
+
+static void rk_dphy_disable_txrx(struct rk_dphy *priv)
+{
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_ENABLE, 0);
+}
+
+static void rk3399_mipidphy_individual_init(struct rk_dphy *priv)
+{
+	/*
+	 * According to the sequence of RK3399_TXRX_DPHY, the setting of isp0 mipi
+	 * will affect txrx dphy in default state of grf_soc_con24.
+	 */
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_SRC_SEL, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_MASTERSLAVEZ, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_BASEDIR, 0);
+	rk_dphy_write_grf(priv, GRF_DVP_V18SEL, 0x1);
+}
+
 static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 {
 	struct rk_dphy *priv = phy_get_drvdata(phy);
@@ -314,20 +413,50 @@ static const struct phy_ops rk_dphy_ops = {
 	.owner		= THIS_MODULE,
 };
 
-static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
-	.clks = rk3399_mipidphy_clks,
-	.num_clks = ARRAY_SIZE(rk3399_mipidphy_clks),
+static const char * const rk3399_mipidphy_rx_clks[] = {
+	"dphy-ref",
+	"dphy-cfg",
+	"grf",
+};
+
+static const char * const rk3399_mipidphy_txrx_clks[] = {
+	"dphy-ref",
+	"dphy-cfg",
+	"grf",
+	"dsi",
+};
+
+static const struct rk_dphy_drv_data rk3399_mipidphy_rx_drv_data = {
+	.clks = rk3399_mipidphy_rx_clks,
+	.num_clks = ARRAY_SIZE(rk3399_mipidphy_rx_clks),
 	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
 	.regs = rk3399_grf_dphy_regs,
 	.enable = rk_dphy_enable_rx,
 	.disable = rk_dphy_disable_rx,
+	.individual_init = rk3399_mipidphy_individual_init,
+};
+
+static const struct rk_dphy_drv_data rk3399_mipidphy_txrx_drv_data = {
+	.clks = rk3399_mipidphy_txrx_clks,
+	.num_clks = ARRAY_SIZE(rk3399_mipidphy_txrx_clks),
+	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
+	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
+	.regs = rk3399_grf_dphy_regs,
+	.txrx_regs = rk3399_txrx_regs,
+	.enable = rk_dphy_enable_txrx,
+	.disable = rk_dphy_disable_txrx,
+	.individual_init = rk3399_mipidphy_individual_init,
 };
 
 static const struct of_device_id rk_dphy_dt_ids[] = {
 	{
 		.compatible = "rockchip,rk3399-mipi-dphy-rx0",
-		.data = &rk3399_mipidphy_drv_data,
+		.data = &rk3399_mipidphy_rx_drv_data,
+	},
+	{
+		.compatible = "rockchip,rk3399-mipi-dphy-tx1rx1",
+		.data = &rk3399_mipidphy_txrx_drv_data,
 	},
 	{}
 };
@@ -345,26 +474,42 @@ static int rk_dphy_probe(struct platform_device *pdev)
 	unsigned int i;
 	int ret;
 
-	if (!dev->parent || !dev->parent->of_node)
-		return -ENODEV;
-
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 	priv->dev = dev;
 
-	priv->grf = syscon_node_to_regmap(dev->parent->of_node);
-	if (IS_ERR(priv->grf)) {
-		dev_err(dev, "Can't find GRF syscon\n");
-		return -ENODEV;
-	}
-
 	of_id = of_match_device(rk_dphy_dt_ids, dev);
 	if (!of_id)
 		return -EINVAL;
 
 	drv_data = of_id->data;
 	priv->drv_data = drv_data;
+
+	if (!drv_data->txrx_regs) {
+		if (!dev->parent || !dev->parent->of_node)
+			return -ENODEV;
+
+		priv->grf = syscon_node_to_regmap(dev->parent->of_node);
+		if (IS_ERR(priv->grf)) {
+			dev_err(dev, "Can't find GRF syscon\n");
+			return -ENODEV;
+		}
+	} else {
+		priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+							    "rockchip,grf");
+		if (IS_ERR(priv->grf)) {
+			dev_err(dev, "Can't find GRF syscon\n");
+			return -ENODEV;
+		}
+
+		priv->txrx_base_addr = devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(priv->txrx_base_addr)) {
+			dev_err(dev, "Failed to ioremap resource\n");
+			return PTR_ERR(priv->txrx_base_addr);
+		}
+	}
+
 	priv->clks = devm_kcalloc(&pdev->dev, drv_data->num_clks,
 				  sizeof(*priv->clks), GFP_KERNEL);
 	if (!priv->clks)
@@ -383,8 +528,14 @@ static int rk_dphy_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy, priv);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		dev_err(dev, "failed to register phy provider\n");
+		return PTR_ERR(phy_provider);
+	}
 
-	return PTR_ERR_OR_ZERO(phy_provider);
+	drv_data->individual_init(priv);
+
+	return 0;
 }
 
 static struct platform_driver rk_dphy_driver = {
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:52 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:52 +0300
Subject: [PATCH v1 3/5] phy: rename phy-rockchip-dphy-rx0 to
 phy-rockchip-dphy-rx
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-4-mike.rudenko@gmail.com>

Since the driver now supports both rx0 and tx1rx1 phys, rename module
and Kconfig option to phy-rockchip-dphy-rx and PHY_ROCKCHIP_DPHY_RX
respectively.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 drivers/phy/rockchip/Kconfig                              | 8 ++++----
 drivers/phy/rockchip/Makefile                             | 2 +-
 .../{phy-rockchip-dphy-rx0.c => phy-rockchip-dphy-rx.c}   | 0
 3 files changed, 5 insertions(+), 5 deletions(-)
 rename drivers/phy/rockchip/{phy-rockchip-dphy-rx0.c => phy-rockchip-dphy-rx.c} (100%)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index e812adad7242..6096ca9a07f9 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -9,17 +9,17 @@ config PHY_ROCKCHIP_DP
 	help
 	  Enable this to support the Rockchip Display Port PHY.
 
-config PHY_ROCKCHIP_DPHY_RX0
+config PHY_ROCKCHIP_DPHY_RX
 	tristate "Rockchip MIPI Synopsys DPHY RX0 driver"
 	depends on ARCH_ROCKCHIP || COMPILE_TEST
 	select GENERIC_PHY_MIPI_DPHY
 	select GENERIC_PHY
 	help
-	  Enable this to support the Rockchip MIPI Synopsys DPHY RX0
-	  associated to the Rockchip ISP module present in RK3399 SoCs.
+	  Enable this to support the Rockchip MIPI Synopsys DPHY RX
+	  associated to the Rockchip ISP modules present in RK3399 SoCs.
 
 	  To compile this driver as a module, choose M here: the module
-	  will be called phy-rockchip-dphy-rx0.
+	  will be called phy-rockchip-dphy-rx.
 
 config PHY_ROCKCHIP_EMMC
 	tristate "Rockchip EMMC PHY Driver"
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index f0eec212b2aa..2d28526808a6 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_PHY_ROCKCHIP_DP)		+= phy-rockchip-dp.o
-obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0)     += phy-rockchip-dphy-rx0.o
+obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX)     += phy-rockchip-dphy-rx.o
 obj-$(CONFIG_PHY_ROCKCHIP_EMMC)		+= phy-rockchip-emmc.o
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY)	+= phy-rockchip-inno-csidphy.o
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY)	+= phy-rockchip-inno-dsidphy.o
diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx.c
similarity index 100%
rename from drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
rename to drivers/phy/rockchip/phy-rockchip-dphy-rx.c
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:53 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:53 +0300
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add support
 for tx1rx1 phy
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-5-mike.rudenko@gmail.com>

RK3399 TX1RX1 D-PHY is not a child of GRF and uses reg, thus add
corresponding properties conditionally. It also requires DSI clock to
operate, so check for it. Since we now support both rx0 and tx1rx1,
rename the schema to rockchip-mipi-dphy-rx.yaml.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} | 39 +++++++++++++++++--
 1 file changed, 35 insertions(+), 4 deletions(-)
 rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)

diff --git a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
similarity index 65%
rename from Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
rename to Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
index 7d888d358823..f42319448fc9 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx0.yaml#
+$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Rockchip SoC MIPI RX0 D-PHY Device Tree Bindings
+title: Rockchip SoC MIPI RX0/TX1RX1 D-PHY Device Tree Bindings
 
 maintainers:
   - Helen Koike <helen.koike at collabora.com>
@@ -16,19 +16,28 @@ description: |
 
 properties:
   compatible:
-    const: rockchip,rk3399-mipi-dphy-rx0
+    enum:
+      - rockchip,rk3399-mipi-dphy-rx0
+      - rockchip,rk3399-mipi-dphy-tx1rx1
+
+  reg:
+    maxItems: 1
 
   clocks:
+    minItems: 3
     items:
       - description: MIPI D-PHY ref clock
-      - description: MIPI D-PHY RX0 cfg clock
+      - description: MIPI D-PHY RX0/TX1RX1 cfg clock
       - description: Video in/out general register file clock
+      - description: MIPI D-PHY DSI clock
 
   clock-names:
+    minItems: 3
     items:
       - const: dphy-ref
       - const: dphy-cfg
       - const: grf
+      - const: dsi
 
   '#phy-cells':
     const: 0
@@ -37,6 +46,12 @@ properties:
     description: Video in/out power domain.
     maxItems: 1
 
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the general register file
+      (GRF), required for TX1RX1 MIPI D-PHY on RK3399.
+
 required:
   - compatible
   - clocks
@@ -44,6 +59,22 @@ required:
   - '#phy-cells'
   - power-domains
 
+if:
+  properties:
+    compatible:
+      contains:
+          const: rockchip,rk3399-mipi-dphy-tx1rx1
+then:
+  required:
+    - reg
+    - rockchip,grf
+
+  properties:
+    clocks:
+      minItems: 4
+    clock-names:
+      minItems: 4
+
 additionalProperties: false
 
 examples:
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:54 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:54 +0300
Subject: [PATCH v1 5/5] arm64: dts: rockchip: add mipi-dphy-tx1rx1 for rk3399
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-6-mike.rudenko@gmail.com>

Add DT node for RX mode of RK3399 TX1RX1 D-PHY.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 3871c7fd83b0..2e4513275a87 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1902,6 +1902,21 @@ mipi1_in_vopl: endpoint at 1 {
 		};
 	};
 
+	mipi_dphy_tx1rx1: mipi-dphy-tx1rx1 at ff968000 {
+		compatible = "rockchip,rk3399-mipi-dphy-tx1rx1";
+		reg = <0x0 0xff968000 0x0 0x8000>;
+		clocks = <&cru SCLK_MIPIDPHY_REF>,
+			<&cru SCLK_DPHY_TX1RX1_CFG>,
+			<&cru PCLK_VIO_GRF>,
+			<&cru PCLK_MIPI_DSI1>;
+		clock-names = "dphy-ref", "dphy-cfg",
+			"grf", "dsi";
+		rockchip,grf = <&grf>;
+		power-domains = <&power RK3399_PD_VIO>;
+		#phy-cells = <0>;
+		status = "disabled";
+	};
+
 	edp: edp at ff970000 {
 		compatible = "rockchip,rk3399-edp";
 		reg = <0x0 0xff970000 0x0 0x8000>;
-- 
2.33.0



From martin.blumenstingl at googlemail.com  Mon Aug 30 12:37:12 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 30 Aug 2021 21:37:12 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
 <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
Message-ID: <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>

Hi Neil,

On Mon, Aug 30, 2021 at 9:45 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 17/08/2021 06:15, Anand Moon wrote:
> > Add missing usb phy power node for usb node fix below warning.
> > P5V0 regulator supply input voltage range to USB host controller.
> > As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> > enable input power to USB ports, set it to Active Low.
> >
> > [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> > [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
> >               mode /soc/usb at c90c0000 failed
>
> First of all, DT is not here to fix boot message.
Anand mentioned elsewhere that this is a debug/info message

> Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
> to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
> should not be added at all.
I think there's a misunderstanding because there's two PWREN signals
with different meanings.
The PWREN signal for the USB host ports is hard-wired and not
connected to the SoC at all.
The PWREN signal for the Micro-USB port (which Anand is adding here)
is controlled by GPIOAO_5. odroid-c1+_rev0.4_20150615.pdf [0] shows it
as an input to "USB_OTG" on page 1. "USB_OTG" consists of a power
switch and the connector itself as shown on page 28.

Personally I think that the change from Anand itself is good.
If you feel otherwise then please speak up.
As I pointed out three smaller changes I am hoping that Anand will
re-send the updated patch anyways. At that point he can also add the
changes from your feedback.


Best regards,
Martin


[0] https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20150615.pdf


From heiko at sntech.de  Mon Aug 30 13:45:03 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 30 Aug 2021 22:45:03 +0200
Subject: [PATCH v1 1/5] phy: phy-rockchip-dphy-rx0: refactor for tx1rx1
 addition
In-Reply-To: <20210830180758.251390-2-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-2-mike.rudenko@gmail.com>
Message-ID: <6474995.6kXVAnRFRJ@diego>

Hi Mikhail,

Am Montag, 30. August 2021, 20:07:50 CEST schrieb Mikhail Rudenko:
> In order to accommodate for rk3399 tx1rx1 addition, make
> enable/disable function calls indirect via function pointers in
> rk_dphy_drv_data. Also rename rk_dphy_write and rk_dphy_enable to
> avoid naming clashes.

You're a bit too late to the party :-( .

The tx1rx1 dphy is living _inside_ the 2nd DSI controller and is
configured through it. 

So having the same peripheral in the dts with different compatibles
does break the devicetree-describes-hardware-not-Linux-implementation-details
paradigm.

Therefore my approach was to handle the switch between tx and rx modes
inside the dsi driver. This got merged for 5.15 as well, see [0] [1].

So sadly this series is somewhat obsolete, but you should find the
building blocks for camera support in linux-next already.


Regards
Heiko




[0] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=71f68fe7f12182ed968cfbbd1ef018721e4dee30
[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=68e0277204c733dff19073686e2ac48239b06fbc


> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 38 +++++++++++++-------
>  1 file changed, 25 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
> index 4df9476ef2a9..72145cdfb036 100644
> --- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
> +++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
> @@ -138,12 +138,17 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
>  	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
>  };
>  
> +struct rk_dphy;
> +
>  struct rk_dphy_drv_data {
>  	const char * const *clks;
>  	unsigned int num_clks;
>  	const struct hsfreq_range *hsfreq_ranges;
>  	unsigned int num_hsfreq_ranges;
>  	const struct dphy_reg *regs;
> +
> +	void (*enable)(struct rk_dphy *priv);
> +	void (*disable)(struct rk_dphy *priv);
>  };
>  
>  struct rk_dphy {
> @@ -170,7 +175,7 @@ static inline void rk_dphy_write_grf(struct rk_dphy *priv,
>  	regmap_write(priv->grf, reg->offset, val);
>  }
>  
> -static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
> +static void rk_dphy_write_mipi_rx(struct rk_dphy *priv, u8 test_code, u8 test_data)
>  {
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_code);
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 1);
> @@ -186,7 +191,7 @@ static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
>  }
>  
> -static void rk_dphy_enable(struct rk_dphy *priv)
> +static void rk_dphy_enable_rx(struct rk_dphy *priv)
>  {
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
> @@ -206,22 +211,27 @@ static void rk_dphy_enable(struct rk_dphy *priv)
>  	usleep_range(100, 150);
>  
>  	/* set clock lane */
> -	/* HS hsfreq_range & lane 0  settle bypass */
> -	rk_dphy_write(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
> +	/* HS hsfreq_range & lane 0	 settle bypass */
> +	rk_dphy_write_mipi_rx(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
>  	/* HS RX Control of lane0 */
> -	rk_dphy_write(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Control of lane1 */
> -	rk_dphy_write(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Control of lane2 */
> -	rk_dphy_write(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Control of lane3 */
> -	rk_dphy_write(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Data Lanes Settle State Time Control */
> -	rk_dphy_write(priv, LANES_THS_SETTLE_CONTROL,
> -		      THS_SETTLE_COUNTER_THRESHOLD);
> +	rk_dphy_write_mipi_rx(priv, LANES_THS_SETTLE_CONTROL,
> +			  THS_SETTLE_COUNTER_THRESHOLD);
>  
>  	/* Normal operation */
> -	rk_dphy_write(priv, 0x0, 0);
> +	rk_dphy_write_mipi_rx(priv, 0x0, 0);
> +}
> +
> +static void rk_dphy_disable_rx(struct rk_dphy *priv)
> +{
> +	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
>  }
>  
>  static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> @@ -266,7 +276,7 @@ static int rk_dphy_power_on(struct phy *phy)
>  	if (ret)
>  		return ret;
>  
> -	rk_dphy_enable(priv);
> +	priv->drv_data->enable(priv);
>  
>  	return 0;
>  }
> @@ -275,7 +285,7 @@ static int rk_dphy_power_off(struct phy *phy)
>  {
>  	struct rk_dphy *priv = phy_get_drvdata(phy);
>  
> -	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
> +	priv->drv_data->disable(priv);
>  	clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
>  	return 0;
>  }
> @@ -310,6 +320,8 @@ static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
>  	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
>  	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
>  	.regs = rk3399_grf_dphy_regs,
> +	.enable = rk_dphy_enable_rx,
> +	.disable = rk_dphy_disable_rx,
>  };
>  
>  static const struct of_device_id rk_dphy_dt_ids[] = {
> 






From jbx6244 at gmail.com  Mon Aug 30 14:00:17 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 30 Aug 2021 23:00:17 +0200
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add
 support for tx1rx1 phy
In-Reply-To: <20210830180758.251390-5-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-5-mike.rudenko@gmail.com>
Message-ID: <60aa055c-d872-3e5c-3c85-09300215a60e@gmail.com>

Hi Mikhail,

Some comments below. Have a look if it is useful.

On 8/30/21 8:07 PM, Mikhail Rudenko wrote:
> RK3399 TX1RX1 D-PHY is not a child of GRF and uses reg, thus add
> corresponding properties conditionally. It also requires DSI clock to
> operate, so check for it. Since we now support both rx0 and tx1rx1,
> rename the schema to rockchip-mipi-dphy-rx.yaml.
> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} | 39 +++++++++++++++++--
>  1 file changed, 35 insertions(+), 4 deletions(-)
>  rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
> similarity index 65%
> rename from Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
> rename to Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
> index 7d888d358823..f42319448fc9 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
> @@ -1,10 +1,10 @@
>  # SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  %YAML 1.2
>  ---
> -$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx0.yaml#
> +$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx.yaml#
>  $schema: http://devicetree.org/meta-schemas/core.yaml#
>  
> -title: Rockchip SoC MIPI RX0 D-PHY Device Tree Bindings
> +title: Rockchip SoC MIPI RX0/TX1RX1 D-PHY Device Tree Bindings
>  
>  maintainers:
>    - Helen Koike <helen.koike at collabora.com>
> @@ -16,19 +16,28 @@ description: |
>  
>  properties:
>    compatible:
> -    const: rockchip,rk3399-mipi-dphy-rx0
> +    enum:
> +      - rockchip,rk3399-mipi-dphy-rx0
> +      - rockchip,rk3399-mipi-dphy-tx1rx1
> +

> +  reg:
> +    maxItems: 1

This allows every node to have a reg property.

>  
>    clocks:
> +    minItems: 3
>      items:
>        - description: MIPI D-PHY ref clock
> -      - description: MIPI D-PHY RX0 cfg clock
> +      - description: MIPI D-PHY RX0/TX1RX1 cfg clock
>        - description: Video in/out general register file clock
> +      - description: MIPI D-PHY DSI clock
>  
>    clock-names:
> +    minItems: 3
>      items:
>        - const: dphy-ref
>        - const: dphy-cfg
>        - const: grf
> +      - const: dsi
>  
>    '#phy-cells':
>      const: 0
> @@ -37,6 +46,12 @@ properties:
>      description: Video in/out power domain.
>      maxItems: 1
>  

> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the general register file
> +      (GRF), required for TX1RX1 MIPI D-PHY on RK3399.

This allows every node to have a rockchip,grf property.

> +
>  required:
>    - compatible
>    - clocks
> @@ -44,6 +59,22 @@ required:
>    - '#phy-cells'
>    - power-domains
>  
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +          const: rockchip,rk3399-mipi-dphy-tx1rx1
> +then:

> +  required:

Move/swap the properties section above the required section.

> +    - reg
> +    - rockchip,grf
> +
> +  properties:

  reg:
    maxItems: 1

> +    clocks:
> +      minItems: 4
> +    clock-names:
> +      minItems: 4

  rockchip,grf:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      The phandle of the syscon node for the general register file(GRF).


", required for TX1RX1 MIPI D-PHY on RK3399."

This phrase is already said/done with the "required:" section above

>  additionalProperties: false
>  
>  examples:
> 


From jbx6244 at gmail.com  Mon Aug 30 14:12:00 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 30 Aug 2021 23:12:00 +0200
Subject: [PATCH v1 5/5] arm64: dts: rockchip: add mipi-dphy-tx1rx1 for
 rk3399
In-Reply-To: <20210830180758.251390-6-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-6-mike.rudenko@gmail.com>
Message-ID: <ac38a6ce-19f6-8d30-6070-55b78cc082e2@gmail.com>

Hi Mikhail,

On 8/30/21 8:07 PM, Mikhail Rudenko wrote:
> Add DT node for RX mode of RK3399 TX1RX1 D-PHY.
> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> index 3871c7fd83b0..2e4513275a87 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> @@ -1902,6 +1902,21 @@ mipi1_in_vopl: endpoint at 1 {
>  		};
>  	};
>  
> +	mipi_dphy_tx1rx1: mipi-dphy-tx1rx1 at ff968000 {
> +		compatible = "rockchip,rk3399-mipi-dphy-tx1rx1";
> +		reg = <0x0 0xff968000 0x0 0x8000>;

> +		clocks = <&cru SCLK_MIPIDPHY_REF>,
> +			<&cru SCLK_DPHY_TX1RX1_CFG>,
> +			<&cru PCLK_VIO_GRF>,
> +			<&cru PCLK_MIPI_DSI1>;
> +		clock-names = "dphy-ref", "dphy-cfg",
> +			"grf", "dsi";

Could you fix the alignment a bit with extra spaces?

> +		rockchip,grf = <&grf>;
> +		power-domains = <&power RK3399_PD_VIO>;

Sort in alphabetical order.

> +		#phy-cells = <0>;
> +		status = "disabled";
> +	};
> +
>  	edp: edp at ff970000 {
>  		compatible = "rockchip,rk3399-edp";
>  		reg = <0x0 0xff970000 0x0 0x8000>;
> 


From jbx6244 at gmail.com  Mon Aug 30 14:50:21 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 30 Aug 2021 23:50:21 +0200
Subject: [PATCH v1 5/5] arm64: dts: rockchip: add mipi-dphy-tx1rx1 for
 rk3399
In-Reply-To: <ac38a6ce-19f6-8d30-6070-55b78cc082e2@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-6-mike.rudenko@gmail.com>
 <ac38a6ce-19f6-8d30-6070-55b78cc082e2@gmail.com>
Message-ID: <909ebc5f-3a9b-c793-a4fa-07429effd8c3@gmail.com>



On 8/30/21 11:12 PM, Johan Jonker wrote:
> Hi Mikhail,
> 
> On 8/30/21 8:07 PM, Mikhail Rudenko wrote:
>> Add DT node for RX mode of RK3399 TX1RX1 D-PHY.
>>
>> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
>> index 3871c7fd83b0..2e4513275a87 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
>> @@ -1902,6 +1902,21 @@ mipi1_in_vopl: endpoint at 1 {
>>  		};
>>  	};
>>  


>> +	mipi_dphy_tx1rx1: mipi-dphy-tx1rx1 at ff968000 {
>> +		compatible = "rockchip,rk3399-mipi-dphy-tx1rx1";



	mipi_dsi1: mipi at ff968000 {
		compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi";
		reg = <0x0 0xff968000 0x0 0x8000>;

Sorry, there's already a node in mainline. Excuse...
See Heiko's comment.


>> +		reg = <0x0 0xff968000 0x0 0x8000>;
> 
>> +		clocks = <&cru SCLK_MIPIDPHY_REF>,
>> +			<&cru SCLK_DPHY_TX1RX1_CFG>,
>> +			<&cru PCLK_VIO_GRF>,
>> +			<&cru PCLK_MIPI_DSI1>;
>> +		clock-names = "dphy-ref", "dphy-cfg",
>> +			"grf", "dsi";
> 
> Could you fix the alignment a bit with extra spaces?
> 
>> +		rockchip,grf = <&grf>;
>> +		power-domains = <&power RK3399_PD_VIO>;
> 
> Sort in alphabetical order.
> 
>> +		#phy-cells = <0>;
>> +		status = "disabled";
>> +	};
>> +
>>  	edp: edp at ff970000 {
>>  		compatible = "rockchip,rk3399-edp";
>>  		reg = <0x0 0xff970000 0x0 0x8000>;
>>


From jbx6244 at gmail.com  Mon Aug 30 15:06:46 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 31 Aug 2021 00:06:46 +0200
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add
 support for tx1rx1 phy
In-Reply-To: <60aa055c-d872-3e5c-3c85-09300215a60e@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-5-mike.rudenko@gmail.com>
 <60aa055c-d872-3e5c-3c85-09300215a60e@gmail.com>
Message-ID: <a9ce814a-d23e-2f5d-0299-4ffbb76609da@gmail.com>

Hi Mikhail,

The file in the link below is in need for a YAML conversion.
Could you help?

Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt

- compatible: one of
	"rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi"
	"rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"
	"rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"

On 8/30/21 11:00 PM, Johan Jonker wrote:

> Some comments below. Have a look if it is useful.
> 


From robh at kernel.org  Mon Aug 30 17:03:53 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 19:03:53 -0500
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add
 support for tx1rx1 phy
In-Reply-To: <20210830180758.251390-5-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-5-mike.rudenko@gmail.com>
Message-ID: <1630368233.493531.2940839.nullmailer@robh.at.kernel.org>

On Mon, 30 Aug 2021 21:07:53 +0300, Mikhail Rudenko wrote:
> RK3399 TX1RX1 D-PHY is not a child of GRF and uses reg, thus add
> corresponding properties conditionally. It also requires DSI clock to
> operate, so check for it. Since we now support both rx0 and tx1rx1,
> rename the schema to rockchip-mipi-dphy-rx.yaml.
> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} | 39 +++++++++++++++++--
>  1 file changed, 35 insertions(+), 4 deletions(-)
>  rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/phy/rockchip-mipi-dphy-rx0.yaml'
xargs: dt-doc-validate: exited with status 255; aborting
make[1]: *** Deleting file 'Documentation/devicetree/bindings/soc/rockchip/grf.example.dt.yaml'
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/phy/rockchip-mipi-dphy-rx0.yaml'
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/soc/rockchip/grf.example.dt.yaml] Error 255
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1522296

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From ezequiel at vanguardiasur.com.ar  Mon Aug 30 17:41:36 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 30 Aug 2021 21:41:36 -0300
Subject: [PATCH v1 1/5] phy: phy-rockchip-dphy-rx0: refactor for tx1rx1
 addition
In-Reply-To: <6474995.6kXVAnRFRJ@diego>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-2-mike.rudenko@gmail.com> <6474995.6kXVAnRFRJ@diego>
Message-ID: <CAAEAJfB6FBbeEPuzirP2nuU_J9nLFSrczgXYVfNQUZbEJrbc7Q@mail.gmail.com>

Hi Heiko,

On Mon, 30 Aug 2021 at 17:46, Heiko St?bner <heiko at sntech.de> wrote:
>
> Hi Mikhail,
>
> Am Montag, 30. August 2021, 20:07:50 CEST schrieb Mikhail Rudenko:
> > In order to accommodate for rk3399 tx1rx1 addition, make
> > enable/disable function calls indirect via function pointers in
> > rk_dphy_drv_data. Also rename rk_dphy_write and rk_dphy_enable to
> > avoid naming clashes.
>
> You're a bit too late to the party :-( .
>
> The tx1rx1 dphy is living _inside_ the 2nd DSI controller and is
> configured through it.
>

Would you be so kind to push a patch adding some comments to
drivers/phy/rockchip/phy-rockchip-dphy-rx0.c with this information?

Thanks,
Ezequiel


From mike.rudenko at gmail.com  Tue Aug 31 05:58:30 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Tue, 31 Aug 2021 15:58:30 +0300
Subject: [PATCH v1 0/5] phy: phy-rockchip-dphy-rx0: add support for
 tx1rx1 rx mode
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <87sfyp4u5b.fsf@gmail.com>

Hi all,

thank you for reviewing this and sorry for me failing my prior research
and overlooking existing Heiko's solution [1] [2].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=71f68fe7f12182ed968cfbbd1ef018721e4dee30
[2] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=68e0277204c733dff19073686e2ac48239b06fbc

--
Regards,
Mikhail


From narmstrong at baylibre.com  Tue Aug 31 07:50:04 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 31 Aug 2021 16:50:04 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
 <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
 <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>
Message-ID: <2b07b3de-cee5-c570-8fde-6a4c684122d6@baylibre.com>

Hi,

On 30/08/2021 21:37, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Mon, Aug 30, 2021 at 9:45 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> Hi,
>>
>> On 17/08/2021 06:15, Anand Moon wrote:
>>> Add missing usb phy power node for usb node fix below warning.
>>> P5V0 regulator supply input voltage range to USB host controller.
>>> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
>>> enable input power to USB ports, set it to Active Low.
>>>
>>> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
>>> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
>>>               mode /soc/usb at c90c0000 failed
>>
>> First of all, DT is not here to fix boot message.
> Anand mentioned elsewhere that this is a debug/info message
> 
>> Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
>> to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
>> should not be added at all.
> I think there's a misunderstanding because there's two PWREN signals
> with different meanings.
> The PWREN signal for the USB host ports is hard-wired and not
> connected to the SoC at all.
> The PWREN signal for the Micro-USB port (which Anand is adding here)
> is controlled by GPIOAO_5. odroid-c1+_rev0.4_20150615.pdf [0] shows it
> as an input to "USB_OTG" on page 1. "USB_OTG" consists of a power
> switch and the connector itself as shown on page 28.
> 
> Personally I think that the change from Anand itself is good.
> If you feel otherwise then please speak up.

Ok thanks for the clarification, then the change is ok, but not the commit message.

>> Add missing usb phy power node for usb node fix below warning.

is not a good reason for a DT change. A proper reason should be added.

And the commit message doesn't specify the change is for the Micro-USB port,
this should be clarified.

Neil

> As I pointed out three smaller changes I am hoping that Anand will
> re-send the updated patch anyways. At that point he can also add the
> changes from your feedback.
> 
> 
> Best regards,
> Martin
> 
> 
> [0] https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20150615.pdf
> 



From linux.amoon at gmail.com  Tue Aug 31 13:47:54 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Wed, 1 Sep 2021 02:17:54 +0530
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <2b07b3de-cee5-c570-8fde-6a4c684122d6@baylibre.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
 <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
 <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>
 <2b07b3de-cee5-c570-8fde-6a4c684122d6@baylibre.com>
Message-ID: <CANAwSgRNp8UtU+Yy4smwZ5POTWTU+xN1mrf_cH7Pu9yX5HU=VA@mail.gmail.com>

Hi Neil / Martin,

Thanks for your review comments.

On Tue, 31 Aug 2021 at 20:20, Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 30/08/2021 21:37, Martin Blumenstingl wrote:
> > Hi Neil,
> >
> > On Mon, Aug 30, 2021 at 9:45 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
> >>
> >> Hi,
> >>
> >> On 17/08/2021 06:15, Anand Moon wrote:
> >>> Add missing usb phy power node for usb node fix below warning.
> >>> P5V0 regulator supply input voltage range to USB host controller.
> >>> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> >>> enable input power to USB ports, set it to Active Low.
> >>>
> >>> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> >>> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
> >>>               mode /soc/usb at c90c0000 failed
> >>
> >> First of all, DT is not here to fix boot message.
> > Anand mentioned elsewhere that this is a debug/info message
> >
> >> Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
> >> to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
> >> should not be added at all.
> > I think there's a misunderstanding because there's two PWREN signals
> > with different meanings.
> > The PWREN signal for the USB host ports is hard-wired and not
> > connected to the SoC at all.
> > The PWREN signal for the Micro-USB port (which Anand is adding here)
> > is controlled by GPIOAO_5. odroid-c1+_rev0.4_20150615.pdf [0] shows it
> > as an input to "USB_OTG" on page 1. "USB_OTG" consists of a power
> > switch and the connector itself as shown on page 28.
> >
> > Personally I think that the change from Anand itself is good.
> > If you feel otherwise then please speak up.
>
> Ok thanks for the clarification, then the change is ok, but not the commit message.
>
> >> Add missing usb phy power node for usb node fix below warning.
>
> is not a good reason for a DT change. A proper reason should be added.
>
> And the commit message doesn't specify the change is for the Micro-USB port,
> this should be clarified.
>
> Neil
>
> > As I pointed out three smaller changes I am hoping that Anand will
> > re-send the updated patch anyways. At that point he can also add the
> > changes from your feedback.
> >
Ok I will try to address your feedback in the next version.

After enabling CONFIG_REGULATOR_DEBUG, with this patch applied
I still not getting the USB regulator to enable.
Do you see different output at your end?

On Odroid C1+
[    5.737571] reg-fixed-voltage regulator-usb-pwr-en: GPIO lookup for
consumer (null)
[    5.737630] reg-fixed-voltage regulator-usb-pwr-en: using device
tree for GPIO lookup
[    5.737711] of_get_named_gpiod_flags: can't parse 'gpios' property
of node '/regulator-usb-pwr-en[0]'
[    5.737906] of_get_named_gpiod_flags: parsed 'gpio' property of
node '/regulator-usb-pwr-en[0]' - status (0)
[    5.738209] gpio_stub_drv gpiochip0: Persistence not supported for GPIO 5
[    5.738490] USB_OTG_PWR: 5000 mV, disabled
[    5.740313] reg-fixed-voltage regulator-usb-pwr-en: Looking up
vin-supply from device tree
[    5.740394] USB_OTG_PWR: supplied by P5V0
[    5.741235] reg-fixed-voltage regulator-usb-pwr-en: USB_OTG_PWR
supplying 5000000uV

Odroid N2.
[    3.047813] reg-fixed-voltage regulator-hub_5v: HUB_5V supplying 5000000uV
[    3.049282] reg-fixed-voltage regulator-usb_pwr_en: GPIO lookup for
consumer (null)
[    3.049305] reg-fixed-voltage regulator-usb_pwr_en: using device
tree for GPIO lookup
[    3.049370] of_get_named_gpiod_flags: can't parse 'gpios' property
of node '/regulator-usb_pwr_en[0]'
[    3.049500] of_get_named_gpiod_flags: parsed 'gpio' property of
node '/regulator-usb_pwr_en[0]' - status (0)
[    3.049622] gpio_stub_drv gpiochip0: Persistence not supported for GPIO 22
[    3.049759] USB_PWR_EN: 5000 mV, disabled
[    3.051257] reg-fixed-voltage regulator-usb_pwr_en: Looking up
vin-supply from device tree
[    3.051320] USB_PWR_EN: supplied by 5V

Thanks
-Anand



> >
> > Best regards,
> > Martin
> >
> >
> > [0] https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20150615.pdf
> >
>


From robh at kernel.org  Tue Aug 31 14:33:32 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:33:32 -0500
Subject: [PATCH 1/2] dt-bindings: phy: rockchip: remove usb-phy fallback
 string for rk3066a/rk3188
In-Reply-To: <20210828111218.10026-1-jbx6244@gmail.com>
References: <20210828111218.10026-1-jbx6244@gmail.com>
Message-ID: <YS6gLG+M4dP+rkl6@robh.at.kernel.org>

On Sat, 28 Aug 2021 13:12:17 +0200, Johan Jonker wrote:
> With the conversion of rockchip-usb-phy.yaml a long time used fallback
> string for rk3066a/rk3188 was added. The linux driver doesn't do much with
> the GRF phy address range, however the u-boot driver rockchip_usb2_phy.c
> does. The bits in GRF_UOC0_CON2 for rk3066a/rk3188 and rk3288 for example
> don't match. Remove the usb-phy fallback string for rk3066a/rk3188
> to prevent possible strange side effects.
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
>  .../devicetree/bindings/phy/rockchip-usb-phy.yaml     | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 

Acked-by: Rob Herring <robh at kernel.org>


