Skip to content

Commit 796722c

Browse files
authored
PCI: qcom: Add D3cold support (#461)
PCI: qcom: Add D3cold support
2 parents cdf31ed + 6b2f39d commit 796722c

4 files changed

Lines changed: 37 additions & 15 deletions

File tree

drivers/pci/controller/dwc/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ config PCIE_QCOM
299299
select CRC8
300300
select PCIE_QCOM_COMMON
301301
select PCI_HOST_COMMON
302-
select PCI_PWRCTRL_SLOT
302+
select PCI_PWRCTRL_GENERIC
303303
help
304304
Say Y here to enable PCIe controller support on Qualcomm SoCs. The
305305
PCIe controller uses the DesignWare core plus Qualcomm-specific

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,8 @@ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
11671167
if (!pci_host_common_can_enter_d3cold(pci->pp.bridge))
11681168
return 0;
11691169

1170+
pci->pp.skip_pwrctrl_off = true;
1171+
11701172
if (pci->pp.ops->pme_turn_off) {
11711173
pci->pp.ops->pme_turn_off(&pci->pp);
11721174
} else {
@@ -1222,6 +1224,7 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
12221224
return 0;
12231225

12241226
pci->suspended = false;
1227+
pci->pp.skip_pwrctrl_off = false;
12251228

12261229
if (pci->pp.ops->init) {
12271230
ret = pci->pp.ops->init(&pci->pp);

drivers/pci/controller/dwc/pcie-designware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ struct dw_pcie_rp {
436436
bool ecam_enabled;
437437
bool native_ecam;
438438
bool skip_l23_ready;
439+
bool skip_pwrctrl_off;
439440
};
440441

441442
struct dw_pcie_ep_ops {

drivers/pci/controller/dwc/pcie-qcom.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,13 +1308,17 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
13081308
if (ret)
13091309
goto err_deinit;
13101310

1311-
ret = pci_pwrctrl_create_devices(pci->dev);
1312-
if (ret)
1313-
goto err_disable_phy;
1311+
if (!pci->suspended) {
1312+
ret = pci_pwrctrl_create_devices(pci->dev);
1313+
if (ret)
1314+
goto err_disable_phy;
1315+
}
13141316

1315-
ret = pci_pwrctrl_power_on_devices(pci->dev);
1316-
if (ret)
1317-
goto err_pwrctrl_destroy;
1317+
if (!pp->skip_pwrctrl_off) {
1318+
ret = pci_pwrctrl_power_on_devices(pci->dev);
1319+
if (ret)
1320+
goto err_pwrctrl_destroy;
1321+
}
13181322

13191323
if (pcie->cfg->ops->post_init) {
13201324
ret = pcie->cfg->ops->post_init(pcie);
@@ -1356,11 +1360,14 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)
13561360

13571361
qcom_pcie_perst_assert(pcie);
13581362

1359-
/*
1360-
* No need to destroy pwrctrl devices as this function only gets called
1361-
* during system suspend as of now.
1362-
*/
1363-
pci_pwrctrl_power_off_devices(pci->dev);
1363+
if (!pci->pp.skip_pwrctrl_off) {
1364+
/*
1365+
* No need to destroy pwrctrl devices as this function only gets called
1366+
* during system suspend as of now.
1367+
*/
1368+
pci_pwrctrl_power_off_devices(pci->dev);
1369+
}
1370+
13641371
qcom_pcie_phy_power_off(pcie);
13651372
pcie->cfg->ops->deinit(pcie);
13661373
}
@@ -2051,11 +2058,16 @@ static int qcom_pcie_resume_noirq(struct device *dev)
20512058
ret = icc_enable(pcie->icc_mem);
20522059
if (ret) {
20532060
dev_err(dev, "Failed to enable PCIe-MEM interconnect path: %d\n", ret);
2054-
return ret;
2061+
goto disable_icc_cpu;
20552062
}
2063+
2064+
/*
2065+
* Ignore -ENODEV & -EIO here since it is expected when no endpoint is
2066+
* connected to the PCIe link.
2067+
*/
20562068
ret = dw_pcie_resume_noirq(pcie->pci);
2057-
if (ret && (ret != -ETIMEDOUT))
2058-
return ret;
2069+
if (ret && ret != -ENODEV && ret != -EIO)
2070+
goto disable_icc_mem;
20592071
} else {
20602072
if (pm_suspend_target_state != PM_SUSPEND_MEM) {
20612073
ret = icc_enable(pcie->icc_cpu);
@@ -2070,6 +2082,12 @@ static int qcom_pcie_resume_noirq(struct device *dev)
20702082
qcom_pcie_icc_opp_update(pcie);
20712083

20722084
return 0;
2085+
disable_icc_mem:
2086+
icc_disable(pcie->icc_mem);
2087+
disable_icc_cpu:
2088+
icc_disable(pcie->icc_cpu);
2089+
2090+
return ret;
20732091
}
20742092

20752093
static const struct of_device_id qcom_pcie_match[] = {

0 commit comments

Comments
 (0)