All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Zhu <hongxing.zhu@nxp.com>
To: "tharvey@gateworks.com" <tharvey@gateworks.com>
Cc: Lucas Stach <l.stach@pengutronix.de>,
	Kishon Vijay Abraham I <kishon@ti.com>,
	"vkoul@kernel.org" <vkoul@kernel.org>,
	Rob Herring <robh@kernel.org>,
	"galak@kernel.crashing.org" <galak@kernel.crashing.org>,
	Shawn Guo <shawnguo@kernel.org>,
	"linux-phy@lists.infradead.org" <linux-phy@lists.infradead.org>,
	Device Tree Mailing List <devicetree@vger.kernel.org>,
	Linux ARM Mailing List <linux-arm-kernel@lists.infradead.org>,
	open list <linux-kernel@vger.kernel.org>,
	Sascha Hauer <kernel@pengutronix.de>,
	dl-linux-imx <linux-imx@nxp.com>
Subject: RE: [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie standalone phy driver
Date: Fri, 22 Oct 2021 00:54:53 +0000	[thread overview]
Message-ID: <AS8PR04MB8676330408A6E18D35D003CB8C809@AS8PR04MB8676.eurprd04.prod.outlook.com> (raw)
In-Reply-To: <CAJ+vNU192BCiVQ=UwXgVCgCMA7tqcAQXQokyh5bO08a+SycOzQ@mail.gmail.com>

> -----Original Message-----
> From: Tim Harvey <tharvey@gateworks.com>
> Sent: Friday, October 22, 2021 12:00 AM
> To: Richard Zhu <hongxing.zhu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>; Kishon Vijay Abraham I
> <kishon@ti.com>; vkoul@kernel.org; Rob Herring <robh@kernel.org>;
> galak@kernel.crashing.org; Shawn Guo <shawnguo@kernel.org>;
> linux-phy@lists.infradead.org; Device Tree Mailing List
> <devicetree@vger.kernel.org>; Linux ARM Mailing List
> <linux-arm-kernel@lists.infradead.org>; open list
> <linux-kernel@vger.kernel.org>; Sascha Hauer <kernel@pengutronix.de>;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie
> standalone phy driver
> 
> On Tue, Oct 12, 2021 at 2:06 AM Richard Zhu <hongxing.zhu@nxp.com>
> wrote:
> >
> > Add the standalone i.MX8 PCIe PHY driver.
> > Some reset bits should be manipulated between PHY configurations and
> > status check(internal PLL is locked or not).
> > So, do the PHY configuration in the phy_calibrate().
> > And check the PHY is ready or not in the phy_init().
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > ---
> >  drivers/phy/freescale/Kconfig              |   9 +
> >  drivers/phy/freescale/Makefile             |   1 +
> >  drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 218
> > +++++++++++++++++++++
> >  3 files changed, 228 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..fb08e5242602
> > 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
> > +       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..317cf61bff37
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
> > @@ -0,0 +1,218 @@
> > +// 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_REF_USE_PAD    BIT(9)
> > +
> > +struct imx8_pcie_phy {
> > +       u32                     refclk_pad_mode;
> > +       void __iomem            *base;
> > +       struct clk              *clk;
> > +       struct phy              *phy;
> > +       struct regmap           *iomuxc_gpr;
> > +       struct reset_control    *reset;
> > +};
> > +
> > +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);
> > +
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_REF_USE_PAD,
> > +                          imx8_phy->refclk_pad_mode == 1 ?
> 
> Hi Richard,
> 
> use the enumerated type for the comparison above for clarity:
> imx8_phy->refclk_pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT
> 
> Also, this is the configuration that makes my imx8mm-venice boards which do
> not use CLKREQ# hang while waiting for PHY. I am setting in my dt:
> &pcie_phy {
>         fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
>         clocks = <&clk IMX8MM_CLK_DUMMY>;
>         status = "okay";
> };
> 
> The NXP kernel woudl always set this bit to 0 which makes my board work.
> 
> The IMX8MMRM documentation appears incorrect here:
> IOMUXC_GPR_GPR14 bit 9: GPR_PCIE1_ PHY_I_AUX_ EN_OVERRIDE_ EN:
> {GPR_PCIE1_PHY_I_AUX_EN_OVERRIDE_EN,
> GPR_PCIE1_PHY_FUNC_I_AUX_EN}
>  2'b00 External Reference Clock I/O (for PLL) Disable
>  2'b01 External Reference Clock I/O (for PLL) Enable
>  2'b10 External Reference Clock I/O (for PLL) Disable
>  2'b11 External Reference Clock I/O (for PLL) output is controlled by CLKREQ#
> 
> How is it they define this as a single bit then give descriptions for
> 2 bits? Something is wrong here.
> 
[Richard Zhu] The descriptions are not correct, please ignore them.

> > +                          IMX8MM_GPR_PCIE_REF_USE_PAD : 0);
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_AUX_EN,
> > +                          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,
> > +                          IMX8MM_GPR_PCIE_SSC_EN, 0);
> > +
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_REF_CLK_SEL,
> > +                          imx8_phy->refclk_pad_mode == 1 ?
> 
> imx8_phy->refclk_pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT
[Richard Zhu] Got that. Thanks.

BR
Richard
> 
> Best regards,
> 
> Tim
> 
> > +                          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);
> > +
> > +
> > +       pad_mode = imx8_phy->refclk_pad_mode;
> > +       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(PCIE_PHY_TRSV_REG5_GEN1_DEEMP,
> > +              imx8_phy->base + PCIE_PHY_TRSV_REG5);
> > +       writel(PCIE_PHY_TRSV_REG6_GEN2_DEEMP,
> > +              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);
> > +
> > +       imx8_phy->clk = devm_clk_get(dev, "phy");
> > +       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
> >

WARNING: multiple messages have this Message-ID (diff)
From: Richard Zhu <hongxing.zhu@nxp.com>
To: "tharvey@gateworks.com" <tharvey@gateworks.com>
Cc: Lucas Stach <l.stach@pengutronix.de>,
	Kishon Vijay Abraham I <kishon@ti.com>,
	"vkoul@kernel.org" <vkoul@kernel.org>,
	Rob Herring <robh@kernel.org>,
	"galak@kernel.crashing.org" <galak@kernel.crashing.org>,
	Shawn Guo <shawnguo@kernel.org>,
	"linux-phy@lists.infradead.org" <linux-phy@lists.infradead.org>,
	Device Tree Mailing List <devicetree@vger.kernel.org>,
	Linux ARM Mailing List <linux-arm-kernel@lists.infradead.org>,
	open list <linux-kernel@vger.kernel.org>,
	Sascha Hauer <kernel@pengutronix.de>,
	dl-linux-imx <linux-imx@nxp.com>
Subject: RE: [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie standalone phy driver
Date: Fri, 22 Oct 2021 00:54:53 +0000	[thread overview]
Message-ID: <AS8PR04MB8676330408A6E18D35D003CB8C809@AS8PR04MB8676.eurprd04.prod.outlook.com> (raw)
In-Reply-To: <CAJ+vNU192BCiVQ=UwXgVCgCMA7tqcAQXQokyh5bO08a+SycOzQ@mail.gmail.com>

> -----Original Message-----
> From: Tim Harvey <tharvey@gateworks.com>
> Sent: Friday, October 22, 2021 12:00 AM
> To: Richard Zhu <hongxing.zhu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>; Kishon Vijay Abraham I
> <kishon@ti.com>; vkoul@kernel.org; Rob Herring <robh@kernel.org>;
> galak@kernel.crashing.org; Shawn Guo <shawnguo@kernel.org>;
> linux-phy@lists.infradead.org; Device Tree Mailing List
> <devicetree@vger.kernel.org>; Linux ARM Mailing List
> <linux-arm-kernel@lists.infradead.org>; open list
> <linux-kernel@vger.kernel.org>; Sascha Hauer <kernel@pengutronix.de>;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie
> standalone phy driver
> 
> On Tue, Oct 12, 2021 at 2:06 AM Richard Zhu <hongxing.zhu@nxp.com>
> wrote:
> >
> > Add the standalone i.MX8 PCIe PHY driver.
> > Some reset bits should be manipulated between PHY configurations and
> > status check(internal PLL is locked or not).
> > So, do the PHY configuration in the phy_calibrate().
> > And check the PHY is ready or not in the phy_init().
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > ---
> >  drivers/phy/freescale/Kconfig              |   9 +
> >  drivers/phy/freescale/Makefile             |   1 +
> >  drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 218
> > +++++++++++++++++++++
> >  3 files changed, 228 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..fb08e5242602
> > 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
> > +       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..317cf61bff37
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
> > @@ -0,0 +1,218 @@
> > +// 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_REF_USE_PAD    BIT(9)
> > +
> > +struct imx8_pcie_phy {
> > +       u32                     refclk_pad_mode;
> > +       void __iomem            *base;
> > +       struct clk              *clk;
> > +       struct phy              *phy;
> > +       struct regmap           *iomuxc_gpr;
> > +       struct reset_control    *reset;
> > +};
> > +
> > +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);
> > +
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_REF_USE_PAD,
> > +                          imx8_phy->refclk_pad_mode == 1 ?
> 
> Hi Richard,
> 
> use the enumerated type for the comparison above for clarity:
> imx8_phy->refclk_pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT
> 
> Also, this is the configuration that makes my imx8mm-venice boards which do
> not use CLKREQ# hang while waiting for PHY. I am setting in my dt:
> &pcie_phy {
>         fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
>         clocks = <&clk IMX8MM_CLK_DUMMY>;
>         status = "okay";
> };
> 
> The NXP kernel woudl always set this bit to 0 which makes my board work.
> 
> The IMX8MMRM documentation appears incorrect here:
> IOMUXC_GPR_GPR14 bit 9: GPR_PCIE1_ PHY_I_AUX_ EN_OVERRIDE_ EN:
> {GPR_PCIE1_PHY_I_AUX_EN_OVERRIDE_EN,
> GPR_PCIE1_PHY_FUNC_I_AUX_EN}
>  2'b00 External Reference Clock I/O (for PLL) Disable
>  2'b01 External Reference Clock I/O (for PLL) Enable
>  2'b10 External Reference Clock I/O (for PLL) Disable
>  2'b11 External Reference Clock I/O (for PLL) output is controlled by CLKREQ#
> 
> How is it they define this as a single bit then give descriptions for
> 2 bits? Something is wrong here.
> 
[Richard Zhu] The descriptions are not correct, please ignore them.

> > +                          IMX8MM_GPR_PCIE_REF_USE_PAD : 0);
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_AUX_EN,
> > +                          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,
> > +                          IMX8MM_GPR_PCIE_SSC_EN, 0);
> > +
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_REF_CLK_SEL,
> > +                          imx8_phy->refclk_pad_mode == 1 ?
> 
> imx8_phy->refclk_pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT
[Richard Zhu] Got that. Thanks.

BR
Richard
> 
> Best regards,
> 
> Tim
> 
> > +                          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);
> > +
> > +
> > +       pad_mode = imx8_phy->refclk_pad_mode;
> > +       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(PCIE_PHY_TRSV_REG5_GEN1_DEEMP,
> > +              imx8_phy->base + PCIE_PHY_TRSV_REG5);
> > +       writel(PCIE_PHY_TRSV_REG6_GEN2_DEEMP,
> > +              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);
> > +
> > +       imx8_phy->clk = devm_clk_get(dev, "phy");
> > +       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-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

WARNING: multiple messages have this Message-ID (diff)
From: Richard Zhu <hongxing.zhu@nxp.com>
To: "tharvey@gateworks.com" <tharvey@gateworks.com>
Cc: Lucas Stach <l.stach@pengutronix.de>,
	Kishon Vijay Abraham I <kishon@ti.com>,
	"vkoul@kernel.org" <vkoul@kernel.org>,
	Rob Herring <robh@kernel.org>,
	"galak@kernel.crashing.org" <galak@kernel.crashing.org>,
	Shawn Guo <shawnguo@kernel.org>,
	"linux-phy@lists.infradead.org" <linux-phy@lists.infradead.org>,
	Device Tree Mailing List <devicetree@vger.kernel.org>,
	Linux ARM Mailing List <linux-arm-kernel@lists.infradead.org>,
	open list <linux-kernel@vger.kernel.org>,
	Sascha Hauer <kernel@pengutronix.de>,
	dl-linux-imx <linux-imx@nxp.com>
Subject: RE: [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie standalone phy driver
Date: Fri, 22 Oct 2021 00:54:53 +0000	[thread overview]
Message-ID: <AS8PR04MB8676330408A6E18D35D003CB8C809@AS8PR04MB8676.eurprd04.prod.outlook.com> (raw)
In-Reply-To: <CAJ+vNU192BCiVQ=UwXgVCgCMA7tqcAQXQokyh5bO08a+SycOzQ@mail.gmail.com>

> -----Original Message-----
> From: Tim Harvey <tharvey@gateworks.com>
> Sent: Friday, October 22, 2021 12:00 AM
> To: Richard Zhu <hongxing.zhu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>; Kishon Vijay Abraham I
> <kishon@ti.com>; vkoul@kernel.org; Rob Herring <robh@kernel.org>;
> galak@kernel.crashing.org; Shawn Guo <shawnguo@kernel.org>;
> linux-phy@lists.infradead.org; Device Tree Mailing List
> <devicetree@vger.kernel.org>; Linux ARM Mailing List
> <linux-arm-kernel@lists.infradead.org>; open list
> <linux-kernel@vger.kernel.org>; Sascha Hauer <kernel@pengutronix.de>;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie
> standalone phy driver
> 
> On Tue, Oct 12, 2021 at 2:06 AM Richard Zhu <hongxing.zhu@nxp.com>
> wrote:
> >
> > Add the standalone i.MX8 PCIe PHY driver.
> > Some reset bits should be manipulated between PHY configurations and
> > status check(internal PLL is locked or not).
> > So, do the PHY configuration in the phy_calibrate().
> > And check the PHY is ready or not in the phy_init().
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > ---
> >  drivers/phy/freescale/Kconfig              |   9 +
> >  drivers/phy/freescale/Makefile             |   1 +
> >  drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 218
> > +++++++++++++++++++++
> >  3 files changed, 228 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..fb08e5242602
> > 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
> > +       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..317cf61bff37
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
> > @@ -0,0 +1,218 @@
> > +// 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_REF_USE_PAD    BIT(9)
> > +
> > +struct imx8_pcie_phy {
> > +       u32                     refclk_pad_mode;
> > +       void __iomem            *base;
> > +       struct clk              *clk;
> > +       struct phy              *phy;
> > +       struct regmap           *iomuxc_gpr;
> > +       struct reset_control    *reset;
> > +};
> > +
> > +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);
> > +
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_REF_USE_PAD,
> > +                          imx8_phy->refclk_pad_mode == 1 ?
> 
> Hi Richard,
> 
> use the enumerated type for the comparison above for clarity:
> imx8_phy->refclk_pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT
> 
> Also, this is the configuration that makes my imx8mm-venice boards which do
> not use CLKREQ# hang while waiting for PHY. I am setting in my dt:
> &pcie_phy {
>         fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
>         clocks = <&clk IMX8MM_CLK_DUMMY>;
>         status = "okay";
> };
> 
> The NXP kernel woudl always set this bit to 0 which makes my board work.
> 
> The IMX8MMRM documentation appears incorrect here:
> IOMUXC_GPR_GPR14 bit 9: GPR_PCIE1_ PHY_I_AUX_ EN_OVERRIDE_ EN:
> {GPR_PCIE1_PHY_I_AUX_EN_OVERRIDE_EN,
> GPR_PCIE1_PHY_FUNC_I_AUX_EN}
>  2'b00 External Reference Clock I/O (for PLL) Disable
>  2'b01 External Reference Clock I/O (for PLL) Enable
>  2'b10 External Reference Clock I/O (for PLL) Disable
>  2'b11 External Reference Clock I/O (for PLL) output is controlled by CLKREQ#
> 
> How is it they define this as a single bit then give descriptions for
> 2 bits? Something is wrong here.
> 
[Richard Zhu] The descriptions are not correct, please ignore them.

> > +                          IMX8MM_GPR_PCIE_REF_USE_PAD : 0);
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_AUX_EN,
> > +                          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,
> > +                          IMX8MM_GPR_PCIE_SSC_EN, 0);
> > +
> > +       regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
> > +                          IMX8MM_GPR_PCIE_REF_CLK_SEL,
> > +                          imx8_phy->refclk_pad_mode == 1 ?
> 
> imx8_phy->refclk_pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT
[Richard Zhu] Got that. Thanks.

BR
Richard
> 
> Best regards,
> 
> Tim
> 
> > +                          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);
> > +
> > +
> > +       pad_mode = imx8_phy->refclk_pad_mode;
> > +       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(PCIE_PHY_TRSV_REG5_GEN1_DEEMP,
> > +              imx8_phy->base + PCIE_PHY_TRSV_REG5);
> > +       writel(PCIE_PHY_TRSV_REG6_GEN2_DEEMP,
> > +              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);
> > +
> > +       imx8_phy->clk = devm_clk_get(dev, "phy");
> > +       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

  reply	other threads:[~2021-10-22  0:54 UTC|newest]

Thread overview: 144+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-12  8:41 [PATCH v3 0/9] add the imx8m pcie phy driver and imx8mm pcie support Richard Zhu
2021-10-12  8:41 ` Richard Zhu
2021-10-12  8:41 ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 1/9] dt-bindings: phy: phy-imx8-pcie: Add binding for the pad modes of imx8 pcie phy Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 2/9] dt-bindings: phy: add imx8 pcie phy driver support Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12 13:18   ` Rob Herring
2021-10-12 13:18     ` Rob Herring
2021-10-12 13:18     ` Rob Herring
2021-10-12 23:46     ` Richard Zhu
2021-10-12 23:46       ` Richard Zhu
2021-10-12 23:46       ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 3/9] arm64: dts: imx8mm: add the pcie phy support Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-15 18:30   ` Lucas Stach
2021-10-15 18:30     ` Lucas Stach
2021-10-15 18:30     ` Lucas Stach
2021-10-22  1:57     ` Richard Zhu
2021-10-22  1:57       ` Richard Zhu
2021-10-22  1:57       ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 4/9] arm64: dts: imx8mm-evk: " Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-15 18:32   ` Lucas Stach
2021-10-15 18:32     ` Lucas Stach
2021-10-15 18:32     ` Lucas Stach
2021-10-22  1:58     ` Richard Zhu
2021-10-22  1:58       ` Richard Zhu
2021-10-22  1:58       ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 5/9] phy: freescale: pcie: initialize the imx8 pcie standalone phy driver Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-15 18:55   ` Lucas Stach
2021-10-15 18:55     ` Lucas Stach
2021-10-15 18:55     ` Lucas Stach
2021-10-22  4:30     ` Richard Zhu
2021-10-22  4:30       ` Richard Zhu
2021-10-22  4:30       ` Richard Zhu
2021-10-21 16:00   ` Tim Harvey
2021-10-21 16:00     ` Tim Harvey
2021-10-21 16:00     ` Tim Harvey
2021-10-22  0:54     ` Richard Zhu [this message]
2021-10-22  0:54       ` Richard Zhu
2021-10-22  0:54       ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 6/9] dt-bindings: imx6q-pcie: Add PHY phandles and name properties Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-18 19:18   ` Rob Herring
2021-10-18 19:18     ` Rob Herring
2021-10-18 19:18     ` Rob Herring
2021-10-22  2:04     ` Richard Zhu
2021-10-22  2:04       ` Richard Zhu
2021-10-22  2:04       ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 7/9] arm64: dts: imx8mm: add the pcie support Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 8/9] arm64: dts: imx8mm-evk: add the pcie support on imx8mm evk board Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-15 19:03   ` Lucas Stach
2021-10-15 19:03     ` Lucas Stach
2021-10-15 19:03     ` Lucas Stach
2021-10-22  2:07     ` Richard Zhu
2021-10-22  2:07       ` Richard Zhu
2021-10-22  2:07       ` Richard Zhu
2021-10-12  8:41 ` [PATCH v3 9/9] PCI: imx: add the imx8mm pcie support Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-12  8:41   ` Richard Zhu
2021-10-13 12:45   ` Matthias Schiffer
2021-10-13 12:45     ` Matthias Schiffer
2021-10-13 12:45     ` Matthias Schiffer
2021-10-14  1:20     ` Richard Zhu
2021-10-14  1:20       ` Richard Zhu
2021-10-14  1:20       ` Richard Zhu
2021-10-15 19:00   ` Lucas Stach
2021-10-15 19:00     ` Lucas Stach
2021-10-15 19:00     ` Lucas Stach
2021-10-22  2:06     ` Richard Zhu
2021-10-22  2:06       ` Richard Zhu
2021-10-22  2:06       ` Richard Zhu
2021-10-15 19:58 ` [PATCH v3 0/9] add the imx8m pcie phy driver and " Tim Harvey
2021-10-15 19:58   ` Tim Harvey
2021-10-15 19:58   ` Tim Harvey
2021-10-19  2:10   ` Richard Zhu
2021-10-19  2:10     ` Richard Zhu
2021-10-19  2:10     ` Richard Zhu
2021-10-19 15:52     ` Tim Harvey
2021-10-19 15:52       ` Tim Harvey
2021-10-19 15:52       ` Tim Harvey
2021-10-20  2:10       ` Richard Zhu
2021-10-20  2:10         ` Richard Zhu
2021-10-20  2:10         ` Richard Zhu
2021-10-20 21:22         ` Tim Harvey
2021-10-20 21:22           ` Tim Harvey
2021-10-20 21:22           ` Tim Harvey
2021-10-21  3:32           ` Richard Zhu
2021-10-21  3:32             ` Richard Zhu
2021-10-21  3:32             ` Richard Zhu
2021-10-21 16:25             ` Tim Harvey
2021-10-21 16:25               ` Tim Harvey
2021-10-21 16:25               ` Tim Harvey
2021-10-22  0:43               ` Richard Zhu
2021-10-22  0:43                 ` Richard Zhu
2021-10-22  0:43                 ` Richard Zhu
2021-10-22 15:59                 ` Tim Harvey
2021-10-22 15:59                   ` Tim Harvey
2021-10-22 15:59                   ` Tim Harvey
2021-10-22 16:55                   ` Tim Harvey
2021-10-22 16:55                     ` Tim Harvey
2021-10-22 16:55                     ` Tim Harvey
2021-10-25  2:12                     ` Richard Zhu
2021-10-25  2:12                       ` Richard Zhu
2021-10-25  2:12                       ` Richard Zhu
2021-10-25  7:23                       ` Richard Zhu
2021-10-25  7:23                         ` Richard Zhu
2021-10-25  7:23                         ` Richard Zhu
2021-10-25 17:14                         ` Tim Harvey
2021-10-25 17:14                           ` Tim Harvey
2021-10-25 17:14                           ` Tim Harvey
2021-10-26  5:41                           ` Richard Zhu
2021-10-26  5:41                             ` Richard Zhu
2021-10-26  5:41                             ` Richard Zhu
2021-10-26 16:06                             ` Tim Harvey
2021-10-26 16:06                               ` Tim Harvey
2021-10-26 16:06                               ` Tim Harvey
2021-10-27  6:18                               ` Richard Zhu
2021-10-27  6:18                                 ` Richard Zhu
2021-10-27  6:18                                 ` Richard Zhu
2021-10-27 15:40                                 ` Tim Harvey
2021-10-27 15:40                                   ` Tim Harvey
2021-10-27 15:40                                   ` Tim Harvey
2021-10-28  1:51                                   ` Richard Zhu
2021-10-28  1:51                                     ` Richard Zhu
2021-10-28  1:51                                     ` Richard Zhu
2021-10-26 15:56 ` Marcel Ziswiler
2021-10-26 15:56   ` Marcel Ziswiler
2021-10-26 15:56   ` Marcel Ziswiler
2021-10-27  1:39   ` Richard Zhu
2021-10-27  1:39     ` Richard Zhu
2021-10-27  1:39     ` Richard Zhu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AS8PR04MB8676330408A6E18D35D003CB8C809@AS8PR04MB8676.eurprd04.prod.outlook.com \
    --to=hongxing.zhu@nxp.com \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@kernel.crashing.org \
    --cc=kernel@pengutronix.de \
    --cc=kishon@ti.com \
    --cc=l.stach@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=robh@kernel.org \
    --cc=shawnguo@kernel.org \
    --cc=tharvey@gateworks.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.