From 3a936b2a5a581e50dd5cab20a48eb0055a527f02 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 2 Nov 2022 10:07:04 +0100 Subject: [PATCH 1/3] dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects Add the missing SC8280XP/SA8540P "pcie-mem" and "cpu-pcie" interconnect paths to the bindings. Link: https://lore.kernel.org/r/20221102090705.23634-2-johan+linaro@kernel.org Fixes: 76d777ae045e ("dt-bindings: PCI: qcom: Add SC8280XP to binding") Fixes: 76c4207f4085 ("dt-bindings: PCI: qcom: Add SA8540P to binding") Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring Acked-by: Manivannan Sadhasivam --- .../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: From c4860af88d0cb1bb006df12615c5515ae509f73b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 2 Nov 2022 10:07:05 +0100 Subject: [PATCH 2/3] PCI: qcom: Add basic interconnect support 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). Link: https://lore.kernel.org/r/20221102090705.23634-3-johan+linaro@kernel.org Fixes: 70574511f3fc ("PCI: qcom: Add support for SC8280XP") Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Brian Masney Reviewed-by: Manivannan Sadhasivam Acked-by: Georgi Djakov --- 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 f711acacaeaf..ec230b988ba2 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -223,6 +224,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; }; @@ -1639,6 +1641,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; @@ -1699,6 +1769,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; @@ -1717,6 +1791,8 @@ static int qcom_pcie_probe(struct platform_device *pdev) goto err_phy_exit; } + qcom_pcie_icc_update(pcie); + return 0; err_phy_exit: From 74eac50391ce42c5d0038d6f0e580576e53aec4e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Dec 2022 10:45:30 +0100 Subject: [PATCH 3/3] dt-bindings: PCI: qcom: Allow 'dma-coherent' property Devices on some PCIe buses may be cache coherent and must be marked as such in the devicetree to avoid data corruption. This is specifically needed on recent Qualcomm platforms like SC8280XP. Link: https://lore.kernel.org/r/20221205094530.12883-1-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Acked-by: Rob Herring --- Documentation/devicetree/bindings/pci/qcom,pcie.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml index 2f851c804bb0..a5859bb3dc28 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml @@ -62,6 +62,8 @@ properties: minItems: 3 maxItems: 13 + dma-coherent: true + interconnects: maxItems: 2