[PATCH v4 0/8] add the imx8m pcie phy driver and imx8mm pcie support

STALE1773d

Revision v4 of 6 in this series.

20 messages, 3 authors, 2021-11-02 · open the first message on its own page

[PATCH v4 0/8] add the imx8m pcie phy driver and imx8mm pcie support

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:01

Refer to the discussion [1] when try to enable i.MX8MM PCIe support,
one standalone PCIe PHY driver should be seperated from i.MX PCIe
driver when enable i.MX8MM PCIe support.

This patch-set adds the standalone PCIe PHY driver suport[1-5], and i.MX8MM
PCIe support[6-8] to have whole view to review this patch-set.

The PCIe works on i.MX8MM EVK board based the the blkctrl power driver
[2] and this patch-set.

[1] https://patchwork.ozlabs.org/project/linux-pci/patch/20210510141509.929120-3-l.stach@pengutronix.de/
[2] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20210910202640.980366-1-l.stach@pengutronix.de/

Main changes v3 --> v4:
- Update the yaml to fix syntax error, add maxitems and drop description of phy
- Correct the clock name in PHY DT node.
- Squash the EVK board relalted dts changes into one patch, and drop the
  useless dummy clock and gpio suffix in DT nodes.
- Add board specific de-emphasis parameters as DT properties. Thus each board
  can specify its actual de-emphasis values.
- Update the commit log of PHY driver.
- Remove the useless codes from PCIe driver, since they are moved to PHY driver
- After the discussion and verification of the CLKREQ# configurations with Tim,
  agree to add an optional boolean property "fsl,clkreq-unsupported", indicates
  the CLKREQ# signal is hooked or not in HW designs.
- Add "Tested-by: Marcel Ziswiler [off-list ref]" tag, since
  Marcel help to test the v3 patch-set.

Main changes v2 --> v3:
- Regarding Lucas' comments.
 - to have a whole view to review the patches, send out the i.MX8MM PCIe support too.
 - move the PHY related bits manipulations of the GPR/SRC to standalone PHY driver.
 - split the dts changes to SOC and board DT, and use the enum instead of raw value.
 - update the license of the dt-binding header file.

Changes v1 --> v2:
- Update the license of the dt-binding header file to make the license
  compatible with dts files.
- Fix the dt_binding_check errors.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml    |   6 +++
Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml |  95 +++++++++++++++++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi                |  55 +++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8mm.dtsi                    |  46 +++++++++++++++-
drivers/pci/controller/dwc/pci-imx6.c                        |  73 ++++++++++++++++++++++---
drivers/phy/freescale/Kconfig                                |   9 ++++
drivers/phy/freescale/Makefile                               |   1 +
drivers/phy/freescale/phy-fsl-imx8m-pcie.c                   | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/dt-bindings/phy/phy-imx8-pcie.h                      |  14 +++++
9 files changed, 525 insertions(+), 8 deletions(-)

[PATCH v4 1/8] dt-bindings: phy: phy-imx8-pcie: Add binding for the
[PATCH v4 2/8] dt-bindings: phy: Add imx8 pcie phy driver support
[PATCH v4 3/8] dt-bindings: imx6q-pcie: Add PHY phandles and name
[PATCH v4 4/8] arm64: dts: imx8mm: Add the pcie phy support
[PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
[PATCH v4 6/8] arm64: dts: imx8mm: Add the pcie support
[PATCH v4 7/8] arm64: dts: imx8mm-evk: Add the pcie support on imx8mm
[PATCH v4 8/8] PCI: imx: Add the imx8mm pcie support

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 1/8] dt-bindings: phy: phy-imx8-pcie: Add binding for the pad modes of imx8 pcie phy

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:04

Add binding for reference clock PAD modes of the i.MX8 PCIe PHY.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 include/dt-bindings/phy/phy-imx8-pcie.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 include/dt-bindings/phy/phy-imx8-pcie.h
diff --git a/include/dt-bindings/phy/phy-imx8-pcie.h b/include/dt-bindings/phy/phy-imx8-pcie.h
new file mode 100644
index 000000000000..8bbe2d6538d8
--- /dev/null
+++ b/include/dt-bindings/phy/phy-imx8-pcie.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * This header provides constants for i.MX8 PCIe.
+ */
+
+#ifndef _DT_BINDINGS_IMX8_PCIE_H
+#define _DT_BINDINGS_IMX8_PCIE_H
+
+/* Reference clock PAD mode */
+#define IMX8_PCIE_REFCLK_PAD_UNUSED	0
+#define IMX8_PCIE_REFCLK_PAD_INPUT	1
+#define IMX8_PCIE_REFCLK_PAD_OUTPUT	2
+
+#endif /* _DT_BINDINGS_IMX8_PCIE_H */
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 2/8] dt-bindings: phy: Add imx8 pcie phy driver support

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:07

Add dt-binding for the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 .../bindings/phy/fsl,imx8-pcie-phy.yaml       | 95 +++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml
new file mode 100644
index 000000000000..b9f89e343b0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8-pcie-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8 SoC series PCIe PHY Device Tree Bindings
+
+maintainers:
+  - Richard Zhu <hongxing.zhu@nxp.com>
+
+properties:
+  "#phy-cells":
+    const: 0
+
+  compatible:
+    enum:
+      - fsl,imx8mm-pcie-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY module clock
+
+  clock-names:
+    items:
+      - const: ref
+
+  resets:
+    items:
+      - description: Phandles to PCIe-related reset lines exposed by SRC
+          IP block.
+
+  reset-names:
+    items:
+      - const: pciephy
+
+  fsl,refclk-pad-mode:
+    description: |
+      Specifies the mode of the refclk pad used. It can be UNUSED(PHY
+      refclock is derived from SoC internal source), INPUT(PHY refclock
+      is provided externally via the refclk pad) or OUTPUT(PHY refclock
+      is derived from SoC internal source and provided on the refclk pad).
+      Refer include/dt-bindings/phy/phy-imx8-pcie.h for the constants
+      to be used.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [ 0, 1, 2 ]
+
+  fsl,tx-deemph-gen1:
+    description: Gen1 De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2:
+    description: Gen2 De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,clkreq-unsupported:
+    type: boolean
+    description: A boolean property indicating the CLKREQ# signal is
+      not supported in the board design (optional)
+
+required:
+  - "#phy-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - fsl,refclk-pad-mode
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mm-clock.h>
+    #include <dt-bindings/phy/phy-imx8-pcie.h>
+    #include <dt-bindings/reset/imx8mq-reset.h>
+
+    pcie_phy: pcie-phy@32f00000 {
+            compatible = "fsl,imx8mm-pcie-phy";
+            reg = <0x32f00000 0x10000>;
+            clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+            clock-names = "ref";
+            assigned-clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+            assigned-clock-rates = <100000000>;
+            assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_100M>;
+            resets = <&src IMX8MQ_RESET_PCIEPHY>;
+            reset-names = "pciephy";
+            fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+            #phy-cells = <0>;
+    };
+...
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 3/8] dt-bindings: imx6q-pcie: Add PHY phandles and name properties

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:12

i.MX8MM PCIe has the PHY. Add a PHY phandle and name properties
in the binding document.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 2911e565b260..46b5446f5791 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -128,6 +128,12 @@ properties:
     enum: [1, 2, 3, 4]
     default: 1
 
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: pcie-phy
+
   reset-gpio:
     description: Should specify the GPIO for controlling the PCI bus device
       reset signal. It's not polarity aware and defaults to active-low reset
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 4/8] arm64: dts: imx8mm: Add the pcie phy support

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:18

Add the PCIe PHY support on iMX8MM platforms.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index c2f3f118f82e..0844f3144887 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -1135,6 +1135,19 @@ usbmisc2: usbmisc@32e50200 {
 				reg = <0x32e50200 0x200>;
 			};
 
+			pcie_phy: pcie-phy@32f00000 {
+				compatible = "fsl,imx8mm-pcie-phy";
+				reg = <0x32f00000 0x10000>;
+				clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+				clock-names = "ref";
+				assigned-clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+				assigned-clock-rates = <100000000>;
+				assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_100M>;
+				resets = <&src IMX8MQ_RESET_PCIEPHY>;
+				reset-names = "pciephy";
+				#phy-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		dma_apbh: dma-controller@33000000 {
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:21

Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234 +++++++++++++++++++++
 3 files changed, 244 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 320630ffe3cd..de9ee7020f76 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
 	help
 	  Enable this to add support for the Mixel DSI PHY as found
 	  on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+	tristate "Freescale i.MX8 PCIE PHY"
+	depends on OF && HAS_IOMEM
+	select GENERIC_PHY
+	default ARCH_MXC && ARM64
+	help
+	  Enable this to add support for the PCIE PHY as found on
+	  i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 1d02e3869b45..55d07c742ab0 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)	+= phy-fsl-imx8m-pcie.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061	0x184
+#define  ANA_PLL_CLK_OUT_TO_EXT_IO_EN	BIT(0)
+#define IMX8MM_PCIE_PHY_CMN_REG062	0x188
+#define  ANA_PLL_CLK_OUT_TO_EXT_IO_SEL	BIT(3)
+#define IMX8MM_PCIE_PHY_CMN_REG063	0x18C
+#define  AUX_PLL_REFCLK_SEL_SYS_PLL	GENMASK(7, 6)
+#define IMX8MM_PCIE_PHY_CMN_REG064	0x190
+#define  ANA_AUX_RX_TX_SEL_TX		BIT(7)
+#define  ANA_AUX_RX_TERM_GND_EN		BIT(3)
+#define  ANA_AUX_TX_TERM		BIT(2)
+#define IMX8MM_PCIE_PHY_CMN_REG065	0x194
+#define  ANA_AUX_RX_TERM		(BIT(7) | BIT(4))
+#define  ANA_AUX_TX_LVL			GENMASK(3, 0)
+#define IMX8MM_PCIE_PHY_CMN_REG75	0x1D4
+#define  PCIE_PHY_CMN_REG75_PLL_DONE	0x3
+#define PCIE_PHY_TRSV_REG5		0x414
+#define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP	0x2D
+#define PCIE_PHY_TRSV_REG6		0x418
+#define  PCIE_PHY_TRSV_REG6_GEN2_DEEMP	0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL	GENMASK(25, 24)
+#define IMX8MM_GPR_PCIE_REF_CLK_PLL	FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3)
+#define IMX8MM_GPR_PCIE_REF_CLK_EXT	FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2)
+#define IMX8MM_GPR_PCIE_AUX_EN		BIT(19)
+#define IMX8MM_GPR_PCIE_CMN_RST		BIT(18)
+#define IMX8MM_GPR_PCIE_POWER_OFF	BIT(17)
+#define IMX8MM_GPR_PCIE_SSC_EN		BIT(16)
+#define IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE	BIT(9)
+
+struct imx8_pcie_phy {
+	void __iomem		*base;
+	struct clk		*clk;
+	struct phy		*phy;
+	struct regmap		*iomuxc_gpr;
+	struct reset_control	*reset;
+	u32			refclk_pad_mode;
+	u32			tx_deemph_gen1;
+	u32			tx_deemph_gen2;
+	bool			clkreq_unused;
+};
+
+static int imx8_pcie_phy_init(struct phy *phy)
+{
+	int ret;
+	u32 val, pad_mode;
+	struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+	reset_control_assert(imx8_phy->reset);
+
+	pad_mode = imx8_phy->refclk_pad_mode;
+	/* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */
+	regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+			   IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE,
+			   imx8_phy->clkreq_unused ?
+			   0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
+	regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+			   IMX8MM_GPR_PCIE_AUX_EN,
+			   pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
+			   IMX8MM_GPR_PCIE_AUX_EN : 0);
+	regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+			   IMX8MM_GPR_PCIE_POWER_OFF, 0);
+	regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+			   IMX8MM_GPR_PCIE_SSC_EN, 0);
+
+	regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+			   IMX8MM_GPR_PCIE_REF_CLK_SEL,
+			   pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
+			   IMX8MM_GPR_PCIE_REF_CLK_EXT :
+			   IMX8MM_GPR_PCIE_REF_CLK_PLL);
+	usleep_range(100, 200);
+
+	/* Do the PHY common block reset */
+	regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+			   IMX8MM_GPR_PCIE_CMN_RST,
+			   IMX8MM_GPR_PCIE_CMN_RST);
+	usleep_range(200, 500);
+
+
+	if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT) {
+		/* Configure the pad as input */
+		val = readl(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG061);
+		writel(val & ~ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
+		       imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG061);
+	} else if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT) {
+		/* Configure the PHY to output the refclock via pad */
+		writel(ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
+		       imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG061);
+		writel(ANA_PLL_CLK_OUT_TO_EXT_IO_SEL,
+		       imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG062);
+		writel(AUX_PLL_REFCLK_SEL_SYS_PLL,
+		       imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG063);
+		val = ANA_AUX_RX_TX_SEL_TX | ANA_AUX_TX_TERM;
+		writel(val | ANA_AUX_RX_TERM_GND_EN,
+		       imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG064);
+		writel(ANA_AUX_RX_TERM | ANA_AUX_TX_LVL,
+		       imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG065);
+	}
+
+	/* Tune PHY de-emphasis setting to pass PCIe compliance. */
+	writel(imx8_phy->tx_deemph_gen1, imx8_phy->base + PCIE_PHY_TRSV_REG5);
+	writel(imx8_phy->tx_deemph_gen2, imx8_phy->base + PCIE_PHY_TRSV_REG6);
+
+	reset_control_deassert(imx8_phy->reset);
+
+	/* Polling to check the phy is ready or not. */
+	ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG75,
+				 val, val == PCIE_PHY_CMN_REG75_PLL_DONE,
+				 10, 20000);
+	return ret;
+}
+
+static int imx8_pcie_phy_power_on(struct phy *phy)
+{
+	struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+	return clk_prepare_enable(imx8_phy->clk);
+}
+
+static int imx8_pcie_phy_power_off(struct phy *phy)
+{
+	struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(imx8_phy->clk);
+
+	return 0;
+}
+
+static const struct phy_ops imx8_pcie_phy_ops = {
+	.init		= imx8_pcie_phy_init,
+	.power_on	= imx8_pcie_phy_power_on,
+	.power_off	= imx8_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int imx8_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct imx8_pcie_phy *imx8_phy;
+	struct resource *res;
+
+	imx8_phy = devm_kzalloc(dev, sizeof(*imx8_phy), GFP_KERNEL);
+	if (!imx8_phy)
+		return -ENOMEM;
+
+	/* get PHY refclk pad mode */
+	of_property_read_u32(np, "fsl,refclk-pad-mode",
+			     &imx8_phy->refclk_pad_mode);
+
+	if (of_property_read_u32(np, "fsl,tx-deemph-gen1",
+				 &imx8_phy->tx_deemph_gen1))
+		imx8_phy->tx_deemph_gen1 = 0;
+
+	if (of_property_read_u32(np, "fsl,tx-deemph-gen2",
+				 &imx8_phy->tx_deemph_gen2))
+		imx8_phy->tx_deemph_gen2 = 0;
+
+	if (of_property_read_bool(np, "fsl,clkreq-unsupported"))
+		imx8_phy->clkreq_unused = true;
+	else
+		imx8_phy->clkreq_unused = false;
+
+	imx8_phy->clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(imx8_phy->clk)) {
+		dev_err(dev, "failed to get imx pcie phy clock\n");
+		return PTR_ERR(imx8_phy->clk);
+	}
+
+	/* Grab GPR config register range */
+	imx8_phy->iomuxc_gpr =
+		 syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+	if (IS_ERR(imx8_phy->iomuxc_gpr)) {
+		dev_err(dev, "unable to find iomuxc registers\n");
+		return PTR_ERR(imx8_phy->iomuxc_gpr);
+	}
+
+	imx8_phy->reset = devm_reset_control_get_exclusive(dev, "pciephy");
+	if (IS_ERR(imx8_phy->reset)) {
+		dev_err(dev, "Failed to get PCIEPHY reset control\n");
+		return PTR_ERR(imx8_phy->reset);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	imx8_phy->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(imx8_phy->base))
+		return PTR_ERR(imx8_phy->base);
+
+	imx8_phy->phy = devm_phy_create(dev, NULL, &imx8_pcie_phy_ops);
+	if (IS_ERR(imx8_phy->phy))
+		return PTR_ERR(imx8_phy->phy);
+
+	phy_set_drvdata(imx8_phy->phy, imx8_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 imx8_pcie_phy_of_match[] = {
+	{.compatible = "fsl,imx8mm-pcie-phy",},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
+
+static struct platform_driver imx8_pcie_phy_driver = {
+	.probe	= imx8_pcie_phy_probe,
+	.driver = {
+		.name	= "imx8-pcie-phy",
+		.of_match_table	= imx8_pcie_phy_of_match,
+	}
+};
+module_platform_driver(imx8_pcie_phy_driver);
+
+MODULE_DESCRIPTION("FSL IMX8 PCIE PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 6/8] arm64: dts: imx8mm: Add the pcie support

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:25

Add the PCIe support on i.MX8MM platforms.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 33 ++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 0844f3144887..75f4317215ac 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -520,7 +520,7 @@ iomuxc: pinctrl@30330000 {
 			};
 
 			gpr: iomuxc-gpr@30340000 {
-				compatible = "fsl,imx8mm-iomuxc-gpr", "syscon";
+				compatible = "fsl,imx8mm-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", "syscon";
 				reg = <0x30340000 0x10000>;
 			};
 
@@ -1179,6 +1179,37 @@ gpmi: nand-controller@33002000{
 			status = "disabled";
 		};
 
+		pcie0: pcie@33800000 {
+			compatible = "fsl,imx8mm-pcie";
+			reg = <0x33800000 0x400000>, <0x1ff00000 0x80000>;
+			reg-names = "dbi", "config";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			bus-range = <0x00 0xff>;
+			ranges =  <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
+				   0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
+			num-lanes = <1>;
+			num-viewport = <4>;
+			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &gic GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			fsl,max-link-speed = <2>;
+			linux,pci-domain = <0>;
+			power-domains = <&pgc_pcie>;
+			resets = <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>,
+				 <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>;
+			reset-names = "apps", "turnoff";
+			phys = <&pcie_phy>;
+			phy-names = "pcie-phy";
+			status = "disabled";
+		};
+
 		gpu_3d: gpu@38000000 {
 			compatible = "vivante,gc";
 			reg = <0x38000000 0x8000>;
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 7/8] arm64: dts: imx8mm-evk: Add the pcie support on imx8mm evk board

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:27

Add the PCIe support on iMX8MM EVK boards.
And set the default reference clock mode.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index e033d0257b5a..fc1803a8af5b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/phy/phy-imx8-pcie.h>
 #include <dt-bindings/usb/pd.h>
 #include "imx8mm.dtsi"
 
@@ -30,6 +31,23 @@ status {
 		};
 	};
 
+	pcie0_refclk: pcie0-refclk {
+		compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <100000000>;
+	};
+
+	reg_pcie0: regulator-pcie {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pcie0_reg>;
+		regulator-name = "MPCIE_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
 	reg_usdhc2_vmmc: regulator-usdhc2 {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -289,6 +307,30 @@ pca6416: gpio@20 {
 	};
 };
 
+&pcie_phy {
+	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+	fsl,tx-deemph-gen1 = <0x2D>;
+	fsl,tx-deemph-gen2 = <0xF>;
+	clocks = <&pcie0_refclk>;
+	status = "okay";
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie0>;
+	reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+		 <&pcie0_refclk>;
+	clock-names = "pcie", "pcie_aux", "pcie_bus";
+	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+			  <&clk IMX8MM_CLK_PCIE1_CTRL>;
+	assigned-clock-rates = <10000000>, <250000000>;
+	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+				 <&clk IMX8MM_SYS_PLL2_250M>;
+	vpcie-supply = <&reg_pcie0>;
+	status = "okay";
+};
+
 &sai3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sai3>;
@@ -406,6 +448,19 @@ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA			0x400001c3
 		>;
 	};
 
+	pinctrl_pcie0: pcie0grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B    0x61
+			MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21       0x41
+		>;
+	};
+
+	pinctrl_pcie0_reg: pcie0reggrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5       0x41
+		>;
+	};
+
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x141
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v4 8/8] PCI: imx: Add the imx8mm pcie support

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-28 07:53:32

i.MX8MM PCIe works mostly like the i.MX8MQ one, but has a different PHY
and allows to output the internal PHY reference clock via the refclk pad.
Add the i.MX8MM PCIe support based on the standalone PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 drivers/pci/controller/dwc/pci-imx6.c | 73 ++++++++++++++++++++++++---
 1 file changed, 66 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 26f49f797b0f..d8c587b4d54f 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/reset.h>
+#include <linux/phy/phy.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
@@ -49,6 +50,7 @@ enum imx6_pcie_variants {
 	IMX6QP,
 	IMX7D,
 	IMX8MQ,
+	IMX8MM,
 };
 
 #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
@@ -88,6 +90,7 @@ struct imx6_pcie {
 	struct device		*pd_pcie;
 	/* power domain for pcie phy */
 	struct device		*pd_pcie_phy;
+	struct phy		*phy;
 	const struct imx6_pcie_drvdata *drvdata;
 };
 
@@ -372,6 +375,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 	case IMX7D:
 	case IMX8MQ:
 		reset_control_assert(imx6_pcie->pciephy_reset);
+		fallthrough;
+	case IMX8MM:
 		reset_control_assert(imx6_pcie->apps_reset);
 		break;
 	case IMX6SX:
@@ -407,7 +412,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 
 static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
 {
-	WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ);
+	WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ &&
+		imx6_pcie->drvdata->variant != IMX8MM);
 	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
 }
 
@@ -446,6 +452,13 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 		break;
 	case IMX7D:
 		break;
+	case IMX8MM:
+		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
+		if (ret) {
+			dev_err(dev, "unable to enable pcie_aux clock\n");
+			break;
+		}
+		break;
 	case IMX8MQ:
 		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
 		if (ret) {
@@ -522,6 +535,14 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 		goto err_ref_clk;
 	}
 
+	switch (imx6_pcie->drvdata->variant) {
+	case IMX8MM:
+		if (phy_power_on(imx6_pcie->phy))
+			dev_err(dev, "unable to power on PHY\n");
+		break;
+	default:
+		break;
+	}
 	/* allow the clocks to stabilize */
 	usleep_range(200, 500);
 
@@ -538,6 +559,10 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	case IMX8MQ:
 		reset_control_deassert(imx6_pcie->pciephy_reset);
 		break;
+	case IMX8MM:
+		if (phy_init(imx6_pcie->phy) != 0)
+			dev_err(dev, "Waiting for PHY ready timeout!\n");
+		break;
 	case IMX7D:
 		reset_control_deassert(imx6_pcie->pciephy_reset);
 
@@ -614,6 +639,8 @@ static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
 {
 	switch (imx6_pcie->drvdata->variant) {
+	case IMX8MM:
+		break;
 	case IMX8MQ:
 		/*
 		 * TODO: Currently this code assumes external
@@ -753,6 +780,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
 		break;
 	case IMX7D:
 	case IMX8MQ:
+	case IMX8MM:
 		reset_control_deassert(imx6_pcie->apps_reset);
 		break;
 	}
@@ -871,6 +899,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
 				   IMX6Q_GPR12_PCIE_CTL_2, 0);
 		break;
 	case IMX7D:
+	case IMX8MM:
 		reset_control_assert(imx6_pcie->apps_reset);
 		break;
 	default:
@@ -930,6 +959,7 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
 				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
 		break;
 	case IMX8MQ:
+	case IMX8MM:
 		clk_disable_unprepare(imx6_pcie->pcie_aux);
 		break;
 	default:
@@ -1043,11 +1073,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	}
 
 	/* Fetch clocks */
-	imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
-	if (IS_ERR(imx6_pcie->pcie_phy))
-		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy),
-				     "pcie_phy clock source missing or invalid\n");
-
 	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
 	if (IS_ERR(imx6_pcie->pcie_bus))
 		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus),
@@ -1089,10 +1114,39 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 			dev_err(dev, "Failed to get PCIE APPS reset control\n");
 			return PTR_ERR(imx6_pcie->apps_reset);
 		}
+		break;
+	case IMX8MM:
+		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
+		if (IS_ERR(imx6_pcie->pcie_aux))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
+					     "pcie_aux clock source missing or invalid\n");
+		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
+									 "apps");
+		if (IS_ERR(imx6_pcie->apps_reset)) {
+			dev_err(dev, "Failed to get PCIE APPS reset control\n");
+			return PTR_ERR(imx6_pcie->apps_reset);
+		}
+
+		imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
+		if (IS_ERR(imx6_pcie->phy)) {
+			if (PTR_ERR(imx6_pcie->phy) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;
+			dev_err(dev, "Failed to get PCIE PHY\n");
+			return PTR_ERR(imx6_pcie->phy);
+		}
+
 		break;
 	default:
 		break;
 	}
+	/* Don't fetch the pcie_phy clock, if it has abstract PHY driver */
+	if (imx6_pcie->phy == NULL) {
+		imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
+		if (IS_ERR(imx6_pcie->pcie_phy))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy),
+					     "pcie_phy clock source missing or invalid\n");
+	}
+
 
 	/* Grab turnoff reset */
 	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
@@ -1202,6 +1256,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
 	},
+	[IMX8MM] = {
+		.variant = IMX8MM,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+	},
 };
 
 static const struct of_device_id imx6_pcie_of_match[] = {
@@ -1209,7 +1267,8 @@ static const struct of_device_id imx6_pcie_of_match[] = {
 	{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
 	{ .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
 	{ .compatible = "fsl,imx7d-pcie",  .data = &drvdata[IMX7D],  },
-	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], } ,
+	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
+	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
 	{},
 };
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v4 0/8] add the imx8m pcie phy driver and imx8mm pcie support

From: Tim Harvey <tharvey@gateworks.com>
Date: 2021-10-28 18:17:28

On Thu, Oct 28, 2021 at 12:52 AM Richard Zhu [off-list ref] wrote:
Refer to the discussion [1] when try to enable i.MX8MM PCIe support,
one standalone PCIe PHY driver should be seperated from i.MX PCIe
driver when enable i.MX8MM PCIe support.

This patch-set adds the standalone PCIe PHY driver suport[1-5], and i.MX8MM
PCIe support[6-8] to have whole view to review this patch-set.

The PCIe works on i.MX8MM EVK board based the the blkctrl power driver
[2] and this patch-set.

[1] https://patchwork.ozlabs.org/project/linux-pci/patch/20210510141509.929120-3-l.stach@pengutronix.de/
[2] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20210910202640.980366-1-l.stach@pengutronix.de/

Main changes v3 --> v4:
- Update the yaml to fix syntax error, add maxitems and drop description of phy
- Correct the clock name in PHY DT node.
- Squash the EVK board relalted dts changes into one patch, and drop the
  useless dummy clock and gpio suffix in DT nodes.
- Add board specific de-emphasis parameters as DT properties. Thus each board
  can specify its actual de-emphasis values.
- Update the commit log of PHY driver.
- Remove the useless codes from PCIe driver, since they are moved to PHY driver
- After the discussion and verification of the CLKREQ# configurations with Tim,
  agree to add an optional boolean property "fsl,clkreq-unsupported", indicates
  the CLKREQ# signal is hooked or not in HW designs.
- Add "Tested-by: Marcel Ziswiler [off-list ref]" tag, since
  Marcel help to test the v3 patch-set.

Main changes v2 --> v3:
- Regarding Lucas' comments.
 - to have a whole view to review the patches, send out the i.MX8MM PCIe support too.
 - move the PHY related bits manipulations of the GPR/SRC to standalone PHY driver.
 - split the dts changes to SOC and board DT, and use the enum instead of raw value.
 - update the license of the dt-binding header file.

Changes v1 --> v2:
- Update the license of the dt-binding header file to make the license
  compatible with dts files.
- Fix the dt_binding_check errors.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml    |   6 +++
Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml |  95 +++++++++++++++++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi                |  55 +++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8mm.dtsi                    |  46 +++++++++++++++-
drivers/pci/controller/dwc/pci-imx6.c                        |  73 ++++++++++++++++++++++---
drivers/phy/freescale/Kconfig                                |   9 ++++
drivers/phy/freescale/Makefile                               |   1 +
drivers/phy/freescale/phy-fsl-imx8m-pcie.c                   | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/dt-bindings/phy/phy-imx8-pcie.h                      |  14 +++++
9 files changed, 525 insertions(+), 8 deletions(-)

[PATCH v4 1/8] dt-bindings: phy: phy-imx8-pcie: Add binding for the
[PATCH v4 2/8] dt-bindings: phy: Add imx8 pcie phy driver support
[PATCH v4 3/8] dt-bindings: imx6q-pcie: Add PHY phandles and name
[PATCH v4 4/8] arm64: dts: imx8mm: Add the pcie phy support
[PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
[PATCH v4 6/8] arm64: dts: imx8mm: Add the pcie support
[PATCH v4 7/8] arm64: dts: imx8mm-evk: Add the pcie support on imx8mm
[PATCH v4 8/8] PCI: imx: Add the imx8mm pcie support
Richard,

For your v4 series:

Reviewed-By: Tim Harvey <tharvey@gateworks.com>
Tested-By: Tim Harvey <tharvey@gateworks.com>

I tested this on imx8mm-venice* boards with no CLKREQ# support as well
as an imx8mm-evk board.

Thanks again for your effort on this series!

Best regards,

Tim

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

RE: [PATCH v4 0/8] add the imx8m pcie phy driver and imx8mm pcie support

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-29 01:11:57

-----Original Message-----
From: Tim Harvey <tharvey@gateworks.com>
Sent: Friday, October 29, 2021 2:17 AM
To: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>; Marcel Ziswiler
[off-list ref]; Kishon Vijay Abraham I
[off-list ref]; vkoul@kernel.org; Rob Herring [off-list ref];
galak@kernel.crashing.org; Shawn Guo [off-list ref];
linux-phy@lists.infradead.org; Device Tree Mailing List
[off-list ref]; Linux ARM Mailing List
[off-list ref]; open list
[off-list ref]; Sascha Hauer [off-list ref];
dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 0/8] add the imx8m pcie phy driver and imx8mm
pcie support

On Thu, Oct 28, 2021 at 12:52 AM Richard Zhu [off-list ref]
wrote:
quoted
Refer to the discussion [1] when try to enable i.MX8MM PCIe support,
one standalone PCIe PHY driver should be seperated from i.MX PCIe
driver when enable i.MX8MM PCIe support.

This patch-set adds the standalone PCIe PHY driver suport[1-5], and
i.MX8MM PCIe support[6-8] to have whole view to review this
patch-set.
quoted
The PCIe works on i.MX8MM EVK board based the the blkctrl power
driver
quoted
[2] and this patch-set.

[1]
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpa
tc
quoted
hwork.ozlabs.org%2Fproject%2Flinux-pci%2Fpatch%2F20210510141509.
929120
quoted
-3-l.stach%40pengutronix.de%2F&amp;data=04%7C01%7Chongxing.zhu
%40nxp.c
quoted
om%7C90b27fd98a4d47a5a68c08d99a3f32e3%7C686ea1d3bc2b4c6fa92
cd99c5c3016
quoted
35%7C0%7C0%7C637710418493785262%7CUnknown%7CTWFpbGZsb3d
8eyJWIjoiMC4wLj
quoted
AwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&
amp;sdata=
quoted
K%2B5UzVRndlp9qJT9RlkQp2qzKAx%2B76xwMd51xHLEZKI%3D&amp;re
served=0
quoted
[2]
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpa
tc
quoted
hwork.kernel.org%2Fproject%2Flinux-arm-kernel%2Fcover%2F20210910
202640
quoted
.980366-1-l.stach%40pengutronix.de%2F&amp;data=04%7C01%7Chon
gxing.zhu%
quoted
40nxp.com%7C90b27fd98a4d47a5a68c08d99a3f32e3%7C686ea1d3bc2b
4c6fa92cd99
quoted
c5c301635%7C0%7C0%7C637710418493795238%7CUnknown%7CTWFp
bGZsb3d8eyJWIjo
quoted
iMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
7C1000&amp
quoted
;sdata=kKpDrUNfZy0qR3QlJxW7tUgmVl8PS0WwUb4O694bOkA%3D&a
mp;reserved=0
quoted
Main changes v3 --> v4:
- Update the yaml to fix syntax error, add maxitems and drop
description of phy
- Correct the clock name in PHY DT node.
- Squash the EVK board relalted dts changes into one patch, and drop
the
quoted
  useless dummy clock and gpio suffix in DT nodes.
- Add board specific de-emphasis parameters as DT properties. Thus
each board
quoted
  can specify its actual de-emphasis values.
- Update the commit log of PHY driver.
- Remove the useless codes from PCIe driver, since they are moved to
PHY driver
- After the discussion and verification of the CLKREQ# configurations
with Tim,
quoted
  agree to add an optional boolean property "fsl,clkreq-unsupported",
indicates
quoted
  the CLKREQ# signal is hooked or not in HW designs.
- Add "Tested-by: Marcel Ziswiler [off-list ref]" tag,
since
quoted
  Marcel help to test the v3 patch-set.

Main changes v2 --> v3:
- Regarding Lucas' comments.
 - to have a whole view to review the patches, send out the i.MX8MM
PCIe support too.
quoted
 - move the PHY related bits manipulations of the GPR/SRC to
standalone PHY driver.
quoted
 - split the dts changes to SOC and board DT, and use the enum instead
of raw value.
quoted
 - update the license of the dt-binding header file.

Changes v1 --> v2:
- Update the license of the dt-binding header file to make the license
  compatible with dts files.
- Fix the dt_binding_check errors.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml    |   6
+++
quoted
Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml |  95
+++++++++++++++++++++++++++++++++
quoted
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi                |
55 +++++++++++++++++++
quoted
arch/arm64/boot/dts/freescale/imx8mm.dtsi                    |
46 +++++++++++++++-
quoted
drivers/pci/controller/dwc/pci-imx6.c                        |
73 ++++++++++++++++++++++---
quoted
drivers/phy/freescale/Kconfig                                |
9 ++++
quoted
drivers/phy/freescale/Makefile                               |
1 +
quoted
drivers/phy/freescale/phy-fsl-imx8m-pcie.c                   |
234
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++
quoted
include/dt-bindings/phy/phy-imx8-pcie.h                      |
14 +++++
quoted
9 files changed, 525 insertions(+), 8 deletions(-)

[PATCH v4 1/8] dt-bindings: phy: phy-imx8-pcie: Add binding for the
[PATCH v4 2/8] dt-bindings: phy: Add imx8 pcie phy driver support
[PATCH v4 3/8] dt-bindings: imx6q-pcie: Add PHY phandles and name
[PATCH v4 4/8] arm64: dts: imx8mm: Add the pcie phy support [PATCH
v4
quoted
5/8] phy: freescale: pcie: Initialize the imx8 pcie [PATCH v4 6/8]
arm64: dts: imx8mm: Add the pcie support [PATCH v4 7/8] arm64: dts:
imx8mm-evk: Add the pcie support on imx8mm [PATCH v4 8/8] PCI:
imx:
quoted
Add the imx8mm pcie support
Richard,

For your v4 series:

Reviewed-By: Tim Harvey <tharvey@gateworks.com>
Tested-By: Tim Harvey <tharvey@gateworks.com>

I tested this on imx8mm-venice* boards with no CLKREQ# support as well
as an imx8mm-evk board.
[Richard Zhu] Thanks a lot.

Best Regards
Richard Zhu
Thanks again for your effort on this series!

Best regards,

Tim
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Marcel Ziswiler <hidden>
Date: 2021-10-29 08:12:55

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments in-
lined below.
quoted hunk
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234 +++++++++++++++++++++
 3 files changed, 244 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 320630ffe3cd..de9ee7020f76 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI PHY as found
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
quoted hunk
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 1d02e3869b45..55d07c742ab0 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       += phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      += phy-fsl-imx8-mipi-dphy.o
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       += phy-fsl-imx8m-pcie.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184
+#define  ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0)
+#define IMX8MM_PCIE_PHY_CMN_REG062     0x188
+#define  ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3)
+#define IMX8MM_PCIE_PHY_CMN_REG063     0x18C
+#define  AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6)
+#define IMX8MM_PCIE_PHY_CMN_REG064     0x190
+#define  ANA_AUX_RX_TX_SEL_TX          BIT(7)
+#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
+#define  ANA_AUX_TX_TERM               BIT(2)
+#define IMX8MM_PCIE_PHY_CMN_REG065     0x194
+#define  ANA_AUX_RX_TERM               (BIT(7) | BIT(4))
+#define  ANA_AUX_TX_LVL                        GENMASK(3, 0)
+#define IMX8MM_PCIE_PHY_CMN_REG75      0x1D4
+#define  PCIE_PHY_CMN_REG75_PLL_DONE   0x3
+#define PCIE_PHY_TRSV_REG5             0x414
+#define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
+#define PCIE_PHY_TRSV_REG6             0x418
+#define  PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
+#define IMX8MM_GPR_PCIE_REF_CLK_PLL    FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3)
+#define IMX8MM_GPR_PCIE_REF_CLK_EXT    FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2)
+#define IMX8MM_GPR_PCIE_AUX_EN         BIT(19)
+#define IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
+#define IMX8MM_GPR_PCIE_POWER_OFF      BIT(17)
+#define IMX8MM_GPR_PCIE_SSC_EN         BIT(16)
+#define IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
+       u32                     tx_deemph_gen1;
+       u32                     tx_deemph_gen2;
+       bool                    clkreq_unused;
+};
+
+static int imx8_pcie_phy_init(struct phy *phy)
+{
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */
+       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+                          IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE,
+                          imx8_phy->clkreq_unused ?
+                          0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
+       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+                          IMX8MM_GPR_PCIE_AUX_EN,
+                          pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
+                          IMX8MM_GPR_PCIE_AUX_EN : 0);
V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out V4 stopped working for our output use-case as it only
enables it for the input use-case. If I enable this one always it starts working again.
+       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+                          IMX8MM_GPR_PCIE_POWER_OFF, 0);
+       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+                          IMX8MM_GPR_PCIE_SSC_EN, 0);
+
+       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+                          IMX8MM_GPR_PCIE_REF_CLK_SEL,
+                          pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
+                          IMX8MM_GPR_PCIE_REF_CLK_EXT :
+                          IMX8MM_GPR_PCIE_REF_CLK_PLL);
+       usleep_range(100, 200);
+
+       /* Do the PHY common block reset */
+       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
+                          IMX8MM_GPR_PCIE_CMN_RST,
+                          IMX8MM_GPR_PCIE_CMN_RST);
+       usleep_range(200, 500);
+
+
+       if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT) {
+               /* Configure the pad as input */
+               val = readl(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG061);
+               writel(val & ~ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
+                      imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG061);
+       } else if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT) {
+               /* Configure the PHY to output the refclock via pad */
+               writel(ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
+                      imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG061);
+               writel(ANA_PLL_CLK_OUT_TO_EXT_IO_SEL,
+                      imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG062);
+               writel(AUX_PLL_REFCLK_SEL_SYS_PLL,
+                      imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG063);
+               val = ANA_AUX_RX_TX_SEL_TX | ANA_AUX_TX_TERM;
+               writel(val | ANA_AUX_RX_TERM_GND_EN,
+                      imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG064);
+               writel(ANA_AUX_RX_TERM | ANA_AUX_TX_LVL,
+                      imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG065);
+       }
+
+       /* Tune PHY de-emphasis setting to pass PCIe compliance. */
+       writel(imx8_phy->tx_deemph_gen1, imx8_phy->base + PCIE_PHY_TRSV_REG5);
+       writel(imx8_phy->tx_deemph_gen2, imx8_phy->base + PCIE_PHY_TRSV_REG6);
+
+       reset_control_deassert(imx8_phy->reset);
+
+       /* Polling to check the phy is ready or not. */
+       ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG75,
+                                val, val == PCIE_PHY_CMN_REG75_PLL_DONE,
+                                10, 20000);
+       return ret;
+}
+
+static int imx8_pcie_phy_power_on(struct phy *phy)
+{
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       return clk_prepare_enable(imx8_phy->clk);
+}
+
+static int imx8_pcie_phy_power_off(struct phy *phy)
+{
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       clk_disable_unprepare(imx8_phy->clk);
+
+       return 0;
+}
+
+static const struct phy_ops imx8_pcie_phy_ops = {
+       .init           = imx8_pcie_phy_init,
+       .power_on       = imx8_pcie_phy_power_on,
+       .power_off      = imx8_pcie_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static int imx8_pcie_phy_probe(struct platform_device *pdev)
+{
+       struct phy_provider *phy_provider;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct imx8_pcie_phy *imx8_phy;
+       struct resource *res;
+
+       imx8_phy = devm_kzalloc(dev, sizeof(*imx8_phy), GFP_KERNEL);
+       if (!imx8_phy)
+               return -ENOMEM;
+
+       /* get PHY refclk pad mode */
+       of_property_read_u32(np, "fsl,refclk-pad-mode",
+                            &imx8_phy->refclk_pad_mode);
+
+       if (of_property_read_u32(np, "fsl,tx-deemph-gen1",
+                                &imx8_phy->tx_deemph_gen1))
+               imx8_phy->tx_deemph_gen1 = 0;
Is zero here really a sane default or should we rather use the previous hard-coded value?
+
+       if (of_property_read_u32(np, "fsl,tx-deemph-gen2",
+                                &imx8_phy->tx_deemph_gen2))
+               imx8_phy->tx_deemph_gen2 = 0;
Ditto.
+
+       if (of_property_read_bool(np, "fsl,clkreq-unsupported"))
+               imx8_phy->clkreq_unused = true;
+       else
+               imx8_phy->clkreq_unused = false;
+
+       imx8_phy->clk = devm_clk_get(dev, "ref");
+       if (IS_ERR(imx8_phy->clk)) {
+               dev_err(dev, "failed to get imx pcie phy clock\n");
+               return PTR_ERR(imx8_phy->clk);
+       }
+
+       /* Grab GPR config register range */
+       imx8_phy->iomuxc_gpr =
+                syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+       if (IS_ERR(imx8_phy->iomuxc_gpr)) {
+               dev_err(dev, "unable to find iomuxc registers\n");
+               return PTR_ERR(imx8_phy->iomuxc_gpr);
+       }
+
+       imx8_phy->reset = devm_reset_control_get_exclusive(dev, "pciephy");
+       if (IS_ERR(imx8_phy->reset)) {
+               dev_err(dev, "Failed to get PCIEPHY reset control\n");
+               return PTR_ERR(imx8_phy->reset);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       imx8_phy->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(imx8_phy->base))
+               return PTR_ERR(imx8_phy->base);
+
+       imx8_phy->phy = devm_phy_create(dev, NULL, &imx8_pcie_phy_ops);
+       if (IS_ERR(imx8_phy->phy))
+               return PTR_ERR(imx8_phy->phy);
+
+       phy_set_drvdata(imx8_phy->phy, imx8_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 imx8_pcie_phy_of_match[] = {
+       {.compatible = "fsl,imx8mm-pcie-phy",},
+       { },
+};
+MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
+
+static struct platform_driver imx8_pcie_phy_driver = {
+       .probe  = imx8_pcie_phy_probe,
+       .driver = {
+               .name   = "imx8-pcie-phy",
+               .of_match_table = imx8_pcie_phy_of_match,
+       }
+};
+module_platform_driver(imx8_pcie_phy_driver);
+
+MODULE_DESCRIPTION("FSL IMX8 PCIE PHY driver");
+MODULE_LICENSE("GPL");
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v4 7/8] arm64: dts: imx8mm-evk: Add the pcie support on imx8mm evk board

From: Marcel Ziswiler <hidden>
Date: 2021-10-29 08:21:32

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted hunk
Add the PCIe support on iMX8MM EVK boards.
And set the default reference clock mode.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index e033d0257b5a..fc1803a8af5b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/phy/phy-imx8-pcie.h>
 #include <dt-bindings/usb/pd.h>
 #include "imx8mm.dtsi"
 
@@ -30,6 +31,23 @@ status {
                };
        };
 
+       pcie0_refclk: pcie0-refclk {
+               compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <100000000>;
+       };
+
+       reg_pcie0: regulator-pcie {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pcie0_reg>;
+               regulator-name = "MPCIE_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
        reg_usdhc2_vmmc: regulator-usdhc2 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
@@ -289,6 +307,30 @@ pca6416: gpio@20 {
        };
 };
 
+&pcie_phy {
+       fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+       fsl,tx-deemph-gen1 = <0x2D>;
+       fsl,tx-deemph-gen2 = <0xF>;
Usually, hex notation uses lower-case letters in device trees.
quoted hunk
+       clocks = <&pcie0_refclk>;
+       status = "okay";
+};
+
+&pcie0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie0>;
+       reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+       clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+                <&pcie0_refclk>;
+       clock-names = "pcie", "pcie_aux", "pcie_bus";
+       assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+                         <&clk IMX8MM_CLK_PCIE1_CTRL>;
+       assigned-clock-rates = <10000000>, <250000000>;
+       assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+                                <&clk IMX8MM_SYS_PLL2_250M>;
+       vpcie-supply = <&reg_pcie0>;
+       status = "okay";
+};
+
 &sai3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai3>;
@@ -406,6 +448,19 @@ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA                     0x400001c3
                >;
        };
 
+       pinctrl_pcie0: pcie0grp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B    0x61
+                       MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21       0x41
+               >;
+       };
+
+       pinctrl_pcie0_reg: pcie0reggrp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5       0x41
+               >;
+       };
+
        pinctrl_pmic: pmicirqgrp {
                fsl,pins = <
                        MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3               0x141
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

RE: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-29 08:45:25

-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:13 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com; galak@kernel.crashing.org; Richard Zhu
[off-list ref]
Cc: linux-phy@lists.infradead.org; linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
standalone phy driver

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our
IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments in- lined
below.
[Richard Zhu] Sorry to hear about that. Then, it seems that this bit should be
 set anyway.
It's hard to understand this bit refer to the RM document. Sigh ☹.
Would set the AUX_EN bit later.
quoted
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234
+++++++++++++++++++++
 3 files changed, 244 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig
b/drivers/phy/freescale/Kconfig index 320630ffe3cd..de9ee7020f76
100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI PHY as
found
quoted
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
[Richard Zhu] Okay, would be added later.
Thanks.
quoted
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile
b/drivers/phy/freescale/Makefile index 1d02e3869b45..55d07c742ab0
100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       +=
phy-fsl-imx8mq-usb.o
quoted
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      +=
phy-fsl-imx8-mipi-dphy.o
quoted
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       +=
phy-fsl-imx8m-pcie.o
quoted
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0) #define
+IMX8MM_PCIE_PHY_CMN_REG062     0x188 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3) #define
+IMX8MM_PCIE_PHY_CMN_REG063     0x18C #define
+AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6) #define
+IMX8MM_PCIE_PHY_CMN_REG064     0x190
#define  ANA_AUX_RX_TX_SEL_TX
quoted
+BIT(7)
#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
#define
quoted
+ANA_AUX_TX_TERM               BIT(2) #define
+IMX8MM_PCIE_PHY_CMN_REG065     0x194
#define  ANA_AUX_RX_TERM
quoted
+(BIT(7) | BIT(4))
#define  ANA_AUX_TX_LVL
quoted
+GENMASK(3, 0) #define
IMX8MM_PCIE_PHY_CMN_REG75      0x1D4 #define
quoted
+PCIE_PHY_CMN_REG75_PLL_DONE   0x3 #define
PCIE_PHY_TRSV_REG5
quoted
+0x414 #define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D #define
+PCIE_PHY_TRSV_REG6             0x418 #define
+PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
#define
quoted
+IMX8MM_GPR_PCIE_REF_CLK_PLL
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3) #define
+IMX8MM_GPR_PCIE_REF_CLK_EXT
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2) #define
+IMX8MM_GPR_PCIE_AUX_EN         BIT(19) #define
+IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
#define
quoted
+IMX8MM_GPR_PCIE_POWER_OFF      BIT(17) #define
IMX8MM_GPR_PCIE_SSC_EN
quoted
+BIT(16) #define
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
quoted
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
+       u32                     tx_deemph_gen1;
+       u32                     tx_deemph_gen2;
+       bool                    clkreq_unused; };
+
+static int imx8_pcie_phy_init(struct phy *phy) {
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't
hooked */
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN_
OVERRIDE,
quoted
+                          imx8_phy->clkreq_unused ?
+                          0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN,
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN :
0);

V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out V4
stopped working for our output use-case as it only enables it for the input
use-case. If I enable this one always it starts working again.
[Richard Zhu] See my comment above.
Sorry to bring the regression on your board.
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_POWER_O
FF, 0);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_SSC_EN,
0);
quoted
+
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_REF_CLK_S
EL,
quoted
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_REF_CLK_
EXT :
quoted
+                          IMX8MM_GPR_PCIE_REF_CLK_
PLL);
quoted
+       usleep_range(100, 200);
+
+       /* Do the PHY common block reset */
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_CMN_RST,
quoted
+                          IMX8MM_GPR_PCIE_CMN_RST)
;
quoted
+       usleep_range(200, 500);
+
+
+       if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT) {
+               /* Configure the pad as input */
+               val = readl(imx8_phy->base +
+IMX8MM_PCIE_PHY_CMN_REG061);
+               writel(val &
~ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
quoted
+                      imx8_phy->base +
IMX8MM_PCIE_PHY_CMN_REG061);
quoted
+       } else if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT) {
+               /* Configure the PHY to output the refclock via
pad */
quoted
+               writel(ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
+                      imx8_phy->base +
IMX8MM_PCIE_PHY_CMN_REG061);
quoted
+               writel(ANA_PLL_CLK_OUT_TO_EXT_IO_SEL,
+                      imx8_phy->base +
IMX8MM_PCIE_PHY_CMN_REG062);
quoted
+               writel(AUX_PLL_REFCLK_SEL_SYS_PLL,
+                      imx8_phy->base +
IMX8MM_PCIE_PHY_CMN_REG063);
quoted
+               val = ANA_AUX_RX_TX_SEL_TX |
ANA_AUX_TX_TERM;
quoted
+               writel(val | ANA_AUX_RX_TERM_GND_EN,
+                      imx8_phy->base +
IMX8MM_PCIE_PHY_CMN_REG064);
quoted
+               writel(ANA_AUX_RX_TERM |
ANA_AUX_TX_LVL,
quoted
+                      imx8_phy->base +
IMX8MM_PCIE_PHY_CMN_REG065);
quoted
+       }
+
+       /* Tune PHY de-emphasis setting to pass PCIe compliance.
*/
quoted
+       writel(imx8_phy->tx_deemph_gen1, imx8_phy->base +
+PCIE_PHY_TRSV_REG5);
+       writel(imx8_phy->tx_deemph_gen2, imx8_phy->base +
+PCIE_PHY_TRSV_REG6);
+
+       reset_control_deassert(imx8_phy->reset);
+
+       /* Polling to check the phy is ready or not. */
+       ret = readl_poll_timeout(imx8_phy->base +
+IMX8MM_PCIE_PHY_CMN_REG75,
+                                val, val ==
+PCIE_PHY_CMN_REG75_PLL_DONE,
+                                10, 20000);
+       return ret;
+}
+
+static int imx8_pcie_phy_power_on(struct phy *phy) {
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       return clk_prepare_enable(imx8_phy->clk);
+}
+
+static int imx8_pcie_phy_power_off(struct phy *phy) {
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       clk_disable_unprepare(imx8_phy->clk);
+
+       return 0;
+}
+
+static const struct phy_ops imx8_pcie_phy_ops = {
+       .init           = imx8_pcie_phy_init,
+       .power_on       = imx8_pcie_phy_power_on,
+       .power_off      = imx8_pcie_phy_power_off,
+       .owner          = THIS_MODULE, };
+
+static int imx8_pcie_phy_probe(struct platform_device *pdev) {
+       struct phy_provider *phy_provider;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct imx8_pcie_phy *imx8_phy;
+       struct resource *res;
+
+       imx8_phy = devm_kzalloc(dev, sizeof(*imx8_phy),
GFP_KERNEL);
quoted
+       if (!imx8_phy)
+               return -ENOMEM;
+
+       /* get PHY refclk pad mode */
+       of_property_read_u32(np, "fsl,refclk-pad-mode",
+                            &imx8_phy->refclk_pad_mod
e);
quoted
+
+       if (of_property_read_u32(np, "fsl,tx-deemph-gen1",
+                                &imx8_phy->tx_deemp
h_gen1))
quoted
+               imx8_phy->tx_deemph_gen1 = 0;
Is zero here really a sane default or should we rather use the previous
hard-coded value?
quoted
+
+       if (of_property_read_u32(np, "fsl,tx-deemph-gen2",
+                                &imx8_phy->tx_deemp
h_gen2))
quoted
+               imx8_phy->tx_deemph_gen2 = 0;
Ditto.
[Richard Zhu] Refer to the RM document, the default values is zero.
How about to not touch the registers if the values of the tx_deemph_gen#
 are zero?

In the end, thanks a lot for your tests on this series patches.

BR
Richard
quoted
+
+       if (of_property_read_bool(np, "fsl,clkreq-unsupported"))
+               imx8_phy->clkreq_unused = true;
+       else
+               imx8_phy->clkreq_unused = false;
+
+       imx8_phy->clk = devm_clk_get(dev, "ref");
+       if (IS_ERR(imx8_phy->clk)) {
+               dev_err(dev, "failed to get imx pcie phy
clock\n");
quoted
+               return PTR_ERR(imx8_phy->clk);
+       }
+
+       /* Grab GPR config register range */
+       imx8_phy->iomuxc_gpr =
+
+syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+       if (IS_ERR(imx8_phy->iomuxc_gpr)) {
+               dev_err(dev, "unable to find iomuxc
registers\n");
quoted
+               return PTR_ERR(imx8_phy->iomuxc_gpr);
+       }
+
+       imx8_phy->reset = devm_reset_control_get_exclusive(dev,
+"pciephy");
+       if (IS_ERR(imx8_phy->reset)) {
+               dev_err(dev, "Failed to get PCIEPHY reset
control\n");
quoted
+               return PTR_ERR(imx8_phy->reset);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       imx8_phy->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(imx8_phy->base))
+               return PTR_ERR(imx8_phy->base);
+
+       imx8_phy->phy = devm_phy_create(dev, NULL,
+&imx8_pcie_phy_ops);
+       if (IS_ERR(imx8_phy->phy))
+               return PTR_ERR(imx8_phy->phy);
+
+       phy_set_drvdata(imx8_phy->phy, imx8_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 imx8_pcie_phy_of_match[] = {
+       {.compatible = "fsl,imx8mm-pcie-phy",},
+       { },
+};
+MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
+
+static struct platform_driver imx8_pcie_phy_driver = {
+       .probe  = imx8_pcie_phy_probe,
+       .driver = {
+               .name   = "imx8-pcie-phy",
+               .of_match_table = imx8_pcie_phy_of_match,
+       }
+};
+module_platform_driver(imx8_pcie_phy_driver);
+
+MODULE_DESCRIPTION("FSL IMX8 PCIE PHY driver");
+MODULE_LICENSE("GPL");
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

RE: [PATCH v4 7/8] arm64: dts: imx8mm-evk: Add the pcie support on imx8mm evk board

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-10-29 08:46:07

-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:21 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com; galak@kernel.crashing.org; Richard Zhu
[off-list ref]
Cc: linux-phy@lists.infradead.org; linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 7/8] arm64: dts: imx8mm-evk: Add the pcie
support on imx8mm evk board

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the PCIe support on iMX8MM EVK boards.
And set the default reference clock mode.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 55
+++++++++++++++++++
 1 file changed, 55 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index e033d0257b5a..fc1803a8af5b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -5,6 +5,7 @@
 /dts-v1/;

+#include <dt-bindings/phy/phy-imx8-pcie.h>
 #include <dt-bindings/usb/pd.h>
 #include "imx8mm.dtsi"
@@ -30,6 +31,23 @@ status {
                };
        };

+       pcie0_refclk: pcie0-refclk {
+               compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <100000000>;
+       };
+
+       reg_pcie0: regulator-pcie {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pcie0_reg>;
+               regulator-name = "MPCIE_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
        reg_usdhc2_vmmc: regulator-usdhc2 {
                compatible = "regulator-fixed";
                pinctrl-names = "default"; @@ -289,6 +307,30
@@
quoted
pca6416: gpio@20 {
        };
 };

+&pcie_phy {
+       fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+       fsl,tx-deemph-gen1 = <0x2D>;
+       fsl,tx-deemph-gen2 = <0xF>;
Usually, hex notation uses lower-case letters in device trees.
[Richard Zhu] Okay, would be changed later in next version later.
Thanks

BR
Richard
quoted
+       clocks = <&pcie0_refclk>;
+       status = "okay";
+};
+
+&pcie0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie0>;
+       reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+       clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk
+IMX8MM_CLK_PCIE1_AUX>,
+                <&pcie0_refclk>;
+       clock-names = "pcie", "pcie_aux", "pcie_bus";
+       assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+                         <&clk
IMX8MM_CLK_PCIE1_CTRL>;
quoted
+       assigned-clock-rates = <10000000>, <250000000>;
+       assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+                                <&clk
IMX8MM_SYS_PLL2_250M>;
quoted
+       vpcie-supply = <&reg_pcie0>;
+       status = "okay";
+};
+
 &sai3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai3>;
@@ -406,6 +448,19 @@
MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA
quoted
0x400001c3
                >;
        };

+       pinctrl_pcie0: pcie0grp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_I2C4_SCL_PCIE1
_CLKREQ_B    0x61
quoted
+                       MX8MM_IOMUXC_SAI2_RXFS_GPIO
4_IO21       0x41
quoted
+               >;
+       };
+
+       pinctrl_pcie0_reg: pcie0reggrp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_GPIO1_IO05_GPI
O1_IO5       0x41
quoted
+               >;
+       };
+
        pinctrl_pmic: pmicirqgrp {
                fsl,pins = <
                        MX8MM_IOMUXC_GPIO1_IO03_
GPIO1_IO3
quoted
0x141
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Tim Harvey <tharvey@gateworks.com>
Date: 2021-10-29 17:45:11

On Fri, Oct 29, 2021 at 1:45 AM Richard Zhu [off-list ref] wrote:
quoted
-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:13 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com; galak@kernel.crashing.org; Richard Zhu
[off-list ref]
Cc: linux-phy@lists.infradead.org; linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
standalone phy driver

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our
IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments in- lined
below.
[Richard Zhu] Sorry to hear about that. Then, it seems that this bit should be
 set anyway.
It's hard to understand this bit refer to the RM document. Sigh ☹.
Would set the AUX_EN bit later.
quoted
quoted
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234
+++++++++++++++++++++
 3 files changed, 244 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig
b/drivers/phy/freescale/Kconfig index 320630ffe3cd..de9ee7020f76
100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI PHY as
found
quoted
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
[Richard Zhu] Okay, would be added later.
Thanks.
quoted
quoted
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile
b/drivers/phy/freescale/Makefile index 1d02e3869b45..55d07c742ab0
100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       +=
phy-fsl-imx8mq-usb.o
quoted
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      +=
phy-fsl-imx8-mipi-dphy.o
quoted
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       +=
phy-fsl-imx8m-pcie.o
quoted
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0) #define
+IMX8MM_PCIE_PHY_CMN_REG062     0x188 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3) #define
+IMX8MM_PCIE_PHY_CMN_REG063     0x18C #define
+AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6) #define
+IMX8MM_PCIE_PHY_CMN_REG064     0x190
#define  ANA_AUX_RX_TX_SEL_TX
quoted
+BIT(7)
#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
#define
quoted
+ANA_AUX_TX_TERM               BIT(2) #define
+IMX8MM_PCIE_PHY_CMN_REG065     0x194
#define  ANA_AUX_RX_TERM
quoted
+(BIT(7) | BIT(4))
#define  ANA_AUX_TX_LVL
quoted
+GENMASK(3, 0) #define
IMX8MM_PCIE_PHY_CMN_REG75      0x1D4 #define
quoted
+PCIE_PHY_CMN_REG75_PLL_DONE   0x3 #define
PCIE_PHY_TRSV_REG5
quoted
+0x414 #define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D #define
+PCIE_PHY_TRSV_REG6             0x418 #define
+PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
#define
quoted
+IMX8MM_GPR_PCIE_REF_CLK_PLL
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3) #define
+IMX8MM_GPR_PCIE_REF_CLK_EXT
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2) #define
+IMX8MM_GPR_PCIE_AUX_EN         BIT(19) #define
+IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
#define
quoted
+IMX8MM_GPR_PCIE_POWER_OFF      BIT(17) #define
IMX8MM_GPR_PCIE_SSC_EN
quoted
+BIT(16) #define
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
quoted
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
+       u32                     tx_deemph_gen1;
+       u32                     tx_deemph_gen2;
+       bool                    clkreq_unused; };
+
+static int imx8_pcie_phy_init(struct phy *phy) {
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't
hooked */
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN_
OVERRIDE,
quoted
+                          imx8_phy->clkreq_unused ?
+                          0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN,
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN :
0);

V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out V4
stopped working for our output use-case as it only enables it for the input
use-case. If I enable this one always it starts working again.
[Richard Zhu] See my comment above.
Sorry to bring the regression on your board.
Marcel,

Your board does not use an external clk, but does it hook up CLKREQ#
from the socket to either I2C4_SCL or UART4_RXD and pin muxed as such?

For my board that uses an external clk and does not connect CLKREQ# to
the IMX8MM I need to disable that bit. As Richard says we have invalid
documentation for these bits unfortunately which is not helping.

Richard, when we do figure out proper documentation for these bits I
suggest you also add a comment block right above their #defines in the
phy driver with the correct documentation to avoid future confusion.
NXP has had so many mistakes in the various IMX8M RM's and I fear they
will never get fixed.

Best regards,

Tim

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

RE: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-11-01 08:19:27

-----Original Message-----
From: Tim Harvey <tharvey@gateworks.com>
Sent: Saturday, October 30, 2021 1:45 AM
To: Richard Zhu <hongxing.zhu@nxp.com>; Marcel Ziswiler
[off-list ref]
Cc: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
galak@kernel.crashing.org; linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org; kernel@pengutronix.de;
devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; dl-linux-imx
[off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
standalone phy driver

On Fri, Oct 29, 2021 at 1:45 AM Richard Zhu [off-list ref]
wrote:
quoted
quoted
-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:13 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com;
quoted
quoted
galak@kernel.crashing.org; Richard Zhu [off-list ref]
Cc: linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the
imx8 pcie standalone phy driver

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our
IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments in-
lined
quoted
quoted
below.
[Richard Zhu] Sorry to hear about that. Then, it seems that this bit
should be  set anyway.
It's hard to understand this bit refer to the RM document. Sigh ☹.
Would set the AUX_EN bit later.
quoted
quoted
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234
+++++++++++++++++++++
 3 files changed, 244 insertions(+)  create mode 100644
drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig
b/drivers/phy/freescale/Kconfig index 320630ffe3cd..de9ee7020f76
100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI PHY as
found
quoted
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
[Richard Zhu] Okay, would be added later.
Thanks.
quoted
quoted
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile
b/drivers/phy/freescale/Makefile index
1d02e3869b45..55d07c742ab0
quoted
quoted
quoted
100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       +=
phy-fsl-imx8mq-usb.o
quoted
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      +=
phy-fsl-imx8-mipi-dphy.o
quoted
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       +=
phy-fsl-imx8m-pcie.o
quoted
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h> #include <linux/regmap.h>
+#include <linux/reset.h> #include
+<dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0) #define
+IMX8MM_PCIE_PHY_CMN_REG062     0x188 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3) #define
+IMX8MM_PCIE_PHY_CMN_REG063     0x18C #define
+AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6) #define
+IMX8MM_PCIE_PHY_CMN_REG064     0x190
#define  ANA_AUX_RX_TX_SEL_TX
quoted
+BIT(7)
#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
#define
quoted
+ANA_AUX_TX_TERM               BIT(2) #define
+IMX8MM_PCIE_PHY_CMN_REG065     0x194
#define  ANA_AUX_RX_TERM
quoted
+(BIT(7) | BIT(4))
#define  ANA_AUX_TX_LVL
quoted
+GENMASK(3, 0) #define
IMX8MM_PCIE_PHY_CMN_REG75      0x1D4 #define
quoted
+PCIE_PHY_CMN_REG75_PLL_DONE   0x3 #define
PCIE_PHY_TRSV_REG5
quoted
+0x414 #define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
#define
quoted
quoted
quoted
+PCIE_PHY_TRSV_REG6             0x418 #define
+PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
#define
quoted
+IMX8MM_GPR_PCIE_REF_CLK_PLL
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3) #define
+IMX8MM_GPR_PCIE_REF_CLK_EXT
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2) #define
+IMX8MM_GPR_PCIE_AUX_EN         BIT(19) #define
+IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
#define
quoted
+IMX8MM_GPR_PCIE_POWER_OFF      BIT(17) #define
IMX8MM_GPR_PCIE_SSC_EN
quoted
+BIT(16) #define
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
quoted
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
+       u32                     tx_deemph_gen1;
+       u32                     tx_deemph_gen2;
+       bool                    clkreq_unused; };
+
+static int imx8_pcie_phy_init(struct phy *phy) {
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't
hooked */
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN_
OVERRIDE,
quoted
+                          imx8_phy->clkreq_unused ?
+                          0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN,
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN :
0);

V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out V4
stopped
quoted
quoted
working for our output use-case as it only enables it for the input
use-case. If I enable this one always it starts working again.
[Richard Zhu] See my comment above.
Sorry to bring the regression on your board.
Marcel,

Your board does not use an external clk, but does it hook up CLKREQ#
from the socket to either I2C4_SCL or UART4_RXD and pin muxed as
such?

For my board that uses an external clk and does not connect CLKREQ# to
the IMX8MM I need to disable that bit. As Richard says we have invalid
documentation for these bits unfortunately which is not helping.

Richard, when we do figure out proper documentation for these bits I
suggest you also add a comment block right above their #defines in the
phy driver with the correct documentation to avoid future confusion.
NXP has had so many mistakes in the various IMX8M RM's and I fear they
will never get fixed.
[Richard Zhu] Hi Tim: 
I took look at the validation codes, and found that the AUX_EN is always
 set to be 1b'1. Whatever the reference clock mode is selected.
I'm sending a query email to design team, but I'm not sure I can get response
in time.
Can you help to take a double tests at your board when AUX_EN(bit19 of GPR14)
is set to be 1b'1 firstly?
Thanks in advanced.

BR
Richard
Best regards,

Tim
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Tim Harvey <tharvey@gateworks.com>
Date: 2021-11-01 17:13:19

On Mon, Nov 1, 2021 at 1:19 AM Richard Zhu [off-list ref] wrote:
quoted
-----Original Message-----
From: Tim Harvey <tharvey@gateworks.com>
Sent: Saturday, October 30, 2021 1:45 AM
To: Richard Zhu <hongxing.zhu@nxp.com>; Marcel Ziswiler
[off-list ref]
Cc: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
galak@kernel.crashing.org; linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org; kernel@pengutronix.de;
devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; dl-linux-imx
[off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
standalone phy driver

On Fri, Oct 29, 2021 at 1:45 AM Richard Zhu [off-list ref]
wrote:
quoted
quoted
-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:13 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com;
quoted
quoted
galak@kernel.crashing.org; Richard Zhu [off-list ref]
Cc: linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the
imx8 pcie standalone phy driver

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our
IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments in-
lined
quoted
quoted
below.
[Richard Zhu] Sorry to hear about that. Then, it seems that this bit
should be  set anyway.
It's hard to understand this bit refer to the RM document. Sigh ☹.
Would set the AUX_EN bit later.
quoted
quoted
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234
+++++++++++++++++++++
 3 files changed, 244 insertions(+)  create mode 100644
drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig
b/drivers/phy/freescale/Kconfig index 320630ffe3cd..de9ee7020f76
100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI PHY as
found
quoted
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
[Richard Zhu] Okay, would be added later.
Thanks.
quoted
quoted
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile
b/drivers/phy/freescale/Makefile index
1d02e3869b45..55d07c742ab0
quoted
quoted
quoted
100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       +=
phy-fsl-imx8mq-usb.o
quoted
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      +=
phy-fsl-imx8-mipi-dphy.o
quoted
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       +=
phy-fsl-imx8m-pcie.o
quoted
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h> #include <linux/regmap.h>
+#include <linux/reset.h> #include
+<dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0) #define
+IMX8MM_PCIE_PHY_CMN_REG062     0x188 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3) #define
+IMX8MM_PCIE_PHY_CMN_REG063     0x18C #define
+AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6) #define
+IMX8MM_PCIE_PHY_CMN_REG064     0x190
#define  ANA_AUX_RX_TX_SEL_TX
quoted
+BIT(7)
#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
#define
quoted
+ANA_AUX_TX_TERM               BIT(2) #define
+IMX8MM_PCIE_PHY_CMN_REG065     0x194
#define  ANA_AUX_RX_TERM
quoted
+(BIT(7) | BIT(4))
#define  ANA_AUX_TX_LVL
quoted
+GENMASK(3, 0) #define
IMX8MM_PCIE_PHY_CMN_REG75      0x1D4 #define
quoted
+PCIE_PHY_CMN_REG75_PLL_DONE   0x3 #define
PCIE_PHY_TRSV_REG5
quoted
+0x414 #define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
#define
quoted
quoted
quoted
+PCIE_PHY_TRSV_REG6             0x418 #define
+PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
#define
quoted
+IMX8MM_GPR_PCIE_REF_CLK_PLL
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3) #define
+IMX8MM_GPR_PCIE_REF_CLK_EXT
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2) #define
+IMX8MM_GPR_PCIE_AUX_EN         BIT(19) #define
+IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
#define
quoted
+IMX8MM_GPR_PCIE_POWER_OFF      BIT(17) #define
IMX8MM_GPR_PCIE_SSC_EN
quoted
+BIT(16) #define
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
quoted
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
+       u32                     tx_deemph_gen1;
+       u32                     tx_deemph_gen2;
+       bool                    clkreq_unused; };
+
+static int imx8_pcie_phy_init(struct phy *phy) {
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't
hooked */
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN_
OVERRIDE,
quoted
+                          imx8_phy->clkreq_unused ?
+                          0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN,
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN :
0);

V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out V4
stopped
quoted
quoted
working for our output use-case as it only enables it for the input
use-case. If I enable this one always it starts working again.
[Richard Zhu] See my comment above.
Sorry to bring the regression on your board.
Marcel,

Your board does not use an external clk, but does it hook up CLKREQ#
from the socket to either I2C4_SCL or UART4_RXD and pin muxed as
such?

For my board that uses an external clk and does not connect CLKREQ# to
the IMX8MM I need to disable that bit. As Richard says we have invalid
documentation for these bits unfortunately which is not helping.

Richard, when we do figure out proper documentation for these bits I
suggest you also add a comment block right above their #defines in the
phy driver with the correct documentation to avoid future confusion.
NXP has had so many mistakes in the various IMX8M RM's and I fear they
will never get fixed.
[Richard Zhu] Hi Tim:
I took look at the validation codes, and found that the AUX_EN is always
 set to be 1b'1. Whatever the reference clock mode is selected.
I'm sending a query email to design team, but I'm not sure I can get response
in time.
Can you help to take a double tests at your board when AUX_EN(bit19 of GPR14)
is set to be 1b'1 firstly?
Thanks in advanced.
Richard and Marcel,

I apologize, my mistake I was referring to GPR14 bit 9 and not bit19
in my testing above.

I tested leaving bit 9 set and this still works on my boards with ext
clk and no CLKREQ# as well as imx8mm-evk with ext clk and CLKREQ#.

So the change on top of your v4 would be:
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
index 4b4402eaddcc..003f575b36f0 100644
--- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -73,8 +73,7 @@ static int imx8_pcie_phy_init(struct phy *phy)
                           0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
        regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
                           IMX8MM_GPR_PCIE_AUX_EN,
-                          pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
-                          IMX8MM_GPR_PCIE_AUX_EN : 0);
+                          IMX8MM_GPR_PCIE_AUX_EN);
        regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
                           IMX8MM_GPR_PCIE_POWER_OFF, 0);
        regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
Marcel, does this look right for your board?

Best regards,

Tim

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Marcel Ziswiler <hidden>
Date: 2021-11-01 23:53:39

Hi Tim and Richard

On Mon, 2021-11-01 at 10:13 -0700, Tim Harvey wrote:
quoted hunk
On Mon, Nov 1, 2021 at 1:19 AM Richard Zhu [off-list ref] wrote:
quoted
quoted
-----Original Message-----
From: Tim Harvey <tharvey@gateworks.com>
Sent: Saturday, October 30, 2021 1:45 AM
To: Richard Zhu <hongxing.zhu@nxp.com>; Marcel Ziswiler
[off-list ref]
Cc: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
galak@kernel.crashing.org; linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org; kernel@pengutronix.de;
devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; dl-linux-imx
[off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
standalone phy driver

On Fri, Oct 29, 2021 at 1:45 AM Richard Zhu [off-list ref]
wrote:
quoted
quoted
-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:13 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com;
quoted
quoted
galak@kernel.crashing.org; Richard Zhu [off-list ref]
Cc: linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the
imx8 pcie standalone phy driver

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our
IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments in-
lined
quoted
quoted
below.
[Richard Zhu] Sorry to hear about that. Then, it seems that this bit
should be  set anyway.
It's hard to understand this bit refer to the RM document. Sigh ☹.
Would set the AUX_EN bit later.
quoted
quoted
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234
+++++++++++++++++++++
 3 files changed, 244 insertions(+)  create mode 100644
drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig
b/drivers/phy/freescale/Kconfig index 320630ffe3cd..de9ee7020f76
100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI PHY as
found
quoted
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
[Richard Zhu] Okay, would be added later.
Thanks.
quoted
quoted
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile
b/drivers/phy/freescale/Makefile index
1d02e3869b45..55d07c742ab0
quoted
quoted
quoted
100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       +=
phy-fsl-imx8mq-usb.o
quoted
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      +=
phy-fsl-imx8-mipi-dphy.o
quoted
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       +=
phy-fsl-imx8m-pcie.o
quoted
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h> #include <linux/regmap.h>
+#include <linux/reset.h> #include
+<dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0) #define
+IMX8MM_PCIE_PHY_CMN_REG062     0x188 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3) #define
+IMX8MM_PCIE_PHY_CMN_REG063     0x18C #define
+AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6) #define
+IMX8MM_PCIE_PHY_CMN_REG064     0x190
#define  ANA_AUX_RX_TX_SEL_TX
quoted
+BIT(7)
#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
#define
quoted
+ANA_AUX_TX_TERM               BIT(2) #define
+IMX8MM_PCIE_PHY_CMN_REG065     0x194
#define  ANA_AUX_RX_TERM
quoted
+(BIT(7) | BIT(4))
#define  ANA_AUX_TX_LVL
quoted
+GENMASK(3, 0) #define
IMX8MM_PCIE_PHY_CMN_REG75      0x1D4 #define
quoted
+PCIE_PHY_CMN_REG75_PLL_DONE   0x3 #define
PCIE_PHY_TRSV_REG5
quoted
+0x414 #define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
#define
quoted
quoted
quoted
+PCIE_PHY_TRSV_REG6             0x418 #define
+PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
#define
quoted
+IMX8MM_GPR_PCIE_REF_CLK_PLL
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3) #define
+IMX8MM_GPR_PCIE_REF_CLK_EXT
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2) #define
+IMX8MM_GPR_PCIE_AUX_EN         BIT(19) #define
+IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
#define
quoted
+IMX8MM_GPR_PCIE_POWER_OFF      BIT(17) #define
IMX8MM_GPR_PCIE_SSC_EN
quoted
+BIT(16) #define
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
quoted
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
+       u32                     tx_deemph_gen1;
+       u32                     tx_deemph_gen2;
+       bool                    clkreq_unused; };
+
+static int imx8_pcie_phy_init(struct phy *phy) {
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't
hooked */
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN_
OVERRIDE,
quoted
+                          imx8_phy->clkreq_unused ?
+                          0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN,
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN :
0);

V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out V4
stopped
quoted
quoted
working for our output use-case as it only enables it for the input
use-case. If I enable this one always it starts working again.
[Richard Zhu] See my comment above.
Sorry to bring the regression on your board.
Marcel,

Your board does not use an external clk, but does it hook up CLKREQ#
from the socket to either I2C4_SCL or UART4_RXD and pin muxed as
such?

For my board that uses an external clk and does not connect CLKREQ# to
the IMX8MM I need to disable that bit. As Richard says we have invalid
documentation for these bits unfortunately which is not helping.

Richard, when we do figure out proper documentation for these bits I
suggest you also add a comment block right above their #defines in the
phy driver with the correct documentation to avoid future confusion.
NXP has had so many mistakes in the various IMX8M RM's and I fear they
will never get fixed.
[Richard Zhu] Hi Tim:
I took look at the validation codes, and found that the AUX_EN is always
 set to be 1b'1. Whatever the reference clock mode is selected.
I'm sending a query email to design team, but I'm not sure I can get response
in time.
Can you help to take a double tests at your board when AUX_EN(bit19 of GPR14)
is set to be 1b'1 firstly?
Thanks in advanced.
Richard and Marcel,

I apologize, my mistake I was referring to GPR14 bit 9 and not bit19
in my testing above.

I tested leaving bit 9 set and this still works on my boards with ext
clk and no CLKREQ# as well as imx8mm-evk with ext clk and CLKREQ#.

So the change on top of your v4 would be:
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
index 4b4402eaddcc..003f575b36f0 100644
--- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -73,8 +73,7 @@ static int imx8_pcie_phy_init(struct phy *phy)
                           0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
        regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
                           IMX8MM_GPR_PCIE_AUX_EN,
-                          pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
-                          IMX8MM_GPR_PCIE_AUX_EN : 0);
+                          IMX8MM_GPR_PCIE_AUX_EN);
        regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
                           IMX8MM_GPR_PCIE_POWER_OFF, 0);
        regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,

Marcel, does this look right for your board?
Yes, that is exactly how I run it now. Thanks!
Best regards,

Tim
Cheers

Marcel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

RE: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver

From: Richard Zhu <hongxing.zhu@nxp.com>
Date: 2021-11-02 02:42:32

-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Tuesday, November 2, 2021 7:53 AM
To: tharvey@gateworks.com; Richard Zhu <hongxing.zhu@nxp.com>
Cc: kishon@ti.com; vkoul@kernel.org; kernel@pengutronix.de;
dl-linux-imx [off-list ref]; devicetree@vger.kernel.org;
robh@kernel.org; l.stach@pengutronix.de; shawnguo@kernel.org;
linux-arm-kernel@lists.infradead.org; linux-phy@lists.infradead.org;
galak@kernel.crashing.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the imx8 pcie
standalone phy driver

Hi Tim and Richard

On Mon, 2021-11-01 at 10:13 -0700, Tim Harvey wrote:
quoted
On Mon, Nov 1, 2021 at 1:19 AM Richard Zhu [off-list ref]
wrote:
quoted
quoted
quoted
-----Original Message-----
From: Tim Harvey <tharvey@gateworks.com>
Sent: Saturday, October 30, 2021 1:45 AM
To: Richard Zhu <hongxing.zhu@nxp.com>; Marcel Ziswiler
[off-list ref]
Cc: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
galak@kernel.crashing.org; linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org; kernel@pengutronix.de;
devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
dl-linux-imx [off-list ref]
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize the
imx8 pcie standalone phy driver

On Fri, Oct 29, 2021 at 1:45 AM Richard Zhu
[off-list ref]
quoted
quoted
quoted
wrote:
quoted
quoted
-----Original Message-----
From: Marcel Ziswiler <redacted>
Sent: Friday, October 29, 2021 4:13 PM
To: kishon@ti.com; vkoul@kernel.org; robh@kernel.org;
l.stach@pengutronix.de; shawnguo@kernel.org;
tharvey@gateworks.com;
quoted
quoted
galak@kernel.crashing.org; Richard Zhu
[off-list ref]
quoted
quoted
quoted
quoted
quoted
Cc: linux-phy@lists.infradead.org;
linux-arm-kernel@lists.infradead.org;
kernel@pengutronix.de; devicetree@vger.kernel.org;
linux-kernel@vger.kernel.org; dl-linux-imx
[off-list ref]
quoted
quoted
quoted
quoted
quoted
Subject: Re: [PATCH v4 5/8] phy: freescale: pcie: Initialize
the
imx8 pcie standalone phy driver

On Thu, 2021-10-28 at 15:27 +0800, Richard Zhu wrote:
quoted
Add the standalone i.MX8 PCIe PHY driver.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Tested-by: Marcel Ziswiler <redacted>
Unfortunately, this version no longer works for our
IMX8_PCIE_REFCLK_PAD_OUTPUT use-case. Further comments
in-
quoted
quoted
quoted
lined
quoted
quoted
below.
[Richard Zhu] Sorry to hear about that. Then, it seems that this
bit should be  set anyway.
It's hard to understand this bit refer to the RM document. Sigh
☹.
quoted
quoted
quoted
quoted
Would set the AUX_EN bit later.
quoted
quoted
---
 drivers/phy/freescale/Kconfig              |   9 +
 drivers/phy/freescale/Makefile             |   1 +
 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 234
+++++++++++++++++++++
 3 files changed, 244 insertions(+)  create mode 100644
drivers/phy/freescale/phy-fsl-imx8m-pcie.c
diff --git a/drivers/phy/freescale/Kconfig
b/drivers/phy/freescale/Kconfig index
320630ffe3cd..de9ee7020f76
100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -14,3 +14,12 @@ config PHY_MIXEL_MIPI_DPHY
        help
          Enable this to add support for the Mixel DSI
PHY
quoted
quoted
quoted
quoted
quoted
quoted
as
found
quoted
          on NXP's i.MX8 family of SOCs.
+
+config PHY_FSL_IMX8M_PCIE
+       tristate "Freescale i.MX8 PCIE PHY"
Above description is missing the M as in i.MX 8M.
[Richard Zhu] Okay, would be added later.
Thanks.
quoted
quoted
+       depends on OF && HAS_IOMEM
+       select GENERIC_PHY
+       default ARCH_MXC && ARM64
+       help
+         Enable this to add support for the PCIE PHY as
+found on
+         i.MX8M family of SOCs.
diff --git a/drivers/phy/freescale/Makefile
b/drivers/phy/freescale/Makefile index
1d02e3869b45..55d07c742ab0
quoted
quoted
quoted
100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)       +=
phy-fsl-imx8mq-usb.o
quoted
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      +=
phy-fsl-imx8-mipi-dphy.o
quoted
+obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       +=
phy-fsl-imx8m-pcie.o
quoted
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
new file mode 100644
index 000000000000..4b4402eaddcc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h> #include
+<linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h> #include
+<linux/regmap.h> #include <linux/reset.h> #include
+<dt-bindings/phy/phy-imx8-pcie.h>
+
+#define IMX8MM_PCIE_PHY_CMN_REG061     0x184
#define
quoted
quoted
quoted
quoted
quoted
quoted
+ANA_PLL_CLK_OUT_TO_EXT_IO_EN  BIT(0) #define
+IMX8MM_PCIE_PHY_CMN_REG062     0x188 #define
+ANA_PLL_CLK_OUT_TO_EXT_IO_SEL BIT(3) #define
+IMX8MM_PCIE_PHY_CMN_REG063     0x18C #define
+AUX_PLL_REFCLK_SEL_SYS_PLL    GENMASK(7, 6) #define
+IMX8MM_PCIE_PHY_CMN_REG064     0x190
#define  ANA_AUX_RX_TX_SEL_TX
quoted
+BIT(7)
#define  ANA_AUX_RX_TERM_GND_EN                BIT(3)
#define
quoted
quoted
quoted
quoted
quoted
quoted
+ANA_AUX_TX_TERM               BIT(2) #define
+IMX8MM_PCIE_PHY_CMN_REG065     0x194
#define  ANA_AUX_RX_TERM
quoted
+(BIT(7) | BIT(4))
#define  ANA_AUX_TX_LVL
quoted
+GENMASK(3, 0) #define
IMX8MM_PCIE_PHY_CMN_REG75      0x1D4 #define
quoted
+PCIE_PHY_CMN_REG75_PLL_DONE   0x3 #define
PCIE_PHY_TRSV_REG5
quoted
+0x414 #define  PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
#define
quoted
quoted
quoted
+PCIE_PHY_TRSV_REG6             0x418 #define
+PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
+
+#define
IMX8MM_GPR_PCIE_REF_CLK_SEL    GENMASK(25, 24)
quoted
quoted
quoted
quoted
quoted
#define
quoted
+IMX8MM_GPR_PCIE_REF_CLK_PLL
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3) #define
+IMX8MM_GPR_PCIE_REF_CLK_EXT
+FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x2) #define
+IMX8MM_GPR_PCIE_AUX_EN         BIT(19) #define
+IMX8MM_GPR_PCIE_CMN_RST                BIT(18)
quoted
quoted
quoted
quoted
quoted
#define
quoted
+IMX8MM_GPR_PCIE_POWER_OFF      BIT(17) #define
IMX8MM_GPR_PCIE_SSC_EN
quoted
+BIT(16) #define
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE        BIT(9)
quoted
+
+struct imx8_pcie_phy {
+       void __iomem            *base;
+       struct clk              *clk;
+       struct phy              *phy;
+       struct regmap           *iomuxc_gpr;
+       struct reset_control    *reset;
+       u32                     refclk_pad_mode;
quoted
quoted
quoted
quoted
quoted
quoted
+       u32                     tx_deemph_gen1;
quoted
quoted
quoted
quoted
quoted
quoted
+       u32                     tx_deemph_gen2;
quoted
quoted
quoted
quoted
quoted
quoted
+       bool                    clkreq_unused; };
quoted
quoted
quoted
quoted
quoted
quoted
+
+static int imx8_pcie_phy_init(struct phy *phy) {
+       int ret;
+       u32 val, pad_mode;
+       struct imx8_pcie_phy *imx8_phy =
+phy_get_drvdata(phy);
+
+       reset_control_assert(imx8_phy->reset);
+
+       pad_mode = imx8_phy->refclk_pad_mode;
+       /* Set AUX_EN_OVERRIDE 1'b0, when the
CLKREQ# isn't
quoted
quoted
quoted
quoted
quoted
hooked */
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN_
quoted
quoted
quoted
quoted
quoted
OVERRIDE,
quoted
+                          imx8_phy->clkreq_unused ?
quoted
quoted
quoted
quoted
quoted
quoted
+                          0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
+       regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN,
quoted
quoted
quoted
quoted
quoted
quoted
+                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN :
quoted
quoted
quoted
quoted
quoted
0);

V3 had IMX8MM_GPR_PCIE_AUX_EN always enabled. Turns out
V4
quoted
quoted
quoted
stopped
quoted
quoted
working for our output use-case as it only enables it for the
input use-case. If I enable this one always it starts working
again.
quoted
quoted
quoted
quoted
[Richard Zhu] See my comment above.
Sorry to bring the regression on your board.
Marcel,

Your board does not use an external clk, but does it hook up
CLKREQ# from the socket to either I2C4_SCL or UART4_RXD and pin
muxed as such?

For my board that uses an external clk and does not connect
CLKREQ# to the IMX8MM I need to disable that bit. As Richard says
we have invalid documentation for these bits unfortunately which is
not helping.
quoted
quoted
quoted
Richard, when we do figure out proper documentation for these bits
I suggest you also add a comment block right above their #defines
in the phy driver with the correct documentation to avoid future
confusion.
quoted
quoted
quoted
NXP has had so many mistakes in the various IMX8M RM's and I
fear
quoted
quoted
quoted
they will never get fixed.
[Richard Zhu] Hi Tim:
I took look at the validation codes, and found that the AUX_EN is
always
 set to be 1b'1. Whatever the reference clock mode is selected.
I'm sending a query email to design team, but I'm not sure I can get
response in time.
Can you help to take a double tests at your board when AUX_EN(bit19
of GPR14) is set to be 1b'1 firstly?
Thanks in advanced.
Richard and Marcel,

I apologize, my mistake I was referring to GPR14 bit 9 and not bit19
in my testing above.

I tested leaving bit 9 set and this still works on my boards with ext
clk and no CLKREQ# as well as imx8mm-evk with ext clk and CLKREQ#.

So the change on top of your v4 would be:
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
index 4b4402eaddcc..003f575b36f0 100644
--- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -73,8 +73,7 @@ static int imx8_pcie_phy_init(struct phy *phy)
                           0 :
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
quoted
        regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
                           IMX8MM_GPR_PCIE_AUX_E
N,
quoted
-                          pad_mode ==
IMX8_PCIE_REFCLK_PAD_INPUT ?
quoted
-                          IMX8MM_GPR_PCIE_AUX_EN :
0);
quoted
+                          IMX8MM_GPR_PCIE_AUX_EN);
quoted
        regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
                           IMX8MM_GPR_PCIE_POWER
_OFF, 0);
quoted
        regmap_update_bits(imx8_phy->iomuxc_gpr,
IOMUXC_GPR14,
quoted
Marcel, does this look right for your board?
Yes, that is exactly how I run it now. Thanks!
[Richard Zhu] That's great.
Thanks a lot. I will send v5 set a moment later.
BR
Richard
quoted
Best regards,

Tim
Cheers

Marcel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help