From nobody Fri Oct 3 14:34:26 2025 Received: from azure-sdnproxy.icoremail.net (azure-sdnproxy.icoremail.net [13.75.44.102]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F1461273811; Fri, 29 Aug 2025 08:23:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.75.44.102 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756455786; cv=none; b=LfuJHf7uVX9zbuB6CHtJ7IdNDAzYIEf7z2JG93D79/vqDNCVrIoT47m8iODiPvxuByJxmbRm3xN9au8EZH3SFwKqHkn+HZ0Bz2Je7EMrX534rD9VbqUZgzZfVP5e5thcB2dndMnbv07CzZgkX/sM2/ayGZVxOv/6kd/mTJkCc6g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756455786; c=relaxed/simple; bh=xGs36GmUR4Ma64Vpf/dnzJmRSRvQApj2NRbJ7tAqxwE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WOhUpNgMZQnI4mMSG9pdUPrnGsn3CPaXaWm8dQ9q8jR+achbyfaMec6HDva7uIfH+awfMw0T2fNVlH+j5TL85D9ACWHYhumuOEmhNgp7n1+JZTDnknw+j1e75t2oviU/IfB3kVN1k9erWrrAYQ+mSIip3S1dG0m1r37z0qtw8w0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com; spf=pass smtp.mailfrom=eswincomputing.com; arc=none smtp.client-ip=13.75.44.102 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from E0004758DT.eswin.cn (unknown [10.12.96.83]) by app1 (Coremail) with SMTP id TAJkCgAXLxBQY7Fo2gvFAA--.9196S2; Fri, 29 Aug 2025 16:22:42 +0800 (CST) From: zhangsenchuan@eswincomputing.com To: bhelgaas@google.com, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, p.zabel@pengutronix.de, johan+linaro@kernel.org, quic_schintav@quicinc.com, shradha.t@samsung.com, cassel@kernel.org, thippeswamy.havalige@amd.com, mayank.rana@oss.qualcomm.com, inochiama@gmail.com Cc: ningyu@eswincomputing.com, linmin@eswincomputing.com, pinkesh.vaghela@einfochips.com, Senchuan Zhang Subject: [PATCH v2 1/2] dt-bindings: PCI: eic7700: Add Eswin eic7700 PCIe host controller Date: Fri, 29 Aug 2025 16:22:37 +0800 Message-ID: <20250829082237.1064-1-zhangsenchuan@eswincomputing.com> X-Mailer: git-send-email 2.49.0.windows.1 In-Reply-To: <20250829082021.49-1-zhangsenchuan@eswincomputing.com> References: <20250829082021.49-1-zhangsenchuan@eswincomputing.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: TAJkCgAXLxBQY7Fo2gvFAA--.9196S2 X-Coremail-Antispam: 1UD129KBjvJXoWxZw1kXr45urWkWryxJFW8WFg_yoWrJryrpF WDGFykCr48Xr13Zw48JF1jkF13JanYkFnYyrn7Wa13trZ5ta4qqr43KF13C343Gr1jq34Y gFnIvr1xtw17A3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBv14x267AKxVW5JVWrJwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gc CE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E 2Ix0cI8IcVAFwI0_Jrv_JF1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJV W8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2 Y2ka0xkIwI1lw4CEc2x0rVAKj4xxMxkF7I0En4kS14v26r4a6rW5MxkIecxEwVCm-wCF04 k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18 MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij64vIr4 1lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1l IxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4 A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0pRmZXOUUUUU= X-CM-SenderInfo: x2kd0wpvhquxxxdqqvxvzl0uprps33xlqjhudrp/ Content-Type: text/plain; charset="utf-8" From: Senchuan Zhang 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 Signed-off-by: Senchuan Zhang Reviewed-by: Krzysztof Kozlowski --- .../bindings/pci/eswin,eic7700-pcie.yaml | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/eswin,eic7700-pci= e.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..65f640902b11 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/eswin,eic7700-pcie.yaml @@ -0,0 +1,142 @@ +# 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 + - Senchuan Zhang + +description: + The PCIe controller on EIC7700 SoC. + +allOf: + - $ref: /schemas/pci/pci-host-bridge.yaml# + +properties: + compatible: + const: eswin,eic7700-pcie + + reg: + maxItems: 3 + + reg-names: + items: + - const: dbi + - const: config + - const: mgmt + + ranges: + maxItems: 3 + + num-lanes: + const: 4 + + '#interrupt-cells': + const: 1 + + interrupts: + maxItems: 9 + + interrupt-names: + items: + - const: msi + - const: inta + - const: intb + - const: intc + - const: intd + - const: inte + - const: intf + - const: intg + - const: inth + + 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: pclk + - const: aux + + resets: + maxItems: 3 + + reset-names: + items: + - const: cfg + - const: powerup + - const: pwren + +required: + - compatible + - reg + - ranges + - num-lanes + - interrupts + - interrupt-names + - interrupt-map-mask + - interrupt-map + - '#interrupt-cells' + - clocks + - clock-names + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + pcie@54000000 { + compatible =3D "eswin,eic7700-pcie"; + reg =3D <0x0 0x54000000 0x0 0x4000000>, + <0x0 0x40000000 0x0 0x800000>, + <0x0 0x50000000 0x0 0x100000>; + reg-names =3D "dbi", "config", "mgmt"; + #address-cells =3D <3>; + #size-cells =3D <2>; + #interrupt-cells =3D <1>; + ranges =3D <0x81000000 0x0 0x40800000 0x0 0x40800000 0x0 0x800= 000>, + <0x82000000 0x0 0x41000000 0x0 0x41000000 0x0 0xf0000= 00>, + <0xc3000000 0x80 0x00000000 0x80 0x00000000 0x2 0x000= 00000>; + bus-range =3D <0x0 0xff>; + clocks =3D <&clock 562>, + <&clock 563>, + <&clock 564>, + <&clock 565>; + clock-names =3D "mstr", "dbi", "pclk", "aux"; + resets =3D <&reset 8 (1 << 0)>, + <&reset 8 (1 << 1)>, + <&reset 8 (1 << 2)>; + reset-names =3D "cfg", "powerup", "pwren"; + interrupts =3D <220>, <179>, <180>, <181>, <182>, <183>, <184>= , <185>, <186>; + interrupt-names =3D "msi", "inta", "intb", "intc", "intd", + "inte", "intf", "intg", "inth"; + interrupt-parent =3D <&plic>; + interrupt-map-mask =3D <0x0 0x0 0x0 0x7>; + interrupt-map =3D <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 =3D "pci"; + num-lanes =3D <0x4>; + }; + }; -- 2.25.1 From nobody Fri Oct 3 14:34:26 2025 Received: from zg8tmja5ljk3lje4mi4ymjia.icoremail.net (zg8tmja5ljk3lje4mi4ymjia.icoremail.net [209.97.182.222]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0A5B427CCE2; Fri, 29 Aug 2025 08:24:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.97.182.222 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756455871; cv=none; b=Q80aOHkr/u5DcT71D067Y3lduZDl9XBfWUASiN2mLMTjoqWzdH8SmaL97kzIfkwREXQbi+2PKNovr+ZuOJdX1A7vSR6IOP7T39wshBaaHBxnds58K4r4PJx0genKZCbx/yYlu2Pa+Dkf0GifruOSFK+zytfQT/AtHmChXxgAJz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756455871; c=relaxed/simple; bh=HuRBr4DeKf4h0ZHdI9uVOEumW9yYIUjlHyYdC1c6pqc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gQrFG7z/zXyzW8bBdUQFpYEF10qtIDfAmyseGtbqywadBc7CF/+yiCkSh1m1yVQvTek01TsVSvBvX5U27zzw+gB7UQgZ9iZ5hr16h7Fk+jVmTgwmHsuvGkiE0KdHuL1E4B3JGI6hK6lvCokPp2R/ZpkLgpITeEx8MRr0gTpZUMQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com; spf=pass smtp.mailfrom=eswincomputing.com; arc=none smtp.client-ip=209.97.182.222 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from E0004758DT.eswin.cn (unknown [10.12.96.83]) by app2 (Coremail) with SMTP id TQJkCgBnBpWoY7FooQfFAA--.41052S2; Fri, 29 Aug 2025 16:24:10 +0800 (CST) From: zhangsenchuan@eswincomputing.com To: bhelgaas@google.com, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, p.zabel@pengutronix.de, johan+linaro@kernel.org, quic_schintav@quicinc.com, shradha.t@samsung.com, cassel@kernel.org, thippeswamy.havalige@amd.com, mayank.rana@oss.qualcomm.com, inochiama@gmail.com Cc: ningyu@eswincomputing.com, linmin@eswincomputing.com, pinkesh.vaghela@einfochips.com, Senchuan Zhang Subject: [PATCH v2 2/2] PCI: eic7700: Add Eswin eic7700 PCIe host controller driver Date: Fri, 29 Aug 2025 16:24:05 +0800 Message-ID: <20250829082405.1203-1-zhangsenchuan@eswincomputing.com> X-Mailer: git-send-email 2.49.0.windows.1 In-Reply-To: <20250829082021.49-1-zhangsenchuan@eswincomputing.com> References: <20250829082021.49-1-zhangsenchuan@eswincomputing.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: TQJkCgBnBpWoY7FooQfFAA--.41052S2 X-Coremail-Antispam: 1UD129KBjvJXoW3Kw4kCrWrtF15KryxurWkCrg_yoWktFyfpa 1UJayYyF48JrW3Wa13AF95uF4avFnxua4UJ39agan7uay3J34kWr1ftry3tF97Cr4kury3 J3WUta4xCF43JwUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBm14x267AKxVW5JVWrJwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gc CE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E 2Ix0cI8IcVAFwI0_Jrv_JF1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJV W8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2 Y2ka0xkIwI1lw4CEc2x0rVAKj4xxMxkF7I0En4kS14v26r4a6rW5MxkIecxEwVCm-wCF04 k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18 MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij64vIr4 1lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1U MIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I 8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjTRNSdgDUUUU X-CM-SenderInfo: x2kd0wpvhquxxxdqqvxvzl0uprps33xlqjhudrp/ Content-Type: text/plain; charset="utf-8" From: Senchuan Zhang Add driver for the Eswin EIC7700 PCIe host controller. The controller is based on the DesignWare PCIe core. Signed-off-by: Yu Ning Signed-off-by: Senchuan Zhang --- drivers/pci/controller/dwc/Kconfig | 12 + drivers/pci/controller/dwc/Makefile | 1 + drivers/pci/controller/dwc/pcie-eic7700.c | 350 ++++++++++++++++++++++ 3 files changed, 363 insertions(+) create mode 100644 drivers/pci/controller/dwc/pcie-eic7700.c diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dw= c/Kconfig index ff6b6d9e18ec..1c4063107a8a 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -492,4 +492,16 @@ config PCIE_VISCONTI_HOST Say Y here if you want PCIe controller support on Toshiba Visconti SoC. This driver supports TMPV7708 SoC. +config PCIE_EIC7700 + tristate "ESWIN PCIe host controller" + depends on PCI_MSI + depends on ARCH_ESWIN || COMPILE_TEST + select PCIE_DW_HOST + help + Enables support for the PCIe controller in the Eswin SoC + The PCI controller on Eswin is based on DesignWare hardware + It is a high-speed hardware bus standard used to connect + processors with external devices. Say Y here if you want + PCIe controller support for the ESWIN. + endmenu diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/d= wc/Makefile index 6919d27798d1..0717fe73a2a9 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_PCIE_UNIPHIER) +=3D pcie-uniphier.o obj-$(CONFIG_PCIE_UNIPHIER_EP) +=3D pcie-uniphier-ep.o obj-$(CONFIG_PCIE_VISCONTI_HOST) +=3D pcie-visconti.o obj-$(CONFIG_PCIE_RCAR_GEN4) +=3D pcie-rcar-gen4.o +obj-$(CONFIG_PCIE_EIC7700) +=3D pcie-eic7700.o # The following drivers are for devices that use the generic ACPI # pci_root.c driver but don't support standard ECAM config access. diff --git a/drivers/pci/controller/dwc/pcie-eic7700.c b/drivers/pci/contro= ller/dwc/pcie-eic7700.c new file mode 100644 index 000000000000..bf942154d971 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-eic7700.c @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ESWIN PCIe root complex driver + * + * Copyright 2025, Beijing ESWIN Computing Technology Co., Ltd. + * + * Authors: Yu Ning + * Senchuan Zhang + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-designware.h" + +struct eswin_pcie { + struct dw_pcie pci; + void __iomem *mgmt_base; + struct clk_bulk_data *clks; + struct reset_control *powerup_rst; + struct reset_control *cfg_rst; + struct reset_control *perst; + + int num_clks; +}; + +#define PCIE_PM_SEL_AUX_CLK BIT(16) +#define PCIEMGMT_APP_LTSSM_ENABLE BIT(5) + +#define PCIEMGMT_CTRL0_OFFSET 0x0 +#define PCIEMGMT_STATUS0_OFFSET 0x100 + +#define PCIE_TYPE_DEV_VEND_ID 0x0 +#define PCIE_DSP_PF0_MSI_CAP 0x50 +#define PCIE_NEXT_CAP_PTR 0x70 +#define DEVICE_CONTROL_DEVICE_STATUS 0x78 + +#define PCIE_MSI_MULTIPLE_MSG_32 (0x5 << 17) +#define PCIE_MSI_MULTIPLE_MSG_MASK (0x7 << 17) + +#define PCIEMGMT_LINKUP_STATE_VALIDATE ((0x11 << 2) | 0x3) +#define PCIEMGMT_LINKUP_STATE_MASK 0xff + +static int eswin_pcie_start_link(struct dw_pcie *pci) +{ + struct device *dev =3D pci->dev; + struct eswin_pcie *pcie =3D dev_get_drvdata(dev); + u32 val; + + /* Enable LTSSM */ + val =3D readl_relaxed(pcie->mgmt_base + PCIEMGMT_CTRL0_OFFSET); + val |=3D PCIEMGMT_APP_LTSSM_ENABLE; + writel_relaxed(val, pcie->mgmt_base + PCIEMGMT_CTRL0_OFFSET); + + return 0; +} + +static bool eswin_pcie_link_up(struct dw_pcie *pci) +{ + struct device *dev =3D pci->dev; + struct eswin_pcie *pcie =3D dev_get_drvdata(dev); + u32 val; + + val =3D readl_relaxed(pcie->mgmt_base + PCIEMGMT_STATUS0_OFFSET); + + return ((val & PCIEMGMT_LINKUP_STATE_MASK) =3D=3D + PCIEMGMT_LINKUP_STATE_VALIDATE); +} + +static int eswin_pcie_power_on(struct eswin_pcie *pcie) +{ + int ret =3D 0; + + /* pciet_cfg_rstn */ + ret =3D reset_control_deassert(pcie->cfg_rst); + if (ret) { + dev_err(pcie->pci.dev, "cfg signal is invalid"); + return ret; + } + + /* pciet_powerup_rstn */ + ret =3D reset_control_deassert(pcie->powerup_rst); + if (ret) { + dev_err(pcie->pci.dev, "powerup signal is invalid"); + goto err_deassert_powerup; + } + + return ret; + +err_deassert_powerup: + reset_control_assert(pcie->cfg_rst); + + return ret; +} + +static void eswin_pcie_power_off(struct eswin_pcie *eswin_pcie) +{ + reset_control_assert(eswin_pcie->powerup_rst); + reset_control_assert(eswin_pcie->cfg_rst); +} + +static int eswin_pcie_host_init(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci =3D to_dw_pcie_from_pp(pp); + struct eswin_pcie *pcie =3D dev_get_drvdata(pci->dev); + int ret; + u32 val; + u32 retries; + + /* Fetch clocks */ + pcie->num_clks =3D devm_clk_bulk_get_all_enabled(pci->dev, &pcie->clks); + if (pcie->num_clks < 0) + return dev_err_probe(pci->dev, pcie->num_clks, + "failed to get pcie clocks\n"); + + ret =3D eswin_pcie_power_on(pcie); + if (ret) + return ret; + + /* set device type : rc */ + val =3D readl_relaxed(pcie->mgmt_base + PCIEMGMT_CTRL0_OFFSET); + val &=3D 0xfffffff0; + writel_relaxed(val | 0x4, pcie->mgmt_base + PCIEMGMT_CTRL0_OFFSET); + + ret =3D reset_control_assert(pcie->perst); + if (ret) { + dev_err(pci->dev, "perst assert signal is invalid"); + goto err_perst; + } + msleep(100); + ret =3D reset_control_deassert(pcie->perst); + if (ret) { + dev_err(pci->dev, "perst deassert signal is invalid"); + goto err_perst; + } + + /* app_hold_phy_rst */ + val =3D readl_relaxed(pcie->mgmt_base + PCIEMGMT_CTRL0_OFFSET); + val &=3D ~(0x40); + writel_relaxed(val, pcie->mgmt_base + PCIEMGMT_CTRL0_OFFSET); + + /* + * It takes at least 20ms to wait for the pcie + * status register to be 0. + */ + retries =3D 30; + do { + val =3D readl_relaxed(pcie->mgmt_base + PCIEMGMT_STATUS0_OFFSET); + if (!(val & PCIE_PM_SEL_AUX_CLK)) + break; + usleep_range(1000, 1100); + retries--; + } while (retries); + + if (!retries) { + dev_err(pci->dev, "No clock exist.\n"); + ret =3D -ENODEV; + goto err_clock; + } + + /* config eswin vendor id and eic7700 device id */ + dw_pcie_writel_dbi(pci, PCIE_TYPE_DEV_VEND_ID, 0x20301fe1); + + /* lane fix config, real driver NOT need, default x4 */ + val =3D dw_pcie_readl_dbi(pci, PCIE_PORT_MULTI_LANE_CTRL); + val &=3D 0xffffff80; + val |=3D 0x44; + dw_pcie_writel_dbi(pci, PCIE_PORT_MULTI_LANE_CTRL, val); + + val =3D dw_pcie_readl_dbi(pci, DEVICE_CONTROL_DEVICE_STATUS); + val &=3D ~(0x7 << 5); + val |=3D (0x2 << 5); + dw_pcie_writel_dbi(pci, DEVICE_CONTROL_DEVICE_STATUS, val); + + /* config support 32 msi vectors */ + val =3D dw_pcie_readl_dbi(pci, PCIE_DSP_PF0_MSI_CAP); + val &=3D ~PCIE_MSI_MULTIPLE_MSG_MASK; + val |=3D PCIE_MSI_MULTIPLE_MSG_32; + dw_pcie_writel_dbi(pci, PCIE_DSP_PF0_MSI_CAP, val); + + /* disable msix cap */ + val =3D dw_pcie_readl_dbi(pci, PCIE_NEXT_CAP_PTR); + val &=3D 0xffff00ff; + dw_pcie_writel_dbi(pci, PCIE_NEXT_CAP_PTR, val); + + return 0; + +err_clock: + reset_control_assert(pcie->perst); +err_perst: + eswin_pcie_power_off(pcie); + return ret; +} + +static const struct dw_pcie_host_ops eswin_pcie_host_ops =3D { + .init =3D eswin_pcie_host_init, +}; + +static const struct dw_pcie_ops dw_pcie_ops =3D { + .start_link =3D eswin_pcie_start_link, + .link_up =3D eswin_pcie_link_up, +}; + +static int eswin_pcie_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct dw_pcie *pci; + struct eswin_pcie *pcie; + int ret; + + pcie =3D devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + pci =3D &pcie->pci; + pci->dev =3D dev; + pci->ops =3D &dw_pcie_ops; + pci->pp.ops =3D &eswin_pcie_host_ops; + + /* SiFive specific region: mgmt */ + pcie->mgmt_base =3D devm_platform_ioremap_resource_byname(pdev, "mgmt"); + if (IS_ERR(pcie->mgmt_base)) + return dev_err_probe(dev, PTR_ERR(pcie->mgmt_base), + "failed to map mgmt memory\n"); + + /* Fetch reset */ + pcie->powerup_rst =3D devm_reset_control_get_optional(&pdev->dev, + "powerup"); + if (IS_ERR_OR_NULL(pcie->powerup_rst)) + return dev_err_probe(dev, PTR_ERR(pcie->powerup_rst), + "unable to get powerup reset\n"); + + pcie->cfg_rst =3D devm_reset_control_get_optional(&pdev->dev, "cfg"); + if (IS_ERR_OR_NULL(pcie->cfg_rst)) + return dev_err_probe(dev, PTR_ERR(pcie->cfg_rst), + "unable to get cfg reset\n"); + + pcie->perst =3D devm_reset_control_get_optional(&pdev->dev, "pwren"); + if (IS_ERR_OR_NULL(pcie->perst)) + return dev_err_probe(dev, PTR_ERR(pcie->perst), + "unable to get perst reset\n"); + + platform_set_drvdata(pdev, pcie); + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + ret =3D pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "pm_runtime_get_sync failed: %d\n", ret); + goto err_get_sync; + } + + ret =3D dw_pcie_host_init(&pci->pp); + if (ret) { + dev_err(dev, "failed to initialize host: %d\n", ret); + goto err_host_init; + } + + return ret; + +err_host_init: + pm_runtime_put_sync(dev); +err_get_sync: + pm_runtime_disable(dev); + return ret; +} + +static void eswin_pcie_remove(struct platform_device *pdev) +{ + struct eswin_pcie *pcie =3D platform_get_drvdata(pdev); + + dw_pcie_host_deinit(&pcie->pci.pp); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + reset_control_assert(pcie->perst); + eswin_pcie_power_off(pcie); +} + +static void eswin_pcie_shutdown(struct platform_device *pdev) +{ + struct eswin_pcie *pcie =3D platform_get_drvdata(pdev); + + /* Bring down link, so bootloader gets clean state in case of reboot */ + reset_control_assert(pcie->perst); +} + +static int eswin_pcie_suspend(struct device *dev) +{ + struct eswin_pcie *pcie =3D dev_get_drvdata(dev); + + reset_control_assert(pcie->perst); + eswin_pcie_power_off(pcie); + clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks); + + return 0; +} + +static int eswin_pcie_resume(struct device *dev) +{ + int ret; + struct eswin_pcie *pcie =3D dev_get_drvdata(dev); + + ret =3D eswin_pcie_host_init(&pcie->pci.pp); + if (ret < 0) { + dev_err(dev, "Failed to init host: %d\n", ret); + return ret; + } + + dw_pcie_setup_rc(&pcie->pci.pp); + eswin_pcie_start_link(&pcie->pci); + dw_pcie_wait_for_link(&pcie->pci); + + return 0; +} + +static const struct dev_pm_ops eswin_pcie_pm_ops =3D { + NOIRQ_SYSTEM_SLEEP_PM_OPS(eswin_pcie_suspend, eswin_pcie_resume) +}; + +static const struct of_device_id eswin_pcie_of_match[] =3D { + { .compatible =3D "eswin,eic7700-pcie" }, + {}, +}; + +static struct platform_driver eswin_pcie_driver =3D { + .driver =3D { + .name =3D "eic7700-pcie", + .of_match_table =3D eswin_pcie_of_match, + .suppress_bind_attrs =3D true, + .pm =3D &eswin_pcie_pm_ops, + }, + .probe =3D eswin_pcie_probe, + .remove =3D eswin_pcie_remove, + .shutdown =3D eswin_pcie_shutdown, +}; + +module_platform_driver(eswin_pcie_driver); + +MODULE_DEVICE_TABLE(of, eswin_pcie_of_match); +MODULE_DESCRIPTION("PCIe host controller driver for eic7700 SoCs"); +MODULE_AUTHOR("Yu Ning "); +MODULE_AUTHOR("Senchuan Zhang "); +MODULE_LICENSE("GPL"); -- 2.25.1