Message ID | 20240226080433.3307154-6-sumit.garg@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | imx8mp: Enable PCIe/NVMe support | expand |
On 2/26/24 9:04 AM, Sumit Garg wrote: > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > PHY initialization moved to this standalone PHY driver. > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. Commit ID , see previous comments. [...] > +static int imx8_pcie_phy_probe(struct udevice *dev) > +{ > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(dev); > + ofnode gpr; > + int ret = 0; > + > + imx8_phy->drvdata = (void *)dev_get_driver_data(dev); > + imx8_phy->base = dev_read_addr(dev); > + if (!imx8_phy->base) > + return -EINVAL; > + > + /* get PHY refclk pad mode */ > + dev_read_u32(dev, "fsl,refclk-pad-mode", &imx8_phy->refclk_pad_mode); > + > + if (dev_read_u32(dev, "fsl,tx-deemph-gen1", &imx8_phy->tx_deemph_gen1)) > + imx8_phy->tx_deemph_gen1 = 0; Use dev_read_u32_default() and you won't need the if (...) > + if (dev_read_u32(dev, "fsl,tx-deemph-gen2", &imx8_phy->tx_deemph_gen2)) > + imx8_phy->tx_deemph_gen2 = 0; > + > + if (dev_read_bool(dev, "fsl,clkreq-unsupported")) > + imx8_phy->clkreq_unused = true; > + else > + imx8_phy->clkreq_unused = false; > + > + /* Grab GPR config register range */ > + gpr = ofnode_by_compatible(ofnode_null(), imx8_phy->drvdata->gpr); > + if (ofnode_equal(gpr, ofnode_null())) { > + dev_err(dev, "unable to find GPR node\n"); > + return -ENODEV; > + } > + > + imx8_phy->iomuxc_gpr = syscon_node_to_regmap(gpr); > + if (IS_ERR(imx8_phy->iomuxc_gpr)) { > + dev_err(dev, "unable to find iomuxc registers\n"); > + return PTR_ERR(imx8_phy->iomuxc_gpr); > + } > + > + ret = clk_get_by_name(dev, "ref", &imx8_phy->hsio_clk); > + if (ret) { > + dev_err(dev, "Failed to get PCIEPHY ref clock\n"); > + return ret; > + } > + > + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); > + if (ret) { > + dev_err(dev, "Failed to get PCIEPHY reset control\n"); > + return ret; > + } Some clk_put() and co. fail path is missing here. Also .remove is missing .
On Mon, 26 Feb 2024 at 14:24, Marek Vasut <marex@denx.de> wrote: > > On 2/26/24 9:04 AM, Sumit Garg wrote: > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > PHY initialization moved to this standalone PHY driver. > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > Commit ID , see previous comments. > > [...] > > > +static int imx8_pcie_phy_probe(struct udevice *dev) > > +{ > > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(dev); > > + ofnode gpr; > > + int ret = 0; > > + > > + imx8_phy->drvdata = (void *)dev_get_driver_data(dev); > > + imx8_phy->base = dev_read_addr(dev); > > + if (!imx8_phy->base) > > + return -EINVAL; > > + > > + /* get PHY refclk pad mode */ > > + dev_read_u32(dev, "fsl,refclk-pad-mode", &imx8_phy->refclk_pad_mode); > > + > > + if (dev_read_u32(dev, "fsl,tx-deemph-gen1", &imx8_phy->tx_deemph_gen1)) > > + imx8_phy->tx_deemph_gen1 = 0; > > Use dev_read_u32_default() and you won't need the if (...) > Ack. > > + if (dev_read_u32(dev, "fsl,tx-deemph-gen2", &imx8_phy->tx_deemph_gen2)) > > + imx8_phy->tx_deemph_gen2 = 0; > > + > > + if (dev_read_bool(dev, "fsl,clkreq-unsupported")) > > + imx8_phy->clkreq_unused = true; > > + else > > + imx8_phy->clkreq_unused = false; > > + > > + /* Grab GPR config register range */ > > + gpr = ofnode_by_compatible(ofnode_null(), imx8_phy->drvdata->gpr); > > + if (ofnode_equal(gpr, ofnode_null())) { > > + dev_err(dev, "unable to find GPR node\n"); > > + return -ENODEV; > > + } > > + > > + imx8_phy->iomuxc_gpr = syscon_node_to_regmap(gpr); > > + if (IS_ERR(imx8_phy->iomuxc_gpr)) { > > + dev_err(dev, "unable to find iomuxc registers\n"); > > + return PTR_ERR(imx8_phy->iomuxc_gpr); > > + } > > + > > + ret = clk_get_by_name(dev, "ref", &imx8_phy->hsio_clk); > > + if (ret) { > > + dev_err(dev, "Failed to get PCIEPHY ref clock\n"); > > + return ret; > > + } > > + > > + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); > > + if (ret) { > > + dev_err(dev, "Failed to get PCIEPHY reset control\n"); > > + return ret; > > + } > > Some clk_put() and co. fail path is missing here. Ditto for clk_put() not being available. However, I can add the fail path for the other reset. > Also .remove is missing . Sure, I will add that to release resets. -Sumit
On 2/26/24 1:50 PM, Sumit Garg wrote: [...] >>> + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); >>> + if (ret) { >>> + dev_err(dev, "Failed to get PCIEPHY reset control\n"); >>> + return ret; >>> + } >> >> Some clk_put() and co. fail path is missing here. > > Ditto for clk_put() not being available. However, I can add the fail > path for the other reset. Oh, maybe reset_free() and clk_release*() then ?
On Mon, 26 Feb 2024 at 18:34, Marek Vasut <marex@denx.de> wrote: > > On 2/26/24 1:50 PM, Sumit Garg wrote: > > [...] > > >>> + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); > >>> + if (ret) { > >>> + dev_err(dev, "Failed to get PCIEPHY reset control\n"); > >>> + return ret; > >>> + } > >> > >> Some clk_put() and co. fail path is missing here. > > > > Ditto for clk_put() not being available. However, I can add the fail > > path for the other reset. > > Oh, maybe reset_free() and clk_release*() then ? AFAICS, clk_release*() APIs are internally only a wrapper around clk_disable(). So actually those APIs don't seem to do anything useful in the fail path here. However, I will let clock tree maintainers chime in here if they plan to remove clk_release*() APIs on similar lines as with clk_free(). -Sumit
On 2/26/24 2:30 PM, Sumit Garg wrote: > On Mon, 26 Feb 2024 at 18:34, Marek Vasut <marex@denx.de> wrote: >> >> On 2/26/24 1:50 PM, Sumit Garg wrote: >> >> [...] >> >>>>> + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); >>>>> + if (ret) { >>>>> + dev_err(dev, "Failed to get PCIEPHY reset control\n"); >>>>> + return ret; >>>>> + } >>>> >>>> Some clk_put() and co. fail path is missing here. >>> >>> Ditto for clk_put() not being available. However, I can add the fail >>> path for the other reset. >> >> Oh, maybe reset_free() and clk_release*() then ? > > AFAICS, clk_release*() APIs are internally only a wrapper around > clk_disable(). So actually those APIs don't seem to do anything useful > in the fail path here. > > However, I will let clock tree maintainers chime in here if they plan > to remove clk_release*() APIs on similar lines as with clk_free(). Maybe they should be in place so in case in the future clock should be torn down, it wouldn't be necessary to fix so many drivers ?
On Mon, 26 Feb 2024 at 19:06, Marek Vasut <marex@denx.de> wrote: > > On 2/26/24 2:30 PM, Sumit Garg wrote: > > On Mon, 26 Feb 2024 at 18:34, Marek Vasut <marex@denx.de> wrote: > >> > >> On 2/26/24 1:50 PM, Sumit Garg wrote: > >> > >> [...] > >> > >>>>> + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); > >>>>> + if (ret) { > >>>>> + dev_err(dev, "Failed to get PCIEPHY reset control\n"); > >>>>> + return ret; > >>>>> + } > >>>> > >>>> Some clk_put() and co. fail path is missing here. > >>> > >>> Ditto for clk_put() not being available. However, I can add the fail > >>> path for the other reset. > >> > >> Oh, maybe reset_free() and clk_release*() then ? > > > > AFAICS, clk_release*() APIs are internally only a wrapper around > > clk_disable(). So actually those APIs don't seem to do anything useful > > in the fail path here. > > > > However, I will let clock tree maintainers chime in here if they plan > > to remove clk_release*() APIs on similar lines as with clk_free(). > > Maybe they should be in place so in case in the future clock should be > torn down, it wouldn't be necessary to fix so many drivers ? See the following comparison: $ git grep -nr clk_get_by_name | wc -l 229 $ git grep -nr clk_release | wc -l 59 There are already many driver instances which don't use clk_release*() APIs. -Sumit
On 2/26/24 2:49 PM, Sumit Garg wrote: > On Mon, 26 Feb 2024 at 19:06, Marek Vasut <marex@denx.de> wrote: >> >> On 2/26/24 2:30 PM, Sumit Garg wrote: >>> On Mon, 26 Feb 2024 at 18:34, Marek Vasut <marex@denx.de> wrote: >>>> >>>> On 2/26/24 1:50 PM, Sumit Garg wrote: >>>> >>>> [...] >>>> >>>>>>> + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); >>>>>>> + if (ret) { >>>>>>> + dev_err(dev, "Failed to get PCIEPHY reset control\n"); >>>>>>> + return ret; >>>>>>> + } >>>>>> >>>>>> Some clk_put() and co. fail path is missing here. >>>>> >>>>> Ditto for clk_put() not being available. However, I can add the fail >>>>> path for the other reset. >>>> >>>> Oh, maybe reset_free() and clk_release*() then ? >>> >>> AFAICS, clk_release*() APIs are internally only a wrapper around >>> clk_disable(). So actually those APIs don't seem to do anything useful >>> in the fail path here. >>> >>> However, I will let clock tree maintainers chime in here if they plan >>> to remove clk_release*() APIs on similar lines as with clk_free(). >> >> Maybe they should be in place so in case in the future clock should be >> torn down, it wouldn't be necessary to fix so many drivers ? > > See the following comparison: > > $ git grep -nr clk_get_by_name | wc -l > 229 > > $ git grep -nr clk_release | wc -l > 59 > > There are already many driver instances which don't use clk_release*() APIs. And that's a good argument to make the situation worse ?
On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > PHY initialization moved to this standalone PHY driver. > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. I have a PCIe device that works just fine in Linux. I have applied your series an enabled the same config options as you did along with some others to resolve some build issues. Any ideas how to address: nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on pcie-phy@32f00000: -110. My PHY node looks like this &pcie_phy { fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; clocks = <&pcie0_refclk>; clock-names = "ref"; status = "okay"; }; The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk dump shows it to be: 100000000 0 |-- clock-pcie > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > --- > drivers/phy/Kconfig | 9 ++ > drivers/phy/Makefile | 1 + > drivers/phy/phy-imx8m-pcie.c | 269 +++++++++++++++++++++++++++++++++++ > 3 files changed, 279 insertions(+) > create mode 100644 drivers/phy/phy-imx8m-pcie.c > > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig > index 60138beca498..110ec8f5008d 100644 > --- a/drivers/phy/Kconfig > +++ b/drivers/phy/Kconfig > @@ -284,6 +284,15 @@ config PHY_IMX8MQ_USB > help > Support the USB3.0 PHY in NXP i.MX8MQ or i.MX8MP SoC > > +config PHY_IMX8M_PCIE > + bool "NXP i.MX8MM/i.MX8MP PCIe PHY Driver" > + depends on PHY > + depends on IMX8MM || IMX8MP This should also depend on SYSCON and REGMAP to prevent build errors. > + help > + Support the PCIe PHY in NXP i.MX8MM or i.MX8MP SoC > + > + This PHY is found on i.MX8M devices supporting PCIe. > + > config PHY_XILINX_ZYNQMP > tristate "Xilinx ZynqMP PHY driver" > depends on PHY && ARCH_ZYNQMP > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile > index 2e8723186c05..7a2b764492be 100644 > --- a/drivers/phy/Makefile > +++ b/drivers/phy/Makefile > @@ -38,6 +38,7 @@ obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o > obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o > obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o > obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o > +obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o > obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o > obj-y += cadence/ > obj-y += ti/ > diff --git a/drivers/phy/phy-imx8m-pcie.c b/drivers/phy/phy-imx8m-pcie.c > new file mode 100644 > index 000000000000..e09a7ac97235 > --- /dev/null > +++ b/drivers/phy/phy-imx8m-pcie.c > @@ -0,0 +1,269 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2024 Linaro Ltd. > + * > + * Derived from Linux counterpart driver > + */ > + > +#include <asm/io.h> > +#include <clk.h> > +#include <dm.h> > +#include <dm/device_compat.h> > +#include <generic-phy.h> > +#include <linux/bitfield.h> > +#include <linux/clk-provider.h> > +#include <linux/iopoll.h> > +#include <syscon.h> > +#include <regmap.h> > +#include <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_REG075 0x1D4 > +#define ANA_PLL_DONE 0x3 > +#define PCIE_PHY_TRSV_REG5 0x414 > +#define PCIE_PHY_TRSV_REG6 0x418 > + > +#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) > + > +#define IOMUXC_GPR14_OFFSET 0x38 > + > +enum imx8_pcie_phy_type { > + IMX8MM, > + IMX8MP, > +}; > + > +struct imx8_pcie_phy_drvdata { > + const char *gpr; > + enum imx8_pcie_phy_type variant; > +}; > + > +struct imx8_pcie_phy { > + ulong base; > + struct clk hsio_clk; > + struct regmap *iomuxc_gpr; > + struct reset_ctl perst; > + struct reset_ctl reset; > + u32 refclk_pad_mode; > + u32 tx_deemph_gen1; > + u32 tx_deemph_gen2; > + bool clkreq_unused; > + const struct imx8_pcie_phy_drvdata *drvdata; > +}; > + > +static int imx8_pcie_phy_power_on(struct phy *phy) > +{ > + int ret; > + u32 val, pad_mode; > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); > + > + pad_mode = imx8_phy->refclk_pad_mode; > + switch (imx8_phy->drvdata->variant) { > + case IMX8MM: > + reset_assert(&imx8_phy->reset); > + > + /* Tune PHY de-emphasis setting to pass PCIe compliance. */ > + if (imx8_phy->tx_deemph_gen1) > + writel(imx8_phy->tx_deemph_gen1, > + imx8_phy->base + PCIE_PHY_TRSV_REG5); > + if (imx8_phy->tx_deemph_gen2) > + writel(imx8_phy->tx_deemph_gen2, > + imx8_phy->base + PCIE_PHY_TRSV_REG6); > + break; > + case IMX8MP: /* Do nothing. */ > + break; > + } > + > + if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT || > + pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) { > + /* 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 { > + /* 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); > + } > + > + if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT || > + pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) { > + /* Source clock from SoC internal PLL */ > + 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); > + } > + > + /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */ > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > + 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_OFFSET, > + IMX8MM_GPR_PCIE_AUX_EN, > + IMX8MM_GPR_PCIE_AUX_EN); > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > + IMX8MM_GPR_PCIE_POWER_OFF, 0); > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > + IMX8MM_GPR_PCIE_SSC_EN, 0); > + > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > + 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); > + udelay(200); > + > + /* Do the PHY common block reset */ > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > + IMX8MM_GPR_PCIE_CMN_RST, > + IMX8MM_GPR_PCIE_CMN_RST); > + > + switch (imx8_phy->drvdata->variant) { > + case IMX8MP: > + reset_deassert(&imx8_phy->perst); > + fallthrough; > + case IMX8MM: > + reset_deassert(&imx8_phy->reset); > + udelay(500); > + break; > + } > + > + /* Polling to check the phy is ready or not. */ > + ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075, > + val, val == ANA_PLL_DONE, 20000); > + return ret; > +} > + > +static int imx8_pcie_phy_init(struct phy *phy) > +{ > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); > + > + return clk_enable(&imx8_phy->hsio_clk); > +} > + > +static int imx8_pcie_phy_exit(struct phy *phy) > +{ > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); > + > + return clk_disable(&imx8_phy->hsio_clk); > +} > + > +static const struct phy_ops imx8_pcie_phy_ops = { > + .init = imx8_pcie_phy_init, > + .exit = imx8_pcie_phy_exit, > + .power_on = imx8_pcie_phy_power_on, > +}; > + > +static const struct imx8_pcie_phy_drvdata imx8mm_drvdata = { > + .gpr = "fsl,imx8mm-iomuxc-gpr", > + .variant = IMX8MM, > +}; > + > +static const struct imx8_pcie_phy_drvdata imx8mp_drvdata = { > + .gpr = "fsl,imx8mp-iomuxc-gpr", > + .variant = IMX8MP, > +}; > + > +static const struct udevice_id imx8_pcie_phy_of_match[] = { > + {.compatible = "fsl,imx8mm-pcie-phy", .data = (ulong)&imx8mm_drvdata, }, > + {.compatible = "fsl,imx8mp-pcie-phy", .data = (ulong)&imx8mp_drvdata, }, > + { }, > +}; > + > +static int imx8_pcie_phy_probe(struct udevice *dev) > +{ > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(dev); > + ofnode gpr; > + int ret = 0; > + > + imx8_phy->drvdata = (void *)dev_get_driver_data(dev); > + imx8_phy->base = dev_read_addr(dev); > + if (!imx8_phy->base) > + return -EINVAL; > + > + /* get PHY refclk pad mode */ > + dev_read_u32(dev, "fsl,refclk-pad-mode", &imx8_phy->refclk_pad_mode); > + > + if (dev_read_u32(dev, "fsl,tx-deemph-gen1", &imx8_phy->tx_deemph_gen1)) > + imx8_phy->tx_deemph_gen1 = 0; > + > + if (dev_read_u32(dev, "fsl,tx-deemph-gen2", &imx8_phy->tx_deemph_gen2)) > + imx8_phy->tx_deemph_gen2 = 0; > + > + if (dev_read_bool(dev, "fsl,clkreq-unsupported")) > + imx8_phy->clkreq_unused = true; > + else > + imx8_phy->clkreq_unused = false; > + > + /* Grab GPR config register range */ > + gpr = ofnode_by_compatible(ofnode_null(), imx8_phy->drvdata->gpr); > + if (ofnode_equal(gpr, ofnode_null())) { > + dev_err(dev, "unable to find GPR node\n"); > + return -ENODEV; > + } > + > + imx8_phy->iomuxc_gpr = syscon_node_to_regmap(gpr); > + if (IS_ERR(imx8_phy->iomuxc_gpr)) { > + dev_err(dev, "unable to find iomuxc registers\n"); > + return PTR_ERR(imx8_phy->iomuxc_gpr); > + } > + > + ret = clk_get_by_name(dev, "ref", &imx8_phy->hsio_clk); > + if (ret) { > + dev_err(dev, "Failed to get PCIEPHY ref clock\n"); > + return ret; > + } > + > + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); > + if (ret) { > + dev_err(dev, "Failed to get PCIEPHY reset control\n"); > + return ret; > + } > + > + if (imx8_phy->drvdata->variant == IMX8MP) { > + ret = reset_get_by_name(dev, "perst", &imx8_phy->perst); > + if (ret) { > + dev_err(dev, > + "Failed to get PCIEPHY PHY PERST control\n"); > + return ret; > + } > + } > + > + return 0; > +} > + > +U_BOOT_DRIVER(nxp_imx8_pcie_phy) = { > + .name = "nxp_imx8_pcie_phy", > + .id = UCLASS_PHY, > + .of_match = imx8_pcie_phy_of_match, > + .probe = imx8_pcie_phy_probe, > + .ops = &imx8_pcie_phy_ops, > + .priv_auto = sizeof(struct imx8_pcie_phy), > +}; > -- > 2.34.1 >
Hi Adam, On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > PHY initialization moved to this standalone PHY driver. > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > I have a PCIe device that works just fine in Linux. I have applied > your series an enabled the same config options as you did along with > some others to resolve some build issues. > > Any ideas how to address: > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > pcie-phy@32f00000: -110. > > My PHY node looks like this > > &pcie_phy { > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > clocks = <&pcie0_refclk>; > clock-names = "ref"; > status = "okay"; > }; > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > dump shows it to be: > > 100000000 0 |-- clock-pcie > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator required for EVK board via following patch: diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c index 7856823c9188..32fd2cb05d4b 100644 --- a/drivers/pci/pcie_dw_imx.c +++ b/drivers/pci/pcie_dw_imx.c @@ -17,6 +17,7 @@ #include <linux/iopoll.h> #include <log.h> #include <pci.h> +#include <power/regulator.h> #include <regmap.h> #include <reset.h> #include <syscon.h> @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) struct pci_controller *hose = dev_get_uclass_priv(ctlr); int ret; + regulator_autoset_by_name("MPCIE_3V3", NULL); + ret = imx_pcie_assert_core_reset(priv); if (ret) { dev_err(dev, "failed to assert core reset\n"); > > > > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > > --- > > drivers/phy/Kconfig | 9 ++ > > drivers/phy/Makefile | 1 + > > drivers/phy/phy-imx8m-pcie.c | 269 +++++++++++++++++++++++++++++++++++ > > 3 files changed, 279 insertions(+) > > create mode 100644 drivers/phy/phy-imx8m-pcie.c > > > > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig > > index 60138beca498..110ec8f5008d 100644 > > --- a/drivers/phy/Kconfig > > +++ b/drivers/phy/Kconfig > > @@ -284,6 +284,15 @@ config PHY_IMX8MQ_USB > > help > > Support the USB3.0 PHY in NXP i.MX8MQ or i.MX8MP SoC > > > > +config PHY_IMX8M_PCIE > > + bool "NXP i.MX8MM/i.MX8MP PCIe PHY Driver" > > + depends on PHY > > + depends on IMX8MM || IMX8MP > > This should also depend on SYSCON and REGMAP to prevent build errors. > Ack, I will add those. -Sumit > > + help > > + Support the PCIe PHY in NXP i.MX8MM or i.MX8MP SoC > > + > > + This PHY is found on i.MX8M devices supporting PCIe. > > + > > config PHY_XILINX_ZYNQMP > > tristate "Xilinx ZynqMP PHY driver" > > depends on PHY && ARCH_ZYNQMP > > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile > > index 2e8723186c05..7a2b764492be 100644 > > --- a/drivers/phy/Makefile > > +++ b/drivers/phy/Makefile > > @@ -38,6 +38,7 @@ obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o > > obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o > > obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o > > obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o > > +obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o > > obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o > > obj-y += cadence/ > > obj-y += ti/ > > diff --git a/drivers/phy/phy-imx8m-pcie.c b/drivers/phy/phy-imx8m-pcie.c > > new file mode 100644 > > index 000000000000..e09a7ac97235 > > --- /dev/null > > +++ b/drivers/phy/phy-imx8m-pcie.c > > @@ -0,0 +1,269 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright 2024 Linaro Ltd. > > + * > > + * Derived from Linux counterpart driver > > + */ > > + > > +#include <asm/io.h> > > +#include <clk.h> > > +#include <dm.h> > > +#include <dm/device_compat.h> > > +#include <generic-phy.h> > > +#include <linux/bitfield.h> > > +#include <linux/clk-provider.h> > > +#include <linux/iopoll.h> > > +#include <syscon.h> > > +#include <regmap.h> > > +#include <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_REG075 0x1D4 > > +#define ANA_PLL_DONE 0x3 > > +#define PCIE_PHY_TRSV_REG5 0x414 > > +#define PCIE_PHY_TRSV_REG6 0x418 > > + > > +#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) > > + > > +#define IOMUXC_GPR14_OFFSET 0x38 > > + > > +enum imx8_pcie_phy_type { > > + IMX8MM, > > + IMX8MP, > > +}; > > + > > +struct imx8_pcie_phy_drvdata { > > + const char *gpr; > > + enum imx8_pcie_phy_type variant; > > +}; > > + > > +struct imx8_pcie_phy { > > + ulong base; > > + struct clk hsio_clk; > > + struct regmap *iomuxc_gpr; > > + struct reset_ctl perst; > > + struct reset_ctl reset; > > + u32 refclk_pad_mode; > > + u32 tx_deemph_gen1; > > + u32 tx_deemph_gen2; > > + bool clkreq_unused; > > + const struct imx8_pcie_phy_drvdata *drvdata; > > +}; > > + > > +static int imx8_pcie_phy_power_on(struct phy *phy) > > +{ > > + int ret; > > + u32 val, pad_mode; > > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); > > + > > + pad_mode = imx8_phy->refclk_pad_mode; > > + switch (imx8_phy->drvdata->variant) { > > + case IMX8MM: > > + reset_assert(&imx8_phy->reset); > > + > > + /* Tune PHY de-emphasis setting to pass PCIe compliance. */ > > + if (imx8_phy->tx_deemph_gen1) > > + writel(imx8_phy->tx_deemph_gen1, > > + imx8_phy->base + PCIE_PHY_TRSV_REG5); > > + if (imx8_phy->tx_deemph_gen2) > > + writel(imx8_phy->tx_deemph_gen2, > > + imx8_phy->base + PCIE_PHY_TRSV_REG6); > > + break; > > + case IMX8MP: /* Do nothing. */ > > + break; > > + } > > + > > + if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT || > > + pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) { > > + /* 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 { > > + /* 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); > > + } > > + > > + if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT || > > + pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) { > > + /* Source clock from SoC internal PLL */ > > + 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); > > + } > > + > > + /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */ > > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > > + 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_OFFSET, > > + IMX8MM_GPR_PCIE_AUX_EN, > > + IMX8MM_GPR_PCIE_AUX_EN); > > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > > + IMX8MM_GPR_PCIE_POWER_OFF, 0); > > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > > + IMX8MM_GPR_PCIE_SSC_EN, 0); > > + > > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > > + 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); > > + udelay(200); > > + > > + /* Do the PHY common block reset */ > > + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, > > + IMX8MM_GPR_PCIE_CMN_RST, > > + IMX8MM_GPR_PCIE_CMN_RST); > > + > > + switch (imx8_phy->drvdata->variant) { > > + case IMX8MP: > > + reset_deassert(&imx8_phy->perst); > > + fallthrough; > > + case IMX8MM: > > + reset_deassert(&imx8_phy->reset); > > + udelay(500); > > + break; > > + } > > + > > + /* Polling to check the phy is ready or not. */ > > + ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075, > > + val, val == ANA_PLL_DONE, 20000); > > + return ret; > > +} > > + > > +static int imx8_pcie_phy_init(struct phy *phy) > > +{ > > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); > > + > > + return clk_enable(&imx8_phy->hsio_clk); > > +} > > + > > +static int imx8_pcie_phy_exit(struct phy *phy) > > +{ > > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); > > + > > + return clk_disable(&imx8_phy->hsio_clk); > > +} > > + > > +static const struct phy_ops imx8_pcie_phy_ops = { > > + .init = imx8_pcie_phy_init, > > + .exit = imx8_pcie_phy_exit, > > + .power_on = imx8_pcie_phy_power_on, > > +}; > > + > > +static const struct imx8_pcie_phy_drvdata imx8mm_drvdata = { > > + .gpr = "fsl,imx8mm-iomuxc-gpr", > > + .variant = IMX8MM, > > +}; > > + > > +static const struct imx8_pcie_phy_drvdata imx8mp_drvdata = { > > + .gpr = "fsl,imx8mp-iomuxc-gpr", > > + .variant = IMX8MP, > > +}; > > + > > +static const struct udevice_id imx8_pcie_phy_of_match[] = { > > + {.compatible = "fsl,imx8mm-pcie-phy", .data = (ulong)&imx8mm_drvdata, }, > > + {.compatible = "fsl,imx8mp-pcie-phy", .data = (ulong)&imx8mp_drvdata, }, > > + { }, > > +}; > > + > > +static int imx8_pcie_phy_probe(struct udevice *dev) > > +{ > > + struct imx8_pcie_phy *imx8_phy = dev_get_priv(dev); > > + ofnode gpr; > > + int ret = 0; > > + > > + imx8_phy->drvdata = (void *)dev_get_driver_data(dev); > > + imx8_phy->base = dev_read_addr(dev); > > + if (!imx8_phy->base) > > + return -EINVAL; > > + > > + /* get PHY refclk pad mode */ > > + dev_read_u32(dev, "fsl,refclk-pad-mode", &imx8_phy->refclk_pad_mode); > > + > > + if (dev_read_u32(dev, "fsl,tx-deemph-gen1", &imx8_phy->tx_deemph_gen1)) > > + imx8_phy->tx_deemph_gen1 = 0; > > + > > + if (dev_read_u32(dev, "fsl,tx-deemph-gen2", &imx8_phy->tx_deemph_gen2)) > > + imx8_phy->tx_deemph_gen2 = 0; > > + > > + if (dev_read_bool(dev, "fsl,clkreq-unsupported")) > > + imx8_phy->clkreq_unused = true; > > + else > > + imx8_phy->clkreq_unused = false; > > + > > + /* Grab GPR config register range */ > > + gpr = ofnode_by_compatible(ofnode_null(), imx8_phy->drvdata->gpr); > > + if (ofnode_equal(gpr, ofnode_null())) { > > + dev_err(dev, "unable to find GPR node\n"); > > + return -ENODEV; > > + } > > + > > + imx8_phy->iomuxc_gpr = syscon_node_to_regmap(gpr); > > + if (IS_ERR(imx8_phy->iomuxc_gpr)) { > > + dev_err(dev, "unable to find iomuxc registers\n"); > > + return PTR_ERR(imx8_phy->iomuxc_gpr); > > + } > > + > > + ret = clk_get_by_name(dev, "ref", &imx8_phy->hsio_clk); > > + if (ret) { > > + dev_err(dev, "Failed to get PCIEPHY ref clock\n"); > > + return ret; > > + } > > + > > + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); > > + if (ret) { > > + dev_err(dev, "Failed to get PCIEPHY reset control\n"); > > + return ret; > > + } > > + > > + if (imx8_phy->drvdata->variant == IMX8MP) { > > + ret = reset_get_by_name(dev, "perst", &imx8_phy->perst); > > + if (ret) { > > + dev_err(dev, > > + "Failed to get PCIEPHY PHY PERST control\n"); > > + return ret; > > + } > > + } > > + > > + return 0; > > +} > > + > > +U_BOOT_DRIVER(nxp_imx8_pcie_phy) = { > > + .name = "nxp_imx8_pcie_phy", > > + .id = UCLASS_PHY, > > + .of_match = imx8_pcie_phy_of_match, > > + .probe = imx8_pcie_phy_probe, > > + .ops = &imx8_pcie_phy_ops, > > + .priv_auto = sizeof(struct imx8_pcie_phy), > > +}; > > -- > > 2.34.1 > >
Hi Adam, On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > Hi Adam, > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > PHY initialization moved to this standalone PHY driver. > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > I have a PCIe device that works just fine in Linux. I have applied > > your series an enabled the same config options as you did along with > > some others to resolve some build issues. > > > > Any ideas how to address: > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > pcie-phy@32f00000: -110. > > > > My PHY node looks like this > > > > &pcie_phy { > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > clocks = <&pcie0_refclk>; > > clock-names = "ref"; > > status = "okay"; > > }; > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > dump shows it to be: > > > > 100000000 0 |-- clock-pcie > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > required for EVK board via following patch: > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > index 7856823c9188..32fd2cb05d4b 100644 > --- a/drivers/pci/pcie_dw_imx.c > +++ b/drivers/pci/pcie_dw_imx.c > @@ -17,6 +17,7 @@ > #include <linux/iopoll.h> > #include <log.h> > #include <pci.h> > +#include <power/regulator.h> > #include <regmap.h> > #include <reset.h> > #include <syscon.h> > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > int ret; > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > + > ret = imx_pcie_assert_core_reset(priv); > if (ret) { > dev_err(dev, "failed to assert core reset\n"); > Were you able to give a retry with the above diff? -Sumit
On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > Hi Adam, > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > Hi Adam, > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > your series an enabled the same config options as you did along with > > > some others to resolve some build issues. > > > > > > Any ideas how to address: > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > pcie-phy@32f00000: -110. > > > > > > My PHY node looks like this > > > > > > &pcie_phy { > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > clocks = <&pcie0_refclk>; > > > clock-names = "ref"; > > > status = "okay"; > > > }; > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > dump shows it to be: > > > > > > 100000000 0 |-- clock-pcie > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > required for EVK board via following patch: > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > index 7856823c9188..32fd2cb05d4b 100644 > > --- a/drivers/pci/pcie_dw_imx.c > > +++ b/drivers/pci/pcie_dw_imx.c > > @@ -17,6 +17,7 @@ > > #include <linux/iopoll.h> > > #include <log.h> > > #include <pci.h> > > +#include <power/regulator.h> > > #include <regmap.h> > > #include <reset.h> > > #include <syscon.h> > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > int ret; > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > + > > ret = imx_pcie_assert_core_reset(priv); > > if (ret) { > > dev_err(dev, "failed to assert core reset\n"); > > > > Were you able to give a retry with the above diff? Not yet, but I'll try to do it tonight. adam > > -Sumit
On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > Hi Adam, > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > Hi Adam, > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > your series an enabled the same config options as you did along with > > > > some others to resolve some build issues. > > > > > > > > Any ideas how to address: > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > pcie-phy@32f00000: -110. > > > > > > > > My PHY node looks like this > > > > > > > > &pcie_phy { > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > clocks = <&pcie0_refclk>; > > > > clock-names = "ref"; > > > > status = "okay"; > > > > }; > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > dump shows it to be: > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > required for EVK board via following patch: > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > index 7856823c9188..32fd2cb05d4b 100644 > > > --- a/drivers/pci/pcie_dw_imx.c > > > +++ b/drivers/pci/pcie_dw_imx.c > > > @@ -17,6 +17,7 @@ > > > #include <linux/iopoll.h> > > > #include <log.h> > > > #include <pci.h> > > > +#include <power/regulator.h> > > > #include <regmap.h> > > > #include <reset.h> > > > #include <syscon.h> > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > int ret; > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); I think you should search the device tree for "vpcie-supply" and enable the corresponding regulator, because is more flexible than hard-coding regulator names. This is also more of a standard practice. > > > + > > > ret = imx_pcie_assert_core_reset(priv); > > > if (ret) { > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > Were you able to give a retry with the above diff? > > Not yet, but I'll try to do it tonight. That didn't work for me. I am using a Beacon Embedded kit which does not use a regulator, so this had no impact, but I think having the vpcie-supply regulator is a good idea. I'll investigate a bit more and let you know if I make any progress. adam > > adam > > > > -Sumit
On Wed, 6 Mar 2024 at 06:17, Adam Ford <aford173@gmail.com> wrote: > > On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > Hi Adam, > > > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > Hi Adam, > > > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > > your series an enabled the same config options as you did along with > > > > > some others to resolve some build issues. > > > > > > > > > > Any ideas how to address: > > > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > > pcie-phy@32f00000: -110. > > > > > > > > > > My PHY node looks like this > > > > > > > > > > &pcie_phy { > > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > > clocks = <&pcie0_refclk>; > > > > > clock-names = "ref"; > > > > > status = "okay"; > > > > > }; > > > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > > dump shows it to be: > > > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > > required for EVK board via following patch: > > > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > > index 7856823c9188..32fd2cb05d4b 100644 > > > > --- a/drivers/pci/pcie_dw_imx.c > > > > +++ b/drivers/pci/pcie_dw_imx.c > > > > @@ -17,6 +17,7 @@ > > > > #include <linux/iopoll.h> > > > > #include <log.h> > > > > #include <pci.h> > > > > +#include <power/regulator.h> > > > > #include <regmap.h> > > > > #include <reset.h> > > > > #include <syscon.h> > > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > > int ret; > > > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > I think you should search the device tree for "vpcie-supply" and > enable the corresponding regulator, because is more flexible than > hard-coding regulator names. This is also more of a standard practice. > Yeah I agree, this was sort of a minimal diff to test with. > > > > + > > > > ret = imx_pcie_assert_core_reset(priv); > > > > if (ret) { > > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > > > > Were you able to give a retry with the above diff? > > > > Not yet, but I'll try to do it tonight. > > That didn't work for me. I am using a Beacon Embedded kit which does > not use a regulator, so this had no impact, but I think having the > vpcie-supply regulator is a good idea. Sure, I can add that. -Sumit > > I'll investigate a bit more and let you know if I make any progress. > > adam > > > > adam > > > > > > -Sumit
On Tue, Mar 5, 2024 at 4:47 PM Adam Ford <aford173@gmail.com> wrote: > > On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > Hi Adam, > > > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > Hi Adam, > > > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > > your series an enabled the same config options as you did along with > > > > > some others to resolve some build issues. > > > > > > > > > > Any ideas how to address: > > > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > > pcie-phy@32f00000: -110. > > > > > > > > > > My PHY node looks like this > > > > > > > > > > &pcie_phy { > > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > > clocks = <&pcie0_refclk>; > > > > > clock-names = "ref"; > > > > > status = "okay"; > > > > > }; > > > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > > dump shows it to be: > > > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > > required for EVK board via following patch: > > > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > > index 7856823c9188..32fd2cb05d4b 100644 > > > > --- a/drivers/pci/pcie_dw_imx.c > > > > +++ b/drivers/pci/pcie_dw_imx.c > > > > @@ -17,6 +17,7 @@ > > > > #include <linux/iopoll.h> > > > > #include <log.h> > > > > #include <pci.h> > > > > +#include <power/regulator.h> > > > > #include <regmap.h> > > > > #include <reset.h> > > > > #include <syscon.h> > > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > > int ret; > > > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > I think you should search the device tree for "vpcie-supply" and > enable the corresponding regulator, because is more flexible than > hard-coding regulator names. This is also more of a standard practice. > > > > > + > > > > ret = imx_pcie_assert_core_reset(priv); > > > > if (ret) { > > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > > > > Were you able to give a retry with the above diff? > > > > Not yet, but I'll try to do it tonight. > > That didn't work for me. I am using a Beacon Embedded kit which does > not use a regulator, so this had no impact, but I think having the > vpcie-supply regulator is a good idea. > > I'll investigate a bit more and let you know if I make any progress. > Adam and Sumit, In case it helps this series works for PCI bus scanning for the imx8mp-venice-* boards with the following patch: diff --git a/configs/imx8mp_venice_defconfig b/configs/imx8mp_venice_defconfig index 11b356b77856..ff7ea9811ed6 100644 --- a/configs/imx8mp_venice_defconfig +++ b/configs/imx8mp_venice_defconfig @@ -12,6 +12,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx8mp-venice" CONFIG_SPL_TEXT_BASE=0x920000 CONFIG_TARGET_IMX8MP_VENICE=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_DM_RESET=y CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SPL_MMC=y CONFIG_SPL_SERIAL=y @@ -21,6 +22,7 @@ CONFIG_SPL=y CONFIG_ENV_OFFSET_REDUND=0x3f8000 CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 CONFIG_SYS_LOAD_ADDR=0x40480000 +CONFIG_PCI=y CONFIG_SYS_MEMTEST_START=0x40000000 CONFIG_SYS_MEMTEST_END=0x80000000 CONFIG_LTO=y @@ -65,6 +67,7 @@ CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y CONFIG_CMD_USB=y CONFIG_SYS_DISABLE_AUTOLOAD=y CONFIG_CMD_CACHE=y @@ -86,6 +89,8 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_IP_DEFRAG=y CONFIG_TFTP_BLOCKSIZE=4096 CONFIG_SPL_DM=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_CLK_IMX8MP=y CONFIG_GPIO_HOG=y @@ -114,7 +119,10 @@ CONFIG_FEC_MXC=y CONFIG_KSZ9477=y CONFIG_RGMII=y CONFIG_MII=y +CONFIG_NVME_PCI=y +CONFIG_PCIE_DW_IMX=y CONFIG_PHY_IMX8MQ_USB=y +CONFIG_PHY_IMX8M_PCIE=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y on an imx8mp-venice-gw71xx-2x (imx8mp with miniPCIe socket using a miniPCIe to NVMe adapter) u-boot=> pci enum PCIE-0: Link up (Gen1-x1, Bus0) u-boot=> pci BusDevFun VendorId DeviceId Device Class Sub-Class
On Wed, 6 Mar 2024 at 22:56, Tim Harvey <tharvey@gateworks.com> wrote: > > On Tue, Mar 5, 2024 at 4:47 PM Adam Ford <aford173@gmail.com> wrote: > > > > On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > > > > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > Hi Adam, > > > > > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > Hi Adam, > > > > > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > > > your series an enabled the same config options as you did along with > > > > > > some others to resolve some build issues. > > > > > > > > > > > > Any ideas how to address: > > > > > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > > > pcie-phy@32f00000: -110. > > > > > > > > > > > > My PHY node looks like this > > > > > > > > > > > > &pcie_phy { > > > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > > > clocks = <&pcie0_refclk>; > > > > > > clock-names = "ref"; > > > > > > status = "okay"; > > > > > > }; > > > > > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > > > dump shows it to be: > > > > > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > > > required for EVK board via following patch: > > > > > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > > > index 7856823c9188..32fd2cb05d4b 100644 > > > > > --- a/drivers/pci/pcie_dw_imx.c > > > > > +++ b/drivers/pci/pcie_dw_imx.c > > > > > @@ -17,6 +17,7 @@ > > > > > #include <linux/iopoll.h> > > > > > #include <log.h> > > > > > #include <pci.h> > > > > > +#include <power/regulator.h> > > > > > #include <regmap.h> > > > > > #include <reset.h> > > > > > #include <syscon.h> > > > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > > > int ret; > > > > > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > > > I think you should search the device tree for "vpcie-supply" and > > enable the corresponding regulator, because is more flexible than > > hard-coding regulator names. This is also more of a standard practice. > > > > > > > + > > > > > ret = imx_pcie_assert_core_reset(priv); > > > > > if (ret) { > > > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > > > > > > > Were you able to give a retry with the above diff? > > > > > > Not yet, but I'll try to do it tonight. > > > > That didn't work for me. I am using a Beacon Embedded kit which does > > not use a regulator, so this had no impact, but I think having the > > vpcie-supply regulator is a good idea. > > > > I'll investigate a bit more and let you know if I make any progress. > > > > Adam and Sumit, > > In case it helps this series works for PCI bus scanning for the > imx8mp-venice-* boards with the following patch: Thanks Tim for taking time to test this series. I hope you are fine with me taking your below patch with you being the author. > diff --git a/configs/imx8mp_venice_defconfig b/configs/imx8mp_venice_defconfig > index 11b356b77856..ff7ea9811ed6 100644 > --- a/configs/imx8mp_venice_defconfig > +++ b/configs/imx8mp_venice_defconfig > @@ -12,6 +12,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx8mp-venice" > CONFIG_SPL_TEXT_BASE=0x920000 > CONFIG_TARGET_IMX8MP_VENICE=y > CONFIG_OF_LIBFDT_OVERLAY=y > +CONFIG_DM_RESET=y > CONFIG_SYS_MONITOR_LEN=524288 > CONFIG_SPL_MMC=y > CONFIG_SPL_SERIAL=y > @@ -21,6 +22,7 @@ CONFIG_SPL=y > CONFIG_ENV_OFFSET_REDUND=0x3f8000 > CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 > CONFIG_SYS_LOAD_ADDR=0x40480000 > +CONFIG_PCI=y > CONFIG_SYS_MEMTEST_START=0x40000000 > CONFIG_SYS_MEMTEST_END=0x80000000 > CONFIG_LTO=y > @@ -65,6 +67,7 @@ CONFIG_CMD_FUSE=y > CONFIG_CMD_GPIO=y > CONFIG_CMD_I2C=y > CONFIG_CMD_MMC=y > +CONFIG_CMD_PCI=y > CONFIG_CMD_USB=y > CONFIG_SYS_DISABLE_AUTOLOAD=y > CONFIG_CMD_CACHE=y > @@ -86,6 +89,8 @@ CONFIG_NET_RANDOM_ETHADDR=y > CONFIG_IP_DEFRAG=y > CONFIG_TFTP_BLOCKSIZE=4096 > CONFIG_SPL_DM=y > +CONFIG_REGMAP=y > +CONFIG_SYSCON=y > CONFIG_CLK_COMPOSITE_CCF=y > CONFIG_CLK_IMX8MP=y > CONFIG_GPIO_HOG=y > @@ -114,7 +119,10 @@ CONFIG_FEC_MXC=y > CONFIG_KSZ9477=y > CONFIG_RGMII=y > CONFIG_MII=y > +CONFIG_NVME_PCI=y > +CONFIG_PCIE_DW_IMX=y > CONFIG_PHY_IMX8MQ_USB=y > +CONFIG_PHY_IMX8M_PCIE=y > CONFIG_PINCTRL=y > CONFIG_SPL_PINCTRL=y > CONFIG_PINCTRL_IMX8M=y > > on an imx8mp-venice-gw71xx-2x (imx8mp with miniPCIe socket using a > miniPCIe to NVMe adapter) > u-boot=> pci enum > PCIE-0: Link up (Gen1-x1, Bus0) > u-boot=> pci > BusDevFun VendorId DeviceId Device Class Sub-Class > _____________________________________________________________ > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > 01.00.00 0x10ec 0x5765 Mass storage controller 0x08 > u-boot=> nvme scan > u-boot=> nvme info > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > Type: Hard Disk > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > I also verified this works imx8mp-venice-gw74xx (imx8mp with PCIe > switch to multiple miniPCIe sockets using a miniPCIe to NVMe adapter) > u-boot=> pci enum > PCIE-0: Link up (Gen1-x1, Bus0) > u-boot=> pci > BusDevFun VendorId DeviceId Device Class Sub-Class > _____________________________________________________________ > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > 01.00.00 0x12d8 0x2608 Bridge device 0x04 > 02.01.00 0x12d8 0x2608 Bridge device 0x04 > 02.02.00 0x12d8 0x2608 Bridge device 0x04 > 02.03.00 0x12d8 0x2608 Bridge device 0x04 > 02.04.00 0x12d8 0x2608 Bridge device 0x04 > 05.00.00 0x10ec 0x5765 Mass storage controller 0x08 > u-boot=> nvme scan > u-boot=> nvme info > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > Type: Hard Disk > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > It looks like the imx8mp-beacon-kit has almost the same setup as the > imx8mp-venice-gw74xx with the exception of you having a PCIe_nDIS gpio > defined in pinctrl (used nowhere) and the gw74xx does not support > CLKREQ so has 'fsl,clkreq-unsupported'. Ah, I see. So it turns out that it's Adam Linux kernel DTS patch [1] which is missing for U-Boot DTS. This is one of the reasons why we should switch to OF_UPSTREAM to start regular sync with Linux kernel DTS. Adam, Can you make corresponding changes to U-Boot DTS for imx8mp-beacon-kit? Or better just switch to OF_UPSTREAM instead? [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?id=63c46b51c7995d8aeb4b44493633f4ce1dcf62bc > > tested-by: Tim Harvey <tharvey@gateworks.com> : imx8mp-venice* > Thanks again. -Sumit > Best regards, > > Tim
On Thu, Mar 7, 2024 at 12:35 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > On Wed, 6 Mar 2024 at 22:56, Tim Harvey <tharvey@gateworks.com> wrote: > > > > On Tue, Mar 5, 2024 at 4:47 PM Adam Ford <aford173@gmail.com> wrote: > > > > > > On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > > > > > > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > Hi Adam, > > > > > > > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Hi Adam, > > > > > > > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > > > > your series an enabled the same config options as you did along with > > > > > > > some others to resolve some build issues. > > > > > > > > > > > > > > Any ideas how to address: > > > > > > > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > > > > pcie-phy@32f00000: -110. > > > > > > > > > > > > > > My PHY node looks like this > > > > > > > > > > > > > > &pcie_phy { > > > > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > > > > clocks = <&pcie0_refclk>; > > > > > > > clock-names = "ref"; > > > > > > > status = "okay"; > > > > > > > }; > > > > > > > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > > > > dump shows it to be: > > > > > > > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > > > > required for EVK board via following patch: > > > > > > > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > > > > index 7856823c9188..32fd2cb05d4b 100644 > > > > > > --- a/drivers/pci/pcie_dw_imx.c > > > > > > +++ b/drivers/pci/pcie_dw_imx.c > > > > > > @@ -17,6 +17,7 @@ > > > > > > #include <linux/iopoll.h> > > > > > > #include <log.h> > > > > > > #include <pci.h> > > > > > > +#include <power/regulator.h> > > > > > > #include <regmap.h> > > > > > > #include <reset.h> > > > > > > #include <syscon.h> > > > > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > > > > int ret; > > > > > > > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > > > > > I think you should search the device tree for "vpcie-supply" and > > > enable the corresponding regulator, because is more flexible than > > > hard-coding regulator names. This is also more of a standard practice. > > > > > > > > > + > > > > > > ret = imx_pcie_assert_core_reset(priv); > > > > > > if (ret) { > > > > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > > > > > > > > > > Were you able to give a retry with the above diff? > > > > > > > > Not yet, but I'll try to do it tonight. > > > > > > That didn't work for me. I am using a Beacon Embedded kit which does > > > not use a regulator, so this had no impact, but I think having the > > > vpcie-supply regulator is a good idea. > > > > > > I'll investigate a bit more and let you know if I make any progress. > > > > > > > Adam and Sumit, > > > > In case it helps this series works for PCI bus scanning for the > > imx8mp-venice-* boards with the following patch: > > Thanks Tim for taking time to test this series. I hope you are fine > with me taking your below patch with you being the author. > > > diff --git a/configs/imx8mp_venice_defconfig b/configs/imx8mp_venice_defconfig > > index 11b356b77856..ff7ea9811ed6 100644 > > --- a/configs/imx8mp_venice_defconfig > > +++ b/configs/imx8mp_venice_defconfig > > @@ -12,6 +12,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx8mp-venice" > > CONFIG_SPL_TEXT_BASE=0x920000 > > CONFIG_TARGET_IMX8MP_VENICE=y > > CONFIG_OF_LIBFDT_OVERLAY=y > > +CONFIG_DM_RESET=y > > CONFIG_SYS_MONITOR_LEN=524288 > > CONFIG_SPL_MMC=y > > CONFIG_SPL_SERIAL=y > > @@ -21,6 +22,7 @@ CONFIG_SPL=y > > CONFIG_ENV_OFFSET_REDUND=0x3f8000 > > CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 > > CONFIG_SYS_LOAD_ADDR=0x40480000 > > +CONFIG_PCI=y > > CONFIG_SYS_MEMTEST_START=0x40000000 > > CONFIG_SYS_MEMTEST_END=0x80000000 > > CONFIG_LTO=y > > @@ -65,6 +67,7 @@ CONFIG_CMD_FUSE=y > > CONFIG_CMD_GPIO=y > > CONFIG_CMD_I2C=y > > CONFIG_CMD_MMC=y > > +CONFIG_CMD_PCI=y > > CONFIG_CMD_USB=y > > CONFIG_SYS_DISABLE_AUTOLOAD=y > > CONFIG_CMD_CACHE=y > > @@ -86,6 +89,8 @@ CONFIG_NET_RANDOM_ETHADDR=y > > CONFIG_IP_DEFRAG=y > > CONFIG_TFTP_BLOCKSIZE=4096 > > CONFIG_SPL_DM=y > > +CONFIG_REGMAP=y > > +CONFIG_SYSCON=y > > CONFIG_CLK_COMPOSITE_CCF=y > > CONFIG_CLK_IMX8MP=y > > CONFIG_GPIO_HOG=y > > @@ -114,7 +119,10 @@ CONFIG_FEC_MXC=y > > CONFIG_KSZ9477=y > > CONFIG_RGMII=y > > CONFIG_MII=y > > +CONFIG_NVME_PCI=y > > +CONFIG_PCIE_DW_IMX=y > > CONFIG_PHY_IMX8MQ_USB=y > > +CONFIG_PHY_IMX8M_PCIE=y > > CONFIG_PINCTRL=y > > CONFIG_SPL_PINCTRL=y > > CONFIG_PINCTRL_IMX8M=y > > > > on an imx8mp-venice-gw71xx-2x (imx8mp with miniPCIe socket using a > > miniPCIe to NVMe adapter) > > u-boot=> pci enum > > PCIE-0: Link up (Gen1-x1, Bus0) > > u-boot=> pci > > BusDevFun VendorId DeviceId Device Class Sub-Class > > _____________________________________________________________ > > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > > 01.00.00 0x10ec 0x5765 Mass storage controller 0x08 > > u-boot=> nvme scan > > u-boot=> nvme info > > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > > Type: Hard Disk > > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > > > I also verified this works imx8mp-venice-gw74xx (imx8mp with PCIe > > switch to multiple miniPCIe sockets using a miniPCIe to NVMe adapter) > > u-boot=> pci enum > > PCIE-0: Link up (Gen1-x1, Bus0) > > u-boot=> pci > > BusDevFun VendorId DeviceId Device Class Sub-Class > > _____________________________________________________________ > > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > > 01.00.00 0x12d8 0x2608 Bridge device 0x04 > > 02.01.00 0x12d8 0x2608 Bridge device 0x04 > > 02.02.00 0x12d8 0x2608 Bridge device 0x04 > > 02.03.00 0x12d8 0x2608 Bridge device 0x04 > > 02.04.00 0x12d8 0x2608 Bridge device 0x04 > > 05.00.00 0x10ec 0x5765 Mass storage controller 0x08 > > u-boot=> nvme scan > > u-boot=> nvme info > > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > > Type: Hard Disk > > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > > > It looks like the imx8mp-beacon-kit has almost the same setup as the > > imx8mp-venice-gw74xx with the exception of you having a PCIe_nDIS gpio > > defined in pinctrl (used nowhere) and the gw74xx does not support > > CLKREQ so has 'fsl,clkreq-unsupported'. > > Ah, I see. So it turns out that it's Adam Linux kernel DTS patch [1] > which is missing for U-Boot DTS. This is one of the reasons why we > should switch to OF_UPSTREAM to start regular sync with Linux kernel > DTS. > > Adam, > > Can you make corresponding changes to U-Boot DTS for > imx8mp-beacon-kit? Or better just switch to OF_UPSTREAM instead? > I have it working now. > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?id=63c46b51c7995d8aeb4b44493633f4ce1dcf62bc > This is one of the first things I did when I tried the patch, but the renesas clock driver isn't available in U-Boot. With and without that above patch, the Linux driver enumerates, but the real issue appears to be something related to ATF (or lack thereof). I had experimented with a series of patches which bypassed ATF, and pushed them upstream a while ago. Unfortunately, it appears to have caused more issues. When I revert those it all works just fine. Sorry for the noise. u-boot=> pci enum PCIE-0: Link up (Gen1-x1, Bus0) u-boot=> nvme scan u-boot=> nvme info Device 0: Vendor: 0x15b7 Rev: 20120022 Prod: 184960441105 Type: Hard Disk Capacity: 122104.3 MB = 119.2 GB (250069680 x 512) u-boot=> WIth my suggested regulator and build-dependency fixes added you can add Tested-by: Adam Ford <aford173@gmail.com> #imx8mp-beacon-kit adam > > > > tested-by: Tim Harvey <tharvey@gateworks.com> : imx8mp-venice* > > > > Thanks again. > > -Sumit > > > Best regards, > > > > Tim
On Thu, 7 Mar 2024 at 17:12, Adam Ford <aford173@gmail.com> wrote: > > On Thu, Mar 7, 2024 at 12:35 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > On Wed, 6 Mar 2024 at 22:56, Tim Harvey <tharvey@gateworks.com> wrote: > > > > > > On Tue, Mar 5, 2024 at 4:47 PM Adam Ford <aford173@gmail.com> wrote: > > > > > > > > On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Hi Adam, > > > > > > > > > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > Hi Adam, > > > > > > > > > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > > > > > your series an enabled the same config options as you did along with > > > > > > > > some others to resolve some build issues. > > > > > > > > > > > > > > > > Any ideas how to address: > > > > > > > > > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > > > > > pcie-phy@32f00000: -110. > > > > > > > > > > > > > > > > My PHY node looks like this > > > > > > > > > > > > > > > > &pcie_phy { > > > > > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > > > > > clocks = <&pcie0_refclk>; > > > > > > > > clock-names = "ref"; > > > > > > > > status = "okay"; > > > > > > > > }; > > > > > > > > > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > > > > > dump shows it to be: > > > > > > > > > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > > > > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > > > > > required for EVK board via following patch: > > > > > > > > > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > > > > > index 7856823c9188..32fd2cb05d4b 100644 > > > > > > > --- a/drivers/pci/pcie_dw_imx.c > > > > > > > +++ b/drivers/pci/pcie_dw_imx.c > > > > > > > @@ -17,6 +17,7 @@ > > > > > > > #include <linux/iopoll.h> > > > > > > > #include <log.h> > > > > > > > #include <pci.h> > > > > > > > +#include <power/regulator.h> > > > > > > > #include <regmap.h> > > > > > > > #include <reset.h> > > > > > > > #include <syscon.h> > > > > > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > > > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > > > > > int ret; > > > > > > > > > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > > > > > > > I think you should search the device tree for "vpcie-supply" and > > > > enable the corresponding regulator, because is more flexible than > > > > hard-coding regulator names. This is also more of a standard practice. > > > > > > > > > > > + > > > > > > > ret = imx_pcie_assert_core_reset(priv); > > > > > > > if (ret) { > > > > > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > > > > > > > > > > > > > Were you able to give a retry with the above diff? > > > > > > > > > > Not yet, but I'll try to do it tonight. > > > > > > > > That didn't work for me. I am using a Beacon Embedded kit which does > > > > not use a regulator, so this had no impact, but I think having the > > > > vpcie-supply regulator is a good idea. > > > > > > > > I'll investigate a bit more and let you know if I make any progress. > > > > > > > > > > Adam and Sumit, > > > > > > In case it helps this series works for PCI bus scanning for the > > > imx8mp-venice-* boards with the following patch: > > > > Thanks Tim for taking time to test this series. I hope you are fine > > with me taking your below patch with you being the author. > > > > > diff --git a/configs/imx8mp_venice_defconfig b/configs/imx8mp_venice_defconfig > > > index 11b356b77856..ff7ea9811ed6 100644 > > > --- a/configs/imx8mp_venice_defconfig > > > +++ b/configs/imx8mp_venice_defconfig > > > @@ -12,6 +12,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx8mp-venice" > > > CONFIG_SPL_TEXT_BASE=0x920000 > > > CONFIG_TARGET_IMX8MP_VENICE=y > > > CONFIG_OF_LIBFDT_OVERLAY=y > > > +CONFIG_DM_RESET=y > > > CONFIG_SYS_MONITOR_LEN=524288 > > > CONFIG_SPL_MMC=y > > > CONFIG_SPL_SERIAL=y > > > @@ -21,6 +22,7 @@ CONFIG_SPL=y > > > CONFIG_ENV_OFFSET_REDUND=0x3f8000 > > > CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 > > > CONFIG_SYS_LOAD_ADDR=0x40480000 > > > +CONFIG_PCI=y > > > CONFIG_SYS_MEMTEST_START=0x40000000 > > > CONFIG_SYS_MEMTEST_END=0x80000000 > > > CONFIG_LTO=y > > > @@ -65,6 +67,7 @@ CONFIG_CMD_FUSE=y > > > CONFIG_CMD_GPIO=y > > > CONFIG_CMD_I2C=y > > > CONFIG_CMD_MMC=y > > > +CONFIG_CMD_PCI=y > > > CONFIG_CMD_USB=y > > > CONFIG_SYS_DISABLE_AUTOLOAD=y > > > CONFIG_CMD_CACHE=y > > > @@ -86,6 +89,8 @@ CONFIG_NET_RANDOM_ETHADDR=y > > > CONFIG_IP_DEFRAG=y > > > CONFIG_TFTP_BLOCKSIZE=4096 > > > CONFIG_SPL_DM=y > > > +CONFIG_REGMAP=y > > > +CONFIG_SYSCON=y > > > CONFIG_CLK_COMPOSITE_CCF=y > > > CONFIG_CLK_IMX8MP=y > > > CONFIG_GPIO_HOG=y > > > @@ -114,7 +119,10 @@ CONFIG_FEC_MXC=y > > > CONFIG_KSZ9477=y > > > CONFIG_RGMII=y > > > CONFIG_MII=y > > > +CONFIG_NVME_PCI=y > > > +CONFIG_PCIE_DW_IMX=y > > > CONFIG_PHY_IMX8MQ_USB=y > > > +CONFIG_PHY_IMX8M_PCIE=y > > > CONFIG_PINCTRL=y > > > CONFIG_SPL_PINCTRL=y > > > CONFIG_PINCTRL_IMX8M=y > > > > > > on an imx8mp-venice-gw71xx-2x (imx8mp with miniPCIe socket using a > > > miniPCIe to NVMe adapter) > > > u-boot=> pci enum > > > PCIE-0: Link up (Gen1-x1, Bus0) > > > u-boot=> pci > > > BusDevFun VendorId DeviceId Device Class Sub-Class > > > _____________________________________________________________ > > > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > > > 01.00.00 0x10ec 0x5765 Mass storage controller 0x08 > > > u-boot=> nvme scan > > > u-boot=> nvme info > > > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > > > Type: Hard Disk > > > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > > > > > I also verified this works imx8mp-venice-gw74xx (imx8mp with PCIe > > > switch to multiple miniPCIe sockets using a miniPCIe to NVMe adapter) > > > u-boot=> pci enum > > > PCIE-0: Link up (Gen1-x1, Bus0) > > > u-boot=> pci > > > BusDevFun VendorId DeviceId Device Class Sub-Class > > > _____________________________________________________________ > > > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > > > 01.00.00 0x12d8 0x2608 Bridge device 0x04 > > > 02.01.00 0x12d8 0x2608 Bridge device 0x04 > > > 02.02.00 0x12d8 0x2608 Bridge device 0x04 > > > 02.03.00 0x12d8 0x2608 Bridge device 0x04 > > > 02.04.00 0x12d8 0x2608 Bridge device 0x04 > > > 05.00.00 0x10ec 0x5765 Mass storage controller 0x08 > > > u-boot=> nvme scan > > > u-boot=> nvme info > > > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > > > Type: Hard Disk > > > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > > > > > It looks like the imx8mp-beacon-kit has almost the same setup as the > > > imx8mp-venice-gw74xx with the exception of you having a PCIe_nDIS gpio > > > defined in pinctrl (used nowhere) and the gw74xx does not support > > > CLKREQ so has 'fsl,clkreq-unsupported'. > > > > Ah, I see. So it turns out that it's Adam Linux kernel DTS patch [1] > > which is missing for U-Boot DTS. This is one of the reasons why we > > should switch to OF_UPSTREAM to start regular sync with Linux kernel > > DTS. > > > > Adam, > > > > Can you make corresponding changes to U-Boot DTS for > > imx8mp-beacon-kit? Or better just switch to OF_UPSTREAM instead? > > > > I have it working now. > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?id=63c46b51c7995d8aeb4b44493633f4ce1dcf62bc > > > > This is one of the first things I did when I tried the patch, but the > renesas clock driver isn't available in U-Boot. With and without that > above patch, the Linux driver enumerates, but the real issue appears > to be something related to ATF (or lack thereof). I had experimented > with a series of patches which bypassed ATF, and pushed them upstream > a while ago. Unfortunately, it appears to have caused more issues. > When I revert those it all works just fine. Sorry for the noise. > No worries. > > u-boot=> pci enum > PCIE-0: Link up (Gen1-x1, Bus0) > u-boot=> nvme scan > u-boot=> nvme info > Device 0: Vendor: 0x15b7 Rev: 20120022 Prod: 184960441105 > Type: Hard Disk > Capacity: 122104.3 MB = 119.2 GB (250069680 x 512) > u-boot=> > > WIth my suggested regulator and build-dependency fixes added you can add > > Tested-by: Adam Ford <aford173@gmail.com> #imx8mp-beacon-kit > Thanks for taking time to test this series. -Sumit > adam > > > > > > > > tested-by: Tim Harvey <tharvey@gateworks.com> : imx8mp-venice* > > > > > > > Thanks again. > > > > -Sumit > > > > > Best regards, > > > > > > Tim
On Wed, Mar 6, 2024 at 10:35 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > On Wed, 6 Mar 2024 at 22:56, Tim Harvey <tharvey@gateworks.com> wrote: > > > > On Tue, Mar 5, 2024 at 4:47 PM Adam Ford <aford173@gmail.com> wrote: > > > > > > On Tue, Mar 5, 2024 at 7:51 AM Adam Ford <aford173@gmail.com> wrote: > > > > > > > > On Tue, Mar 5, 2024 at 7:48 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > Hi Adam, > > > > > > > > > > On Wed, 28 Feb 2024 at 12:29, Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > Hi Adam, > > > > > > > > > > > > On Wed, 28 Feb 2024 at 04:42, Adam Ford <aford173@gmail.com> wrote: > > > > > > > > > > > > > > On Mon, Feb 26, 2024 at 2:05 AM Sumit Garg <sumit.garg@linaro.org> wrote: > > > > > > > > > > > > > > > > Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe > > > > > > > > PHY initialization moved to this standalone PHY driver. > > > > > > > > > > > > > > > > Inspired from counterpart Linux kernel v6.8-rc3 driver: > > > > > > > > drivers/phy/freescale/phy-fsl-imx8m-pcie.c. > > > > > > > > > > > > > > I have a PCIe device that works just fine in Linux. I have applied > > > > > > > your series an enabled the same config options as you did along with > > > > > > > some others to resolve some build issues. > > > > > > > > > > > > > > Any ideas how to address: > > > > > > > > > > > > > > nxp_imx8_pcie_phy pcie-phy@32f00000: PHY: Failed to power on > > > > > > > pcie-phy@32f00000: -110. > > > > > > > > > > > > > > My PHY node looks like this > > > > > > > > > > > > > > &pcie_phy { > > > > > > > fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; > > > > > > > clocks = <&pcie0_refclk>; > > > > > > > clock-names = "ref"; > > > > > > > status = "okay"; > > > > > > > }; > > > > > > > > > > > > > > The pcie_refcllk is defined as a 100MHz fixed clock in U-Boot. clk > > > > > > > dump shows it to be: > > > > > > > > > > > > > > 100000000 0 |-- clock-pcie > > > > > > > > > > > > > > > > > > > I suppose that's an EVK board, try enabling MPCIE_3V3 regulator > > > > > > required for EVK board via following patch: > > > > > > > > > > > > diff --git a/drivers/pci/pcie_dw_imx.c b/drivers/pci/pcie_dw_imx.c > > > > > > index 7856823c9188..32fd2cb05d4b 100644 > > > > > > --- a/drivers/pci/pcie_dw_imx.c > > > > > > +++ b/drivers/pci/pcie_dw_imx.c > > > > > > @@ -17,6 +17,7 @@ > > > > > > #include <linux/iopoll.h> > > > > > > #include <log.h> > > > > > > #include <pci.h> > > > > > > +#include <power/regulator.h> > > > > > > #include <regmap.h> > > > > > > #include <reset.h> > > > > > > #include <syscon.h> > > > > > > @@ -158,6 +159,8 @@ static int pcie_dw_imx_probe(struct udevice *dev) > > > > > > struct pci_controller *hose = dev_get_uclass_priv(ctlr); > > > > > > int ret; > > > > > > > > > > > > + regulator_autoset_by_name("MPCIE_3V3", NULL); > > > > > > I think you should search the device tree for "vpcie-supply" and > > > enable the corresponding regulator, because is more flexible than > > > hard-coding regulator names. This is also more of a standard practice. > > > > > > > > > + > > > > > > ret = imx_pcie_assert_core_reset(priv); > > > > > > if (ret) { > > > > > > dev_err(dev, "failed to assert core reset\n"); > > > > > > > > > > > > > > > > Were you able to give a retry with the above diff? > > > > > > > > Not yet, but I'll try to do it tonight. > > > > > > That didn't work for me. I am using a Beacon Embedded kit which does > > > not use a regulator, so this had no impact, but I think having the > > > vpcie-supply regulator is a good idea. > > > > > > I'll investigate a bit more and let you know if I make any progress. > > > > > > > Adam and Sumit, > > > > In case it helps this series works for PCI bus scanning for the > > imx8mp-venice-* boards with the following patch: > > Thanks Tim for taking time to test this series. I hope you are fine > with me taking your below patch with you being the author. Sumit, Yes you can take that patch if you want to add it to your series - thanks! Tim > > > diff --git a/configs/imx8mp_venice_defconfig b/configs/imx8mp_venice_defconfig > > index 11b356b77856..ff7ea9811ed6 100644 > > --- a/configs/imx8mp_venice_defconfig > > +++ b/configs/imx8mp_venice_defconfig > > @@ -12,6 +12,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx8mp-venice" > > CONFIG_SPL_TEXT_BASE=0x920000 > > CONFIG_TARGET_IMX8MP_VENICE=y > > CONFIG_OF_LIBFDT_OVERLAY=y > > +CONFIG_DM_RESET=y > > CONFIG_SYS_MONITOR_LEN=524288 > > CONFIG_SPL_MMC=y > > CONFIG_SPL_SERIAL=y > > @@ -21,6 +22,7 @@ CONFIG_SPL=y > > CONFIG_ENV_OFFSET_REDUND=0x3f8000 > > CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 > > CONFIG_SYS_LOAD_ADDR=0x40480000 > > +CONFIG_PCI=y > > CONFIG_SYS_MEMTEST_START=0x40000000 > > CONFIG_SYS_MEMTEST_END=0x80000000 > > CONFIG_LTO=y > > @@ -65,6 +67,7 @@ CONFIG_CMD_FUSE=y > > CONFIG_CMD_GPIO=y > > CONFIG_CMD_I2C=y > > CONFIG_CMD_MMC=y > > +CONFIG_CMD_PCI=y > > CONFIG_CMD_USB=y > > CONFIG_SYS_DISABLE_AUTOLOAD=y > > CONFIG_CMD_CACHE=y > > @@ -86,6 +89,8 @@ CONFIG_NET_RANDOM_ETHADDR=y > > CONFIG_IP_DEFRAG=y > > CONFIG_TFTP_BLOCKSIZE=4096 > > CONFIG_SPL_DM=y > > +CONFIG_REGMAP=y > > +CONFIG_SYSCON=y > > CONFIG_CLK_COMPOSITE_CCF=y > > CONFIG_CLK_IMX8MP=y > > CONFIG_GPIO_HOG=y > > @@ -114,7 +119,10 @@ CONFIG_FEC_MXC=y > > CONFIG_KSZ9477=y > > CONFIG_RGMII=y > > CONFIG_MII=y > > +CONFIG_NVME_PCI=y > > +CONFIG_PCIE_DW_IMX=y > > CONFIG_PHY_IMX8MQ_USB=y > > +CONFIG_PHY_IMX8M_PCIE=y > > CONFIG_PINCTRL=y > > CONFIG_SPL_PINCTRL=y > > CONFIG_PINCTRL_IMX8M=y > > > > on an imx8mp-venice-gw71xx-2x (imx8mp with miniPCIe socket using a > > miniPCIe to NVMe adapter) > > u-boot=> pci enum > > PCIE-0: Link up (Gen1-x1, Bus0) > > u-boot=> pci > > BusDevFun VendorId DeviceId Device Class Sub-Class > > _____________________________________________________________ > > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > > 01.00.00 0x10ec 0x5765 Mass storage controller 0x08 > > u-boot=> nvme scan > > u-boot=> nvme info > > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > > Type: Hard Disk > > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > > > I also verified this works imx8mp-venice-gw74xx (imx8mp with PCIe > > switch to multiple miniPCIe sockets using a miniPCIe to NVMe adapter) > > u-boot=> pci enum > > PCIE-0: Link up (Gen1-x1, Bus0) > > u-boot=> pci > > BusDevFun VendorId DeviceId Device Class Sub-Class > > _____________________________________________________________ > > 00.00.00 0x16c3 0xabcd Bridge device 0x04 > > 01.00.00 0x12d8 0x2608 Bridge device 0x04 > > 02.01.00 0x12d8 0x2608 Bridge device 0x04 > > 02.02.00 0x12d8 0x2608 Bridge device 0x04 > > 02.03.00 0x12d8 0x2608 Bridge device 0x04 > > 02.04.00 0x12d8 0x2608 Bridge device 0x04 > > 05.00.00 0x10ec 0x5765 Mass storage controller 0x08 > > u-boot=> nvme scan > > u-boot=> nvme info > > Device 0: Vendor: 0x10ec Rev: 0426-D00 Prod: 60272-0005 > > Type: Hard Disk > > Capacity: 57241.8 MB = 55.9 GB (117231408 x 512) > > > > It looks like the imx8mp-beacon-kit has almost the same setup as the > > imx8mp-venice-gw74xx with the exception of you having a PCIe_nDIS gpio > > defined in pinctrl (used nowhere) and the gw74xx does not support > > CLKREQ so has 'fsl,clkreq-unsupported'. > > Ah, I see. So it turns out that it's Adam Linux kernel DTS patch [1] > which is missing for U-Boot DTS. This is one of the reasons why we > should switch to OF_UPSTREAM to start regular sync with Linux kernel > DTS. > > Adam, > > Can you make corresponding changes to U-Boot DTS for > imx8mp-beacon-kit? Or better just switch to OF_UPSTREAM instead? > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?id=63c46b51c7995d8aeb4b44493633f4ce1dcf62bc > > > > > tested-by: Tim Harvey <tharvey@gateworks.com> : imx8mp-venice* > > > > Thanks again. > > -Sumit > > > Best regards, > > > > Tim
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 60138beca498..110ec8f5008d 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -284,6 +284,15 @@ config PHY_IMX8MQ_USB help Support the USB3.0 PHY in NXP i.MX8MQ or i.MX8MP SoC +config PHY_IMX8M_PCIE + bool "NXP i.MX8MM/i.MX8MP PCIe PHY Driver" + depends on PHY + depends on IMX8MM || IMX8MP + help + Support the PCIe PHY in NXP i.MX8MM or i.MX8MP SoC + + This PHY is found on i.MX8M devices supporting PCIe. + config PHY_XILINX_ZYNQMP tristate "Xilinx ZynqMP PHY driver" depends on PHY && ARCH_ZYNQMP diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 2e8723186c05..7a2b764492be 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o +obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o obj-y += cadence/ obj-y += ti/ diff --git a/drivers/phy/phy-imx8m-pcie.c b/drivers/phy/phy-imx8m-pcie.c new file mode 100644 index 000000000000..e09a7ac97235 --- /dev/null +++ b/drivers/phy/phy-imx8m-pcie.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2024 Linaro Ltd. + * + * Derived from Linux counterpart driver + */ + +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <generic-phy.h> +#include <linux/bitfield.h> +#include <linux/clk-provider.h> +#include <linux/iopoll.h> +#include <syscon.h> +#include <regmap.h> +#include <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_REG075 0x1D4 +#define ANA_PLL_DONE 0x3 +#define PCIE_PHY_TRSV_REG5 0x414 +#define PCIE_PHY_TRSV_REG6 0x418 + +#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) + +#define IOMUXC_GPR14_OFFSET 0x38 + +enum imx8_pcie_phy_type { + IMX8MM, + IMX8MP, +}; + +struct imx8_pcie_phy_drvdata { + const char *gpr; + enum imx8_pcie_phy_type variant; +}; + +struct imx8_pcie_phy { + ulong base; + struct clk hsio_clk; + struct regmap *iomuxc_gpr; + struct reset_ctl perst; + struct reset_ctl reset; + u32 refclk_pad_mode; + u32 tx_deemph_gen1; + u32 tx_deemph_gen2; + bool clkreq_unused; + const struct imx8_pcie_phy_drvdata *drvdata; +}; + +static int imx8_pcie_phy_power_on(struct phy *phy) +{ + int ret; + u32 val, pad_mode; + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); + + pad_mode = imx8_phy->refclk_pad_mode; + switch (imx8_phy->drvdata->variant) { + case IMX8MM: + reset_assert(&imx8_phy->reset); + + /* Tune PHY de-emphasis setting to pass PCIe compliance. */ + if (imx8_phy->tx_deemph_gen1) + writel(imx8_phy->tx_deemph_gen1, + imx8_phy->base + PCIE_PHY_TRSV_REG5); + if (imx8_phy->tx_deemph_gen2) + writel(imx8_phy->tx_deemph_gen2, + imx8_phy->base + PCIE_PHY_TRSV_REG6); + break; + case IMX8MP: /* Do nothing. */ + break; + } + + if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT || + pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) { + /* 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 { + /* 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); + } + + if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT || + pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) { + /* Source clock from SoC internal PLL */ + 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); + } + + /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */ + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, + 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_OFFSET, + IMX8MM_GPR_PCIE_AUX_EN, + IMX8MM_GPR_PCIE_AUX_EN); + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, + IMX8MM_GPR_PCIE_POWER_OFF, 0); + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, + IMX8MM_GPR_PCIE_SSC_EN, 0); + + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, + 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); + udelay(200); + + /* Do the PHY common block reset */ + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14_OFFSET, + IMX8MM_GPR_PCIE_CMN_RST, + IMX8MM_GPR_PCIE_CMN_RST); + + switch (imx8_phy->drvdata->variant) { + case IMX8MP: + reset_deassert(&imx8_phy->perst); + fallthrough; + case IMX8MM: + reset_deassert(&imx8_phy->reset); + udelay(500); + break; + } + + /* Polling to check the phy is ready or not. */ + ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075, + val, val == ANA_PLL_DONE, 20000); + return ret; +} + +static int imx8_pcie_phy_init(struct phy *phy) +{ + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); + + return clk_enable(&imx8_phy->hsio_clk); +} + +static int imx8_pcie_phy_exit(struct phy *phy) +{ + struct imx8_pcie_phy *imx8_phy = dev_get_priv(phy->dev); + + return clk_disable(&imx8_phy->hsio_clk); +} + +static const struct phy_ops imx8_pcie_phy_ops = { + .init = imx8_pcie_phy_init, + .exit = imx8_pcie_phy_exit, + .power_on = imx8_pcie_phy_power_on, +}; + +static const struct imx8_pcie_phy_drvdata imx8mm_drvdata = { + .gpr = "fsl,imx8mm-iomuxc-gpr", + .variant = IMX8MM, +}; + +static const struct imx8_pcie_phy_drvdata imx8mp_drvdata = { + .gpr = "fsl,imx8mp-iomuxc-gpr", + .variant = IMX8MP, +}; + +static const struct udevice_id imx8_pcie_phy_of_match[] = { + {.compatible = "fsl,imx8mm-pcie-phy", .data = (ulong)&imx8mm_drvdata, }, + {.compatible = "fsl,imx8mp-pcie-phy", .data = (ulong)&imx8mp_drvdata, }, + { }, +}; + +static int imx8_pcie_phy_probe(struct udevice *dev) +{ + struct imx8_pcie_phy *imx8_phy = dev_get_priv(dev); + ofnode gpr; + int ret = 0; + + imx8_phy->drvdata = (void *)dev_get_driver_data(dev); + imx8_phy->base = dev_read_addr(dev); + if (!imx8_phy->base) + return -EINVAL; + + /* get PHY refclk pad mode */ + dev_read_u32(dev, "fsl,refclk-pad-mode", &imx8_phy->refclk_pad_mode); + + if (dev_read_u32(dev, "fsl,tx-deemph-gen1", &imx8_phy->tx_deemph_gen1)) + imx8_phy->tx_deemph_gen1 = 0; + + if (dev_read_u32(dev, "fsl,tx-deemph-gen2", &imx8_phy->tx_deemph_gen2)) + imx8_phy->tx_deemph_gen2 = 0; + + if (dev_read_bool(dev, "fsl,clkreq-unsupported")) + imx8_phy->clkreq_unused = true; + else + imx8_phy->clkreq_unused = false; + + /* Grab GPR config register range */ + gpr = ofnode_by_compatible(ofnode_null(), imx8_phy->drvdata->gpr); + if (ofnode_equal(gpr, ofnode_null())) { + dev_err(dev, "unable to find GPR node\n"); + return -ENODEV; + } + + imx8_phy->iomuxc_gpr = syscon_node_to_regmap(gpr); + if (IS_ERR(imx8_phy->iomuxc_gpr)) { + dev_err(dev, "unable to find iomuxc registers\n"); + return PTR_ERR(imx8_phy->iomuxc_gpr); + } + + ret = clk_get_by_name(dev, "ref", &imx8_phy->hsio_clk); + if (ret) { + dev_err(dev, "Failed to get PCIEPHY ref clock\n"); + return ret; + } + + ret = reset_get_by_name(dev, "pciephy", &imx8_phy->reset); + if (ret) { + dev_err(dev, "Failed to get PCIEPHY reset control\n"); + return ret; + } + + if (imx8_phy->drvdata->variant == IMX8MP) { + ret = reset_get_by_name(dev, "perst", &imx8_phy->perst); + if (ret) { + dev_err(dev, + "Failed to get PCIEPHY PHY PERST control\n"); + return ret; + } + } + + return 0; +} + +U_BOOT_DRIVER(nxp_imx8_pcie_phy) = { + .name = "nxp_imx8_pcie_phy", + .id = UCLASS_PHY, + .of_match = imx8_pcie_phy_of_match, + .probe = imx8_pcie_phy_probe, + .ops = &imx8_pcie_phy_ops, + .priv_auto = sizeof(struct imx8_pcie_phy), +};
Add initial support for i.MX8M{M/P} PCIe PHY. On i.MX8M{M/P} SoCs PCIe PHY initialization moved to this standalone PHY driver. Inspired from counterpart Linux kernel v6.8-rc3 driver: drivers/phy/freescale/phy-fsl-imx8m-pcie.c. Signed-off-by: Sumit Garg <sumit.garg@linaro.org> --- drivers/phy/Kconfig | 9 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-imx8m-pcie.c | 269 +++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 drivers/phy/phy-imx8m-pcie.c