Skip to content

Commit a1dd5e7

Browse files
committed
Merge branch 'pci/controller/dwc-qcom-ep'
- Add DT binding and driver support for SA8255p Endpoint being managed by firmware (Mrinmay Sarkar) * pci/controller/dwc-qcom-ep: PCI: qcom-ep: Add support for firmware-managed PCIe Endpoint dt-bindings: PCI: qcom,sa8255p-pcie-ep: Document firmware managed PCIe endpoint
2 parents 9b2e9ba + 5b026a9 commit a1dd5e7

3 files changed

Lines changed: 164 additions & 8 deletions

File tree

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/pci/qcom,sa8255p-pcie-ep.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Qualcomm firmware managed PCIe Endpoint Controller
8+
9+
description:
10+
Qualcomm SA8255p SoC PCIe endpoint controller is based on the Synopsys
11+
DesignWare PCIe IP which is managed by firmware.
12+
13+
maintainers:
14+
- Manivannan Sadhasivam <mani@kernel.org>
15+
16+
properties:
17+
compatible:
18+
const: qcom,sa8255p-pcie-ep
19+
20+
reg:
21+
items:
22+
- description: Qualcomm-specific PARF configuration registers
23+
- description: DesignWare PCIe registers
24+
- description: External local bus interface registers
25+
- description: Address Translation Unit (ATU) registers
26+
- description: Memory region used to map remote RC address space
27+
- description: BAR memory region
28+
- description: DMA register space
29+
30+
reg-names:
31+
items:
32+
- const: parf
33+
- const: dbi
34+
- const: elbi
35+
- const: atu
36+
- const: addr_space
37+
- const: mmio
38+
- const: dma
39+
40+
interrupts:
41+
items:
42+
- description: PCIe Global interrupt
43+
- description: PCIe Doorbell interrupt
44+
- description: DMA interrupt
45+
46+
interrupt-names:
47+
items:
48+
- const: global
49+
- const: doorbell
50+
- const: dma
51+
52+
iommus:
53+
maxItems: 1
54+
55+
reset-gpios:
56+
description: GPIO used as PERST# input signal
57+
maxItems: 1
58+
59+
wake-gpios:
60+
description: GPIO used as WAKE# output signal
61+
maxItems: 1
62+
63+
power-domains:
64+
maxItems: 1
65+
66+
dma-coherent: true
67+
68+
num-lanes:
69+
default: 2
70+
71+
required:
72+
- compatible
73+
- reg
74+
- reg-names
75+
- interrupts
76+
- interrupt-names
77+
- reset-gpios
78+
- power-domains
79+
80+
additionalProperties: false
81+
82+
examples:
83+
- |
84+
#include <dt-bindings/gpio/gpio.h>
85+
#include <dt-bindings/interrupt-controller/arm-gic.h>
86+
soc {
87+
#address-cells = <2>;
88+
#size-cells = <2>;
89+
pcie1_ep: pcie-ep@1c10000 {
90+
compatible = "qcom,sa8255p-pcie-ep";
91+
reg = <0x0 0x01c10000 0x0 0x3000>,
92+
<0x0 0x60000000 0x0 0xf20>,
93+
<0x0 0x60000f20 0x0 0xa8>,
94+
<0x0 0x60001000 0x0 0x4000>,
95+
<0x0 0x60200000 0x0 0x100000>,
96+
<0x0 0x01c13000 0x0 0x1000>,
97+
<0x0 0x60005000 0x0 0x2000>;
98+
reg-names = "parf", "dbi", "elbi", "atu", "addr_space", "mmio", "dma";
99+
interrupts = <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
100+
<GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
101+
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
102+
interrupt-names = "global", "doorbell", "dma";
103+
reset-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
104+
wake-gpios = <&tlmm 5 GPIO_ACTIVE_LOW>;
105+
dma-coherent;
106+
iommus = <&pcie_smmu 0x80 0x7f>;
107+
power-domains = <&scmi6_pd 1>;
108+
num-lanes = <4>;
109+
};
110+
};

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20365,6 +20365,7 @@ L: linux-pci@vger.kernel.org
2036520365
L: linux-arm-msm@vger.kernel.org
2036620366
S: Maintained
2036720367
F: Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
20368+
F: Documentation/devicetree/bindings/pci/qcom,sa8255p-pcie-ep.yaml
2036820369
F: drivers/pci/controller/dwc/pcie-qcom-common.c
2036920370
F: drivers/pci/controller/dwc/pcie-qcom-ep.c
2037020371

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

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,13 @@ enum qcom_pcie_ep_link_status {
168168
* @hdma_support: HDMA support on this SoC
169169
* @override_no_snoop: Override NO_SNOOP attribute in TLP to enable cache snooping
170170
* @disable_mhi_ram_parity_check: Disable MHI RAM data parity error check
171+
* @firmware_managed: Set if the controller is firmware managed
171172
*/
172173
struct qcom_pcie_ep_cfg {
173174
bool hdma_support;
174175
bool override_no_snoop;
175176
bool disable_mhi_ram_parity_check;
177+
bool firmware_managed;
176178
};
177179

178180
/**
@@ -377,6 +379,14 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
377379

378380
static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep)
379381
{
382+
struct device *dev = pcie_ep->pci.dev;
383+
384+
pm_runtime_put(dev);
385+
386+
/* Skip resource disablement if controller is firmware-managed */
387+
if (pcie_ep->cfg && pcie_ep->cfg->firmware_managed)
388+
return;
389+
380390
icc_set_bw(pcie_ep->icc_mem, 0, 0);
381391
phy_power_off(pcie_ep->phy);
382392
phy_exit(pcie_ep->phy);
@@ -390,12 +400,24 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
390400
u32 val, offset;
391401
int ret;
392402

403+
ret = pm_runtime_resume_and_get(dev);
404+
if (ret < 0) {
405+
dev_err(dev, "Failed to enable device: %d\n", ret);
406+
return ret;
407+
}
408+
409+
/* Skip resource enablement if controller is firmware-managed */
410+
if (pcie_ep->cfg && pcie_ep->cfg->firmware_managed)
411+
goto skip_resources_enable;
412+
393413
ret = qcom_pcie_enable_resources(pcie_ep);
394414
if (ret) {
395415
dev_err(dev, "Failed to enable resources: %d\n", ret);
416+
pm_runtime_put(dev);
396417
return ret;
397418
}
398419

420+
skip_resources_enable:
399421
/* Perform cleanup that requires refclk */
400422
pci_epc_deinit_notify(pci->ep.epc);
401423
dw_pcie_ep_cleanup(&pci->ep);
@@ -630,6 +652,17 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
630652
return ret;
631653
}
632654

655+
pcie_ep->reset = devm_gpiod_get(dev, "reset", GPIOD_IN);
656+
if (IS_ERR(pcie_ep->reset))
657+
return PTR_ERR(pcie_ep->reset);
658+
659+
pcie_ep->wake = devm_gpiod_get_optional(dev, "wake", GPIOD_OUT_LOW);
660+
if (IS_ERR(pcie_ep->wake))
661+
return PTR_ERR(pcie_ep->wake);
662+
663+
if (pcie_ep->cfg && pcie_ep->cfg->firmware_managed)
664+
return 0;
665+
633666
pcie_ep->num_clks = devm_clk_bulk_get_all(dev, &pcie_ep->clks);
634667
if (pcie_ep->num_clks < 0) {
635668
dev_err(dev, "Failed to get clocks\n");
@@ -640,14 +673,6 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
640673
if (IS_ERR(pcie_ep->core_reset))
641674
return PTR_ERR(pcie_ep->core_reset);
642675

643-
pcie_ep->reset = devm_gpiod_get(dev, "reset", GPIOD_IN);
644-
if (IS_ERR(pcie_ep->reset))
645-
return PTR_ERR(pcie_ep->reset);
646-
647-
pcie_ep->wake = devm_gpiod_get_optional(dev, "wake", GPIOD_OUT_LOW);
648-
if (IS_ERR(pcie_ep->wake))
649-
return PTR_ERR(pcie_ep->wake);
650-
651676
pcie_ep->phy = devm_phy_optional_get(dev, "pciephy");
652677
if (IS_ERR(pcie_ep->phy))
653678
ret = PTR_ERR(pcie_ep->phy);
@@ -875,6 +900,12 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
875900

876901
platform_set_drvdata(pdev, pcie_ep);
877902

903+
pm_runtime_get_noresume(dev);
904+
pm_runtime_set_active(dev);
905+
ret = devm_pm_runtime_enable(dev);
906+
if (ret)
907+
return ret;
908+
878909
ret = qcom_pcie_ep_get_resources(pdev, pcie_ep);
879910
if (ret)
880911
return ret;
@@ -895,6 +926,12 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
895926
goto err_disable_irqs;
896927
}
897928

929+
ret = pm_runtime_put_sync(dev);
930+
if (ret < 0) {
931+
dev_err(dev, "Failed to suspend device: %d\n", ret);
932+
goto err_disable_irqs;
933+
}
934+
898935
pcie_ep->debugfs = debugfs_create_dir(name, NULL);
899936
qcom_pcie_ep_init_debugfs(pcie_ep);
900937

@@ -931,7 +968,15 @@ static const struct qcom_pcie_ep_cfg cfg_1_34_0 = {
931968
.disable_mhi_ram_parity_check = true,
932969
};
933970

971+
static const struct qcom_pcie_ep_cfg cfg_1_34_0_fw_managed = {
972+
.hdma_support = true,
973+
.override_no_snoop = true,
974+
.disable_mhi_ram_parity_check = true,
975+
.firmware_managed = true,
976+
};
977+
934978
static const struct of_device_id qcom_pcie_ep_match[] = {
979+
{ .compatible = "qcom,sa8255p-pcie-ep", .data = &cfg_1_34_0_fw_managed},
935980
{ .compatible = "qcom,sa8775p-pcie-ep", .data = &cfg_1_34_0},
936981
{ .compatible = "qcom,sdx55-pcie-ep", },
937982
{ .compatible = "qcom,sm8450-pcie-ep", },

0 commit comments

Comments
 (0)