[PATCH v1] PCI: imx6: Update MPLLB bandwidth for i.MX95 PCIe Gen3 stability
From: <hidden>
Date: 2026-07-06 07:00:23
Also in:
imx, linux-pci, lkml
Subsystem:
pci driver for imx6, pci native host bridge and endpoint drivers, pci subsystem, the rest · Maintainers:
Richard Zhu, Lucas Stach, Lorenzo Pieralisi, Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas, Linus Torvalds
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> --- drivers/pci/controller/dwc/pci-imx6.c | 31 +++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6924a06bde305..023145b0dd2c7 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_BW_OVRD_EN 0x400 +#define IMX95_PCIE_PHY_MPLLB_BW_OVRD_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,20 @@ 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) +{ + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0, + IMX95_PCIE_PHY_CR_PARA_SEL, + IMX95_PCIE_PHY_CR_PARA_SEL); + + fsleep(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) { /*
@@ -284,10 +307,10 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_1, IMX95_PCIE_SYS_AUX_PWR_DET); - regmap_update_bits(imx_pcie->iomuxc_gpr, - IMX95_PCIE_SS_RW_REG_0, - IMX95_PCIE_PHY_CR_PARA_SEL, - IMX95_PCIE_PHY_CR_PARA_SEL); + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_BW_OVRD_IN, + IMX95_PCIE_PHY_MPLLB_BW); + imx95_pcie_phy_write(imx_pcie, IMX95_PCIE_PHY_MPLLB_OVRD_IN, + IMX95_PCIE_PHY_MPLLB_BW_OVRD_EN); return 0; }
--
2.34.1