Lines Matching +full:pci +full:- +full:ep

1 // SPDX-License-Identifier: GPL-2.0
14 #include "pcie-designware.h"
15 #include <linux/pci-epc.h>
16 #include <linux/pci-epf.h>
19 * dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func corresponding to
21 * @ep: DWC EP device
27 dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no) in dw_pcie_ep_get_func_from_ep() argument
31 list_for_each_entry(ep_func, &ep->func_list, list) { in dw_pcie_ep_get_func_from_ep()
32 if (ep_func->func_no == func_no) in dw_pcie_ep_get_func_from_ep()
39 static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no, in __dw_pcie_ep_reset_bar() argument
42 struct dw_pcie_ep *ep = &pci->ep; in __dw_pcie_ep_reset_bar() local
46 dw_pcie_dbi_ro_wr_en(pci); in __dw_pcie_ep_reset_bar()
47 dw_pcie_ep_writel_dbi2(ep, func_no, reg, 0x0); in __dw_pcie_ep_reset_bar()
48 dw_pcie_ep_writel_dbi(ep, func_no, reg, 0x0); in __dw_pcie_ep_reset_bar()
50 dw_pcie_ep_writel_dbi2(ep, func_no, reg + 4, 0x0); in __dw_pcie_ep_reset_bar()
51 dw_pcie_ep_writel_dbi(ep, func_no, reg + 4, 0x0); in __dw_pcie_ep_reset_bar()
53 dw_pcie_dbi_ro_wr_dis(pci); in __dw_pcie_ep_reset_bar()
57 * dw_pcie_ep_reset_bar - Reset endpoint BAR
58 * @pci: DWC PCI device
61 void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) in dw_pcie_ep_reset_bar() argument
65 funcs = pci->ep.epc->max_functions; in dw_pcie_ep_reset_bar()
68 __dw_pcie_ep_reset_bar(pci, func_no, bar, 0); in dw_pcie_ep_reset_bar()
72 static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no, in __dw_pcie_ep_find_next_cap() argument
81 reg = dw_pcie_ep_readw_dbi(ep, func_no, cap_ptr); in __dw_pcie_ep_find_next_cap()
91 return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); in __dw_pcie_ep_find_next_cap()
94 static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap) in dw_pcie_ep_find_capability() argument
99 reg = dw_pcie_ep_readw_dbi(ep, func_no, PCI_CAPABILITY_LIST); in dw_pcie_ep_find_capability()
102 return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); in dw_pcie_ep_find_capability()
108 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_write_header() local
109 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_write_header() local
111 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_write_header()
112 dw_pcie_ep_writew_dbi(ep, func_no, PCI_VENDOR_ID, hdr->vendorid); in dw_pcie_ep_write_header()
113 dw_pcie_ep_writew_dbi(ep, func_no, PCI_DEVICE_ID, hdr->deviceid); in dw_pcie_ep_write_header()
114 dw_pcie_ep_writeb_dbi(ep, func_no, PCI_REVISION_ID, hdr->revid); in dw_pcie_ep_write_header()
115 dw_pcie_ep_writeb_dbi(ep, func_no, PCI_CLASS_PROG, hdr->progif_code); in dw_pcie_ep_write_header()
116 dw_pcie_ep_writew_dbi(ep, func_no, PCI_CLASS_DEVICE, in dw_pcie_ep_write_header()
117 hdr->subclass_code | hdr->baseclass_code << 8); in dw_pcie_ep_write_header()
118 dw_pcie_ep_writeb_dbi(ep, func_no, PCI_CACHE_LINE_SIZE, in dw_pcie_ep_write_header()
119 hdr->cache_line_size); in dw_pcie_ep_write_header()
120 dw_pcie_ep_writew_dbi(ep, func_no, PCI_SUBSYSTEM_VENDOR_ID, in dw_pcie_ep_write_header()
121 hdr->subsys_vendor_id); in dw_pcie_ep_write_header()
122 dw_pcie_ep_writew_dbi(ep, func_no, PCI_SUBSYSTEM_ID, hdr->subsys_id); in dw_pcie_ep_write_header()
123 dw_pcie_ep_writeb_dbi(ep, func_no, PCI_INTERRUPT_PIN, in dw_pcie_ep_write_header()
124 hdr->interrupt_pin); in dw_pcie_ep_write_header()
125 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_write_header()
130 static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type, in dw_pcie_ep_inbound_atu() argument
136 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_inbound_atu() local
138 if (!ep->bar_to_atu[bar]) in dw_pcie_ep_inbound_atu()
139 free_win = find_first_zero_bit(ep->ib_window_map, pci->num_ib_windows); in dw_pcie_ep_inbound_atu()
141 free_win = ep->bar_to_atu[bar] - 1; in dw_pcie_ep_inbound_atu()
143 if (free_win >= pci->num_ib_windows) { in dw_pcie_ep_inbound_atu()
144 dev_err(pci->dev, "No free inbound window\n"); in dw_pcie_ep_inbound_atu()
145 return -EINVAL; in dw_pcie_ep_inbound_atu()
148 ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type, in dw_pcie_ep_inbound_atu()
151 dev_err(pci->dev, "Failed to program IB window\n"); in dw_pcie_ep_inbound_atu()
159 ep->bar_to_atu[bar] = free_win + 1; in dw_pcie_ep_inbound_atu()
160 set_bit(free_win, ep->ib_window_map); in dw_pcie_ep_inbound_atu()
165 static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, in dw_pcie_ep_outbound_atu() argument
168 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_outbound_atu() local
172 free_win = find_first_zero_bit(ep->ob_window_map, pci->num_ob_windows); in dw_pcie_ep_outbound_atu()
173 if (free_win >= pci->num_ob_windows) { in dw_pcie_ep_outbound_atu()
174 dev_err(pci->dev, "No free outbound window\n"); in dw_pcie_ep_outbound_atu()
175 return -EINVAL; in dw_pcie_ep_outbound_atu()
178 atu->index = free_win; in dw_pcie_ep_outbound_atu()
179 ret = dw_pcie_prog_outbound_atu(pci, atu); in dw_pcie_ep_outbound_atu()
183 set_bit(free_win, ep->ob_window_map); in dw_pcie_ep_outbound_atu()
184 ep->outbound_addr[free_win] = atu->cpu_addr; in dw_pcie_ep_outbound_atu()
192 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_clear_bar() local
193 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_clear_bar() local
194 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_clear_bar()
195 u32 atu_index = ep->bar_to_atu[bar] - 1; in dw_pcie_ep_clear_bar()
197 if (!ep->bar_to_atu[bar]) in dw_pcie_ep_clear_bar()
200 __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags); in dw_pcie_ep_clear_bar()
202 dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); in dw_pcie_ep_clear_bar()
203 clear_bit(atu_index, ep->ib_window_map); in dw_pcie_ep_clear_bar()
204 ep->epf_bar[bar] = NULL; in dw_pcie_ep_clear_bar()
205 ep->bar_to_atu[bar] = 0; in dw_pcie_ep_clear_bar()
211 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_set_bar() local
212 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_set_bar() local
213 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_set_bar()
214 size_t size = epf_bar->size; in dw_pcie_ep_set_bar()
215 int flags = epf_bar->flags; in dw_pcie_ep_set_bar()
221 * 1 and 2 to form a 64-bit BAR. in dw_pcie_ep_set_bar()
224 return -EINVAL; in dw_pcie_ep_set_bar()
229 * calling clear_bar() would clear the BAR's PCI address assigned by the in dw_pcie_ep_set_bar()
232 if (ep->epf_bar[bar]) { in dw_pcie_ep_set_bar()
237 if (ep->epf_bar[bar]->barno != bar || in dw_pcie_ep_set_bar()
238 ep->epf_bar[bar]->size != size || in dw_pcie_ep_set_bar()
239 ep->epf_bar[bar]->flags != flags) in dw_pcie_ep_set_bar()
240 return -EINVAL; in dw_pcie_ep_set_bar()
244 * that would clear the BAR's PCI address assigned by the host. in dw_pcie_ep_set_bar()
251 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_set_bar()
253 dw_pcie_ep_writel_dbi2(ep, func_no, reg, lower_32_bits(size - 1)); in dw_pcie_ep_set_bar()
254 dw_pcie_ep_writel_dbi(ep, func_no, reg, flags); in dw_pcie_ep_set_bar()
257 dw_pcie_ep_writel_dbi2(ep, func_no, reg + 4, upper_32_bits(size - 1)); in dw_pcie_ep_set_bar()
258 dw_pcie_ep_writel_dbi(ep, func_no, reg + 4, 0); in dw_pcie_ep_set_bar()
261 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_set_bar()
269 ret = dw_pcie_ep_inbound_atu(ep, func_no, type, epf_bar->phys_addr, bar, in dw_pcie_ep_set_bar()
274 ep->epf_bar[bar] = epf_bar; in dw_pcie_ep_set_bar()
279 static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, in dw_pcie_find_index() argument
283 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_find_index() local
285 for (index = 0; index < pci->num_ob_windows; index++) { in dw_pcie_find_index()
286 if (ep->outbound_addr[index] != addr) in dw_pcie_find_index()
292 return -EINVAL; in dw_pcie_find_index()
298 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_align_addr() local
299 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_align_addr() local
300 u64 mask = pci->region_align - 1; in dw_pcie_ep_align_addr()
303 *pci_size = ALIGN(ofst + *pci_size, epc->mem->window.page_size); in dw_pcie_ep_align_addr()
314 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_unmap_addr() local
315 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_unmap_addr() local
317 ret = dw_pcie_find_index(ep, addr, &atu_index); in dw_pcie_ep_unmap_addr()
321 ep->outbound_addr[atu_index] = 0; in dw_pcie_ep_unmap_addr()
322 dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, atu_index); in dw_pcie_ep_unmap_addr()
323 clear_bit(atu_index, ep->ob_window_map); in dw_pcie_ep_unmap_addr()
330 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_map_addr() local
331 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_map_addr() local
339 ret = dw_pcie_ep_outbound_atu(ep, &atu); in dw_pcie_ep_map_addr()
341 dev_err(pci->dev, "Failed to enable address\n"); in dw_pcie_ep_map_addr()
350 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_get_msi() local
354 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_get_msi()
355 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_get_msi()
356 return -EINVAL; in dw_pcie_ep_get_msi()
358 reg = ep_func->msi_cap + PCI_MSI_FLAGS; in dw_pcie_ep_get_msi()
359 val = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_get_msi()
361 return -EINVAL; in dw_pcie_ep_get_msi()
371 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_set_msi() local
372 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_set_msi() local
376 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_set_msi()
377 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_set_msi()
378 return -EINVAL; in dw_pcie_ep_set_msi()
380 reg = ep_func->msi_cap + PCI_MSI_FLAGS; in dw_pcie_ep_set_msi()
381 val = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_set_msi()
384 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_set_msi()
385 dw_pcie_ep_writew_dbi(ep, func_no, reg, val); in dw_pcie_ep_set_msi()
386 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_set_msi()
393 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_get_msix() local
397 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_get_msix()
398 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_get_msix()
399 return -EINVAL; in dw_pcie_ep_get_msix()
401 reg = ep_func->msix_cap + PCI_MSIX_FLAGS; in dw_pcie_ep_get_msix()
402 val = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_get_msix()
404 return -EINVAL; in dw_pcie_ep_get_msix()
414 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_set_msix() local
415 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_set_msix() local
419 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_set_msix()
420 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_set_msix()
421 return -EINVAL; in dw_pcie_ep_set_msix()
423 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_set_msix()
425 reg = ep_func->msix_cap + PCI_MSIX_FLAGS; in dw_pcie_ep_set_msix()
426 val = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_set_msix()
429 dw_pcie_writew_dbi(pci, reg, val); in dw_pcie_ep_set_msix()
431 reg = ep_func->msix_cap + PCI_MSIX_TABLE; in dw_pcie_ep_set_msix()
433 dw_pcie_ep_writel_dbi(ep, func_no, reg, val); in dw_pcie_ep_set_msix()
435 reg = ep_func->msix_cap + PCI_MSIX_PBA; in dw_pcie_ep_set_msix()
437 dw_pcie_ep_writel_dbi(ep, func_no, reg, val); in dw_pcie_ep_set_msix()
439 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_set_msix()
447 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_raise_irq() local
449 if (!ep->ops->raise_irq) in dw_pcie_ep_raise_irq()
450 return -EINVAL; in dw_pcie_ep_raise_irq()
452 return ep->ops->raise_irq(ep, func_no, type, interrupt_num); in dw_pcie_ep_raise_irq()
457 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_stop() local
458 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_stop() local
460 dw_pcie_stop_link(pci); in dw_pcie_ep_stop()
465 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_start() local
466 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_start() local
468 return dw_pcie_start_link(pci); in dw_pcie_ep_start()
474 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_get_features() local
476 if (!ep->ops->get_features) in dw_pcie_ep_get_features()
479 return ep->ops->get_features(ep); in dw_pcie_ep_get_features()
500 * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host
501 * @ep: DWC EP device
506 int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no) in dw_pcie_ep_raise_intx_irq() argument
508 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_intx_irq() local
509 struct device *dev = pci->dev; in dw_pcie_ep_raise_intx_irq()
511 dev_err(dev, "EP cannot raise INTX IRQs\n"); in dw_pcie_ep_raise_intx_irq()
513 return -EINVAL; in dw_pcie_ep_raise_intx_irq()
518 * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host
519 * @ep: DWC EP device
525 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, in dw_pcie_ep_raise_msi_irq() argument
530 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msi_irq()
538 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_raise_msi_irq()
539 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_raise_msi_irq()
540 return -EINVAL; in dw_pcie_ep_raise_msi_irq()
542 /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */ in dw_pcie_ep_raise_msi_irq()
543 reg = ep_func->msi_cap + PCI_MSI_FLAGS; in dw_pcie_ep_raise_msi_irq()
544 msg_ctrl = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_raise_msi_irq()
546 reg = ep_func->msi_cap + PCI_MSI_ADDRESS_LO; in dw_pcie_ep_raise_msi_irq()
547 msg_addr_lower = dw_pcie_ep_readl_dbi(ep, func_no, reg); in dw_pcie_ep_raise_msi_irq()
549 reg = ep_func->msi_cap + PCI_MSI_ADDRESS_HI; in dw_pcie_ep_raise_msi_irq()
550 msg_addr_upper = dw_pcie_ep_readl_dbi(ep, func_no, reg); in dw_pcie_ep_raise_msi_irq()
551 reg = ep_func->msi_cap + PCI_MSI_DATA_64; in dw_pcie_ep_raise_msi_irq()
552 msg_data = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_raise_msi_irq()
555 reg = ep_func->msi_cap + PCI_MSI_DATA_32; in dw_pcie_ep_raise_msi_irq()
556 msg_data = dw_pcie_ep_readw_dbi(ep, func_no, reg); in dw_pcie_ep_raise_msi_irq()
561 ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msi_irq()
566 writel(msg_data | (interrupt_num - 1), ep->msi_mem + offset); in dw_pcie_ep_raise_msi_irq()
568 dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); in dw_pcie_ep_raise_msi_irq()
575 * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSI-X to the host using Doorbell
577 * @ep: DWC EP device
583 int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no, in dw_pcie_ep_raise_msix_irq_doorbell() argument
586 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_msix_irq_doorbell() local
590 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_raise_msix_irq_doorbell()
591 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq_doorbell()
592 return -EINVAL; in dw_pcie_ep_raise_msix_irq_doorbell()
595 (interrupt_num - 1); in dw_pcie_ep_raise_msix_irq_doorbell()
597 dw_pcie_writel_dbi(pci, PCIE_MSIX_DOORBELL, msg_data); in dw_pcie_ep_raise_msix_irq_doorbell()
603 * dw_pcie_ep_raise_msix_irq - Raise MSI-X to the host
604 * @ep: DWC EP device
610 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, in dw_pcie_ep_raise_msix_irq() argument
613 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_msix_irq() local
616 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msix_irq()
625 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_raise_msix_irq()
626 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq()
627 return -EINVAL; in dw_pcie_ep_raise_msix_irq()
629 reg = ep_func->msix_cap + PCI_MSIX_TABLE; in dw_pcie_ep_raise_msix_irq()
630 tbl_offset = dw_pcie_ep_readl_dbi(ep, func_no, reg); in dw_pcie_ep_raise_msix_irq()
634 msix_tbl = ep->epf_bar[bir]->addr + tbl_offset; in dw_pcie_ep_raise_msix_irq()
635 msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr; in dw_pcie_ep_raise_msix_irq()
636 msg_data = msix_tbl[(interrupt_num - 1)].msg_data; in dw_pcie_ep_raise_msix_irq()
637 vec_ctrl = msix_tbl[(interrupt_num - 1)].vector_ctrl; in dw_pcie_ep_raise_msix_irq()
640 dev_dbg(pci->dev, "MSI-X entry ctrl set\n"); in dw_pcie_ep_raise_msix_irq()
641 return -EPERM; in dw_pcie_ep_raise_msix_irq()
645 ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msix_irq()
650 writel(msg_data, ep->msi_mem + offset); in dw_pcie_ep_raise_msix_irq()
652 dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); in dw_pcie_ep_raise_msix_irq()
658 * dw_pcie_ep_cleanup - Cleanup DWC EP resources after fundamental reset
659 * @ep: DWC EP device
661 * Cleans up the DWC EP specific resources like eDMA etc... after fundamental
665 void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) in dw_pcie_ep_cleanup() argument
667 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_cleanup() local
669 dw_pcie_edma_remove(pci); in dw_pcie_ep_cleanup()
674 * dw_pcie_ep_deinit - Deinitialize the endpoint device
675 * @ep: DWC EP device
680 void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) in dw_pcie_ep_deinit() argument
682 struct pci_epc *epc = ep->epc; in dw_pcie_ep_deinit()
684 dw_pcie_ep_cleanup(ep); in dw_pcie_ep_deinit()
686 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, in dw_pcie_ep_deinit()
687 epc->mem->window.page_size); in dw_pcie_ep_deinit()
693 static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) in dw_pcie_ep_find_ext_capability() argument
699 header = dw_pcie_readl_dbi(pci, pos); in dw_pcie_ep_find_ext_capability()
711 static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci) in dw_pcie_ep_init_non_sticky_registers() argument
717 offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR); in dw_pcie_ep_init_non_sticky_registers()
719 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_init_non_sticky_registers()
722 reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL); in dw_pcie_ep_init_non_sticky_registers()
732 dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, BIT(4)); in dw_pcie_ep_init_non_sticky_registers()
735 dw_pcie_setup(pci); in dw_pcie_ep_init_non_sticky_registers()
736 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_init_non_sticky_registers()
740 * dw_pcie_ep_init_registers - Initialize DWC EP specific registers
741 * @ep: DWC EP device
743 * Initialize the registers (CSRs) specific to DWC EP. This API should be called
747 int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep) in dw_pcie_ep_init_registers() argument
749 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_init_registers() local
751 struct device *dev = pci->dev; in dw_pcie_ep_init_registers()
752 struct pci_epc *epc = ep->epc; in dw_pcie_ep_init_registers()
759 hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & in dw_pcie_ep_init_registers()
762 dev_err(pci->dev, in dw_pcie_ep_init_registers()
763 "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n", in dw_pcie_ep_init_registers()
765 return -EIO; in dw_pcie_ep_init_registers()
768 dw_pcie_version_detect(pci); in dw_pcie_ep_init_registers()
770 dw_pcie_iatu_detect(pci); in dw_pcie_ep_init_registers()
772 ret = dw_pcie_edma_detect(pci); in dw_pcie_ep_init_registers()
776 ret = -ENOMEM; in dw_pcie_ep_init_registers()
777 if (!ep->ib_window_map) { in dw_pcie_ep_init_registers()
778 ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, in dw_pcie_ep_init_registers()
780 if (!ep->ib_window_map) in dw_pcie_ep_init_registers()
784 if (!ep->ob_window_map) { in dw_pcie_ep_init_registers()
785 ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, in dw_pcie_ep_init_registers()
787 if (!ep->ob_window_map) in dw_pcie_ep_init_registers()
791 if (!ep->outbound_addr) { in dw_pcie_ep_init_registers()
792 addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), in dw_pcie_ep_init_registers()
796 ep->outbound_addr = addr; in dw_pcie_ep_init_registers()
799 for (func_no = 0; func_no < epc->max_functions; func_no++) { in dw_pcie_ep_init_registers()
801 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_init_registers()
809 ep_func->func_no = func_no; in dw_pcie_ep_init_registers()
810 ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init_registers()
812 ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init_registers()
815 list_add_tail(&ep_func->list, &ep->func_list); in dw_pcie_ep_init_registers()
818 if (ep->ops->init) in dw_pcie_ep_init_registers()
819 ep->ops->init(ep); in dw_pcie_ep_init_registers()
821 ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM); in dw_pcie_ep_init_registers()
828 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_init_registers()
829 reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP); in dw_pcie_ep_init_registers()
831 dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg); in dw_pcie_ep_init_registers()
833 reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP); in dw_pcie_ep_init_registers()
835 dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg); in dw_pcie_ep_init_registers()
836 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_init_registers()
839 dw_pcie_ep_init_non_sticky_registers(pci); in dw_pcie_ep_init_registers()
844 dw_pcie_edma_remove(pci); in dw_pcie_ep_init_registers()
851 * dw_pcie_ep_linkup - Notify EPF drivers about Link Up event
852 * @ep: DWC EP device
854 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) in dw_pcie_ep_linkup() argument
856 struct pci_epc *epc = ep->epc; in dw_pcie_ep_linkup()
863 * dw_pcie_ep_linkdown - Notify EPF drivers about Link Down event
864 * @ep: DWC EP device
866 * Non-sticky registers are also initialized before sending the notification to
870 void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep) in dw_pcie_ep_linkdown() argument
872 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_linkdown() local
873 struct pci_epc *epc = ep->epc; in dw_pcie_ep_linkdown()
876 * Initialize the non-sticky DWC registers as they would've reset post in dw_pcie_ep_linkdown()
881 dw_pcie_ep_init_non_sticky_registers(pci); in dw_pcie_ep_linkdown()
888 * dw_pcie_ep_init - Initialize the endpoint device
889 * @ep: DWC EP device
896 int dw_pcie_ep_init(struct dw_pcie_ep *ep) in dw_pcie_ep_init() argument
901 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_init() local
902 struct device *dev = pci->dev; in dw_pcie_ep_init()
904 struct device_node *np = dev->of_node; in dw_pcie_ep_init()
906 INIT_LIST_HEAD(&ep->func_list); in dw_pcie_ep_init()
908 ret = dw_pcie_get_resources(pci); in dw_pcie_ep_init()
914 return -EINVAL; in dw_pcie_ep_init()
916 ep->phys_base = res->start; in dw_pcie_ep_init()
917 ep->addr_size = resource_size(res); in dw_pcie_ep_init()
919 if (ep->ops->pre_init) in dw_pcie_ep_init()
920 ep->ops->pre_init(ep); in dw_pcie_ep_init()
928 ep->epc = epc; in dw_pcie_ep_init()
929 epc_set_drvdata(epc, ep); in dw_pcie_ep_init()
931 ret = of_property_read_u8(np, "max-functions", &epc->max_functions); in dw_pcie_ep_init()
933 epc->max_functions = 1; in dw_pcie_ep_init()
935 ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size, in dw_pcie_ep_init()
936 ep->page_size); in dw_pcie_ep_init()
942 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, in dw_pcie_ep_init()
943 epc->mem->window.page_size); in dw_pcie_ep_init()
944 if (!ep->msi_mem) { in dw_pcie_ep_init()
945 ret = -ENOMEM; in dw_pcie_ep_init()
946 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n"); in dw_pcie_ep_init()