In preparation to add support for the PCI-Express Gen3 controller
found in newer MediaTek SoCs, such as the Dimensity 9400 MT6991
and the MT8196 Chromebook SoC, add the definition for the PCIE
Resource Control register and a new sys_clk_rdy_time_us variable
in platform data.
If sys_clk_rdy_time_us is found (> 0), set the new value in the
aforementioned register only after configuring the controller to
RC mode, as this may otherwise be reset.
Overriding the register defaults for SYS_CLK_RDY_TIME allows to
work around sys_clk_rdy signal glitching in MT6991 and MT8196.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/pci/controller/pcie-mediatek-gen3.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index 5464b4ae5c20..8035f7f812aa 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -101,6 +101,9 @@
#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80
#define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04
+#define PCIE_RESOURCE_CTRL_REG 0xd2c
+#define PCIE_RSRC_SYS_CLK_RDY_TIME_MASK GENMASK(7, 0)
+
#define PCIE_ICMD_PM_REG 0x198
#define PCIE_TURN_OFF_LINK BIT(4)
@@ -148,6 +151,7 @@ enum mtk_gen3_pcie_flags {
* struct mtk_gen3_pcie_pdata - differentiate between host generations
* @power_up: pcie power_up callback
* @phy_resets: phy reset lines SoC data.
+ * @sys_clk_rdy_time_us: System clock ready time override (microseconds)
* @flags: pcie device flags.
*/
struct mtk_gen3_pcie_pdata {
@@ -156,6 +160,7 @@ struct mtk_gen3_pcie_pdata {
const char *id[MAX_NUM_PHY_RESETS];
int num_resets;
} phy_resets;
+ u8 sys_clk_rdy_time_us;
u32 flags;
};
@@ -436,6 +441,15 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
writel_relaxed(val, pcie->base + PCIE_CONF_LINK2_CTL_STS);
}
+ /* If parameter is present, adjust SYS_CLK_RDY_TIME to avoid glitching */
+ if (pcie->soc->sys_clk_rdy_time_us) {
+ val = readl_relaxed(pcie->base + PCIE_RESOURCE_CTRL_REG);
+ val &= ~PCIE_RSRC_SYS_CLK_RDY_TIME_MASK;
+ val |= FIELD_PREP(PCIE_RSRC_SYS_CLK_RDY_TIME_MASK,
+ pcie->soc->sys_clk_rdy_time_us);
+ writel_relaxed(val, pcie->base + PCIE_RESOURCE_CTRL_REG);
+ }
+
/* Set class code */
val = readl_relaxed(pcie->base + PCIE_PCI_IDS_1);
val &= ~GENMASK(31, 8);
--
2.49.0
On Thu, Jul 03, 2025 at 02:08:45PM GMT, AngeloGioacchino Del Regno wrote: > In preparation to add support for the PCI-Express Gen3 controller > found in newer MediaTek SoCs, such as the Dimensity 9400 MT6991 > and the MT8196 Chromebook SoC, add the definition for the PCIE > Resource Control register and a new sys_clk_rdy_time_us variable > in platform data. > > If sys_clk_rdy_time_us is found (> 0), set the new value in the > aforementioned register only after configuring the controller to > RC mode, as this may otherwise be reset. > > Overriding the register defaults for SYS_CLK_RDY_TIME allows to > work around sys_clk_rdy signal glitching in MT6991 and MT8196. > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/pci/controller/pcie-mediatek-gen3.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c > index 5464b4ae5c20..8035f7f812aa 100644 > --- a/drivers/pci/controller/pcie-mediatek-gen3.c > +++ b/drivers/pci/controller/pcie-mediatek-gen3.c > @@ -101,6 +101,9 @@ > #define PCIE_MSI_SET_ADDR_HI_BASE 0xc80 > #define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04 > > +#define PCIE_RESOURCE_CTRL_REG 0xd2c > +#define PCIE_RSRC_SYS_CLK_RDY_TIME_MASK GENMASK(7, 0) > + > #define PCIE_ICMD_PM_REG 0x198 > #define PCIE_TURN_OFF_LINK BIT(4) > > @@ -148,6 +151,7 @@ enum mtk_gen3_pcie_flags { > * struct mtk_gen3_pcie_pdata - differentiate between host generations > * @power_up: pcie power_up callback > * @phy_resets: phy reset lines SoC data. > + * @sys_clk_rdy_time_us: System clock ready time override (microseconds) > * @flags: pcie device flags. > */ > struct mtk_gen3_pcie_pdata { > @@ -156,6 +160,7 @@ struct mtk_gen3_pcie_pdata { > const char *id[MAX_NUM_PHY_RESETS]; > int num_resets; > } phy_resets; > + u8 sys_clk_rdy_time_us; > u32 flags; > }; > > @@ -436,6 +441,15 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) > writel_relaxed(val, pcie->base + PCIE_CONF_LINK2_CTL_STS); > } > > + /* If parameter is present, adjust SYS_CLK_RDY_TIME to avoid glitching */ > + if (pcie->soc->sys_clk_rdy_time_us) { > + val = readl_relaxed(pcie->base + PCIE_RESOURCE_CTRL_REG); > + val &= ~PCIE_RSRC_SYS_CLK_RDY_TIME_MASK; > + val |= FIELD_PREP(PCIE_RSRC_SYS_CLK_RDY_TIME_MASK, > + pcie->soc->sys_clk_rdy_time_us); Nit: Mask and update could be simplified with: FIELD_MODIFY(PCIE_RSRC_SYS_CLK_RDY_TIME_MASK, &val, pcie->soc->sys_clk_rdy_time_us); I'll ammend it while applying. - Mani -- மணிவண்ணன் சதாசிவம்
© 2016 - 2025 Red Hat, Inc.