mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
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
This commit is contained in:
committed by
Manivannan Sadhasivam
parent
2d58bc7777
commit
09150ab1a7
@@ -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,23 +689,25 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
|
||||
regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
|
||||
}
|
||||
|
||||
/* Assert all reset signals */
|
||||
writel(0, port->base + PCIE_RST_CTRL);
|
||||
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.
|
||||
*/
|
||||
writel(PCIE_LINKDOWN_RST_EN, 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);
|
||||
msleep(PCIE_T_PVPERL_MS);
|
||||
|
||||
/* De-assert PHY, PE, PIPE, MAC and configuration reset */
|
||||
val = readl(port->base + PCIE_RST_CTRL);
|
||||
val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
|
||||
PCIE_MAC_SRSTB | PCIE_CRSTB;
|
||||
writel(val, port->base + PCIE_RST_CTRL);
|
||||
/* De-assert PHY, PE, PIPE, MAC and configuration reset */
|
||||
val = readl(port->base + PCIE_RST_CTRL);
|
||||
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 },
|
||||
|
||||
Reference in New Issue
Block a user