Lines Matching +full:pcie +full:- +full:ob
1 // SPDX-License-Identifier: GPL-2.0
3 * Synopsys DesignWare PCIe Endpoint controller driver
12 #include "pcie-designware.h"
13 #include <linux/pci-epc.h>
14 #include <linux/pci-epf.h>
20 struct pci_epc *epc = ep->epc; in dw_pcie_ep_linkup()
28 struct pci_epc *epc = ep->epc; in dw_pcie_ep_init_notify()
39 list_for_each_entry(ep_func, &ep->func_list, list) { in dw_pcie_ep_get_func_from_ep()
40 if (ep_func->func_no == func_no) in dw_pcie_ep_get_func_from_ep()
51 if (ep->ops->func_conf_select) in dw_pcie_ep_func_select()
52 func_offset = ep->ops->func_conf_select(ep, func_no); in dw_pcie_ep_func_select()
62 struct dw_pcie_ep *ep = &pci->ep; in __dw_pcie_ep_reset_bar()
81 funcs = pci->ep.epc->max_functions; in dw_pcie_ep_reset_bar()
138 dw_pcie_writew_dbi(pci, func_offset + PCI_VENDOR_ID, hdr->vendorid); in dw_pcie_ep_write_header()
139 dw_pcie_writew_dbi(pci, func_offset + PCI_DEVICE_ID, hdr->deviceid); in dw_pcie_ep_write_header()
140 dw_pcie_writeb_dbi(pci, func_offset + PCI_REVISION_ID, hdr->revid); in dw_pcie_ep_write_header()
141 dw_pcie_writeb_dbi(pci, func_offset + PCI_CLASS_PROG, hdr->progif_code); in dw_pcie_ep_write_header()
143 hdr->subclass_code | hdr->baseclass_code << 8); in dw_pcie_ep_write_header()
145 hdr->cache_line_size); in dw_pcie_ep_write_header()
147 hdr->subsys_vendor_id); in dw_pcie_ep_write_header()
148 dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_ID, hdr->subsys_id); in dw_pcie_ep_write_header()
150 hdr->interrupt_pin); in dw_pcie_ep_write_header()
164 free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows); in dw_pcie_ep_inbound_atu()
165 if (free_win >= ep->num_ib_windows) { in dw_pcie_ep_inbound_atu()
166 dev_err(pci->dev, "No free inbound window\n"); in dw_pcie_ep_inbound_atu()
167 return -EINVAL; in dw_pcie_ep_inbound_atu()
173 dev_err(pci->dev, "Failed to program IB window\n"); in dw_pcie_ep_inbound_atu()
177 ep->bar_to_atu[bar] = free_win; in dw_pcie_ep_inbound_atu()
178 set_bit(free_win, ep->ib_window_map); in dw_pcie_ep_inbound_atu()
190 free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows); in dw_pcie_ep_outbound_atu()
191 if (free_win >= ep->num_ob_windows) { in dw_pcie_ep_outbound_atu()
192 dev_err(pci->dev, "No free outbound window\n"); in dw_pcie_ep_outbound_atu()
193 return -EINVAL; in dw_pcie_ep_outbound_atu()
199 set_bit(free_win, ep->ob_window_map); in dw_pcie_ep_outbound_atu()
200 ep->outbound_addr[free_win] = phys_addr; in dw_pcie_ep_outbound_atu()
210 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_clear_bar()
211 u32 atu_index = ep->bar_to_atu[bar]; in dw_pcie_ep_clear_bar()
213 __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags); in dw_pcie_ep_clear_bar()
216 clear_bit(atu_index, ep->ib_window_map); in dw_pcie_ep_clear_bar()
217 ep->epf_bar[bar] = NULL; in dw_pcie_ep_clear_bar()
226 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_set_bar()
227 size_t size = epf_bar->size; in dw_pcie_ep_set_bar()
228 int flags = epf_bar->flags; in dw_pcie_ep_set_bar()
243 epf_bar->phys_addr, as_type); in dw_pcie_ep_set_bar()
249 dw_pcie_writel_dbi2(pci, reg, lower_32_bits(size - 1)); in dw_pcie_ep_set_bar()
253 dw_pcie_writel_dbi2(pci, reg + 4, upper_32_bits(size - 1)); in dw_pcie_ep_set_bar()
257 ep->epf_bar[bar] = epf_bar; in dw_pcie_ep_set_bar()
268 for (index = 0; index < ep->num_ob_windows; index++) { in dw_pcie_find_index()
269 if (ep->outbound_addr[index] != addr) in dw_pcie_find_index()
275 return -EINVAL; in dw_pcie_find_index()
291 clear_bit(atu_index, ep->ob_window_map); in dw_pcie_ep_unmap_addr()
304 dev_err(pci->dev, "Failed to enable address\n"); in dw_pcie_ep_map_addr()
320 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_get_msi()
321 return -EINVAL; in dw_pcie_ep_get_msi()
325 reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS; in dw_pcie_ep_get_msi()
328 return -EINVAL; in dw_pcie_ep_get_msi()
344 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_set_msi()
345 return -EINVAL; in dw_pcie_ep_set_msi()
349 reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS; in dw_pcie_ep_set_msi()
369 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_get_msix()
370 return -EINVAL; in dw_pcie_ep_get_msix()
374 reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS; in dw_pcie_ep_get_msix()
377 return -EINVAL; in dw_pcie_ep_get_msix()
394 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_set_msix()
395 return -EINVAL; in dw_pcie_ep_set_msix()
401 reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS; in dw_pcie_ep_set_msix()
407 reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE; in dw_pcie_ep_set_msix()
411 reg = ep_func->msix_cap + func_offset + PCI_MSIX_PBA; in dw_pcie_ep_set_msix()
425 if (!ep->ops->raise_irq) in dw_pcie_ep_raise_irq()
426 return -EINVAL; in dw_pcie_ep_raise_irq()
428 return ep->ops->raise_irq(ep, func_no, type, interrupt_num); in dw_pcie_ep_raise_irq()
436 if (!pci->ops->stop_link) in dw_pcie_ep_stop()
439 pci->ops->stop_link(pci); in dw_pcie_ep_stop()
447 if (!pci->ops->start_link) in dw_pcie_ep_start()
448 return -EINVAL; in dw_pcie_ep_start()
450 return pci->ops->start_link(pci); in dw_pcie_ep_start()
458 if (!ep->ops->get_features) in dw_pcie_ep_get_features()
461 return ep->ops->get_features(ep); in dw_pcie_ep_get_features()
483 struct device *dev = pci->dev; in dw_pcie_ep_raise_legacy_irq()
487 return -EINVAL; in dw_pcie_ep_raise_legacy_irq()
495 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msi_irq()
505 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_raise_msi_irq()
506 return -EINVAL; in dw_pcie_ep_raise_msi_irq()
511 reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS; in dw_pcie_ep_raise_msi_irq()
514 reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_LO; in dw_pcie_ep_raise_msi_irq()
517 reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_HI; in dw_pcie_ep_raise_msi_irq()
519 reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_64; in dw_pcie_ep_raise_msi_irq()
523 reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_32; in dw_pcie_ep_raise_msi_irq()
526 aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1); in dw_pcie_ep_raise_msi_irq()
529 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msi_irq()
530 epc->mem->window.page_size); in dw_pcie_ep_raise_msi_irq()
534 writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset); in dw_pcie_ep_raise_msi_irq()
536 dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys); in dw_pcie_ep_raise_msi_irq()
549 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq_doorbell()
550 return -EINVAL; in dw_pcie_ep_raise_msix_irq_doorbell()
553 (interrupt_num - 1); in dw_pcie_ep_raise_msix_irq_doorbell()
566 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msix_irq()
576 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq()
577 return -EINVAL; in dw_pcie_ep_raise_msix_irq()
581 reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE; in dw_pcie_ep_raise_msix_irq()
586 msix_tbl = ep->epf_bar[bir]->addr + tbl_offset; in dw_pcie_ep_raise_msix_irq()
587 msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr; in dw_pcie_ep_raise_msix_irq()
588 msg_data = msix_tbl[(interrupt_num - 1)].msg_data; in dw_pcie_ep_raise_msix_irq()
589 vec_ctrl = msix_tbl[(interrupt_num - 1)].vector_ctrl; in dw_pcie_ep_raise_msix_irq()
592 dev_dbg(pci->dev, "MSI-X entry ctrl set\n"); in dw_pcie_ep_raise_msix_irq()
593 return -EPERM; in dw_pcie_ep_raise_msix_irq()
596 aligned_offset = msg_addr & (epc->mem->window.page_size - 1); in dw_pcie_ep_raise_msix_irq()
597 msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); in dw_pcie_ep_raise_msix_irq()
598 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msix_irq()
599 epc->mem->window.page_size); in dw_pcie_ep_raise_msix_irq()
603 writel(msg_data, ep->msi_mem + aligned_offset); in dw_pcie_ep_raise_msix_irq()
605 dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys); in dw_pcie_ep_raise_msix_irq()
612 struct pci_epc *epc = ep->epc; in dw_pcie_ep_exit()
614 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, in dw_pcie_ep_exit()
615 epc->mem->window.page_size); in dw_pcie_ep_exit()
650 dev_err(pci->dev, in dw_pcie_ep_init_complete()
651 "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n", in dw_pcie_ep_init_complete()
653 return -EIO; in dw_pcie_ep_init_complete()
683 struct device *dev = pci->dev; in dw_pcie_ep_init()
684 struct device_node *np = dev->of_node; in dw_pcie_ep_init()
688 INIT_LIST_HEAD(&ep->func_list); in dw_pcie_ep_init()
690 if (!pci->dbi_base || !pci->dbi_base2) { in dw_pcie_ep_init()
692 return -EINVAL; in dw_pcie_ep_init()
695 ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows); in dw_pcie_ep_init()
697 dev_err(dev, "Unable to read *num-ib-windows* property\n"); in dw_pcie_ep_init()
700 if (ep->num_ib_windows > MAX_IATU_IN) { in dw_pcie_ep_init()
701 dev_err(dev, "Invalid *num-ib-windows*\n"); in dw_pcie_ep_init()
702 return -EINVAL; in dw_pcie_ep_init()
705 ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows); in dw_pcie_ep_init()
707 dev_err(dev, "Unable to read *num-ob-windows* property\n"); in dw_pcie_ep_init()
710 if (ep->num_ob_windows > MAX_IATU_OUT) { in dw_pcie_ep_init()
711 dev_err(dev, "Invalid *num-ob-windows*\n"); in dw_pcie_ep_init()
712 return -EINVAL; in dw_pcie_ep_init()
715 ep->ib_window_map = devm_kcalloc(dev, in dw_pcie_ep_init()
716 BITS_TO_LONGS(ep->num_ib_windows), in dw_pcie_ep_init()
719 if (!ep->ib_window_map) in dw_pcie_ep_init()
720 return -ENOMEM; in dw_pcie_ep_init()
722 ep->ob_window_map = devm_kcalloc(dev, in dw_pcie_ep_init()
723 BITS_TO_LONGS(ep->num_ob_windows), in dw_pcie_ep_init()
726 if (!ep->ob_window_map) in dw_pcie_ep_init()
727 return -ENOMEM; in dw_pcie_ep_init()
729 addr = devm_kcalloc(dev, ep->num_ob_windows, sizeof(phys_addr_t), in dw_pcie_ep_init()
732 return -ENOMEM; in dw_pcie_ep_init()
733 ep->outbound_addr = addr; in dw_pcie_ep_init()
735 if (pci->link_gen < 1) in dw_pcie_ep_init()
736 pci->link_gen = of_pci_get_max_link_speed(np); in dw_pcie_ep_init()
744 ep->epc = epc; in dw_pcie_ep_init()
747 ret = of_property_read_u8(np, "max-functions", &epc->max_functions); in dw_pcie_ep_init()
749 epc->max_functions = 1; in dw_pcie_ep_init()
751 for (func_no = 0; func_no < epc->max_functions; func_no++) { in dw_pcie_ep_init()
754 return -ENOMEM; in dw_pcie_ep_init()
756 ep_func->func_no = func_no; in dw_pcie_ep_init()
757 ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init()
759 ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init()
762 list_add_tail(&ep_func->list, &ep->func_list); in dw_pcie_ep_init()
765 if (ep->ops->ep_init) in dw_pcie_ep_init()
766 ep->ops->ep_init(ep); in dw_pcie_ep_init()
768 ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size, in dw_pcie_ep_init()
769 ep->page_size); in dw_pcie_ep_init()
775 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, in dw_pcie_ep_init()
776 epc->mem->window.page_size); in dw_pcie_ep_init()
777 if (!ep->msi_mem) { in dw_pcie_ep_init()
778 ret = -ENOMEM; in dw_pcie_ep_init()
779 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n"); in dw_pcie_ep_init()
783 if (ep->ops->get_features) { in dw_pcie_ep_init()
784 epc_features = ep->ops->get_features(ep); in dw_pcie_ep_init()
785 if (epc_features->core_init_notifier) in dw_pcie_ep_init()
796 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, in dw_pcie_ep_init()
797 epc->mem->window.page_size); in dw_pcie_ep_init()