linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kishon Vijay Abraham I <kishon@ti.com>
To: Gustavo Pimentel <gustavo.pimentel@synopsys.com>,
	<bhelgaas@google.com>, <lorenzo.pieralisi@arm.com>,
	<Joao.Pinto@synopsys.com>, <jingoohan1@gmail.com>,
	<adouglas@cadence.com>, <jesper.nilsson@axis.com>,
	<shawn.lin@rock-chips.com>
Cc: <linux-pci@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v9 04/12] PCI: dwc: Add MSI-X callbacks handler
Date: Fri, 13 Jul 2018 13:25:06 +0530	[thread overview]
Message-ID: <b1db283e-b9db-a8c4-409c-d9dc64805c94@ti.com> (raw)
In-Reply-To: <5e4ca8380a65da72cf5d3ab46588948e3537aeae.1531155252.git.gustavo.pimentel@synopsys.com>

Hi,

On Monday 09 July 2018 11:12 PM, Gustavo Pimentel wrote:
> Add PCIe config space capability search function.
> 
> Add sysfs set/get interface to allow the change of EP MSI-X maximum number.
> 
> Add EP MSI-X callback for triggering interruptions.
> 
> Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
> ---
> Change v1->v2:
>  - Nothing changed, just to follow the patch set version.
> Change v2->v3:
>  - Moved dra7xx_pcie_raise_irq() signature change to patch file #3.
>  - Moved artpec6_pcie_raise_irq() signature change to patch file #3.
>  - Replaced wrong return value 0 to -EINVAL.
>  - Removed an else if by code refactoring.
>  - Reduced the size of ioremap_nocache mapping from ep->addr_size to
> PCI_MSIX_ENTRY_SIZE.
>  - Fixed a small bug. If the MSI-X vector bit has been set, the function
> would return without executing the proper unmap.
> Change v3->v4:
>  - Rebased to Lorenzo's master branch v4.18-rc1.
>  - Added static prefix to __dw_pcie_ep_find_next_cap function.
> Change v4->v5:
>  - Added static prefix to dw_pcie_ep_find_capability function.
>  - Swap patch files position (#2 <-> #3).
>  - Moved dw_pcie_ep_raise_irq and dw_plat_pcie_ep_raise_irq functions
> signatures change to patch file #2.
> Change v5->v6:
>  - Nothing changed, just to follow the patch set version.
> Change v6->v7:
>  - Nothing changed, just to follow the patch set version.
> Change v7->v8:
>  - Re-sending the patch series.
> Change v8->v9:
>  - Nothing changed, just to follow the patch set version.
> 
>  drivers/pci/controller/dwc/pcie-designware-ep.c   | 144 ++++++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-designware-plat.c |   2 +
>  drivers/pci/controller/dwc/pcie-designware.h      |  12 ++
>  3 files changed, 158 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 69d039d..72c4188 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -40,6 +40,39 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
>  	__dw_pcie_ep_reset_bar(pci, bar, 0);
>  }
>  
> +static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
> +			      u8 cap)
> +{
> +	u8 cap_id, next_cap_ptr;
> +	u16 reg;
> +
> +	reg = dw_pcie_readw_dbi(pci, cap_ptr);
> +	next_cap_ptr = (reg & 0xff00) >> 8;
> +	cap_id = (reg & 0x00ff);
> +
> +	if (!next_cap_ptr || cap_id > PCI_CAP_ID_MAX)
> +		return 0;
> +
> +	if (cap_id == cap)
> +		return cap_ptr;
> +
> +	return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
> +}
> +
> +static u8 dw_pcie_ep_find_capability(struct dw_pcie *pci, u8 cap)
> +{
> +	u8 next_cap_ptr;
> +	u16 reg;
> +
> +	reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
> +	next_cap_ptr = (reg & 0x00ff);
> +
> +	if (!next_cap_ptr)
> +		return 0;
> +
> +	return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
> +}
> +
>  static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
>  				   struct pci_epf_header *hdr)
>  {
> @@ -241,6 +274,45 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
>  	return 0;
>  }
>  
> +static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
> +{
> +	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +	u32 val, reg;
> +
> +	if (!ep->msix_cap)
> +		return -EINVAL;
> +
> +	reg = ep->msix_cap + PCI_MSIX_FLAGS;
> +	val = dw_pcie_readw_dbi(pci, reg);
> +	if (!(val & PCI_MSIX_FLAGS_ENABLE))
> +		return -EINVAL;
> +
> +	val &= PCI_MSIX_FLAGS_QSIZE;
> +
> +	return val;
> +}
> +
> +static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
> +{
> +	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +	u32 val, reg;
> +
> +	if (!ep->msix_cap)
> +		return -EINVAL;
> +
> +	reg = ep->msix_cap + PCI_MSIX_FLAGS;
> +	val = dw_pcie_readw_dbi(pci, reg);
> +	val &= ~PCI_MSIX_FLAGS_QSIZE;
> +	val |= interrupts;
> +	dw_pcie_dbi_ro_wr_en(pci);
> +	dw_pcie_writew_dbi(pci, reg, val);
> +	dw_pcie_dbi_ro_wr_dis(pci);
> +
> +	return 0;
> +}
> +
>  static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
>  				enum pci_epc_irq_type type, u16 interrupt_num)
>  {
> @@ -282,6 +354,8 @@ static const struct pci_epc_ops epc_ops = {
>  	.unmap_addr		= dw_pcie_ep_unmap_addr,
>  	.set_msi		= dw_pcie_ep_set_msi,
>  	.get_msi		= dw_pcie_ep_get_msi,
> +	.set_msix		= dw_pcie_ep_set_msix,
> +	.get_msix		= dw_pcie_ep_get_msix,
>  	.raise_irq		= dw_pcie_ep_raise_irq,
>  	.start			= dw_pcie_ep_start,
>  	.stop			= dw_pcie_ep_stop,
> @@ -322,6 +396,64 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	return 0;
>  }
>  
> +int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> +			     u16 interrupt_num)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +	struct pci_epc *epc = ep->epc;
> +	u16 tbl_offset, bir;
> +	u32 bar_addr_upper, bar_addr_lower;
> +	u32 msg_addr_upper, msg_addr_lower;
> +	u32 reg, msg_data, vec_ctrl;
> +	u64 tbl_addr, msg_addr, reg_u64;
> +	void __iomem *msix_tbl;
> +	int ret;
> +
> +	reg = ep->msix_cap + PCI_MSIX_TABLE;
> +	tbl_offset = dw_pcie_readl_dbi(pci, reg);
> +	bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
> +	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
> +	tbl_offset >>= 3;
> +
> +	reg = PCI_BASE_ADDRESS_0 + (4 * bir);
> +	bar_addr_upper = 0;
> +	bar_addr_lower = dw_pcie_readl_dbi(pci, reg);
> +	reg_u64 = (bar_addr_lower & PCI_BASE_ADDRESS_MEM_TYPE_MASK);
> +	if (reg_u64 == PCI_BASE_ADDRESS_MEM_TYPE_64)
> +		bar_addr_upper = dw_pcie_readl_dbi(pci, reg + 4);
> +
> +	tbl_addr = ((u64) bar_addr_upper) << 32 | bar_addr_lower;
> +	tbl_addr += (tbl_offset + ((interrupt_num - 1) * PCI_MSIX_ENTRY_SIZE));
> +	tbl_addr &= PCI_BASE_ADDRESS_MEM_MASK;
> +
> +	msix_tbl = ioremap_nocache(ep->phys_base + tbl_addr,
> +				   PCI_MSIX_ENTRY_SIZE);
> +	if (!msix_tbl)
> +		return -EINVAL;
> +
> +	msg_addr_lower = readl(msix_tbl + PCI_MSIX_ENTRY_LOWER_ADDR);
> +	msg_addr_upper = readl(msix_tbl + PCI_MSIX_ENTRY_UPPER_ADDR);
> +	msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
> +	msg_data = readl(msix_tbl + PCI_MSIX_ENTRY_DATA);
> +	vec_ctrl = readl(msix_tbl + PCI_MSIX_ENTRY_VECTOR_CTRL);
> +
> +	iounmap(msix_tbl);
> +
> +	if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)
> +		return -EPERM;
> +
> +	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msix_mem_phys, msg_addr,
> +				  epc->mem->page_size);
> +	if (ret)
> +		return ret;
> +
> +	writel(msg_data, ep->msix_mem);
> +
> +	dw_pcie_ep_unmap_addr(epc, func_no, ep->msix_mem_phys);
> +
> +	return 0;
> +}
> +
>  void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
>  {
>  	struct pci_epc *epc = ep->epc;
> @@ -329,6 +461,9 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
>  	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
>  			      epc->mem->page_size);
>  
> +	pci_epc_mem_free_addr(epc, ep->msix_mem_phys, ep->msix_mem,
> +			      epc->mem->page_size);
> +
>  	pci_epc_mem_exit(epc);
>  }
>  
> @@ -415,6 +550,15 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  		dev_err(dev, "Failed to reserve memory for MSI\n");
>  		return -ENOMEM;
>  	}
> +	ep->msi_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSI);
> +
> +	ep->msix_mem = pci_epc_mem_alloc_addr(epc, &ep->msix_mem_phys,
> +					     epc->mem->page_size);
> +	if (!ep->msix_mem) {
> +		dev_err(dev, "Failed to reserve memory for MSI-X\n");
> +		return -ENOMEM;

Do we have to allocate memory for MSIX memory separately? I think we can reuse
msi_mem. That's also because we shouldn't fail if a platform doesn't support
MSIX and fails to allocate msix_mem.

Thanks
Kishon

  reply	other threads:[~2018-07-13  8:08 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-09 17:42 [PATCH v9 00/12] Add MSI-X support on pcitest tool Gustavo Pimentel
2018-07-09 17:42 ` [PATCH v9 01/12] PCI: dwc: Fix EP link notification implementation Gustavo Pimentel
2018-07-13  7:47   ` Kishon Vijay Abraham I
2018-07-09 17:42 ` [PATCH v9 02/12] PCI: endpoint: Add MSI-X interfaces Gustavo Pimentel
2018-07-09 17:42 ` [PATCH v9 03/12] PCI: Update xxx_pcie_ep_raise_irq() and pci_epc_raise_irq() signatures Gustavo Pimentel
2018-07-13  7:49   ` Kishon Vijay Abraham I
2018-07-09 17:42 ` [PATCH v9 04/12] PCI: dwc: Add MSI-X callbacks handler Gustavo Pimentel
2018-07-13  7:55   ` Kishon Vijay Abraham I [this message]
2018-07-13 15:55     ` Gustavo Pimentel
2018-07-09 17:42 ` [PATCH v9 05/12] PCI: dwc: Rework MSI " Gustavo Pimentel
2018-07-13  7:55   ` Kishon Vijay Abraham I
2018-07-09 17:42 ` [PATCH v9 06/12] PCI: dwc: Add legacy interrupt callback handler Gustavo Pimentel
2018-07-09 17:42 ` [PATCH v9 07/12] pci-epf-test/pci_endpoint_test: Cleanup PCI_ENDPOINT_TEST memspace Gustavo Pimentel
2018-07-13  7:59   ` Kishon Vijay Abraham I
2018-07-09 17:42 ` [PATCH v9 08/12] pci-epf-test/pci_endpoint_test: Use irq_type module parameter Gustavo Pimentel
2018-07-13  8:00   ` Kishon Vijay Abraham I
2018-07-09 17:42 ` [PATCH v9 09/12] pci-epf-test/pci_endpoint_test: Add MSI-X support Gustavo Pimentel
2018-07-13  8:08   ` Kishon Vijay Abraham I
2018-07-09 17:42 ` [PATCH v9 10/12] pci_endpoint_test: Add 2 ioctl commands Gustavo Pimentel
2018-07-10 10:10   ` Alan Douglas
2018-07-10 10:35     ` Gustavo Pimentel
2018-07-09 17:42 ` [PATCH v9 11/12] tools: PCI: Add MSI-X support Gustavo Pimentel
2018-07-09 17:42 ` [PATCH v9 12/12] PCI: endpoint: Add MSI set maximum restriction Gustavo Pimentel
2018-07-13 13:25 ` [PATCH v9 00/12] Add MSI-X support on pcitest tool Lorenzo Pieralisi
2018-07-13 15:59   ` Gustavo Pimentel
2018-07-16  4:07     ` Kishon Vijay Abraham I
2018-07-16 14:49       ` Gustavo Pimentel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b1db283e-b9db-a8c4-409c-d9dc64805c94@ti.com \
    --to=kishon@ti.com \
    --cc=Joao.Pinto@synopsys.com \
    --cc=adouglas@cadence.com \
    --cc=bhelgaas@google.com \
    --cc=gustavo.pimentel@synopsys.com \
    --cc=jesper.nilsson@axis.com \
    --cc=jingoohan1@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=shawn.lin@rock-chips.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).