Lines Matching +full:msi +full:- +full:x

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2018 - 2020 Microchip Corporation. All rights reserved.
13 #include <linux/msi.h>
17 #include <linux/pci-ecam.h>
22 /* Number of MSI IRQs */
88 /* PCIe Config space MSI capability structure */
195 #define PCIE_EVENT_CAUSE(x, s) \ argument
196 [EVENT_PCIE_ ## x] = { __stringify(x), s }
198 #define SEC_ERROR_CAUSE(x, s) \ argument
199 [EVENT_SEC_ ## x] = { __stringify(x), s }
201 #define DED_ERROR_CAUSE(x, s) \ argument
202 [EVENT_DED_ ## x] = { __stringify(x), s }
204 #define LOCAL_EVENT_CAUSE(x, s) \ argument
205 [EVENT_LOCAL_ ## x] = { __stringify(x), s }
207 #define PCIE_EVENT(x) \ argument
212 .mask = PCIE_EVENT_INT_ ## x ## _INT, \
215 #define SEC_EVENT(x) \ argument
219 .mask = SEC_ERROR_INT_ ## x ## _INT, \
223 #define DED_EVENT(x) \ argument
228 .mask = DED_ERROR_INT_ ## x ## _INT, \
231 #define LOCAL_EVENT(x) \ argument
236 .mask = x ## _MASK, \
239 #define PCIE_EVENT_TO_EVENT_MAP(x) \ argument
240 { PCIE_EVENT_INT_ ## x ## _INT, EVENT_PCIE_ ## x }
242 #define SEC_ERROR_TO_EVENT_MAP(x) \ argument
243 { SEC_ERROR_INT_ ## x ## _INT, EVENT_SEC_ ## x }
245 #define DED_ERROR_TO_EVENT_MAP(x) \ argument
246 { DED_ERROR_INT_ ## x ## _INT, EVENT_DED_ ## x }
248 #define LOCAL_STATUS_TO_EVENT_MAP(x) \ argument
249 { x ## _MASK, EVENT_LOCAL_ ## x }
271 struct mc_msi msi; member
387 struct mc_msi *msi = &port->msi; in mc_pcie_enable_msi() local
400 writel_relaxed(lower_32_bits(msi->vector_phy), in mc_pcie_enable_msi()
402 writel_relaxed(upper_32_bits(msi->vector_phy), in mc_pcie_enable_msi()
410 struct device *dev = port->dev; in mc_handle_msi()
411 struct mc_msi *msi = &port->msi; in mc_handle_msi() local
413 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_handle_msi()
424 for_each_set_bit(bit, &status, msi->num_vectors) { in mc_handle_msi()
425 ret = generic_handle_domain_irq(msi->dev_domain, bit); in mc_handle_msi()
427 dev_err_ratelimited(dev, "bad MSI IRQ %d\n", in mc_handle_msi()
439 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_msi_bottom_irq_ack()
440 u32 bitpos = data->hwirq; in mc_msi_bottom_irq_ack()
448 phys_addr_t addr = port->msi.vector_phy; in mc_compose_msi_msg()
450 msg->address_lo = lower_32_bits(addr); in mc_compose_msi_msg()
451 msg->address_hi = upper_32_bits(addr); in mc_compose_msi_msg()
452 msg->data = data->hwirq; in mc_compose_msi_msg()
454 dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n", in mc_compose_msi_msg()
455 (int)data->hwirq, msg->address_hi, msg->address_lo); in mc_compose_msi_msg()
461 return -EINVAL; in mc_msi_set_affinity()
465 .name = "Microchip MSI",
474 struct mc_pcie *port = domain->host_data; in mc_irq_msi_domain_alloc()
475 struct mc_msi *msi = &port->msi; in mc_irq_msi_domain_alloc() local
477 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_irq_msi_domain_alloc()
481 mutex_lock(&msi->lock); in mc_irq_msi_domain_alloc()
482 bit = find_first_zero_bit(msi->used, msi->num_vectors); in mc_irq_msi_domain_alloc()
483 if (bit >= msi->num_vectors) { in mc_irq_msi_domain_alloc()
484 mutex_unlock(&msi->lock); in mc_irq_msi_domain_alloc()
485 return -ENOSPC; in mc_irq_msi_domain_alloc()
488 set_bit(bit, msi->used); in mc_irq_msi_domain_alloc()
491 domain->host_data, handle_edge_irq, NULL, NULL); in mc_irq_msi_domain_alloc()
493 /* Enable MSI interrupts */ in mc_irq_msi_domain_alloc()
498 mutex_unlock(&msi->lock); in mc_irq_msi_domain_alloc()
508 struct mc_msi *msi = &port->msi; in mc_irq_msi_domain_free() local
510 mutex_lock(&msi->lock); in mc_irq_msi_domain_free()
512 if (test_bit(d->hwirq, msi->used)) in mc_irq_msi_domain_free()
513 __clear_bit(d->hwirq, msi->used); in mc_irq_msi_domain_free()
515 dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq); in mc_irq_msi_domain_free()
517 mutex_unlock(&msi->lock); in mc_irq_msi_domain_free()
526 .name = "Microchip PCIe MSI",
540 struct device *dev = port->dev; in mc_allocate_msi_domains()
541 struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node); in mc_allocate_msi_domains()
542 struct mc_msi *msi = &port->msi; in mc_allocate_msi_domains() local
544 mutex_init(&port->msi.lock); in mc_allocate_msi_domains()
546 msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors, in mc_allocate_msi_domains()
548 if (!msi->dev_domain) { in mc_allocate_msi_domains()
550 return -ENOMEM; in mc_allocate_msi_domains()
553 msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info, in mc_allocate_msi_domains()
554 msi->dev_domain); in mc_allocate_msi_domains()
555 if (!msi->msi_domain) { in mc_allocate_msi_domains()
556 dev_err(dev, "failed to create MSI domain\n"); in mc_allocate_msi_domains()
557 irq_domain_remove(msi->dev_domain); in mc_allocate_msi_domains()
558 return -ENOMEM; in mc_allocate_msi_domains()
568 struct device *dev = port->dev; in mc_handle_intx()
570 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_handle_intx()
582 ret = generic_handle_domain_irq(port->intx_domain, bit); in mc_handle_intx()
596 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_ack_intx_irq()
597 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT); in mc_ack_intx_irq()
606 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_mask_intx_irq()
608 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT); in mc_mask_intx_irq()
611 raw_spin_lock_irqsave(&port->lock, flags); in mc_mask_intx_irq()
615 raw_spin_unlock_irqrestore(&port->lock, flags); in mc_mask_intx_irq()
622 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_unmask_intx_irq()
624 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT); in mc_unmask_intx_irq()
627 raw_spin_lock_irqsave(&port->lock, flags); in mc_unmask_intx_irq()
631 raw_spin_unlock_irqrestore(&port->lock, flags); in mc_unmask_intx_irq()
645 irq_set_chip_data(irq, domain->host_data); in mc_pcie_intx_map()
710 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in get_events()
711 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in get_events()
725 struct device *dev = port->dev; in mc_event_handler()
728 data = irq_domain_get_irq_data(port->event_domain, irq); in mc_event_handler()
730 if (event_cause[data->hwirq].str) in mc_event_handler()
731 dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str); in mc_event_handler()
733 dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq); in mc_event_handler()
750 generic_handle_domain_irq(port->event_domain, bit); in mc_handle_event()
758 u32 event = data->hwirq; in mc_ack_event_irq()
762 addr = port->axi_base_addr + event_descs[event].base + in mc_ack_event_irq()
773 u32 event = data->hwirq; in mc_mask_event_irq()
778 addr = port->axi_base_addr + event_descs[event].base + in mc_mask_event_irq()
789 raw_spin_lock(&port->lock); in mc_mask_event_irq()
797 raw_spin_unlock(&port->lock); in mc_mask_event_irq()
803 u32 event = data->hwirq; in mc_unmask_event_irq()
808 addr = port->axi_base_addr + event_descs[event].base + in mc_unmask_event_irq()
821 raw_spin_lock(&port->lock); in mc_unmask_event_irq()
828 raw_spin_unlock(&port->lock); in mc_unmask_event_irq()
842 irq_set_chip_data(irq, domain->host_data); in mc_pcie_event_map()
892 struct device *dev = port->dev; in mc_pcie_init_irq_domains()
893 struct device_node *node = dev->of_node; in mc_pcie_init_irq_domains()
900 return -EINVAL; in mc_pcie_init_irq_domains()
903 port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS, in mc_pcie_init_irq_domains()
905 if (!port->event_domain) { in mc_pcie_init_irq_domains()
908 return -ENOMEM; in mc_pcie_init_irq_domains()
911 irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS); in mc_pcie_init_irq_domains()
913 port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, in mc_pcie_init_irq_domains()
915 if (!port->intx_domain) { in mc_pcie_init_irq_domains()
918 return -ENOMEM; in mc_pcie_init_irq_domains()
921 irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED); in mc_pcie_init_irq_domains()
924 raw_spin_lock_init(&port->lock); in mc_pcie_init_irq_domains()
933 u32 atr_sz = ilog2(size) - 1; in mc_pcie_setup_window()
971 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_pcie_setup_windows()
977 resource_list_for_each_entry(entry, &bridge->windows) { in mc_pcie_setup_windows()
978 if (resource_type(entry->res) == IORESOURCE_MEM) { in mc_pcie_setup_windows()
979 pci_addr = entry->res->start - entry->offset; in mc_pcie_setup_windows()
981 entry->res->start, pci_addr, in mc_pcie_setup_windows()
982 resource_size(entry->res)); in mc_pcie_setup_windows()
992 struct device *dev = cfg->parent; in mc_platform_init()
1005 return -ENOMEM; in mc_platform_init()
1006 port->dev = dev; in mc_platform_init()
1011 return -ENODEV; in mc_platform_init()
1014 port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1); in mc_platform_init()
1015 if (IS_ERR(port->axi_base_addr)) in mc_platform_init()
1016 return PTR_ERR(port->axi_base_addr); in mc_platform_init()
1018 bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_platform_init()
1019 ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in mc_platform_init()
1021 port->msi.vector_phy = MSI_ADDR; in mc_platform_init()
1022 port->msi.num_vectors = MC_NUM_MSI_IRQS; in mc_platform_init()
1031 return -ENODEV; in mc_platform_init()
1034 event_irq = irq_create_mapping(port->event_domain, i); in mc_platform_init()
1037 return -ENXIO; in mc_platform_init()
1048 intx_irq = irq_create_mapping(port->event_domain, in mc_platform_init()
1052 return -ENXIO; in mc_platform_init()
1058 msi_irq = irq_create_mapping(port->event_domain, in mc_platform_init()
1061 return -ENXIO; in mc_platform_init()
1063 /* Plug the MSI chained handler */ in mc_platform_init()
1069 /* Hardware doesn't setup MSI by default */ in mc_platform_init()
1070 mc_pcie_enable_msi(port, cfg->win); in mc_platform_init()
1103 mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start & 0xffffffff, in mc_platform_init()
1104 cfg->res.start, resource_size(&cfg->res)); in mc_platform_init()
1120 .compatible = "microchip,pcie-host-1.0",
1131 .name = "microchip-pcie",