From 22fc8822d14663cad66f2852e7a14f442e1d3ab5 Mon Sep 17 00:00:00 2001 From: Jian Yang Date: Mon, 13 Apr 2026 15:13:55 +0800 Subject: [PATCH 1/4] 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 --- drivers/pci/controller/pcie-mediatek-gen3.c | 26 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index b0accd828589..01badc4f9311 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); } From 7a0e17e7a0816d532c0f02e8d64f603a4dc283ee Mon Sep 17 00:00:00 2001 From: Jian Yang Date: Mon, 13 Apr 2026 15:13:56 +0800 Subject: [PATCH 2/4] PCI: mediatek-gen3: Add a .shutdown() callback to control PERST# signal Add a .shutdown() callback to control the timing of PERST# and power during system shutdown to ensure that PERST# is asserted before power to the connector is removed, as required by PCIe CEM r6.0, sec 2.2. Signed-off-by: Jian Yang Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260413071401.1151-3-jian.yang@mediatek.com --- drivers/pci/controller/pcie-mediatek-gen3.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 01badc4f9311..8aec57626f5f 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -1286,6 +1286,14 @@ static void mtk_pcie_remove(struct platform_device *pdev) mtk_pcie_irq_teardown(pcie); } +static void mtk_pcie_shutdown(struct platform_device *pdev) +{ + struct mtk_gen3_pcie *pcie = platform_get_drvdata(pdev); + + mtk_pcie_devices_power_down(pcie); + mtk_pcie_power_down(pcie); +} + static void mtk_pcie_irq_save(struct mtk_gen3_pcie *pcie) { int i; @@ -1424,6 +1432,7 @@ MODULE_DEVICE_TABLE(of, mtk_pcie_of_match); static struct platform_driver mtk_pcie_driver = { .probe = mtk_pcie_probe, .remove = mtk_pcie_remove, + .shutdown = mtk_pcie_shutdown, .driver = { .name = "mtk-pcie-gen3", .of_match_table = mtk_pcie_of_match, From d39d55d7411c18ca6aeb63aafa8035f4ad8b317f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 5 May 2026 18:59:16 +0800 Subject: [PATCH 3/4] PCI: mediatek-gen3: Do full device power down on removal When power control for downstream devices was introduced in the mediatek-gen3 PCIe controller driver, only the power to the downstream devices was cut when the controller driver is removed. This matched existing behavior, but in hindsight a proper power down sequence should have been followed. Call mtk_pcie_devices_power_down() on driver removal so that in addition to removing power from the downstream devices, PERST# is asserted. Fixes: 1a152e21940a ("PCI: mediatek-gen3: Integrate new pwrctrl API") Signed-off-by: Chen-Yu Tsai Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260505105918.1823170-1-wenst@chromium.org --- drivers/pci/controller/pcie-mediatek-gen3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 8aec57626f5f..1da2166d1017 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -1280,7 +1280,7 @@ static void mtk_pcie_remove(struct platform_device *pdev) pci_remove_root_bus(host->bus); pci_unlock_rescan_remove(); - pci_pwrctrl_power_off_devices(pcie->dev); + mtk_pcie_devices_power_down(pcie); mtk_pcie_power_down(pcie); pci_pwrctrl_destroy_devices(pcie->dev); mtk_pcie_irq_teardown(pcie); From 8ba433753d9b131c2e43b1ff7ba8c5730cef8231 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 12 May 2026 18:33:45 +0800 Subject: [PATCH 4/4] PCI: mediatek-gen3: Fix incorrectly skipped pwrctrl error message When pwrctrl integration was added, the error message for pci_pwrctrl_create_devices() failure was incorrectly added after the goto statement, causing it to be skipped. Move the goto statement after the dev_err_probe() call so that the error message actually gets printed (or saved if probe is deferred). Fixes: 1a152e21940a ("PCI: mediatek-gen3: Integrate new pwrctrl API") Reported-by: Dan Carpenter Closes: https://lore.kernel.org/all/adjNaKB5KGpl6qIp@stanley.mountain/ Signed-off-by: Chen-Yu Tsai Signed-off-by: Manivannan Sadhasivam Reviewed-by: Hans Zhang <18255117159@163.com> Link: https://patch.msgid.link/20260512103347.1751080-1-wenst@chromium.org --- drivers/pci/controller/pcie-mediatek-gen3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 1da2166d1017..654e63f8fb57 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -1242,8 +1242,8 @@ static int mtk_pcie_probe(struct platform_device *pdev) err = pci_pwrctrl_create_devices(pcie->dev); if (err) { - goto err_tear_down_irq; dev_err_probe(dev, err, "failed to create pwrctrl devices\n"); + goto err_tear_down_irq; } err = mtk_pcie_setup(pcie);