From nobody Sun May 24 22:42:19 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF3E2423A6C; Wed, 20 May 2026 18:38:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779302339; cv=none; b=onne1VkS3D+VlhSyaFwDp853ADWK1jW4EnczETvMM/2bo6oCvpHaib10WLRwskDd8WCmb5zELoR44930t3ZtvDYPIzTv9yJNOFIY4SIT3PPMPlW2+M4KJgT5WKmvTw6zAE3KDwtEH3bu8Zg5sFKcAQhUPMu9zVGYj5+TWkBvT8M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779302339; c=relaxed/simple; bh=+a3wGo8sRThJd6g5H5ApthN34xOnIrvwiId/Vy4N/UU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XfyCUFPTgPuqmR6hyEEsyJJd6VCIGjlQPNzNhDNUnM+XkZqnP/pCA172Zbzqelm/OfKUQOrPsgGgYmC+IuW668tj5Qus9GURe5ahgGpPv3X/V+93Zt/OC4ulumVk19d3HRbeJS2/Bfwf1mdaS423q/KJb5BMsKOi1WZK5XRPjuo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=none smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=jgl9S/zb; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="jgl9S/zb" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 30568440E80; Wed, 20 May 2026 20:38:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1779302334; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=JUupb00qUDRStdXnj1nJ2QrJYhHtRgXvfohXbm+8Fh4=; b=jgl9S/zb02YvbpSWBGrl+UzPOWGyOoBohk4peKGufmcxTHyggdEy1yRZCk4BKbazxnb7Gr 7uOLRMgwlRGwOwyWbsydjwiFA3YI/mu66hxDPCws5iVU+iCQDhRRxR5szr4rzR/DnJ5Nki 1A4EuxAtn1ysJ8Y8gsIPEyLzzdH2nNRlBnajY966DKXHzBEm6RkiD4MBBSmlEMiIaKMOJz 02rTiSD6E99wZ3q5P5D+NYUfgC+nC8oe05bVfMtKjjJT/Qx0B2pXIUa2KoP9hM7bcas5+d EVKHTtxU0AQ8oOItLNvUOOMcV791Me3UDlj55X4tO5QSbcb9y2HJQWuvewzJRQ== From: Caleb James DeLisle To: linux-pci@vger.kernel.org Cc: linux-mips@vger.kernel.org, naseefkm@gmail.com, ryder.lee@mediatek.com, helgaas@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, ansuelsmth@gmail.com, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam , Caleb James DeLisle Subject: [PATCH v8 1/3] PCI: mediatek: Use actual physical address instead of virt_to_phys() Date: Wed, 20 May 2026 18:38:25 +0000 Message-Id: <20260520183827.908243-2-cjd@cjdns.fr> In-Reply-To: <20260520183827.908243-1-cjd@cjdns.fr> References: <20260520183827.908243-1-cjd@cjdns.fr> 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-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" From: Manivannan Sadhasivam The driver previously used virt_to_phys() on the ioremapped register base (port->base) to compute the MSI message address. Using virt_to_phys() on an IO mapped address is incorrect because it expects a kernel virtual address. To fix it, store the physical start of the I/O register region in mtk_pcie_port->phys_base and use it to build the MSI address. This replaces the incorrect virt_to_phys() usage and ensures MSI addresses are generated correctly. Fixes: 43e6409db64d ("PCI: mediatek: Add MSI support for MT2712 and MT7622") Signed-off-by: Manivannan Sadhasivam Tested-by: Caleb James DeLisle --- drivers/pci/controller/pcie-mediatek.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controlle= r/pcie-mediatek.c index 75722524fe74..c503fbd774d0 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -175,6 +175,7 @@ struct mtk_pcie_soc { /** * struct mtk_pcie_port - PCIe port information * @base: IO mapped register base + * @phys_base: Physical address of the I/O register base region * @list: port list * @pcie: pointer to PCIe host info * @reset: pointer to port reset control @@ -196,6 +197,7 @@ struct mtk_pcie_soc { */ struct mtk_pcie_port { void __iomem *base; + phys_addr_t phys_base; struct list_head list; struct mtk_pcie *pcie; struct reset_control *reset; @@ -405,7 +407,7 @@ static void mtk_compose_msi_msg(struct irq_data *data, = struct msi_msg *msg) phys_addr_t addr; =20 /* MT2712/MT7622 only support 32-bit MSI addresses */ - addr =3D virt_to_phys(port->base + PCIE_MSI_VECTOR); + addr =3D port->phys_base + PCIE_MSI_VECTOR; msg->address_hi =3D 0; msg->address_lo =3D lower_32_bits(addr); =20 @@ -520,7 +522,7 @@ static void mtk_pcie_enable_msi(struct mtk_pcie_port *p= ort) u32 val; phys_addr_t msg_addr; =20 - msg_addr =3D virt_to_phys(port->base + PCIE_MSI_VECTOR); + msg_addr =3D port->phys_base + PCIE_MSI_VECTOR; val =3D lower_32_bits(msg_addr); writel(val, port->base + PCIE_IMSI_ADDR); =20 @@ -953,6 +955,7 @@ static int mtk_pcie_parse_port(struct mtk_pcie *pcie, struct mtk_pcie_port *port; struct device *dev =3D pcie->dev; struct platform_device *pdev =3D to_platform_device(dev); + struct resource *res; char name[20]; int err; =20 @@ -961,7 +964,14 @@ static int mtk_pcie_parse_port(struct mtk_pcie *pcie, return -ENOMEM; =20 snprintf(name, sizeof(name), "port%d", slot); - port->base =3D devm_platform_ioremap_resource_byname(pdev, name); + res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + if (!res) { + dev_err(dev, "failed to get port%d base\n", slot); + return -EINVAL; + } + + port->phys_base =3D res->start; + port->base =3D devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(port->base)) { dev_err(dev, "failed to map port%d base\n", slot); return PTR_ERR(port->base); --=20 2.39.5 From nobody Sun May 24 22:42:19 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 070A33FCB10; Wed, 20 May 2026 18:39:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779302344; cv=none; b=Ct9RhRFr/jIrCouoW1GmZCp8Y7LkM4B/s9lFlKNpBcwx7Om6g/2fx1TGV4/yZhAFazUCOZbalPPBPlW9sab7ffGyPVfi8O8zxHyEgltWOsRRqz+fn4JNisgOPy+bqjJX6YVLmQo0PNRGebPh57Na8DYrli7nckaeqTeYWwPjKBM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779302344; c=relaxed/simple; bh=waINsKFbSyXcxAqUAzgj9r8Ga8BceWjqseF36ALPBz8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AtVKb5+Spxytff61/Kxb5/nRxzmAPpam6U0PO+b1udNvFlvo77iXPzqYeeIodNKZI3liZGFU1AksH3fMaLMijgU/I2em2FB4cCFKsWTjxWEBy2oRpUCHba1Fc/wc5gAHaatgT3dbrQ+JAMmaq9k1ca4rG49e2SHC4WNs7gJgCL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=none smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=gtH4ny7q; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="gtH4ny7q" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CC5F443F6E7; Wed, 20 May 2026 20:38:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1779302340; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=IXgx7gfpsPR0kF8ck7MRUn7Q28yaC8th/9vky8kZIes=; b=gtH4ny7qs726XGUPG/HHffN9G5ztVqKI4iE5VzJ1eUBWavNKOmbrwglTgwB0+3SqQ0zmCc 5crYkRq79JU3M0U9Bjx1m7O0iy1322+wZZELS30+zraLWuryefrBvu45+PdrtiRbjM+6cj bvgVJGsZ4hiQ2HDz6zFVuUhMdTCU48pAOUvyS7tkha4rUrMzv0qC4ehH07lQIRZSgXgaH8 iTex0icGE25k20wf3vZnCtnK8r9Dr+S82vZW2FP7b9f1n4NVILF6se0hv3gIa4lCAXhK0l 61sEZN23jcc/lhjYN2VTZd7e6bM5mllAAmVW2RxLcUInTenYTbI0KgXZu0W6uA== From: Caleb James DeLisle To: linux-pci@vger.kernel.org Cc: linux-mips@vger.kernel.org, naseefkm@gmail.com, ryder.lee@mediatek.com, helgaas@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, ansuelsmth@gmail.com, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb James DeLisle , Conor Dooley Subject: [PATCH v8 2/3] dt-bindings: PCI: mediatek: Add support for EcoNet EN7528 Date: Wed, 20 May 2026 18:38:26 +0000 Message-Id: <20260520183827.908243-3-cjd@cjdns.fr> In-Reply-To: <20260520183827.908243-1-cjd@cjdns.fr> References: <20260520183827.908243-1-cjd@cjdns.fr> 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-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Introduce EcoNet EN7528 SoC compatible in MediaTek PCIe controller binding. EcoNet PCIe controller has the same configuration model as Mediatek v2 but is initialized more similarly to an MT7621 PCIe. Signed-off-by: Caleb James DeLisle Acked-by: Conor Dooley --- .../bindings/pci/mediatek-pcie.yaml | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.yaml b/Doc= umentation/devicetree/bindings/pci/mediatek-pcie.yaml index 0b8c78ec4f91..c009a7a52bc6 100644 --- a/Documentation/devicetree/bindings/pci/mediatek-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.yaml @@ -14,6 +14,7 @@ properties: oneOf: - enum: - airoha,an7583-pcie + - econet,en7528-pcie - mediatek,mt2712-pcie - mediatek,mt7622-pcie - mediatek,mt7629-pcie @@ -226,6 +227,31 @@ allOf: =20 mediatek,pbus-csr: false =20 + - if: + properties: + compatible: + contains: + const: econet,en7528-pcie + then: + properties: + clocks: + maxItems: 1 + + clock-names: + maxItems: 1 + + resets: false + + reset-names: false + + power-domains: false + + mediatek,pbus-csr: false + + required: + - phys + - phy-names + unevaluatedProperties: false =20 examples: --=20 2.39.5 From nobody Sun May 24 22:42:19 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33A0D439010; Wed, 20 May 2026 18:39:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779302349; cv=none; b=Ut1pMUM6AMZPsn8UvbyrIrJAK0qPzeKM5tD9QV0F/xmWKaNRZ6V0yW/1EZ3FMMOJnTkuLu12ftd/vigqN9tJgtVNGnk/5fiXZZV0MnNg6Mv+asc7L1wDWIt3ImorSVxLngmcSSeUuqzDCXzsf9utHoTtMBWAGtachil6bPtXZg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779302349; c=relaxed/simple; bh=8C37hzjR1SVnXQ8/GTqJJCIov2hR+IOPo1WmYm27f8I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OB8+1tX+E1fJK0hIb0IpSGXeVqiDonn8GAIda7DA3NPxElkeS5TnD3p4t4By7857rUg73RZKSV6EtGEqqnEETCkdnSgwZlM1M9jA7+Dp8pk5XTOVMw8KkcLRPMp9VhHTkeYJk5cA4okUsn+q8DeK/Zxqe0P1Ge9j0I3YL7aTp2o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=none smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=FZgzIMZD; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="FZgzIMZD" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BD065440F94; Wed, 20 May 2026 20:39:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1779302344; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=XGm9ZWVoNbn0xhTUGl1gaGb/LD9HwB97Pokf5bwcBhw=; b=FZgzIMZDpowBKKjMQFUR8NIgr9ZFC1bgfGg+ZosrJr+lk5W8mdcVO7t9hKA4yr2IV3G3yG bhEREpCE9aCxOrmID5aM979/lfZintVTJIPQHgnduTsqfqbbMXCg/2ByFEsygLw1FKwRme nkQya41qEDPvke05KNzWqtWPR8Bh4ZTHSxcURwddpT+zDEWLu1/YC2fhRDjozMvJGoA8PP cDRtahDsAcZ+WYznKL4uVpQEjdiiLagCOxTWsg8wv6wGMy/0QrEiNJXIjJVO8o1Iu1bHgF aHqlNPSf2UlHS1CafI0Rn3VF8Zd0XSYXimLyFRW/XxEIJE/WV6WneQ9/tS2nHw== From: Caleb James DeLisle To: linux-pci@vger.kernel.org Cc: linux-mips@vger.kernel.org, naseefkm@gmail.com, ryder.lee@mediatek.com, helgaas@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, ansuelsmth@gmail.com, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb James DeLisle Subject: [PATCH v8 3/3] PCI: mediatek: Add support for EcoNet EN7528 SoC Date: Wed, 20 May 2026 18:38:27 +0000 Message-Id: <20260520183827.908243-4-cjd@cjdns.fr> In-Reply-To: <20260520183827.908243-1-cjd@cjdns.fr> References: <20260520183827.908243-1-cjd@cjdns.fr> 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-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Add support for the PCIe present on the EcoNet EN7528 (and EN751221) SoCs. These SoCs have a mix of Gen1 and Gen2 capable ports, but the Gen2 ports require re-training after startup. Co-developed-by: Ahmed Naseef Signed-off-by: Ahmed Naseef Signed-off-by: Caleb James DeLisle --- drivers/pci/controller/Kconfig | 2 +- drivers/pci/controller/pcie-mediatek.c | 152 +++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 2247709ef6d6..8a3a31b2bc12 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -209,7 +209,7 @@ config PCI_MVEBU =20 config PCIE_MEDIATEK tristate "MediaTek PCIe controller" - depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST + depends on ARCH_AIROHA || ARCH_MEDIATEK || ECONET || COMPILE_TEST depends on OF depends on PCI_MSI select IRQ_MSI_LIB diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controlle= r/pcie-mediatek.c index c503fbd774d0..4e4d4b1559f7 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -9,11 +9,13 @@ =20 #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -77,6 +79,7 @@ =20 #define PCIE_CONF_VEND_ID 0x100 #define PCIE_CONF_DEVICE_ID 0x102 +#define PCIE_CONF_REV_CLASS 0x104 #define PCIE_CONF_CLASS_ID 0x106 =20 #define PCIE_INT_MASK 0x420 @@ -89,6 +92,11 @@ #define MSI_MASK BIT(23) #define MTK_MSI_IRQS_NUM 32 =20 +#define EN7528_HOST_MODE 0x00804201 +#define EN7528_LINKUP_REG 0x50 +#define EN7528_RC0_LINKUP BIT(1) +#define EN7528_RC1_LINKUP BIT(2) + #define PCIE_AHB_TRANS_BASE0_L 0x438 #define PCIE_AHB_TRANS_BASE0_H 0x43c #define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) @@ -148,12 +156,15 @@ struct mtk_pcie_port; * @MTK_PCIE_FIX_DEVICE_ID: host's device ID needed to be fixed * @MTK_PCIE_NO_MSI: Bridge has no MSI support, and relies on an external = block * @MTK_PCIE_SKIP_RSTB: Skip calling RSTB bits on PCIe probe + * @MTK_PCIE_RETRAIN: Retrain link to bridge after startup because some + * Gen2-capable devices start as Gen1. */ enum mtk_pcie_quirks { MTK_PCIE_FIX_CLASS_ID =3D BIT(0), MTK_PCIE_FIX_DEVICE_ID =3D BIT(1), MTK_PCIE_NO_MSI =3D BIT(2), MTK_PCIE_SKIP_RSTB =3D BIT(3), + MTK_PCIE_RETRAIN =3D BIT(4), }; =20 /** @@ -755,6 +766,132 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_p= ort *port) return 0; } =20 +static int mtk_pcie_startup_port_en7528(struct mtk_pcie_port *port) +{ + struct mtk_pcie *pcie =3D port->pcie; + struct pci_host_bridge *host =3D pci_host_bridge_from_priv(pcie); + struct resource *mem =3D NULL; + struct resource_entry *entry; + u32 val, link_mask; + int err; + + entry =3D resource_list_first_type(&host->windows, IORESOURCE_MEM); + if (entry) + mem =3D entry->res; + if (!mem) + return -EINVAL; + + if (!pcie->cfg) { + dev_err(pcie->dev, "EN7528: pciecfg syscon not available\n"); + return -EINVAL; + } + + /* Assert all reset signals */ + writel(0, port->base + PCIE_RST_CTRL); + + /* + * Enable PCIe link down reset, if link status changed from link up to + * link down, this will reset MAC control registers and configuration + * space. + */ + writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); + + msleep(PCIE_T_PVPERL_MS); + + /* De-assert PHY, PE, PIPE, MAC and configuration reset */ + val =3D readl(port->base + PCIE_RST_CTRL); + val |=3D PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | + PCIE_MAC_SRSTB | PCIE_CRSTB; + writel(val, port->base + PCIE_RST_CTRL); + + writel(PCIE_CLASS_CODE | PCIE_REVISION_ID, + port->base + PCIE_CONF_REV_CLASS); + writel(EN7528_HOST_MODE, port->base); + + link_mask =3D (port->slot =3D=3D 0) ? EN7528_RC0_LINKUP : EN7528_RC1_LINK= UP; + + /* 100ms timeout value should be enough for Gen1/2 training */ + err =3D regmap_read_poll_timeout(pcie->cfg, EN7528_LINKUP_REG, val, + !!(val & link_mask), 20, + PCI_PM_D3COLD_WAIT * USEC_PER_MSEC); + if (err) { + dev_err(pcie->dev, "EN7528: port%d link timeout\n", port->slot); + return -ETIMEDOUT; + } + + /* Activate INTx interrupts */ + val =3D readl(port->base + PCIE_INT_MASK); + val &=3D ~INTX_MASK; + writel(val, port->base + PCIE_INT_MASK); + + if (IS_ENABLED(CONFIG_PCI_MSI)) + mtk_pcie_enable_msi(port); + + /* Set AHB to PCIe translation windows */ + val =3D lower_32_bits(mem->start) | + AHB2PCIE_SIZE(fls(resource_size(mem))); + writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); + + val =3D upper_32_bits(mem->start); + writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); + + writel(WIN_ENABLE, port->base + PCIE_AXI_WINDOW0); + + if (!IS_BUILTIN(CONFIG_PCIE_MEDIATEK)) + dev_info(pcie->dev, + "module not built-in, Gen2 unavailable even if supported\n"); + + return 0; +} + +/** + * mtk_pcie_retrain - retrain the root bridge link if needed + * @dev: The device, for use in logging + * @host: The host bridge which contains the link + * + * Due to what is likely a hardware bug, some devices (notably EcoNet) sta= rt up + * as Gen1, and must be retrained once after initial configuration in orde= r to + * reach Gen2. + * + * These devices always self-identify as Gen2 capable, but sometimes the P= HY is + * only capable of Gen1 operation, and sometimes the PCIe card (e.g. wifi)= is + * only Gen1 capable. Therefore it is most convenient to retrain every port + * after startup. + */ +static int mtk_pcie_retrain(struct device *dev, struct pci_host_bridge *ho= st) +{ + struct pci_dev *rp; + int ret =3D -ENOENT; + u16 lnksta =3D 0; + u32 speed; + + /* Should already have been warned about during startup_port */ + if (!IS_BUILTIN(CONFIG_PCIE_MEDIATEK)) + return 0; + + for_each_pci_bridge(rp, host->bus) { + if (pci_pcie_type(rp) !=3D PCI_EXP_TYPE_ROOT_PORT) + continue; + +#if IS_BUILTIN(CONFIG_PCIE_MEDIATEK) + ret =3D pcie_retrain_link(rp, true); +#endif + + if (ret) + return dev_err_probe(&rp->dev, ret, + "failed to retrain port\n"); + + pcie_capability_read_word(rp, PCI_EXP_LNKSTA, &lnksta); + speed =3D lnksta & PCI_EXP_LNKSTA_CLS; + + pci_info(rp, "link retrained, speed %s\n", + pci_speed_string(pcie_link_speed[speed])); + + } + + return 0; +} + static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, int where) { @@ -1159,6 +1296,13 @@ static int mtk_pcie_probe(struct platform_device *pd= ev) if (err) goto put_resources; =20 + /* + * Ignore error because pci_host_probe() was already called, and in any + * case it is possible that the port will still work as Gen1. + */ + if (pcie->soc->quirks & MTK_PCIE_RETRAIN) + mtk_pcie_retrain(dev, host); + return 0; =20 put_resources: @@ -1274,8 +1418,16 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt7629= =3D { .quirks =3D MTK_PCIE_FIX_CLASS_ID | MTK_PCIE_FIX_DEVICE_ID, }; =20 +static const struct mtk_pcie_soc mtk_pcie_soc_en7528 =3D { + .ops =3D &mtk_pcie_ops_v2, + .startup =3D mtk_pcie_startup_port_en7528, + .setup_irq =3D mtk_pcie_setup_irq, + .quirks =3D MTK_PCIE_RETRAIN, +}; + static const struct of_device_id mtk_pcie_ids[] =3D { { .compatible =3D "airoha,an7583-pcie", .data =3D &mtk_pcie_soc_an7583 }, + { .compatible =3D "econet,en7528-pcie", .data =3D &mtk_pcie_soc_en7528 }, { .compatible =3D "mediatek,mt2701-pcie", .data =3D &mtk_pcie_soc_v1 }, { .compatible =3D "mediatek,mt7623-pcie", .data =3D &mtk_pcie_soc_v1 }, { .compatible =3D "mediatek,mt2712-pcie", .data =3D &mtk_pcie_soc_mt2712 = }, --=20 2.39.5