Lines Matching +full:msi +full:- +full:x
1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe driver for Renesas R-Car SoCs
7 * arch/sh/drivers/pci/pcie-sh7786.c
8 * arch/sh/drivers/pci/ops-sh7786.c
9 * Copyright (C) 2009 - 2011 Paul Mundt
22 #include <linux/msi.h>
62 #define PCIEPRAR(x) (0x02080 + ((x) * 0x4)) argument
65 #define PCIELAR(x) (0x02200 + ((x) * 0x20)) argument
66 #define PCIELAMR(x) (0x02208 + ((x) * 0x20)) argument
72 #define PCIEPALR(x) (0x03400 + ((x) * 0x20)) argument
73 #define PCIEPAUR(x) (0x03404 + ((x) * 0x20)) argument
74 #define PCIEPAMR(x) (0x03408 + ((x) * 0x20)) argument
75 #define PCIEPTCTLR(x) (0x0340c + ((x) * 0x20)) argument
80 #define PCICONF(x) (0x010000 + ((x) * 0x4)) argument
81 #define PMCAP(x) (0x010040 + ((x) * 0x4)) argument
82 #define EXPCAP(x) (0x010070 + ((x) * 0x4)) argument
83 #define VCCAP(x) (0x010100 + ((x) * 0x4)) argument
106 /* R-Car H1 PHY */
115 /* R-Car Gen2 PHY */
122 #define RCONF(x) (PCICONF(0) + (x)) argument
123 #define RPMCAP(x) (PMCAP(0) + (x)) argument
124 #define REXPCAP(x) (EXPCAP(0) + (x)) argument
125 #define RVCCAP(x) (VCCAP(0) + (x)) argument
157 struct rcar_msi msi; member
163 writel(val, pcie->base + reg); in rcar_pci_write_reg()
169 return readl(pcie->base + reg); in rcar_pci_read_reg()
208 * While each channel has its own memory-mapped extended config in rcar_pcie_config_access()
216 * the same channel <-> device access works for any PCI_SLOT() in rcar_pcie_config_access()
218 * space to devfn 0 in order to enable self-enumeration. In this in rcar_pcie_config_access()
231 pcie->root_bus_nr = *data & 0xff; in rcar_pcie_config_access()
239 if (pcie->root_bus_nr < 0) in rcar_pcie_config_access()
246 rcar_pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) | in rcar_pcie_config_access()
250 if (bus->parent->number == pcie->root_bus_nr) in rcar_pcie_config_access()
278 struct rcar_pcie *pcie = bus->sysdata; in rcar_pcie_read_conf()
293 dev_dbg(&bus->dev, "pcie-config-read: bus=%3d devfn=0x%04x where=0x%04x size=%d val=0x%08lx\n", in rcar_pcie_read_conf()
294 bus->number, devfn, where, size, (unsigned long)*val); in rcar_pcie_read_conf()
303 struct rcar_pcie *pcie = bus->sysdata; in rcar_pcie_write_conf()
312 dev_dbg(&bus->dev, "pcie-config-write: bus=%3d devfn=0x%04x where=0x%04x size=%d val=0x%08lx\n", in rcar_pcie_write_conf()
313 bus->number, devfn, where, size, (unsigned long)val); in rcar_pcie_write_conf()
343 struct resource *res = window->res; in rcar_pcie_setup_window()
353 mask = (roundup_pow_of_two(size) / SZ_128) - 1; in rcar_pcie_setup_window()
356 if (res->flags & IORESOURCE_IO) in rcar_pcie_setup_window()
357 res_start = pci_pio_to_address(res->start) - window->offset; in rcar_pcie_setup_window()
359 res_start = res->start - window->offset; in rcar_pcie_setup_window()
367 if (res->flags & IORESOURCE_IO) in rcar_pcie_setup_window()
379 resource_list_for_each_entry(win, &pci->resources) { in rcar_pcie_setup()
380 struct resource *res = win->res; in rcar_pcie_setup()
382 if (!res->flags) in rcar_pcie_setup()
392 pci->root_bus_nr = res->start; in rcar_pcie_setup()
406 struct device *dev = pcie->dev; in rcar_pcie_force_speedup()
436 while (timeout--) { in rcar_pcie_force_speedup()
460 struct device *dev = pcie->dev; in rcar_pcie_enable()
468 rcar_pcie_setup(&bridge->windows, pcie); in rcar_pcie_enable()
472 bridge->dev.parent = dev; in rcar_pcie_enable()
473 bridge->sysdata = pcie; in rcar_pcie_enable()
474 bridge->busnr = pcie->root_bus_nr; in rcar_pcie_enable()
475 bridge->ops = &rcar_pcie_ops; in rcar_pcie_enable()
476 bridge->map_irq = of_irq_parse_and_map_pci; in rcar_pcie_enable()
477 bridge->swizzle_irq = pci_common_swizzle; in rcar_pcie_enable()
479 bridge->msi = &pcie->msi.chip; in rcar_pcie_enable()
485 bus = bridge->bus; in rcar_pcie_enable()
490 list_for_each_entry(child, &bus->children, node) in rcar_pcie_enable()
500 struct device *dev = pcie->dev; in phy_wait_for_ack()
503 while (timeout--) { in phy_wait_for_ack()
512 return -ETIMEDOUT; in phy_wait_for_ack()
545 while (timeout--) { in rcar_pcie_wait_for_phyrdy()
552 return -ETIMEDOUT; in rcar_pcie_wait_for_phyrdy()
559 while (timeout--) { in rcar_pcie_wait_for_dl()
567 return -ETIMEDOUT; in rcar_pcie_wait_for_dl()
618 /* Enable MSI */ in rcar_pcie_hw_init()
624 /* Finish initialization - establish a PCI Express link */ in rcar_pcie_hw_init()
666 * These settings come from the R-Car Series, 2nd Generation User's in rcar_pcie_phy_init_gen2()
687 err = phy_init(pcie->phy); in rcar_pcie_phy_init_gen3()
691 err = phy_power_on(pcie->phy); in rcar_pcie_phy_init_gen3()
693 phy_exit(pcie->phy); in rcar_pcie_phy_init_gen3()
700 int msi; in rcar_msi_alloc() local
702 mutex_lock(&chip->lock); in rcar_msi_alloc()
704 msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR); in rcar_msi_alloc()
705 if (msi < INT_PCI_MSI_NR) in rcar_msi_alloc()
706 set_bit(msi, chip->used); in rcar_msi_alloc()
708 msi = -ENOSPC; in rcar_msi_alloc()
710 mutex_unlock(&chip->lock); in rcar_msi_alloc()
712 return msi; in rcar_msi_alloc()
717 int msi; in rcar_msi_alloc_region() local
719 mutex_lock(&chip->lock); in rcar_msi_alloc_region()
720 msi = bitmap_find_free_region(chip->used, INT_PCI_MSI_NR, in rcar_msi_alloc_region()
722 mutex_unlock(&chip->lock); in rcar_msi_alloc_region()
724 return msi; in rcar_msi_alloc_region()
729 mutex_lock(&chip->lock); in rcar_msi_free()
730 clear_bit(irq, chip->used); in rcar_msi_free()
731 mutex_unlock(&chip->lock); in rcar_msi_free()
737 struct rcar_msi *msi = &pcie->msi; in rcar_pcie_msi_irq() local
738 struct device *dev = pcie->dev; in rcar_pcie_msi_irq()
743 /* MSI & INTx share an interrupt - we only handle MSI here */ in rcar_pcie_msi_irq()
754 irq = irq_find_mapping(msi->domain, index); in rcar_pcie_msi_irq()
756 if (test_bit(index, msi->used)) in rcar_pcie_msi_irq()
759 dev_info(dev, "unhandled MSI\n"); in rcar_pcie_msi_irq()
761 /* Unknown MSI, just clear it */ in rcar_pcie_msi_irq()
762 dev_dbg(dev, "unexpected MSI\n"); in rcar_pcie_msi_irq()
775 struct rcar_msi *msi = to_rcar_msi(chip); in rcar_msi_setup_irq() local
776 struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip); in rcar_msi_setup_irq()
781 hwirq = rcar_msi_alloc(msi); in rcar_msi_setup_irq()
785 irq = irq_find_mapping(msi->domain, hwirq); in rcar_msi_setup_irq()
787 rcar_msi_free(msi, hwirq); in rcar_msi_setup_irq()
788 return -EINVAL; in rcar_msi_setup_irq()
805 struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip); in rcar_msi_setup_irqs()
806 struct rcar_msi *msi = to_rcar_msi(chip); in rcar_msi_setup_irqs() local
813 /* MSI-X interrupts are not supported */ in rcar_msi_setup_irqs()
815 return -EINVAL; in rcar_msi_setup_irqs()
817 WARN_ON(!list_is_singular(&pdev->dev.msi_list)); in rcar_msi_setup_irqs()
818 desc = list_entry(pdev->dev.msi_list.next, struct msi_desc, list); in rcar_msi_setup_irqs()
820 hwirq = rcar_msi_alloc_region(msi, nvec); in rcar_msi_setup_irqs()
822 return -ENOSPC; in rcar_msi_setup_irqs()
824 irq = irq_find_mapping(msi->domain, hwirq); in rcar_msi_setup_irqs()
826 return -ENOSPC; in rcar_msi_setup_irqs()
830 * irq_create_mapping() called from rcar_pcie_probe() pre- in rcar_msi_setup_irqs()
833 * returns non-zero, then the descs are also successfully in rcar_msi_setup_irqs()
838 return -EINVAL; in rcar_msi_setup_irqs()
842 desc->nvec_used = nvec; in rcar_msi_setup_irqs()
843 desc->msi_attrib.multiple = order_base_2(nvec); in rcar_msi_setup_irqs()
856 struct rcar_msi *msi = to_rcar_msi(chip); in rcar_msi_teardown_irq() local
859 rcar_msi_free(msi, d->hwirq); in rcar_msi_teardown_irq()
863 .name = "R-Car PCIe MSI",
874 irq_set_chip_data(irq, domain->host_data); in rcar_msi_map()
885 struct rcar_msi *msi = &pcie->msi; in rcar_pcie_unmap_msi() local
889 irq = irq_find_mapping(msi->domain, i); in rcar_pcie_unmap_msi()
894 irq_domain_remove(msi->domain); in rcar_pcie_unmap_msi()
899 struct device *dev = pcie->dev; in rcar_pcie_enable_msi()
900 struct rcar_msi *msi = &pcie->msi; in rcar_pcie_enable_msi() local
904 mutex_init(&msi->lock); in rcar_pcie_enable_msi()
906 msi->chip.dev = dev; in rcar_pcie_enable_msi()
907 msi->chip.setup_irq = rcar_msi_setup_irq; in rcar_pcie_enable_msi()
908 msi->chip.setup_irqs = rcar_msi_setup_irqs; in rcar_pcie_enable_msi()
909 msi->chip.teardown_irq = rcar_msi_teardown_irq; in rcar_pcie_enable_msi()
911 msi->domain = irq_domain_add_linear(dev->of_node, INT_PCI_MSI_NR, in rcar_pcie_enable_msi()
912 &msi_domain_ops, &msi->chip); in rcar_pcie_enable_msi()
913 if (!msi->domain) { in rcar_pcie_enable_msi()
915 return -ENOMEM; in rcar_pcie_enable_msi()
919 irq_create_mapping(msi->domain, i); in rcar_pcie_enable_msi()
921 /* Two irqs are for MSI, but they are also used for non-MSI irqs */ in rcar_pcie_enable_msi()
922 err = devm_request_irq(dev, msi->irq1, rcar_pcie_msi_irq, in rcar_pcie_enable_msi()
930 err = devm_request_irq(dev, msi->irq2, rcar_pcie_msi_irq, in rcar_pcie_enable_msi()
938 /* setup MSI data target */ in rcar_pcie_enable_msi()
939 msi->pages = __get_free_pages(GFP_KERNEL, 0); in rcar_pcie_enable_msi()
940 if (!msi->pages) { in rcar_pcie_enable_msi()
941 err = -ENOMEM; in rcar_pcie_enable_msi()
944 base = virt_to_phys((void *)msi->pages); in rcar_pcie_enable_msi()
949 /* enable all MSI interrupts */ in rcar_pcie_enable_msi()
961 struct rcar_msi *msi = &pcie->msi; in rcar_pcie_teardown_msi() local
963 /* Disable all MSI interrupts */ in rcar_pcie_teardown_msi()
966 /* Disable address decoding of the MSI interrupt, MSIFE */ in rcar_pcie_teardown_msi()
969 free_pages(msi->pages, 0); in rcar_pcie_teardown_msi()
976 struct device *dev = pcie->dev; in rcar_pcie_get_resources()
980 pcie->phy = devm_phy_optional_get(dev, "pcie"); in rcar_pcie_get_resources()
981 if (IS_ERR(pcie->phy)) in rcar_pcie_get_resources()
982 return PTR_ERR(pcie->phy); in rcar_pcie_get_resources()
984 err = of_address_to_resource(dev->of_node, 0, &res); in rcar_pcie_get_resources()
988 pcie->base = devm_ioremap_resource(dev, &res); in rcar_pcie_get_resources()
989 if (IS_ERR(pcie->base)) in rcar_pcie_get_resources()
990 return PTR_ERR(pcie->base); in rcar_pcie_get_resources()
992 pcie->bus_clk = devm_clk_get(dev, "pcie_bus"); in rcar_pcie_get_resources()
993 if (IS_ERR(pcie->bus_clk)) { in rcar_pcie_get_resources()
995 return PTR_ERR(pcie->bus_clk); in rcar_pcie_get_resources()
998 i = irq_of_parse_and_map(dev->of_node, 0); in rcar_pcie_get_resources()
1000 dev_err(dev, "cannot get platform resources for msi interrupt\n"); in rcar_pcie_get_resources()
1001 err = -ENOENT; in rcar_pcie_get_resources()
1004 pcie->msi.irq1 = i; in rcar_pcie_get_resources()
1006 i = irq_of_parse_and_map(dev->of_node, 1); in rcar_pcie_get_resources()
1008 dev_err(dev, "cannot get platform resources for msi interrupt\n"); in rcar_pcie_get_resources()
1009 err = -ENOENT; in rcar_pcie_get_resources()
1012 pcie->msi.irq2 = i; in rcar_pcie_get_resources()
1017 irq_dispose_mapping(pcie->msi.irq1); in rcar_pcie_get_resources()
1026 u64 restype = range->flags; in rcar_pcie_inbound_ranges()
1027 u64 cpu_addr = range->cpu_addr; in rcar_pcie_inbound_ranges()
1028 u64 cpu_end = range->cpu_addr + range->size; in rcar_pcie_inbound_ranges()
1029 u64 pci_addr = range->pci_addr; in rcar_pcie_inbound_ranges()
1046 size = min(range->size, alignment); in rcar_pcie_inbound_ranges()
1048 size = range->size; in rcar_pcie_inbound_ranges()
1053 mask = roundup_pow_of_two(size) - 1; in rcar_pcie_inbound_ranges()
1058 * Set up 64-bit inbound regions as the range parser doesn't in rcar_pcie_inbound_ranges()
1059 * distinguish between 32 and 64-bit types. in rcar_pcie_inbound_ranges()
1078 dev_err(pcie->dev, "Failed to map inbound regions!\n"); in rcar_pcie_inbound_ranges()
1079 return -EINVAL; in rcar_pcie_inbound_ranges()
1096 return -EINVAL; in rcar_pcie_parse_map_dma_ranges()
1098 /* Get the dma-ranges from DT */ in rcar_pcie_parse_map_dma_ranges()
1100 u64 end = range.cpu_addr + range.size - 1; in rcar_pcie_parse_map_dma_ranges()
1102 dev_dbg(pcie->dev, "0x%08x 0x%016llx..0x%016llx -> 0x%016llx\n", in rcar_pcie_parse_map_dma_ranges()
1114 { .compatible = "renesas,pcie-r8a7779",
1116 { .compatible = "renesas,pcie-r8a7790",
1118 { .compatible = "renesas,pcie-r8a7791",
1120 { .compatible = "renesas,pcie-rcar-gen2",
1122 { .compatible = "renesas,pcie-r8a7795",
1124 { .compatible = "renesas,pcie-rcar-gen3",
1131 struct device *dev = &pdev->dev; in rcar_pcie_probe()
1140 return -ENOMEM; in rcar_pcie_probe()
1144 pcie->dev = dev; in rcar_pcie_probe()
1147 err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL); in rcar_pcie_probe()
1151 pm_runtime_enable(pcie->dev); in rcar_pcie_probe()
1152 err = pm_runtime_get_sync(pcie->dev); in rcar_pcie_probe()
1154 dev_err(pcie->dev, "pm_runtime_get_sync failed\n"); in rcar_pcie_probe()
1164 err = clk_prepare_enable(pcie->bus_clk); in rcar_pcie_probe()
1170 err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); in rcar_pcie_probe()
1184 err = -ENODEV; in rcar_pcie_probe()
1189 dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f); in rcar_pcie_probe()
1195 "failed to enable MSI support: %d\n", in rcar_pcie_probe()
1212 if (pcie->phy) { in rcar_pcie_probe()
1213 phy_power_off(pcie->phy); in rcar_pcie_probe()
1214 phy_exit(pcie->phy); in rcar_pcie_probe()
1218 clk_disable_unprepare(pcie->bus_clk); in rcar_pcie_probe()
1221 irq_dispose_mapping(pcie->msi.irq2); in rcar_pcie_probe()
1222 irq_dispose_mapping(pcie->msi.irq1); in rcar_pcie_probe()
1229 pci_free_resource_list(&pcie->resources); in rcar_pcie_probe()
1245 /* Re-establish the PCIe link */ in rcar_pcie_resume_noirq()
1257 .name = "rcar-pcie",