Message ID | 20240409-opp_support-v10-2-1956e6be343f@quicinc.com |
---|---|
State | Superseded |
Headers | show |
Series | PCI: qcom: Add support for OPP | expand |
On Tue, Apr 09, 2024 at 03:43:20PM +0530, Krishna chaitanya chundru wrote: > To access PCIe registers of the host controller and endpoint PCIe > BAR space, config space the CPU-PCIe ICC (interconnect) path should 'To access the host controller registers and endpoint BAR/Config space,' > 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. > > In suspend to ram case there can be some DBI access. Except in suspend > to ram case disable CPU-PCIe ICC path after register space access > is done. > During S2RAM (Suspend-to-RAM), 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. > Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> > Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com> > --- > drivers/pci/controller/dwc/pcie-qcom.c | 43 ++++++++++++++++++++++++++++++---- > 1 file changed, 39 insertions(+), 4 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c > index 14772edcf0d3..e53422171c01 100644 > --- a/drivers/pci/controller/dwc/pcie-qcom.c > +++ b/drivers/pci/controller/dwc/pcie-qcom.c > @@ -245,6 +245,7 @@ struct qcom_pcie { > struct phy *phy; > struct gpio_desc *reset; > struct icc_path *icc_mem; > + struct icc_path *icc_cpu; > const struct qcom_pcie_cfg *cfg; > struct dentry *debugfs; > bool suspended; > @@ -1409,6 +1410,9 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie) > if (IS_ERR(pcie->icc_mem)) > return PTR_ERR(pcie->icc_mem); > > + pcie->icc_cpu = devm_of_icc_get(pci->dev, "cpu-pcie"); > + if (IS_ERR(pcie->icc_cpu)) > + return PTR_ERR(pcie->icc_cpu); > /* > * Some Qualcomm platforms require interconnect bandwidth constraints > * to be set before enabling interconnect clocks. > @@ -1418,7 +1422,20 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie) > */ > ret = icc_set_bw(pcie->icc_mem, 0, QCOM_PCIE_LINK_SPEED_TO_BW(1)); > if (ret) { > - dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n", > + dev_err(pci->dev, "Failed to set interconnect bandwidth for PCIe-MEM: %d\n", 'Failed to set bandwidth for PCIe-MEM interconnect path: %d\n' > + ret); > + return ret; > + } > + > + /* > + * Since the CPU-PCIe path is only used for activities like register > + * access of the host controller and endpoint Config/BAR space access, > + * HW team has recommended to use a minimal bandwidth of 1KBps just to Single space after 'a' > + * keep the path active. > + */ > + ret = icc_set_bw(pcie->icc_cpu, 0, kBps_to_icc(1)); > + if (ret) { > + dev_err(pci->dev, "Failed to set interconnect bandwidth for CPU-PCIe: %d\n", 'Failed to set bandwidth for CPU-PCIe interconnect path: %d\n' > ret); > return ret; > } > @@ -1448,7 +1465,7 @@ static void qcom_pcie_icc_update(struct qcom_pcie *pcie) > > ret = icc_set_bw(pcie->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed)); > if (ret) { > - dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n", > + dev_err(pci->dev, "Failed to set interconnect bandwidth for PCIe-MEM: %d\n", 'Failed to set bandwidth for PCIe-MEM interconnect path: %d\n' > ret); > } > } > @@ -1610,7 +1627,7 @@ static int qcom_pcie_suspend_noirq(struct device *dev) > */ > ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1)); > if (ret) { > - dev_err(dev, "Failed to set interconnect bandwidth: %d\n", ret); > + dev_err(dev, "Failed to set interconnect bandwidth for PCIe-MEM: %d\n", ret); 'Failed to set bandwidth for PCIe-MEM interconnect path: %d\n' > return ret; > } > > @@ -1634,7 +1651,17 @@ static int qcom_pcie_suspend_noirq(struct device *dev) > pcie->suspended = true; > } > > - return 0; > + /* > + * In suspend to ram case there are DBI access, except in suspend to ram case > + * remove the vote for CPU-PCIe path now, since at this point onwards, > + * no register access will be done. > + */ /* * Only disable CPU-PCIe interconnect path if the suspend is non-S2RAM. * Because on some platforms, DBI access can happen very late during the * S2RAM and a non-active CPU-PCIe interconnect path may lead to NoC * error. */ > + if (pm_suspend_target_state != PM_SUSPEND_MEM) { > + ret = icc_disable(pcie->icc_cpu); > + if (ret) > + dev_err(dev, "Failed to disable Interconnect path of CPU-PCIe: %d\n", ret); 'Failed to disable CPU-PCIe interconnect path: %d\n' > + } > + return ret; > } > > static int qcom_pcie_resume_noirq(struct device *dev) > @@ -1642,6 +1669,14 @@ static int qcom_pcie_resume_noirq(struct device *dev) > struct qcom_pcie *pcie = dev_get_drvdata(dev); > int ret; > > + if (pm_suspend_target_state != PM_SUSPEND_MEM) { > + ret = icc_enable(pcie->icc_cpu); > + if (ret) { > + dev_err(dev, "Failed to enable Interconnect path of CPU-PCIe: %d\n", ret); 'Failed to enable CPU-PCIe interconnect path: %d\n' - Mani
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 14772edcf0d3..e53422171c01 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -245,6 +245,7 @@ struct qcom_pcie { struct phy *phy; struct gpio_desc *reset; struct icc_path *icc_mem; + struct icc_path *icc_cpu; const struct qcom_pcie_cfg *cfg; struct dentry *debugfs; bool suspended; @@ -1409,6 +1410,9 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie) if (IS_ERR(pcie->icc_mem)) return PTR_ERR(pcie->icc_mem); + pcie->icc_cpu = devm_of_icc_get(pci->dev, "cpu-pcie"); + if (IS_ERR(pcie->icc_cpu)) + return PTR_ERR(pcie->icc_cpu); /* * Some Qualcomm platforms require interconnect bandwidth constraints * to be set before enabling interconnect clocks. @@ -1418,7 +1422,20 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie) */ ret = icc_set_bw(pcie->icc_mem, 0, QCOM_PCIE_LINK_SPEED_TO_BW(1)); if (ret) { - dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n", + dev_err(pci->dev, "Failed to set interconnect bandwidth for PCIe-MEM: %d\n", + ret); + return ret; + } + + /* + * Since the CPU-PCIe path is only used for activities like register + * access of the host controller and endpoint Config/BAR space access, + * HW team has recommended to use a minimal bandwidth of 1KBps just to + * keep the path active. + */ + ret = icc_set_bw(pcie->icc_cpu, 0, kBps_to_icc(1)); + if (ret) { + dev_err(pci->dev, "Failed to set interconnect bandwidth for CPU-PCIe: %d\n", ret); return ret; } @@ -1448,7 +1465,7 @@ static void qcom_pcie_icc_update(struct qcom_pcie *pcie) ret = icc_set_bw(pcie->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed)); if (ret) { - dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n", + dev_err(pci->dev, "Failed to set interconnect bandwidth for PCIe-MEM: %d\n", ret); } } @@ -1610,7 +1627,7 @@ static int qcom_pcie_suspend_noirq(struct device *dev) */ ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1)); if (ret) { - dev_err(dev, "Failed to set interconnect bandwidth: %d\n", ret); + dev_err(dev, "Failed to set interconnect bandwidth for PCIe-MEM: %d\n", ret); return ret; } @@ -1634,7 +1651,17 @@ static int qcom_pcie_suspend_noirq(struct device *dev) pcie->suspended = true; } - return 0; + /* + * In suspend to ram case there are DBI access, except in suspend to ram case + * remove the vote for CPU-PCIe path now, since at this point onwards, + * no register access will be done. + */ + if (pm_suspend_target_state != PM_SUSPEND_MEM) { + ret = icc_disable(pcie->icc_cpu); + if (ret) + dev_err(dev, "Failed to disable Interconnect path of CPU-PCIe: %d\n", ret); + } + return ret; } static int qcom_pcie_resume_noirq(struct device *dev) @@ -1642,6 +1669,14 @@ static int qcom_pcie_resume_noirq(struct device *dev) struct qcom_pcie *pcie = dev_get_drvdata(dev); int ret; + if (pm_suspend_target_state != PM_SUSPEND_MEM) { + ret = icc_enable(pcie->icc_cpu); + if (ret) { + dev_err(dev, "Failed to enable Interconnect path of CPU-PCIe: %d\n", ret); + return ret; + } + } + if (pcie->suspended) { ret = qcom_pcie_host_init(&pcie->pci->pp); if (ret)