All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
To: linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-arm-kernel@axis.com, lorenzo.pieralisi@arm.com,
	robh@kernel.org, bhelgaas@google.com
Cc: kishon@ti.com, minghuan.Lian@nxp.com, jesper.nilsson@axis.com,
	jingoohan1@gmail.com, gustavo.pimentel@synopsys.com,
	hayashi.kunihiko@socionext.com,
	Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Subject: [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure
Date: Thu,  7 Jan 2021 17:11:21 +0800	[thread overview]
Message-ID: <20210107091123.8616-3-Zhiqiang.Hou@nxp.com> (raw)
In-Reply-To: <20210107091123.8616-1-Zhiqiang.Hou@nxp.com>

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

To avoid multiple calculating of the CFG offset for each function, store
the CFG offset info to the function's represented structure, and only do
one time calculation during the initialization.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 .../pci/controller/dwc/pcie-designware-ep.c   | 138 ++++++++----------
 drivers/pci/controller/dwc/pcie-designware.h  |   1 +
 2 files changed, 59 insertions(+), 80 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index e583700b5ba3..bc6ad1f96a48 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -42,24 +42,23 @@ dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
 
 static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8 func_no)
 {
-	unsigned int func_offset = 0;
-
 	if (ep->ops->func_conf_select)
-		func_offset = ep->ops->func_conf_select(ep, func_no);
+		return ep->ops->func_conf_select(ep, func_no);
 
-	return func_offset;
+	return 0;
 }
 
 static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
 				   enum pci_barno bar, int flags)
 {
 	u32 reg;
-	unsigned int func_offset = 0;
 	struct dw_pcie_ep *ep = &pci->ep;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return;
 
-	reg = func_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
+	reg = func->cfg_off + PCI_BASE_ADDRESS_0 + (4 * bar);
 	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writel_dbi2(pci, reg, 0x0);
 	dw_pcie_writel_dbi(pci, reg, 0x0);
@@ -83,17 +82,15 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
 static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
 		u8 cap_ptr, u8 cap)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
 	u8 cap_id, next_cap_ptr;
 	u16 reg;
 
-	if (!cap_ptr)
+	if (!cap_ptr || !func)
 		return 0;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = dw_pcie_readw_dbi(pci, func_offset + cap_ptr);
+	reg = dw_pcie_readw_dbi(pci, func->cfg_off + cap_ptr);
 	cap_id = (reg & 0x00ff);
 
 	if (cap_id > PCI_CAP_ID_MAX)
@@ -108,14 +105,15 @@ static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
 
 static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
 	u8 next_cap_ptr;
 	u16 reg;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return 0;
 
-	reg = dw_pcie_readw_dbi(pci, func_offset + PCI_CAPABILITY_LIST);
+	reg = dw_pcie_readw_dbi(pci, func->cfg_off + PCI_CAPABILITY_LIST);
 	next_cap_ptr = (reg & 0x00ff);
 
 	return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
@@ -126,23 +124,26 @@ static int dw_pcie_ep_write_header(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);
-	unsigned int func_offset = 0;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
+	u32 cfg_off;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return -EINVAL;
 
+	cfg_off = func->cfg_off;
 	dw_pcie_dbi_ro_wr_en(pci);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_VENDOR_ID, hdr->vendorid);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_DEVICE_ID, hdr->deviceid);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_REVISION_ID, hdr->revid);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_CLASS_PROG, hdr->progif_code);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_CLASS_DEVICE,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_VENDOR_ID, hdr->vendorid);
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_DEVICE_ID, hdr->deviceid);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_REVISION_ID, hdr->revid);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_CLASS_PROG, hdr->progif_code);
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_CLASS_DEVICE,
 			   hdr->subclass_code | hdr->baseclass_code << 8);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_CACHE_LINE_SIZE,
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_CACHE_LINE_SIZE,
 			   hdr->cache_line_size);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_VENDOR_ID,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_SUBSYSTEM_VENDOR_ID,
 			   hdr->subsys_vendor_id);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_ID, hdr->subsys_id);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_INTERRUPT_PIN,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_SUBSYSTEM_ID, hdr->subsys_id);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_INTERRUPT_PIN,
 			   hdr->interrupt_pin);
 	dw_pcie_dbi_ro_wr_dis(pci);
 
@@ -223,12 +224,13 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
 	size_t size = epf_bar->size;
 	int flags = epf_bar->flags;
 	enum dw_pcie_as_type as_type;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 reg;
-	unsigned int func_offset = 0;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return -EINVAL;
 
-	reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
+	reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func->cfg_off;
 
 	if (!(flags & PCI_BASE_ADDRESS_SPACE))
 		as_type = DW_PCIE_AS_MEM;
@@ -309,17 +311,13 @@ static int dw_pcie_ep_get_msi(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);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	if (!(val & PCI_MSI_FLAGS_ENABLE))
 		return -EINVAL;
@@ -333,17 +331,13 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	val &= ~PCI_MSI_FLAGS_QMASK;
 	val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
@@ -358,17 +352,13 @@ 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);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	if (!(val & PCI_MSIX_FLAGS_ENABLE))
 		return -EINVAL;
@@ -383,29 +373,25 @@ 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);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
 	dw_pcie_dbi_ro_wr_en(pci);
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
 	val |= interrupts;
 	dw_pcie_writew_dbi(pci, reg, val);
 
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_TABLE;
 	val = offset | bir;
 	dw_pcie_writel_dbi(pci, reg, val);
 
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_PBA;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_PBA;
 	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
 	dw_pcie_writel_dbi(pci, reg, val);
 
@@ -487,37 +473,33 @@ int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u8 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	struct pci_epc *epc = ep->epc;
 	unsigned int aligned_offset;
-	unsigned int func_offset = 0;
 	u16 msg_ctrl, msg_data;
 	u32 msg_addr_lower, msg_addr_upper, reg;
 	u64 msg_addr;
 	bool has_upper;
 	int ret;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
 	/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	msg_ctrl = dw_pcie_readw_dbi(pci, reg);
 	has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_LO;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_ADDRESS_LO;
 	msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
 	if (has_upper) {
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_HI;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_ADDRESS_HI;
 		msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_64;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_DATA_64;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	} else {
 		msg_addr_upper = 0;
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_32;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_DATA_32;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	}
 	aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1);
@@ -538,12 +520,11 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 				       u16 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	u32 msg_data;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
 	msg_data = (func_no << PCIE_MSIX_DOORBELL_PF_SHIFT) |
@@ -557,11 +538,10 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 			      u16 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	struct pci_epf_msix_tbl *msix_tbl;
 	struct pci_epc *epc = ep->epc;
-	unsigned int func_offset = 0;
 	u32 reg, msg_data, vec_ctrl;
 	unsigned int aligned_offset;
 	u32 tbl_offset;
@@ -569,13 +549,10 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	int ret;
 	u8 bir;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE;
+	reg = func->msix_cap + func->cfg_off + PCI_MSIX_TABLE;
 	tbl_offset = dw_pcie_readl_dbi(pci, reg);
 	bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
 	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
@@ -753,6 +730,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 
 	for (i = 0; i < epc->max_functions; i++) {
 		funcs[i].func_no = i;
+		funcs[i].cfg_off = dw_pcie_ep_func_select(ep, i);
 		funcs[i].msi_cap = dw_pcie_ep_find_capability(ep, i,
 							      PCI_CAP_ID_MSI);
 		funcs[i].msix_cap = dw_pcie_ep_find_capability(ep, i,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 16d239c4d09b..8ee67d4b8109 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -224,6 +224,7 @@ struct dw_pcie_ep_func {
 	u8			func_no;
 	u8			msi_cap;	/* MSI capability offset */
 	u8			msix_cap;	/* MSI-X capability offset */
+	u32			cfg_off;	/* CFG offset from DBI base */
 };
 
 struct dw_pcie_ep {
-- 
2.17.1


WARNING: multiple messages have this Message-ID (diff)
From: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
To: linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-arm-kernel@axis.com, lorenzo.pieralisi@arm.com,
	robh@kernel.org, bhelgaas@google.com
Cc: jesper.nilsson@axis.com, hayashi.kunihiko@socionext.com,
	jingoohan1@gmail.com, Hou Zhiqiang <Zhiqiang.Hou@nxp.com>,
	kishon@ti.com, minghuan.Lian@nxp.com,
	gustavo.pimentel@synopsys.com
Subject: [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure
Date: Thu,  7 Jan 2021 17:11:21 +0800	[thread overview]
Message-ID: <20210107091123.8616-3-Zhiqiang.Hou@nxp.com> (raw)
In-Reply-To: <20210107091123.8616-1-Zhiqiang.Hou@nxp.com>

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

To avoid multiple calculating of the CFG offset for each function, store
the CFG offset info to the function's represented structure, and only do
one time calculation during the initialization.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 .../pci/controller/dwc/pcie-designware-ep.c   | 138 ++++++++----------
 drivers/pci/controller/dwc/pcie-designware.h  |   1 +
 2 files changed, 59 insertions(+), 80 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index e583700b5ba3..bc6ad1f96a48 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -42,24 +42,23 @@ dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
 
 static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8 func_no)
 {
-	unsigned int func_offset = 0;
-
 	if (ep->ops->func_conf_select)
-		func_offset = ep->ops->func_conf_select(ep, func_no);
+		return ep->ops->func_conf_select(ep, func_no);
 
-	return func_offset;
+	return 0;
 }
 
 static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
 				   enum pci_barno bar, int flags)
 {
 	u32 reg;
-	unsigned int func_offset = 0;
 	struct dw_pcie_ep *ep = &pci->ep;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return;
 
-	reg = func_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
+	reg = func->cfg_off + PCI_BASE_ADDRESS_0 + (4 * bar);
 	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writel_dbi2(pci, reg, 0x0);
 	dw_pcie_writel_dbi(pci, reg, 0x0);
@@ -83,17 +82,15 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
 static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
 		u8 cap_ptr, u8 cap)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
 	u8 cap_id, next_cap_ptr;
 	u16 reg;
 
-	if (!cap_ptr)
+	if (!cap_ptr || !func)
 		return 0;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = dw_pcie_readw_dbi(pci, func_offset + cap_ptr);
+	reg = dw_pcie_readw_dbi(pci, func->cfg_off + cap_ptr);
 	cap_id = (reg & 0x00ff);
 
 	if (cap_id > PCI_CAP_ID_MAX)
@@ -108,14 +105,15 @@ static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
 
 static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
 	u8 next_cap_ptr;
 	u16 reg;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return 0;
 
-	reg = dw_pcie_readw_dbi(pci, func_offset + PCI_CAPABILITY_LIST);
+	reg = dw_pcie_readw_dbi(pci, func->cfg_off + PCI_CAPABILITY_LIST);
 	next_cap_ptr = (reg & 0x00ff);
 
 	return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
@@ -126,23 +124,26 @@ static int dw_pcie_ep_write_header(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);
-	unsigned int func_offset = 0;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
+	u32 cfg_off;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return -EINVAL;
 
+	cfg_off = func->cfg_off;
 	dw_pcie_dbi_ro_wr_en(pci);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_VENDOR_ID, hdr->vendorid);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_DEVICE_ID, hdr->deviceid);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_REVISION_ID, hdr->revid);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_CLASS_PROG, hdr->progif_code);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_CLASS_DEVICE,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_VENDOR_ID, hdr->vendorid);
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_DEVICE_ID, hdr->deviceid);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_REVISION_ID, hdr->revid);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_CLASS_PROG, hdr->progif_code);
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_CLASS_DEVICE,
 			   hdr->subclass_code | hdr->baseclass_code << 8);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_CACHE_LINE_SIZE,
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_CACHE_LINE_SIZE,
 			   hdr->cache_line_size);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_VENDOR_ID,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_SUBSYSTEM_VENDOR_ID,
 			   hdr->subsys_vendor_id);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_ID, hdr->subsys_id);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_INTERRUPT_PIN,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_SUBSYSTEM_ID, hdr->subsys_id);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_INTERRUPT_PIN,
 			   hdr->interrupt_pin);
 	dw_pcie_dbi_ro_wr_dis(pci);
 
@@ -223,12 +224,13 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
 	size_t size = epf_bar->size;
 	int flags = epf_bar->flags;
 	enum dw_pcie_as_type as_type;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 reg;
-	unsigned int func_offset = 0;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return -EINVAL;
 
-	reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
+	reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func->cfg_off;
 
 	if (!(flags & PCI_BASE_ADDRESS_SPACE))
 		as_type = DW_PCIE_AS_MEM;
@@ -309,17 +311,13 @@ static int dw_pcie_ep_get_msi(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);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	if (!(val & PCI_MSI_FLAGS_ENABLE))
 		return -EINVAL;
@@ -333,17 +331,13 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	val &= ~PCI_MSI_FLAGS_QMASK;
 	val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
@@ -358,17 +352,13 @@ 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);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	if (!(val & PCI_MSIX_FLAGS_ENABLE))
 		return -EINVAL;
@@ -383,29 +373,25 @@ 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);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
 	dw_pcie_dbi_ro_wr_en(pci);
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
 	val |= interrupts;
 	dw_pcie_writew_dbi(pci, reg, val);
 
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_TABLE;
 	val = offset | bir;
 	dw_pcie_writel_dbi(pci, reg, val);
 
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_PBA;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_PBA;
 	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
 	dw_pcie_writel_dbi(pci, reg, val);
 
@@ -487,37 +473,33 @@ int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u8 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	struct pci_epc *epc = ep->epc;
 	unsigned int aligned_offset;
-	unsigned int func_offset = 0;
 	u16 msg_ctrl, msg_data;
 	u32 msg_addr_lower, msg_addr_upper, reg;
 	u64 msg_addr;
 	bool has_upper;
 	int ret;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
 	/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	msg_ctrl = dw_pcie_readw_dbi(pci, reg);
 	has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_LO;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_ADDRESS_LO;
 	msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
 	if (has_upper) {
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_HI;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_ADDRESS_HI;
 		msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_64;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_DATA_64;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	} else {
 		msg_addr_upper = 0;
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_32;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_DATA_32;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	}
 	aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1);
@@ -538,12 +520,11 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 				       u16 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	u32 msg_data;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
 	msg_data = (func_no << PCIE_MSIX_DOORBELL_PF_SHIFT) |
@@ -557,11 +538,10 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 			      u16 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	struct pci_epf_msix_tbl *msix_tbl;
 	struct pci_epc *epc = ep->epc;
-	unsigned int func_offset = 0;
 	u32 reg, msg_data, vec_ctrl;
 	unsigned int aligned_offset;
 	u32 tbl_offset;
@@ -569,13 +549,10 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	int ret;
 	u8 bir;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE;
+	reg = func->msix_cap + func->cfg_off + PCI_MSIX_TABLE;
 	tbl_offset = dw_pcie_readl_dbi(pci, reg);
 	bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
 	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
@@ -753,6 +730,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 
 	for (i = 0; i < epc->max_functions; i++) {
 		funcs[i].func_no = i;
+		funcs[i].cfg_off = dw_pcie_ep_func_select(ep, i);
 		funcs[i].msi_cap = dw_pcie_ep_find_capability(ep, i,
 							      PCI_CAP_ID_MSI);
 		funcs[i].msix_cap = dw_pcie_ep_find_capability(ep, i,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 16d239c4d09b..8ee67d4b8109 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -224,6 +224,7 @@ struct dw_pcie_ep_func {
 	u8			func_no;
 	u8			msi_cap;	/* MSI capability offset */
 	u8			msix_cap;	/* MSI-X capability offset */
+	u32			cfg_off;	/* CFG offset from DBI base */
 };
 
 struct dw_pcie_ep {
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2021-01-07  9:04 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
2021-01-07  9:11 ` Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 1/4] PCI: dwc: Change to use an array to store the structure of functions Zhiqiang Hou
2021-01-07  9:11   ` Zhiqiang Hou
2021-01-07  9:11 ` Zhiqiang Hou [this message]
2021-01-07  9:11   ` [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 3/4] PCI: dwc: Rename callback function func_conf_select and its instance Zhiqiang Hou
2021-01-07  9:11   ` Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 4/4] PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar() Zhiqiang Hou
2021-01-07  9:11   ` Zhiqiang Hou
2021-04-06  9:03 ` [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Z.q. Hou
2021-04-06  9:03   ` Z.q. Hou

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=20210107091123.8616-3-Zhiqiang.Hou@nxp.com \
    --to=zhiqiang.hou@nxp.com \
    --cc=bhelgaas@google.com \
    --cc=gustavo.pimentel@synopsys.com \
    --cc=hayashi.kunihiko@socionext.com \
    --cc=jesper.nilsson@axis.com \
    --cc=jingoohan1@gmail.com \
    --cc=kishon@ti.com \
    --cc=linux-arm-kernel@axis.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=minghuan.Lian@nxp.com \
    --cc=robh@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.