{"id":2229737,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2229737/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/20260428163925.6DF1968D07@verein.lst.de/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/1.1/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20260428163925.6DF1968D07@verein.lst.de>","date":"2026-04-28T16:39:25","name":"[v2,3/9] pci: brcmstb: Support different variants using a cfg struct","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"a279511fd57ba15d384b32c06efe1450ec57fad5","submitter":{"id":2722,"url":"http://patchwork.ozlabs.org/api/1.1/people/2722/?format=json","name":"Torsten Duwe","email":"duwe@lst.de"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/20260428163925.6DF1968D07@verein.lst.de/mbox/","series":[{"id":501902,"url":"http://patchwork.ozlabs.org/api/1.1/series/501902/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=501902","date":"2026-04-28T16:23:19","name":"ARM: RPi5: Enable PCIe","version":2,"mbox":"http://patchwork.ozlabs.org/series/501902/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2229737/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2229737/checks/","tags":{},"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)","phobos.denx.de;\n dmarc=fail (p=none dis=none) header.from=lst.de","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de;\n dmarc=fail (p=none dis=none) header.from=lst.de","phobos.denx.de; spf=pass smtp.mailfrom=duwe@lst.de"],"Received":["from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4mTx6XSTz1yHv\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 02:43:49 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 3A10E84674;\n\tTue, 28 Apr 2026 18:43:24 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id 615EF845E3; Tue, 28 Apr 2026 18:39:32 +0200 (CEST)","from verein.lst.de (verein.lst.de [213.95.11.211])\n (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id C130184605\n for <u-boot@lists.denx.de>; Tue, 28 Apr 2026 18:39:27 +0200 (CEST)","by verein.lst.de (Postfix, from userid 2005)\n id 6DF1968D07; Tue, 28 Apr 2026 18:39:25 +0200 (CEST)"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-1.9 required=5.0 tests=BAYES_00,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2","Subject":"[PATCH v2 3/9] pci: brcmstb: Support different variants using a cfg\n struct","To":"Peter Robinson <pbrobinson@gmail.com>,\n Matthias Brugger <mbrugger@suse.com>","Cc":"=?unknown-8bit?q?Tom_Rini_=3Ctrini=40konsulko=2Ecom=3E=2C=22Jan_=C4=8Cer?=\n\t=?unknown-8bit?q?m=C3=A1k=22_=3Csairon=40sairon=2Ecz=3E=2CAndrea_della_Port?=\n\t=?unknown-8bit?q?a_=3Candrea=2Eporta=40suse=2Ecom=3E=2C=22Ivan_T=2E_Ivanov?=\n\t=?unknown-8bit?q?=22_=3Ciivanov=40suse=2Ede=3E=2C_Stanimir_Varbanov_=3Cstan?=\n\t=?unknown-8bit?q?imir=2Evarbanov=40suse=2Ecom=3E=2C_Oleksii_Moisieiev_=3COl?=\n\t=?unknown-8bit?q?eksii=5FMoisieiev=40epam=2Ecom=3E=2C_Volodymyr_Babchuk_=3C?=\n\t=?unknown-8bit?q?volodymyr=5Fbabchuk=40epam=2Ecom=3E=2C_Marek_Vasut_=3Cmare?=\n\t=?unknown-8bit?q?k=2Evasut+renesas=40mailbox=2Eorg=3E=2CPaul_Barker_=3Cpaul?=\n\t=?unknown-8bit?q?=2Ebarker=2Ect=40bp=2Erenesas=2Ecom=3E=2CPatrice_Chotard_?=\n\t=?unknown-8bit?q?=3Cpatrice=2Echotard=40foss=2Est=2Ecom=3E=2CChristian_Mara?=\n\t=?unknown-8bit?q?ngi_=3Cansuelsmth=40gmail=2Ecom=3E=2CPatrick_Delaunay_=3Cp?=\n\t=?unknown-8bit?q?atrick=2Edelaunay=40foss=2Est=2Ecom=3E=2CHuan_Zhou_=3Cme?=\n\t=?unknown-8bit?q?=40per1cycle=2Eorg=3E=2CGabriel_Fernandez_=3Cgabriel=2Efer?=\n\t=?unknown-8bit?q?nandez=40foss=2Est=2Ecom=3E=2CKever_Yang_=3Ckever=2Eyang?=\n\t=?unknown-8bit?q?=40rock-chips=2Ecom=3E=2CJonas_Karlman_=3Cjonas=40kwiboo?=\n\t=?unknown-8bit?q?=2Ese=3E=2CJoseph_Chen_=3Cchenjh=40rock-chips=2Ecom=3E=2CE?=\n\t=?unknown-8bit?q?laine_Zhang_=3Czhangqing=40rock-chips=2Ecom=3E=2C_Pedro_Fa?=\n\t=?unknown-8bit?q?lcato_=3Cpfalcato=40suse=2Ede=3E=2Cu-boot=40lists=2Edenx?=\n\t=?unknown-8bit?q?=2Ede?=","In-Reply-To":"<20260428162319.99B4268B05@verein.lst.de>","Message-Id":"<20260428163925.6DF1968D07@verein.lst.de>","Date":"Tue, 28 Apr 2026 18:39:25 +0200 (CEST)","From":"duwe@lst.de (Torsten Duwe)","X-Mailman-Approved-At":"Tue, 28 Apr 2026 18:43:21 +0200","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.39","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<https://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>","X-Virus-Scanned":"clamav-milter 0.103.8 at phobos.denx.de","X-Virus-Status":"Clean"},"content":"From: Torsten Duwe <duwe@suse.de>\n\nThe Linux kernel driver already had support for multiple hardware\nvariants when the bcm2712 was added (see e.g. linux commit\n10dbedad3c818 which is the last in a longer set of changes). This\npatch brings in this required infrastructure and adds a\ndifferentiation between 2711 and 2712 register layouts on top.\nIt also accounts for the bcm2712 reset logic quirk that the software\ninit bit must not remain set, albeit the reset control location is\nonly corrected in patch#6 of this series.\n\nSigned-off-by: Torsten Duwe <duwe@suse.de>\nCo-authored-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>\nTested-by: Pedro Falcato <pfalcato@suse.de>\n\n---\n .../mach-bcm283x/include/mach/acpi/bcm2711.h  |   6 +-\n drivers/pci/pcie_brcmstb.c                    | 122 ++++++++++++++++--\n 2 files changed, 114 insertions(+), 14 deletions(-)","diff":"diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h\nindex a86875b1833..6eb5389b858 100644\n--- a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h\n+++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h\n@@ -70,6 +70,7 @@\n #define PCIE_MISC_RC_BAR2_CONFIG_HI               0x4038\n #define PCIE_MISC_RC_BAR3_CONFIG_LO               0x403c\n #define  RC_BAR3_CONFIG_LO_SIZE_MASK                0x1f\n+#define PCIE_MISC_PCIE_CTRL\t\t\t  0x4064\n #define PCIE_MISC_PCIE_STATUS                     0x4068\n #define  STATUS_PCIE_PORT_MASK                      0x80\n #define  STATUS_PCIE_PORT_SHIFT                        7\n@@ -107,7 +108,10 @@\n #define PCIE_MSI_INTR2_MASK_SET               0x4510\n \n #define PCIE_RGR1_SW_INIT_1                   0x9210\n-#define PCIE_EXT_CFG_INDEX                    0x9000\n+#define  RGR1_SW_INIT_1_PERST_MASK\t\t\t0x1\n+#define  RGR1_SW_INIT_1_PERSTB_MASK\t\t\t0x4\n+#define  RGR1_SW_INIT_1_INIT_MASK\t\t\t0x2\n+\n /* A small window pointing at the ECAM of the device selected by CFG_INDEX */\n #define PCIE_EXT_CFG_DATA                     0x8000\n \ndiff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c\nindex 47c0802df23..261f8790528 100644\n--- a/drivers/pci/pcie_brcmstb.c\n+++ b/drivers/pci/pcie_brcmstb.c\n@@ -49,6 +49,28 @@\n #define SSC_STATUS_PLL_LOCK_MASK\t\t\t0x800\n #define SSC_STATUS_PLL_LOCK_SHIFT\t\t\t11\n \n+enum {\n+\tRGR1_SW_INIT_1,\n+\tEXT_CFG_INDEX,\n+\tEXT_CFG_DATA,\n+\tPCIE_HARD_DEBUG,\n+};\n+\n+enum brcm_pcie_type {\n+\tBCM2711,\n+\tBCM2712\n+};\n+\n+struct brcm_pcie;\n+\n+struct brcm_pcie_cfg_data {\n+\tconst int *offsets;\n+\tconst enum brcm_pcie_type type;\n+\tvoid (*perst_set)(struct brcm_pcie *pcie, u32 val);\n+\tvoid (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);\n+\tbool (*rc_mode)(struct brcm_pcie *pcie);\n+};\n+\n /**\n  * struct brcm_pcie - the PCIe controller state\n  * @base: Base address of memory mapped IO registers of the controller\n@@ -61,6 +83,7 @@ struct brcm_pcie {\n \n \tint\t\t\tgen;\n \tbool\t\t\tssc;\n+\tconst struct brcm_pcie_cfg_data *pcie_cfg;\n };\n \n /**\n@@ -104,6 +127,36 @@ static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)\n \treturn (val & STATUS_PCIE_PORT_MASK) >> STATUS_PCIE_PORT_SHIFT;\n }\n \n+static void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)\n+{\n+\tif (val)\n+\t\tsetbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],\n+\t\t\t     RGR1_SW_INIT_1_PERST_MASK);\n+\telse\n+\t\tclrbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],\n+\t\t\t     RGR1_SW_INIT_1_PERST_MASK);\n+}\n+\n+static void brcm_pcie_perst_set_2712(struct brcm_pcie *pcie, u32 val)\n+{\n+\tu32 tmp;\n+\n+\t/* Perst bit has moved and assert value is 0 */\n+\ttmp = readl(pcie->base + PCIE_MISC_PCIE_CTRL);\n+\tu32p_replace_bits(&tmp, !val, RGR1_SW_INIT_1_PERSTB_MASK);\n+\twritel(tmp, pcie->base + PCIE_MISC_PCIE_CTRL);\n+}\n+\n+static void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)\n+{\n+\tif (val)\n+\t\tsetbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],\n+\t\t\t     RGR1_SW_INIT_1_INIT_MASK);\n+\telse\n+\t\tclrbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],\n+\t\t\t     RGR1_SW_INIT_1_INIT_MASK);\n+}\n+\n /**\n  * brcm_pcie_link_up() - Check whether the PCIe link is up\n  * @pcie: Pointer to the PCIe controller state\n@@ -150,8 +203,8 @@ static int brcm_pcie_config_address(const struct udevice *dev, pci_dev_t bdf,\n \t/* For devices, write to the config space index register */\n \tidx = PCIE_ECAM_OFFSET(pci_bus, pci_dev, pci_func, 0);\n \n-\twritel(idx, pcie->base + PCIE_EXT_CFG_INDEX);\n-\t*paddress = pcie->base + PCIE_EXT_CFG_DATA + offset;\n+\twritel(idx, pcie->base + pcie->pcie_cfg->offsets[EXT_CFG_INDEX]);\n+\t*paddress = pcie->base + pcie->pcie_cfg->offsets[EXT_CFG_DATA] + offset;\n \n \treturn 0;\n }\n@@ -365,8 +418,9 @@ static int brcm_pcie_probe(struct udevice *dev)\n \t * e.g. BCM7278, the fundamental reset should not be asserted here.\n \t * This will need to be changed when support for other SoCs is added.\n \t */\n-\tsetbits_le32(base + PCIE_RGR1_SW_INIT_1,\n-\t\t     PCIE_RGR1_SW_INIT_1_INIT_MASK | PCIE_RGR1_SW_INIT_1_PERST_MASK);\n+\tpcie->pcie_cfg->bridge_sw_init_set(pcie, 1);\n+\tif (pcie->pcie_cfg->type != BCM2712)\n+\t\tpcie->pcie_cfg->perst_set(pcie, 1);\n \t/*\n \t * The delay is a safety precaution to preclude the reset signal\n \t * from looking like a glitch.\n@@ -374,9 +428,9 @@ static int brcm_pcie_probe(struct udevice *dev)\n \tudelay(100);\n \n \t/* Take the bridge out of reset */\n-\tclrbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK);\n+\tpcie->pcie_cfg->bridge_sw_init_set(pcie, 0);\n \n-\tclrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,\n+\tclrbits_le32(base + pcie->pcie_cfg->offsets[PCIE_HARD_DEBUG],\n \t\t     PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);\n \n \t/* Wait for SerDes to be stable */\n@@ -426,8 +480,7 @@ static int brcm_pcie_probe(struct udevice *dev)\n \t\tbrcm_pcie_set_gen(pcie, pcie->gen);\n \n \t/* Unassert the fundamental reset */\n-\tclrbits_le32(pcie->base + PCIE_RGR1_SW_INIT_1,\n-\t\t     PCIE_RGR1_SW_INIT_1_PERST_MASK);\n+\tpcie->pcie_cfg->perst_set(pcie, 0);\n \n \t/*\n \t * Wait for 100ms after PERST# deassertion; see PCIe CEM specification\n@@ -446,7 +499,7 @@ static int brcm_pcie_probe(struct udevice *dev)\n \t\treturn -EINVAL;\n \t}\n \n-\tif (!brcm_pcie_rc_mode(pcie)) {\n+\tif (!pcie->pcie_cfg->rc_mode(pcie)) {\n \t\tprintf(\"PCIe misconfigured; is in EP mode\\n\");\n \t\treturn -EINVAL;\n \t}\n@@ -514,14 +567,25 @@ static int brcm_pcie_remove(struct udevice *dev)\n \tvoid __iomem *base = pcie->base;\n \n \t/* Assert fundamental reset */\n-\tsetbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_PERST_MASK);\n+\tsetbits_le32(base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],\n+\t\t     PCIE_RGR1_SW_INIT_1_PERST_MASK);\n \n \t/* Turn off SerDes */\n-\tsetbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,\n+\tsetbits_le32(base + pcie->pcie_cfg->offsets[PCIE_HARD_DEBUG],\n \t\t     PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);\n \n \t/* Shutdown bridge */\n-\tsetbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK);\n+\tpcie->pcie_cfg->bridge_sw_init_set(pcie, 1);\n+\n+\t/*\n+\t * For the controllers that are utilizing reset for bridge Sw init,\n+\t * such as BCM2712, reset should be deasserted after assertion.\n+\t * Leaving it in asserted state may lead to unexpected hangs in\n+\t * the Linux Kernel driver because it do not perform reset initialization\n+\t * and start accessing device memory.\n+\t */\n+\tif (pcie->pcie_cfg->type == BCM2712)\n+\t\tpcie->pcie_cfg->bridge_sw_init_set(pcie, 0);\n \n \treturn 0;\n }\n@@ -546,6 +610,7 @@ static int brcm_pcie_of_to_plat(struct udevice *dev)\n \telse\n \t\tpcie->gen = max_link_speed;\n \n+\tpcie->pcie_cfg = (const struct brcm_pcie_cfg_data *)dev_get_driver_data(dev);\n \treturn 0;\n }\n \n@@ -554,8 +619,39 @@ static const struct dm_pci_ops brcm_pcie_ops = {\n \t.write_config\t= brcm_pcie_write_config,\n };\n \n+static const int pcie_offsets[] = {\n+\t[RGR1_SW_INIT_1] = 0x9210,\n+\t[EXT_CFG_INDEX]  = 0x9000,\n+\t[EXT_CFG_DATA]   = 0x8000,\n+\t[PCIE_HARD_DEBUG] = 0x4204,\n+};\n+\n+static const struct brcm_pcie_cfg_data bcm2711_cfg = {\n+\t.offsets\t= pcie_offsets,\n+\t.type\t\t= BCM2711,\n+\t.perst_set\t= brcm_pcie_perst_set_generic,\n+\t.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,\n+\t.rc_mode\t= brcm_pcie_rc_mode,\n+};\n+\n+static const int pcie_offsets_bcm2712[] = {\n+\t[RGR1_SW_INIT_1] = 0x0,\n+\t[EXT_CFG_INDEX] = 0x9000,\n+\t[EXT_CFG_DATA] = 0x8000,\n+\t[PCIE_HARD_DEBUG] = 0x4304,\n+};\n+\n+static const struct brcm_pcie_cfg_data bcm2712_cfg = {\n+\t.offsets\t= pcie_offsets_bcm2712,\n+\t.type\t\t= BCM2712,\n+\t.perst_set\t= brcm_pcie_perst_set_2712,\n+\t.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,\n+\t.rc_mode\t= brcm_pcie_rc_mode,\n+};\n+\n static const struct udevice_id brcm_pcie_ids[] = {\n-\t{ .compatible = \"brcm,bcm2711-pcie\" },\n+\t{ .compatible = \"brcm,bcm2711-pcie\", .data = (ulong)&bcm2711_cfg },\n+\t{ .compatible = \"brcm,bcm2712-pcie\", .data = (ulong)&bcm2712_cfg },\n \t{ }\n };\n \n","prefixes":["v2","3/9"]}