From e9881b2ceeb7a324da45e96924fdd49ffd145efc Mon Sep 17 00:00:00 2001 From: Manikanta Maddireddy Date: Sun, 23 Jun 2024 18:15:20 +0000 Subject: [PATCH] PCI: tegra264: Add link disable and SBR support When PCIe link is disabled or secondary bus reset is done by RP, EP LTSSM state goes to link disable or hot reset respectively. Update the LTSSM state check accordingly to support link disable and secondary bus reset. XTL_EP_PRI_BAR_CONFIG and XTL_EP_PRI_RESIZE_BAR1 are part of hot reset domain, when link is going through hot reset, these registers are not accessible. So, remove these register programming in tegra264_pcie_ep_clear_bar(). After hot reset these registers come back with reset values. Bug 4712053 Change-Id: Ieaf37ed9fed6722db8a16027947121b1cfd1ef4c Signed-off-by: Manikanta Maddireddy Reviewed-on: https://git-master.nvidia.com/r/c/linux-t264/+/3163927 Reviewed-by: Bibek Basu Reviewed-by: Nagarjuna Kristam GVS: buildbot_gerritrpt --- .../controller/private-soc/pcie-tegra264-ep.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/pci/controller/private-soc/pcie-tegra264-ep.c b/drivers/pci/controller/private-soc/pcie-tegra264-ep.c index 092d709a..e72e8865 100644 --- a/drivers/pci/controller/private-soc/pcie-tegra264-ep.c +++ b/drivers/pci/controller/private-soc/pcie-tegra264-ep.c @@ -110,7 +110,8 @@ #define XPL_PL_LTSSM_STATE 0x1700 #define XPL_PL_LTSSM_STATE_FULL GENMASK(7, 0) -#define XPL_PL_LTSSM_STATE_DETECT_RESET 0 +#define XPL_PL_LTSSM_STATE_DISABLE_TX 40 +#define XPL_PL_LTSSM_STATE_HOT_RESET 41 #define NV_EP_PCFG_MSI_64_HEADER 0x48 @@ -336,8 +337,6 @@ static void tegra264_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn, u32 val; if (bar == BAR_1) { - writel(0x0, pcie->xtl_ep_pri_base + XTL_EP_PRI_RESIZE_BAR1); - writel(0x0, pcie->xal_ep_dm_base + XAL_EP_DM_I_ATU_REDIR_BAR1_ADDR_MSB); writel(0x0, pcie->xal_ep_dm_base + XAL_EP_DM_I_ATU_REDIR_BAR1_ADDR_LSB); @@ -345,9 +344,6 @@ static void tegra264_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn, val &= ~XAL_EP_DM_I_ATU_REDIR_CTRL_BAR1_EN; writel(val, pcie->xal_ep_dm_base + XAL_EP_DM_I_ATU_REDIR_CTRL); } else if (bar == BAR_2) { - val = readl(pcie->xtl_ep_pri_base + XTL_EP_PRI_BAR_CONFIG); - writel(val, pcie->xtl_ep_pri_base + XTL_EP_PRI_BAR_CONFIG); - writel(0x0, pcie->xal_ep_dm_base + XAL_EP_DM_I_ATU_REDIR_BAR2_ADDR_MSB); writel(0x0, pcie->xal_ep_dm_base + XAL_EP_DM_I_ATU_REDIR_BAR2_ADDR_LSB); @@ -355,10 +351,6 @@ static void tegra264_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn, val &= ~XAL_EP_DM_I_ATU_REDIR_CTRL_BAR2_EN; writel(val, pcie->xal_ep_dm_base + XAL_EP_DM_I_ATU_REDIR_CTRL); } - - val = readl(pcie->xtl_ep_pri_base + XTL_EP_PRI_BAR_CONFIG); - val &= ~(XTL_EP_PRI_BAR_CONFIG_BAR1_EN | XTL_EP_PRI_BAR_CONFIG_BAR2_EN); - writel(val, pcie->xtl_ep_pri_base + XTL_EP_PRI_BAR_CONFIG); } static int tegra264_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no, @@ -567,12 +559,15 @@ static irqreturn_t tegra264_pcie_ep_irq_thread(int irq, void *arg) int ret; ret = readl_poll_timeout(pcie->xpl_base + XPL_PL_LTSSM_STATE, val, - (val & XPL_PL_LTSSM_STATE_FULL) == XPL_PL_LTSSM_STATE_DETECT_RESET, - PCIE_LTSSM_DELAY, PCIE_LTSSM_TIMEOUT); + ((val & XPL_PL_LTSSM_STATE_FULL) == XPL_PL_LTSSM_STATE_DISABLE_TX) || + ((val & XPL_PL_LTSSM_STATE_FULL) == XPL_PL_LTSSM_STATE_HOT_RESET), + PCIE_LTSSM_DELAY, PCIE_LTSSM_TIMEOUT); if (ret) dev_err(pcie->dev, "PCIe LTSSM state not in detect reset, ltssm: 0x%x\n", val); tegra264_pcie_ep_rst_assert(pcie); + /* Per PCIe CEM spec minimum time between PERST# toggle is 100 usec(TPERST) */ + usleep_range(100, 200); tegra264_pcie_ep_rst_deassert(pcie); return IRQ_HANDLED;