* [PATCH v10 1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller
2026-01-29 9:26 [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller zhangsenchuan
@ 2026-01-29 9:28 ` zhangsenchuan
2026-01-29 9:29 ` [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver zhangsenchuan
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: zhangsenchuan @ 2026-01-29 9:28 UTC (permalink / raw)
To: bhelgaas, mani, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li
Cc: ningyu, linmin, pinkesh.vaghela, ouyanghui, Senchuan Zhang
From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
Add Device Tree binding documentation for the Eswin EIC7700 PCIe
controller module, the PCIe controller enables the core to correctly
initialize and manage the PCIe bus and connected devices.
Signed-off-by: Yu Ning <ningyu@eswincomputing.com>
Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>
Signed-off-by: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
.../bindings/pci/eswin,eic7700-pcie.yaml | 167 ++++++++++++++++++
1 file changed, 167 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/eswin,eic7700-pcie.yaml
diff --git a/Documentation/devicetree/bindings/pci/eswin,eic7700-pcie.yaml b/Documentation/devicetree/bindings/pci/eswin,eic7700-pcie.yaml
new file mode 100644
index 000000000000..9c0150834e6d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/eswin,eic7700-pcie.yaml
@@ -0,0 +1,167 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/eswin,eic7700-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Eswin EIC7700 PCIe host controller
+
+maintainers:
+ - Yu Ning <ningyu@eswincomputing.com>
+ - Senchuan Zhang <zhangsenchuan@eswincomputing.com>
+ - Yanghui Ou <ouyanghui@eswincomputing.com>
+
+description:
+ Eswin EIC7700 SoC PCIe root complex controller is based on the Synopsys
+ DesignWare PCIe IP.
+
+properties:
+ compatible:
+ const: eswin,eic7700-pcie
+
+ reg:
+ maxItems: 3
+
+ reg-names:
+ items:
+ - const: dbi
+ - const: config
+ - const: elbi
+
+ ranges:
+ maxItems: 3
+
+ '#interrupt-cells':
+ const: 1
+
+ interrupt-names:
+ items:
+ - const: msi
+ - const: inta
+ - const: intb
+ - const: intc
+ - const: intd
+
+ interrupt-map:
+ maxItems: 4
+
+ interrupt-map-mask:
+ items:
+ - const: 0
+ - const: 0
+ - const: 0
+ - const: 7
+
+ clocks:
+ maxItems: 4
+
+ clock-names:
+ items:
+ - const: mstr
+ - const: dbi
+ - const: phy_reg
+ - const: aux
+
+ resets:
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: dbi
+ - const: pwr
+
+patternProperties:
+ "^pcie@":
+ type: object
+ $ref: /schemas/pci/pci-pci-bridge.yaml#
+
+ properties:
+ reg:
+ maxItems: 1
+
+ num-lanes:
+ maximum: 4
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ items:
+ - const: perst
+
+ required:
+ - reg
+ - ranges
+ - num-lanes
+ - resets
+ - reset-names
+
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - ranges
+ - interrupts
+ - interrupt-names
+ - interrupt-map-mask
+ - interrupt-map
+ - '#interrupt-cells'
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+allOf:
+ - $ref: /schemas/pci/snps,dw-pcie.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie@54000000 {
+ compatible = "eswin,eic7700-pcie";
+ reg = <0x0 0x54000000 0x0 0x4000000>,
+ <0x0 0x40000000 0x0 0x800000>,
+ <0x0 0x50000000 0x0 0x100000>;
+ reg-names = "dbi", "config", "elbi";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x01000000 0x0 0x40800000 0x0 0x40800000 0x0 0x800000>,
+ <0x02000000 0x0 0x41000000 0x0 0x41000000 0x0 0xf000000>,
+ <0x43000000 0x80 0x00000000 0x80 0x00000000 0x2 0x00000000>;
+ bus-range = <0x00 0xff>;
+ clocks = <&clock 144>,
+ <&clock 145>,
+ <&clock 146>,
+ <&clock 147>;
+ clock-names = "mstr", "dbi", "phy_reg", "aux";
+ resets = <&reset 97>,
+ <&reset 98>;
+ reset-names = "dbi", "pwr";
+ interrupts = <220>, <179>, <180>, <181>, <182>, <183>, <184>, <185>, <186>;
+ interrupt-names = "msi", "inta", "intb", "intc", "intd";
+ interrupt-parent = <&plic>;
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &plic 179>,
+ <0x0 0x0 0x0 0x2 &plic 180>,
+ <0x0 0x0 0x0 0x3 &plic 181>,
+ <0x0 0x0 0x0 0x4 &plic 182>;
+ device_type = "pci";
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ device_type = "pci";
+ num-lanes = <4>;
+ resets = <&reset 99>;
+ reset-names = "perst";
+ };
+ };
+ };
--
2.25.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-01-29 9:26 [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller zhangsenchuan
2026-01-29 9:28 ` [PATCH v10 1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller zhangsenchuan
@ 2026-01-29 9:29 ` zhangsenchuan
2026-02-18 12:47 ` Manivannan Sadhasivam
2026-02-01 12:24 ` [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller Leon Romanovsky
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: zhangsenchuan @ 2026-01-29 9:29 UTC (permalink / raw)
To: bhelgaas, mani, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li
Cc: ningyu, linmin, pinkesh.vaghela, ouyanghui, Senchuan Zhang
From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
Add driver for the Eswin EIC7700 PCIe host controller, which is based on
the DesignWare PCIe core, IP revision 5.96a. The PCIe Gen.3 controller
supports a data rate of 8 GT/s and 4 channels, support INTx and MSI
interrupts.
Signed-off-by: Yu Ning <ningyu@eswincomputing.com>
Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>
Signed-off-by: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
---
drivers/pci/controller/dwc/Kconfig | 11 +
drivers/pci/controller/dwc/Makefile | 1 +
drivers/pci/controller/dwc/pcie-eic7700.c | 410 ++++++++++++++++++++++
3 files changed, 422 insertions(+)
create mode 100644 drivers/pci/controller/dwc/pcie-eic7700.c
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 519b59422b47..c837cb5947b6 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -93,6 +93,17 @@ config PCIE_BT1
Enables support for the PCIe controller in the Baikal-T1 SoC to work
in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
+config PCIE_EIC7700
+ tristate "Eswin EIC7700 PCIe controller"
+ depends on ARCH_ESWIN || COMPILE_TEST
+ depends on PCI_MSI
+ select PCIE_DW_HOST
+ help
+ Say Y here if you want PCIe controller support for the Eswin EIC7700.
+ The PCIe controller on EIC7700 is based on DesignWare hardware,
+ enables support for the PCIe controller in the EIC7700 SoC to work in
+ host mode.
+
config PCI_IMX6
bool
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index 67ba59c02038..7c5a5186ea83 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
obj-$(CONFIG_PCIE_AMD_MDB) += pcie-amd-mdb.o
obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
+obj-$(CONFIG_PCIE_EIC7700) += pcie-eic7700.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
diff --git a/drivers/pci/controller/dwc/pcie-eic7700.c b/drivers/pci/controller/dwc/pcie-eic7700.c
new file mode 100644
index 000000000000..dab8e3b98810
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-eic7700.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ESWIN EIC7700 PCIe root complex driver
+ *
+ * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ * Authors: Yu Ning <ningyu@eswincomputing.com>
+ * Senchuan Zhang <zhangsenchuan@eswincomputing.com>
+ * Yanghui Ou <ouyanghui@eswincomputing.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/resource.h>
+#include <linux/reset.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+
+/* ELBI registers */
+#define PCIEELBI_CTRL0_OFFSET 0x0
+#define PCIEELBI_STATUS0_OFFSET 0x100
+
+/* LTSSM register fields */
+#define PCIEELBI_APP_LTSSM_ENABLE BIT(5)
+
+/* APP_HOLD_PHY_RST register fields */
+#define PCIEELBI_APP_HOLD_PHY_RST BIT(6)
+
+/* PM_SEL_AUX_CLK register fields */
+#define PCIEELBI_PM_SEL_AUX_CLK BIT(16)
+
+/* DEV_TYPE register fields */
+#define PCIEELBI_CTRL0_DEV_TYPE GENMASK(3, 0)
+
+/* Vendor and device ID value */
+#define PCI_VENDOR_ID_ESWIN 0x1fe1
+#define PCI_DEVICE_ID_ESWIN_EIC7700 0x2030
+
+#define EIC7700_NUM_RSTS ARRAY_SIZE(eic7700_pcie_rsts)
+
+static const char * const eic7700_pcie_rsts[] = {
+ "pwr",
+ "dbi",
+};
+
+struct eic7700_pcie_port {
+ struct list_head list;
+ struct reset_control *perst;
+ int num_lanes;
+};
+
+struct eic7700_pcie {
+ struct dw_pcie pci;
+ struct clk_bulk_data *clks;
+ struct reset_control_bulk_data resets[EIC7700_NUM_RSTS];
+ struct list_head ports;
+ int num_clks;
+};
+
+#define to_eic7700_pcie(x) dev_get_drvdata((x)->dev)
+
+static int eic7700_pcie_start_link(struct dw_pcie *pci)
+{
+ u32 val;
+
+ /* Enable LTSSM */
+ val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
+ val |= PCIEELBI_APP_LTSSM_ENABLE;
+ writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
+
+ return 0;
+}
+
+static bool eic7700_pcie_link_up(struct dw_pcie *pci)
+{
+ u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+ u16 val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
+
+ return val & PCI_EXP_LNKSTA_DLLLA;
+}
+
+static int eic7700_pcie_perst_reset(struct eic7700_pcie_port *port,
+ struct eic7700_pcie *pcie)
+{
+ int ret;
+
+ ret = reset_control_assert(port->perst);
+ if (ret) {
+ dev_err(pcie->pci.dev, "Failed to assert PERST#\n");
+ return ret;
+ }
+
+ /* Ensure that PERST# has been asserted for at least 100 ms */
+ msleep(PCIE_T_PVPERL_MS);
+
+ ret = reset_control_deassert(port->perst);
+ if (ret) {
+ dev_err(pcie->pci.dev, "Failed to deassert PERST#\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void eic7700_pcie_assert(struct eic7700_pcie *pcie)
+{
+ struct eic7700_pcie_port *port;
+
+ list_for_each_entry(port, &pcie->ports, list)
+ reset_control_assert(port->perst);
+ reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
+}
+
+static int eic7700_pcie_parse_port(struct eic7700_pcie *pcie,
+ struct device_node *node)
+{
+ struct device *dev = pcie->pci.dev;
+ struct eic7700_pcie_port *port;
+
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+
+ port->perst = of_reset_control_get_exclusive(node, "perst");
+ if (IS_ERR(port->perst)) {
+ dev_err(dev, "Failed to get PERST# reset\n");
+ return PTR_ERR(port->perst);
+ }
+
+ /*
+ * TODO: Since the Root Port node is separated out by pcie devicetree,
+ * the DWC core initialization code can't parse the num-lanes attribute
+ * in the Root Port. Before entering the DWC core initialization code,
+ * the platform driver code parses the Root Port node. The EIC7700 only
+ * supports one Root Port node, and the num-lanes attribute is suitable
+ * for the case of one Root Port.
+ */
+ if (!of_property_read_u32(node, "num-lanes", &port->num_lanes))
+ pcie->pci.num_lanes = port->num_lanes;
+
+ INIT_LIST_HEAD(&port->list);
+ list_add_tail(&port->list, &pcie->ports);
+
+ return 0;
+}
+
+static int eic7700_pcie_parse_ports(struct eic7700_pcie *pcie)
+{
+ struct eic7700_pcie_port *port, *tmp;
+ struct device *dev = pcie->pci.dev;
+ int ret;
+
+ for_each_available_child_of_node_scoped(dev->of_node, of_port) {
+ ret = eic7700_pcie_parse_port(pcie, of_port);
+ if (ret)
+ goto err_port;
+ }
+
+ return 0;
+
+err_port:
+ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+ reset_control_put(port->perst);
+ list_del(&port->list);
+ }
+
+ return ret;
+}
+
+static int eic7700_pcie_host_init(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
+ struct eic7700_pcie_port *port;
+ u32 val;
+ int ret;
+
+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
+ if (ret)
+ return ret;
+
+ /*
+ * The PWR and DBI reset signals are respectively used to reset the
+ * PCIe controller and the DBI register.
+ *
+ * The PERST# signal is a reset signal that simultaneously controls the
+ * PCIe controller, PHY, and Endpoint. Before configuring the PHY, the
+ * PERST# signal must first be deasserted.
+ *
+ * The external reference clock is supplied simultaneously to the PHY
+ * and EP. When the PHY is configurable, the entire chip already has
+ * stable power and reference clock. The PHY will be ready within 20ms
+ * after writing app_hold_phy_rst register bit of ELBI register space.
+ */
+ ret = reset_control_bulk_deassert(EIC7700_NUM_RSTS, pcie->resets);
+ if (ret) {
+ dev_err(pcie->pci.dev, "Failed to deassert resets\n");
+ goto err_deassert;
+ }
+
+ /* Configure Root Port type */
+ val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
+ val &= ~PCIEELBI_CTRL0_DEV_TYPE;
+ val |= FIELD_PREP(PCIEELBI_CTRL0_DEV_TYPE, PCI_EXP_TYPE_ROOT_PORT);
+ writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
+
+ list_for_each_entry(port, &pcie->ports, list) {
+ ret = eic7700_pcie_perst_reset(port, pcie);
+ if (ret)
+ goto err_perst;
+ }
+
+ /* Configure app_hold_phy_rst */
+ val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
+ val &= ~PCIEELBI_APP_HOLD_PHY_RST;
+ writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
+
+ /* The maximum waiting time for the clock switch lock is 20ms */
+ ret = readl_poll_timeout(pci->elbi_base + PCIEELBI_STATUS0_OFFSET, val,
+ !(val & PCIEELBI_PM_SEL_AUX_CLK), 1000,
+ 20000);
+ if (ret) {
+ dev_err(pci->dev, "Timeout waiting for PM_SEL_AUX_CLK ready\n");
+ goto err_phy_init;
+ }
+
+ /*
+ * Configure ESWIN VID:DID for Root Port as the default values are
+ * invalid.
+ */
+ dw_pcie_dbi_ro_wr_en(pci);
+ dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, PCI_VENDOR_ID_ESWIN);
+ dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, PCI_DEVICE_ID_ESWIN_EIC7700);
+ dw_pcie_dbi_ro_wr_dis(pci);
+
+ return 0;
+
+err_phy_init:
+ list_for_each_entry(port, &pcie->ports, list)
+ reset_control_assert(port->perst);
+err_perst:
+ reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
+err_deassert:
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+
+ return ret;
+}
+
+static void eic7700_pcie_host_deinit(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
+
+ eic7700_pcie_assert(pcie);
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+}
+
+static const struct dw_pcie_host_ops eic7700_pcie_host_ops = {
+ .init = eic7700_pcie_host_init,
+ .deinit = eic7700_pcie_host_deinit,
+};
+
+static const struct dw_pcie_ops dw_pcie_ops = {
+ .start_link = eic7700_pcie_start_link,
+ .link_up = eic7700_pcie_link_up,
+};
+
+static int eic7700_pcie_probe(struct platform_device *pdev)
+{
+ struct eic7700_pcie_port *port, *tmp;
+ struct device *dev = &pdev->dev;
+ struct eic7700_pcie *pcie;
+ struct dw_pcie *pci;
+ int ret, i;
+
+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&pcie->ports);
+
+ pci = &pcie->pci;
+ pci->dev = dev;
+ pci->ops = &dw_pcie_ops;
+ pci->pp.ops = &eic7700_pcie_host_ops;
+
+ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
+ if (pcie->num_clks < 0)
+ return dev_err_probe(dev, pcie->num_clks,
+ "Failed to get pcie clocks\n");
+
+ for (i = 0; i < EIC7700_NUM_RSTS; i++)
+ pcie->resets[i].id = eic7700_pcie_rsts[i];
+
+ ret = devm_reset_control_bulk_get_exclusive(dev, EIC7700_NUM_RSTS,
+ pcie->resets);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get resets\n");
+
+ ret = eic7700_pcie_parse_ports(pcie);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to parse Root Port\n");
+
+ platform_set_drvdata(pdev, pcie);
+
+ pm_runtime_no_callbacks(dev);
+ devm_pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ goto err_pm_runtime_put;
+
+ ret = dw_pcie_host_init(&pci->pp);
+ if (ret) {
+ dev_err(dev, "Failed to init host\n");
+ goto err_pm_runtime_put;
+ }
+
+ return 0;
+
+err_pm_runtime_put:
+ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+ reset_control_put(port->perst);
+ list_del(&port->list);
+ }
+ pm_runtime_put(dev);
+
+ return ret;
+}
+
+static int eic7700_pcie_suspend_noirq(struct device *dev)
+{
+ struct eic7700_pcie *pcie = dev_get_drvdata(dev);
+
+ /*
+ * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
+ * link states. It cannot enter the L2/L3 Ready state through the
+ * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
+ * the dw_pcie_suspend_noirq API is not used.
+ */
+ eic7700_pcie_host_deinit(&pcie->pci.pp);
+
+ return 0;
+}
+
+static int eic7700_pcie_resume_noirq(struct device *dev)
+{
+ struct eic7700_pcie *pcie = dev_get_drvdata(dev);
+ struct eic7700_pcie_port *port, *tmp;
+ int ret;
+
+ ret = eic7700_pcie_host_init(&pcie->pci.pp);
+ if (ret) {
+ dev_err(dev, "Host init failed: %d\n", ret);
+ goto err_init;
+ }
+
+ ret = dw_pcie_setup_rc(&pcie->pci.pp);
+ if (ret)
+ goto err_setup_rc;
+
+ ret = eic7700_pcie_start_link(&pcie->pci);
+ if (ret)
+ goto err_setup_rc;
+
+ dw_pcie_wait_for_link(&pcie->pci);
+
+ return 0;
+
+err_setup_rc:
+ eic7700_pcie_host_deinit(&pcie->pci.pp);
+err_init:
+ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+ reset_control_put(port->perst);
+ list_del(&port->list);
+ }
+
+ return ret;
+}
+
+DEFINE_NOIRQ_DEV_PM_OPS(eic7700_pcie_pm, eic7700_pcie_suspend_noirq,
+ eic7700_pcie_resume_noirq);
+
+static const struct of_device_id eic7700_pcie_of_match[] = {
+ { .compatible = "eswin,eic7700-pcie" },
+ {}
+};
+
+static struct platform_driver eic7700_pcie_driver = {
+ .probe = eic7700_pcie_probe,
+ .driver = {
+ .name = "eic7700-pcie",
+ .of_match_table = eic7700_pcie_of_match,
+ .suppress_bind_attrs = true,
+ .pm = &eic7700_pcie_pm,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+};
+builtin_platform_driver(eic7700_pcie_driver);
+
+MODULE_DESCRIPTION("Eswin EIC7700 PCIe host controller driver");
+MODULE_AUTHOR("Yu Ning <ningyu@eswincomputing.com>");
+MODULE_AUTHOR("Senchuan Zhang <zhangsenchuan@eswincomputing.com>");
+MODULE_AUTHOR("Yanghui Ou <ouyanghui@eswincomputing.com>");
+MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-01-29 9:29 ` [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver zhangsenchuan
@ 2026-02-18 12:47 ` Manivannan Sadhasivam
2026-02-24 8:14 ` zhangsenchuan
0 siblings, 1 reply; 17+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-18 12:47 UTC (permalink / raw)
To: zhangsenchuan
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
>
> Add driver for the Eswin EIC7700 PCIe host controller, which is based on
> the DesignWare PCIe core, IP revision 5.96a. The PCIe Gen.3 controller
> supports a data rate of 8 GT/s and 4 channels, support INTx and MSI
> interrupts.
>
> Signed-off-by: Yu Ning <ningyu@eswincomputing.com>
> Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>
> Signed-off-by: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> ---
> drivers/pci/controller/dwc/Kconfig | 11 +
> drivers/pci/controller/dwc/Makefile | 1 +
> drivers/pci/controller/dwc/pcie-eic7700.c | 410 ++++++++++++++++++++++
> 3 files changed, 422 insertions(+)
> create mode 100644 drivers/pci/controller/dwc/pcie-eic7700.c
>
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 519b59422b47..c837cb5947b6 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -93,6 +93,17 @@ config PCIE_BT1
> Enables support for the PCIe controller in the Baikal-T1 SoC to work
> in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
>
> +config PCIE_EIC7700
> + tristate "Eswin EIC7700 PCIe controller"
> + depends on ARCH_ESWIN || COMPILE_TEST
> + depends on PCI_MSI
> + select PCIE_DW_HOST
> + help
> + Say Y here if you want PCIe controller support for the Eswin EIC7700.
> + The PCIe controller on EIC7700 is based on DesignWare hardware,
> + enables support for the PCIe controller in the EIC7700 SoC to work in
> + host mode.
> +
> config PCI_IMX6
> bool
>
> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> index 67ba59c02038..7c5a5186ea83 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> obj-$(CONFIG_PCIE_AMD_MDB) += pcie-amd-mdb.o
> obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> +obj-$(CONFIG_PCIE_EIC7700) += pcie-eic7700.o
> obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> diff --git a/drivers/pci/controller/dwc/pcie-eic7700.c b/drivers/pci/controller/dwc/pcie-eic7700.c
> new file mode 100644
> index 000000000000..dab8e3b98810
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-eic7700.c
> @@ -0,0 +1,410 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * ESWIN EIC7700 PCIe root complex driver
> + *
> + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.
> + *
> + * Authors: Yu Ning <ningyu@eswincomputing.com>
> + * Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> + * Yanghui Ou <ouyanghui@eswincomputing.com>
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/resource.h>
> +#include <linux/reset.h>
> +#include <linux/types.h>
> +
> +#include "pcie-designware.h"
> +
> +/* ELBI registers */
> +#define PCIEELBI_CTRL0_OFFSET 0x0
> +#define PCIEELBI_STATUS0_OFFSET 0x100
> +
> +/* LTSSM register fields */
> +#define PCIEELBI_APP_LTSSM_ENABLE BIT(5)
> +
> +/* APP_HOLD_PHY_RST register fields */
> +#define PCIEELBI_APP_HOLD_PHY_RST BIT(6)
> +
> +/* PM_SEL_AUX_CLK register fields */
> +#define PCIEELBI_PM_SEL_AUX_CLK BIT(16)
> +
> +/* DEV_TYPE register fields */
> +#define PCIEELBI_CTRL0_DEV_TYPE GENMASK(3, 0)
> +
> +/* Vendor and device ID value */
> +#define PCI_VENDOR_ID_ESWIN 0x1fe1
> +#define PCI_DEVICE_ID_ESWIN_EIC7700 0x2030
> +
> +#define EIC7700_NUM_RSTS ARRAY_SIZE(eic7700_pcie_rsts)
> +
> +static const char * const eic7700_pcie_rsts[] = {
> + "pwr",
> + "dbi",
> +};
> +
> +struct eic7700_pcie_port {
> + struct list_head list;
> + struct reset_control *perst;
> + int num_lanes;
> +};
> +
> +struct eic7700_pcie {
> + struct dw_pcie pci;
> + struct clk_bulk_data *clks;
> + struct reset_control_bulk_data resets[EIC7700_NUM_RSTS];
> + struct list_head ports;
> + int num_clks;
> +};
> +
> +#define to_eic7700_pcie(x) dev_get_drvdata((x)->dev)
> +
> +static int eic7700_pcie_start_link(struct dw_pcie *pci)
> +{
> + u32 val;
> +
> + /* Enable LTSSM */
> + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> + val |= PCIEELBI_APP_LTSSM_ENABLE;
> + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> +
> + return 0;
> +}
> +
> +static bool eic7700_pcie_link_up(struct dw_pcie *pci)
> +{
> + u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> + u16 val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
> +
> + return val & PCI_EXP_LNKSTA_DLLLA;
> +}
> +
> +static int eic7700_pcie_perst_reset(struct eic7700_pcie_port *port,
> + struct eic7700_pcie *pcie)
> +{
> + int ret;
> +
> + ret = reset_control_assert(port->perst);
> + if (ret) {
> + dev_err(pcie->pci.dev, "Failed to assert PERST#\n");
> + return ret;
> + }
> +
> + /* Ensure that PERST# has been asserted for at least 100 ms */
> + msleep(PCIE_T_PVPERL_MS);
> +
> + ret = reset_control_deassert(port->perst);
> + if (ret) {
> + dev_err(pcie->pci.dev, "Failed to deassert PERST#\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void eic7700_pcie_assert(struct eic7700_pcie *pcie)
> +{
> + struct eic7700_pcie_port *port;
> +
> + list_for_each_entry(port, &pcie->ports, list)
> + reset_control_assert(port->perst);
> + reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
> +}
> +
> +static int eic7700_pcie_parse_port(struct eic7700_pcie *pcie,
> + struct device_node *node)
> +{
> + struct device *dev = pcie->pci.dev;
> + struct eic7700_pcie_port *port;
> +
> + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> + if (!port)
> + return -ENOMEM;
> +
> + port->perst = of_reset_control_get_exclusive(node, "perst");
> + if (IS_ERR(port->perst)) {
> + dev_err(dev, "Failed to get PERST# reset\n");
> + return PTR_ERR(port->perst);
> + }
> +
> + /*
> + * TODO: Since the Root Port node is separated out by pcie devicetree,
> + * the DWC core initialization code can't parse the num-lanes attribute
> + * in the Root Port. Before entering the DWC core initialization code,
> + * the platform driver code parses the Root Port node. The EIC7700 only
> + * supports one Root Port node, and the num-lanes attribute is suitable
> + * for the case of one Root Port.
> + */
> + if (!of_property_read_u32(node, "num-lanes", &port->num_lanes))
> + pcie->pci.num_lanes = port->num_lanes;
> +
> + INIT_LIST_HEAD(&port->list);
> + list_add_tail(&port->list, &pcie->ports);
> +
> + return 0;
> +}
> +
> +static int eic7700_pcie_parse_ports(struct eic7700_pcie *pcie)
> +{
> + struct eic7700_pcie_port *port, *tmp;
> + struct device *dev = pcie->pci.dev;
> + int ret;
> +
> + for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> + ret = eic7700_pcie_parse_port(pcie, of_port);
> + if (ret)
> + goto err_port;
> + }
> +
> + return 0;
> +
> +err_port:
> + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> + reset_control_put(port->perst);
> + list_del(&port->list);
> + }
> +
> + return ret;
> +}
> +
> +static int eic7700_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
> + struct eic7700_pcie_port *port;
> + u32 val;
> + int ret;
> +
> + ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
> + if (ret)
> + return ret;
> +
> + /*
> + * The PWR and DBI reset signals are respectively used to reset the
> + * PCIe controller and the DBI register.
> + *
> + * The PERST# signal is a reset signal that simultaneously controls the
> + * PCIe controller, PHY, and Endpoint. Before configuring the PHY, the
> + * PERST# signal must first be deasserted.
> + *
> + * The external reference clock is supplied simultaneously to the PHY
> + * and EP. When the PHY is configurable, the entire chip already has
> + * stable power and reference clock. The PHY will be ready within 20ms
> + * after writing app_hold_phy_rst register bit of ELBI register space.
> + */
> + ret = reset_control_bulk_deassert(EIC7700_NUM_RSTS, pcie->resets);
> + if (ret) {
> + dev_err(pcie->pci.dev, "Failed to deassert resets\n");
> + goto err_deassert;
> + }
> +
> + /* Configure Root Port type */
> + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> + val &= ~PCIEELBI_CTRL0_DEV_TYPE;
> + val |= FIELD_PREP(PCIEELBI_CTRL0_DEV_TYPE, PCI_EXP_TYPE_ROOT_PORT);
> + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> +
> + list_for_each_entry(port, &pcie->ports, list) {
> + ret = eic7700_pcie_perst_reset(port, pcie);
> + if (ret)
> + goto err_perst;
> + }
> +
> + /* Configure app_hold_phy_rst */
> + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> + val &= ~PCIEELBI_APP_HOLD_PHY_RST;
> + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> +
> + /* The maximum waiting time for the clock switch lock is 20ms */
> + ret = readl_poll_timeout(pci->elbi_base + PCIEELBI_STATUS0_OFFSET, val,
> + !(val & PCIEELBI_PM_SEL_AUX_CLK), 1000,
> + 20000);
> + if (ret) {
> + dev_err(pci->dev, "Timeout waiting for PM_SEL_AUX_CLK ready\n");
> + goto err_phy_init;
> + }
> +
> + /*
> + * Configure ESWIN VID:DID for Root Port as the default values are
> + * invalid.
> + */
> + dw_pcie_dbi_ro_wr_en(pci);
> + dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, PCI_VENDOR_ID_ESWIN);
> + dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, PCI_DEVICE_ID_ESWIN_EIC7700);
> + dw_pcie_dbi_ro_wr_dis(pci);
> +
> + return 0;
> +
> +err_phy_init:
> + list_for_each_entry(port, &pcie->ports, list)
> + reset_control_assert(port->perst);
> +err_perst:
> + reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
> +err_deassert:
> + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
> +
> + return ret;
> +}
> +
> +static void eic7700_pcie_host_deinit(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
> +
> + eic7700_pcie_assert(pcie);
> + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
> +}
> +
> +static const struct dw_pcie_host_ops eic7700_pcie_host_ops = {
> + .init = eic7700_pcie_host_init,
> + .deinit = eic7700_pcie_host_deinit,
> +};
> +
> +static const struct dw_pcie_ops dw_pcie_ops = {
> + .start_link = eic7700_pcie_start_link,
> + .link_up = eic7700_pcie_link_up,
> +};
> +
> +static int eic7700_pcie_probe(struct platform_device *pdev)
> +{
> + struct eic7700_pcie_port *port, *tmp;
> + struct device *dev = &pdev->dev;
> + struct eic7700_pcie *pcie;
> + struct dw_pcie *pci;
> + int ret, i;
> +
> + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> + if (!pcie)
> + return -ENOMEM;
> +
> + INIT_LIST_HEAD(&pcie->ports);
> +
> + pci = &pcie->pci;
> + pci->dev = dev;
> + pci->ops = &dw_pcie_ops;
> + pci->pp.ops = &eic7700_pcie_host_ops;
> +
> + pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
> + if (pcie->num_clks < 0)
> + return dev_err_probe(dev, pcie->num_clks,
> + "Failed to get pcie clocks\n");
> +
> + for (i = 0; i < EIC7700_NUM_RSTS; i++)
> + pcie->resets[i].id = eic7700_pcie_rsts[i];
> +
> + ret = devm_reset_control_bulk_get_exclusive(dev, EIC7700_NUM_RSTS,
> + pcie->resets);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to get resets\n");
> +
> + ret = eic7700_pcie_parse_ports(pcie);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to parse Root Port\n");
> +
> + platform_set_drvdata(pdev, pcie);
> +
> + pm_runtime_no_callbacks(dev);
> + devm_pm_runtime_enable(dev);
> + ret = pm_runtime_get_sync(dev);
> + if (ret < 0)
> + goto err_pm_runtime_put;
> +
> + ret = dw_pcie_host_init(&pci->pp);
> + if (ret) {
> + dev_err(dev, "Failed to init host\n");
> + goto err_pm_runtime_put;
> + }
> +
> + return 0;
> +
> +err_pm_runtime_put:
> + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> + reset_control_put(port->perst);
> + list_del(&port->list);
> + }
> + pm_runtime_put(dev);
> +
> + return ret;
> +}
> +
> +static int eic7700_pcie_suspend_noirq(struct device *dev)
> +{
> + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> +
> + /*
> + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> + * link states. It cannot enter the L2/L3 Ready state through the
> + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> + * the dw_pcie_suspend_noirq API is not used.
> + */
With 7.0, you can provide a dummy pme_turn_off() API and set
'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
- Mani
> + eic7700_pcie_host_deinit(&pcie->pci.pp);
> +
> + return 0;
> +}
> +
> +static int eic7700_pcie_resume_noirq(struct device *dev)
> +{
> + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> + struct eic7700_pcie_port *port, *tmp;
> + int ret;
> +
> + ret = eic7700_pcie_host_init(&pcie->pci.pp);
> + if (ret) {
> + dev_err(dev, "Host init failed: %d\n", ret);
> + goto err_init;
> + }
> +
> + ret = dw_pcie_setup_rc(&pcie->pci.pp);
> + if (ret)
> + goto err_setup_rc;
> +
> + ret = eic7700_pcie_start_link(&pcie->pci);
> + if (ret)
> + goto err_setup_rc;
> +
> + dw_pcie_wait_for_link(&pcie->pci);
> +
> + return 0;
> +
> +err_setup_rc:
> + eic7700_pcie_host_deinit(&pcie->pci.pp);
> +err_init:
> + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> + reset_control_put(port->perst);
> + list_del(&port->list);
> + }
> +
> + return ret;
> +}
> +
> +DEFINE_NOIRQ_DEV_PM_OPS(eic7700_pcie_pm, eic7700_pcie_suspend_noirq,
> + eic7700_pcie_resume_noirq);
> +
> +static const struct of_device_id eic7700_pcie_of_match[] = {
> + { .compatible = "eswin,eic7700-pcie" },
> + {}
> +};
> +
> +static struct platform_driver eic7700_pcie_driver = {
> + .probe = eic7700_pcie_probe,
> + .driver = {
> + .name = "eic7700-pcie",
> + .of_match_table = eic7700_pcie_of_match,
> + .suppress_bind_attrs = true,
> + .pm = &eic7700_pcie_pm,
> + .probe_type = PROBE_PREFER_ASYNCHRONOUS,
> + },
> +};
> +builtin_platform_driver(eic7700_pcie_driver);
> +
> +MODULE_DESCRIPTION("Eswin EIC7700 PCIe host controller driver");
> +MODULE_AUTHOR("Yu Ning <ningyu@eswincomputing.com>");
> +MODULE_AUTHOR("Senchuan Zhang <zhangsenchuan@eswincomputing.com>");
> +MODULE_AUTHOR("Yanghui Ou <ouyanghui@eswincomputing.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-18 12:47 ` Manivannan Sadhasivam
@ 2026-02-24 8:14 ` zhangsenchuan
2026-02-25 13:37 ` Manivannan Sadhasivam
0 siblings, 1 reply; 17+ messages in thread
From: zhangsenchuan @ 2026-02-24 8:14 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
> -----Original Messages-----
> From: "Manivannan Sadhasivam" <mani@kernel.org>
> Send time:Wednesday, 18/02/2026 20:47:14
> To: zhangsenchuan@eswincomputing.com
> Cc: bhelgaas@google.com, krzk+dt@kernel.org, conor+dt@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org, robh@kernel.org, p.zabel@pengutronix.de, linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, christian.bruel@foss.st.com, shradha.t@samsung.com, krishna.chundru@oss.qualcomm.com, thippeswamy.havalige@amd.com, inochiama@gmail.com, Frank.li@nxp.com, ningyu@eswincomputing.com, linmin@eswincomputing.com, pinkesh.vaghela@einfochips.com, ouyanghui@eswincomputing.com
> Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
>
> On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> >
> > Add driver for the Eswin EIC7700 PCIe host controller, which is based on
> > the DesignWare PCIe core, IP revision 5.96a. The PCIe Gen.3 controller
> > supports a data rate of 8 GT/s and 4 channels, support INTx and MSI
> > interrupts.
> >
> > Signed-off-by: Yu Ning <ningyu@eswincomputing.com>
> > Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>
> > Signed-off-by: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > ---
> > drivers/pci/controller/dwc/Kconfig | 11 +
> > drivers/pci/controller/dwc/Makefile | 1 +
> > drivers/pci/controller/dwc/pcie-eic7700.c | 410 ++++++++++++++++++++++
> > 3 files changed, 422 insertions(+)
> > create mode 100644 drivers/pci/controller/dwc/pcie-eic7700.c
> >
> > diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> > index 519b59422b47..c837cb5947b6 100644
> > --- a/drivers/pci/controller/dwc/Kconfig
> > +++ b/drivers/pci/controller/dwc/Kconfig
> > @@ -93,6 +93,17 @@ config PCIE_BT1
> > Enables support for the PCIe controller in the Baikal-T1 SoC to work
> > in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
> >
> > +config PCIE_EIC7700
> > + tristate "Eswin EIC7700 PCIe controller"
> > + depends on ARCH_ESWIN || COMPILE_TEST
> > + depends on PCI_MSI
> > + select PCIE_DW_HOST
> > + help
> > + Say Y here if you want PCIe controller support for the Eswin EIC7700.
> > + The PCIe controller on EIC7700 is based on DesignWare hardware,
> > + enables support for the PCIe controller in the EIC7700 SoC to work in
> > + host mode.
> > +
> > config PCI_IMX6
> > bool
> >
> > diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> > index 67ba59c02038..7c5a5186ea83 100644
> > --- a/drivers/pci/controller/dwc/Makefile
> > +++ b/drivers/pci/controller/dwc/Makefile
> > @@ -6,6 +6,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> > obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> > obj-$(CONFIG_PCIE_AMD_MDB) += pcie-amd-mdb.o
> > obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> > +obj-$(CONFIG_PCIE_EIC7700) += pcie-eic7700.o
> > obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> > obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> > obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> > diff --git a/drivers/pci/controller/dwc/pcie-eic7700.c b/drivers/pci/controller/dwc/pcie-eic7700.c
> > new file mode 100644
> > index 000000000000..dab8e3b98810
> > --- /dev/null
> > +++ b/drivers/pci/controller/dwc/pcie-eic7700.c
> > @@ -0,0 +1,410 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * ESWIN EIC7700 PCIe root complex driver
> > + *
> > + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.
> > + *
> > + * Authors: Yu Ning <ningyu@eswincomputing.com>
> > + * Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > + * Yanghui Ou <ouyanghui@eswincomputing.com>
> > + */
> > +
> > +#include <linux/interrupt.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/pci.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/resource.h>
> > +#include <linux/reset.h>
> > +#include <linux/types.h>
> > +
> > +#include "pcie-designware.h"
> > +
> > +/* ELBI registers */
> > +#define PCIEELBI_CTRL0_OFFSET 0x0
> > +#define PCIEELBI_STATUS0_OFFSET 0x100
> > +
> > +/* LTSSM register fields */
> > +#define PCIEELBI_APP_LTSSM_ENABLE BIT(5)
> > +
> > +/* APP_HOLD_PHY_RST register fields */
> > +#define PCIEELBI_APP_HOLD_PHY_RST BIT(6)
> > +
> > +/* PM_SEL_AUX_CLK register fields */
> > +#define PCIEELBI_PM_SEL_AUX_CLK BIT(16)
> > +
> > +/* DEV_TYPE register fields */
> > +#define PCIEELBI_CTRL0_DEV_TYPE GENMASK(3, 0)
> > +
> > +/* Vendor and device ID value */
> > +#define PCI_VENDOR_ID_ESWIN 0x1fe1
> > +#define PCI_DEVICE_ID_ESWIN_EIC7700 0x2030
> > +
> > +#define EIC7700_NUM_RSTS ARRAY_SIZE(eic7700_pcie_rsts)
> > +
> > +static const char * const eic7700_pcie_rsts[] = {
> > + "pwr",
> > + "dbi",
> > +};
> > +
> > +struct eic7700_pcie_port {
> > + struct list_head list;
> > + struct reset_control *perst;
> > + int num_lanes;
> > +};
> > +
> > +struct eic7700_pcie {
> > + struct dw_pcie pci;
> > + struct clk_bulk_data *clks;
> > + struct reset_control_bulk_data resets[EIC7700_NUM_RSTS];
> > + struct list_head ports;
> > + int num_clks;
> > +};
> > +
> > +#define to_eic7700_pcie(x) dev_get_drvdata((x)->dev)
> > +
> > +static int eic7700_pcie_start_link(struct dw_pcie *pci)
> > +{
> > + u32 val;
> > +
> > + /* Enable LTSSM */
> > + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > + val |= PCIEELBI_APP_LTSSM_ENABLE;
> > + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > +
> > + return 0;
> > +}
> > +
> > +static bool eic7700_pcie_link_up(struct dw_pcie *pci)
> > +{
> > + u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> > + u16 val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
> > +
> > + return val & PCI_EXP_LNKSTA_DLLLA;
> > +}
> > +
> > +static int eic7700_pcie_perst_reset(struct eic7700_pcie_port *port,
> > + struct eic7700_pcie *pcie)
> > +{
> > + int ret;
> > +
> > + ret = reset_control_assert(port->perst);
> > + if (ret) {
> > + dev_err(pcie->pci.dev, "Failed to assert PERST#\n");
> > + return ret;
> > + }
> > +
> > + /* Ensure that PERST# has been asserted for at least 100 ms */
> > + msleep(PCIE_T_PVPERL_MS);
> > +
> > + ret = reset_control_deassert(port->perst);
> > + if (ret) {
> > + dev_err(pcie->pci.dev, "Failed to deassert PERST#\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void eic7700_pcie_assert(struct eic7700_pcie *pcie)
> > +{
> > + struct eic7700_pcie_port *port;
> > +
> > + list_for_each_entry(port, &pcie->ports, list)
> > + reset_control_assert(port->perst);
> > + reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
> > +}
> > +
> > +static int eic7700_pcie_parse_port(struct eic7700_pcie *pcie,
> > + struct device_node *node)
> > +{
> > + struct device *dev = pcie->pci.dev;
> > + struct eic7700_pcie_port *port;
> > +
> > + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> > + if (!port)
> > + return -ENOMEM;
> > +
> > + port->perst = of_reset_control_get_exclusive(node, "perst");
> > + if (IS_ERR(port->perst)) {
> > + dev_err(dev, "Failed to get PERST# reset\n");
> > + return PTR_ERR(port->perst);
> > + }
> > +
> > + /*
> > + * TODO: Since the Root Port node is separated out by pcie devicetree,
> > + * the DWC core initialization code can't parse the num-lanes attribute
> > + * in the Root Port. Before entering the DWC core initialization code,
> > + * the platform driver code parses the Root Port node. The EIC7700 only
> > + * supports one Root Port node, and the num-lanes attribute is suitable
> > + * for the case of one Root Port.
> > + */
> > + if (!of_property_read_u32(node, "num-lanes", &port->num_lanes))
> > + pcie->pci.num_lanes = port->num_lanes;
> > +
> > + INIT_LIST_HEAD(&port->list);
> > + list_add_tail(&port->list, &pcie->ports);
> > +
> > + return 0;
> > +}
> > +
> > +static int eic7700_pcie_parse_ports(struct eic7700_pcie *pcie)
> > +{
> > + struct eic7700_pcie_port *port, *tmp;
> > + struct device *dev = pcie->pci.dev;
> > + int ret;
> > +
> > + for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> > + ret = eic7700_pcie_parse_port(pcie, of_port);
> > + if (ret)
> > + goto err_port;
> > + }
> > +
> > + return 0;
> > +
> > +err_port:
> > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > + reset_control_put(port->perst);
> > + list_del(&port->list);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int eic7700_pcie_host_init(struct dw_pcie_rp *pp)
> > +{
> > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > + struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
> > + struct eic7700_pcie_port *port;
> > + u32 val;
> > + int ret;
> > +
> > + ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
> > + if (ret)
> > + return ret;
> > +
> > + /*
> > + * The PWR and DBI reset signals are respectively used to reset the
> > + * PCIe controller and the DBI register.
> > + *
> > + * The PERST# signal is a reset signal that simultaneously controls the
> > + * PCIe controller, PHY, and Endpoint. Before configuring the PHY, the
> > + * PERST# signal must first be deasserted.
> > + *
> > + * The external reference clock is supplied simultaneously to the PHY
> > + * and EP. When the PHY is configurable, the entire chip already has
> > + * stable power and reference clock. The PHY will be ready within 20ms
> > + * after writing app_hold_phy_rst register bit of ELBI register space.
> > + */
> > + ret = reset_control_bulk_deassert(EIC7700_NUM_RSTS, pcie->resets);
> > + if (ret) {
> > + dev_err(pcie->pci.dev, "Failed to deassert resets\n");
> > + goto err_deassert;
> > + }
> > +
> > + /* Configure Root Port type */
> > + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > + val &= ~PCIEELBI_CTRL0_DEV_TYPE;
> > + val |= FIELD_PREP(PCIEELBI_CTRL0_DEV_TYPE, PCI_EXP_TYPE_ROOT_PORT);
> > + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > +
> > + list_for_each_entry(port, &pcie->ports, list) {
> > + ret = eic7700_pcie_perst_reset(port, pcie);
> > + if (ret)
> > + goto err_perst;
> > + }
> > +
> > + /* Configure app_hold_phy_rst */
> > + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > + val &= ~PCIEELBI_APP_HOLD_PHY_RST;
> > + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > +
> > + /* The maximum waiting time for the clock switch lock is 20ms */
> > + ret = readl_poll_timeout(pci->elbi_base + PCIEELBI_STATUS0_OFFSET, val,
> > + !(val & PCIEELBI_PM_SEL_AUX_CLK), 1000,
> > + 20000);
> > + if (ret) {
> > + dev_err(pci->dev, "Timeout waiting for PM_SEL_AUX_CLK ready\n");
> > + goto err_phy_init;
> > + }
> > +
> > + /*
> > + * Configure ESWIN VID:DID for Root Port as the default values are
> > + * invalid.
> > + */
> > + dw_pcie_dbi_ro_wr_en(pci);
> > + dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, PCI_VENDOR_ID_ESWIN);
> > + dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, PCI_DEVICE_ID_ESWIN_EIC7700);
> > + dw_pcie_dbi_ro_wr_dis(pci);
> > +
> > + return 0;
> > +
> > +err_phy_init:
> > + list_for_each_entry(port, &pcie->ports, list)
> > + reset_control_assert(port->perst);
> > +err_perst:
> > + reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
> > +err_deassert:
> > + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
> > +
> > + return ret;
> > +}
> > +
> > +static void eic7700_pcie_host_deinit(struct dw_pcie_rp *pp)
> > +{
> > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > + struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
> > +
> > + eic7700_pcie_assert(pcie);
> > + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
> > +}
> > +
> > +static const struct dw_pcie_host_ops eic7700_pcie_host_ops = {
> > + .init = eic7700_pcie_host_init,
> > + .deinit = eic7700_pcie_host_deinit,
> > +};
> > +
> > +static const struct dw_pcie_ops dw_pcie_ops = {
> > + .start_link = eic7700_pcie_start_link,
> > + .link_up = eic7700_pcie_link_up,
> > +};
> > +
> > +static int eic7700_pcie_probe(struct platform_device *pdev)
> > +{
> > + struct eic7700_pcie_port *port, *tmp;
> > + struct device *dev = &pdev->dev;
> > + struct eic7700_pcie *pcie;
> > + struct dw_pcie *pci;
> > + int ret, i;
> > +
> > + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > + if (!pcie)
> > + return -ENOMEM;
> > +
> > + INIT_LIST_HEAD(&pcie->ports);
> > +
> > + pci = &pcie->pci;
> > + pci->dev = dev;
> > + pci->ops = &dw_pcie_ops;
> > + pci->pp.ops = &eic7700_pcie_host_ops;
> > +
> > + pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
> > + if (pcie->num_clks < 0)
> > + return dev_err_probe(dev, pcie->num_clks,
> > + "Failed to get pcie clocks\n");
> > +
> > + for (i = 0; i < EIC7700_NUM_RSTS; i++)
> > + pcie->resets[i].id = eic7700_pcie_rsts[i];
> > +
> > + ret = devm_reset_control_bulk_get_exclusive(dev, EIC7700_NUM_RSTS,
> > + pcie->resets);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "Failed to get resets\n");
> > +
> > + ret = eic7700_pcie_parse_ports(pcie);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "Failed to parse Root Port\n");
> > +
> > + platform_set_drvdata(pdev, pcie);
> > +
> > + pm_runtime_no_callbacks(dev);
> > + devm_pm_runtime_enable(dev);
> > + ret = pm_runtime_get_sync(dev);
> > + if (ret < 0)
> > + goto err_pm_runtime_put;
> > +
> > + ret = dw_pcie_host_init(&pci->pp);
> > + if (ret) {
> > + dev_err(dev, "Failed to init host\n");
> > + goto err_pm_runtime_put;
> > + }
> > +
> > + return 0;
> > +
> > +err_pm_runtime_put:
> > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > + reset_control_put(port->perst);
> > + list_del(&port->list);
> > + }
> > + pm_runtime_put(dev);
> > +
> > + return ret;
> > +}
> > +
> > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > +{
> > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > +
> > + /*
> > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > + * link states. It cannot enter the L2/L3 Ready state through the
> > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > + * the dw_pcie_suspend_noirq API is not used.
> > + */
>
> With 7.0, you can provide a dummy pme_turn_off() API and set
> 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
>
Hi Mani,
Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
execute, the clk/reset resources in the pci->pp.ops->init function cannot
be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
I have observed that in the current imx6 case, the clk resources cannot be
released either. If qcom and other manufacturers later switch to using the
dw_pcie_resume_noirq function, they will also encounter this problem.
At present, it seems that implementing the suspend/resume functions by myself
is a bit more convenient.
Kind regards,
Senchuan
>
> > + eic7700_pcie_host_deinit(&pcie->pci.pp);
> > +
> > + return 0;
> > +}
> > +
> > +static int eic7700_pcie_resume_noirq(struct device *dev)
> > +{
> > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > + struct eic7700_pcie_port *port, *tmp;
> > + int ret;
> > +
> > + ret = eic7700_pcie_host_init(&pcie->pci.pp);
> > + if (ret) {
> > + dev_err(dev, "Host init failed: %d\n", ret);
> > + goto err_init;
> > + }
> > +
> > + ret = dw_pcie_setup_rc(&pcie->pci.pp);
> > + if (ret)
> > + goto err_setup_rc;
> > +
> > + ret = eic7700_pcie_start_link(&pcie->pci);
> > + if (ret)
> > + goto err_setup_rc;
> > +
> > + dw_pcie_wait_for_link(&pcie->pci);
> > +
> > + return 0;
> > +
> > +err_setup_rc:
> > + eic7700_pcie_host_deinit(&pcie->pci.pp);
> > +err_init:
> > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > + reset_control_put(port->perst);
> > + list_del(&port->list);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +DEFINE_NOIRQ_DEV_PM_OPS(eic7700_pcie_pm, eic7700_pcie_suspend_noirq,
> > + eic7700_pcie_resume_noirq);
> > +
> > +static const struct of_device_id eic7700_pcie_of_match[] = {
> > + { .compatible = "eswin,eic7700-pcie" },
> > + {}
> > +};
> > +
> > +static struct platform_driver eic7700_pcie_driver = {
> > + .probe = eic7700_pcie_probe,
> > + .driver = {
> > + .name = "eic7700-pcie",
> > + .of_match_table = eic7700_pcie_of_match,
> > + .suppress_bind_attrs = true,
> > + .pm = &eic7700_pcie_pm,
> > + .probe_type = PROBE_PREFER_ASYNCHRONOUS,
> > + },
> > +};
> > +builtin_platform_driver(eic7700_pcie_driver);
> > +
> > +MODULE_DESCRIPTION("Eswin EIC7700 PCIe host controller driver");
> > +MODULE_AUTHOR("Yu Ning <ningyu@eswincomputing.com>");
> > +MODULE_AUTHOR("Senchuan Zhang <zhangsenchuan@eswincomputing.com>");
> > +MODULE_AUTHOR("Yanghui Ou <ouyanghui@eswincomputing.com>");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.25.1
> >
>
> --
> மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-24 8:14 ` zhangsenchuan
@ 2026-02-25 13:37 ` Manivannan Sadhasivam
2026-02-26 8:09 ` zhangsenchuan
0 siblings, 1 reply; 17+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-25 13:37 UTC (permalink / raw)
To: zhangsenchuan
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
On Tue, Feb 24, 2026 at 04:14:16PM +0800, zhangsenchuan wrote:
>
>
>
> > -----Original Messages-----
> > From: "Manivannan Sadhasivam" <mani@kernel.org>
> > Send time:Wednesday, 18/02/2026 20:47:14
> > To: zhangsenchuan@eswincomputing.com
> > Cc: bhelgaas@google.com, krzk+dt@kernel.org, conor+dt@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org, robh@kernel.org, p.zabel@pengutronix.de, linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, christian.bruel@foss.st.com, shradha.t@samsung.com, krishna.chundru@oss.qualcomm.com, thippeswamy.havalige@amd.com, inochiama@gmail.com, Frank.li@nxp.com, ningyu@eswincomputing.com, linmin@eswincomputing.com, pinkesh.vaghela@einfochips.com, ouyanghui@eswincomputing.com
> > Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> >
> > On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > >
> > > Add driver for the Eswin EIC7700 PCIe host controller, which is based on
> > > the DesignWare PCIe core, IP revision 5.96a. The PCIe Gen.3 controller
> > > supports a data rate of 8 GT/s and 4 channels, support INTx and MSI
> > > interrupts.
> > >
> > > Signed-off-by: Yu Ning <ningyu@eswincomputing.com>
> > > Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>
> > > Signed-off-by: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > ---
> > > drivers/pci/controller/dwc/Kconfig | 11 +
> > > drivers/pci/controller/dwc/Makefile | 1 +
> > > drivers/pci/controller/dwc/pcie-eic7700.c | 410 ++++++++++++++++++++++
> > > 3 files changed, 422 insertions(+)
> > > create mode 100644 drivers/pci/controller/dwc/pcie-eic7700.c
> > >
> > > diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> > > index 519b59422b47..c837cb5947b6 100644
> > > --- a/drivers/pci/controller/dwc/Kconfig
> > > +++ b/drivers/pci/controller/dwc/Kconfig
> > > @@ -93,6 +93,17 @@ config PCIE_BT1
> > > Enables support for the PCIe controller in the Baikal-T1 SoC to work
> > > in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
> > >
> > > +config PCIE_EIC7700
> > > + tristate "Eswin EIC7700 PCIe controller"
> > > + depends on ARCH_ESWIN || COMPILE_TEST
> > > + depends on PCI_MSI
> > > + select PCIE_DW_HOST
> > > + help
> > > + Say Y here if you want PCIe controller support for the Eswin EIC7700.
> > > + The PCIe controller on EIC7700 is based on DesignWare hardware,
> > > + enables support for the PCIe controller in the EIC7700 SoC to work in
> > > + host mode.
> > > +
> > > config PCI_IMX6
> > > bool
> > >
> > > diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> > > index 67ba59c02038..7c5a5186ea83 100644
> > > --- a/drivers/pci/controller/dwc/Makefile
> > > +++ b/drivers/pci/controller/dwc/Makefile
> > > @@ -6,6 +6,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> > > obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> > > obj-$(CONFIG_PCIE_AMD_MDB) += pcie-amd-mdb.o
> > > obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> > > +obj-$(CONFIG_PCIE_EIC7700) += pcie-eic7700.o
> > > obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> > > obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> > > obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> > > diff --git a/drivers/pci/controller/dwc/pcie-eic7700.c b/drivers/pci/controller/dwc/pcie-eic7700.c
> > > new file mode 100644
> > > index 000000000000..dab8e3b98810
> > > --- /dev/null
> > > +++ b/drivers/pci/controller/dwc/pcie-eic7700.c
> > > @@ -0,0 +1,410 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * ESWIN EIC7700 PCIe root complex driver
> > > + *
> > > + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.
> > > + *
> > > + * Authors: Yu Ning <ningyu@eswincomputing.com>
> > > + * Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > + * Yanghui Ou <ouyanghui@eswincomputing.com>
> > > + */
> > > +
> > > +#include <linux/interrupt.h>
> > > +#include <linux/iopoll.h>
> > > +#include <linux/module.h>
> > > +#include <linux/of.h>
> > > +#include <linux/pci.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/pm_runtime.h>
> > > +#include <linux/resource.h>
> > > +#include <linux/reset.h>
> > > +#include <linux/types.h>
> > > +
> > > +#include "pcie-designware.h"
> > > +
> > > +/* ELBI registers */
> > > +#define PCIEELBI_CTRL0_OFFSET 0x0
> > > +#define PCIEELBI_STATUS0_OFFSET 0x100
> > > +
> > > +/* LTSSM register fields */
> > > +#define PCIEELBI_APP_LTSSM_ENABLE BIT(5)
> > > +
> > > +/* APP_HOLD_PHY_RST register fields */
> > > +#define PCIEELBI_APP_HOLD_PHY_RST BIT(6)
> > > +
> > > +/* PM_SEL_AUX_CLK register fields */
> > > +#define PCIEELBI_PM_SEL_AUX_CLK BIT(16)
> > > +
> > > +/* DEV_TYPE register fields */
> > > +#define PCIEELBI_CTRL0_DEV_TYPE GENMASK(3, 0)
> > > +
> > > +/* Vendor and device ID value */
> > > +#define PCI_VENDOR_ID_ESWIN 0x1fe1
> > > +#define PCI_DEVICE_ID_ESWIN_EIC7700 0x2030
> > > +
> > > +#define EIC7700_NUM_RSTS ARRAY_SIZE(eic7700_pcie_rsts)
> > > +
> > > +static const char * const eic7700_pcie_rsts[] = {
> > > + "pwr",
> > > + "dbi",
> > > +};
> > > +
> > > +struct eic7700_pcie_port {
> > > + struct list_head list;
> > > + struct reset_control *perst;
> > > + int num_lanes;
> > > +};
> > > +
> > > +struct eic7700_pcie {
> > > + struct dw_pcie pci;
> > > + struct clk_bulk_data *clks;
> > > + struct reset_control_bulk_data resets[EIC7700_NUM_RSTS];
> > > + struct list_head ports;
> > > + int num_clks;
> > > +};
> > > +
> > > +#define to_eic7700_pcie(x) dev_get_drvdata((x)->dev)
> > > +
> > > +static int eic7700_pcie_start_link(struct dw_pcie *pci)
> > > +{
> > > + u32 val;
> > > +
> > > + /* Enable LTSSM */
> > > + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > > + val |= PCIEELBI_APP_LTSSM_ENABLE;
> > > + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static bool eic7700_pcie_link_up(struct dw_pcie *pci)
> > > +{
> > > + u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> > > + u16 val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
> > > +
> > > + return val & PCI_EXP_LNKSTA_DLLLA;
> > > +}
> > > +
> > > +static int eic7700_pcie_perst_reset(struct eic7700_pcie_port *port,
> > > + struct eic7700_pcie *pcie)
> > > +{
> > > + int ret;
> > > +
> > > + ret = reset_control_assert(port->perst);
> > > + if (ret) {
> > > + dev_err(pcie->pci.dev, "Failed to assert PERST#\n");
> > > + return ret;
> > > + }
> > > +
> > > + /* Ensure that PERST# has been asserted for at least 100 ms */
> > > + msleep(PCIE_T_PVPERL_MS);
> > > +
> > > + ret = reset_control_deassert(port->perst);
> > > + if (ret) {
> > > + dev_err(pcie->pci.dev, "Failed to deassert PERST#\n");
> > > + return ret;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void eic7700_pcie_assert(struct eic7700_pcie *pcie)
> > > +{
> > > + struct eic7700_pcie_port *port;
> > > +
> > > + list_for_each_entry(port, &pcie->ports, list)
> > > + reset_control_assert(port->perst);
> > > + reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
> > > +}
> > > +
> > > +static int eic7700_pcie_parse_port(struct eic7700_pcie *pcie,
> > > + struct device_node *node)
> > > +{
> > > + struct device *dev = pcie->pci.dev;
> > > + struct eic7700_pcie_port *port;
> > > +
> > > + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> > > + if (!port)
> > > + return -ENOMEM;
> > > +
> > > + port->perst = of_reset_control_get_exclusive(node, "perst");
> > > + if (IS_ERR(port->perst)) {
> > > + dev_err(dev, "Failed to get PERST# reset\n");
> > > + return PTR_ERR(port->perst);
> > > + }
> > > +
> > > + /*
> > > + * TODO: Since the Root Port node is separated out by pcie devicetree,
> > > + * the DWC core initialization code can't parse the num-lanes attribute
> > > + * in the Root Port. Before entering the DWC core initialization code,
> > > + * the platform driver code parses the Root Port node. The EIC7700 only
> > > + * supports one Root Port node, and the num-lanes attribute is suitable
> > > + * for the case of one Root Port.
> > > + */
> > > + if (!of_property_read_u32(node, "num-lanes", &port->num_lanes))
> > > + pcie->pci.num_lanes = port->num_lanes;
> > > +
> > > + INIT_LIST_HEAD(&port->list);
> > > + list_add_tail(&port->list, &pcie->ports);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int eic7700_pcie_parse_ports(struct eic7700_pcie *pcie)
> > > +{
> > > + struct eic7700_pcie_port *port, *tmp;
> > > + struct device *dev = pcie->pci.dev;
> > > + int ret;
> > > +
> > > + for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> > > + ret = eic7700_pcie_parse_port(pcie, of_port);
> > > + if (ret)
> > > + goto err_port;
> > > + }
> > > +
> > > + return 0;
> > > +
> > > +err_port:
> > > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > > + reset_control_put(port->perst);
> > > + list_del(&port->list);
> > > + }
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int eic7700_pcie_host_init(struct dw_pcie_rp *pp)
> > > +{
> > > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > + struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
> > > + struct eic7700_pcie_port *port;
> > > + u32 val;
> > > + int ret;
> > > +
> > > + ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + /*
> > > + * The PWR and DBI reset signals are respectively used to reset the
> > > + * PCIe controller and the DBI register.
> > > + *
> > > + * The PERST# signal is a reset signal that simultaneously controls the
> > > + * PCIe controller, PHY, and Endpoint. Before configuring the PHY, the
> > > + * PERST# signal must first be deasserted.
> > > + *
> > > + * The external reference clock is supplied simultaneously to the PHY
> > > + * and EP. When the PHY is configurable, the entire chip already has
> > > + * stable power and reference clock. The PHY will be ready within 20ms
> > > + * after writing app_hold_phy_rst register bit of ELBI register space.
> > > + */
> > > + ret = reset_control_bulk_deassert(EIC7700_NUM_RSTS, pcie->resets);
> > > + if (ret) {
> > > + dev_err(pcie->pci.dev, "Failed to deassert resets\n");
> > > + goto err_deassert;
> > > + }
> > > +
> > > + /* Configure Root Port type */
> > > + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > > + val &= ~PCIEELBI_CTRL0_DEV_TYPE;
> > > + val |= FIELD_PREP(PCIEELBI_CTRL0_DEV_TYPE, PCI_EXP_TYPE_ROOT_PORT);
> > > + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > > +
> > > + list_for_each_entry(port, &pcie->ports, list) {
> > > + ret = eic7700_pcie_perst_reset(port, pcie);
> > > + if (ret)
> > > + goto err_perst;
> > > + }
> > > +
> > > + /* Configure app_hold_phy_rst */
> > > + val = readl_relaxed(pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > > + val &= ~PCIEELBI_APP_HOLD_PHY_RST;
> > > + writel_relaxed(val, pci->elbi_base + PCIEELBI_CTRL0_OFFSET);
> > > +
> > > + /* The maximum waiting time for the clock switch lock is 20ms */
> > > + ret = readl_poll_timeout(pci->elbi_base + PCIEELBI_STATUS0_OFFSET, val,
> > > + !(val & PCIEELBI_PM_SEL_AUX_CLK), 1000,
> > > + 20000);
> > > + if (ret) {
> > > + dev_err(pci->dev, "Timeout waiting for PM_SEL_AUX_CLK ready\n");
> > > + goto err_phy_init;
> > > + }
> > > +
> > > + /*
> > > + * Configure ESWIN VID:DID for Root Port as the default values are
> > > + * invalid.
> > > + */
> > > + dw_pcie_dbi_ro_wr_en(pci);
> > > + dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, PCI_VENDOR_ID_ESWIN);
> > > + dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, PCI_DEVICE_ID_ESWIN_EIC7700);
> > > + dw_pcie_dbi_ro_wr_dis(pci);
> > > +
> > > + return 0;
> > > +
> > > +err_phy_init:
> > > + list_for_each_entry(port, &pcie->ports, list)
> > > + reset_control_assert(port->perst);
> > > +err_perst:
> > > + reset_control_bulk_assert(EIC7700_NUM_RSTS, pcie->resets);
> > > +err_deassert:
> > > + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static void eic7700_pcie_host_deinit(struct dw_pcie_rp *pp)
> > > +{
> > > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > + struct eic7700_pcie *pcie = to_eic7700_pcie(pci);
> > > +
> > > + eic7700_pcie_assert(pcie);
> > > + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
> > > +}
> > > +
> > > +static const struct dw_pcie_host_ops eic7700_pcie_host_ops = {
> > > + .init = eic7700_pcie_host_init,
> > > + .deinit = eic7700_pcie_host_deinit,
> > > +};
> > > +
> > > +static const struct dw_pcie_ops dw_pcie_ops = {
> > > + .start_link = eic7700_pcie_start_link,
> > > + .link_up = eic7700_pcie_link_up,
> > > +};
> > > +
> > > +static int eic7700_pcie_probe(struct platform_device *pdev)
> > > +{
> > > + struct eic7700_pcie_port *port, *tmp;
> > > + struct device *dev = &pdev->dev;
> > > + struct eic7700_pcie *pcie;
> > > + struct dw_pcie *pci;
> > > + int ret, i;
> > > +
> > > + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > > + if (!pcie)
> > > + return -ENOMEM;
> > > +
> > > + INIT_LIST_HEAD(&pcie->ports);
> > > +
> > > + pci = &pcie->pci;
> > > + pci->dev = dev;
> > > + pci->ops = &dw_pcie_ops;
> > > + pci->pp.ops = &eic7700_pcie_host_ops;
> > > +
> > > + pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
> > > + if (pcie->num_clks < 0)
> > > + return dev_err_probe(dev, pcie->num_clks,
> > > + "Failed to get pcie clocks\n");
> > > +
> > > + for (i = 0; i < EIC7700_NUM_RSTS; i++)
> > > + pcie->resets[i].id = eic7700_pcie_rsts[i];
> > > +
> > > + ret = devm_reset_control_bulk_get_exclusive(dev, EIC7700_NUM_RSTS,
> > > + pcie->resets);
> > > + if (ret)
> > > + return dev_err_probe(dev, ret, "Failed to get resets\n");
> > > +
> > > + ret = eic7700_pcie_parse_ports(pcie);
> > > + if (ret)
> > > + return dev_err_probe(dev, ret, "Failed to parse Root Port\n");
> > > +
> > > + platform_set_drvdata(pdev, pcie);
> > > +
> > > + pm_runtime_no_callbacks(dev);
> > > + devm_pm_runtime_enable(dev);
> > > + ret = pm_runtime_get_sync(dev);
> > > + if (ret < 0)
> > > + goto err_pm_runtime_put;
> > > +
> > > + ret = dw_pcie_host_init(&pci->pp);
> > > + if (ret) {
> > > + dev_err(dev, "Failed to init host\n");
> > > + goto err_pm_runtime_put;
> > > + }
> > > +
> > > + return 0;
> > > +
> > > +err_pm_runtime_put:
> > > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > > + reset_control_put(port->perst);
> > > + list_del(&port->list);
> > > + }
> > > + pm_runtime_put(dev);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > > +{
> > > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > > +
> > > + /*
> > > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > > + * link states. It cannot enter the L2/L3 Ready state through the
> > > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > > + * the dw_pcie_suspend_noirq API is not used.
> > > + */
> >
> > With 7.0, you can provide a dummy pme_turn_off() API and set
> > 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
> >
>
> Hi Mani,
>
> Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
> dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
> function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
> execute, the clk/reset resources in the pci->pp.ops->init function cannot
> be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
Will this help?
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 6ae6189e9b8a..38ad79bbeab1 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1300,15 +1300,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
ret = dw_pcie_start_link(pci);
if (ret)
- return ret;
+ goto err_deinit;
ret = dw_pcie_wait_for_link(pci);
if (ret)
- return ret;
+ goto err_stop_link;
if (pci->pp.ops->post_init)
pci->pp.ops->post_init(&pci->pp);
+ return 0;
+
+err_stop_link:
+ dw_pcie_stop_link(pci);
+
+err_deinit:
+ if (pci->pp.ops->deinit)
+ pci->pp.ops->deinit(&pci->pp);
+
return ret;
}
EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-25 13:37 ` Manivannan Sadhasivam
@ 2026-02-26 8:09 ` zhangsenchuan
2026-02-26 8:36 ` Manivannan Sadhasivam
0 siblings, 1 reply; 17+ messages in thread
From: zhangsenchuan @ 2026-02-26 8:09 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
> > > Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> > >
> > > On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > > > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > >
> > > > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > > > +{
> > > > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > > > +
> > > > + /*
> > > > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > > > + * link states. It cannot enter the L2/L3 Ready state through the
> > > > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > > > + * the dw_pcie_suspend_noirq API is not used.
> > > > + */
> > >
> > > With 7.0, you can provide a dummy pme_turn_off() API and set
> > > 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > >
> >
> > Hi Mani,
> >
> > Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
> > dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
> > function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
> > execute, the clk/reset resources in the pci->pp.ops->init function cannot
> > be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
>
> Will this help?
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 6ae6189e9b8a..38ad79bbeab1 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1300,15 +1300,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
>
> ret = dw_pcie_start_link(pci);
> if (ret)
> - return ret;
> + goto err_deinit;
>
> ret = dw_pcie_wait_for_link(pci);
> if (ret)
> - return ret;
> + goto err_stop_link;
>
> if (pci->pp.ops->post_init)
> pci->pp.ops->post_init(&pci->pp);
>
> + return 0;
> +
> +err_stop_link:
> + dw_pcie_stop_link(pci);
> +
> +err_deinit:
> + if (pci->pp.ops->deinit)
> + pci->pp.ops->deinit(&pci->pp);
> +
> return ret;
> }
> EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
>
Yes, this can release the resources after init, after optimizing the
resume function, i can reuse the dw_pcie_{suspend/resume}_noirq APIs.
I noticed that the dw_pcie_wait_for_link function has been optimized. Is
it necessary to release the resources only when it return -ETIMEOUT?
Perhaps it needs to be slightly improved:
ret = dw_pcie_wait_for_link(pci);
if (ret == -ETIMEOUT)
goto err_stop_link;
What about your suggestion?
Kind regards,
Senchuan
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-26 8:09 ` zhangsenchuan
@ 2026-02-26 8:36 ` Manivannan Sadhasivam
2026-02-26 9:37 ` zhangsenchuan
0 siblings, 1 reply; 17+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-26 8:36 UTC (permalink / raw)
To: zhangsenchuan
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
On Thu, Feb 26, 2026 at 04:09:44PM +0800, zhangsenchuan wrote:
>
> > > > Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> > > >
> > > > On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > > > > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > > >
> > > > > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > > > > +{
> > > > > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > > > > +
> > > > > + /*
> > > > > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > > > > + * link states. It cannot enter the L2/L3 Ready state through the
> > > > > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > > > > + * the dw_pcie_suspend_noirq API is not used.
> > > > > + */
> > > >
> > > > With 7.0, you can provide a dummy pme_turn_off() API and set
> > > > 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > > >
> > >
> > > Hi Mani,
> > >
> > > Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
> > > dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
> > > function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
> > > execute, the clk/reset resources in the pci->pp.ops->init function cannot
> > > be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
> >
> > Will this help?
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 6ae6189e9b8a..38ad79bbeab1 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -1300,15 +1300,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> >
> > ret = dw_pcie_start_link(pci);
> > if (ret)
> > - return ret;
> > + goto err_deinit;
> >
> > ret = dw_pcie_wait_for_link(pci);
> > if (ret)
> > - return ret;
> > + goto err_stop_link;
> >
> > if (pci->pp.ops->post_init)
> > pci->pp.ops->post_init(&pci->pp);
> >
> > + return 0;
> > +
> > +err_stop_link:
> > + dw_pcie_stop_link(pci);
> > +
> > +err_deinit:
> > + if (pci->pp.ops->deinit)
> > + pci->pp.ops->deinit(&pci->pp);
> > +
> > return ret;
> > }
> > EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
> >
>
> Yes, this can release the resources after init, after optimizing the
> resume function, i can reuse the dw_pcie_{suspend/resume}_noirq APIs.
>
> I noticed that the dw_pcie_wait_for_link function has been optimized. Is
> it necessary to release the resources only when it return -ETIMEOUT?
> Perhaps it needs to be slightly improved:
>
> ret = dw_pcie_wait_for_link(pci);
> if (ret == -ETIMEOUT)
> goto err_stop_link;
>
> What about your suggestion?
>
Absolutely! I forgot my own rework ;) I'll cook a patch for the above. Then if
you base your controller driver patch on top of it, we can merge both in a
single tree (if Bjorn agrees).
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-26 8:36 ` Manivannan Sadhasivam
@ 2026-02-26 9:37 ` zhangsenchuan
2026-02-26 13:46 ` Manivannan Sadhasivam
0 siblings, 1 reply; 17+ messages in thread
From: zhangsenchuan @ 2026-02-26 9:37 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
> > > > > Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> > > > >
> > > > > On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > > > > > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > > > >
> > > > > > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > > > > > +{
> > > > > > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > > > > > +
> > > > > > + /*
> > > > > > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > > > > > + * link states. It cannot enter the L2/L3 Ready state through the
> > > > > > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > > > > > + * the dw_pcie_suspend_noirq API is not used.
> > > > > > + */
> > > > >
> > > > > With 7.0, you can provide a dummy pme_turn_off() API and set
> > > > > 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > > > >
> > > >
> > > > Hi Mani,
> > > >
> > > > Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
> > > > dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
> > > > function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
> > > > execute, the clk/reset resources in the pci->pp.ops->init function cannot
> > > > be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
> > >
> > > Will this help?
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index 6ae6189e9b8a..38ad79bbeab1 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -1300,15 +1300,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> > >
> > > ret = dw_pcie_start_link(pci);
> > > if (ret)
> > > - return ret;
> > > + goto err_deinit;
> > >
> > > ret = dw_pcie_wait_for_link(pci);
> > > if (ret)
> > > - return ret;
> > > + goto err_stop_link;
> > >
> > > if (pci->pp.ops->post_init)
> > > pci->pp.ops->post_init(&pci->pp);
> > >
> > > + return 0;
> > > +
> > > +err_stop_link:
> > > + dw_pcie_stop_link(pci);
> > > +
> > > +err_deinit:
> > > + if (pci->pp.ops->deinit)
> > > + pci->pp.ops->deinit(&pci->pp);
> > > +
> > > return ret;
> > > }
> > > EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
> > >
> >
> > Yes, this can release the resources after init, after optimizing the
> > resume function, i can reuse the dw_pcie_{suspend/resume}_noirq APIs.
> >
> > I noticed that the dw_pcie_wait_for_link function has been optimized. Is
> > it necessary to release the resources only when it return -ETIMEOUT?
> > Perhaps it needs to be slightly improved:
> >
> > ret = dw_pcie_wait_for_link(pci);
> > if (ret == -ETIMEOUT)
> > goto err_stop_link;
> >
> > What about your suggestion?
> >
>
> Absolutely! I forgot my own rework ;) I'll cook a patch for the above. Then if
> you base your controller driver patch on top of it, we can merge both in a
> single tree (if Bjorn agrees).
>
Okey,thanks!
I'm a little unsure. Do I need to send the v11 patch here first? Or should I wait
until you release the new fix patch, and then send the v11 patch?
Kind regards,
Senchuan
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-26 9:37 ` zhangsenchuan
@ 2026-02-26 13:46 ` Manivannan Sadhasivam
2026-02-27 11:22 ` zhangsenchuan
0 siblings, 1 reply; 17+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-26 13:46 UTC (permalink / raw)
To: zhangsenchuan
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
On Thu, Feb 26, 2026 at 05:37:48PM +0800, zhangsenchuan wrote:
> > > > > > Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> > > > > >
> > > > > > On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > > > > > > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > > > > >
> > > > > > > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > > > > > > +{
> > > > > > > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > > > > > > +
> > > > > > > + /*
> > > > > > > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > > > > > > + * link states. It cannot enter the L2/L3 Ready state through the
> > > > > > > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > > > > > > + * the dw_pcie_suspend_noirq API is not used.
> > > > > > > + */
> > > > > >
> > > > > > With 7.0, you can provide a dummy pme_turn_off() API and set
> > > > > > 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > > > > >
> > > > >
> > > > > Hi Mani,
> > > > >
> > > > > Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
> > > > > dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
> > > > > function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
> > > > > execute, the clk/reset resources in the pci->pp.ops->init function cannot
> > > > > be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
> > > >
> > > > Will this help?
> > > >
> > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > index 6ae6189e9b8a..38ad79bbeab1 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > @@ -1300,15 +1300,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> > > >
> > > > ret = dw_pcie_start_link(pci);
> > > > if (ret)
> > > > - return ret;
> > > > + goto err_deinit;
> > > >
> > > > ret = dw_pcie_wait_for_link(pci);
> > > > if (ret)
> > > > - return ret;
> > > > + goto err_stop_link;
> > > >
> > > > if (pci->pp.ops->post_init)
> > > > pci->pp.ops->post_init(&pci->pp);
> > > >
> > > > + return 0;
> > > > +
> > > > +err_stop_link:
> > > > + dw_pcie_stop_link(pci);
> > > > +
> > > > +err_deinit:
> > > > + if (pci->pp.ops->deinit)
> > > > + pci->pp.ops->deinit(&pci->pp);
> > > > +
> > > > return ret;
> > > > }
> > > > EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
> > > >
> > >
> > > Yes, this can release the resources after init, after optimizing the
> > > resume function, i can reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > >
> > > I noticed that the dw_pcie_wait_for_link function has been optimized. Is
> > > it necessary to release the resources only when it return -ETIMEOUT?
> > > Perhaps it needs to be slightly improved:
> > >
> > > ret = dw_pcie_wait_for_link(pci);
> > > if (ret == -ETIMEOUT)
> > > goto err_stop_link;
> > >
> > > What about your suggestion?
> > >
> >
> > Absolutely! I forgot my own rework ;) I'll cook a patch for the above. Then if
> > you base your controller driver patch on top of it, we can merge both in a
> > single tree (if Bjorn agrees).
> >
>
> Okey,thanks!
>
> I'm a little unsure. Do I need to send the v11 patch here first? Or should I wait
> until you release the new fix patch, and then send the v11 patch?
>
I've just sent the fix:
https://lore.kernel.org/linux-pci/20260226133951.296743-1-mani@kernel.org
You can post your series on top of it. There should be no build dependency, but
there is a functional dependency. So we may put this patch and your series in a
single branch.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
2026-02-26 13:46 ` Manivannan Sadhasivam
@ 2026-02-27 11:22 ` zhangsenchuan
0 siblings, 0 replies; 17+ messages in thread
From: zhangsenchuan @ 2026-02-27 11:22 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
> > > > > > > Subject: Re: [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> > > > > > >
> > > > > > > On Thu, Jan 29, 2026 at 05:29:00PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > > > > > > > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> > > > > > > >
> > > > > > > > +static int eic7700_pcie_suspend_noirq(struct device *dev)
> > > > > > > > +{
> > > > > > > > + struct eic7700_pcie *pcie = dev_get_drvdata(dev);
> > > > > > > > +
> > > > > > > > + /*
> > > > > > > > + * The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> > > > > > > > + * link states. It cannot enter the L2/L3 Ready state through the
> > > > > > > > + * PME_Turn_Off/PME_To_Ack handshake protocol. To avoid this problem,
> > > > > > > > + * the dw_pcie_suspend_noirq API is not used.
> > > > > > > > + */
> > > > > > >
> > > > > > > With 7.0, you can provide a dummy pme_turn_off() API and set
> > > > > > > 'pci->pp.skip_l23_ready' to reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > > > > > >
> > > > > >
> > > > > > Hi Mani,
> > > > > >
> > > > > > Setting pci->pp.skip_l23_ready does indeed allow us to reuse the
> > > > > > dw_pcie_suspend_noirq function. However, for the dw_pcie_resume_noirq
> > > > > > function, if the dw_pcie_start_link and dw_pcie_wait_for_link APIs fail to
> > > > > > execute, the clk/reset resources in the pci->pp.ops->init function cannot
> > > > > > be released. Perhaps the dw_pcie_resume_noirq function needs to be optimized.
> > > > >
> > > > > Will this help?
> > > > >
> > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > index 6ae6189e9b8a..38ad79bbeab1 100644
> > > > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > @@ -1300,15 +1300,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> > > > >
> > > > > ret = dw_pcie_start_link(pci);
> > > > > if (ret)
> > > > > - return ret;
> > > > > + goto err_deinit;
> > > > >
> > > > > ret = dw_pcie_wait_for_link(pci);
> > > > > if (ret)
> > > > > - return ret;
> > > > > + goto err_stop_link;
> > > > >
> > > > > if (pci->pp.ops->post_init)
> > > > > pci->pp.ops->post_init(&pci->pp);
> > > > >
> > > > > + return 0;
> > > > > +
> > > > > +err_stop_link:
> > > > > + dw_pcie_stop_link(pci);
> > > > > +
> > > > > +err_deinit:
> > > > > + if (pci->pp.ops->deinit)
> > > > > + pci->pp.ops->deinit(&pci->pp);
> > > > > +
> > > > > return ret;
> > > > > }
> > > > > EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
> > > > >
> > > >
> > > > Yes, this can release the resources after init, after optimizing the
> > > > resume function, i can reuse the dw_pcie_{suspend/resume}_noirq APIs.
> > > >
> > > > I noticed that the dw_pcie_wait_for_link function has been optimized. Is
> > > > it necessary to release the resources only when it return -ETIMEOUT?
> > > > Perhaps it needs to be slightly improved:
> > > >
> > > > ret = dw_pcie_wait_for_link(pci);
> > > > if (ret == -ETIMEOUT)
> > > > goto err_stop_link;
> > > >
> > > > What about your suggestion?
> > > >
> > >
> > > Absolutely! I forgot my own rework ;) I'll cook a patch for the above. Then if
> > > you base your controller driver patch on top of it, we can merge both in a
> > > single tree (if Bjorn agrees).
> > >
> >
> > Okey,thanks!
> >
> > I'm a little unsure. Do I need to send the v11 patch here first? Or should I wait
> > until you release the new fix patch, and then send the v11 patch?
> >
>
> I've just sent the fix:
> https://lore.kernel.org/linux-pci/20260226133951.296743-1-mani@kernel.org
>
> You can post your series on top of it. There should be no build dependency, but
> there is a functional dependency. So we may put this patch and your series in a
> single branch.
Okey,thanks! I have sent the v11 patch.
Kind regards,
Senchuan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller
2026-01-29 9:26 [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller zhangsenchuan
2026-01-29 9:28 ` [PATCH v10 1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller zhangsenchuan
2026-01-29 9:29 ` [PATCH v10 2/2] PCI: eic7700: Add Eswin PCIe host controller driver zhangsenchuan
@ 2026-02-01 12:24 ` Leon Romanovsky
2026-02-01 12:28 ` Leon Romanovsky
2026-02-01 12:25 ` Leon Romanovsky
2026-02-02 10:59 ` Manivannan Sadhasivam
4 siblings, 1 reply; 17+ messages in thread
From: Leon Romanovsky @ 2026-02-01 12:24 UTC (permalink / raw)
To: bhelgaas, mani, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, zhangsenchuan
Cc: ningyu, linmin, pinkesh.vaghela, ouyanghui
On Thu, 29 Jan 2026 17:26:28 +0800, zhangsenchuan@eswincomputing.com wrote:
> Changes in v10:
> - Updates: eswin,eic7700-pcie.yaml
> - None
>
> - Updates: pcie-eic7700.c
> - Remove devm_clk_bulk_get_all_enabled API, use devm_clk_bulk_get_all
> and clk_bulk_prepare_enable. Add resource release codes and add
> eic7700_pcie_host_deinit API.
> - Update PCI_DEVICE_ID_ESWIN_EIC7700.
> - Add reset_control_put release resources in "goto err_port:".
> - Delete trailing comma after a terminator in eic7700_pcie_of_match.
> - Link to V9: https://lore.kernel.org/all/20251229113021.1859-1-zhangsenchuan@eswincomputing.com/
>
> [...]
Applied, thanks!
[1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller
(no commit info)
[2/2] PCI: eic7700: Add Eswin PCIe host controller driver
(no commit info)
Best regards,
--
Leon Romanovsky <leon@kernel.org>
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller
2026-02-01 12:24 ` [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller Leon Romanovsky
@ 2026-02-01 12:28 ` Leon Romanovsky
2026-02-02 10:57 ` Manivannan Sadhasivam
0 siblings, 1 reply; 17+ messages in thread
From: Leon Romanovsky @ 2026-02-01 12:28 UTC (permalink / raw)
To: bhelgaas, mani, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, zhangsenchuan
Cc: ningyu, linmin, pinkesh.vaghela, ouyanghui
On Sun, Feb 01, 2026 at 07:24:54AM -0500, Leon Romanovsky wrote:
>
> On Thu, 29 Jan 2026 17:26:28 +0800, zhangsenchuan@eswincomputing.com wrote:
> > Changes in v10:
> > - Updates: eswin,eic7700-pcie.yaml
> > - None
> >
> > - Updates: pcie-eic7700.c
> > - Remove devm_clk_bulk_get_all_enabled API, use devm_clk_bulk_get_all
> > and clk_bulk_prepare_enable. Add resource release codes and add
> > eic7700_pcie_host_deinit API.
> > - Update PCI_DEVICE_ID_ESWIN_EIC7700.
> > - Add reset_control_put release resources in "goto err_port:".
> > - Delete trailing comma after a terminator in eic7700_pcie_of_match.
> > - Link to V9: https://lore.kernel.org/all/20251229113021.1859-1-zhangsenchuan@eswincomputing.com/
> >
> > [...]
>
> Applied, thanks!
>
> [1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller
> (no commit info)
> [2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> (no commit info)
Sorry for the noise. The issue was caused by a mistake in my scripts.
Of course, it was never applied.
Thanks
>
> Best regards,
> --
> Leon Romanovsky <leon@kernel.org>
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller
2026-02-01 12:28 ` Leon Romanovsky
@ 2026-02-02 10:57 ` Manivannan Sadhasivam
0 siblings, 0 replies; 17+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-02 10:57 UTC (permalink / raw)
To: Leon Romanovsky
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, zhangsenchuan, ningyu, linmin, pinkesh.vaghela,
ouyanghui
On Sun, Feb 01, 2026 at 02:28:10PM +0200, Leon Romanovsky wrote:
> On Sun, Feb 01, 2026 at 07:24:54AM -0500, Leon Romanovsky wrote:
> >
> > On Thu, 29 Jan 2026 17:26:28 +0800, zhangsenchuan@eswincomputing.com wrote:
> > > Changes in v10:
> > > - Updates: eswin,eic7700-pcie.yaml
> > > - None
> > >
> > > - Updates: pcie-eic7700.c
> > > - Remove devm_clk_bulk_get_all_enabled API, use devm_clk_bulk_get_all
> > > and clk_bulk_prepare_enable. Add resource release codes and add
> > > eic7700_pcie_host_deinit API.
> > > - Update PCI_DEVICE_ID_ESWIN_EIC7700.
> > > - Add reset_control_put release resources in "goto err_port:".
> > > - Delete trailing comma after a terminator in eic7700_pcie_of_match.
> > > - Link to V9: https://lore.kernel.org/all/20251229113021.1859-1-zhangsenchuan@eswincomputing.com/
> > >
> > > [...]
> >
> > Applied, thanks!
> >
> > [1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller
> > (no commit info)
> > [2/2] PCI: eic7700: Add Eswin PCIe host controller driver
> > (no commit info)
>
>
> Sorry for the noise. The issue was caused by a mistake in my scripts.
> Of course, it was never applied.
>
I was about to scream, but glad that this didn't happen.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller
2026-01-29 9:26 [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller zhangsenchuan
` (2 preceding siblings ...)
2026-02-01 12:24 ` [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller Leon Romanovsky
@ 2026-02-01 12:25 ` Leon Romanovsky
2026-02-02 10:59 ` Manivannan Sadhasivam
4 siblings, 0 replies; 17+ messages in thread
From: Leon Romanovsky @ 2026-02-01 12:25 UTC (permalink / raw)
To: bhelgaas, mani, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, zhangsenchuan
Cc: ningyu, linmin, pinkesh.vaghela, ouyanghui
On Thu, 29 Jan 2026 17:26:28 +0800, zhangsenchuan@eswincomputing.com wrote:
> Changes in v10:
> - Updates: eswin,eic7700-pcie.yaml
> - None
>
> - Updates: pcie-eic7700.c
> - Remove devm_clk_bulk_get_all_enabled API, use devm_clk_bulk_get_all
> and clk_bulk_prepare_enable. Add resource release codes and add
> eic7700_pcie_host_deinit API.
> - Update PCI_DEVICE_ID_ESWIN_EIC7700.
> - Add reset_control_put release resources in "goto err_port:".
> - Delete trailing comma after a terminator in eic7700_pcie_of_match.
> - Link to V9: https://lore.kernel.org/all/20251229113021.1859-1-zhangsenchuan@eswincomputing.com/
>
> [...]
Applied, thanks!
[1/2] dt-bindings: PCI: eic7700: Add Eswin PCIe host controller
(no commit info)
[2/2] PCI: eic7700: Add Eswin PCIe host controller driver
(no commit info)
Best regards,
--
Leon Romanovsky <leon@kernel.org>
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller
2026-01-29 9:26 [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller zhangsenchuan
` (3 preceding siblings ...)
2026-02-01 12:25 ` Leon Romanovsky
@ 2026-02-02 10:59 ` Manivannan Sadhasivam
2026-02-06 22:20 ` Bjorn Helgaas
4 siblings, 1 reply; 17+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-02 10:59 UTC (permalink / raw)
To: zhangsenchuan
Cc: bhelgaas, krzk+dt, conor+dt, lpieralisi, kwilczynski, robh,
p.zabel, linux-pci, devicetree, linux-kernel, christian.bruel,
shradha.t, krishna.chundru, thippeswamy.havalige, inochiama,
Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
On Thu, Jan 29, 2026 at 05:26:28PM +0800, zhangsenchuan@eswincomputing.com wrote:
> From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
>
> Changes in v10:
> - Updates: eswin,eic7700-pcie.yaml
> - None
>
This version looks good to me, but it'd be good if Bjorn could give an Ack since
there were previous reviews from him. Also, this week is -rc8, so it is too late
for 7.0. I hope we can merge this series early, once v7.0-rc1 is released.
- Mani
> - Updates: pcie-eic7700.c
> - Remove devm_clk_bulk_get_all_enabled API, use devm_clk_bulk_get_all
> and clk_bulk_prepare_enable. Add resource release codes and add
> eic7700_pcie_host_deinit API.
> - Update PCI_DEVICE_ID_ESWIN_EIC7700.
> - Add reset_control_put release resources in "goto err_port:".
> - Delete trailing comma after a terminator in eic7700_pcie_of_match.
> - Link to V9: https://lore.kernel.org/all/20251229113021.1859-1-zhangsenchuan@eswincomputing.com/
>
> Changes in v9:
> - Updates: eswin,eic7700-pcie.yaml
> - None
>
> - Updates: pcie-eic7700.c
> - Update comment, s/Rort/Port/.
> - Link to V8: https://lore.kernel.org/all/20251215095928.1712-1-zhangsenchuan@eswincomputing.com/
>
> Changes in v8:
> - Updates: eswin,eic7700-pcie.yaml
> - None
>
> - Updates: pcie-eic7700.c
> - Remove dw_pcie_suspend_noirq/dw_pcie_resume_noirq API and add a
> comment, and remove .deinit.
> - Remove no_pme_handshake flag.
> - Add dw_pcie_dbi_ro_wr_en/dw_pcie_dbi_ro_wr_dis API.
> - Add eic7700_pcie_assert helper function.
> - Update NOIRQ_SYSTEM_SLEEP_PM_OPS to DEFINE_NOIRQ_DEV_PM_OPS.
> - Link to V7: https://lore.kernel.org/all/20251202090225.1602-1-zhangsenchuan@eswincomputing.com/
>
> Changes in v7:
> - Updates: eswin,eic7700-pcie.yaml
> - None
>
> - Updates: pcie-eic7700.c
> - Update "config PCIE_EIC7700" bool to tristate.
> - Remove fix MSI-X code, depend on new commit [1].
> - Add set no_pme_handshake flag.
> - Update -EINVAL to -ENODATA and add PM runtime function.
> - Add ".probe_type = PROBE_PREFER_ASYNCHRONOUS,".
> - Update eic7700_pcie_perst_deassert function name to
> eic7700_pcie_perst_reset.
> - Update readw to dw_pcie_readw_dbi function.
> - Add comments above reset_control_bulk_deassert function.
>
> - Updates: pcie-designware.h pcie-designware-host.c
> - The ESWIN EIC7700 SoC lacks hardware support for the L2/L3 low-power
> link states. It cannot enter the L2/L3 ready state through the
> PME_Turn_Off/PME_To_Ack handshake protocol. To address this, add a
> no_pme_handshake flag skip PME_Turn_Off broadcast and link state check
> code, other driver can reuse this flag if meet the similar situation.
> - Link to V6: https://lore.kernel.org/linux-pci/20251120101018.1477-1-zhangsenchuan@eswincomputing.com/
> - Link to: https://lore.kernel.org/linux-pci/20251109-remove_cap-v1-3-2208f46f4dc2@oss.qualcomm.com/ [1]
>
> Changes in v6:
> - Updates: eswin,eic7700-pcie.yaml
> - Add Reviewed-by: Rob Herring (Arm) <robh@kernel.org>.
>
> - Updates: pcie-eic7700.c
> - Remove pci_root_ports_have_device function judgment during suspend.
> - Remove eic7700_pcie_pme_turn_off and eic7700_pcie_get_ltssm function.
> - Add set no_suspport_L2 flag.
>
> - Updates: pcie-designware.h pcie-designware-host.c
> - The ESWIN EIC7700 soc does not support enter L2 link state. Therefore
> add no_suspport_L2 flag skip PME_Turn_Off broadcast and link state
> check code, other driver can reuse this flag if meet the similar
> situation.
> - Link to V5: https://lore.kernel.org/all/20251110090716.1392-1-zhangsenchuan@eswincomputing.com/
> - Link to: https://lore.kernel.org/all/e7plmtwtkkd4ymrt2hkztcqdx4ugfjk64oksjyf6lpi2oui53d@vhuo5occyref/
>
> Changes in v5:
> - Updates: eswin,eic7700-pcie.yaml
> - Modify reg-names: update mgmt to elbi.
> - Modify clock-names: update pclk to phy_reg.
> - Modify reset-names: update powerup to pwr.
> - Remove powerup modify in "snps,dw-pcie-common.yaml" file.
>
> - Updates: pcie-eic7700.c
> - Update the driver submission comment, mention EIC7700 in the
> "config PCIE_EIC7700" and in the driver title.
> - Update some comments, for examples: "s/PME_TURN_OFF/PME_Turn_Off/",
> "s/INTX/INTx/", "s/PERST/PERST#/", "s/perst/PERST#/", "s/id/ID/".
> - Update "struct *_pcie" name and function name, add the eic7700 prefix.
> - Use PCIEELBI_CTRL0_DEV_TYPE macro and update comment, use FIELD_PREP.
> - Add eic7700_pcie_data pointer in struct eic7700_pcie.
> - Update .deinit callback function name and removed the dw_pcie_link_up
> judgment, add pci_root_ports_have_device function judgment.
> - Remove devm_platform_ioremap_resource_byname function get mgmt, use
> platform_get_resource_byname function get elbi in "pcie-designware.c".
> - Update of_reset_control_get to of_reset_control_get_exclusive, use
> devm_reset_control_bulk_get_exclusive function get resets, update use
> reset_control_bulk_assert/reset_control_bulk_deassert function.
> - Link to V4: https://lore.kernel.org/all/20251030082900.1304-1-zhangsenchuan@eswincomputing.com/
> - Link to https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/tree/?h=controller/dwc
>
> Changes in v4:
> - Updates: eswin,eic7700-pcie.yaml
> - Use snps,dw-pcie.yaml instead pci-host-bridge.yaml.
>
> - Updates: snps,dw-pcie-common.yaml
> - Add powerup reset property, our powerup property is somewhat different
> from the general attributes defined by Synopsys DWC binding.
>
> - Updates: pcie-eic7700.c
> - Update the driver submission comment.
> - Alphabetize so the menuconfig entries remain sorted by vendor.
> - Update use PCI_CAP_LIST_NEXT_MASK macro.
> - Use readl_poll_timeout function.
> - Update eswin_pcie_suspend/eswin_pcie_resume name to
> eswin_pcie_suspend_noirq/eswin_pcie_resume_noirq.
> - PM use dw_pcie_suspend_noirq and dw_pcie_resume_noirq function and add
> eswin_pcie_get_ltssm, eswin_pcie_pme_turn_off, eswin_pcie_host_exit
> function adapt to PM.
> - Link to V3: https://lore.kernel.org/linux-pci/20250923120946.1218-1-zhangsenchuan@eswincomputing.com/
>
> Changes in v3:
> - Updates: eswin,eic7700-pcie.yaml
> - Based on the last patch yaml file, devicetree separates the root port
> node, changing it significantly. Therefore, "Reviewed-by: Krzysztof
> Kozlowski <krzysztof.kozlowski@linaro.org>" is not added.
> - Clock and reset drivers are under review. In yaml, macro definitions
> used in clock and reset can only be replaced by constant values.
> - Move the num-lanes and perst resets to the PCIe Root Port node, make
> it easier to support multiple Root Ports in future versions of the
> hardware.
> - Update the num-lanes attribute and modify define num-lanes as decimal.
> - Optimize the ranges attribute and clear the relocatable flag (bit 31)
> for any regions.
> - Update comment: inte~inth are actual interrupts and these names align
> with the interrupt names in the hardware IP, inte~inth interrupts
> corresponds to Deassert_INTA~Deassert_INTD.
> - Add Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>.
>
> - Updates: pcie-eic7700.c
> - Update the submission comment and add DWC IP revision, data rate, lane
> information.
> - Optimize the "config PCIE_EIC7700" configuration.
> - Optimize the macro definition, add bitfield definition for the mask,
> and remove redundant comments. optimize comments, make use of 80
> columns for comments.
> - Use the dw_pcie_find_capability function to obtain the offset by
> traversing the function list.
> - Remove the sets MPS code and configure it by PCI core.
> - Alphabetize so the menuconfig entries remain sorted by vendor.
> - Configure ESWIN VID:DID for Root Port as the default values are
> invalid,and remove the redundant lane config.
> - Use reverse Xmas order for all local variables in this driver
> - Hardware doesn't support MSI-X but it advertises MSI-X capability, set
> a flag and clear it conditionally.
> - Resets are all necessary, Update the interface function for resets.
> - Since driver does not depend on any parent to power on any resource,
> the pm runtime related functions are removed.
> - Remove "eswin_pcie_shutdown" function, our comment on the shutdown
> function is incorrect. Moreover, when the host powers reboots,it will
> enter the shutdown function, we are using host reset and do not need
> to assert perst. Therefore, the shutdown function is not necessary.
> - remove "eswin_pcie_remove", because it is not safe to remove it during
> runtime, and this driver has been modified to builtin_platform_driver
> and does not support hot plugging, therefore, the remove function is
> not needed.
> - The Suspend function adds link state judgment, and for controllers
> with active devices, resources cannot be turned off.
> - Add Signed-off-by: Yanghui Ou <ouyanghui@eswincomputing.com>.
> - Link to V2: https://lore.kernel.org/linux-pci/20250829082021.49-1-zhangsenchuan@eswincomputing.com/
>
> Changes in v2:
> - Updates: eswin,eic7700-pcie.yaml
> - Optimize the naming of "clock-names" and "reset-names".
> - Add a reference to "$ref: /schemas/pci/pci-host-bridge.yaml#".
> (The name of the reset attribute in the "snps,dw-pcie-common.yaml"
> file is different from our reset attribute and "snps,dw-pcie.yaml"
> file cannot be directly referenced)
> - Follow DTS coding style to optimize yaml attributes.
> - Remove status = "disabled" from yaml.
>
> - Updates: pcie-eic7700.c
> - Remove unnecessary imported header files.
> - Use dev_err instead of pr_err and remove the WARN_ON function.
> - The eswin_evb_socket_power_on function is removed and not supported.
> - The eswin_pcie_remove function is placed after the probe function.
> - Optimize function alignment.
> - Manage the clock using the devm_clk_bulk_get_all_enabled function.
> - Handle the release of resources after the dw_pcie_host_init function
> call fails.
> - Remove the dev_dbg function and remove __exit_p.
> - Add support for the system pm function.
> - Link to V1: https://lore.kernel.org/all/20250516094057.1300-1-zhangsenchuan@eswincomputing.com/
>
> Senchuan Zhang (2):
> dt-bindings: PCI: eic7700: Add Eswin PCIe host controller
> PCI: eic7700: Add Eswin PCIe host controller driver
>
> .../bindings/pci/eswin,eic7700-pcie.yaml | 167 +++++++
> drivers/pci/controller/dwc/Kconfig | 11 +
> drivers/pci/controller/dwc/Makefile | 1 +
> drivers/pci/controller/dwc/pcie-eic7700.c | 410 ++++++++++++++++++
> 4 files changed, 589 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pci/eswin,eic7700-pcie.yaml
> create mode 100644 drivers/pci/controller/dwc/pcie-eic7700.c
>
> --
> 2.25.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v10 0/2] Add driver support for Eswin EIC7700 SoC PCIe controller
2026-02-02 10:59 ` Manivannan Sadhasivam
@ 2026-02-06 22:20 ` Bjorn Helgaas
0 siblings, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2026-02-06 22:20 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: zhangsenchuan, bhelgaas, krzk+dt, conor+dt, lpieralisi,
kwilczynski, robh, p.zabel, linux-pci, devicetree, linux-kernel,
christian.bruel, shradha.t, krishna.chundru, thippeswamy.havalige,
inochiama, Frank.li, ningyu, linmin, pinkesh.vaghela, ouyanghui
On Mon, Feb 02, 2026 at 04:29:51PM +0530, Manivannan Sadhasivam wrote:
> On Thu, Jan 29, 2026 at 05:26:28PM +0800, zhangsenchuan@eswincomputing.com wrote:
> > From: Senchuan Zhang <zhangsenchuan@eswincomputing.com>
> >
> > Changes in v10:
> > - Updates: eswin,eic7700-pcie.yaml
> > - None
> >
>
> This version looks good to me, but it'd be good if Bjorn could give
> an Ack since there were previous reviews from him. Also, this week
> is -rc8, so it is too late for 7.0. I hope we can merge this series
> early, once v7.0-rc1 is released.
Will do, ping me after v7.0-rc1 to remind me.
^ permalink raw reply [flat|nested] 17+ messages in thread