* [PATCH v2] PCI: imx6: Add runtime PM support for i.MX95 @ 2026-07-08 3:59 hongxing.zhu 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Fix i.MX6Q/DL boot hang by separating PHY power and reference clock control hongxing.zhu 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability hongxing.zhu 0 siblings, 2 replies; 7+ messages in thread From: hongxing.zhu @ 2026-07-08 3:59 UTC (permalink / raw) To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, s.hauer, kernel, festevam Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu From: Richard Zhu <hongxing.zhu@nxp.com> Enable runtime PM support for i.MX95 PCIe Root Complex to allow dynamic power management when the PCIe link is idle. The i.MX95 PCIe controller supports entering D3hot state when PCIe devices are not actively in use. This implementation uses pm_runtime_no_callbacks() to leverage the PCI core's generic runtime PM handling. The PCI core automatically manages D-state transitions based on the runtime PM state of connected endpoint devices. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> --- Changes in v2: Use devm_pm_runtime_set_active_enabled() simplify the codes and error path. --- drivers/pci/controller/dwc/pci-imx6.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index eae495a1b7990..578410f262aed 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -130,6 +130,7 @@ enum imx_pcie_variants { #define IMX_PCIE_FLAG_SKIP_L23_READY BIT(12) /* Preserve MSI capability for platforms that require it */ #define IMX_PCIE_FLAG_KEEP_MSI_CAP BIT(13) +#define IMX_PCIE_FLAG_PM_RUNTIME BIT(14) #define imx_check_flag(pci, val) (pci->drvdata->flags & val) @@ -1973,6 +1974,13 @@ static int imx_pcie_probe(struct platform_device *pdev) */ imx_pcie_add_lut_by_rid(imx_pcie, 0); } else { + if (imx_pcie->drvdata->flags & IMX_PCIE_FLAG_PM_RUNTIME) { + pm_runtime_no_callbacks(dev); + ret = devm_pm_runtime_set_active_enabled(dev); + if (ret < 0) + return ret; + } + /* * i.MX RC is powered off during suspend, force L2 entry to * ensure proper endpoint notification before power loss. @@ -2121,6 +2129,7 @@ static const struct imx_pcie_drvdata drvdata[] = { .flags = IMX_PCIE_FLAG_HAS_SERDES | IMX_PCIE_FLAG_HAS_LUT | IMX_PCIE_FLAG_8GT_ECN_ERR051586 | + IMX_PCIE_FLAG_PM_RUNTIME | IMX_PCIE_FLAG_SUPPORTS_SUSPEND, .ltssm_off = IMX95_PE0_GEN_CTRL_3, .ltssm_mask = IMX95_PCIE_LTSSM_EN, -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2] PCI: imx6: Fix i.MX6Q/DL boot hang by separating PHY power and reference clock control 2026-07-08 3:59 [PATCH v2] PCI: imx6: Add runtime PM support for i.MX95 hongxing.zhu @ 2026-07-08 3:59 ` hongxing.zhu 2026-07-08 15:28 ` Frank Li 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability hongxing.zhu 1 sibling, 1 reply; 7+ messages in thread From: hongxing.zhu @ 2026-07-08 3:59 UTC (permalink / raw) To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, s.hauer, kernel, festevam Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu From: Richard Zhu <hongxing.zhu@nxp.com> Commit 610fa91d9863 ("PCI: imx6: Assert PERST# before enabling regulators") introduced a boot hang on i.MX6Q/DL variants by changing the initialization sequence. The issue stems from coupling PHY power (TEST_PD) and reference clock (REF_CLK_EN) control in imx6q_pcie_enable_ref_clk(). When these are managed together, the timing between PHY power-up and reference clock enablement cannot be properly controlled, leading to initialization failures. Fix this by separating the two concerns: - Move PHY power control (TEST_PD) to imx6q_pcie_core_reset() where it logically belongs with reset operations. This ensures PHY power state is managed as part of the core reset sequence. - Update imx6qp_pcie_core_reset() to call imx6q_pcie_core_reset() for shared PHY power management, avoiding code duplication. - Make imx6q_pcie_enable_ref_clk() responsible only for reference clock (REF_CLK_EN) control, simplifying its purpose. - Remove the 10us delay workaround from imx6q_pcie_enable_ref_clk() as proper sequencing is now handled by the core_reset functions. This refactoring ensures PHY power is controlled during reset operations, fixing the boot hang while improving code maintainability. Fixes: 610fa91d9863 ("PCI: imx6: Assert PERST# before enabling regulators") Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> --- Changes in v2: Regarding sashiko's reivew, invoke imx_pcie_assert_core_reset() explicitly in error path of imx_pcie_host_init() and imx_pcie_host_exit(). --- drivers/pci/controller/dwc/pci-imx6.c | 45 ++++++++++++--------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 9406bba36953f..53f3da6ab30d5 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -680,21 +680,12 @@ static int imx_pcie_attach_pd(struct device *dev) static int imx6q_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable) { - if (enable) { - /* power up core phy and enable ref clock */ - regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD); - /* - * The async reset input need ref clock to sync internally, - * when the ref clock comes after reset, internal synced - * reset time is too short, cannot meet the requirement. - * Add a ~10us delay here. - */ - usleep_range(10, 100); - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN); - } else { - regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN); - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD); - } + if (enable) + regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN); + else + regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN); return 0; } @@ -823,23 +814,25 @@ static int imx6sx_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) return 0; } -static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) +static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) { - regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_SW_RST, - assert ? IMX6Q_GPR1_PCIE_SW_RST : 0); - if (!assert) - usleep_range(200, 500); + if (assert) + regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD); + else + regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD); return 0; } -static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) +static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) { + imx6q_pcie_core_reset(imx_pcie, assert); + regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_SW_RST, + assert ? IMX6Q_GPR1_PCIE_SW_RST : 0); if (!assert) - return 0; - - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD); - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN); + usleep_range(200, 500); return 0; } @@ -1445,6 +1438,7 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp) return 0; err_phy_off: + imx_pcie_assert_core_reset(imx_pcie); phy_power_off(imx_pcie->phy); err_phy_exit: phy_exit(imx_pcie->phy); @@ -1471,6 +1465,7 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp) dev_err(pci->dev, "unable to power off PHY\n"); phy_exit(imx_pcie->phy); } + imx_pcie_assert_core_reset(imx_pcie); imx_pcie_clk_disable(imx_pcie); pci_pwrctrl_power_off_devices(pci->dev); -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: imx6: Fix i.MX6Q/DL boot hang by separating PHY power and reference clock control 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Fix i.MX6Q/DL boot hang by separating PHY power and reference clock control hongxing.zhu @ 2026-07-08 15:28 ` Frank Li 0 siblings, 0 replies; 7+ messages in thread From: Frank Li @ 2026-07-08 15:28 UTC (permalink / raw) To: hongxing.zhu Cc: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu On Wed, Jul 08, 2026 at 11:59:27AM +0800, hongxing.zhu@oss.nxp.com wrote: > From: Richard Zhu <hongxing.zhu@nxp.com> > > Commit 610fa91d9863 ("PCI: imx6: Assert PERST# before enabling regulators") > introduced a boot hang on i.MX6Q/DL variants by changing the initialization > sequence. > > The issue stems from coupling PHY power (TEST_PD) and reference clock > (REF_CLK_EN) control in imx6q_pcie_enable_ref_clk(). When these are > managed together, the timing between PHY power-up and reference clock > enablement cannot be properly controlled, leading to initialization > failures. > > Fix this by separating the two concerns: > > - Move PHY power control (TEST_PD) to imx6q_pcie_core_reset() where it > logically belongs with reset operations. This ensures PHY power state > is managed as part of the core reset sequence. > > - Update imx6qp_pcie_core_reset() to call imx6q_pcie_core_reset() for > shared PHY power management, avoiding code duplication. > > - Make imx6q_pcie_enable_ref_clk() responsible only for reference clock > (REF_CLK_EN) control, simplifying its purpose. > > - Remove the 10us delay workaround from imx6q_pcie_enable_ref_clk() as > proper sequencing is now handled by the core_reset functions. > > This refactoring ensures PHY power is controlled during reset > operations, fixing the boot hang while improving code maintainability. > > Fixes: 610fa91d9863 ("PCI: imx6: Assert PERST# before enabling regulators") > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> > --- look more symmetry than before. Reviewed-by: Frank Li <Frank.Li@nxp.com> > Changes in v2: > Regarding sashiko's reivew, invoke imx_pcie_assert_core_reset() explicitly > in error path of imx_pcie_host_init() and imx_pcie_host_exit(). > --- > drivers/pci/controller/dwc/pci-imx6.c | 45 ++++++++++++--------------- > 1 file changed, 20 insertions(+), 25 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c > index 9406bba36953f..53f3da6ab30d5 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -680,21 +680,12 @@ static int imx_pcie_attach_pd(struct device *dev) > > static int imx6q_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable) > { > - if (enable) { > - /* power up core phy and enable ref clock */ > - regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD); > - /* > - * The async reset input need ref clock to sync internally, > - * when the ref clock comes after reset, internal synced > - * reset time is too short, cannot meet the requirement. > - * Add a ~10us delay here. > - */ > - usleep_range(10, 100); > - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN); > - } else { > - regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN); > - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD); > - } > + if (enable) > + regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, > + IMX6Q_GPR1_PCIE_REF_CLK_EN); > + else > + regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, > + IMX6Q_GPR1_PCIE_REF_CLK_EN); > > return 0; > } > @@ -823,23 +814,25 @@ static int imx6sx_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) > return 0; > } > > -static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) > +static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) > { > - regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_SW_RST, > - assert ? IMX6Q_GPR1_PCIE_SW_RST : 0); > - if (!assert) > - usleep_range(200, 500); > + if (assert) > + regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, > + IMX6Q_GPR1_PCIE_TEST_PD); > + else > + regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, > + IMX6Q_GPR1_PCIE_TEST_PD); > > return 0; > } > > -static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) > +static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert) > { > + imx6q_pcie_core_reset(imx_pcie, assert); > + regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_SW_RST, > + assert ? IMX6Q_GPR1_PCIE_SW_RST : 0); > if (!assert) > - return 0; > - > - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD); > - regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN); > + usleep_range(200, 500); > > return 0; > } > @@ -1445,6 +1438,7 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp) > return 0; > > err_phy_off: > + imx_pcie_assert_core_reset(imx_pcie); > phy_power_off(imx_pcie->phy); > err_phy_exit: > phy_exit(imx_pcie->phy); > @@ -1471,6 +1465,7 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp) > dev_err(pci->dev, "unable to power off PHY\n"); > phy_exit(imx_pcie->phy); > } > + imx_pcie_assert_core_reset(imx_pcie); > imx_pcie_clk_disable(imx_pcie); > > pci_pwrctrl_power_off_devices(pci->dev); > -- > 2.34.1 > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability 2026-07-08 3:59 [PATCH v2] PCI: imx6: Add runtime PM support for i.MX95 hongxing.zhu 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Fix i.MX6Q/DL boot hang by separating PHY power and reference clock control hongxing.zhu @ 2026-07-08 3:59 ` hongxing.zhu 2026-07-08 15:19 ` Frank Li 1 sibling, 1 reply; 7+ messages in thread From: hongxing.zhu @ 2026-07-08 3:59 UTC (permalink / raw) To: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, s.hauer, kernel, festevam Cc: linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu From: Richard Zhu <hongxing.zhu@nxp.com> Bandwidth marginality was observed during i.MX95 Gen3 PCIe tests with the default MPLLB_BINDWIDTH value. This margin degradation worsens across voltage and temperature (VT) variations and different test matrices, potentially causing link stability issues. Testing with MPLLB_BINDWIDTH value of 140 (0x8c) shows significant improvement in bandwidth margins across all VT conditions and test scenarios. Implement PHY register write helper function and configure: - MPLLB_BW_OVRD_IN = 140 (0x8c) for improved bandwidth margin - MPLLB_BW_OVRD_EN to enable the override This ensures robust PCIe Gen3 performance across all operating conditions. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> --- Changes in v2: Update the register name and bit definitions. Don't move IMX95_PCIE_PHY_CR_PARA_SEL settings. --- drivers/pci/controller/dwc/pci-imx6.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 53f3da6ab30d5..5f75aa09e0377 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -80,6 +80,15 @@ #define IMX95_SID_MASK GENMASK(5, 0) #define IMX95_MAX_LUT 32 +#define IMX95_PCIE_PHY_REG_ADDR 0x3008 +#define IMX95_PCIE_PHY_REG_EN BIT(31) +#define IMX95_PCIE_PHY_REG_ADDR_MASK GENMASK(15, 0) +#define IMX95_PCIE_PHY_REG_DATA 0x300c +#define IMX95_PCIE_PHY_MPLLB_OVRD_IN 0x2004 +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN 0x400 +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN 0x2005 +#define IMX95_PCIE_PHY_MPLLB_BW 0x8c + #define IMX95_PCIE_RST_CTRL 0x3010 #define IMX95_PCIE_COLD_RST BIT(0) @@ -269,6 +278,16 @@ static int imx95_pcie_select_ref_clk_src(struct imx_pcie *imx_pcie) return 0; } +static void imx95_pcie_phy_write(struct imx_pcie *imx_pcie, int addr, u16 data) +{ + udelay(200); + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_ADDR, + IMX95_PCIE_PHY_REG_EN, IMX95_PCIE_PHY_REG_EN); + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_ADDR, + IMX95_PCIE_PHY_REG_ADDR_MASK, addr); + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_DATA, data); +} + static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) { /* @@ -289,6 +308,11 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) IMX95_PCIE_PHY_CR_PARA_SEL, IMX95_PCIE_PHY_CR_PARA_SEL); + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, + IMX95_PCIE_PHY_MPLLB_BW); + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_IN, + IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN); + return 0; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability hongxing.zhu @ 2026-07-08 15:19 ` Frank Li 2026-07-09 7:55 ` Hongxing Zhu (OSS) 0 siblings, 1 reply; 7+ messages in thread From: Frank Li @ 2026-07-08 15:19 UTC (permalink / raw) To: hongxing.zhu Cc: frank.li, l.stach, lpieralisi, kwilczynski, mani, robh, bhelgaas, s.hauer, kernel, festevam, linux-pci, linux-arm-kernel, imx, linux-kernel, Richard Zhu On Wed, Jul 08, 2026 at 11:59:28AM +0800, hongxing.zhu@oss.nxp.com wrote: > From: Richard Zhu <hongxing.zhu@nxp.com> > > Bandwidth marginality was observed during i.MX95 Gen3 PCIe tests with > the default MPLLB_BINDWIDTH value. This margin degradation worsens > across voltage and temperature (VT) variations and different test > matrices, potentially causing link stability issues. > > Testing with MPLLB_BINDWIDTH value of 140 (0x8c) shows significant > improvement in bandwidth margins across all VT conditions and test > scenarios. > > Implement PHY register write helper function and configure: > - MPLLB_BW_OVRD_IN = 140 (0x8c) for improved bandwidth margin > - MPLLB_BW_OVRD_EN to enable the override > > This ensures robust PCIe Gen3 performance across all operating > conditions. > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> > --- > Changes in v2: > Update the register name and bit definitions. > Don't move IMX95_PCIE_PHY_CR_PARA_SEL settings. > --- > drivers/pci/controller/dwc/pci-imx6.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c > index 53f3da6ab30d5..5f75aa09e0377 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -80,6 +80,15 @@ > #define IMX95_SID_MASK GENMASK(5, 0) > #define IMX95_MAX_LUT 32 > > +#define IMX95_PCIE_PHY_REG_ADDR 0x3008 > +#define IMX95_PCIE_PHY_REG_EN BIT(31) > +#define IMX95_PCIE_PHY_REG_ADDR_MASK GENMASK(15, 0) > +#define IMX95_PCIE_PHY_REG_DATA 0x300c > +#define IMX95_PCIE_PHY_MPLLB_OVRD_IN 0x2004 > +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN 0x400 > +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN 0x2005 This one IMX95_PCIE_PHY_MPLLB_BW_IN to keep naming consistent write IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN -> IMX95_PCIE_PHY_MPLLB_OVRD_IN write IMX95_PCIE_PHY_MPLLB_BW -> IMX95_PCIE_PHY_MPLLB_BW_IN > +#define IMX95_PCIE_PHY_MPLLB_BW 0x8c 0x8c only one special value. IMX95_PCIE_PHY_MPLLB_BW_XXX put special name for 0x8c, if no means, you can put 0x8c direct at imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, 0x8c) We need knows what's macro means, like it is offset of regiser or it is field in register easily. Frank > + > #define IMX95_PCIE_RST_CTRL 0x3010 > #define IMX95_PCIE_COLD_RST BIT(0) > > @@ -269,6 +278,16 @@ static int imx95_pcie_select_ref_clk_src(struct imx_pcie *imx_pcie) > return 0; > } > > +static void imx95_pcie_phy_write(struct imx_pcie *imx_pcie, int addr, u16 data) > +{ > + udelay(200); > + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_ADDR, > + IMX95_PCIE_PHY_REG_EN, IMX95_PCIE_PHY_REG_EN); > + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_ADDR, > + IMX95_PCIE_PHY_REG_ADDR_MASK, addr); > + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_DATA, data); > +} > + > static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) > { > /* > @@ -289,6 +308,11 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) > IMX95_PCIE_PHY_CR_PARA_SEL, > IMX95_PCIE_PHY_CR_PARA_SEL); > > + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, > + IMX95_PCIE_PHY_MPLLB_BW); > + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_IN, > + IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN); > + > return 0; > } > > -- > 2.34.1 > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability 2026-07-08 15:19 ` Frank Li @ 2026-07-09 7:55 ` Hongxing Zhu (OSS) 2026-07-09 15:08 ` Frank Li 0 siblings, 1 reply; 7+ messages in thread From: Hongxing Zhu (OSS) @ 2026-07-09 7:55 UTC (permalink / raw) To: Frank Li (OSS), Hongxing Zhu (OSS) Cc: Frank Li, l.stach@pengutronix.de, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, bhelgaas@google.com, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com, linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev, linux-kernel@vger.kernel.org, Hongxing Zhu > -----Original Message----- > From: Frank Li (OSS) <frank.li@oss.nxp.com> > Sent: Wednesday, July 8, 2026 11:19 PM > To: Hongxing Zhu (OSS) <hongxing.zhu@oss.nxp.com> > Cc: Frank Li <frank.li@nxp.com>; l.stach@pengutronix.de; lpieralisi@kernel.org; > kwilczynski@kernel.org; mani@kernel.org; robh@kernel.org; > bhelgaas@google.com; s.hauer@pengutronix.de; kernel@pengutronix.de; > festevam@gmail.com; linux-pci@vger.kernel.org; linux-arm- > kernel@lists.infradead.org; imx@lists.linux.dev; linux-kernel@vger.kernel.org; > Hongxing Zhu <hongxing.zhu@nxp.com> > Subject: Re: [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 > Gen3 PCIe stability > > On Wed, Jul 08, 2026 at 11:59:28AM +0800, hongxing.zhu@oss.nxp.com wrote: > > From: Richard Zhu <hongxing.zhu@nxp.com> > > > > Bandwidth marginality was observed during i.MX95 Gen3 PCIe tests with > > the default MPLLB_BINDWIDTH value. This margin degradation worsens > > across voltage and temperature (VT) variations and different test > > matrices, potentially causing link stability issues. > > > > Testing with MPLLB_BINDWIDTH value of 140 (0x8c) shows significant > > improvement in bandwidth margins across all VT conditions and test > > scenarios. > > > > Implement PHY register write helper function and configure: > > - MPLLB_BW_OVRD_IN = 140 (0x8c) for improved bandwidth margin > > - MPLLB_BW_OVRD_EN to enable the override > > > > This ensures robust PCIe Gen3 performance across all operating > > conditions. > > > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> > > --- > > Changes in v2: > > Update the register name and bit definitions. > > Don't move IMX95_PCIE_PHY_CR_PARA_SEL settings. > > --- > > drivers/pci/controller/dwc/pci-imx6.c | 24 ++++++++++++++++++++++++ > > 1 file changed, 24 insertions(+) > > > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c > > b/drivers/pci/controller/dwc/pci-imx6.c > > index 53f3da6ab30d5..5f75aa09e0377 100644 > > --- a/drivers/pci/controller/dwc/pci-imx6.c > > +++ b/drivers/pci/controller/dwc/pci-imx6.c > > @@ -80,6 +80,15 @@ > > #define IMX95_SID_MASK GENMASK(5, 0) > > #define IMX95_MAX_LUT 32 > > > > +#define IMX95_PCIE_PHY_REG_ADDR 0x3008 > > +#define IMX95_PCIE_PHY_REG_EN BIT(31) > > +#define IMX95_PCIE_PHY_REG_ADDR_MASK GENMASK(15, 0) > > +#define IMX95_PCIE_PHY_REG_DATA 0x300c > > +#define IMX95_PCIE_PHY_MPLLB_OVRD_IN 0x2004 > > +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN 0x400 > > > +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN 0x2005 > > This one IMX95_PCIE_PHY_MPLLB_BW_IN to keep naming consistent > > write IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN -> > IMX95_PCIE_PHY_MPLLB_OVRD_IN write IMX95_PCIE_PHY_MPLLB_BW -> > IMX95_PCIE_PHY_MPLLB_BW_IN > > > +#define IMX95_PCIE_PHY_MPLLB_BW 0x8c > > 0x8c only one special value. > > IMX95_PCIE_PHY_MPLLB_BW_XXX put special name for 0x8c, if no means, you > can put 0x8c direct at > > imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, > 0x8c) > > We need knows what's macro means, like it is offset of regiser or it is field in > register easily. How about add some comments as below? +/* BIT(10): Override enable for mpllb_bandwidth[15:0] */ #define IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN 0x400 -#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN 0x2005 -#define IMX95_PCIE_PHY_MPLLB_BW 0x8c +/* Register offset: Override value for mpllb_bandwidth[15:0] */ +#define IMX95_PCIE_PHY_MPLLB_BW_IN 0x2005 +#define IMX95_PCIE_PHY_MPLLB_BW_VAL 0x8c #define IMX95_PCIE_RST_CTRL 0x3010 #define IMX95_PCIE_COLD_RST BIT(0) @@ -309,8 +311,8 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) IMX95_PCIE_PHY_CR_PARA_SEL, IMX95_PCIE_PHY_CR_PARA_SEL); - imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, - IMX95_PCIE_PHY_MPLLB_BW); + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_BW_IN, + IMX95_PCIE_PHY_MPLLB_BW_VAL); Best Regards Richard Zhu > > Frank > > > + > > #define IMX95_PCIE_RST_CTRL 0x3010 > > #define IMX95_PCIE_COLD_RST BIT(0) > > > > @@ -269,6 +278,16 @@ static int imx95_pcie_select_ref_clk_src(struct > imx_pcie *imx_pcie) > > return 0; > > } > > > > +static void imx95_pcie_phy_write(struct imx_pcie *imx_pcie, int addr, > > +u16 data) { > > + udelay(200); > > + regmap_update_bits(imx_pcie->iomuxc_gpr, > IMX95_PCIE_PHY_REG_ADDR, > > + IMX95_PCIE_PHY_REG_EN, > IMX95_PCIE_PHY_REG_EN); > > + regmap_update_bits(imx_pcie->iomuxc_gpr, > IMX95_PCIE_PHY_REG_ADDR, > > + IMX95_PCIE_PHY_REG_ADDR_MASK, addr); > > + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_DATA, > data); } > > + > > static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) { > > /* > > @@ -289,6 +308,11 @@ static int imx95_pcie_init_phy(struct imx_pcie > *imx_pcie) > > IMX95_PCIE_PHY_CR_PARA_SEL, > > IMX95_PCIE_PHY_CR_PARA_SEL); > > > > + imx95_pcie_phy_write(imx_pcie, > IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, > > + IMX95_PCIE_PHY_MPLLB_BW); > > + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_IN, > > + IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN); > > + > > return 0; > > } > > > > -- > > 2.34.1 > > > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability 2026-07-09 7:55 ` Hongxing Zhu (OSS) @ 2026-07-09 15:08 ` Frank Li 0 siblings, 0 replies; 7+ messages in thread From: Frank Li @ 2026-07-09 15:08 UTC (permalink / raw) To: Hongxing Zhu (OSS) Cc: Frank Li, l.stach@pengutronix.de, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, bhelgaas@google.com, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com, linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev, linux-kernel@vger.kernel.org, Hongxing Zhu On Thu, Jul 09, 2026 at 07:55:10AM +0000, Hongxing Zhu (OSS) wrote: > > -----Original Message----- > > From: Frank Li (OSS) <frank.li@oss.nxp.com> > > Sent: Wednesday, July 8, 2026 11:19 PM > > To: Hongxing Zhu (OSS) <hongxing.zhu@oss.nxp.com> > > Cc: Frank Li <frank.li@nxp.com>; l.stach@pengutronix.de; lpieralisi@kernel.org; > > kwilczynski@kernel.org; mani@kernel.org; robh@kernel.org; > > bhelgaas@google.com; s.hauer@pengutronix.de; kernel@pengutronix.de; > > festevam@gmail.com; linux-pci@vger.kernel.org; linux-arm- > > kernel@lists.infradead.org; imx@lists.linux.dev; linux-kernel@vger.kernel.org; > > Hongxing Zhu <hongxing.zhu@nxp.com> > > Subject: Re: [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 > > Gen3 PCIe stability > > > > On Wed, Jul 08, 2026 at 11:59:28AM +0800, hongxing.zhu@oss.nxp.com wrote: > > > From: Richard Zhu <hongxing.zhu@nxp.com> > > > > > > Bandwidth marginality was observed during i.MX95 Gen3 PCIe tests with > > > the default MPLLB_BINDWIDTH value. This margin degradation worsens > > > across voltage and temperature (VT) variations and different test > > > matrices, potentially causing link stability issues. > > > > > > Testing with MPLLB_BINDWIDTH value of 140 (0x8c) shows significant > > > improvement in bandwidth margins across all VT conditions and test > > > scenarios. > > > > > > Implement PHY register write helper function and configure: > > > - MPLLB_BW_OVRD_IN = 140 (0x8c) for improved bandwidth margin > > > - MPLLB_BW_OVRD_EN to enable the override > > > > > > This ensures robust PCIe Gen3 performance across all operating > > > conditions. > > > > > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> > > > --- > > > Changes in v2: > > > Update the register name and bit definitions. > > > Don't move IMX95_PCIE_PHY_CR_PARA_SEL settings. > > > --- > > > drivers/pci/controller/dwc/pci-imx6.c | 24 ++++++++++++++++++++++++ > > > 1 file changed, 24 insertions(+) > > > > > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c > > > b/drivers/pci/controller/dwc/pci-imx6.c > > > index 53f3da6ab30d5..5f75aa09e0377 100644 > > > --- a/drivers/pci/controller/dwc/pci-imx6.c > > > +++ b/drivers/pci/controller/dwc/pci-imx6.c > > > @@ -80,6 +80,15 @@ > > > #define IMX95_SID_MASK GENMASK(5, 0) > > > #define IMX95_MAX_LUT 32 > > > > > > +#define IMX95_PCIE_PHY_REG_ADDR 0x3008 > > > +#define IMX95_PCIE_PHY_REG_EN BIT(31) > > > +#define IMX95_PCIE_PHY_REG_ADDR_MASK GENMASK(15, 0) > > > +#define IMX95_PCIE_PHY_REG_DATA 0x300c > > > +#define IMX95_PCIE_PHY_MPLLB_OVRD_IN 0x2004 > > > +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN 0x400 > > > > > +#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN 0x2005 > > > > This one IMX95_PCIE_PHY_MPLLB_BW_IN to keep naming consistent > > > > write IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN -> > > IMX95_PCIE_PHY_MPLLB_OVRD_IN write IMX95_PCIE_PHY_MPLLB_BW -> > > IMX95_PCIE_PHY_MPLLB_BW_IN > > > > > +#define IMX95_PCIE_PHY_MPLLB_BW 0x8c > > > > 0x8c only one special value. > > > > IMX95_PCIE_PHY_MPLLB_BW_XXX put special name for 0x8c, if no means, you > > can put 0x8c direct at > > > > imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, > > 0x8c) > > > > We need knows what's macro means, like it is offset of regiser or it is field in > > register easily. > How about add some comments as below? > +/* BIT(10): Override enable for mpllb_bandwidth[15:0] */ > #define IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN 0x400 > -#define IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN 0x2005 > -#define IMX95_PCIE_PHY_MPLLB_BW 0x8c > +/* Register offset: Override value for mpllb_bandwidth[15:0] */ > +#define IMX95_PCIE_PHY_MPLLB_BW_IN 0x2005 > +#define IMX95_PCIE_PHY_MPLLB_BW_VAL 0x8c Okay Frank > > #define IMX95_PCIE_RST_CTRL 0x3010 > #define IMX95_PCIE_COLD_RST BIT(0) > @@ -309,8 +311,8 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) > IMX95_PCIE_PHY_CR_PARA_SEL, > IMX95_PCIE_PHY_CR_PARA_SEL); > > - imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, > - IMX95_PCIE_PHY_MPLLB_BW); > + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_BW_IN, > + IMX95_PCIE_PHY_MPLLB_BW_VAL); > > Best Regards > Richard Zhu > > > > Frank > > > > > + > > > #define IMX95_PCIE_RST_CTRL 0x3010 > > > #define IMX95_PCIE_COLD_RST BIT(0) > > > > > > @@ -269,6 +278,16 @@ static int imx95_pcie_select_ref_clk_src(struct > > imx_pcie *imx_pcie) > > > return 0; > > > } > > > > > > +static void imx95_pcie_phy_write(struct imx_pcie *imx_pcie, int addr, > > > +u16 data) { > > > + udelay(200); > > > + regmap_update_bits(imx_pcie->iomuxc_gpr, > > IMX95_PCIE_PHY_REG_ADDR, > > > + IMX95_PCIE_PHY_REG_EN, > > IMX95_PCIE_PHY_REG_EN); > > > + regmap_update_bits(imx_pcie->iomuxc_gpr, > > IMX95_PCIE_PHY_REG_ADDR, > > > + IMX95_PCIE_PHY_REG_ADDR_MASK, addr); > > > + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_REG_DATA, > > data); } > > > + > > > static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) { > > > /* > > > @@ -289,6 +308,11 @@ static int imx95_pcie_init_phy(struct imx_pcie > > *imx_pcie) > > > IMX95_PCIE_PHY_CR_PARA_SEL, > > > IMX95_PCIE_PHY_CR_PARA_SEL); > > > > > > + imx95_pcie_phy_write(imx_pcie, > > IMX95_PCIE_PHY_MPLLB_OVRD_BW_IN, > > > + IMX95_PCIE_PHY_MPLLB_BW); > > > + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_IN, > > > + IMX95_PCIE_PHY_MPLLB_OVRD_BW_EN); > > > + > > > return 0; > > > } > > > > > > -- > > > 2.34.1 > > > > > > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-09 15:09 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-08 3:59 [PATCH v2] PCI: imx6: Add runtime PM support for i.MX95 hongxing.zhu 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Fix i.MX6Q/DL boot hang by separating PHY power and reference clock control hongxing.zhu 2026-07-08 15:28 ` Frank Li 2026-07-08 3:59 ` [PATCH v2] PCI: imx6: Update MPLLB bandwidth to improve i.MX95 Gen3 PCIe stability hongxing.zhu 2026-07-08 15:19 ` Frank Li 2026-07-09 7:55 ` Hongxing Zhu (OSS) 2026-07-09 15:08 ` Frank Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).