Rockchip's vendor kernel does these calls before starting the actual
process of going into L2 state. I'm not sure about the rationale,
hopefully Shawn can help out with that.
Cc: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Sebastian Reichel <redacted>
---
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3be83feccecb..fbdde82c95b6 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -74,6 +74,9 @@
#define PCIE_CLKREQ_NOT_READY FIELD_PREP_WM16(BIT(0), 0)
#define PCIE_CLKREQ_PULL_DOWN FIELD_PREP_WM16(GENMASK(13, 12), 1)
+/* General Debug Register */
+#define PCIE_CLIENT_GENERAL_DEBUG 0x104
+
/* RASDES TBA information */
#define PCIE_CLIENT_CDM_RASDES_TBA_INFO_CMN 0x154
#define PCIE_CLIENT_CDM_RASDES_TBA_L1_1 BIT(4)
@@ -776,6 +779,11 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
return ret;
}
+static inline void rockchip_pcie_link_status_clear(struct rockchip_pcie *rockchip)
+{
+ rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_GENERAL_DEBUG, 0x0);
+}
+
static int rockchip_pcie_suspend(struct device *dev)
{
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);@@ -789,6 +797,11 @@ static int rockchip_pcie_suspend(struct device *dev)
rockchip->intx = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_MASK_LEGACY);
+ /* All sub-devices are in D3hot by PCIe stack */
+ dw_pcie_dbi_ro_wr_dis(pci);
+
+ rockchip_pcie_link_status_clear(rockchip);
+
ret = dw_pcie_suspend_noirq(pci);
if (ret)
return ret;
--
2.51.0