Message ID | 20190325083501.8088-24-kishon@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add support for PCIe RC and EP mode in TI's AM654 SoC | expand |
On Mon, Mar 25, 2019 at 02:04:58PM +0530, Kishon Vijay Abraham I wrote: > Configure RESBAR capability to advertise the smallest size (1MB) for > couple of reasons. A) Host side resource allocation of BAR fails for > larger sizes. B) Endpoint function driver does not allocate memory > for all supported sizes in RESBAR capability. > If and when there is a usecase required to add more flexibility using > RESBAR, this can be revisited. The #define used in the code below is "REBAR"; maybe spell it out once and then use REBAR instead of RESBAR? > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> > --- > .../pci/controller/dwc/pcie-designware-ep.c | 34 +++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c > index 74477ad7467f..0c208b9bda43 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > @@ -504,10 +504,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; > @@ -591,6 +613,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; > -- > 2.17.1 >
On Sat, Apr 13, 2019 at 11:00:53AM -0500, Bjorn Helgaas wrote: > On Mon, Mar 25, 2019 at 02:04:58PM +0530, Kishon Vijay Abraham I wrote: > > Configure RESBAR capability to advertise the smallest size (1MB) for > > couple of reasons. A) Host side resource allocation of BAR fails for > > larger sizes. B) Endpoint function driver does not allocate memory > > for all supported sizes in RESBAR capability. > > If and when there is a usecase required to add more flexibility using > > RESBAR, this can be revisited. > > The #define used in the code below is "REBAR"; maybe spell it out > once and then use REBAR instead of RESBAR? I think we should just name the capability as it is (Resizable BAR) the kernel defines are there already anyway. I will rewrite the log accordingly. Lorenzo > > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> > > --- > > .../pci/controller/dwc/pcie-designware-ep.c | 34 +++++++++++++++++++ > > 1 file changed, 34 insertions(+) > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c > > index 74477ad7467f..0c208b9bda43 100644 > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > > @@ -504,10 +504,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; > > @@ -591,6 +613,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; > > -- > > 2.17.1 > >
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 74477ad7467f..0c208b9bda43 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -504,10 +504,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; @@ -591,6 +613,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;
Configure RESBAR capability to advertise the smallest size (1MB) for couple of reasons. A) Host side resource allocation of BAR fails for larger sizes. B) Endpoint function driver does not allocate memory for all supported sizes in RESBAR capability. If and when there is a usecase required to add more flexibility using RESBAR, this can be revisited. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> --- .../pci/controller/dwc/pcie-designware-ep.c | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+)