From f6a8256ac35ecb24a9af4c86bbeba4b8e1f848a1 Mon Sep 17 00:00:00 2001 From: Manikanta Maddireddy Date: Tue, 17 Jul 2018 16:34:45 +0530 Subject: [PATCH] PCI: tegra: aspm DT support Squashed below k414 commits into single change. PCI: tegra: Add DT support to disable per state aspm Kernel config option provides choice to disable L0s & L1 or L1 substates combinedly. Add DT support to disable each aspm state individually. bug 200420606 Signed-off-by: Manikanta Maddireddy Reviewed-on: https://git-master.nvidia.com/r/1786548 (cherry picked from commit f3c5bcdc3ab8cadd3d24ea4d1a8e0aba7beea751) PCI: tegra: Fix ASPM DT property parsing code DT property "nvidia,disable-aspm-states" is part of PCIe port node. Use correct of_node pointer to parse this property. bug 200434876 Signed-off-by: Manikanta Maddireddy Reviewed-on: https://git-master.nvidia.com/r/c/linux-4.14/+/2383766 (cherry picked from commit 8dd957e9ecf29da4ba94471e3d74b2aef98a0643) Change-Id: Iee1f573a103c0045d4f8f6606db13b47575b8cb9 Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2408709 Reviewed-by: automaticguardword Reviewed-by: Bitan Biswas Reviewed-by: mobile promotions Tested-by: Bitan Biswas Tested-by: mobile promotions --- drivers/pci/controller/pci-tegra.c | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 77ca6f668cf2..adc6da4d2b4b 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -174,6 +174,10 @@ #define RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1ff << 1) #define RP_L1_PM_SUBSTATES_CTL 0xc00 +#define RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_2 (0x1 << 0) +#define RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_1 (0x1 << 1) +#define RP_L1_PM_SUBSTATES_CTL_ASPM_L1_2 (0x1 << 2) +#define RP_L1_PM_SUBSTATES_CTL_ASPM_L1_1 (0x1 << 3) #define RP_L1_PM_SUBSTATES_CTL_CM_RTIME_MASK (0xff << 8) #define RP_L1_PM_SUBSTATES_CTL_CM_RTIME_SHIFT 8 #define RP_L1_PM_SUBSTATES_CTL_T_PWRN_SCL_MASK (0x3 << 16) @@ -253,6 +257,7 @@ #define RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK (0xff << 18) #define RP_VEND_XP1 0xf04 +#define RP_VEND_XP1_LINK_PVT_CTL_IGNORE_L0S (1 << 23) #define RP_VEND_XP1_LINK_PVT_CTL_L1_ASPM_SUPPORT (1 << 21) @@ -302,6 +307,8 @@ #define RP_LINK_CONTROL_STATUS_2 0x000000b0 +#define RP_L1_PM_SUBSTATES_CAP 0x144 + #define PADS_CTL_SEL 0x0000009c #define PADS_CTL 0x000000a0 @@ -446,6 +453,7 @@ struct tegra_pcie_port { void __iomem *base; unsigned int index; unsigned int lanes; + unsigned int aspm_state; struct phy **phys; @@ -647,6 +655,44 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port) } } +static void disable_aspm_l0s(struct tegra_pcie_port *port) +{ + u32 val = 0; + + val = readl(port->base + RP_VEND_XP1); + val |= RP_VEND_XP1_LINK_PVT_CTL_IGNORE_L0S; + writel(val, port->base + RP_VEND_XP1); +} + +static void disable_aspm_l10(struct tegra_pcie_port *port) +{ + u32 val = 0; + + val = readl(port->base + RP_VEND_XP1); + val &= ~RP_VEND_XP1_LINK_PVT_CTL_L1_ASPM_SUPPORT; + writel(val, port->base + RP_VEND_XP1); +} + +static void disable_aspm_l11(struct tegra_pcie_port *port) +{ + u32 val = 0; + + val = readl(port->base + RP_L1_PM_SUBSTATES_CTL); + val &= ~RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_1; + val &= ~RP_L1_PM_SUBSTATES_CTL_ASPM_L1_1; + writel(val, port->base + RP_L1_PM_SUBSTATES_CTL); +} + +static void disable_aspm_l12(struct tegra_pcie_port *port) +{ + u32 val = 0; + + val = readl(port->base + RP_L1_PM_SUBSTATES_CTL); + val &= ~RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_2; + val &= ~RP_L1_PM_SUBSTATES_CTL_ASPM_L1_2; + writel(val, port->base + RP_L1_PM_SUBSTATES_CTL); +} + static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port) { const struct tegra_pcie_soc *soc = port->pcie->soc; @@ -700,6 +746,22 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port) value |= RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_L1_L1PP; value |= RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_L1_CLKREQ_L1PP; writel(value, port->base + RP_VEND_XP_PAD_PWRDN); + + if (port->aspm_state & 0x1) + disable_aspm_l0s(port); + if (port->aspm_state & 0x2) + disable_aspm_l10(port); + } + + if (soc->has_aspm_l1ss) { + if (port->aspm_state & 0x2) { + disable_aspm_l11(port); + disable_aspm_l12(port); + } + if (port->aspm_state & 0x4) + disable_aspm_l11(port); + if (port->aspm_state & 0x8) + disable_aspm_l12(port); } } @@ -2456,6 +2518,11 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) } } + err = of_property_read_u32(port, "nvidia,disable-aspm-states", + &rp->aspm_state); + if (err < 0) + rp->aspm_state = 0; + list_add_tail(&rp->list, &pcie->ports); }