summaryrefslogtreecommitdiff
path: root/drivers/pci/controller/dwc/pcie-designware-ep.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2023-10-28 13:31:01 -0500
committerBjorn Helgaas <bhelgaas@google.com>2023-10-28 13:31:01 -0500
commitdb20113d702e4f44d614676a967d0f74013fd25b (patch)
tree56638b19dd8676f2274e28c60aa96edcd9d79ce3 /drivers/pci/controller/dwc/pcie-designware-ep.c
parenteecffeb045738b0214219c3ad44cd0502836efdf (diff)
parent6c4b39937f4e65688ea294725ae432b2565821ff (diff)
Merge branch 'pci/controller/rcar'
- Add generic T_PVPERL macro for the required interval between power being stable and PERST# being inactive (Yoshihiro Shimoda) - Factor out dw_pcie_link_set_max_link_width() (Yoshihiro Shimoda) - Update PCI_EXP_LNKCAP_MLW so Link Capabilities shows the correct max link width (Yoshihiro Shimoda) - Drop tegra194 PCI_EXP_LNKCAP_MLW setting since dw_pcie_setup() already does it (Yoshihiro Shimoda) - Add dwc support for different dbi and dbi2 register offsets, to be used for R-Car Gen4 controllers (Yoshihiro Shimoda) - Add EDMA_UNROLL capability flag for R-Car Gen4 controllers that don't correctly advertise unrolled mapping via their eDMA CTRL register (Yoshihiro Shimoda) - Export dw_pcie_ep_exit() for use by the modular R-Car Gen4 driver (Yoshihiro Shimoda) - Add .pre_init() and .deinit() hooks for use by R-Car Gen4 controllers (Yoshihiro Shimoda) - Increase snps,dw-pcie DT reg and reg-names maxItems for R-Car Gen4 controllers (Yoshihiro Shimoda) - Add rcar-gen4-pci host and endpoint DT bindings and drivers (Yoshihiro Shimoda) - Add Renesas R8A779F0 Device ID to pci_endpoint_test to allow testing on R-Car S4-8 (Yoshihiro Shimoda) * pci/controller/rcar: misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller MAINTAINERS: Update PCI DRIVER FOR RENESAS R-CAR for R-Car Gen4 PCI: rcar-gen4: Add endpoint mode support PCI: rcar-gen4: Add R-Car Gen4 PCIe controller support for host mode dt-bindings: PCI: renesas: Add R-Car Gen4 PCIe Endpoint dt-bindings: PCI: renesas: Add R-Car Gen4 PCIe Host dt-bindings: PCI: dwc: Update maxItems of reg and reg-names PCI: dwc: endpoint: Introduce .pre_init() and .deinit() PCI: dwc: Expose dw_pcie_write_dbi2() to module PCI: dwc: Expose dw_pcie_ep_exit() to module PCI: dwc: Add EDMA_UNROLL capability flag PCI: dwc: endpoint: Add multiple PFs support for dbi2 PCI: tegra194: Drop PCI_EXP_LNKSTA_NLW setting PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling PCI: dwc: Add dw_pcie_link_set_max_link_width() PCI: Add T_PVPERL macro
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-designware-ep.c')
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-ep.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index f9182f8d552f..d34a5e87ad18 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -52,21 +52,35 @@ static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8 func_no)
return func_offset;
}
+static unsigned int dw_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep, u8 func_no)
+{
+ unsigned int dbi2_offset = 0;
+
+ if (ep->ops->get_dbi2_offset)
+ dbi2_offset = ep->ops->get_dbi2_offset(ep, func_no);
+ else if (ep->ops->func_conf_select) /* for backward compatibility */
+ dbi2_offset = ep->ops->func_conf_select(ep, func_no);
+
+ return dbi2_offset;
+}
+
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;
+ unsigned int func_offset, dbi2_offset;
struct dw_pcie_ep *ep = &pci->ep;
+ u32 reg, reg_dbi2;
func_offset = dw_pcie_ep_func_select(ep, func_no);
+ dbi2_offset = dw_pcie_ep_get_dbi2_offset(ep, func_no);
reg = func_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
+ reg_dbi2 = dbi2_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
dw_pcie_dbi_ro_wr_en(pci);
- dw_pcie_writel_dbi2(pci, reg, 0x0);
+ dw_pcie_writel_dbi2(pci, reg_dbi2, 0x0);
dw_pcie_writel_dbi(pci, reg, 0x0);
if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
- dw_pcie_writel_dbi2(pci, reg + 4, 0x0);
+ dw_pcie_writel_dbi2(pci, reg_dbi2 + 4, 0x0);
dw_pcie_writel_dbi(pci, reg + 4, 0x0);
}
dw_pcie_dbi_ro_wr_dis(pci);
@@ -228,16 +242,18 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
{
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ unsigned int func_offset, dbi2_offset;
enum pci_barno bar = epf_bar->barno;
size_t size = epf_bar->size;
int flags = epf_bar->flags;
- unsigned int func_offset = 0;
+ u32 reg, reg_dbi2;
int ret, type;
- u32 reg;
func_offset = dw_pcie_ep_func_select(ep, func_no);
+ dbi2_offset = dw_pcie_ep_get_dbi2_offset(ep, func_no);
reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
+ reg_dbi2 = PCI_BASE_ADDRESS_0 + (4 * bar) + dbi2_offset;
if (!(flags & PCI_BASE_ADDRESS_SPACE))
type = PCIE_ATU_TYPE_MEM;
@@ -253,11 +269,11 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
dw_pcie_dbi_ro_wr_en(pci);
- dw_pcie_writel_dbi2(pci, reg, lower_32_bits(size - 1));
+ dw_pcie_writel_dbi2(pci, reg_dbi2, lower_32_bits(size - 1));
dw_pcie_writel_dbi(pci, reg, flags);
if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
- dw_pcie_writel_dbi2(pci, reg + 4, upper_32_bits(size - 1));
+ dw_pcie_writel_dbi2(pci, reg_dbi2 + 4, upper_32_bits(size - 1));
dw_pcie_writel_dbi(pci, reg + 4, 0);
}
@@ -621,7 +637,11 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
epc->mem->window.page_size);
pci_epc_mem_exit(epc);
+
+ if (ep->ops->deinit)
+ ep->ops->deinit(ep);
}
+EXPORT_SYMBOL_GPL(dw_pcie_ep_exit);
static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
{
@@ -723,6 +743,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
ep->phys_base = res->start;
ep->addr_size = resource_size(res);
+ if (ep->ops->pre_init)
+ ep->ops->pre_init(ep);
+
dw_pcie_version_detect(pci);
dw_pcie_iatu_detect(pci);
@@ -777,7 +800,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
ep->page_size);
if (ret < 0) {
dev_err(dev, "Failed to initialize address space\n");
- return ret;
+ goto err_ep_deinit;
}
ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
@@ -814,6 +837,10 @@ err_free_epc_mem:
err_exit_epc_mem:
pci_epc_mem_exit(epc);
+err_ep_deinit:
+ if (ep->ops->deinit)
+ ep->ops->deinit(ep);
+
return ret;
}
EXPORT_SYMBOL_GPL(dw_pcie_ep_init);