PCI: designware-ep: Disable PTM capabilities for EP mode
authorVidya Sagar <vidyas@nvidia.com>
Mon, 19 Sep 2022 14:33:40 +0000 (20:03 +0530)
committerLorenzo Pieralisi <lpieralisi@kernel.org>
Thu, 27 Oct 2022 12:42:56 +0000 (14:42 +0200)
Dual mode DesignWare PCIe IP has PTM capability enabled (if supported) even
in the EP mode. The PCIe compliance for the EP mode expects PTM
capabilities (ROOT_CAPABLE, RES_CAPABLE, CLK_GRAN) be disabled.
Hence disable PTM for the EP mode.

Link: https://lore.kernel.org/r/20220919143340.4527-3-vidyas@nvidia.com
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
drivers/pci/controller/dwc/pcie-designware-ep.c

index 83ddb190292e4f5569254d735851f51ad4ef986d..efc6c6360e28f9f76f0709a6becb02c180284f8b 100644 (file)
@@ -643,7 +643,7 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
 int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       unsigned int offset;
+       unsigned int offset, ptm_cap_base;
        unsigned int nbars;
        u8 hdr_type;
        u32 reg;
@@ -659,6 +659,7 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
        }
 
        offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
+       ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
 
        dw_pcie_dbi_ro_wr_en(pci);
 
@@ -671,6 +672,22 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
                        dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
        }
 
+       /*
+        * PTM responder capability can be disabled only after disabling
+        * PTM root capability.
+        */
+       if (ptm_cap_base) {
+               dw_pcie_dbi_ro_wr_en(pci);
+               reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
+               reg &= ~PCI_PTM_CAP_ROOT;
+               dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
+
+               reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
+               reg &= ~(PCI_PTM_CAP_RES | PCI_PTM_GRANULARITY_MASK);
+               dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
+               dw_pcie_dbi_ro_wr_dis(pci);
+       }
+
        dw_pcie_setup(pci);
        dw_pcie_dbi_ro_wr_dis(pci);