Commit 2ce73872 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/endpoint'

- For fixed-size BARs, retain both the actual size and the possibly larger
  size allocated to accommodate iATU alignment requirements (Jerome Brunet)

- Simplify ctrl/SPAD space allocation and avoid allocating more space than
  needed (Jerome Brunet)

- Correct MSI-X PBA offset calculations for DesignWare and Cadence endpoint
  controllers (Niklas Cassel)

- Align the return value (number of interrupts) encoding for
  pci_epc_get_msi()/pci_epc_ops::get_msi() and
  pci_epc_get_msix()/pci_epc_ops::get_msix() (Niklas Cassel)

- Align the nr_irqs parameter encoding for
  pci_epc_set_msi()/pci_epc_ops::set_msi() and
  pci_epc_set_msix()/pci_epc_ops::set_msix() (Niklas Cassel)

* pci/endpoint:
  PCI: endpoint: Align pci_epc_set_msix(), pci_epc_ops::set_msix() nr_irqs encoding
  PCI: endpoint: Align pci_epc_set_msi(), pci_epc_ops::set_msi() nr_irqs encoding
  PCI: endpoint: Align pci_epc_get_msix(), pci_epc_ops::get_msix() return value encoding
  PCI: endpoint: Align pci_epc_get_msi(), pci_epc_ops::get_msi() return value encoding
  PCI: cadence-ep: Correct PBA offset in .set_msix() callback
  PCI: dwc: ep: Correct PBA offset in .set_msix() callback
  PCI: endpoint: pci-epf-vntb: Simplify ctrl/SPAD space allocation
  PCI: endpoint: Retain fixed-size BAR size as well as aligned size
parents 014dbfe0 de0321bc
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -220,10 +220,11 @@ static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
	clear_bit(r, &ep->ob_region_map);
}

static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 nr_irqs)
{
	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
	struct cdns_pcie *pcie = &ep->pcie;
	u8 mmc = order_base_2(nr_irqs);
	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
	u16 flags;

@@ -262,7 +263,7 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
	 */
	mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);

	return mme;
	return 1 << mme;
}

static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
@@ -281,12 +282,11 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)

	val &= PCI_MSIX_FLAGS_QSIZE;

	return val;
	return val + 1;
}

static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
				 u16 interrupts, enum pci_barno bir,
				 u32 offset)
				 u16 nr_irqs, enum pci_barno bir, u32 offset)
{
	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
	struct cdns_pcie *pcie = &ep->pcie;
@@ -298,7 +298,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
	reg = cap + PCI_MSIX_FLAGS;
	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
	val &= ~PCI_MSIX_FLAGS_QSIZE;
	val |= interrupts;
	val |= nr_irqs - 1; /* encoded as N-1 */
	cdns_pcie_ep_fn_writew(pcie, fn, reg, val);

	/* Set MSI-X BAR and offset */
@@ -308,7 +308,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,

	/* Set PBA BAR and offset.  BAR must match MSI-X BAR */
	reg = cap + PCI_MSIX_PBA;
	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
	val = (offset + (nr_irqs * PCI_MSIX_ENTRY_SIZE)) | bir;
	cdns_pcie_ep_fn_writel(pcie, fn, reg, val);

	return 0;
+8 −7
Original line number Diff line number Diff line
@@ -532,15 +532,16 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)

	val = FIELD_GET(PCI_MSI_FLAGS_QSIZE, val);

	return val;
	return 1 << val;
}

static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
			      u8 interrupts)
			      u8 nr_irqs)
{
	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
	struct dw_pcie_ep_func *ep_func;
	u8 mmc = order_base_2(nr_irqs);
	u32 val, reg;

	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
@@ -550,7 +551,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
	reg = ep_func->msi_cap + PCI_MSI_FLAGS;
	val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
	val &= ~PCI_MSI_FLAGS_QMASK;
	val |= FIELD_PREP(PCI_MSI_FLAGS_QMASK, interrupts);
	val |= FIELD_PREP(PCI_MSI_FLAGS_QMASK, mmc);
	dw_pcie_dbi_ro_wr_en(pci);
	dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
	dw_pcie_dbi_ro_wr_dis(pci);
@@ -575,11 +576,11 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)

	val &= PCI_MSIX_FLAGS_QSIZE;

	return val;
	return val + 1;
}

static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
			       u16 interrupts, enum pci_barno bir, u32 offset)
			       u16 nr_irqs, enum pci_barno bir, u32 offset)
{
	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -595,7 +596,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
	reg = ep_func->msix_cap + PCI_MSIX_FLAGS;
	val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
	val &= ~PCI_MSIX_FLAGS_QSIZE;
	val |= interrupts;
	val |= nr_irqs - 1; /* encoded as N-1 */
	dw_pcie_writew_dbi(pci, reg, val);

	reg = ep_func->msix_cap + PCI_MSIX_TABLE;
@@ -603,7 +604,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
	dw_pcie_ep_writel_dbi(ep, func_no, reg, val);

	reg = ep_func->msix_cap + PCI_MSIX_PBA;
	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
	val = (offset + (nr_irqs * PCI_MSIX_ENTRY_SIZE)) | bir;
	dw_pcie_ep_writel_dbi(ep, func_no, reg, val);

	dw_pcie_dbi_ro_wr_dis(pci);
+4 −4
Original line number Diff line number Diff line
@@ -256,15 +256,15 @@ static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
	clear_bit(atu_index + 1, ep->ib_window_map);
}

static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
				u8 interrupts)
static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 nr_irqs)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	struct rcar_pcie *pcie = &ep->pcie;
	u8 mmc = order_base_2(nr_irqs);
	u32 flags;

	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
	flags |= interrupts << MSICAP0_MMESCAP_OFFSET;
	flags |= mmc << MSICAP0_MMESCAP_OFFSET;
	rcar_pci_write_reg(pcie, flags, MSICAP(fn));

	return 0;
@@ -280,7 +280,7 @@ static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
	if (!(flags & MSICAP0_MSIE))
		return -EINVAL;

	return ((flags & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
	return 1 << ((flags & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
}

static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
+5 −4
Original line number Diff line number Diff line
@@ -308,10 +308,11 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
}

static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
				    u8 multi_msg_cap)
				    u8 nr_irqs)
{
	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
	struct rockchip_pcie *rockchip = &ep->rockchip;
	u8 mmc = order_base_2(nr_irqs);
	u32 flags;

	flags = rockchip_pcie_read(rockchip,
@@ -319,7 +320,7 @@ static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
				   ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
	flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK;
	flags |=
	   (multi_msg_cap << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
	   (mmc << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
	   (PCI_MSI_FLAGS_64BIT << ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET);
	flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP;
	rockchip_pcie_write(rockchip, flags,
@@ -340,7 +341,7 @@ static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
	if (!(flags & ROCKCHIP_PCIE_EP_MSI_CTRL_ME))
		return -EINVAL;

	return ((flags & ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK) >>
	return 1 << ((flags & ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK) >>
		     ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET);
}

+3 −23
Original line number Diff line number Diff line
@@ -408,11 +408,9 @@ static void epf_ntb_config_spad_bar_free(struct epf_ntb *ntb)
 */
static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
{
	size_t align;
	enum pci_barno barno;
	struct epf_ntb_ctrl *ctrl;
	u32 spad_size, ctrl_size;
	u64 size;
	struct pci_epf *epf = ntb->epf;
	struct device *dev = &epf->dev;
	u32 spad_count;
@@ -422,31 +420,13 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
								epf->func_no,
								epf->vfunc_no);
	barno = ntb->epf_ntb_bar[BAR_CONFIG];
	size = epc_features->bar[barno].fixed_size;
	align = epc_features->align;

	if ((!IS_ALIGNED(size, align)))
		return -EINVAL;

	spad_count = ntb->spad_count;

	ctrl_size = sizeof(struct epf_ntb_ctrl);
	ctrl_size = ALIGN(sizeof(struct epf_ntb_ctrl), sizeof(u32));
	spad_size = 2 * spad_count * sizeof(u32);

	if (!align) {
		ctrl_size = roundup_pow_of_two(ctrl_size);
		spad_size = roundup_pow_of_two(spad_size);
	} else {
		ctrl_size = ALIGN(ctrl_size, align);
		spad_size = ALIGN(spad_size, align);
	}

	if (!size)
		size = ctrl_size + spad_size;
	else if (size < ctrl_size + spad_size)
		return -EINVAL;

	base = pci_epf_alloc_space(epf, size, barno, epc_features, 0);
	base = pci_epf_alloc_space(epf, ctrl_size + spad_size,
				   barno, epc_features, 0);
	if (!base) {
		dev_err(dev, "Config/Status/SPAD alloc region fail\n");
		return -ENOMEM;
Loading