Lines Matching +full:versal +full:- +full:cpm5 +full:- +full:host

1 // SPDX-License-Identifier: GPL-2.0+
3 * PCIe host controller driver for Xilinx Versal CPM DMA Bridge
5 * (C) Copyright 2019 - 2020, Xilinx, Inc.
22 #include <linux/pci-ecam.h>
107 CPM5, enumerator
111 * struct xilinx_cpm_variant - CPM variant information
119 * struct xilinx_cpm_pcie - PCIe port information
146 return readl_relaxed(port->reg_base + reg); in pcie_read()
152 writel_relaxed(val, port->reg_base + reg); in pcie_write()
166 dev_dbg(port->dev, "Requester ID %lu\n", in cpm_pcie_clear_err_interrupts()
180 mask = BIT(data->hwirq + XILINX_CPM_PCIE_IDRN_SHIFT); in xilinx_cpm_mask_leg_irq()
181 raw_spin_lock_irqsave(&port->lock, flags); in xilinx_cpm_mask_leg_irq()
184 raw_spin_unlock_irqrestore(&port->lock, flags); in xilinx_cpm_mask_leg_irq()
194 mask = BIT(data->hwirq + XILINX_CPM_PCIE_IDRN_SHIFT); in xilinx_cpm_unmask_leg_irq()
195 raw_spin_lock_irqsave(&port->lock, flags); in xilinx_cpm_unmask_leg_irq()
198 raw_spin_unlock_irqrestore(&port->lock, flags); in xilinx_cpm_unmask_leg_irq()
208 * xilinx_cpm_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid
220 irq_set_chip_data(irq, domain->host_data); in xilinx_cpm_pcie_intx_map()
244 generic_handle_domain_irq(port->intx_domain, i); in xilinx_cpm_pcie_intx_flow()
254 raw_spin_lock(&port->lock); in xilinx_cpm_mask_event_irq()
256 val &= ~BIT(d->hwirq); in xilinx_cpm_mask_event_irq()
258 raw_spin_unlock(&port->lock); in xilinx_cpm_mask_event_irq()
266 raw_spin_lock(&port->lock); in xilinx_cpm_unmask_event_irq()
268 val |= BIT(d->hwirq); in xilinx_cpm_unmask_event_irq()
270 raw_spin_unlock(&port->lock); in xilinx_cpm_unmask_event_irq()
274 .name = "RC-Event",
284 irq_set_chip_data(irq, domain->host_data); in xilinx_cpm_pcie_event_map()
304 generic_handle_domain_irq(port->cpm_domain, i); in xilinx_cpm_pcie_event_flow()
307 if (port->variant->version == CPM5) { in xilinx_cpm_pcie_event_flow()
308 val = readl_relaxed(port->cpm_base + XILINX_CPM_PCIE_IR_STATUS); in xilinx_cpm_pcie_event_flow()
310 writel_relaxed(val, port->cpm_base + in xilinx_cpm_pcie_event_flow()
318 val = readl_relaxed(port->cpm_base + XILINX_CPM_PCIE_MISC_IR_STATUS); in xilinx_cpm_pcie_event_flow()
321 port->cpm_base + XILINX_CPM_PCIE_MISC_IR_STATUS); in xilinx_cpm_pcie_event_flow()
357 struct device *dev = port->dev; in xilinx_cpm_pcie_intr_handler()
360 d = irq_domain_get_irq_data(port->cpm_domain, irq); in xilinx_cpm_pcie_intr_handler()
362 switch (d->hwirq) { in xilinx_cpm_pcie_intr_handler()
370 if (intr_cause[d->hwirq].str) in xilinx_cpm_pcie_intr_handler()
371 dev_warn(dev, "%s\n", intr_cause[d->hwirq].str); in xilinx_cpm_pcie_intr_handler()
373 dev_warn(dev, "Unknown IRQ %ld\n", d->hwirq); in xilinx_cpm_pcie_intr_handler()
381 if (port->intx_domain) { in xilinx_cpm_free_irq_domains()
382 irq_domain_remove(port->intx_domain); in xilinx_cpm_free_irq_domains()
383 port->intx_domain = NULL; in xilinx_cpm_free_irq_domains()
386 if (port->cpm_domain) { in xilinx_cpm_free_irq_domains()
387 irq_domain_remove(port->cpm_domain); in xilinx_cpm_free_irq_domains()
388 port->cpm_domain = NULL; in xilinx_cpm_free_irq_domains()
393 * xilinx_cpm_pcie_init_irq_domain - Initialize IRQ domain
400 struct device *dev = port->dev; in xilinx_cpm_pcie_init_irq_domain()
401 struct device_node *node = dev->of_node; in xilinx_cpm_pcie_init_irq_domain()
408 return -EINVAL; in xilinx_cpm_pcie_init_irq_domain()
411 port->cpm_domain = irq_domain_add_linear(pcie_intc_node, 32, in xilinx_cpm_pcie_init_irq_domain()
414 if (!port->cpm_domain) in xilinx_cpm_pcie_init_irq_domain()
417 irq_domain_update_bus_token(port->cpm_domain, DOMAIN_BUS_NEXUS); in xilinx_cpm_pcie_init_irq_domain()
419 port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, in xilinx_cpm_pcie_init_irq_domain()
422 if (!port->intx_domain) in xilinx_cpm_pcie_init_irq_domain()
425 irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED); in xilinx_cpm_pcie_init_irq_domain()
428 raw_spin_lock_init(&port->lock); in xilinx_cpm_pcie_init_irq_domain()
436 return -ENOMEM; in xilinx_cpm_pcie_init_irq_domain()
441 struct device *dev = port->dev; in xilinx_cpm_setup_irq()
445 port->irq = platform_get_irq(pdev, 0); in xilinx_cpm_setup_irq()
446 if (port->irq < 0) in xilinx_cpm_setup_irq()
447 return port->irq; in xilinx_cpm_setup_irq()
455 irq = irq_create_mapping(port->cpm_domain, i); in xilinx_cpm_setup_irq()
458 return -ENXIO; in xilinx_cpm_setup_irq()
469 port->intx_irq = irq_create_mapping(port->cpm_domain, in xilinx_cpm_setup_irq()
471 if (!port->intx_irq) { in xilinx_cpm_setup_irq()
473 return -ENXIO; in xilinx_cpm_setup_irq()
477 irq_set_chained_handler_and_data(port->intx_irq, in xilinx_cpm_setup_irq()
481 irq_set_chained_handler_and_data(port->irq, in xilinx_cpm_setup_irq()
488 * xilinx_cpm_pcie_init_port - Initialize hardware
494 dev_info(port->dev, "PCIe Link is UP\n"); in xilinx_cpm_pcie_init_port()
496 dev_info(port->dev, "PCIe Link is DOWN\n"); in xilinx_cpm_pcie_init_port()
512 port->cpm_base + XILINX_CPM_PCIE_MISC_IR_ENABLE); in xilinx_cpm_pcie_init_port()
514 if (port->variant->version == CPM5) { in xilinx_cpm_pcie_init_port()
516 port->cpm_base + XILINX_CPM_PCIE_IR_ENABLE); in xilinx_cpm_pcie_init_port()
526 * xilinx_cpm_pcie_parse_dt - Parse Device tree
535 struct device *dev = port->dev; in xilinx_cpm_pcie_parse_dt()
539 port->cpm_base = devm_platform_ioremap_resource_byname(pdev, in xilinx_cpm_pcie_parse_dt()
541 if (IS_ERR(port->cpm_base)) in xilinx_cpm_pcie_parse_dt()
542 return PTR_ERR(port->cpm_base); in xilinx_cpm_pcie_parse_dt()
546 return -ENXIO; in xilinx_cpm_pcie_parse_dt()
548 port->cfg = pci_ecam_create(dev, res, bus_range, in xilinx_cpm_pcie_parse_dt()
550 if (IS_ERR(port->cfg)) in xilinx_cpm_pcie_parse_dt()
551 return PTR_ERR(port->cfg); in xilinx_cpm_pcie_parse_dt()
553 if (port->variant->version == CPM5) { in xilinx_cpm_pcie_parse_dt()
554 port->reg_base = devm_platform_ioremap_resource_byname(pdev, in xilinx_cpm_pcie_parse_dt()
556 if (IS_ERR(port->reg_base)) in xilinx_cpm_pcie_parse_dt()
557 return PTR_ERR(port->reg_base); in xilinx_cpm_pcie_parse_dt()
559 port->reg_base = port->cfg->win; in xilinx_cpm_pcie_parse_dt()
567 irq_set_chained_handler_and_data(port->intx_irq, NULL, NULL); in xilinx_cpm_free_interrupts()
568 irq_set_chained_handler_and_data(port->irq, NULL, NULL); in xilinx_cpm_free_interrupts()
572 * xilinx_cpm_pcie_probe - Probe function
580 struct device *dev = &pdev->dev; in xilinx_cpm_pcie_probe()
587 return -ENODEV; in xilinx_cpm_pcie_probe()
591 port->dev = dev; in xilinx_cpm_pcie_probe()
597 bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); in xilinx_cpm_pcie_probe()
599 return -ENODEV; in xilinx_cpm_pcie_probe()
601 port->variant = of_device_get_match_data(dev); in xilinx_cpm_pcie_probe()
603 err = xilinx_cpm_pcie_parse_dt(port, bus->res); in xilinx_cpm_pcie_probe()
617 bridge->sysdata = port->cfg; in xilinx_cpm_pcie_probe()
618 bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops; in xilinx_cpm_pcie_probe()
629 pci_ecam_free(port->cfg); in xilinx_cpm_pcie_probe()
640 .version = CPM5,
645 .compatible = "xlnx,versal-cpm-host-1.00",
649 .compatible = "xlnx,versal-cpm5-host",
657 .name = "xilinx-cpm-pcie",