Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: mediatek: Add support for Airoha AN7583 SoC

Add support for the second PCIe Root Complex present on Airoha AN7583
SoC.

This is based on the Mediatek Gen1/2 PCIe driver and similar to Gen3
also require workaround for the reset signals.

Introduce a new quirk to skip having to reset signals and also introduce
some additional logic to configure the PBUS registers required for Airoha
SoC.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20251020111121.31779-6-ansuelsmth@gmail.com

authored by

Christian Marangi and committed by
Manivannan Sadhasivam
09150ab1 2d58bc77

+61 -14
+61 -14
drivers/pci/controller/pcie-mediatek.c
··· 147 147 * @MTK_PCIE_FIX_CLASS_ID: host's class ID needed to be fixed 148 148 * @MTK_PCIE_FIX_DEVICE_ID: host's device ID needed to be fixed 149 149 * @MTK_PCIE_NO_MSI: Bridge has no MSI support, and relies on an external block 150 + * @MTK_PCIE_SKIP_RSTB: Skip calling RSTB bits on PCIe probe 150 151 */ 151 152 enum mtk_pcie_quirks { 152 153 MTK_PCIE_FIX_CLASS_ID = BIT(0), 153 154 MTK_PCIE_FIX_DEVICE_ID = BIT(1), 154 155 MTK_PCIE_NO_MSI = BIT(2), 156 + MTK_PCIE_SKIP_RSTB = BIT(3), 155 157 }; 156 158 157 159 /** ··· 689 687 regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val); 690 688 } 691 689 692 - /* Assert all reset signals */ 693 - writel(0, port->base + PCIE_RST_CTRL); 690 + if (!(soc->quirks & MTK_PCIE_SKIP_RSTB)) { 691 + /* Assert all reset signals */ 692 + writel(0, port->base + PCIE_RST_CTRL); 694 693 695 - /* 696 - * Enable PCIe link down reset, if link status changed from link up to 697 - * link down, this will reset MAC control registers and configuration 698 - * space. 699 - */ 700 - writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); 694 + /* 695 + * Enable PCIe link down reset, if link status changed from 696 + * link up to link down, this will reset MAC control registers 697 + * and configuration space. 698 + */ 699 + writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); 701 700 702 - msleep(PCIE_T_PVPERL_MS); 701 + msleep(PCIE_T_PVPERL_MS); 703 702 704 - /* De-assert PHY, PE, PIPE, MAC and configuration reset */ 705 - val = readl(port->base + PCIE_RST_CTRL); 706 - val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | 707 - PCIE_MAC_SRSTB | PCIE_CRSTB; 708 - writel(val, port->base + PCIE_RST_CTRL); 703 + /* De-assert PHY, PE, PIPE, MAC and configuration reset */ 704 + val = readl(port->base + PCIE_RST_CTRL); 705 + val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | 706 + PCIE_MAC_SRSTB | PCIE_CRSTB; 707 + writel(val, port->base + PCIE_RST_CTRL); 708 + } 709 709 710 710 /* Set up vendor ID and class code */ 711 711 if (soc->quirks & MTK_PCIE_FIX_CLASS_ID) { ··· 826 822 writel(val, pcie->base + PCIE_CFG_DATA); 827 823 828 824 return 0; 825 + } 826 + 827 + static int mtk_pcie_startup_port_an7583(struct mtk_pcie_port *port) 828 + { 829 + struct mtk_pcie *pcie = port->pcie; 830 + struct device *dev = pcie->dev; 831 + struct pci_host_bridge *host; 832 + struct resource_entry *entry; 833 + struct regmap *pbus_regmap; 834 + resource_size_t addr; 835 + u32 args[2], size; 836 + 837 + /* 838 + * Configure PBus base address and base address mask to allow 839 + * the hw to detect if a given address is accessible on PCIe 840 + * controller. 841 + */ 842 + pbus_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, 843 + "mediatek,pbus-csr", 844 + ARRAY_SIZE(args), 845 + args); 846 + if (IS_ERR(pbus_regmap)) 847 + return PTR_ERR(pbus_regmap); 848 + 849 + host = pci_host_bridge_from_priv(pcie); 850 + entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); 851 + if (!entry) 852 + return -ENODEV; 853 + 854 + addr = entry->res->start - entry->offset; 855 + regmap_write(pbus_regmap, args[0], lower_32_bits(addr)); 856 + size = lower_32_bits(resource_size(entry->res)); 857 + regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); 858 + 859 + return mtk_pcie_startup_port_v2(port); 829 860 } 830 861 831 862 static void mtk_pcie_enable_port(struct mtk_pcie_port *port) ··· 1247 1208 .quirks = MTK_PCIE_FIX_CLASS_ID, 1248 1209 }; 1249 1210 1211 + static const struct mtk_pcie_soc mtk_pcie_soc_an7583 = { 1212 + .ops = &mtk_pcie_ops_v2, 1213 + .startup = mtk_pcie_startup_port_an7583, 1214 + .setup_irq = mtk_pcie_setup_irq, 1215 + .quirks = MTK_PCIE_FIX_CLASS_ID | MTK_PCIE_SKIP_RSTB, 1216 + }; 1217 + 1250 1218 static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = { 1251 1219 .device_id = PCI_DEVICE_ID_MEDIATEK_7629, 1252 1220 .ops = &mtk_pcie_ops_v2, ··· 1263 1217 }; 1264 1218 1265 1219 static const struct of_device_id mtk_pcie_ids[] = { 1220 + { .compatible = "airoha,an7583-pcie", .data = &mtk_pcie_soc_an7583 }, 1266 1221 { .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 }, 1267 1222 { .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 }, 1268 1223 { .compatible = "mediatek,mt2712-pcie", .data = &mtk_pcie_soc_mt2712 },