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

1 // SPDX-License-Identifier: GPL-2.0+
3 * Rockchip AXI PCIe endpoint controller driver
7 * Author: Shawn Lin <shawn.lin@rock-chips.com>
8 * Simon Xue <xxm@rock-chips.com>
15 #include <linux/pci-epc.h>
17 #include <linux/pci-epf.h>
20 #include "pcie-rockchip.h"
23 * struct rockchip_pcie_ep - private data for PCIe endpoint controller driver
24 * @rockchip: Rockchip PCIe controller
33 * IRQ) TLP through the PCIe bus.
74 u64 sz = 1ULL << fls64(size - 1); in rockchip_pcie_prog_ep_ob_atu()
83 cpu_addr -= rockchip->mem_res->start; in rockchip_pcie_prog_ep_ob_atu()
84 addr0 = ((is_nor_msg ? 0x10 : (num_pass_bits - 1)) & in rockchip_pcie_prog_ep_ob_atu()
112 ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) | in rockchip_pcie_prog_ep_ob_atu()
128 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_write_header() local
129 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_write_header()
133 u32 vid_regs = (hdr->vendorid & GENMASK(15, 0)) | in rockchip_pcie_ep_write_header()
134 (hdr->subsys_vendor_id & GENMASK(31, 16)) << 16; in rockchip_pcie_ep_write_header()
140 rockchip_pcie_write(rockchip, hdr->deviceid << 16, in rockchip_pcie_ep_write_header()
144 hdr->revid | in rockchip_pcie_ep_write_header()
145 hdr->progif_code << 8 | in rockchip_pcie_ep_write_header()
146 hdr->subclass_code << 16 | in rockchip_pcie_ep_write_header()
147 hdr->baseclass_code << 24, in rockchip_pcie_ep_write_header()
149 rockchip_pcie_write(rockchip, hdr->cache_line_size, in rockchip_pcie_ep_write_header()
152 rockchip_pcie_write(rockchip, hdr->subsys_id << 16, in rockchip_pcie_ep_write_header()
155 rockchip_pcie_write(rockchip, hdr->interrupt_pin << 8, in rockchip_pcie_ep_write_header()
165 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_set_bar() local
166 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_set_bar()
167 dma_addr_t bar_phys = epf_bar->phys_addr; in rockchip_pcie_ep_set_bar()
168 enum pci_barno bar = epf_bar->barno; in rockchip_pcie_ep_set_bar()
169 int flags = epf_bar->flags; in rockchip_pcie_ep_set_bar()
174 sz = max_t(size_t, epf_bar->size, MIN_EP_APERTURE); in rockchip_pcie_ep_set_bar()
180 sz = 1ULL << fls64(sz - 1); in rockchip_pcie_ep_set_bar()
181 aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */ in rockchip_pcie_ep_set_bar()
190 return -EINVAL; in rockchip_pcie_ep_set_bar()
209 b = bar - BAR_4; in rockchip_pcie_ep_set_bar()
233 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_clear_bar() local
234 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_clear_bar()
236 enum pci_barno bar = epf_bar->barno; in rockchip_pcie_ep_clear_bar()
243 b = bar - BAR_4; in rockchip_pcie_ep_clear_bar()
263 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_map_addr() local
264 struct rockchip_pcie *pcie = &ep->rockchip; in rockchip_pcie_ep_map_addr() local
267 r = find_first_zero_bit(&ep->ob_region_map, in rockchip_pcie_ep_map_addr()
268 sizeof(ep->ob_region_map) * BITS_PER_LONG); in rockchip_pcie_ep_map_addr()
273 if (r >= ep->max_regions - 1) { in rockchip_pcie_ep_map_addr()
274 dev_err(&epc->dev, "no free outbound region\n"); in rockchip_pcie_ep_map_addr()
275 return -EINVAL; in rockchip_pcie_ep_map_addr()
278 rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, AXI_WRAPPER_MEM_WRITE, addr, in rockchip_pcie_ep_map_addr()
281 set_bit(r, &ep->ob_region_map); in rockchip_pcie_ep_map_addr()
282 ep->ob_addr[r] = addr; in rockchip_pcie_ep_map_addr()
290 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_unmap_addr() local
291 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_unmap_addr()
294 for (r = 0; r < ep->max_regions - 1; r++) in rockchip_pcie_ep_unmap_addr()
295 if (ep->ob_addr[r] == addr) in rockchip_pcie_ep_unmap_addr()
302 if (r == ep->max_regions - 1) in rockchip_pcie_ep_unmap_addr()
307 ep->ob_addr[r] = 0; in rockchip_pcie_ep_unmap_addr()
308 clear_bit(r, &ep->ob_region_map); in rockchip_pcie_ep_unmap_addr()
314 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_set_msi() local
315 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_set_msi()
334 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_get_msi() local
335 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_get_msi()
342 return -EINVAL; in rockchip_pcie_ep_get_msi()
348 static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn, in rockchip_pcie_ep_assert_intx() argument
351 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_assert_intx()
352 u32 r = ep->max_regions - 1; in rockchip_pcie_ep_assert_intx()
357 if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR || in rockchip_pcie_ep_assert_intx()
358 ep->irq_pci_fn != fn)) { in rockchip_pcie_ep_assert_intx()
361 ep->irq_phys_addr, 0, 0); in rockchip_pcie_ep_assert_intx()
362 ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR; in rockchip_pcie_ep_assert_intx()
363 ep->irq_pci_fn = fn; in rockchip_pcie_ep_assert_intx()
368 ep->irq_pending |= BIT(intx); in rockchip_pcie_ep_assert_intx()
371 ep->irq_pending &= ~BIT(intx); in rockchip_pcie_ep_assert_intx()
380 if ((status != 0) ^ (ep->irq_pending != 0)) { in rockchip_pcie_ep_assert_intx()
390 writel(0, ep->irq_cpu_addr + offset); in rockchip_pcie_ep_assert_intx()
393 static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn, in rockchip_pcie_ep_send_legacy_irq() argument
398 cmd = rockchip_pcie_read(&ep->rockchip, in rockchip_pcie_ep_send_legacy_irq()
403 return -EINVAL; in rockchip_pcie_ep_send_legacy_irq()
410 rockchip_pcie_ep_assert_intx(ep, fn, intx, true); in rockchip_pcie_ep_send_legacy_irq()
412 rockchip_pcie_ep_assert_intx(ep, fn, intx, false); in rockchip_pcie_ep_send_legacy_irq()
416 static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn, in rockchip_pcie_ep_send_msi_irq() argument
419 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_send_msi_irq()
425 flags = rockchip_pcie_read(&ep->rockchip, in rockchip_pcie_ep_send_msi_irq()
429 return -EINVAL; in rockchip_pcie_ep_send_msi_irq()
436 return -EINVAL; in rockchip_pcie_ep_send_msi_irq()
439 data_mask = msi_count - 1; in rockchip_pcie_ep_send_msi_irq()
444 data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask); in rockchip_pcie_ep_send_msi_irq()
459 if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) || in rockchip_pcie_ep_send_msi_irq()
460 ep->irq_pci_fn != fn)) { in rockchip_pcie_ep_send_msi_irq()
461 rockchip_pcie_prog_ep_ob_atu(rockchip, fn, ep->max_regions - 1, in rockchip_pcie_ep_send_msi_irq()
463 ep->irq_phys_addr, in rockchip_pcie_ep_send_msi_irq()
466 ep->irq_pci_addr = (pci_addr & ~pci_addr_mask); in rockchip_pcie_ep_send_msi_irq()
467 ep->irq_pci_fn = fn; in rockchip_pcie_ep_send_msi_irq()
470 writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask)); in rockchip_pcie_ep_send_msi_irq()
478 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_raise_irq() local
482 return rockchip_pcie_ep_send_legacy_irq(ep, fn, 0); in rockchip_pcie_ep_raise_irq()
484 return rockchip_pcie_ep_send_msi_irq(ep, fn, interrupt_num); in rockchip_pcie_ep_raise_irq()
486 return -EINVAL; in rockchip_pcie_ep_raise_irq()
492 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); in rockchip_pcie_ep_start() local
493 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_start()
498 list_for_each_entry(epf, &epc->pci_epf, list) in rockchip_pcie_ep_start()
499 cfg |= BIT(epf->func_no); in rockchip_pcie_ep_start()
532 struct rockchip_pcie_ep *ep) in rockchip_pcie_parse_ep_dt() argument
534 struct device *dev = rockchip->dev; in rockchip_pcie_parse_ep_dt()
545 err = of_property_read_u32(dev->of_node, in rockchip_pcie_parse_ep_dt()
546 "rockchip,max-outbound-regions", in rockchip_pcie_parse_ep_dt()
547 &ep->max_regions); in rockchip_pcie_parse_ep_dt()
548 if (err < 0 || ep->max_regions > MAX_REGION_LIMIT) in rockchip_pcie_parse_ep_dt()
549 ep->max_regions = MAX_REGION_LIMIT; in rockchip_pcie_parse_ep_dt()
551 err = of_property_read_u8(dev->of_node, "max-functions", in rockchip_pcie_parse_ep_dt()
552 &ep->epc->max_functions); in rockchip_pcie_parse_ep_dt()
554 ep->epc->max_functions = 1; in rockchip_pcie_parse_ep_dt()
560 { .compatible = "rockchip,rk3399-pcie-ep"},
566 struct device *dev = &pdev->dev; in rockchip_pcie_ep_probe()
567 struct rockchip_pcie_ep *ep; in rockchip_pcie_ep_probe() local
573 ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL); in rockchip_pcie_ep_probe()
574 if (!ep) in rockchip_pcie_ep_probe()
575 return -ENOMEM; in rockchip_pcie_ep_probe()
577 rockchip = &ep->rockchip; in rockchip_pcie_ep_probe()
578 rockchip->is_rc = false; in rockchip_pcie_ep_probe()
579 rockchip->dev = dev; in rockchip_pcie_ep_probe()
587 ep->epc = epc; in rockchip_pcie_ep_probe()
588 epc_set_drvdata(epc, ep); in rockchip_pcie_ep_probe()
590 err = rockchip_pcie_parse_ep_dt(rockchip, ep); in rockchip_pcie_ep_probe()
606 max_regions = ep->max_regions; in rockchip_pcie_ep_probe()
607 ep->ob_addr = devm_kcalloc(dev, max_regions, sizeof(*ep->ob_addr), in rockchip_pcie_ep_probe()
610 if (!ep->ob_addr) { in rockchip_pcie_ep_probe()
611 err = -ENOMEM; in rockchip_pcie_ep_probe()
618 err = pci_epc_mem_init(epc, rockchip->mem_res->start, in rockchip_pcie_ep_probe()
619 resource_size(rockchip->mem_res), PAGE_SIZE); in rockchip_pcie_ep_probe()
625 ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr, in rockchip_pcie_ep_probe()
627 if (!ep->irq_cpu_addr) { in rockchip_pcie_ep_probe()
629 err = -ENOMEM; in rockchip_pcie_ep_probe()
633 ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR; in rockchip_pcie_ep_probe()
647 .name = "rockchip-pcie-ep",