From 536a60889d19aaf31779bf4aa0a157158845737d Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Sat, 1 Nov 2025 23:34:03 +0000 Subject: [PATCH] pci: tegra: add t210b01 support This commit also fixes configuration checks Signed-off-by: Thomas Makin --- drivers/pci/controller/pci-tegra.c | 85 +++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 579d390bf94a..b1e9aa7a7f21 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -1846,6 +1846,15 @@ static void tegra_pcie_disable_interrupts(struct tegra_pcie *pcie) afi_writel(pcie, value, AFI_INTR_MASK); } +static void update_rp_lanes(struct tegra_pcie *pcie, u32 lanes) +{ + struct tegra_pcie_port *port = NULL; + + list_for_each_entry(port, &pcie->ports, list) + port->lanes = (lanes >> (port->index << 3)) & 0xFF; + +} + static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, u32 *xbar) { @@ -1874,6 +1883,21 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, "switching to default 2x1, 1x1, 1x1 " "configuration\n"); *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211; + update_rp_lanes(pcie, 0x010102); + return 0; + } + } else if (of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) { + switch (lanes) { + case 0x0104: + dev_info(pcie->dev, "4x1, 1x1 configuration\n"); + *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1; + return 0; + + default: + dev_info(pcie->dev, "wrong configuration updated in DT, " + "switching to default 4x1, 1x1 configuration\n"); + *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1; + update_rp_lanes(pcie, 0x0104); return 0; } } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie") || @@ -1888,6 +1912,13 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, dev_info(dev, "2x1, 1x1 configuration\n"); *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1; return 0; + + default: + dev_info(pcie->dev, "wrong configuration updated in DT, " + "switching to default 4x1, 1x1 configuration\n"); + *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1; + update_rp_lanes(pcie, 0x0104); + return 0; } } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { switch (lanes) { @@ -1905,6 +1936,14 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, dev_info(dev, "4x1, 1x2 configuration\n"); *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411; return 0; + + default: + dev_info(dev, "wrong configuration updated in DT, " + "switching to default 4x1, 1x2 " + "configuration\n"); + *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411; + update_rp_lanes(pcie, 0x010104); + return 0; } } else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) { switch (lanes) { @@ -1917,6 +1956,14 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, dev_info(dev, "dual-mode configuration\n"); *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL; return 0; + + default: + dev_info(dev, "wrong configuration updated in DT, " + "switching to default dual-mode " + "configuration\n"); + *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL; + update_rp_lanes(pcie, 0x000202); + return 0; } } @@ -2010,7 +2057,8 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask) pcie->supplies[i++].supply = "hvdd-pex-pll"; pcie->supplies[i++].supply = "hvdd-pex"; pcie->supplies[i++].supply = "vddio-pexctl-aud"; - } else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) { + } else if (of_device_is_compatible(np, "nvidia,tegra210-pcie") || + of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) { pcie->num_supplies = 3; pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies, @@ -2490,6 +2538,40 @@ static const struct tegra_pcie_soc tegra210_pcie = { }, }; +static const struct tegra_pcie_soc tegra210b01_pcie = { + .num_ports = 2, + .ports = tegra20_pcie_ports, + .msi_base_shift = 8, + .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, + .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, + .pads_refclk_cfg0 = 0x90b890b8, + /* FC threshold is bit[25:18] */ + .update_fc_threshold = 0x01800000, + .has_pex_clkreq_en = true, + .has_pex_bias_ctrl = true, + .has_intr_prsnt_sense = true, + .has_cml_clk = true, + .has_gen2 = true, + .force_pca_enable = true, + .program_uphy = true, + .program_deskew_time = true, + .update_fc_timer = true, + .has_cache_bars = false, + .ectl = { + .regs = { + .rp_ectl_2_r1 = 0x0000000f, + .rp_ectl_4_r1 = 0x00000067, + .rp_ectl_5_r1 = 0x55010000, + .rp_ectl_6_r1 = 0x00000001, + .rp_ectl_2_r2 = 0x0000008f, + .rp_ectl_4_r2 = 0x000000c7, + .rp_ectl_5_r2 = 0x55010000, + .rp_ectl_6_r2 = 0x00000001, + }, + .enable = true, + }, +}; + static const struct tegra_pcie_port_soc tegra186_pcie_ports[] = { { .pme.turnoff_bit = 0, .pme.ack_bit = 5 }, { .pme.turnoff_bit = 8, .pme.ack_bit = 10 }, @@ -2522,6 +2604,7 @@ static const struct tegra_pcie_soc tegra186_pcie = { static const struct of_device_id tegra_pcie_of_match[] = { { .compatible = "nvidia,tegra186-pcie", .data = &tegra186_pcie }, { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie }, + { .compatible = "nvidia,tegra210b01-pcie", .data = &tegra210b01_pcie }, { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie }, { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie }, { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },