Lines Matching +full:axi +full:- +full:pcie +full:- +full:host +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
3 * Microchip AXI PCIe Bridge host controller driver
5 * Copyright (c) 2018 - 2020 Microchip Corporation. All rights reserved.
18 #include <linux/pci-ecam.h>
26 /* PCIe Bridge Phy and Controller Phy offsets */
33 /* PCIe Bridge Phy Regs */
43 #define DMA_END_ENGINE_1_SHIFT 1
89 /* PCIe Master table init defines */
92 #define ATR0_PCIE_ATR_SIZE_SHIFT 1
98 /* PCIe AXI slave table init defines */
100 #define ATR_SIZE_SHIFT 1
101 #define ATR_IMPL_ENABLE 1
111 /* PCIe Controller Phy Regs */
132 #define ECC_CONTROL_TX_RAM_INJ_ERROR_1 BIT(1)
153 #define PCIE_EVENT_INT_HOTRST_EXIT_INT BIT(1)
163 /* PCIe Config space MSI capability structure */
168 #define EVENT_PCIE_HOTRST_EXIT 1
213 .mask_high = 1, \
222 .mask_high = 1, \
229 .mask_high = 1, \
294 LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_1, "dma engine 1 error"),
295 LOCAL_EVENT_CAUSE(A_ATR_EVT_POST_ERR, "axi write request error"),
296 LOCAL_EVENT_CAUSE(A_ATR_EVT_FETCH_ERR, "axi read request error"),
297 LOCAL_EVENT_CAUSE(A_ATR_EVT_DISCARD_ERR, "axi read timeout"),
298 LOCAL_EVENT_CAUSE(P_ATR_EVT_POST_ERR, "pcie write request error"),
299 LOCAL_EVENT_CAUSE(P_ATR_EVT_FETCH_ERR, "pcie read request error"),
300 LOCAL_EVENT_CAUSE(P_ATR_EVT_DISCARD_ERR, "pcie read timeout"),
391 struct mc_msi *msi = &port->msi; in mc_pcie_enable_msi()
406 writel_relaxed(lower_32_bits(msi->vector_phy), in mc_pcie_enable_msi()
408 writel_relaxed(upper_32_bits(msi->vector_phy), in mc_pcie_enable_msi()
416 struct device *dev = port->dev; in mc_handle_msi()
417 struct mc_msi *msi = &port->msi; in mc_handle_msi()
419 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_handle_msi()
430 for_each_set_bit(bit, &status, msi->num_vectors) { in mc_handle_msi()
431 ret = generic_handle_domain_irq(msi->dev_domain, bit); in mc_handle_msi()
445 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_msi_bottom_irq_ack()
446 u32 bitpos = data->hwirq; in mc_msi_bottom_irq_ack()
454 phys_addr_t addr = port->msi.vector_phy; in mc_compose_msi_msg()
456 msg->address_lo = lower_32_bits(addr); in mc_compose_msi_msg()
457 msg->address_hi = upper_32_bits(addr); in mc_compose_msi_msg()
458 msg->data = data->hwirq; in mc_compose_msi_msg()
460 dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n", in mc_compose_msi_msg()
461 (int)data->hwirq, msg->address_hi, msg->address_lo); in mc_compose_msi_msg()
467 return -EINVAL; in mc_msi_set_affinity()
480 struct mc_pcie *port = domain->host_data; in mc_irq_msi_domain_alloc()
481 struct mc_msi *msi = &port->msi; in mc_irq_msi_domain_alloc()
484 mutex_lock(&msi->lock); in mc_irq_msi_domain_alloc()
485 bit = find_first_zero_bit(msi->used, msi->num_vectors); in mc_irq_msi_domain_alloc()
486 if (bit >= msi->num_vectors) { in mc_irq_msi_domain_alloc()
487 mutex_unlock(&msi->lock); in mc_irq_msi_domain_alloc()
488 return -ENOSPC; in mc_irq_msi_domain_alloc()
491 set_bit(bit, msi->used); in mc_irq_msi_domain_alloc()
494 domain->host_data, handle_edge_irq, NULL, NULL); in mc_irq_msi_domain_alloc()
496 mutex_unlock(&msi->lock); in mc_irq_msi_domain_alloc()
506 struct mc_msi *msi = &port->msi; in mc_irq_msi_domain_free()
508 mutex_lock(&msi->lock); in mc_irq_msi_domain_free()
510 if (test_bit(d->hwirq, msi->used)) in mc_irq_msi_domain_free()
511 __clear_bit(d->hwirq, msi->used); in mc_irq_msi_domain_free()
513 dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq); in mc_irq_msi_domain_free()
515 mutex_unlock(&msi->lock); in mc_irq_msi_domain_free()
524 .name = "Microchip PCIe MSI",
538 struct device *dev = port->dev; in mc_allocate_msi_domains()
539 struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node); in mc_allocate_msi_domains()
540 struct mc_msi *msi = &port->msi; in mc_allocate_msi_domains()
542 mutex_init(&port->msi.lock); in mc_allocate_msi_domains()
544 msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors, in mc_allocate_msi_domains()
546 if (!msi->dev_domain) { in mc_allocate_msi_domains()
548 return -ENOMEM; in mc_allocate_msi_domains()
551 msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info, in mc_allocate_msi_domains()
552 msi->dev_domain); in mc_allocate_msi_domains()
553 if (!msi->msi_domain) { in mc_allocate_msi_domains()
555 irq_domain_remove(msi->dev_domain); in mc_allocate_msi_domains()
556 return -ENOMEM; in mc_allocate_msi_domains()
566 struct device *dev = port->dev; in mc_handle_intx()
568 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_handle_intx()
580 ret = generic_handle_domain_irq(port->intx_domain, bit); in mc_handle_intx()
594 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_ack_intx_irq()
595 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT); in mc_ack_intx_irq()
604 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_mask_intx_irq()
606 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT); in mc_mask_intx_irq()
609 raw_spin_lock_irqsave(&port->lock, flags); in mc_mask_intx_irq()
613 raw_spin_unlock_irqrestore(&port->lock, flags); in mc_mask_intx_irq()
620 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_unmask_intx_irq()
622 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT); in mc_unmask_intx_irq()
625 raw_spin_lock_irqsave(&port->lock, flags); in mc_unmask_intx_irq()
629 raw_spin_unlock_irqrestore(&port->lock, flags); in mc_unmask_intx_irq()
633 .name = "Microchip PCIe INTx",
643 irq_set_chip_data(irq, domain->host_data); in mc_pcie_intx_map()
659 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in pcie_events()
672 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in sec_errors()
685 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in ded_errors()
698 void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in local_events()
724 struct device *dev = port->dev; in mc_event_handler()
727 data = irq_domain_get_irq_data(port->event_domain, irq); in mc_event_handler()
729 if (event_cause[data->hwirq].str) in mc_event_handler()
730 dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str); in mc_event_handler()
732 dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq); in mc_event_handler()
749 generic_handle_domain_irq(port->event_domain, bit); in mc_handle_event()
757 u32 event = data->hwirq; in mc_ack_event_irq()
761 addr = port->axi_base_addr + event_descs[event].base + in mc_ack_event_irq()
772 u32 event = data->hwirq; in mc_mask_event_irq()
777 addr = port->axi_base_addr + event_descs[event].base + in mc_mask_event_irq()
788 raw_spin_lock(&port->lock); in mc_mask_event_irq()
796 raw_spin_unlock(&port->lock); in mc_mask_event_irq()
802 u32 event = data->hwirq; in mc_unmask_event_irq()
807 addr = port->axi_base_addr + event_descs[event].base + in mc_unmask_event_irq()
820 raw_spin_lock(&port->lock); in mc_unmask_event_irq()
827 raw_spin_unlock(&port->lock); in mc_unmask_event_irq()
831 .name = "Microchip PCIe EVENT",
841 irq_set_chip_data(irq, domain->host_data); in mc_pcie_event_map()
883 * PCIe may be clocked via Fabric Interface using between 1 and 4 in mc_pcie_init_clks()
897 struct device *dev = port->dev; in mc_pcie_init_irq_domains()
898 struct device_node *node = dev->of_node; in mc_pcie_init_irq_domains()
904 dev_err(dev, "failed to find PCIe Intc node\n"); in mc_pcie_init_irq_domains()
905 return -EINVAL; in mc_pcie_init_irq_domains()
908 port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS, in mc_pcie_init_irq_domains()
910 if (!port->event_domain) { in mc_pcie_init_irq_domains()
913 return -ENOMEM; in mc_pcie_init_irq_domains()
916 irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS); in mc_pcie_init_irq_domains()
918 port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, in mc_pcie_init_irq_domains()
920 if (!port->intx_domain) { in mc_pcie_init_irq_domains()
923 return -ENOMEM; in mc_pcie_init_irq_domains()
926 irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED); in mc_pcie_init_irq_domains()
929 raw_spin_lock_init(&port->lock); in mc_pcie_init_irq_domains()
938 u32 atr_sz = ilog2(size) - 1; in mc_pcie_setup_window()
976 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_pcie_setup_windows()
980 u32 index = 1; in mc_pcie_setup_windows()
982 resource_list_for_each_entry(entry, &bridge->windows) { in mc_pcie_setup_windows()
983 if (resource_type(entry->res) == IORESOURCE_MEM) { in mc_pcie_setup_windows()
984 pci_addr = entry->res->start - entry->offset; in mc_pcie_setup_windows()
986 entry->res->start, pci_addr, in mc_pcie_setup_windows()
987 resource_size(entry->res)); in mc_pcie_setup_windows()
997 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in mc_clear_secs()
1006 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in mc_clear_deds()
1015 void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_disable_interrupts()
1016 void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR; in mc_disable_interrupts()
1041 /* Disable PCIe events and clear any outstanding */ in mc_disable_interrupts()
1050 /* Disable host interrupts and clear any outstanding */ in mc_disable_interrupts()
1057 struct device *dev = &pdev->dev; in mc_init_interrupts()
1070 return -ENODEV; in mc_init_interrupts()
1073 event_irq = irq_create_mapping(port->event_domain, i); in mc_init_interrupts()
1076 return -ENXIO; in mc_init_interrupts()
1087 intx_irq = irq_create_mapping(port->event_domain, in mc_init_interrupts()
1091 return -ENXIO; in mc_init_interrupts()
1097 msi_irq = irq_create_mapping(port->event_domain, in mc_init_interrupts()
1100 return -ENXIO; in mc_init_interrupts()
1113 struct device *dev = cfg->parent; in mc_platform_init()
1116 port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_platform_init()
1119 /* Configure address translation table 0 for PCIe config space */ in mc_platform_init()
1120 mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start, in mc_platform_init()
1121 cfg->res.start, in mc_platform_init()
1122 resource_size(&cfg->res)); in mc_platform_init()
1125 mc_pcie_enable_msi(port, cfg->win); in mc_platform_init()
1127 /* Configure non-config space outbound ranges */ in mc_platform_init()
1142 struct device *dev = &pdev->dev; in mc_host_probe()
1149 return -ENOMEM; in mc_host_probe()
1151 port->dev = dev; in mc_host_probe()
1153 port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1); in mc_host_probe()
1154 if (IS_ERR(port->axi_base_addr)) in mc_host_probe()
1155 return PTR_ERR(port->axi_base_addr); in mc_host_probe()
1159 bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; in mc_host_probe()
1161 /* Allow enabling MSI by disabling MSI-X */ in mc_host_probe()
1171 port->msi.num_vectors = 1 << val; in mc_host_probe()
1174 port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR); in mc_host_probe()
1179 return -ENODEV; in mc_host_probe()
1196 .compatible = "microchip,pcie-host-1.0",
1207 .name = "microchip-pcie",
1215 MODULE_DESCRIPTION("Microchip PCIe host controller driver");