Commit 09150ab1 authored by Christian Marangi's avatar Christian Marangi Committed by Manivannan Sadhasivam
Browse files

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: default avatarChristian Marangi <ansuelsmth@gmail.com>
Signed-off-by: default avatarManivannan Sadhasivam <mani@kernel.org>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20251020111121.31779-6-ansuelsmth@gmail.com
parent 2d58bc77
Loading
Loading
Loading
Loading
+61 −14
Original line number Diff line number Diff line
@@ -147,11 +147,13 @@ struct mtk_pcie_port;
 * @MTK_PCIE_FIX_CLASS_ID: host's class ID needed to be fixed
 * @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
 */
enum mtk_pcie_quirks {
	MTK_PCIE_FIX_CLASS_ID = BIT(0),
	MTK_PCIE_FIX_DEVICE_ID = BIT(1),
	MTK_PCIE_NO_MSI = BIT(2),
	MTK_PCIE_SKIP_RSTB = BIT(3),
};

/**
@@ -687,13 +689,14 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
	}

	if (!(soc->quirks & MTK_PCIE_SKIP_RSTB)) {
		/* 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.
		 * 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);

@@ -704,6 +707,7 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
		val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
		       PCIE_MAC_SRSTB | PCIE_CRSTB;
		writel(val, port->base + PCIE_RST_CTRL);
	}

	/* Set up vendor ID and class code */
	if (soc->quirks & MTK_PCIE_FIX_CLASS_ID) {
@@ -824,6 +828,41 @@ static int mtk_pcie_startup_port(struct mtk_pcie_port *port)
	return 0;
}

static int mtk_pcie_startup_port_an7583(struct mtk_pcie_port *port)
{
	struct mtk_pcie *pcie = port->pcie;
	struct device *dev = pcie->dev;
	struct pci_host_bridge *host;
	struct resource_entry *entry;
	struct regmap *pbus_regmap;
	resource_size_t addr;
	u32 args[2], size;

	/*
	 * Configure PBus base address and base address mask to allow
	 * the hw to detect if a given address is accessible on PCIe
	 * controller.
	 */
	pbus_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node,
							   "mediatek,pbus-csr",
							   ARRAY_SIZE(args),
							   args);
	if (IS_ERR(pbus_regmap))
		return PTR_ERR(pbus_regmap);

	host = pci_host_bridge_from_priv(pcie);
	entry = resource_list_first_type(&host->windows, IORESOURCE_MEM);
	if (!entry)
		return -ENODEV;

	addr = entry->res->start - entry->offset;
	regmap_write(pbus_regmap, args[0], lower_32_bits(addr));
	size = lower_32_bits(resource_size(entry->res));
	regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size)));

	return mtk_pcie_startup_port_v2(port);
}

static void mtk_pcie_enable_port(struct mtk_pcie_port *port)
{
	struct mtk_pcie *pcie = port->pcie;
@@ -1208,6 +1247,13 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = {
	.quirks = MTK_PCIE_FIX_CLASS_ID,
};

static const struct mtk_pcie_soc mtk_pcie_soc_an7583 = {
	.ops = &mtk_pcie_ops_v2,
	.startup = mtk_pcie_startup_port_an7583,
	.setup_irq = mtk_pcie_setup_irq,
	.quirks = MTK_PCIE_FIX_CLASS_ID | MTK_PCIE_SKIP_RSTB,
};

static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
	.device_id = PCI_DEVICE_ID_MEDIATEK_7629,
	.ops = &mtk_pcie_ops_v2,
@@ -1217,6 +1263,7 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
};

static const struct of_device_id mtk_pcie_ids[] = {
	{ .compatible = "airoha,an7583-pcie", .data = &mtk_pcie_soc_an7583 },
	{ .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 },
	{ .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 },
	{ .compatible = "mediatek,mt2712-pcie", .data = &mtk_pcie_soc_mt2712 },