Skip to content

Commit 980136d

Browse files
Krishna chaitanya chundrubjorn-helgaas
authored andcommitted
PCI: qcom: Add ICC bandwidth vote for CPU to PCIe path
To access the host controller registers of the host controller and the endpoint BAR/config space, the CPU-PCIe ICC (interconnect) path should be voted otherwise it may lead to NoC (Network on chip) timeout. We are surviving because of other driver voting for this path. As there is less access on this path compared to PCIe to mem path add minimum vote i.e 1KBps bandwidth always which is sufficient enough to keep the path active and is recommended by HW team. During S2RAM (Suspend-to-RAM), the DBI access can happen very late (while disabling the boot CPU). So do not disable the CPU-PCIe interconnect path during S2RAM as that may lead to NoC error. Link: https://lore.kernel.org/linux-pci/[email protected] Signed-off-by: Krishna chaitanya chundru <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Reviewed-by: Bryan O'Donoghue <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]>
1 parent 9123157 commit 980136d

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

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

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ struct qcom_pcie {
255255
struct phy *phy;
256256
struct gpio_desc *reset;
257257
struct icc_path *icc_mem;
258+
struct icc_path *icc_cpu;
258259
const struct qcom_pcie_cfg *cfg;
259260
struct dentry *debugfs;
260261
bool suspended;
@@ -1371,6 +1372,9 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
13711372
if (IS_ERR(pcie->icc_mem))
13721373
return PTR_ERR(pcie->icc_mem);
13731374

1375+
pcie->icc_cpu = devm_of_icc_get(pci->dev, "cpu-pcie");
1376+
if (IS_ERR(pcie->icc_cpu))
1377+
return PTR_ERR(pcie->icc_cpu);
13741378
/*
13751379
* Some Qualcomm platforms require interconnect bandwidth constraints
13761380
* to be set before enabling interconnect clocks.
@@ -1380,11 +1384,25 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
13801384
*/
13811385
ret = icc_set_bw(pcie->icc_mem, 0, QCOM_PCIE_LINK_SPEED_TO_BW(1));
13821386
if (ret) {
1383-
dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
1387+
dev_err(pci->dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n",
13841388
ret);
13851389
return ret;
13861390
}
13871391

1392+
/*
1393+
* Since the CPU-PCIe path is only used for activities like register
1394+
* access of the host controller and endpoint Config/BAR space access,
1395+
* HW team has recommended to use a minimal bandwidth of 1KBps just to
1396+
* keep the path active.
1397+
*/
1398+
ret = icc_set_bw(pcie->icc_cpu, 0, kBps_to_icc(1));
1399+
if (ret) {
1400+
dev_err(pci->dev, "Failed to set bandwidth for CPU-PCIe interconnect path: %d\n",
1401+
ret);
1402+
icc_set_bw(pcie->icc_mem, 0, 0);
1403+
return ret;
1404+
}
1405+
13881406
return 0;
13891407
}
13901408

@@ -1410,7 +1428,7 @@ static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
14101428

14111429
ret = icc_set_bw(pcie->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed));
14121430
if (ret) {
1413-
dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
1431+
dev_err(pci->dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n",
14141432
ret);
14151433
}
14161434
}
@@ -1572,7 +1590,7 @@ static int qcom_pcie_suspend_noirq(struct device *dev)
15721590
*/
15731591
ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1));
15741592
if (ret) {
1575-
dev_err(dev, "Failed to set interconnect bandwidth: %d\n", ret);
1593+
dev_err(dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n", ret);
15761594
return ret;
15771595
}
15781596

@@ -1596,14 +1614,33 @@ static int qcom_pcie_suspend_noirq(struct device *dev)
15961614
pcie->suspended = true;
15971615
}
15981616

1599-
return 0;
1617+
/*
1618+
* Only disable CPU-PCIe interconnect path if the suspend is non-S2RAM.
1619+
* Because on some platforms, DBI access can happen very late during the
1620+
* S2RAM and a non-active CPU-PCIe interconnect path may lead to NoC
1621+
* error.
1622+
*/
1623+
if (pm_suspend_target_state != PM_SUSPEND_MEM) {
1624+
ret = icc_disable(pcie->icc_cpu);
1625+
if (ret)
1626+
dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", ret);
1627+
}
1628+
return ret;
16001629
}
16011630

16021631
static int qcom_pcie_resume_noirq(struct device *dev)
16031632
{
16041633
struct qcom_pcie *pcie = dev_get_drvdata(dev);
16051634
int ret;
16061635

1636+
if (pm_suspend_target_state != PM_SUSPEND_MEM) {
1637+
ret = icc_enable(pcie->icc_cpu);
1638+
if (ret) {
1639+
dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", ret);
1640+
return ret;
1641+
}
1642+
}
1643+
16071644
if (pcie->suspended) {
16081645
ret = qcom_pcie_host_init(&pcie->pci->pp);
16091646
if (ret)

0 commit comments

Comments
 (0)