From: Jian Yang Date: Mon, 13 Apr 2026 07:13:55 +0000 (+0800) Subject: PCI: mediatek-gen3: Fix PERST# control timing during system startup X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22fc8822d14663cad66f2852e7a14f442e1d3ab5;p=thirdparty%2Flinux.git PCI: mediatek-gen3: Fix PERST# control timing during system startup Some MediaTek chips stop generating REFCLK if the PCIE_PHY_RSTB signal of PCIe controller is asserted at the start of mtk_pcie_devices_power_up(). But the driver deasserts PCIE_PHY_RSTB together with PCIE_PE_RSTB signal that is used to deassert PERST#. This violates PCIe CEM r6.0, sec 2.11.2, which mandates waiting for 100ms (PCIE_T_PVPERL_MS) after power becomes stable. Move the MAC, PHY and BRG reset deassert code above the PCIE_T_PVPERL_MS delay and leave the PCIE_PE_RSTB deassertion after the delay. Add the 10ms delay mentioned in the MediaTek datasheet after asserting PCIE_BRG_RSTB and before accessing the PCIE_RST_CTRL_REG register. Signed-off-by: Jian Yang [mani: commit log and comments rewording] Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260413071401.1151-2-jian.yang@mediatek.com --- diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index b0accd8285892..01badc4f93119 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -63,6 +63,12 @@ #define PCIE_BRG_RSTB BIT(2) #define PCIE_PE_RSTB BIT(3) +/* + * As described in the datasheet of MediaTek PCIe Gen3 controller, wait 10ms + * after setting PCIE_BRG_RSTB, and before accessing PCIe internal registers. + */ +#define PCIE_BRG_RST_RDY_MS 10 + #define PCIE_LTSSM_STATUS_REG 0x150 #define PCIE_LTSSM_STATE_MASK GENMASK(28, 24) #define PCIE_LTSSM_STATE(val) ((val & PCIE_LTSSM_STATE_MASK) >> 24) @@ -430,6 +436,21 @@ static int mtk_pcie_devices_power_up(struct mtk_gen3_pcie *pcie) return err; } + /* + * Some of MediaTek's chips won't output REFCLK when PCIE_PHY_RSTB is + * asserted, we have to de-assert MAC & PHY & BRG reset signals first + * to allow the REFCLK to be stable. While PCIE_BRG_RSTB is asserted, + * there is a short period during which the PCIe internal register + * cannot be accessed, so we need to wait 10ms here. + */ + msleep(PCIE_BRG_RST_RDY_MS); + + if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) { + /* De-assert MAC, PHY and BRG reset signals */ + val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB); + writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); + } + /* * Described in PCIe CEM specification revision 6.0. * @@ -439,9 +460,8 @@ static int mtk_pcie_devices_power_up(struct mtk_gen3_pcie *pcie) msleep(PCIE_T_PVPERL_MS); if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) { - /* De-assert reset signals */ - val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | - PCIE_PE_RSTB); + /* De-assert PERST# signal */ + val &= ~PCIE_PE_RSTB; writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); }