Subject: [PATCH v4 1/3] PCI: qcom: Refactor common code

Refactor common code from RC(Root Complex) and EP(End Point)
drivers and move them to a common driver. This acts as placeholder
for common source code for both drivers, thus avoiding duplication.

Signed-off-by: Shashank Babu Chinta Venkata <[email protected]>
---
drivers/pci/controller/dwc/Kconfig | 5 ++
drivers/pci/controller/dwc/Makefile | 1 +
drivers/pci/controller/dwc/pcie-qcom-common.c | 76 +++++++++++++++++++
drivers/pci/controller/dwc/pcie-qcom-common.h | 12 +++
drivers/pci/controller/dwc/pcie-qcom-ep.c | 39 +---------
drivers/pci/controller/dwc/pcie-qcom.c | 69 +++--------------
6 files changed, 108 insertions(+), 94 deletions(-)
create mode 100644 drivers/pci/controller/dwc/pcie-qcom-common.c
create mode 100644 drivers/pci/controller/dwc/pcie-qcom-common.h

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 8afacc90c63b..1599550cd628 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -265,12 +265,16 @@ config PCIE_DW_PLAT_EP
order to enable device-specific features PCI_DW_PLAT_EP must be
selected.

+config PCIE_QCOM_COMMON
+ bool
+
config PCIE_QCOM
bool "Qualcomm PCIe controller (host mode)"
depends on OF && (ARCH_QCOM || COMPILE_TEST)
depends on PCI_MSI
select PCIE_DW_HOST
select CRC8
+ select PCIE_QCOM_COMMON
help
Say Y here to enable PCIe controller support on Qualcomm SoCs. The
PCIe controller uses the DesignWare core plus Qualcomm-specific
@@ -281,6 +285,7 @@ config PCIE_QCOM_EP
depends on OF && (ARCH_QCOM || COMPILE_TEST)
depends on PCI_ENDPOINT
select PCIE_DW_EP
+ select PCIE_QCOM_COMMON
help
Say Y here to enable support for the PCIe controllers on Qualcomm SoCs
to work in endpoint mode. The PCIe controller uses the DesignWare core
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index bac103faa523..3f557dd60c38 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o
obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
obj-$(CONFIG_PCIE_QCOM_EP) += pcie-qcom-ep.o
+obj-$(CONFIG_PCIE_QCOM_COMMON) += pcie-qcom-common.o
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
obj-$(CONFIG_PCIE_ROCKCHIP_DW_HOST) += pcie-dw-rockchip.o
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
new file mode 100644
index 000000000000..228d9eec0222
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2015, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2021 Linaro Limited.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/interconnect.h>
+
+#include "../../pci.h"
+#include "pcie-designware.h"
+#include "pcie-qcom-common.h"
+
+#define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
+ Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
+
+struct icc_path *qcom_pcie_common_icc_get_resource(struct dw_pcie *pci, const char *path)
+{
+ struct icc_path *icc_mem_p;
+
+ icc_mem_p = devm_of_icc_get(pci->dev, path);
+ if (IS_ERR_OR_NULL(icc_mem_p))
+ return PTR_ERR(icc_mem_p);
+ return icc_mem_p;
+}
+EXPORT_SYMBOL_GPL(qcom_pcie_common_icc_get_resource);
+
+int qcom_pcie_common_icc_init(struct dw_pcie *pci, struct icc_path *icc_mem)
+{
+ int ret;
+
+ /*
+ * 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(icc_mem, 0, QCOM_PCIE_LINK_SPEED_TO_BW(1));
+ if (ret) {
+ dev_err(pci->dev, "Failed to set interconnect bandwidth: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_pcie_common_icc_init);
+
+void qcom_pcie_common_icc_update(struct dw_pcie *pci, struct icc_path *icc_mem)
+{
+ u32 offset, status;
+ int speed, width;
+ int ret;
+
+ if (!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);
+
+ ret = icc_set_bw(icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed));
+ if (ret)
+ dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
+ ret);
+}
+EXPORT_SYMBOL_GPL(qcom_pcie_common_icc_update);
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h
new file mode 100644
index 000000000000..da1760c7e164
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-qcom-common.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2014-2015, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2021 Linaro Limited.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "pcie-designware.h"
+
+struct icc_path *qcom_pcie_common_icc_get_resource(struct dw_pcie *pci, const char *path);
+int qcom_pcie_common_icc_init(struct dw_pcie *pci, struct icc_path *icc_mem);
+void qcom_pcie_common_icc_update(struct dw_pcie *pci, struct icc_path *icc_mem);
diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 36e5e80cd22f..f0c61d847643 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -25,6 +25,7 @@

#include "../../pci.h"
#include "pcie-designware.h"
+#include "pcie-qcom-common.h"

/* PARF registers */
#define PARF_SYS_CTRL 0x00
@@ -137,9 +138,6 @@
#define CORE_RESET_TIME_US_MAX 1005
#define WAKE_DELAY_US 2000 /* 2 ms */

-#define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
- Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
-
#define to_pcie_ep(x) dev_get_drvdata((x)->dev)

enum qcom_pcie_ep_link_status {
@@ -278,28 +276,6 @@ static void qcom_pcie_dw_write_dbi2(struct dw_pcie *pci, void __iomem *base,
writel(0, pcie_ep->elbi + ELBI_CS2_ENABLE);
}

-static void qcom_pcie_ep_icc_update(struct qcom_pcie_ep *pcie_ep)
-{
- struct dw_pcie *pci = &pcie_ep->pci;
- u32 offset, status;
- int speed, width;
- int ret;
-
- if (!pcie_ep->icc_mem)
- return;
-
- offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
- status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
-
- speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
- width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status);
-
- ret = icc_set_bw(pcie_ep->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed));
- if (ret)
- dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
- ret);
-}
-
static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
{
struct dw_pcie *pci = &pcie_ep->pci;
@@ -325,14 +301,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
if (ret)
goto err_phy_exit;

- /*
- * 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_ep->icc_mem, 0, QCOM_PCIE_LINK_SPEED_TO_BW(1));
+ ret = qcom_pcie_common_icc_init(pci, pcie_ep->icc_mem);
if (ret) {
dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
ret);
@@ -616,7 +585,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
if (IS_ERR(pcie_ep->phy))
ret = PTR_ERR(pcie_ep->phy);

- pcie_ep->icc_mem = devm_of_icc_get(dev, "pcie-mem");
+ pcie_ep->icc_mem = qcom_pcie_common_icc_get_resource(&pcie_ep->pci, "pcie-mem");
if (IS_ERR(pcie_ep->icc_mem))
ret = PTR_ERR(pcie_ep->icc_mem);

@@ -643,7 +612,7 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data)
} else if (FIELD_GET(PARF_INT_ALL_BME, status)) {
dev_dbg(dev, "Received BME event. Link is enabled!\n");
pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED;
- qcom_pcie_ep_icc_update(pcie_ep);
+ qcom_pcie_common_icc_update(pci, pcie_ep->icc_mem);
pci_epc_bme_notify(pci->ep.epc);
} else if (FIELD_GET(PARF_INT_ALL_PM_TURNOFF, status)) {
dev_dbg(dev, "Received PM Turn-off event! Entering L23\n");
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 2ce2a3bd932b..0095c42aeee0 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -32,6 +32,7 @@
#include <linux/types.h>

#include "../../pci.h"
+#include "pcie-qcom-common.h"
#include "pcie-designware.h"

/* PARF registers */
@@ -147,9 +148,6 @@

#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))

-#define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
- Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
-
#define QCOM_PCIE_1_0_0_MAX_CLOCKS 4
struct qcom_pcie_resources_1_0_0 {
struct clk_bulk_data clks[QCOM_PCIE_1_0_0_MAX_CLOCKS];
@@ -1363,59 +1361,6 @@ 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, QCOM_PCIE_LINK_SPEED_TO_BW(1));
- 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;
- 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);
-
- ret = icc_set_bw(pcie->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed));
- if (ret) {
- dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
- ret);
- }
-}
-
static int qcom_pcie_link_transition_count(struct seq_file *s, void *data)
{
struct qcom_pcie *pcie = (struct qcom_pcie *)dev_get_drvdata(s->private);
@@ -1524,7 +1469,13 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}

- ret = qcom_pcie_icc_init(pcie);
+ pcie->icc_mem = qcom_pcie_common_icc_get_resource(pcie->pci, "pcie-mem");
+ if (IS_ERR_OR_NULL(pcie->icc_mem)) {
+ ret = PTR_ERR(pcie->icc_mem);
+ goto err_pm_runtime_put;
+ }
+
+ ret = qcom_pcie_common_icc_init(pcie->pci, pcie->icc_mem);
if (ret)
goto err_pm_runtime_put;

@@ -1546,7 +1497,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_phy_exit;
}

- qcom_pcie_icc_update(pcie);
+ qcom_pcie_common_icc_update(pcie->pci, pcie->icc_mem);

if (pcie->mhi)
qcom_pcie_init_debugfs(pcie);
@@ -1613,7 +1564,7 @@ static int qcom_pcie_resume_noirq(struct device *dev)
pcie->suspended = false;
}

- qcom_pcie_icc_update(pcie);
+ qcom_pcie_common_icc_update(pcie->pci, pcie->icc_mem);

return 0;
}
--
2.43.2



2024-05-04 05:31:33

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v4 1/3] PCI: qcom: Refactor common code

Hi Shashank,

kernel test robot noticed the following build warnings:

[auto build test WARNING on pci/next]
[also build test WARNING on pci/for-linus linus/master v6.9-rc6 next-20240503]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Shashank-Babu-Chinta-Venkata/PCI-qcom-Refactor-common-code/20240502-003801
base: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link: https://lore.kernel.org/r/20240501163610.8900-2-quic_schintav%40quicinc.com
patch subject: [PATCH v4 1/3] PCI: qcom: Refactor common code
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20240504/[email protected]/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240504/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

drivers/pci/controller/dwc/pcie-qcom-common.c: In function 'qcom_pcie_common_icc_get_resource':
>> drivers/pci/controller/dwc/pcie-qcom-common.c:25:24: warning: returning 'long int' from a function with return type 'struct icc_path *' makes pointer from integer without a cast [-Wint-conversion]
25 | return PTR_ERR(icc_mem_p);
| ^~~~~~~~~~~~~~~~~~


vim +25 drivers/pci/controller/dwc/pcie-qcom-common.c

15
16 #define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
17 Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
18
19 struct icc_path *qcom_pcie_common_icc_get_resource(struct dw_pcie *pci, const char *path)
20 {
21 struct icc_path *icc_mem_p;
22
23 icc_mem_p = devm_of_icc_get(pci->dev, path);
24 if (IS_ERR_OR_NULL(icc_mem_p))
> 25 return PTR_ERR(icc_mem_p);
26 return icc_mem_p;
27 }
28 EXPORT_SYMBOL_GPL(qcom_pcie_common_icc_get_resource);
29

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2024-05-06 07:56:43

by Johan Hovold

[permalink] [raw]
Subject: Re: [PATCH v4 1/3] PCI: qcom: Refactor common code

On Wed, May 01, 2024 at 09:35:32AM -0700, Shashank Babu Chinta Venkata wrote:
> Refactor common code from RC(Root Complex) and EP(End Point)
> drivers and move them to a common driver. This acts as placeholder
> for common source code for both drivers, thus avoiding duplication.
>
> Signed-off-by: Shashank Babu Chinta Venkata <[email protected]>
> ---
> drivers/pci/controller/dwc/Kconfig | 5 ++
> drivers/pci/controller/dwc/Makefile | 1 +
> drivers/pci/controller/dwc/pcie-qcom-common.c | 76 +++++++++++++++++++
> drivers/pci/controller/dwc/pcie-qcom-common.h | 12 +++
> drivers/pci/controller/dwc/pcie-qcom-ep.c | 39 +---------
> drivers/pci/controller/dwc/pcie-qcom.c | 69 +++--------------
> 6 files changed, 108 insertions(+), 94 deletions(-)
> create mode 100644 drivers/pci/controller/dwc/pcie-qcom-common.c
> create mode 100644 drivers/pci/controller/dwc/pcie-qcom-common.h

> diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
> new file mode 100644
> index 000000000000..228d9eec0222
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
> @@ -0,0 +1,76 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2014-2015, 2020 The Linux Foundation. All rights reserved.
> + * Copyright (c) 2015, 2021 Linaro Limited.
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.

You can't claim copyright for just moving old code around. So drop this.

> + *
> + */

> diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h
> new file mode 100644
> index 000000000000..da1760c7e164
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-qcom-common.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2014-2015, 2020 The Linux Foundation. All rights reserved.
> + * Copyright (c) 2015, 2021 Linaro Limited.
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.

Same here.

> + */

Johan

2024-05-07 21:05:24

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v4 1/3] PCI: qcom: Refactor common code

Hi Shashank,

kernel test robot noticed the following build warnings:

[auto build test WARNING on pci/next]
[also build test WARNING on pci/for-linus linus/master v6.9-rc7 next-20240507]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Shashank-Babu-Chinta-Venkata/PCI-qcom-Refactor-common-code/20240502-003801
base: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link: https://lore.kernel.org/r/20240501163610.8900-2-quic_schintav%40quicinc.com
patch subject: [PATCH v4 1/3] PCI: qcom: Refactor common code
config: mips-randconfig-r112-20240508 (https://download.01.org/0day-ci/archive/20240508/[email protected]/config)
compiler: mips-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240508/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

sparse warnings: (new ones prefixed by >>)
>> drivers/pci/controller/dwc/pcie-qcom-common.c:25:31: sparse: sparse: incorrect type in return expression (different base types) @@ expected struct icc_path * @@ got long @@
drivers/pci/controller/dwc/pcie-qcom-common.c:25:31: sparse: expected struct icc_path *
drivers/pci/controller/dwc/pcie-qcom-common.c:25:31: sparse: got long

vim +25 drivers/pci/controller/dwc/pcie-qcom-common.c

15
16 #define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
17 Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
18
19 struct icc_path *qcom_pcie_common_icc_get_resource(struct dw_pcie *pci, const char *path)
20 {
21 struct icc_path *icc_mem_p;
22
23 icc_mem_p = devm_of_icc_get(pci->dev, path);
24 if (IS_ERR_OR_NULL(icc_mem_p))
> 25 return PTR_ERR(icc_mem_p);
26 return icc_mem_p;
27 }
28 EXPORT_SYMBOL_GPL(qcom_pcie_common_icc_get_resource);
29

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki