|
|
@@ -502,10 +502,32 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
|
|
|
pci_epc_mem_exit(epc);
|
|
|
}
|
|
|
|
|
|
+static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
|
|
|
+{
|
|
|
+ u32 header;
|
|
|
+ int pos = PCI_CFG_SPACE_SIZE;
|
|
|
+
|
|
|
+ while (pos) {
|
|
|
+ header = dw_pcie_readl_dbi(pci, pos);
|
|
|
+ if (PCI_EXT_CAP_ID(header) == cap)
|
|
|
+ return pos;
|
|
|
+
|
|
|
+ pos = PCI_EXT_CAP_NEXT(header);
|
|
|
+ if (!pos)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
int dw_pcie_ep_init(struct dw_pcie_ep *ep)
|
|
|
{
|
|
|
+ int i;
|
|
|
int ret;
|
|
|
+ u32 reg;
|
|
|
void *addr;
|
|
|
+ unsigned int nbars;
|
|
|
+ unsigned int offset;
|
|
|
struct pci_epc *epc;
|
|
|
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
|
|
struct device *dev = pci->dev;
|
|
|
@@ -589,6 +611,18 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
|
|
|
|
|
|
ep->msix_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSIX);
|
|
|
|
|
|
+ offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
|
|
|
+ if (offset) {
|
|
|
+ reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
|
|
|
+ nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
|
|
|
+ PCI_REBAR_CTRL_NBAR_SHIFT;
|
|
|
+
|
|
|
+ dw_pcie_dbi_ro_wr_en(pci);
|
|
|
+ for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
|
|
|
+ dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
|
|
|
+ dw_pcie_dbi_ro_wr_dis(pci);
|
|
|
+ }
|
|
|
+
|
|
|
dw_pcie_setup(pci);
|
|
|
|
|
|
return 0;
|