Lines Matching +full:pcie +full:- +full:ep

1 // SPDX-License-Identifier: GPL-2.0
3 // Cadence PCIe endpoint controller driver.
4 // Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
11 #include <linux/pci-epc.h>
15 #include "pcie-cadence.h"
22 static u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn) in cdns_pcie_get_fn_from_vfn() argument
30 cap = cdns_pcie_find_ext_capability(pcie, PCI_EXT_CAP_ID_SRIOV); in cdns_pcie_get_fn_from_vfn()
31 first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET); in cdns_pcie_get_fn_from_vfn()
32 stride = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_STRIDE); in cdns_pcie_get_fn_from_vfn()
33 fn = fn + first_vf_offset + ((vfn - 1) * stride); in cdns_pcie_get_fn_from_vfn()
41 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_write_header() local
42 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_write_header() local
46 cap = cdns_pcie_find_ext_capability(pcie, PCI_EXT_CAP_ID_SRIOV); in cdns_pcie_ep_write_header()
48 dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n"); in cdns_pcie_ep_write_header()
49 return -EINVAL; in cdns_pcie_ep_write_header()
52 cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid); in cdns_pcie_ep_write_header()
56 cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid); in cdns_pcie_ep_write_header()
57 cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid); in cdns_pcie_ep_write_header()
58 cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CLASS_PROG, hdr->progif_code); in cdns_pcie_ep_write_header()
59 cdns_pcie_ep_fn_writew(pcie, fn, PCI_CLASS_DEVICE, in cdns_pcie_ep_write_header()
60 hdr->subclass_code | hdr->baseclass_code << 8); in cdns_pcie_ep_write_header()
61 cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CACHE_LINE_SIZE, in cdns_pcie_ep_write_header()
62 hdr->cache_line_size); in cdns_pcie_ep_write_header()
63 cdns_pcie_ep_fn_writew(pcie, fn, PCI_SUBSYSTEM_ID, hdr->subsys_id); in cdns_pcie_ep_write_header()
64 cdns_pcie_ep_fn_writeb(pcie, fn, PCI_INTERRUPT_PIN, hdr->interrupt_pin); in cdns_pcie_ep_write_header()
72 u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) | in cdns_pcie_ep_write_header()
73 CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id); in cdns_pcie_ep_write_header()
75 cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id); in cdns_pcie_ep_write_header()
84 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_set_bar() local
85 struct cdns_pcie_epf *epf = &ep->epf[fn]; in cdns_pcie_ep_set_bar()
86 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_set_bar() local
87 dma_addr_t bar_phys = epf_bar->phys_addr; in cdns_pcie_ep_set_bar()
88 enum pci_barno bar = epf_bar->barno; in cdns_pcie_ep_set_bar()
89 int flags = epf_bar->flags; in cdns_pcie_ep_set_bar()
94 sz = max_t(size_t, epf_bar->size, CDNS_PCIE_EP_MIN_APERTURE); in cdns_pcie_ep_set_bar()
99 sz = 1ULL << fls64(sz - 1); in cdns_pcie_ep_set_bar()
100 aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */ in cdns_pcie_ep_set_bar()
109 return -EINVAL; in cdns_pcie_ep_set_bar()
128 b = (bar < BAR_4) ? bar : bar - BAR_4; in cdns_pcie_ep_set_bar()
131 cfg = cdns_pcie_readl(pcie, reg); in cdns_pcie_ep_set_bar()
136 cdns_pcie_writel(pcie, reg, cfg); in cdns_pcie_ep_set_bar()
139 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_set_bar()
140 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), in cdns_pcie_ep_set_bar()
142 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), in cdns_pcie_ep_set_bar()
146 epf = &epf->epf[vfn - 1]; in cdns_pcie_ep_set_bar()
147 epf->epf_bar[bar] = epf_bar; in cdns_pcie_ep_set_bar()
155 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_clear_bar() local
156 struct cdns_pcie_epf *epf = &ep->epf[fn]; in cdns_pcie_ep_clear_bar()
157 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_clear_bar() local
158 enum pci_barno bar = epf_bar->barno; in cdns_pcie_ep_clear_bar()
165 b = (bar < BAR_4) ? bar : bar - BAR_4; in cdns_pcie_ep_clear_bar()
169 cfg = cdns_pcie_readl(pcie, reg); in cdns_pcie_ep_clear_bar()
173 cdns_pcie_writel(pcie, reg, cfg); in cdns_pcie_ep_clear_bar()
176 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_clear_bar()
177 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0); in cdns_pcie_ep_clear_bar()
178 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0); in cdns_pcie_ep_clear_bar()
181 epf = &epf->epf[vfn - 1]; in cdns_pcie_ep_clear_bar()
182 epf->epf_bar[bar] = NULL; in cdns_pcie_ep_clear_bar()
188 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_map_addr() local
189 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_map_addr() local
192 r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG); in cdns_pcie_ep_map_addr()
193 if (r >= ep->max_regions - 1) { in cdns_pcie_ep_map_addr()
194 dev_err(&epc->dev, "no free outbound region\n"); in cdns_pcie_ep_map_addr()
195 return -EINVAL; in cdns_pcie_ep_map_addr()
198 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_map_addr()
199 cdns_pcie_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size); in cdns_pcie_ep_map_addr()
201 set_bit(r, &ep->ob_region_map); in cdns_pcie_ep_map_addr()
202 ep->ob_addr[r] = addr; in cdns_pcie_ep_map_addr()
210 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_unmap_addr() local
211 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_unmap_addr() local
214 for (r = 0; r < ep->max_regions - 1; r++) in cdns_pcie_ep_unmap_addr()
215 if (ep->ob_addr[r] == addr) in cdns_pcie_ep_unmap_addr()
218 if (r == ep->max_regions - 1) in cdns_pcie_ep_unmap_addr()
221 cdns_pcie_reset_outbound_region(pcie, r); in cdns_pcie_ep_unmap_addr()
223 ep->ob_addr[r] = 0; in cdns_pcie_ep_unmap_addr()
224 clear_bit(r, &ep->ob_region_map); in cdns_pcie_ep_unmap_addr()
229 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_set_msi() local
230 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_set_msi() local
235 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI); in cdns_pcie_ep_set_msi()
236 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_set_msi()
242 flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS); in cdns_pcie_ep_set_msi()
246 cdns_pcie_ep_fn_writew(pcie, fn, cap + PCI_MSI_FLAGS, flags); in cdns_pcie_ep_set_msi()
253 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_get_msi() local
254 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_get_msi() local
258 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); in cdns_pcie_ep_get_msi()
259 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_get_msi()
262 flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS); in cdns_pcie_ep_get_msi()
264 return -EINVAL; in cdns_pcie_ep_get_msi()
277 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_get_msix() local
278 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_get_msix() local
282 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); in cdns_pcie_ep_get_msix()
283 func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no); in cdns_pcie_ep_get_msix()
286 val = cdns_pcie_ep_fn_readw(pcie, func_no, reg); in cdns_pcie_ep_get_msix()
288 return -EINVAL; in cdns_pcie_ep_get_msix()
298 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_set_msix() local
299 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_set_msix() local
303 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); in cdns_pcie_ep_set_msix()
304 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_set_msix()
307 val = cdns_pcie_ep_fn_readw(pcie, fn, reg); in cdns_pcie_ep_set_msix()
309 val |= nr_irqs - 1; /* encoded as N-1 */ in cdns_pcie_ep_set_msix()
310 cdns_pcie_ep_fn_writew(pcie, fn, reg, val); in cdns_pcie_ep_set_msix()
312 /* Set MSI-X BAR and offset */ in cdns_pcie_ep_set_msix()
315 cdns_pcie_ep_fn_writel(pcie, fn, reg, val); in cdns_pcie_ep_set_msix()
317 /* Set PBA BAR and offset. BAR must match MSI-X BAR */ in cdns_pcie_ep_set_msix()
320 cdns_pcie_ep_fn_writel(pcie, fn, reg, val); in cdns_pcie_ep_set_msix()
325 static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx, in cdns_pcie_ep_assert_intx() argument
328 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_assert_intx() local
337 if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY || in cdns_pcie_ep_assert_intx()
338 ep->irq_pci_fn != fn)) { in cdns_pcie_ep_assert_intx()
340 cdns_pcie_set_outbound_region_for_normal_msg(pcie, 0, fn, 0, in cdns_pcie_ep_assert_intx()
341 ep->irq_phys_addr); in cdns_pcie_ep_assert_intx()
342 ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY; in cdns_pcie_ep_assert_intx()
343 ep->irq_pci_fn = fn; in cdns_pcie_ep_assert_intx()
347 ep->irq_pending |= BIT(intx); in cdns_pcie_ep_assert_intx()
350 ep->irq_pending &= ~BIT(intx); in cdns_pcie_ep_assert_intx()
354 spin_lock_irqsave(&ep->lock, flags); in cdns_pcie_ep_assert_intx()
355 status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS); in cdns_pcie_ep_assert_intx()
356 if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) { in cdns_pcie_ep_assert_intx()
358 cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status); in cdns_pcie_ep_assert_intx()
360 spin_unlock_irqrestore(&ep->lock, flags); in cdns_pcie_ep_assert_intx()
364 writel(0, ep->irq_cpu_addr + offset); in cdns_pcie_ep_assert_intx()
367 static int cdns_pcie_ep_send_intx_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn, in cdns_pcie_ep_send_intx_irq() argument
372 cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND); in cdns_pcie_ep_send_intx_irq()
374 return -EINVAL; in cdns_pcie_ep_send_intx_irq()
376 cdns_pcie_ep_assert_intx(ep, fn, intx, true); in cdns_pcie_ep_send_intx_irq()
381 cdns_pcie_ep_assert_intx(ep, fn, intx, false); in cdns_pcie_ep_send_intx_irq()
385 static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn, in cdns_pcie_ep_send_msi_irq() argument
388 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_send_msi_irq() local
393 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI); in cdns_pcie_ep_send_msi_irq()
394 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_send_msi_irq()
397 flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS); in cdns_pcie_ep_send_msi_irq()
399 return -EINVAL; in cdns_pcie_ep_send_msi_irq()
405 return -EINVAL; in cdns_pcie_ep_send_msi_irq()
408 data_mask = msi_count - 1; in cdns_pcie_ep_send_msi_irq()
409 data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64); in cdns_pcie_ep_send_msi_irq()
410 data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask); in cdns_pcie_ep_send_msi_irq()
413 pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI); in cdns_pcie_ep_send_msi_irq()
415 pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO); in cdns_pcie_ep_send_msi_irq()
419 if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) || in cdns_pcie_ep_send_msi_irq()
420 ep->irq_pci_fn != fn)) { in cdns_pcie_ep_send_msi_irq()
422 cdns_pcie_set_outbound_region(pcie, 0, fn, 0, in cdns_pcie_ep_send_msi_irq()
424 ep->irq_phys_addr, in cdns_pcie_ep_send_msi_irq()
427 ep->irq_pci_addr = (pci_addr & ~pci_addr_mask); in cdns_pcie_ep_send_msi_irq()
428 ep->irq_pci_fn = fn; in cdns_pcie_ep_send_msi_irq()
430 writel(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask)); in cdns_pcie_ep_send_msi_irq()
440 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_map_msi_irq() local
441 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_map_msi_irq() local
448 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI); in cdns_pcie_ep_map_msi_irq()
449 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_map_msi_irq()
452 flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS); in cdns_pcie_ep_map_msi_irq()
454 return -EINVAL; in cdns_pcie_ep_map_msi_irq()
460 return -EINVAL; in cdns_pcie_ep_map_msi_irq()
463 data_mask = msi_count - 1; in cdns_pcie_ep_map_msi_irq()
464 data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64); in cdns_pcie_ep_map_msi_irq()
468 pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI); in cdns_pcie_ep_map_msi_irq()
470 pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO); in cdns_pcie_ep_map_msi_irq()
488 static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn, in cdns_pcie_ep_send_msix_irq() argument
492 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_send_msix_irq() local
500 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); in cdns_pcie_ep_send_msix_irq()
501 epf = &ep->epf[fn]; in cdns_pcie_ep_send_msix_irq()
503 epf = &epf->epf[vfn - 1]; in cdns_pcie_ep_send_msix_irq()
505 fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); in cdns_pcie_ep_send_msix_irq()
507 /* Check whether the MSI-X feature has been enabled by the PCI host. */ in cdns_pcie_ep_send_msix_irq()
508 flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS); in cdns_pcie_ep_send_msix_irq()
510 return -EINVAL; in cdns_pcie_ep_send_msix_irq()
513 tbl_offset = cdns_pcie_ep_fn_readl(pcie, fn, reg); in cdns_pcie_ep_send_msix_irq()
517 msix_tbl = epf->epf_bar[bir]->addr + tbl_offset; in cdns_pcie_ep_send_msix_irq()
518 msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr; in cdns_pcie_ep_send_msix_irq()
519 msg_data = msix_tbl[(interrupt_num - 1)].msg_data; in cdns_pcie_ep_send_msix_irq()
522 if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) || in cdns_pcie_ep_send_msix_irq()
523 ep->irq_pci_fn != fn) { in cdns_pcie_ep_send_msix_irq()
525 cdns_pcie_set_outbound_region(pcie, 0, fn, 0, in cdns_pcie_ep_send_msix_irq()
527 ep->irq_phys_addr, in cdns_pcie_ep_send_msix_irq()
530 ep->irq_pci_addr = (msg_addr & ~pci_addr_mask); in cdns_pcie_ep_send_msix_irq()
531 ep->irq_pci_fn = fn; in cdns_pcie_ep_send_msix_irq()
533 writel(msg_data, ep->irq_cpu_addr + (msg_addr & pci_addr_mask)); in cdns_pcie_ep_send_msix_irq()
541 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_raise_irq() local
542 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_raise_irq() local
543 struct device *dev = pcie->dev; in cdns_pcie_ep_raise_irq()
549 return -EINVAL; in cdns_pcie_ep_raise_irq()
551 return cdns_pcie_ep_send_intx_irq(ep, fn, vfn, 0); in cdns_pcie_ep_raise_irq()
554 return cdns_pcie_ep_send_msi_irq(ep, fn, vfn, interrupt_num); in cdns_pcie_ep_raise_irq()
557 return cdns_pcie_ep_send_msix_irq(ep, fn, vfn, interrupt_num); in cdns_pcie_ep_raise_irq()
563 return -EINVAL; in cdns_pcie_ep_raise_irq()
568 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); in cdns_pcie_ep_start() local
569 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_start() local
570 struct device *dev = pcie->dev; in cdns_pcie_ep_start()
571 int max_epfs = sizeof(epc->function_num_map) * 8; in cdns_pcie_ep_start()
576 cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP); in cdns_pcie_ep_start()
581 cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, epc->function_num_map); in cdns_pcie_ep_start()
588 last_fn = find_last_bit(&epc->function_num_map, BITS_PER_LONG); in cdns_pcie_ep_start()
590 value = cdns_pcie_readl(pcie, reg); in cdns_pcie_ep_start()
592 cdns_pcie_writel(pcie, reg, value); in cdns_pcie_ep_start()
594 if (ep->quirk_disable_flr) { in cdns_pcie_ep_start()
596 if (!(epc->function_num_map & BIT(epf))) in cdns_pcie_ep_start()
599 value = cdns_pcie_ep_fn_readl(pcie, epf, in cdns_pcie_ep_start()
602 cdns_pcie_ep_fn_writel(pcie, epf, in cdns_pcie_ep_start()
607 ret = cdns_pcie_start_link(pcie); in cdns_pcie_ep_start()
653 void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep) in cdns_pcie_ep_disable() argument
655 struct device *dev = ep->pcie.dev; in cdns_pcie_ep_disable()
659 pci_epc_mem_free_addr(epc, ep->irq_phys_addr, ep->irq_cpu_addr, in cdns_pcie_ep_disable()
665 int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) in cdns_pcie_ep_setup() argument
667 struct device *dev = ep->pcie.dev; in cdns_pcie_ep_setup()
669 struct device_node *np = dev->of_node; in cdns_pcie_ep_setup()
670 struct cdns_pcie *pcie = &ep->pcie; in cdns_pcie_ep_setup() local
677 pcie->is_rc = false; in cdns_pcie_ep_setup()
679 pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg"); in cdns_pcie_ep_setup()
680 if (IS_ERR(pcie->reg_base)) { in cdns_pcie_ep_setup()
682 return PTR_ERR(pcie->reg_base); in cdns_pcie_ep_setup()
688 return -EINVAL; in cdns_pcie_ep_setup()
690 pcie->mem_res = res; in cdns_pcie_ep_setup()
692 ep->max_regions = CDNS_PCIE_MAX_OB; in cdns_pcie_ep_setup()
693 of_property_read_u32(np, "cdns,max-outbound-regions", &ep->max_regions); in cdns_pcie_ep_setup()
695 ep->ob_addr = devm_kcalloc(dev, in cdns_pcie_ep_setup()
696 ep->max_regions, sizeof(*ep->ob_addr), in cdns_pcie_ep_setup()
698 if (!ep->ob_addr) in cdns_pcie_ep_setup()
699 return -ENOMEM; in cdns_pcie_ep_setup()
702 cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, BIT(0)); in cdns_pcie_ep_setup()
710 epc_set_drvdata(epc, ep); in cdns_pcie_ep_setup()
712 if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0) in cdns_pcie_ep_setup()
713 epc->max_functions = 1; in cdns_pcie_ep_setup()
715 ep->epf = devm_kcalloc(dev, epc->max_functions, sizeof(*ep->epf), in cdns_pcie_ep_setup()
717 if (!ep->epf) in cdns_pcie_ep_setup()
718 return -ENOMEM; in cdns_pcie_ep_setup()
720 epc->max_vfs = devm_kcalloc(dev, epc->max_functions, in cdns_pcie_ep_setup()
721 sizeof(*epc->max_vfs), GFP_KERNEL); in cdns_pcie_ep_setup()
722 if (!epc->max_vfs) in cdns_pcie_ep_setup()
723 return -ENOMEM; in cdns_pcie_ep_setup()
725 ret = of_property_read_u8_array(np, "max-virtual-functions", in cdns_pcie_ep_setup()
726 epc->max_vfs, epc->max_functions); in cdns_pcie_ep_setup()
728 for (i = 0; i < epc->max_functions; i++) { in cdns_pcie_ep_setup()
729 epf = &ep->epf[i]; in cdns_pcie_ep_setup()
730 if (epc->max_vfs[i] == 0) in cdns_pcie_ep_setup()
732 epf->epf = devm_kcalloc(dev, epc->max_vfs[i], in cdns_pcie_ep_setup()
733 sizeof(*ep->epf), GFP_KERNEL); in cdns_pcie_ep_setup()
734 if (!epf->epf) in cdns_pcie_ep_setup()
735 return -ENOMEM; in cdns_pcie_ep_setup()
739 ret = pci_epc_mem_init(epc, pcie->mem_res->start, in cdns_pcie_ep_setup()
740 resource_size(pcie->mem_res), PAGE_SIZE); in cdns_pcie_ep_setup()
746 ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr, in cdns_pcie_ep_setup()
748 if (!ep->irq_cpu_addr) { in cdns_pcie_ep_setup()
750 ret = -ENOMEM; in cdns_pcie_ep_setup()
753 ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE; in cdns_pcie_ep_setup()
755 set_bit(0, &ep->ob_region_map); in cdns_pcie_ep_setup()
757 if (ep->quirk_detect_quiet_flag) in cdns_pcie_ep_setup()
758 cdns_pcie_detect_quiet_min_delay_set(&ep->pcie); in cdns_pcie_ep_setup()
760 spin_lock_init(&ep->lock); in cdns_pcie_ep_setup()
774 MODULE_DESCRIPTION("Cadence PCIe endpoint controller driver");
775 MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@free-electrons.com>");