Skip to content

Commit 008ee71

Browse files
committed
Merge branch 'remotes/lorenzo/pci/qcom'
- Add DT and driver support for SC8280XP/SA8540P basic interconnects where interconnect bandwidth must be requested before enabling interconnect clocks (Johan Hovold) - Add 'dma-coherent' property (Johan Hovold) * remotes/lorenzo/pci/qcom: dt-bindings: PCI: qcom: Allow 'dma-coherent' property PCI: qcom: Add basic interconnect support dt-bindings: PCI: qcom: Add SC8280XP/SA8540P interconnects
2 parents 8ecdba3 + 74eac50 commit 008ee71

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

Documentation/devicetree/bindings/pci/qcom,pcie.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ properties:
6262
minItems: 3
6363
maxItems: 13
6464

65+
dma-coherent: true
66+
67+
interconnects:
68+
maxItems: 2
69+
70+
interconnect-names:
71+
items:
72+
- const: pcie-mem
73+
- const: cpu-pcie
74+
6575
resets:
6676
minItems: 1
6777
maxItems: 12
@@ -631,6 +641,18 @@ allOf:
631641
items:
632642
- const: pci # PCIe core reset
633643

644+
- if:
645+
properties:
646+
compatible:
647+
contains:
648+
enum:
649+
- qcom,pcie-sa8540p
650+
- qcom,pcie-sc8280xp
651+
then:
652+
required:
653+
- interconnects
654+
- interconnect-names
655+
634656
- if:
635657
not:
636658
properties:

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

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/crc8.h>
1313
#include <linux/delay.h>
1414
#include <linux/gpio/consumer.h>
15+
#include <linux/interconnect.h>
1516
#include <linux/interrupt.h>
1617
#include <linux/io.h>
1718
#include <linux/iopoll.h>
@@ -223,6 +224,7 @@ struct qcom_pcie {
223224
union qcom_pcie_resources res;
224225
struct phy *phy;
225226
struct gpio_desc *reset;
227+
struct icc_path *icc_mem;
226228
const struct qcom_pcie_cfg *cfg;
227229
};
228230

@@ -1639,6 +1641,74 @@ static const struct dw_pcie_ops dw_pcie_ops = {
16391641
.start_link = qcom_pcie_start_link,
16401642
};
16411643

1644+
static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
1645+
{
1646+
struct dw_pcie *pci = pcie->pci;
1647+
int ret;
1648+
1649+
pcie->icc_mem = devm_of_icc_get(pci->dev, "pcie-mem");
1650+
if (IS_ERR(pcie->icc_mem))
1651+
return PTR_ERR(pcie->icc_mem);
1652+
1653+
/*
1654+
* Some Qualcomm platforms require interconnect bandwidth constraints
1655+
* to be set before enabling interconnect clocks.
1656+
*
1657+
* Set an initial peak bandwidth corresponding to single-lane Gen 1
1658+
* for the pcie-mem path.
1659+
*/
1660+
ret = icc_set_bw(pcie->icc_mem, 0, MBps_to_icc(250));
1661+
if (ret) {
1662+
dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
1663+
ret);
1664+
return ret;
1665+
}
1666+
1667+
return 0;
1668+
}
1669+
1670+
static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
1671+
{
1672+
struct dw_pcie *pci = pcie->pci;
1673+
u32 offset, status, bw;
1674+
int speed, width;
1675+
int ret;
1676+
1677+
if (!pcie->icc_mem)
1678+
return;
1679+
1680+
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
1681+
status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
1682+
1683+
/* Only update constraints if link is up. */
1684+
if (!(status & PCI_EXP_LNKSTA_DLLLA))
1685+
return;
1686+
1687+
speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
1688+
width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status);
1689+
1690+
switch (speed) {
1691+
case 1:
1692+
bw = MBps_to_icc(250);
1693+
break;
1694+
case 2:
1695+
bw = MBps_to_icc(500);
1696+
break;
1697+
default:
1698+
WARN_ON_ONCE(1);
1699+
fallthrough;
1700+
case 3:
1701+
bw = MBps_to_icc(985);
1702+
break;
1703+
}
1704+
1705+
ret = icc_set_bw(pcie->icc_mem, 0, width * bw);
1706+
if (ret) {
1707+
dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
1708+
ret);
1709+
}
1710+
}
1711+
16421712
static int qcom_pcie_probe(struct platform_device *pdev)
16431713
{
16441714
struct device *dev = &pdev->dev;
@@ -1699,6 +1769,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
16991769
goto err_pm_runtime_put;
17001770
}
17011771

1772+
ret = qcom_pcie_icc_init(pcie);
1773+
if (ret)
1774+
goto err_pm_runtime_put;
1775+
17021776
ret = pcie->cfg->ops->get_resources(pcie);
17031777
if (ret)
17041778
goto err_pm_runtime_put;
@@ -1717,6 +1791,8 @@ static int qcom_pcie_probe(struct platform_device *pdev)
17171791
goto err_phy_exit;
17181792
}
17191793

1794+
qcom_pcie_icc_update(pcie);
1795+
17201796
return 0;
17211797

17221798
err_phy_exit:

0 commit comments

Comments
 (0)