Lines Matching +full:rockchip +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0+
3 * Rockchip AXI PCIe endpoint controller driver
5 * Copyright (c) 2018 Rockchip, Inc.
7 * Author: Shawn Lin <shawn.lin@rock-chips.com>
8 * Simon Xue <xxm@rock-chips.com>
18 #include <linux/pci-epc.h>
20 #include <linux/pci-epf.h>
24 #include "pcie-rockchip.h"
27 * struct rockchip_pcie_ep - private data for PCIe endpoint controller driver
28 * @rockchip: Rockchip PCIe controller
29 * @epc: PCI EPC device
49 struct rockchip_pcie rockchip; member
65 static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip, in rockchip_pcie_clear_ep_ob_atu() argument
68 rockchip_pcie_write(rockchip, 0, in rockchip_pcie_clear_ep_ob_atu()
70 rockchip_pcie_write(rockchip, 0, in rockchip_pcie_clear_ep_ob_atu()
72 rockchip_pcie_write(rockchip, 0, in rockchip_pcie_clear_ep_ob_atu()
74 rockchip_pcie_write(rockchip, 0, in rockchip_pcie_clear_ep_ob_atu()
78 static int rockchip_pcie_ep_ob_atu_num_bits(struct rockchip_pcie *rockchip, in rockchip_pcie_ep_ob_atu_num_bits() argument
81 int num_pass_bits = fls64(pci_addr ^ (pci_addr + size - 1)); in rockchip_pcie_ep_ob_atu_num_bits()
88 static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn, in rockchip_pcie_prog_ep_ob_atu() argument
95 num_pass_bits = rockchip_pcie_ep_ob_atu_num_bits(rockchip, in rockchip_pcie_prog_ep_ob_atu()
98 addr0 = ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) | in rockchip_pcie_prog_ep_ob_atu()
104 rockchip_pcie_write(rockchip, addr0, in rockchip_pcie_prog_ep_ob_atu()
106 rockchip_pcie_write(rockchip, addr1, in rockchip_pcie_prog_ep_ob_atu()
108 rockchip_pcie_write(rockchip, desc0, in rockchip_pcie_prog_ep_ob_atu()
110 rockchip_pcie_write(rockchip, 0, in rockchip_pcie_prog_ep_ob_atu()
119 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_write_header() local
123 rockchip_pcie_write(rockchip, in rockchip_pcie_ep_write_header()
124 hdr->vendorid | hdr->subsys_vendor_id << 16, in rockchip_pcie_ep_write_header()
128 reg = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_DID_VID); in rockchip_pcie_ep_write_header()
129 reg = (reg & 0xFFFF) | (hdr->deviceid << 16); in rockchip_pcie_ep_write_header()
130 rockchip_pcie_write(rockchip, reg, PCIE_EP_CONFIG_DID_VID); in rockchip_pcie_ep_write_header()
132 rockchip_pcie_write(rockchip, in rockchip_pcie_ep_write_header()
133 hdr->revid | in rockchip_pcie_ep_write_header()
134 hdr->progif_code << 8 | in rockchip_pcie_ep_write_header()
135 hdr->subclass_code << 16 | in rockchip_pcie_ep_write_header()
136 hdr->baseclass_code << 24, in rockchip_pcie_ep_write_header()
138 rockchip_pcie_write(rockchip, hdr->cache_line_size, in rockchip_pcie_ep_write_header()
141 rockchip_pcie_write(rockchip, hdr->subsys_id << 16, in rockchip_pcie_ep_write_header()
144 rockchip_pcie_write(rockchip, hdr->interrupt_pin << 8, in rockchip_pcie_ep_write_header()
155 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_set_bar() local
156 dma_addr_t bar_phys = epf_bar->phys_addr; in rockchip_pcie_ep_set_bar()
157 enum pci_barno bar = epf_bar->barno; in rockchip_pcie_ep_set_bar()
158 int flags = epf_bar->flags; in rockchip_pcie_ep_set_bar()
163 sz = max_t(size_t, epf_bar->size, MIN_EP_APERTURE); in rockchip_pcie_ep_set_bar()
169 sz = 1ULL << fls64(sz - 1); in rockchip_pcie_ep_set_bar()
170 aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */ in rockchip_pcie_ep_set_bar()
179 return -EINVAL; in rockchip_pcie_ep_set_bar()
198 b = bar - BAR_4; in rockchip_pcie_ep_set_bar()
204 cfg = rockchip_pcie_read(rockchip, reg); in rockchip_pcie_ep_set_bar()
210 rockchip_pcie_write(rockchip, cfg, reg); in rockchip_pcie_ep_set_bar()
211 rockchip_pcie_write(rockchip, addr0, in rockchip_pcie_ep_set_bar()
213 rockchip_pcie_write(rockchip, addr1, in rockchip_pcie_ep_set_bar()
223 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_clear_bar() local
225 enum pci_barno bar = epf_bar->barno; in rockchip_pcie_ep_clear_bar()
232 b = bar - BAR_4; in rockchip_pcie_ep_clear_bar()
236 cfg = rockchip_pcie_read(rockchip, reg); in rockchip_pcie_ep_clear_bar()
241 rockchip_pcie_write(rockchip, cfg, reg); in rockchip_pcie_ep_clear_bar()
242 rockchip_pcie_write(rockchip, 0x0, in rockchip_pcie_ep_clear_bar()
244 rockchip_pcie_write(rockchip, 0x0, in rockchip_pcie_ep_clear_bar()
261 num_bits = rockchip_pcie_ep_ob_atu_num_bits(&ep->rockchip, in rockchip_pcie_ep_align_addr()
263 mask = (1ULL << num_bits) - 1; in rockchip_pcie_ep_align_addr()
267 size = SZ_1M - offset; in rockchip_pcie_ep_align_addr()
280 struct rockchip_pcie *pcie = &ep->rockchip; in rockchip_pcie_ep_map_addr()
283 if (test_bit(r, &ep->ob_region_map)) in rockchip_pcie_ep_map_addr()
284 return -EBUSY; in rockchip_pcie_ep_map_addr()
288 set_bit(r, &ep->ob_region_map); in rockchip_pcie_ep_map_addr()
289 ep->ob_addr[r] = addr; in rockchip_pcie_ep_map_addr()
298 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_unmap_addr() local
301 if (addr != ep->ob_addr[r] || !test_bit(r, &ep->ob_region_map)) in rockchip_pcie_ep_unmap_addr()
304 rockchip_pcie_clear_ep_ob_atu(rockchip, r); in rockchip_pcie_ep_unmap_addr()
306 ep->ob_addr[r] = 0; in rockchip_pcie_ep_unmap_addr()
307 clear_bit(r, &ep->ob_region_map); in rockchip_pcie_ep_unmap_addr()
314 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_set_msi() local
317 flags = rockchip_pcie_read(rockchip, in rockchip_pcie_ep_set_msi()
325 rockchip_pcie_write(rockchip, flags, in rockchip_pcie_ep_set_msi()
334 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_get_msi() local
337 flags = rockchip_pcie_read(rockchip, in rockchip_pcie_ep_get_msi()
341 return -EINVAL; in rockchip_pcie_ep_get_msi()
350 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_assert_intx() local
355 ep->irq_pending |= BIT(intx); in rockchip_pcie_ep_assert_intx()
356 rockchip_pcie_write(rockchip, in rockchip_pcie_ep_assert_intx()
361 ep->irq_pending &= ~BIT(intx); in rockchip_pcie_ep_assert_intx()
362 rockchip_pcie_write(rockchip, in rockchip_pcie_ep_assert_intx()
374 cmd = rockchip_pcie_read(&ep->rockchip, in rockchip_pcie_ep_send_intx_irq()
379 return -EINVAL; in rockchip_pcie_ep_send_intx_irq()
395 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_send_msi_irq() local
403 flags = rockchip_pcie_read(&ep->rockchip, in rockchip_pcie_ep_send_msi_irq()
407 return -EINVAL; in rockchip_pcie_ep_send_msi_irq()
414 return -EINVAL; in rockchip_pcie_ep_send_msi_irq()
417 data_mask = msi_count - 1; in rockchip_pcie_ep_send_msi_irq()
418 data = rockchip_pcie_read(rockchip, in rockchip_pcie_ep_send_msi_irq()
422 data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask); in rockchip_pcie_ep_send_msi_irq()
425 pci_addr = rockchip_pcie_read(rockchip, in rockchip_pcie_ep_send_msi_irq()
430 pci_addr |= rockchip_pcie_read(rockchip, in rockchip_pcie_ep_send_msi_irq()
437 irq_pci_addr = rockchip_pcie_ep_align_addr(ep->epc, in rockchip_pcie_ep_send_msi_irq()
440 if (unlikely(ep->irq_pci_addr != irq_pci_addr || in rockchip_pcie_ep_send_msi_irq()
441 ep->irq_pci_fn != fn)) { in rockchip_pcie_ep_send_msi_irq()
442 rockchip_pcie_prog_ep_ob_atu(rockchip, fn, in rockchip_pcie_ep_send_msi_irq()
443 rockchip_ob_region(ep->irq_phys_addr), in rockchip_pcie_ep_send_msi_irq()
444 ep->irq_phys_addr, in rockchip_pcie_ep_send_msi_irq()
446 ep->irq_pci_addr = irq_pci_addr; in rockchip_pcie_ep_send_msi_irq()
447 ep->irq_pci_fn = fn; in rockchip_pcie_ep_send_msi_irq()
450 writew(data, ep->irq_cpu_addr + offset + (pci_addr & ~PCIE_ADDR_MASK)); in rockchip_pcie_ep_send_msi_irq()
465 return -EINVAL; in rockchip_pcie_ep_raise_irq()
472 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_start() local
477 list_for_each_entry(epf, &epc->pci_epf, list) in rockchip_pcie_ep_start()
478 cfg |= BIT(epf->func_no); in rockchip_pcie_ep_start()
480 rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG); in rockchip_pcie_ep_start()
482 if (rockchip->perst_gpio) in rockchip_pcie_ep_start()
483 enable_irq(ep->perst_irq); in rockchip_pcie_ep_start()
486 rockchip_pcie_write(rockchip, in rockchip_pcie_ep_start()
491 if (!rockchip->perst_gpio) in rockchip_pcie_ep_start()
492 schedule_delayed_work(&ep->link_training, 0); in rockchip_pcie_ep_start()
500 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_stop() local
502 if (rockchip->perst_gpio) { in rockchip_pcie_ep_stop()
503 ep->perst_asserted = true; in rockchip_pcie_ep_stop()
504 disable_irq(ep->perst_irq); in rockchip_pcie_ep_stop()
507 cancel_delayed_work_sync(&ep->link_training); in rockchip_pcie_ep_stop()
510 rockchip_pcie_write(rockchip, in rockchip_pcie_ep_stop()
516 static void rockchip_pcie_ep_retrain_link(struct rockchip_pcie *rockchip) in rockchip_pcie_ep_retrain_link() argument
520 status = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_LCS); in rockchip_pcie_ep_retrain_link()
522 rockchip_pcie_write(rockchip, status, PCIE_EP_CONFIG_LCS); in rockchip_pcie_ep_retrain_link()
525 static bool rockchip_pcie_ep_link_up(struct rockchip_pcie *rockchip) in rockchip_pcie_ep_link_up() argument
527 u32 val = rockchip_pcie_read(rockchip, PCIE_CLIENT_BASIC_STATUS1); in rockchip_pcie_ep_link_up()
536 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_link_training() local
537 struct device *dev = rockchip->dev; in rockchip_pcie_ep_link_training()
542 ret = readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL, in rockchip_pcie_ep_link_training()
549 ret = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_BASIC_STATUS1, in rockchip_pcie_ep_link_training()
559 val = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); in rockchip_pcie_ep_link_training()
560 if (!PCIE_LINK_IS_GEN2(val) && rockchip->link_gen == 2) { in rockchip_pcie_ep_link_training()
562 rockchip_pcie_ep_retrain_link(rockchip); in rockchip_pcie_ep_link_training()
563 readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL, in rockchip_pcie_ep_link_training()
569 if (!rockchip_pcie_ep_link_up(rockchip)) in rockchip_pcie_ep_link_training()
576 if (ep->perst_asserted) in rockchip_pcie_ep_link_training()
579 val = rockchip_pcie_read(rockchip, PCIE_CLIENT_BASIC_STATUS0); in rockchip_pcie_ep_link_training()
587 pci_epc_linkup(ep->epc); in rockchip_pcie_ep_link_training()
588 ep->link_up = true; in rockchip_pcie_ep_link_training()
593 schedule_delayed_work(&ep->link_training, msecs_to_jiffies(5)); in rockchip_pcie_ep_link_training()
598 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_perst_assert() local
600 dev_dbg(rockchip->dev, "PERST# asserted, link down\n"); in rockchip_pcie_ep_perst_assert()
602 if (ep->perst_asserted) in rockchip_pcie_ep_perst_assert()
605 ep->perst_asserted = true; in rockchip_pcie_ep_perst_assert()
607 cancel_delayed_work_sync(&ep->link_training); in rockchip_pcie_ep_perst_assert()
609 if (ep->link_up) { in rockchip_pcie_ep_perst_assert()
610 pci_epc_linkdown(ep->epc); in rockchip_pcie_ep_perst_assert()
611 ep->link_up = false; in rockchip_pcie_ep_perst_assert()
617 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_perst_deassert() local
619 dev_dbg(rockchip->dev, "PERST# de-asserted, starting link training\n"); in rockchip_pcie_ep_perst_deassert()
621 if (!ep->perst_asserted) in rockchip_pcie_ep_perst_deassert()
624 ep->perst_asserted = false; in rockchip_pcie_ep_perst_deassert()
626 /* Enable link re-training */ in rockchip_pcie_ep_perst_deassert()
627 rockchip_pcie_ep_retrain_link(rockchip); in rockchip_pcie_ep_perst_deassert()
630 schedule_delayed_work(&ep->link_training, 0); in rockchip_pcie_ep_perst_deassert()
637 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_perst_irq_thread() local
638 u32 perst = gpiod_get_value(rockchip->perst_gpio); in rockchip_pcie_ep_perst_irq_thread()
645 irq_set_irq_type(ep->perst_irq, in rockchip_pcie_ep_perst_irq_thread()
654 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_setup_irq() local
655 struct device *dev = rockchip->dev; in rockchip_pcie_ep_setup_irq()
658 if (!rockchip->perst_gpio) in rockchip_pcie_ep_setup_irq()
662 ep->perst_irq = gpiod_to_irq(rockchip->perst_gpio); in rockchip_pcie_ep_setup_irq()
663 if (ep->perst_irq < 0) { in rockchip_pcie_ep_setup_irq()
666 ep->perst_irq); in rockchip_pcie_ep_setup_irq()
668 return ep->perst_irq; in rockchip_pcie_ep_setup_irq()
676 ep->perst_asserted = true; in rockchip_pcie_ep_setup_irq()
677 irq_set_status_flags(ep->perst_irq, IRQ_NOAUTOEN); in rockchip_pcie_ep_setup_irq()
678 ret = devm_request_threaded_irq(dev, ep->perst_irq, NULL, in rockchip_pcie_ep_setup_irq()
681 "pcie-ep-perst", epc); in rockchip_pcie_ep_setup_irq()
721 static int rockchip_pcie_ep_get_resources(struct rockchip_pcie *rockchip, in rockchip_pcie_ep_get_resources() argument
724 struct device *dev = rockchip->dev; in rockchip_pcie_ep_get_resources()
727 err = rockchip_pcie_parse_dt(rockchip); in rockchip_pcie_ep_get_resources()
731 err = rockchip_pcie_get_phys(rockchip); in rockchip_pcie_ep_get_resources()
735 err = of_property_read_u32(dev->of_node, in rockchip_pcie_ep_get_resources()
736 "rockchip,max-outbound-regions", in rockchip_pcie_ep_get_resources()
737 &ep->max_regions); in rockchip_pcie_ep_get_resources()
738 if (err < 0 || ep->max_regions > MAX_REGION_LIMIT) in rockchip_pcie_ep_get_resources()
739 ep->max_regions = MAX_REGION_LIMIT; in rockchip_pcie_ep_get_resources()
741 ep->ob_region_map = 0; in rockchip_pcie_ep_get_resources()
743 err = of_property_read_u8(dev->of_node, "max-functions", in rockchip_pcie_ep_get_resources()
744 &ep->epc->max_functions); in rockchip_pcie_ep_get_resources()
746 ep->epc->max_functions = 1; in rockchip_pcie_ep_get_resources()
752 { .compatible = "rockchip,rk3399-pcie-ep"},
758 struct rockchip_pcie *rockchip = &ep->rockchip; in rockchip_pcie_ep_init_ob_mem() local
759 struct device *dev = rockchip->dev; in rockchip_pcie_ep_init_ob_mem()
763 ep->ob_addr = devm_kcalloc(dev, ep->max_regions, sizeof(*ep->ob_addr), in rockchip_pcie_ep_init_ob_mem()
766 if (!ep->ob_addr) in rockchip_pcie_ep_init_ob_mem()
767 return -ENOMEM; in rockchip_pcie_ep_init_ob_mem()
769 windows = devm_kcalloc(dev, ep->max_regions, in rockchip_pcie_ep_init_ob_mem()
772 return -ENOMEM; in rockchip_pcie_ep_init_ob_mem()
774 for (i = 0; i < ep->max_regions; i++) { in rockchip_pcie_ep_init_ob_mem()
775 windows[i].phys_base = rockchip->mem_res->start + (SZ_1M * i); in rockchip_pcie_ep_init_ob_mem()
779 err = pci_epc_multi_mem_init(ep->epc, windows, ep->max_regions); in rockchip_pcie_ep_init_ob_mem()
787 ep->irq_cpu_addr = pci_epc_mem_alloc_addr(ep->epc, &ep->irq_phys_addr, in rockchip_pcie_ep_init_ob_mem()
789 if (!ep->irq_cpu_addr) { in rockchip_pcie_ep_init_ob_mem()
791 err = -ENOMEM; in rockchip_pcie_ep_init_ob_mem()
795 ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR; in rockchip_pcie_ep_init_ob_mem()
800 pci_epc_mem_exit(ep->epc); in rockchip_pcie_ep_init_ob_mem()
807 pci_epc_mem_exit(ep->epc); in rockchip_pcie_ep_exit_ob_mem()
810 static void rockchip_pcie_ep_hide_broken_msix_cap(struct rockchip_pcie *rockchip) in rockchip_pcie_ep_hide_broken_msix_cap() argument
815 * MSI-X is not supported but the controller still advertises the MSI-X in rockchip_pcie_ep_hide_broken_msix_cap()
817 * allocating MSI-X vectors which cannot be used. Avoid this by skipping in rockchip_pcie_ep_hide_broken_msix_cap()
818 * the MSI-X capability entry in the PCIe capabilities linked-list: get in rockchip_pcie_ep_hide_broken_msix_cap()
819 * the next pointer from the MSI-X entry and set that in the MSI in rockchip_pcie_ep_hide_broken_msix_cap()
820 * capability entry (which is the previous entry). This way the MSI-X in rockchip_pcie_ep_hide_broken_msix_cap()
821 * entry is skipped (left out of the linked-list) and not advertised. in rockchip_pcie_ep_hide_broken_msix_cap()
823 cfg_msi = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_BASE + in rockchip_pcie_ep_hide_broken_msix_cap()
828 cfg_msix_cp = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_BASE + in rockchip_pcie_ep_hide_broken_msix_cap()
834 rockchip_pcie_write(rockchip, cfg_msi, in rockchip_pcie_ep_hide_broken_msix_cap()
840 struct device *dev = &pdev->dev; in rockchip_pcie_ep_probe()
842 struct rockchip_pcie *rockchip; in rockchip_pcie_ep_probe() local
848 return -ENOMEM; in rockchip_pcie_ep_probe()
850 rockchip = &ep->rockchip; in rockchip_pcie_ep_probe()
851 rockchip->is_rc = false; in rockchip_pcie_ep_probe()
852 rockchip->dev = dev; in rockchip_pcie_ep_probe()
853 INIT_DELAYED_WORK(&ep->link_training, rockchip_pcie_ep_link_training); in rockchip_pcie_ep_probe()
857 dev_err(dev, "failed to create EPC device\n"); in rockchip_pcie_ep_probe()
861 ep->epc = epc; in rockchip_pcie_ep_probe()
864 err = rockchip_pcie_ep_get_resources(rockchip, ep); in rockchip_pcie_ep_probe()
872 err = rockchip_pcie_enable_clocks(rockchip); in rockchip_pcie_ep_probe()
876 err = rockchip_pcie_init_port(rockchip); in rockchip_pcie_ep_probe()
880 rockchip_pcie_ep_hide_broken_msix_cap(rockchip); in rockchip_pcie_ep_probe()
883 rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG); in rockchip_pcie_ep_probe()
893 rockchip_pcie_deinit_phys(rockchip); in rockchip_pcie_ep_probe()
895 rockchip_pcie_disable_clocks(rockchip); in rockchip_pcie_ep_probe()
903 .name = "rockchip-pcie-ep",