From: Hou Zhiqiang <zhiqiang....@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....@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

Reply via email to