@@ -68,6 +68,9 @@
#define PCIE_MSI_SET_ENABLE_REG 0x190
#define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0)
+#define PCIE_MISC_CTRL_REG 0x348
+#define PCIE_DISABLE_DVFSRC_VLT_REQ BIT(1)
+
#define PCIE_MSI_SET_BASE_REG 0xc00
#define PCIE_MSI_SET_OFFSET 0x10
#define PCIE_MSI_SET_STATUS_OFFSET 0x04
@@ -297,6 +300,34 @@ static int mtk_pcie_startup_port(struct mtk_pcie_port *port)
val &= ~PCIE_INTX_ENABLE;
writel_relaxed(val, port->base + PCIE_INT_ENABLE_REG);
+ /*
+ * PCIe Gen3 PHY layer can not work properly when the requested voltage
+ * is lower than a specific level(e.g. 0.55V, it's depends on
+ * the chip manufacturing process).
+ *
+ * When the dvfsrc feature is implemented, the requested voltage
+ * may be reduced to a lower level in suspend mode, hence that
+ * the MAC layer will assert a HW signal to request the dvfsrc
+ * to raise voltage to normal mode, and it will wait the voltage
+ * ready signal from dvfsrc to decide if the LTSSM can start normally.
+ *
+ * When the dvfsrc feature is not implemented, the MAC layer still
+ * assert the voltage request to dvfsrc when exit suspend mode,
+ * but will not get the voltage ready signal, in this case, the LTSSM
+ * cannot start normally, and the PCIe link will be failed.
+ *
+ * If the property of "disable-dvfsrc-vlt-req" is presented
+ * in device node, we assume that the requested voltage is always
+ * higher enough to keep the PCIe Gen3 PHY active, and the voltage
+ * request to dvfsrc should be disabled.
+ */
+ val = readl_relaxed(port->base + PCIE_MISC_CTRL_REG);
+ val &= ~PCIE_DISABLE_DVFSRC_VLT_REQ;
+ if (of_property_read_bool(port->dev->of_node, "disable-dvfsrc-vlt-req"))
+ val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
+
+ writel_relaxed(val, port->base + PCIE_MISC_CTRL_REG);
+
/* Assert all reset signals */
val = readl_relaxed(port->base + PCIE_RST_CTRL_REG);
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;