linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] PCI: qcom: Add basic interconnect support
@ 2022-11-02  9:07 Johan Hovold
  2022-11-02  9:07 ` [PATCH v3 1/2] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects Johan Hovold
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Johan Hovold @ 2022-11-02  9:07 UTC (permalink / raw)
  To: Lorenzo Pieralisi, stanimir.k.varbanov
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Bjorn Helgaas,
	Rob Herring, Krzysztof Kozlowski, Krzysztof Wilczyński,
	Brian Masney, Manivannan Sadhasivam, linux-arm-msm, linux-pci,
	devicetree, linux-kernel, Johan Hovold

On Qualcomm platforms like SC8280XP and SA8540P interconnect bandwidth
must be requested before enabling interconnect clocks.

Add basic support for managing an optional "pcie-mem" interconnect path
by setting a low constraint before enabling clocks and updating it after
the link is up.

This is specifically needed to prevent a crash on SC8280XP/SA8540P when
the interconnect constraints are enforced during boot.

As support for these platforms was added in 6.1-rc1 it would be nice to
have this merged as a fix for 6.1, but deferring for 6.2 works as well.

Johan


Changes in v3
 - remove intermediate assignment in error path (Mani)
 - add WARN_ON_ONCE() as a reminder to anyone ever extending the
   driver with support for higher speeds to update the bandwidth table

Changes in v2
 - update the bindings so that the interconnect-names constraints apply
   to all platforms (Krzysztof)


Johan Hovold (2):
  dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects
  PCI: qcom: Add basic interconnect support

 .../devicetree/bindings/pci/qcom,pcie.yaml    | 20 +++++
 drivers/pci/controller/dwc/pcie-qcom.c        | 76 +++++++++++++++++++
 2 files changed, 96 insertions(+)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/2] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects
  2022-11-02  9:07 [PATCH v3 0/2] PCI: qcom: Add basic interconnect support Johan Hovold
@ 2022-11-02  9:07 ` Johan Hovold
  2022-11-02  9:07 ` [PATCH v3 2/2] PCI: qcom: Add basic interconnect support Johan Hovold
  2022-11-11 11:05 ` [PATCH v3 0/2] " Lorenzo Pieralisi
  2 siblings, 0 replies; 5+ messages in thread
From: Johan Hovold @ 2022-11-02  9:07 UTC (permalink / raw)
  To: Lorenzo Pieralisi, stanimir.k.varbanov
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Bjorn Helgaas,
	Rob Herring, Krzysztof Kozlowski, Krzysztof Wilczyński,
	Brian Masney, Manivannan Sadhasivam, linux-arm-msm, linux-pci,
	devicetree, linux-kernel, Johan Hovold, Rob Herring

Add the missing SC8280XP/SA8540P "pcie-mem" and "cpu-pcie" interconnect
paths to the bindings.

Fixes: 76d777ae045e ("dt-bindings: PCI: qcom: Add SC8280XP to binding")
Fixes: 76c4207f4085 ("dt-bindings: PCI: qcom: Add SA8540P to binding")
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 .../devicetree/bindings/pci/qcom,pcie.yaml    | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
index 54f07852d279..2f851c804bb0 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
@@ -62,6 +62,14 @@ properties:
     minItems: 3
     maxItems: 13
 
+  interconnects:
+    maxItems: 2
+
+  interconnect-names:
+    items:
+      - const: pcie-mem
+      - const: cpu-pcie
+
   resets:
     minItems: 1
     maxItems: 12
@@ -631,6 +639,18 @@ allOf:
           items:
             - const: pci # PCIe core reset
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,pcie-sa8540p
+              - qcom,pcie-sc8280xp
+    then:
+      required:
+        - interconnects
+        - interconnect-names
+
   - if:
       not:
         properties:
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/2] PCI: qcom: Add basic interconnect support
  2022-11-02  9:07 [PATCH v3 0/2] PCI: qcom: Add basic interconnect support Johan Hovold
  2022-11-02  9:07 ` [PATCH v3 1/2] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects Johan Hovold
@ 2022-11-02  9:07 ` Johan Hovold
  2022-11-03 12:34   ` Manivannan Sadhasivam
  2022-11-11 11:05 ` [PATCH v3 0/2] " Lorenzo Pieralisi
  2 siblings, 1 reply; 5+ messages in thread
From: Johan Hovold @ 2022-11-02  9:07 UTC (permalink / raw)
  To: Lorenzo Pieralisi, stanimir.k.varbanov
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Bjorn Helgaas,
	Rob Herring, Krzysztof Kozlowski, Krzysztof Wilczyński,
	Brian Masney, Manivannan Sadhasivam, linux-arm-msm, linux-pci,
	devicetree, linux-kernel, Johan Hovold, Georgi Djakov

On Qualcomm platforms like SC8280XP and SA8540P, interconnect bandwidth
must be requested before enabling interconnect clocks.

Add basic support for managing an optional "pcie-mem" interconnect path
by setting a low constraint before enabling clocks and updating it after
the link is up.

Note that it is not possible for a controller driver to set anything but
a maximum peak bandwidth as expected average bandwidth will vary with
use case and actual use (and power policy?). This very much remains an
unresolved problem with the interconnect framework.

Also note that no constraint is set for the SC8280XP/SA8540P "cpu-pcie"
path for now as it is not clear what an appropriate constraint would be
(and the system does not crash when left unspecified).

Fixes: 70574511f3fc ("PCI: qcom: Add support for SC8280XP")
Reviewed-by: Brian Masney <bmasney@redhat.com>
Acked-by: Georgi Djakov <djakov@kernel.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 76 ++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 7db94a22238d..91b113d0c02a 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -12,6 +12,7 @@
 #include <linux/crc8.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
+#include <linux/interconnect.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -224,6 +225,7 @@ struct qcom_pcie {
 	union qcom_pcie_resources res;
 	struct phy *phy;
 	struct gpio_desc *reset;
+	struct icc_path *icc_mem;
 	const struct qcom_pcie_cfg *cfg;
 };
 
@@ -1644,6 +1646,74 @@ static const struct dw_pcie_ops dw_pcie_ops = {
 	.start_link = qcom_pcie_start_link,
 };
 
+static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
+{
+	struct dw_pcie *pci = pcie->pci;
+	int ret;
+
+	pcie->icc_mem = devm_of_icc_get(pci->dev, "pcie-mem");
+	if (IS_ERR(pcie->icc_mem))
+		return PTR_ERR(pcie->icc_mem);
+
+	/*
+	 * Some Qualcomm platforms require interconnect bandwidth constraints
+	 * to be set before enabling interconnect clocks.
+	 *
+	 * Set an initial peak bandwidth corresponding to single-lane Gen 1
+	 * for the pcie-mem path.
+	 */
+	ret = icc_set_bw(pcie->icc_mem, 0, MBps_to_icc(250));
+	if (ret) {
+		dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
+{
+	struct dw_pcie *pci = pcie->pci;
+	u32 offset, status, bw;
+	int speed, width;
+	int ret;
+
+	if (!pcie->icc_mem)
+		return;
+
+	offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+	status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
+
+	/* Only update constraints if link is up. */
+	if (!(status & PCI_EXP_LNKSTA_DLLLA))
+		return;
+
+	speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
+	width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status);
+
+	switch (speed) {
+	case 1:
+		bw = MBps_to_icc(250);
+		break;
+	case 2:
+		bw = MBps_to_icc(500);
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		fallthrough;
+	case 3:
+		bw = MBps_to_icc(985);
+		break;
+	}
+
+	ret = icc_set_bw(pcie->icc_mem, 0, width * bw);
+	if (ret) {
+		dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
+			ret);
+	}
+}
+
 static int qcom_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1704,6 +1774,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 		goto err_pm_runtime_put;
 	}
 
+	ret = qcom_pcie_icc_init(pcie);
+	if (ret)
+		goto err_pm_runtime_put;
+
 	ret = pcie->cfg->ops->get_resources(pcie);
 	if (ret)
 		goto err_pm_runtime_put;
@@ -1722,6 +1796,8 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 		goto err_phy_exit;
 	}
 
+	qcom_pcie_icc_update(pcie);
+
 	return 0;
 
 err_phy_exit:
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 2/2] PCI: qcom: Add basic interconnect support
  2022-11-02  9:07 ` [PATCH v3 2/2] PCI: qcom: Add basic interconnect support Johan Hovold
@ 2022-11-03 12:34   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 5+ messages in thread
From: Manivannan Sadhasivam @ 2022-11-03 12:34 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Lorenzo Pieralisi, stanimir.k.varbanov, Andy Gross,
	Bjorn Andersson, Konrad Dybcio, Bjorn Helgaas, Rob Herring,
	Krzysztof Kozlowski, Krzysztof Wilczyński, Brian Masney,
	linux-arm-msm, linux-pci, devicetree, linux-kernel,
	Georgi Djakov

On Wed, Nov 02, 2022 at 10:07:05AM +0100, Johan Hovold wrote:
> On Qualcomm platforms like SC8280XP and SA8540P, interconnect bandwidth
> must be requested before enabling interconnect clocks.
> 
> Add basic support for managing an optional "pcie-mem" interconnect path
> by setting a low constraint before enabling clocks and updating it after
> the link is up.
> 
> Note that it is not possible for a controller driver to set anything but
> a maximum peak bandwidth as expected average bandwidth will vary with
> use case and actual use (and power policy?). This very much remains an
> unresolved problem with the interconnect framework.
> 
> Also note that no constraint is set for the SC8280XP/SA8540P "cpu-pcie"
> path for now as it is not clear what an appropriate constraint would be
> (and the system does not crash when left unspecified).
> 
> Fixes: 70574511f3fc ("PCI: qcom: Add support for SC8280XP")
> Reviewed-by: Brian Masney <bmasney@redhat.com>
> Acked-by: Georgi Djakov <djakov@kernel.org>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>

Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>

Thanks,
Mani

> ---
>  drivers/pci/controller/dwc/pcie-qcom.c | 76 ++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 7db94a22238d..91b113d0c02a 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -12,6 +12,7 @@
>  #include <linux/crc8.h>
>  #include <linux/delay.h>
>  #include <linux/gpio/consumer.h>
> +#include <linux/interconnect.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> @@ -224,6 +225,7 @@ struct qcom_pcie {
>  	union qcom_pcie_resources res;
>  	struct phy *phy;
>  	struct gpio_desc *reset;
> +	struct icc_path *icc_mem;
>  	const struct qcom_pcie_cfg *cfg;
>  };
>  
> @@ -1644,6 +1646,74 @@ static const struct dw_pcie_ops dw_pcie_ops = {
>  	.start_link = qcom_pcie_start_link,
>  };
>  
> +static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
> +{
> +	struct dw_pcie *pci = pcie->pci;
> +	int ret;
> +
> +	pcie->icc_mem = devm_of_icc_get(pci->dev, "pcie-mem");
> +	if (IS_ERR(pcie->icc_mem))
> +		return PTR_ERR(pcie->icc_mem);
> +
> +	/*
> +	 * Some Qualcomm platforms require interconnect bandwidth constraints
> +	 * to be set before enabling interconnect clocks.
> +	 *
> +	 * Set an initial peak bandwidth corresponding to single-lane Gen 1
> +	 * for the pcie-mem path.
> +	 */
> +	ret = icc_set_bw(pcie->icc_mem, 0, MBps_to_icc(250));
> +	if (ret) {
> +		dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
> +{
> +	struct dw_pcie *pci = pcie->pci;
> +	u32 offset, status, bw;
> +	int speed, width;
> +	int ret;
> +
> +	if (!pcie->icc_mem)
> +		return;
> +
> +	offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> +	status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
> +
> +	/* Only update constraints if link is up. */
> +	if (!(status & PCI_EXP_LNKSTA_DLLLA))
> +		return;
> +
> +	speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
> +	width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status);
> +
> +	switch (speed) {
> +	case 1:
> +		bw = MBps_to_icc(250);
> +		break;
> +	case 2:
> +		bw = MBps_to_icc(500);
> +		break;
> +	default:
> +		WARN_ON_ONCE(1);
> +		fallthrough;
> +	case 3:
> +		bw = MBps_to_icc(985);
> +		break;
> +	}
> +
> +	ret = icc_set_bw(pcie->icc_mem, 0, width * bw);
> +	if (ret) {
> +		dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
> +			ret);
> +	}
> +}
> +
>  static int qcom_pcie_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -1704,6 +1774,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
>  		goto err_pm_runtime_put;
>  	}
>  
> +	ret = qcom_pcie_icc_init(pcie);
> +	if (ret)
> +		goto err_pm_runtime_put;
> +
>  	ret = pcie->cfg->ops->get_resources(pcie);
>  	if (ret)
>  		goto err_pm_runtime_put;
> @@ -1722,6 +1796,8 @@ static int qcom_pcie_probe(struct platform_device *pdev)
>  		goto err_phy_exit;
>  	}
>  
> +	qcom_pcie_icc_update(pcie);
> +
>  	return 0;
>  
>  err_phy_exit:
> -- 
> 2.37.3
> 

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 0/2] PCI: qcom: Add basic interconnect support
  2022-11-02  9:07 [PATCH v3 0/2] PCI: qcom: Add basic interconnect support Johan Hovold
  2022-11-02  9:07 ` [PATCH v3 1/2] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects Johan Hovold
  2022-11-02  9:07 ` [PATCH v3 2/2] PCI: qcom: Add basic interconnect support Johan Hovold
@ 2022-11-11 11:05 ` Lorenzo Pieralisi
  2 siblings, 0 replies; 5+ messages in thread
From: Lorenzo Pieralisi @ 2022-11-11 11:05 UTC (permalink / raw)
  To: stanimir.k.varbanov, Johan Hovold
  Cc: Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Krzysztof Kozlowski, Bjorn Andersson, linux-kernel, Brian Masney,
	Manivannan Sadhasivam, linux-pci, Krzysztof Wilczyński,
	linux-arm-msm, Konrad Dybcio, Andy Gross, devicetree

On Wed, 2 Nov 2022 10:07:03 +0100, Johan Hovold wrote:
> On Qualcomm platforms like SC8280XP and SA8540P interconnect bandwidth
> must be requested before enabling interconnect clocks.
> 
> Add basic support for managing an optional "pcie-mem" interconnect path
> by setting a low constraint before enabling clocks and updating it after
> the link is up.
> 
> [...]

Applied to pci/qcom, thanks!

[1/2] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects
      https://git.kernel.org/lpieralisi/pci/c/3a936b2a5a58
[2/2] PCI: qcom: Add basic interconnect support
      https://git.kernel.org/lpieralisi/pci/c/c4860af88d0c

Thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-11-11 11:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-02  9:07 [PATCH v3 0/2] PCI: qcom: Add basic interconnect support Johan Hovold
2022-11-02  9:07 ` [PATCH v3 1/2] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects Johan Hovold
2022-11-02  9:07 ` [PATCH v3 2/2] PCI: qcom: Add basic interconnect support Johan Hovold
2022-11-03 12:34   ` Manivannan Sadhasivam
2022-11-11 11:05 ` [PATCH v3 0/2] " Lorenzo Pieralisi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).