diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index e3b5b0d31d77..c5bdc1e04c3c 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -454,6 +454,7 @@ struct tegra_pcie_port { unsigned int index; unsigned int lanes; unsigned int aspm_state; + bool supports_clkreq; struct phy **phys; @@ -762,6 +763,13 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port) disable_aspm_l11(port); if (port->aspm_state & 0x8) disable_aspm_l12(port); + + /* Disable L1SS capability if CLKREQ# is not present */ + if (!port->supports_clkreq) { + value = readl(port->base + RP_L1_PM_SUBSTATES_CTL); + value |= RP_L1_PM_SUBSTATES_CTL_HIDE_CAP; + writel(value, port->base + RP_L1_PM_SUBSTATES_CTL); + } } } @@ -959,8 +967,12 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) value = afi_readl(port->pcie, ctrl); value |= AFI_PEX_CTRL_REFCLK_EN; - if (soc->has_pex_clkreq_en) - value &= ~AFI_PEX_CTRL_CLKREQ_EN; + if (soc->has_pex_clkreq_en) { + if (port->supports_clkreq) + value &= ~AFI_PEX_CTRL_CLKREQ_EN; + else + value |= AFI_PEX_CTRL_CLKREQ_EN; + } value |= AFI_PEX_CTRL_OVERRIDE_EN; @@ -1394,6 +1406,14 @@ static void tegra_pcie_enable_controller(struct tegra_pcie *pcie) value = afi_readl(pcie, AFI_PLLE_CONTROL); value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL; value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN; + + list_for_each_entry(port, &pcie->ports, list) { + if (!port->supports_clkreq) { + value &= ~AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN; + break; + } + } + value &= ~AFI_PLLE_CONTROL_BYPASS_PCIE2PLLE_CONTROL; value |= AFI_PLLE_CONTROL_PCIE2PLLE_CONTROL_EN; afi_writel(pcie, value, AFI_PLLE_CONTROL); @@ -2523,6 +2543,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) if (err < 0) rp->aspm_state = 0; + rp->supports_clkreq = of_property_read_bool(port, + "supports-clkreq"); + list_add_tail(&rp->list, &pcie->ports); }