Lines Matching +full:pci +full:- +full:ep
1 // SPDX-License-Identifier: GPL-2.0
13 #include "pcie-designware.h"
14 #include <linux/pci-epc.h>
15 #include <linux/pci-epf.h>
17 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) in dw_pcie_ep_linkup() argument
19 struct pci_epc *epc = ep->epc; in dw_pcie_ep_linkup()
25 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep) in dw_pcie_ep_init_notify() argument
27 struct pci_epc *epc = ep->epc; in dw_pcie_ep_init_notify()
34 dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no) in dw_pcie_ep_get_func_from_ep() argument
38 list_for_each_entry(ep_func, &ep->func_list, list) { in dw_pcie_ep_get_func_from_ep()
39 if (ep_func->func_no == func_no) in dw_pcie_ep_get_func_from_ep()
46 static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8 func_no) in dw_pcie_ep_func_select() argument
50 if (ep->ops->func_conf_select) in dw_pcie_ep_func_select()
51 func_offset = ep->ops->func_conf_select(ep, func_no); in dw_pcie_ep_func_select()
56 static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no, in __dw_pcie_ep_reset_bar() argument
61 struct dw_pcie_ep *ep = &pci->ep; in __dw_pcie_ep_reset_bar() local
63 func_offset = dw_pcie_ep_func_select(ep, func_no); in __dw_pcie_ep_reset_bar()
66 dw_pcie_dbi_ro_wr_en(pci); in __dw_pcie_ep_reset_bar()
67 dw_pcie_writel_dbi2(pci, reg, 0x0); in __dw_pcie_ep_reset_bar()
68 dw_pcie_writel_dbi(pci, reg, 0x0); in __dw_pcie_ep_reset_bar()
70 dw_pcie_writel_dbi2(pci, reg + 4, 0x0); in __dw_pcie_ep_reset_bar()
71 dw_pcie_writel_dbi(pci, reg + 4, 0x0); in __dw_pcie_ep_reset_bar()
73 dw_pcie_dbi_ro_wr_dis(pci); in __dw_pcie_ep_reset_bar()
76 void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) in dw_pcie_ep_reset_bar() argument
80 funcs = pci->ep.epc->max_functions; in dw_pcie_ep_reset_bar()
83 __dw_pcie_ep_reset_bar(pci, func_no, bar, 0); in dw_pcie_ep_reset_bar()
87 static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no, in __dw_pcie_ep_find_next_cap() argument
90 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in __dw_pcie_ep_find_next_cap() local
98 func_offset = dw_pcie_ep_func_select(ep, func_no); in __dw_pcie_ep_find_next_cap()
100 reg = dw_pcie_readw_dbi(pci, func_offset + cap_ptr); in __dw_pcie_ep_find_next_cap()
110 return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); in __dw_pcie_ep_find_next_cap()
113 static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap) in dw_pcie_ep_find_capability() argument
115 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_find_capability() local
120 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_find_capability()
122 reg = dw_pcie_readw_dbi(pci, func_offset + PCI_CAPABILITY_LIST); in dw_pcie_ep_find_capability()
125 return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); in dw_pcie_ep_find_capability()
131 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_write_header() local
132 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_write_header() local
135 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_write_header()
137 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_write_header()
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()
142 dw_pcie_writew_dbi(pci, func_offset + PCI_CLASS_DEVICE, in dw_pcie_ep_write_header()
143 hdr->subclass_code | hdr->baseclass_code << 8); in dw_pcie_ep_write_header()
144 dw_pcie_writeb_dbi(pci, func_offset + PCI_CACHE_LINE_SIZE, in dw_pcie_ep_write_header()
145 hdr->cache_line_size); in dw_pcie_ep_write_header()
146 dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_VENDOR_ID, 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()
149 dw_pcie_writeb_dbi(pci, func_offset + PCI_INTERRUPT_PIN, in dw_pcie_ep_write_header()
150 hdr->interrupt_pin); in dw_pcie_ep_write_header()
151 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_write_header()
156 static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type, in dw_pcie_ep_inbound_atu() argument
161 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_inbound_atu() local
163 if (!ep->bar_to_atu[bar]) in dw_pcie_ep_inbound_atu()
164 free_win = find_first_zero_bit(ep->ib_window_map, pci->num_ib_windows); in dw_pcie_ep_inbound_atu()
166 free_win = ep->bar_to_atu[bar] - 1; in dw_pcie_ep_inbound_atu()
168 if (free_win >= pci->num_ib_windows) { in dw_pcie_ep_inbound_atu()
169 dev_err(pci->dev, "No free inbound window\n"); in dw_pcie_ep_inbound_atu()
170 return -EINVAL; in dw_pcie_ep_inbound_atu()
173 ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type, in dw_pcie_ep_inbound_atu()
176 dev_err(pci->dev, "Failed to program IB window\n"); in dw_pcie_ep_inbound_atu()
184 ep->bar_to_atu[bar] = free_win + 1; in dw_pcie_ep_inbound_atu()
185 set_bit(free_win, ep->ib_window_map); in dw_pcie_ep_inbound_atu()
190 static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no, in dw_pcie_ep_outbound_atu() argument
194 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_outbound_atu() local
198 free_win = find_first_zero_bit(ep->ob_window_map, pci->num_ob_windows); in dw_pcie_ep_outbound_atu()
199 if (free_win >= pci->num_ob_windows) { in dw_pcie_ep_outbound_atu()
200 dev_err(pci->dev, "No free outbound window\n"); in dw_pcie_ep_outbound_atu()
201 return -EINVAL; in dw_pcie_ep_outbound_atu()
204 ret = dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win, PCIE_ATU_TYPE_MEM, in dw_pcie_ep_outbound_atu()
209 set_bit(free_win, ep->ob_window_map); in dw_pcie_ep_outbound_atu()
210 ep->outbound_addr[free_win] = phys_addr; in dw_pcie_ep_outbound_atu()
218 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_clear_bar() local
219 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_clear_bar() local
220 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_clear_bar()
221 u32 atu_index = ep->bar_to_atu[bar] - 1; in dw_pcie_ep_clear_bar()
223 if (!ep->bar_to_atu[bar]) in dw_pcie_ep_clear_bar()
226 __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags); in dw_pcie_ep_clear_bar()
228 dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); in dw_pcie_ep_clear_bar()
229 clear_bit(atu_index, ep->ib_window_map); in dw_pcie_ep_clear_bar()
230 ep->epf_bar[bar] = NULL; in dw_pcie_ep_clear_bar()
231 ep->bar_to_atu[bar] = 0; in dw_pcie_ep_clear_bar()
237 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_set_bar() local
238 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_set_bar() local
239 enum pci_barno bar = epf_bar->barno; in dw_pcie_ep_set_bar()
240 size_t size = epf_bar->size; in dw_pcie_ep_set_bar()
241 int flags = epf_bar->flags; in dw_pcie_ep_set_bar()
246 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_set_bar()
255 ret = dw_pcie_ep_inbound_atu(ep, func_no, type, epf_bar->phys_addr, bar); in dw_pcie_ep_set_bar()
259 if (ep->epf_bar[bar]) in dw_pcie_ep_set_bar()
262 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_set_bar()
264 dw_pcie_writel_dbi2(pci, reg, lower_32_bits(size - 1)); in dw_pcie_ep_set_bar()
265 dw_pcie_writel_dbi(pci, reg, flags); in dw_pcie_ep_set_bar()
268 dw_pcie_writel_dbi2(pci, reg + 4, upper_32_bits(size - 1)); in dw_pcie_ep_set_bar()
269 dw_pcie_writel_dbi(pci, reg + 4, 0); in dw_pcie_ep_set_bar()
272 ep->epf_bar[bar] = epf_bar; in dw_pcie_ep_set_bar()
273 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_set_bar()
278 static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, in dw_pcie_find_index() argument
282 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_find_index() local
284 for (index = 0; index < pci->num_ob_windows; index++) { in dw_pcie_find_index()
285 if (ep->outbound_addr[index] != addr) in dw_pcie_find_index()
291 return -EINVAL; in dw_pcie_find_index()
299 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_unmap_addr() local
300 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_unmap_addr() local
302 ret = dw_pcie_find_index(ep, addr, &atu_index); in dw_pcie_ep_unmap_addr()
306 dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, atu_index); in dw_pcie_ep_unmap_addr()
307 clear_bit(atu_index, ep->ob_window_map); in dw_pcie_ep_unmap_addr()
314 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_map_addr() local
315 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_map_addr() local
317 ret = dw_pcie_ep_outbound_atu(ep, func_no, addr, pci_addr, size); in dw_pcie_ep_map_addr()
319 dev_err(pci->dev, "Failed to enable address\n"); in dw_pcie_ep_map_addr()
328 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_get_msi() local
329 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_get_msi() local
334 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_get_msi()
335 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_get_msi()
336 return -EINVAL; in dw_pcie_ep_get_msi()
338 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_get_msi()
340 reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS; in dw_pcie_ep_get_msi()
341 val = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_get_msi()
343 return -EINVAL; in dw_pcie_ep_get_msi()
353 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_set_msi() local
354 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_set_msi() local
359 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_set_msi()
360 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_set_msi()
361 return -EINVAL; in dw_pcie_ep_set_msi()
363 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_set_msi()
365 reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS; in dw_pcie_ep_set_msi()
366 val = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_set_msi()
369 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_set_msi()
370 dw_pcie_writew_dbi(pci, reg, val); in dw_pcie_ep_set_msi()
371 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_set_msi()
378 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_get_msix() local
379 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_get_msix() local
384 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_get_msix()
385 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_get_msix()
386 return -EINVAL; in dw_pcie_ep_get_msix()
388 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_get_msix()
390 reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS; in dw_pcie_ep_get_msix()
391 val = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_get_msix()
393 return -EINVAL; in dw_pcie_ep_get_msix()
403 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_set_msix() local
404 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_set_msix() local
409 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_set_msix()
410 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_set_msix()
411 return -EINVAL; in dw_pcie_ep_set_msix()
413 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_set_msix()
415 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_set_msix()
417 reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS; in dw_pcie_ep_set_msix()
418 val = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_set_msix()
421 dw_pcie_writew_dbi(pci, reg, val); in dw_pcie_ep_set_msix()
423 reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE; in dw_pcie_ep_set_msix()
425 dw_pcie_writel_dbi(pci, reg, val); in dw_pcie_ep_set_msix()
427 reg = ep_func->msix_cap + func_offset + PCI_MSIX_PBA; in dw_pcie_ep_set_msix()
429 dw_pcie_writel_dbi(pci, reg, val); in dw_pcie_ep_set_msix()
431 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_set_msix()
439 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_raise_irq() local
441 if (!ep->ops->raise_irq) in dw_pcie_ep_raise_irq()
442 return -EINVAL; in dw_pcie_ep_raise_irq()
444 return ep->ops->raise_irq(ep, func_no, type, interrupt_num); in dw_pcie_ep_raise_irq()
449 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_stop() local
450 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_stop() local
452 dw_pcie_stop_link(pci); in dw_pcie_ep_stop()
457 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_start() local
458 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_start() local
460 return dw_pcie_start_link(pci); in dw_pcie_ep_start()
466 struct dw_pcie_ep *ep = epc_get_drvdata(epc); in dw_pcie_ep_get_features() local
468 if (!ep->ops->get_features) in dw_pcie_ep_get_features()
471 return ep->ops->get_features(ep); in dw_pcie_ep_get_features()
490 int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) in dw_pcie_ep_raise_legacy_irq() argument
492 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_legacy_irq() local
493 struct device *dev = pci->dev; in dw_pcie_ep_raise_legacy_irq()
495 dev_err(dev, "EP cannot trigger legacy IRQs\n"); in dw_pcie_ep_raise_legacy_irq()
497 return -EINVAL; in dw_pcie_ep_raise_legacy_irq()
501 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, in dw_pcie_ep_raise_msi_irq() argument
504 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_msi_irq() local
506 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msi_irq()
515 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_raise_msi_irq()
516 if (!ep_func || !ep_func->msi_cap) in dw_pcie_ep_raise_msi_irq()
517 return -EINVAL; in dw_pcie_ep_raise_msi_irq()
519 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_raise_msi_irq()
521 /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */ in dw_pcie_ep_raise_msi_irq()
522 reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS; in dw_pcie_ep_raise_msi_irq()
523 msg_ctrl = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_raise_msi_irq()
525 reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_LO; in dw_pcie_ep_raise_msi_irq()
526 msg_addr_lower = dw_pcie_readl_dbi(pci, reg); in dw_pcie_ep_raise_msi_irq()
528 reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_HI; in dw_pcie_ep_raise_msi_irq()
529 msg_addr_upper = dw_pcie_readl_dbi(pci, reg); in dw_pcie_ep_raise_msi_irq()
530 reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_64; in dw_pcie_ep_raise_msi_irq()
531 msg_data = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_raise_msi_irq()
534 reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_32; in dw_pcie_ep_raise_msi_irq()
535 msg_data = dw_pcie_readw_dbi(pci, reg); in dw_pcie_ep_raise_msi_irq()
537 aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1); in dw_pcie_ep_raise_msi_irq()
540 ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msi_irq()
541 epc->mem->window.page_size); in dw_pcie_ep_raise_msi_irq()
545 writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset); in dw_pcie_ep_raise_msi_irq()
547 dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); in dw_pcie_ep_raise_msi_irq()
553 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
556 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_msix_irq_doorbell() local
560 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_raise_msix_irq_doorbell()
561 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq_doorbell()
562 return -EINVAL; in dw_pcie_ep_raise_msix_irq_doorbell()
565 (interrupt_num - 1); in dw_pcie_ep_raise_msix_irq_doorbell()
567 dw_pcie_writel_dbi(pci, PCIE_MSIX_DOORBELL, msg_data); in dw_pcie_ep_raise_msix_irq_doorbell()
572 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, in dw_pcie_ep_raise_msix_irq() argument
575 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_raise_msix_irq() local
578 struct pci_epc *epc = ep->epc; in dw_pcie_ep_raise_msix_irq()
587 ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); in dw_pcie_ep_raise_msix_irq()
588 if (!ep_func || !ep_func->msix_cap) in dw_pcie_ep_raise_msix_irq()
589 return -EINVAL; in dw_pcie_ep_raise_msix_irq()
591 func_offset = dw_pcie_ep_func_select(ep, func_no); in dw_pcie_ep_raise_msix_irq()
593 reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE; in dw_pcie_ep_raise_msix_irq()
594 tbl_offset = dw_pcie_readl_dbi(pci, reg); in dw_pcie_ep_raise_msix_irq()
598 msix_tbl = ep->epf_bar[bir]->addr + tbl_offset; in dw_pcie_ep_raise_msix_irq()
599 msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr; in dw_pcie_ep_raise_msix_irq()
600 msg_data = msix_tbl[(interrupt_num - 1)].msg_data; in dw_pcie_ep_raise_msix_irq()
601 vec_ctrl = msix_tbl[(interrupt_num - 1)].vector_ctrl; in dw_pcie_ep_raise_msix_irq()
604 dev_dbg(pci->dev, "MSI-X entry ctrl set\n"); in dw_pcie_ep_raise_msix_irq()
605 return -EPERM; in dw_pcie_ep_raise_msix_irq()
608 aligned_offset = msg_addr & (epc->mem->window.page_size - 1); in dw_pcie_ep_raise_msix_irq()
609 msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); in dw_pcie_ep_raise_msix_irq()
610 ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, in dw_pcie_ep_raise_msix_irq()
611 epc->mem->window.page_size); in dw_pcie_ep_raise_msix_irq()
615 writel(msg_data, ep->msi_mem + aligned_offset); in dw_pcie_ep_raise_msix_irq()
617 dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); in dw_pcie_ep_raise_msix_irq()
622 void dw_pcie_ep_exit(struct dw_pcie_ep *ep) in dw_pcie_ep_exit() argument
624 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_exit() local
625 struct pci_epc *epc = ep->epc; in dw_pcie_ep_exit()
627 dw_pcie_edma_remove(pci); in dw_pcie_ep_exit()
629 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, in dw_pcie_ep_exit()
630 epc->mem->window.page_size); in dw_pcie_ep_exit()
635 static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) in dw_pcie_ep_find_ext_capability() argument
641 header = dw_pcie_readl_dbi(pci, pos); in dw_pcie_ep_find_ext_capability()
653 int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) in dw_pcie_ep_init_complete() argument
655 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_init_complete() local
662 hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & in dw_pcie_ep_init_complete()
665 dev_err(pci->dev, in dw_pcie_ep_init_complete()
666 "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n", in dw_pcie_ep_init_complete()
668 return -EIO; in dw_pcie_ep_init_complete()
671 offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR); in dw_pcie_ep_init_complete()
672 ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM); in dw_pcie_ep_init_complete()
674 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_init_complete()
677 reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL); in dw_pcie_ep_init_complete()
687 dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, BIT(4)); in dw_pcie_ep_init_complete()
695 dw_pcie_dbi_ro_wr_en(pci); in dw_pcie_ep_init_complete()
696 reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP); in dw_pcie_ep_init_complete()
698 dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg); in dw_pcie_ep_init_complete()
700 reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP); in dw_pcie_ep_init_complete()
702 dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg); in dw_pcie_ep_init_complete()
703 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_init_complete()
706 dw_pcie_setup(pci); in dw_pcie_ep_init_complete()
707 dw_pcie_dbi_ro_wr_dis(pci); in dw_pcie_ep_init_complete()
713 int dw_pcie_ep_init(struct dw_pcie_ep *ep) in dw_pcie_ep_init() argument
720 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dw_pcie_ep_init() local
721 struct device *dev = pci->dev; in dw_pcie_ep_init()
723 struct device_node *np = dev->of_node; in dw_pcie_ep_init()
727 INIT_LIST_HEAD(&ep->func_list); in dw_pcie_ep_init()
729 ret = dw_pcie_get_resources(pci); in dw_pcie_ep_init()
735 return -EINVAL; in dw_pcie_ep_init()
737 ep->phys_base = res->start; in dw_pcie_ep_init()
738 ep->addr_size = resource_size(res); in dw_pcie_ep_init()
740 dw_pcie_version_detect(pci); in dw_pcie_ep_init()
742 dw_pcie_iatu_detect(pci); in dw_pcie_ep_init()
744 ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, in dw_pcie_ep_init()
746 if (!ep->ib_window_map) in dw_pcie_ep_init()
747 return -ENOMEM; in dw_pcie_ep_init()
749 ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, in dw_pcie_ep_init()
751 if (!ep->ob_window_map) in dw_pcie_ep_init()
752 return -ENOMEM; in dw_pcie_ep_init()
754 addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), in dw_pcie_ep_init()
757 return -ENOMEM; in dw_pcie_ep_init()
758 ep->outbound_addr = addr; in dw_pcie_ep_init()
766 ep->epc = epc; in dw_pcie_ep_init()
767 epc_set_drvdata(epc, ep); in dw_pcie_ep_init()
769 ret = of_property_read_u8(np, "max-functions", &epc->max_functions); in dw_pcie_ep_init()
771 epc->max_functions = 1; in dw_pcie_ep_init()
773 for (func_no = 0; func_no < epc->max_functions; func_no++) { in dw_pcie_ep_init()
776 return -ENOMEM; in dw_pcie_ep_init()
778 ep_func->func_no = func_no; in dw_pcie_ep_init()
779 ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init()
781 ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, in dw_pcie_ep_init()
784 list_add_tail(&ep_func->list, &ep->func_list); in dw_pcie_ep_init()
787 if (ep->ops->ep_init) in dw_pcie_ep_init()
788 ep->ops->ep_init(ep); in dw_pcie_ep_init()
790 ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size, in dw_pcie_ep_init()
791 ep->page_size); in dw_pcie_ep_init()
797 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, in dw_pcie_ep_init()
798 epc->mem->window.page_size); in dw_pcie_ep_init()
799 if (!ep->msi_mem) { in dw_pcie_ep_init()
800 ret = -ENOMEM; in dw_pcie_ep_init()
801 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n"); in dw_pcie_ep_init()
805 ret = dw_pcie_edma_detect(pci); in dw_pcie_ep_init()
809 if (ep->ops->get_features) { in dw_pcie_ep_init()
810 epc_features = ep->ops->get_features(ep); in dw_pcie_ep_init()
811 if (epc_features->core_init_notifier) in dw_pcie_ep_init()
815 ret = dw_pcie_ep_init_complete(ep); in dw_pcie_ep_init()
822 dw_pcie_edma_remove(pci); in dw_pcie_ep_init()
825 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, in dw_pcie_ep_init()
826 epc->mem->window.page_size); in dw_pcie_ep_init()