Lines Matching +full:local +full:- +full:cap +full:- +full:size

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
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()
42 struct dw_pcie_ep *ep = &pci->ep; in __dw_pcie_ep_reset_bar()
57 * dw_pcie_ep_reset_bar - Reset endpoint BAR
65 funcs = pci->ep.epc->max_functions; in dw_pcie_ep_reset_bar()
73 u8 cap_ptr, u8 cap) in __dw_pcie_ep_find_next_cap() argument
87 if (cap_id == cap) 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
102 return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); in dw_pcie_ep_find_capability()
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()
117 hdr->subclass_code | hdr->baseclass_code << 8); in dw_pcie_ep_write_header()
119 hdr->cache_line_size); 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()
124 hdr->interrupt_pin); in dw_pcie_ep_write_header()
137 if (!ep->bar_to_atu[bar]) in dw_pcie_ep_inbound_atu()
138 free_win = find_first_zero_bit(ep->ib_window_map, pci->num_ib_windows); in dw_pcie_ep_inbound_atu()
140 free_win = ep->bar_to_atu[bar] - 1; in dw_pcie_ep_inbound_atu()
142 if (free_win >= pci->num_ib_windows) { in dw_pcie_ep_inbound_atu()
143 dev_err(pci->dev, "No free inbound window\n"); in dw_pcie_ep_inbound_atu()
144 return -EINVAL; in dw_pcie_ep_inbound_atu()
150 dev_err(pci->dev, "Failed to program IB window\n"); in dw_pcie_ep_inbound_atu()
158 ep->bar_to_atu[bar] = free_win + 1; in dw_pcie_ep_inbound_atu()
159 set_bit(free_win, ep->ib_window_map); in dw_pcie_ep_inbound_atu()
171 free_win = find_first_zero_bit(ep->ob_window_map, pci->num_ob_windows); in dw_pcie_ep_outbound_atu()
172 if (free_win >= pci->num_ob_windows) { in dw_pcie_ep_outbound_atu()
173 dev_err(pci->dev, "No free outbound window\n"); in dw_pcie_ep_outbound_atu()
174 return -EINVAL; in dw_pcie_ep_outbound_atu()
177 atu->index = free_win; in dw_pcie_ep_outbound_atu()
182 set_bit(free_win, ep->ob_window_map); in dw_pcie_ep_outbound_atu()
183 ep->outbound_addr[free_win] = atu->cpu_addr; in dw_pcie_ep_outbound_atu()
193 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_clear_bar()
194 u32 atu_index = ep->bar_to_atu[bar] - 1; in dw_pcie_ep_clear_bar()
196 if (!ep->bar_to_atu[bar]) in dw_pcie_ep_clear_bar()
199 __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags); in dw_pcie_ep_clear_bar()
202 clear_bit(atu_index, ep->ib_window_map); in dw_pcie_ep_clear_bar()
203 ep->epf_bar[bar] = NULL; in dw_pcie_ep_clear_bar()
204 ep->bar_to_atu[bar] = 0; in dw_pcie_ep_clear_bar()
212 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_set_bar()
213 size_t size = epf_bar->size; in dw_pcie_ep_set_bar() local
214 int flags = epf_bar->flags; in dw_pcie_ep_set_bar()
220 * 1 and 2 to form a 64-bit BAR. in dw_pcie_ep_set_bar()
223 return -EINVAL; in dw_pcie_ep_set_bar()
232 ret = dw_pcie_ep_inbound_atu(ep, func_no, type, epf_bar->phys_addr, bar); in dw_pcie_ep_set_bar()
236 if (ep->epf_bar[bar]) in dw_pcie_ep_set_bar()
241 dw_pcie_ep_writel_dbi2(ep, func_no, reg, lower_32_bits(size - 1)); in dw_pcie_ep_set_bar()
245 dw_pcie_ep_writel_dbi2(ep, func_no, reg + 4, upper_32_bits(size - 1)); in dw_pcie_ep_set_bar()
249 ep->epf_bar[bar] = epf_bar; in dw_pcie_ep_set_bar()
261 for (index = 0; index < pci->num_ob_windows; index++) { in dw_pcie_find_index()
262 if (ep->outbound_addr[index] != addr) in dw_pcie_find_index()
268 return -EINVAL; in dw_pcie_find_index()
284 clear_bit(atu_index, ep->ob_window_map); in dw_pcie_ep_unmap_addr()
288 phys_addr_t addr, u64 pci_addr, size_t size) in dw_pcie_ep_map_addr() argument
299 atu.size = size; in dw_pcie_ep_map_addr()
302 dev_err(pci->dev, "Failed to enable address\n"); in dw_pcie_ep_map_addr()
316 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_get_msi()
317 return -EINVAL; in dw_pcie_ep_get_msi()
319 reg = ep_func->msi_cap + PCI_MSI_FLAGS; in dw_pcie_ep_get_msi()
322 return -EINVAL; in dw_pcie_ep_get_msi()
338 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_set_msi()
339 return -EINVAL; in dw_pcie_ep_set_msi()
341 reg = ep_func->msi_cap + PCI_MSI_FLAGS; in dw_pcie_ep_set_msi()
359 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_get_msix()
360 return -EINVAL; in dw_pcie_ep_get_msix()
362 reg = ep_func->msix_cap + PCI_MSIX_FLAGS; in dw_pcie_ep_get_msix()
365 return -EINVAL; in dw_pcie_ep_get_msix()
381 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_set_msix()
382 return -EINVAL; in dw_pcie_ep_set_msix()
386 reg = ep_func->msix_cap + PCI_MSIX_FLAGS; in dw_pcie_ep_set_msix()
392 reg = ep_func->msix_cap + PCI_MSIX_TABLE; in dw_pcie_ep_set_msix()
396 reg = ep_func->msix_cap + PCI_MSIX_PBA; in dw_pcie_ep_set_msix()
410 if (!ep->ops->raise_irq) in dw_pcie_ep_raise_irq()
411 return -EINVAL; in dw_pcie_ep_raise_irq()
413 return ep->ops->raise_irq(ep, func_no, type, interrupt_num); in dw_pcie_ep_raise_irq()
437 if (!ep->ops->get_features) in dw_pcie_ep_get_features()
440 return ep->ops->get_features(ep); in dw_pcie_ep_get_features()
460 * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host
469 struct device *dev = pci->dev; in dw_pcie_ep_raise_intx_irq()
473 return -EINVAL; in dw_pcie_ep_raise_intx_irq()
478 * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host
490 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msi_irq()
498 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_raise_msi_irq()
499 return -EINVAL; in dw_pcie_ep_raise_msi_irq()
501 /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */ in dw_pcie_ep_raise_msi_irq()
502 reg = ep_func->msi_cap + PCI_MSI_FLAGS; in dw_pcie_ep_raise_msi_irq()
505 reg = ep_func->msi_cap + PCI_MSI_ADDRESS_LO; in dw_pcie_ep_raise_msi_irq()
508 reg = ep_func->msi_cap + PCI_MSI_ADDRESS_HI; in dw_pcie_ep_raise_msi_irq()
510 reg = ep_func->msi_cap + PCI_MSI_DATA_64; in dw_pcie_ep_raise_msi_irq()
514 reg = ep_func->msi_cap + PCI_MSI_DATA_32; in dw_pcie_ep_raise_msi_irq()
519 aligned_offset = msg_addr & (epc->mem->window.page_size - 1); in dw_pcie_ep_raise_msi_irq()
520 msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); in dw_pcie_ep_raise_msi_irq()
521 ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msi_irq()
522 epc->mem->window.page_size); in dw_pcie_ep_raise_msi_irq()
526 writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset); in dw_pcie_ep_raise_msi_irq()
528 dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); in dw_pcie_ep_raise_msi_irq()
535 * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSI-X to the host using Doorbell
551 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq_doorbell()
552 return -EINVAL; in dw_pcie_ep_raise_msix_irq_doorbell()
555 (interrupt_num - 1); in dw_pcie_ep_raise_msix_irq_doorbell()
563 * dw_pcie_ep_raise_msix_irq - Raise MSI-X to the host
576 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msix_irq()
585 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq()
586 return -EINVAL; in dw_pcie_ep_raise_msix_irq()
588 reg = ep_func->msix_cap + PCI_MSIX_TABLE; in dw_pcie_ep_raise_msix_irq()
593 msix_tbl = ep->epf_bar[bir]->addr + tbl_offset; in dw_pcie_ep_raise_msix_irq()
594 msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr; in dw_pcie_ep_raise_msix_irq()
595 msg_data = msix_tbl[(interrupt_num - 1)].msg_data; in dw_pcie_ep_raise_msix_irq()
596 vec_ctrl = msix_tbl[(interrupt_num - 1)].vector_ctrl; in dw_pcie_ep_raise_msix_irq()
599 dev_dbg(pci->dev, "MSI-X entry ctrl set\n"); in dw_pcie_ep_raise_msix_irq()
600 return -EPERM; in dw_pcie_ep_raise_msix_irq()
603 aligned_offset = msg_addr & (epc->mem->window.page_size - 1); in dw_pcie_ep_raise_msix_irq()
604 msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); in dw_pcie_ep_raise_msix_irq()
605 ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msix_irq()
606 epc->mem->window.page_size); in dw_pcie_ep_raise_msix_irq()
610 writel(msg_data, ep->msi_mem + aligned_offset); in dw_pcie_ep_raise_msix_irq()
612 dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); in dw_pcie_ep_raise_msix_irq()
618 * dw_pcie_ep_cleanup - Cleanup DWC EP resources after fundamental reset
634 * dw_pcie_ep_deinit - Deinitialize the endpoint device
642 struct pci_epc *epc = ep->epc; in dw_pcie_ep_deinit()
646 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, in dw_pcie_ep_deinit()
647 epc->mem->window.page_size); in dw_pcie_ep_deinit()
653 static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) in dw_pcie_ep_find_ext_capability() argument
660 if (PCI_EXT_CAP_ID(header) == cap) in dw_pcie_ep_find_ext_capability()
688 * size in the range from 1 MB to 512 GB. Advertise support in dw_pcie_ep_init_non_sticky_registers()
689 * for 1 MB BAR size only. in dw_pcie_ep_init_non_sticky_registers()
700 * dw_pcie_ep_init_registers - Initialize DWC EP specific registers
711 struct device *dev = pci->dev; in dw_pcie_ep_init_registers()
712 struct pci_epc *epc = ep->epc; in dw_pcie_ep_init_registers()
722 dev_err(pci->dev, in dw_pcie_ep_init_registers()
725 return -EIO; in dw_pcie_ep_init_registers()
736 if (!ep->ib_window_map) { in dw_pcie_ep_init_registers()
737 ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, in dw_pcie_ep_init_registers()
739 if (!ep->ib_window_map) in dw_pcie_ep_init_registers()
743 if (!ep->ob_window_map) { in dw_pcie_ep_init_registers()
744 ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, in dw_pcie_ep_init_registers()
746 if (!ep->ob_window_map) in dw_pcie_ep_init_registers()
750 if (!ep->outbound_addr) { in dw_pcie_ep_init_registers()
751 addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), in dw_pcie_ep_init_registers()
755 ep->outbound_addr = addr; in dw_pcie_ep_init_registers()
758 for (func_no = 0; func_no < epc->max_functions; func_no++) { in dw_pcie_ep_init_registers()
768 ep_func->func_no = func_no; in dw_pcie_ep_init_registers()
769 ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init_registers()
771 ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init_registers()
774 list_add_tail(&ep_func->list, &ep->func_list); in dw_pcie_ep_init_registers()
777 if (ep->ops->init) in dw_pcie_ep_init_registers()
778 ep->ops->init(ep); in dw_pcie_ep_init_registers()
810 * dw_pcie_ep_linkup - Notify EPF drivers about Link Up event
815 struct pci_epc *epc = ep->epc; in dw_pcie_ep_linkup()
822 * dw_pcie_ep_linkdown - Notify EPF drivers about Link Down event
825 * Non-sticky registers are also initialized before sending the notification to
832 struct pci_epc *epc = ep->epc; in dw_pcie_ep_linkdown()
835 * Initialize the non-sticky DWC registers as they would've reset post in dw_pcie_ep_linkdown()
847 * dw_pcie_ep_init - Initialize the endpoint device
861 struct device *dev = pci->dev; in dw_pcie_ep_init()
863 struct device_node *np = dev->of_node; in dw_pcie_ep_init()
865 INIT_LIST_HEAD(&ep->func_list); in dw_pcie_ep_init()
873 return -EINVAL; in dw_pcie_ep_init()
875 ep->phys_base = res->start; in dw_pcie_ep_init()
876 ep->addr_size = resource_size(res); in dw_pcie_ep_init()
878 if (ep->ops->pre_init) in dw_pcie_ep_init()
879 ep->ops->pre_init(ep); in dw_pcie_ep_init()
887 ep->epc = epc; in dw_pcie_ep_init()
890 ret = of_property_read_u8(np, "max-functions", &epc->max_functions); in dw_pcie_ep_init()
892 epc->max_functions = 1; in dw_pcie_ep_init()
894 ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size, in dw_pcie_ep_init()
895 ep->page_size); in dw_pcie_ep_init()
901 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, in dw_pcie_ep_init()
902 epc->mem->window.page_size); in dw_pcie_ep_init()
903 if (!ep->msi_mem) { in dw_pcie_ep_init()
904 ret = -ENOMEM; in dw_pcie_ep_init()
905 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n"); in dw_pcie_ep_init()