2022-09-14 07:59:01

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 00/12] Improvements to the Qcom PCIe Endpoint driver

Hello,

This series contains improvements to the Qualcomm PCIe Endpoint controller
driver. The major improvements are the addition of SM8450 SoC support and
debugfs interface for exposing link transition counts.

This series has been tested on SM8450 based dev board.

NOTE: Since the bindings are ACKed, the whole series could be merged to the
PCI tree.

Thanks,
Mani

Changes in v4:

* Collected tags for bindings patches
* Reworded the subject of patch 2/12

Changes in v3:

* Removed the maxItems property from "items" list
* Reworded the debugfs patch
* Dropped the eDMA patch since that depends on ongoing eDMA series from Sergey
* Added two new patches that helps in saving power during idle and low power
state

Changes in v2:

* Fixed the comments on bindings patches
* Added Ack from Krzysztof

Manivannan Sadhasivam (12):
PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure
PCI: qcom-ep: Rely on the clocks supplied by devicetree
PCI: qcom-ep: Make use of the cached dev pointer
PCI: qcom-ep: Disable IRQs during driver remove
PCI: qcom-ep: Expose link transition counts via debugfs
PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS
PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic
dt-bindings: PCI: qcom-ep: Make PERST separation optional
PCI: qcom-ep: Make PERST separation optional
dt-bindings: PCI: qcom-ep: Define clocks per platform
dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC
PCI: qcom-ep: Add support for SM8450 SoC

.../devicetree/bindings/pci/qcom,pcie-ep.yaml | 86 +++++++---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 154 ++++++++++++++----
2 files changed, 188 insertions(+), 52 deletions(-)

--
2.25.1


2022-09-14 07:59:36

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 02/12] PCI: qcom-ep: Rely on the clocks supplied by devicetree

Generally, device drivers should just rely on the platform data like
devicetree to supply the clocks required for the functioning of the
peripheral. There is no need to hardcode the clk info in the driver.
So get rid of the static clk info and obtain the platform supplied
clks.

The total number of clocks supplied is obtained using the
devm_clk_bulk_get_all() API and used for the rest of the clk_bulk_ APIs.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 33 +++++++++--------------
1 file changed, 13 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 27b7c9710b5f..34c498d581de 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -130,16 +130,6 @@ enum qcom_pcie_ep_link_status {
QCOM_PCIE_EP_LINK_DOWN,
};

-static struct clk_bulk_data qcom_pcie_ep_clks[] = {
- { .id = "cfg" },
- { .id = "aux" },
- { .id = "bus_master" },
- { .id = "bus_slave" },
- { .id = "ref" },
- { .id = "sleep" },
- { .id = "slave_q2a" },
-};
-
/**
* struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller
* @pci: Designware PCIe controller struct
@@ -151,6 +141,8 @@ static struct clk_bulk_data qcom_pcie_ep_clks[] = {
* @reset: PERST# GPIO
* @wake: WAKE# GPIO
* @phy: PHY controller block
+ * @clks: PCIe clocks
+ * @num_clks: PCIe clocks count
* @perst_en: Flag for PERST enable
* @perst_sep_en: Flag for PERST separation enable
* @link_status: PCIe Link status
@@ -170,6 +162,9 @@ struct qcom_pcie_ep {
struct gpio_desc *wake;
struct phy *phy;

+ struct clk_bulk_data *clks;
+ int num_clks;
+
u32 perst_en;
u32 perst_sep_en;

@@ -244,8 +239,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
{
int ret;

- ret = clk_bulk_prepare_enable(ARRAY_SIZE(qcom_pcie_ep_clks),
- qcom_pcie_ep_clks);
+ ret = clk_bulk_prepare_enable(pcie_ep->num_clks, pcie_ep->clks);
if (ret)
return ret;

@@ -266,8 +260,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
err_phy_exit:
phy_exit(pcie_ep->phy);
err_disable_clk:
- clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks),
- qcom_pcie_ep_clks);
+ clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks);

return ret;
}
@@ -276,8 +269,7 @@ static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep)
{
phy_power_off(pcie_ep->phy);
phy_exit(pcie_ep->phy);
- clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks),
- qcom_pcie_ep_clks);
+ clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks);
}

static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
@@ -495,10 +487,11 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
return ret;
}

- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(qcom_pcie_ep_clks),
- qcom_pcie_ep_clks);
- if (ret)
- return ret;
+ pcie_ep->num_clks = devm_clk_bulk_get_all(dev, &pcie_ep->clks);
+ if (pcie_ep->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return pcie_ep->num_clks;
+ }

pcie_ep->core_reset = devm_reset_control_get_exclusive(dev, "core");
if (IS_ERR(pcie_ep->core_reset))
--
2.25.1

2022-09-14 08:00:27

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 04/12] PCI: qcom-ep: Disable IRQs during driver remove

Disable the Global and PERST IRQs during driver remove to avoid getting
spurious IRQs after resource deallocation.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 1e09eca5b3b2..72eb6cacdb3a 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -585,11 +585,11 @@ static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev,
{
int irq, ret;

- irq = platform_get_irq_byname(pdev, "global");
- if (irq < 0)
- return irq;
+ pcie_ep->global_irq = platform_get_irq_byname(pdev, "global");
+ if (pcie_ep->global_irq < 0)
+ return pcie_ep->global_irq;

- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ ret = devm_request_threaded_irq(&pdev->dev, pcie_ep->global_irq, NULL,
qcom_pcie_ep_global_irq_thread,
IRQF_ONESHOT,
"global_irq", pcie_ep);
@@ -698,6 +698,9 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)
{
struct qcom_pcie_ep *pcie_ep = platform_get_drvdata(pdev);

+ disable_irq(pcie_ep->global_irq);
+ disable_irq(pcie_ep->perst_irq);
+
if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED)
return 0;

--
2.25.1

2022-09-14 08:00:34

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 05/12] PCI: qcom-ep: Expose link transition counts via debugfs

Qualcomm PCIe controllers have debug registers in the MMIO region
that count PCIe link transitions. Expose them over debugfs to
userspace to help debug the low power issues.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 60 +++++++++++++++++++++++
1 file changed, 60 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 72eb6cacdb3a..2dc6d4e44aff 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -10,6 +10,7 @@
*/

#include <linux/clk.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/mfd/syscon.h>
@@ -45,6 +46,11 @@
#define PARF_ATU_BASE_ADDR 0x634
#define PARF_ATU_BASE_ADDR_HI 0x638
#define PARF_SRIS_MODE 0x644
+#define PARF_DEBUG_CNT_PM_LINKST_IN_L2 0xc04
+#define PARF_DEBUG_CNT_PM_LINKST_IN_L1 0xc0c
+#define PARF_DEBUG_CNT_PM_LINKST_IN_L0S 0xc10
+#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1 0xc84
+#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2 0xc88
#define PARF_DEVICE_TYPE 0x1000
#define PARF_BDF_TO_SID_CFG 0x2c00

@@ -135,12 +141,14 @@ enum qcom_pcie_ep_link_status {
* @pci: Designware PCIe controller struct
* @parf: Qualcomm PCIe specific PARF register base
* @elbi: Designware PCIe specific ELBI register base
+ * @mmio: MMIO register base
* @perst_map: PERST regmap
* @mmio_res: MMIO region resource
* @core_reset: PCIe Endpoint core reset
* @reset: PERST# GPIO
* @wake: WAKE# GPIO
* @phy: PHY controller block
+ * @debugfs: PCIe Endpoint Debugfs directory
* @clks: PCIe clocks
* @num_clks: PCIe clocks count
* @perst_en: Flag for PERST enable
@@ -154,6 +162,7 @@ struct qcom_pcie_ep {

void __iomem *parf;
void __iomem *elbi;
+ void __iomem *mmio;
struct regmap *perst_map;
struct resource *mmio_res;

@@ -161,6 +170,7 @@ struct qcom_pcie_ep {
struct gpio_desc *reset;
struct gpio_desc *wake;
struct phy *phy;
+ struct dentry *debugfs;

struct clk_bulk_data *clks;
int num_clks;
@@ -446,6 +456,9 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,

pcie_ep->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"mmio");
+ pcie_ep->mmio = devm_pci_remap_cfg_resource(dev, pcie_ep->mmio_res);
+ if (IS_ERR(pcie_ep->mmio))
+ return PTR_ERR(pcie_ep->mmio);

syscon = of_parse_phandle(dev->of_node, "qcom,perst-regs", 0);
if (!syscon) {
@@ -629,6 +642,37 @@ static int qcom_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
}
}

+static int qcom_pcie_ep_link_transition_count(struct seq_file *s, void *data)
+{
+ struct qcom_pcie_ep *pcie_ep = (struct qcom_pcie_ep *)
+ dev_get_drvdata(s->private);
+
+ seq_printf(s, "L0s transition count: %u\n",
+ readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L0S));
+
+ seq_printf(s, "L1 transition count: %u\n",
+ readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L1));
+
+ seq_printf(s, "L1.1 transition count: %u\n",
+ readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1));
+
+ seq_printf(s, "L1.2 transition count: %u\n",
+ readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2));
+
+ seq_printf(s, "L2 transition count: %u\n",
+ readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L2));
+
+ return 0;
+}
+
+static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep)
+{
+ struct dw_pcie *pci = &pcie_ep->pci;
+
+ debugfs_create_devm_seqfile(pci->dev, "link_transition_count", pcie_ep->debugfs,
+ qcom_pcie_ep_link_transition_count);
+}
+
static const struct pci_epc_features qcom_pcie_epc_features = {
.linkup_notifier = true,
.core_init_notifier = true,
@@ -661,6 +705,7 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct qcom_pcie_ep *pcie_ep;
+ char *name;
int ret;

pcie_ep = devm_kzalloc(dev, sizeof(*pcie_ep), GFP_KERNEL);
@@ -686,8 +731,21 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
if (ret)
goto err_disable_resources;

+ name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
+ if (!name) {
+ ret = -ENOMEM;
+ goto err_disable_irqs;
+ }
+
+ pcie_ep->debugfs = debugfs_create_dir(name, NULL);
+ qcom_pcie_ep_init_debugfs(pcie_ep);
+
return 0;

+err_disable_irqs:
+ disable_irq(pcie_ep->global_irq);
+ disable_irq(pcie_ep->perst_irq);
+
err_disable_resources:
qcom_pcie_disable_resources(pcie_ep);

@@ -701,6 +759,8 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)
disable_irq(pcie_ep->global_irq);
disable_irq(pcie_ep->perst_irq);

+ debugfs_remove_recursive(pcie_ep->debugfs);
+
if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED)
return 0;

--
2.25.1

2022-09-14 08:00:39

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 06/12] PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS

During L1SS, gate the Master clock supplied to the MHI bus to save power.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 2dc6d4e44aff..526e98ea23f6 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -27,6 +27,7 @@
#define PARF_SYS_CTRL 0x00
#define PARF_DB_CTRL 0x10
#define PARF_PM_CTRL 0x20
+#define PARF_MHI_CLOCK_RESET_CTRL 0x174
#define PARF_MHI_BASE_ADDR_LOWER 0x178
#define PARF_MHI_BASE_ADDR_UPPER 0x17c
#define PARF_DEBUG_INT_EN 0x190
@@ -89,6 +90,9 @@
#define PARF_PM_CTRL_READY_ENTR_L23 BIT(2)
#define PARF_PM_CTRL_REQ_NOT_ENTR_L1 BIT(5)

+/* PARF_MHI_CLOCK_RESET_CTRL fields */
+#define PARF_MSTR_AXI_CLK_EN BIT(1)
+
/* PARF_AXI_MSTR_RD_HALT_NO_WRITES register fields */
#define PARF_AXI_MSTR_RD_HALT_NO_WRITE_EN BIT(0)

@@ -394,6 +398,11 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
pcie_ep->parf + PARF_MHI_BASE_ADDR_LOWER);
writel_relaxed(0, pcie_ep->parf + PARF_MHI_BASE_ADDR_UPPER);

+ /* Gate Master AXI clock to MHI bus during L1SS */
+ val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
+ val &= ~PARF_MSTR_AXI_CLK_EN;
+ val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
+
dw_pcie_ep_init_notify(&pcie_ep->pci.ep);

/* Enable LTSSM */
--
2.25.1

2022-09-14 08:15:10

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 08/12] dt-bindings: PCI: qcom-ep: Make PERST separation optional

PERST separation is an optional debug feature used to collect the crash
dump from the PCIe endpoint devices by the PCIe host when the endpoint
crashes. This feature keeps the PCIe link up by separating the PCIe IP
block from the SoC reset logic.

So remove the corresponding property "qcom,perst-regs" from the required
properties list.

Acked-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml | 1 -
1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
index 3d23599e5e91..b728ede3f09f 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
@@ -105,7 +105,6 @@ required:
- reg-names
- clocks
- clock-names
- - qcom,perst-regs
- interrupts
- interrupt-names
- reset-gpios
--
2.25.1

2022-09-14 08:16:12

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 10/12] dt-bindings: PCI: qcom-ep: Define clocks per platform

In preparation of adding the bindings for future SoCs, let's define the
clocks per platform.

Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
.../devicetree/bindings/pci/qcom,pcie-ep.yaml | 50 ++++++++++++-------
1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
index b728ede3f09f..bb8e982e69be 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
@@ -9,9 +9,6 @@ title: Qualcomm PCIe Endpoint Controller binding
maintainers:
- Manivannan Sadhasivam <[email protected]>

-allOf:
- - $ref: "pci-ep.yaml#"
-
properties:
compatible:
const: qcom,sdx55-pcie-ep
@@ -35,24 +32,10 @@ properties:
- const: mmio

clocks:
- items:
- - description: PCIe Auxiliary clock
- - description: PCIe CFG AHB clock
- - description: PCIe Master AXI clock
- - description: PCIe Slave AXI clock
- - description: PCIe Slave Q2A AXI clock
- - description: PCIe Sleep clock
- - description: PCIe Reference clock
+ maxItems: 7

clock-names:
- items:
- - const: aux
- - const: cfg
- - const: bus_master
- - const: bus_slave
- - const: slave_q2a
- - const: sleep
- - const: ref
+ maxItems: 7

qcom,perst-regs:
description: Reference to a syscon representing TCSR followed by the two
@@ -112,6 +95,35 @@ required:
- reset-names
- power-domains

+allOf:
+ - $ref: pci-ep.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,sdx55-pcie-ep
+ then:
+ properties:
+ clocks:
+ items:
+ - description: PCIe Auxiliary clock
+ - description: PCIe CFG AHB clock
+ - description: PCIe Master AXI clock
+ - description: PCIe Slave AXI clock
+ - description: PCIe Slave Q2A AXI clock
+ - description: PCIe Sleep clock
+ - description: PCIe Reference clock
+ clock-names:
+ items:
+ - const: aux
+ - const: cfg
+ - const: bus_master
+ - const: bus_slave
+ - const: slave_q2a
+ - const: sleep
+ - const: ref
+
unevaluatedProperties: false

examples:
--
2.25.1

2022-09-14 08:16:49

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 09/12] PCI: qcom-ep: Make PERST separation optional

PERST separation is an optional debug feature used to collect the crash
dump from the PCIe endpoint devices by the PCIe host when the endpoint
crashes. This feature keeps the PCIe link up by separating the PCIe IP
block from the SoC reset logic.

Hence, make the property optional in the driver.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 40f75a6c55df..92140a09aac5 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -220,8 +220,10 @@ static int qcom_pcie_ep_core_reset(struct qcom_pcie_ep *pcie_ep)
*/
static void qcom_pcie_ep_configure_tcsr(struct qcom_pcie_ep *pcie_ep)
{
- regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0);
- regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0);
+ if (pcie_ep->perst_map) {
+ regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0);
+ regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0);
+ }
}

static int qcom_pcie_dw_link_up(struct dw_pcie *pci)
@@ -478,8 +480,8 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,

syscon = of_parse_phandle(dev->of_node, "qcom,perst-regs", 0);
if (!syscon) {
- dev_err(dev, "Failed to parse qcom,perst-regs\n");
- return -EINVAL;
+ dev_dbg(dev, "PERST separation not available\n");
+ return 0;
}

pcie_ep->perst_map = syscon_node_to_regmap(syscon);
--
2.25.1

2022-09-14 08:17:51

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 01/12] PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure

Add kernel-doc for qcom_pcie_ep structure.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 9f92d53da81a..27b7c9710b5f 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -140,6 +140,23 @@ static struct clk_bulk_data qcom_pcie_ep_clks[] = {
{ .id = "slave_q2a" },
};

+/**
+ * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller
+ * @pci: Designware PCIe controller struct
+ * @parf: Qualcomm PCIe specific PARF register base
+ * @elbi: Designware PCIe specific ELBI register base
+ * @perst_map: PERST regmap
+ * @mmio_res: MMIO region resource
+ * @core_reset: PCIe Endpoint core reset
+ * @reset: PERST# GPIO
+ * @wake: WAKE# GPIO
+ * @phy: PHY controller block
+ * @perst_en: Flag for PERST enable
+ * @perst_sep_en: Flag for PERST separation enable
+ * @link_status: PCIe Link status
+ * @global_irq: Qualcomm PCIe specific Global IRQ
+ * @perst_irq: PERST# IRQ
+ */
struct qcom_pcie_ep {
struct dw_pcie pci;

--
2.25.1

2022-09-14 08:18:15

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 07/12] PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic

The Master AXI clock can be disabled when it is not used i.e., when there
is no traffic on the PCIe bus. This helps to save power during idle state.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 526e98ea23f6..40f75a6c55df 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -105,6 +105,7 @@
/* PARF_SYS_CTRL register fields */
#define PARF_SYS_CTRL_AUX_PWR_DET BIT(4)
#define PARF_SYS_CTRL_CORE_CLK_CGC_DIS BIT(6)
+#define PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS BIT(10)
#define PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE BIT(11)

/* PARF_DB_CTRL register fields */
@@ -341,8 +342,14 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
val &= ~PARF_Q2A_FLUSH_EN;
writel_relaxed(val, pcie_ep->parf + PARF_Q2A_FLUSH);

- /* Disable DBI Wakeup, core clock CGC and enable AUX power */
+ /*
+ * Disable Master AXI clock during idle
+ * Do not allow DBI access to take the core out of L1
+ * Disable core clock gating that gates PIPE clock from propagating to core clock
+ * Report to the host that Vaux is present
+ */
val = readl_relaxed(pcie_ep->parf + PARF_SYS_CTRL);
+ val &= ~PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS;
val |= PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE |
PARF_SYS_CTRL_CORE_CLK_CGC_DIS |
PARF_SYS_CTRL_AUX_PWR_DET;
--
2.25.1

2022-09-14 08:20:56

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 03/12] PCI: qcom-ep: Make use of the cached dev pointer

In the qcom_pcie_ep_get_resources() function, dev pointer is already
cached in a local variable. So let's make use of it instead of getting
the dev pointer again from pdev struct.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 34c498d581de..1e09eca5b3b2 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -483,7 +483,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,

ret = qcom_pcie_ep_get_io_resources(pdev, pcie_ep);
if (ret) {
- dev_err(&pdev->dev, "Failed to get io resources %d\n", ret);
+ dev_err(dev, "Failed to get io resources %d\n", ret);
return ret;
}

@@ -505,7 +505,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
if (IS_ERR(pcie_ep->wake))
return PTR_ERR(pcie_ep->wake);

- pcie_ep->phy = devm_phy_optional_get(&pdev->dev, "pciephy");
+ pcie_ep->phy = devm_phy_optional_get(dev, "pciephy");
if (IS_ERR(pcie_ep->phy))
ret = PTR_ERR(pcie_ep->phy);

--
2.25.1

2022-09-14 08:21:57

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 11/12] dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC

Add devicetree bindings support for SM8450 SoC. Only the clocks are
different on this platform, rest is same as SDX55.

Reviewed-by: Rob Herring <[email protected]>
Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
.../devicetree/bindings/pci/qcom,pcie-ep.yaml | 39 +++++++++++++++++--
1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
index bb8e982e69be..977c976ea799 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
@@ -11,7 +11,9 @@ maintainers:

properties:
compatible:
- const: qcom,sdx55-pcie-ep
+ enum:
+ - qcom,sdx55-pcie-ep
+ - qcom,sm8450-pcie-ep

reg:
items:
@@ -32,10 +34,12 @@ properties:
- const: mmio

clocks:
- maxItems: 7
+ minItems: 7
+ maxItems: 8

clock-names:
- maxItems: 7
+ minItems: 7
+ maxItems: 8

qcom,perst-regs:
description: Reference to a syscon representing TCSR followed by the two
@@ -124,6 +128,35 @@ allOf:
- const: sleep
- const: ref

+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,sm8450-pcie-ep
+ then:
+ properties:
+ clocks:
+ items:
+ - description: PCIe Auxiliary clock
+ - description: PCIe CFG AHB clock
+ - description: PCIe Master AXI clock
+ - description: PCIe Slave AXI clock
+ - description: PCIe Slave Q2A AXI clock
+ - description: PCIe Reference clock
+ - description: PCIe DDRSS SF TBU clock
+ - description: PCIe AGGRE NOC AXI clock
+ clock-names:
+ items:
+ - const: aux
+ - const: cfg
+ - const: bus_master
+ - const: bus_slave
+ - const: slave_q2a
+ - const: ref
+ - const: ddrss_sf_tbu
+ - const: aggre_noc_axi
+
unevaluatedProperties: false

examples:
--
2.25.1

2022-09-14 08:35:30

by Manivannan Sadhasivam

[permalink] [raw]
Subject: [PATCH v4 12/12] PCI: qcom-ep: Add support for SM8450 SoC

Add support for SM8450 SoC to the Qualcomm PCIe Endpoint Controller
driver. The driver uses the same config as of the existing SDX55 chipset.
So additional settings are not required.

Signed-off-by: Manivannan Sadhasivam <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 92140a09aac5..16bb8f166c3b 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -789,6 +789,7 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)

static const struct of_device_id qcom_pcie_ep_match[] = {
{ .compatible = "qcom,sdx55-pcie-ep", },
+ { .compatible = "qcom,sm8450-pcie-ep", },
{ }
};

--
2.25.1

2022-10-03 07:11:52

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v4 00/12] Improvements to the Qcom PCIe Endpoint driver

On Wed, Sep 14, 2022 at 01:23:38PM +0530, Manivannan Sadhasivam wrote:
> Hello,
>
> This series contains improvements to the Qualcomm PCIe Endpoint controller
> driver. The major improvements are the addition of SM8450 SoC support and
> debugfs interface for exposing link transition counts.
>
> This series has been tested on SM8450 based dev board.
>
> NOTE: Since the bindings are ACKed, the whole series could be merged to the
> PCI tree.
>

Lorenzo, can this series make it for 6.1?

Thanks,
Mani

> Thanks,
> Mani
>
> Changes in v4:
>
> * Collected tags for bindings patches
> * Reworded the subject of patch 2/12
>
> Changes in v3:
>
> * Removed the maxItems property from "items" list
> * Reworded the debugfs patch
> * Dropped the eDMA patch since that depends on ongoing eDMA series from Sergey
> * Added two new patches that helps in saving power during idle and low power
> state
>
> Changes in v2:
>
> * Fixed the comments on bindings patches
> * Added Ack from Krzysztof
>
> Manivannan Sadhasivam (12):
> PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure
> PCI: qcom-ep: Rely on the clocks supplied by devicetree
> PCI: qcom-ep: Make use of the cached dev pointer
> PCI: qcom-ep: Disable IRQs during driver remove
> PCI: qcom-ep: Expose link transition counts via debugfs
> PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS
> PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic
> dt-bindings: PCI: qcom-ep: Make PERST separation optional
> PCI: qcom-ep: Make PERST separation optional
> dt-bindings: PCI: qcom-ep: Define clocks per platform
> dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC
> PCI: qcom-ep: Add support for SM8450 SoC
>
> .../devicetree/bindings/pci/qcom,pcie-ep.yaml | 86 +++++++---
> drivers/pci/controller/dwc/pcie-qcom-ep.c | 154 ++++++++++++++----
> 2 files changed, 188 insertions(+), 52 deletions(-)
>
> --
> 2.25.1
>

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

2022-10-03 09:28:14

by Lorenzo Pieralisi

[permalink] [raw]
Subject: Re: [PATCH v4 00/12] Improvements to the Qcom PCIe Endpoint driver

On Wed, 14 Sep 2022 13:23:38 +0530, Manivannan Sadhasivam wrote:
> This series contains improvements to the Qualcomm PCIe Endpoint controller
> driver. The major improvements are the addition of SM8450 SoC support and
> debugfs interface for exposing link transition counts.
>
> This series has been tested on SM8450 based dev board.
>
> NOTE: Since the bindings are ACKed, the whole series could be merged to the
> PCI tree.
>
> [...]

Applied to pci/qcom, thanks!

[01/12] PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure
https://git.kernel.org/lpieralisi/pci/c/f1bfbd000f3b
[02/12] PCI: qcom-ep: Rely on the clocks supplied by devicetree
https://git.kernel.org/lpieralisi/pci/c/e2efd31465b1
[03/12] PCI: qcom-ep: Make use of the cached dev pointer
https://git.kernel.org/lpieralisi/pci/c/9cf4843e1acf
[04/12] PCI: qcom-ep: Disable IRQs during driver remove
https://git.kernel.org/lpieralisi/pci/c/cf0adac4baee
[05/12] PCI: qcom-ep: Expose link transition counts via debugfs
https://git.kernel.org/lpieralisi/pci/c/d48d1bd912a2
[06/12] PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS
https://git.kernel.org/lpieralisi/pci/c/0d47c6b2c9ea
[07/12] PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic
https://git.kernel.org/lpieralisi/pci/c/928decbb22c4
[08/12] dt-bindings: PCI: qcom-ep: Make PERST separation optional
https://git.kernel.org/lpieralisi/pci/c/f5b366f4d1f2
[09/12] PCI: qcom-ep: Make PERST separation optional
https://git.kernel.org/lpieralisi/pci/c/1085b53e3bad
[10/12] dt-bindings: PCI: qcom-ep: Define clocks per platform
https://git.kernel.org/lpieralisi/pci/c/2c744cd7e7e5
[11/12] dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC
https://git.kernel.org/lpieralisi/pci/c/0b0c3ff8de93
[12/12] PCI: qcom-ep: Add support for SM8450 SoC
https://git.kernel.org/lpieralisi/pci/c/e5107be15bef

Thanks,
Lorenzo

2022-10-05 22:14:15

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v4 06/12] PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS

[+cc Krishna]

On Wed, Sep 14, 2022 at 01:23:44PM +0530, Manivannan Sadhasivam wrote:
> During L1SS, gate the Master clock supplied to the MHI bus to save power.
>
> Signed-off-by: Manivannan Sadhasivam <[email protected]>
> ---
> drivers/pci/controller/dwc/pcie-qcom-ep.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 2dc6d4e44aff..526e98ea23f6 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -27,6 +27,7 @@
> #define PARF_SYS_CTRL 0x00
> #define PARF_DB_CTRL 0x10
> #define PARF_PM_CTRL 0x20
> +#define PARF_MHI_CLOCK_RESET_CTRL 0x174
> #define PARF_MHI_BASE_ADDR_LOWER 0x178
> #define PARF_MHI_BASE_ADDR_UPPER 0x17c
> #define PARF_DEBUG_INT_EN 0x190
> @@ -89,6 +90,9 @@
> #define PARF_PM_CTRL_READY_ENTR_L23 BIT(2)
> #define PARF_PM_CTRL_REQ_NOT_ENTR_L1 BIT(5)
>
> +/* PARF_MHI_CLOCK_RESET_CTRL fields */
> +#define PARF_MSTR_AXI_CLK_EN BIT(1)
> +
> /* PARF_AXI_MSTR_RD_HALT_NO_WRITES register fields */
> #define PARF_AXI_MSTR_RD_HALT_NO_WRITE_EN BIT(0)
>
> @@ -394,6 +398,11 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
> pcie_ep->parf + PARF_MHI_BASE_ADDR_LOWER);
> writel_relaxed(0, pcie_ep->parf + PARF_MHI_BASE_ADDR_UPPER);
>
> + /* Gate Master AXI clock to MHI bus during L1SS */
> + val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
> + val &= ~PARF_MSTR_AXI_CLK_EN;
> + val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);

Is this code executed when the link actually transitions to L1.x, or
is this just configuring things so that when the link does transition
to L1.x sometime later, hardware will gate the Master AXI clock?

Just curious because this looks more like *configuration*, i.e., the
latter, but there's the ongoing conversation about qcom system
suspend/resume, where IIUC, software is involved at least in some
L1.2 exits.

> dw_pcie_ep_init_notify(&pcie_ep->pci.ep);
>
> /* Enable LTSSM */
> --
> 2.25.1
>

2022-10-05 22:33:05

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v4 06/12] PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS

On Wed, Oct 05, 2022 at 05:08:38PM -0500, Bjorn Helgaas wrote:
> [+cc Krishna]
>
> On Wed, Sep 14, 2022 at 01:23:44PM +0530, Manivannan Sadhasivam wrote:
> > During L1SS, gate the Master clock supplied to the MHI bus to save power.
> >
> > Signed-off-by: Manivannan Sadhasivam <[email protected]>
> > ---
> > drivers/pci/controller/dwc/pcie-qcom-ep.c | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> > index 2dc6d4e44aff..526e98ea23f6 100644
> > --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> > @@ -27,6 +27,7 @@
> > #define PARF_SYS_CTRL 0x00
> > #define PARF_DB_CTRL 0x10
> > #define PARF_PM_CTRL 0x20
> > +#define PARF_MHI_CLOCK_RESET_CTRL 0x174
> > #define PARF_MHI_BASE_ADDR_LOWER 0x178
> > #define PARF_MHI_BASE_ADDR_UPPER 0x17c
> > #define PARF_DEBUG_INT_EN 0x190
> > @@ -89,6 +90,9 @@
> > #define PARF_PM_CTRL_READY_ENTR_L23 BIT(2)
> > #define PARF_PM_CTRL_REQ_NOT_ENTR_L1 BIT(5)
> >
> > +/* PARF_MHI_CLOCK_RESET_CTRL fields */
> > +#define PARF_MSTR_AXI_CLK_EN BIT(1)
> > +
> > /* PARF_AXI_MSTR_RD_HALT_NO_WRITES register fields */
> > #define PARF_AXI_MSTR_RD_HALT_NO_WRITE_EN BIT(0)
> >
> > @@ -394,6 +398,11 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
> > pcie_ep->parf + PARF_MHI_BASE_ADDR_LOWER);
> > writel_relaxed(0, pcie_ep->parf + PARF_MHI_BASE_ADDR_UPPER);
> >
> > + /* Gate Master AXI clock to MHI bus during L1SS */
> > + val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
> > + val &= ~PARF_MSTR_AXI_CLK_EN;
> > + val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
>
> Is this code executed when the link actually transitions to L1.x, or
> is this just configuring things so that when the link does transition
> to L1.x sometime later, hardware will gate the Master AXI clock?
>

It is the latter... This patch programs the EP controller in such a way that
when the link enters L1.x, the AXI clock supplied to the MHI bus (EP function)
will be cut-off to save power. Once the link goes out of L1.x, the clock will
be restored by the controller.

> Just curious because this looks more like *configuration*, i.e., the
> latter, but there's the ongoing conversation about qcom system
> suspend/resume, where IIUC, software is involved at least in some
> L1.2 exits.
>

Krishna's suspend/resume patches are for Qcom PCIe RC controller, but this
series and this patch is for Qcom PCIe EP controller.

Thanks,
Mani

> > dw_pcie_ep_init_notify(&pcie_ep->pci.ep);
> >
> > /* Enable LTSSM */
> > --
> > 2.25.1
> >

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