Lines Matching +full:versal +full:- +full:cpm +full:- +full:host +full:- +full:1

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.
21 #include "pcie-xilinx-common.h"
33 #define XILINX_CPM_PCIE_MISC_IR_LOCAL BIT(1)
81 CPM, enumerator
86 * struct xilinx_cpm_variant - CPM variant information
87 * @version: CPM version
94 * struct xilinx_cpm_pcie - PCIe port information
97 * @cpm_base: CPM System Level Control and Status Register(SLCR) Base
99 * @cpm_domain: CPM IRQ domain pointer
104 * @variant: CPM version check pointer
121 return readl_relaxed(port->reg_base + reg); in pcie_read()
127 writel_relaxed(val, port->reg_base + reg); in pcie_write()
141 dev_dbg(port->dev, "Requester ID %lu\n", in cpm_pcie_clear_err_interrupts()
155 mask = BIT(data->hwirq + XILINX_CPM_PCIE_IDRN_SHIFT); in xilinx_cpm_mask_leg_irq()
156 raw_spin_lock_irqsave(&port->lock, flags); in xilinx_cpm_mask_leg_irq()
159 raw_spin_unlock_irqrestore(&port->lock, flags); in xilinx_cpm_mask_leg_irq()
169 mask = BIT(data->hwirq + XILINX_CPM_PCIE_IDRN_SHIFT); in xilinx_cpm_unmask_leg_irq()
170 raw_spin_lock_irqsave(&port->lock, flags); in xilinx_cpm_unmask_leg_irq()
173 raw_spin_unlock_irqrestore(&port->lock, flags); in xilinx_cpm_unmask_leg_irq()
183 * xilinx_cpm_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid
195 irq_set_chip_data(irq, domain->host_data); in xilinx_cpm_pcie_intx_map()
219 generic_handle_domain_irq(port->intx_domain, i); in xilinx_cpm_pcie_intx_flow()
229 raw_spin_lock(&port->lock); in xilinx_cpm_mask_event_irq()
231 val &= ~BIT(d->hwirq); in xilinx_cpm_mask_event_irq()
233 raw_spin_unlock(&port->lock); in xilinx_cpm_mask_event_irq()
241 raw_spin_lock(&port->lock); in xilinx_cpm_unmask_event_irq()
243 val |= BIT(d->hwirq); in xilinx_cpm_unmask_event_irq()
245 raw_spin_unlock(&port->lock); in xilinx_cpm_unmask_event_irq()
249 .name = "RC-Event",
259 irq_set_chip_data(irq, domain->host_data); in xilinx_cpm_pcie_event_map()
279 generic_handle_domain_irq(port->cpm_domain, i); in xilinx_cpm_pcie_event_flow()
282 if (port->variant->version == CPM5) { in xilinx_cpm_pcie_event_flow()
283 val = readl_relaxed(port->cpm_base + XILINX_CPM_PCIE_IR_STATUS); in xilinx_cpm_pcie_event_flow()
285 writel_relaxed(val, port->cpm_base + in xilinx_cpm_pcie_event_flow()
291 * CPM SLCR block. in xilinx_cpm_pcie_event_flow()
293 val = readl_relaxed(port->cpm_base + XILINX_CPM_PCIE_MISC_IR_STATUS); in xilinx_cpm_pcie_event_flow()
296 port->cpm_base + XILINX_CPM_PCIE_MISC_IR_STATUS); in xilinx_cpm_pcie_event_flow()
332 struct device *dev = port->dev; in xilinx_cpm_pcie_intr_handler()
335 d = irq_domain_get_irq_data(port->cpm_domain, irq); in xilinx_cpm_pcie_intr_handler()
337 switch (d->hwirq) { in xilinx_cpm_pcie_intr_handler()
345 if (intr_cause[d->hwirq].str) in xilinx_cpm_pcie_intr_handler()
346 dev_warn(dev, "%s\n", intr_cause[d->hwirq].str); in xilinx_cpm_pcie_intr_handler()
348 dev_warn(dev, "Unknown IRQ %ld\n", d->hwirq); in xilinx_cpm_pcie_intr_handler()
356 if (port->intx_domain) { in xilinx_cpm_free_irq_domains()
357 irq_domain_remove(port->intx_domain); in xilinx_cpm_free_irq_domains()
358 port->intx_domain = NULL; in xilinx_cpm_free_irq_domains()
361 if (port->cpm_domain) { in xilinx_cpm_free_irq_domains()
362 irq_domain_remove(port->cpm_domain); in xilinx_cpm_free_irq_domains()
363 port->cpm_domain = NULL; in xilinx_cpm_free_irq_domains()
368 * xilinx_cpm_pcie_init_irq_domain - Initialize IRQ domain
375 struct device *dev = port->dev; in xilinx_cpm_pcie_init_irq_domain()
376 struct device_node *node = dev->of_node; in xilinx_cpm_pcie_init_irq_domain()
383 return -EINVAL; in xilinx_cpm_pcie_init_irq_domain()
386 port->cpm_domain = irq_domain_add_linear(pcie_intc_node, 32, in xilinx_cpm_pcie_init_irq_domain()
389 if (!port->cpm_domain) in xilinx_cpm_pcie_init_irq_domain()
392 irq_domain_update_bus_token(port->cpm_domain, DOMAIN_BUS_NEXUS); in xilinx_cpm_pcie_init_irq_domain()
394 port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, in xilinx_cpm_pcie_init_irq_domain()
397 if (!port->intx_domain) in xilinx_cpm_pcie_init_irq_domain()
400 irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED); in xilinx_cpm_pcie_init_irq_domain()
403 raw_spin_lock_init(&port->lock); in xilinx_cpm_pcie_init_irq_domain()
411 return -ENOMEM; in xilinx_cpm_pcie_init_irq_domain()
416 struct device *dev = port->dev; in xilinx_cpm_setup_irq()
420 port->irq = platform_get_irq(pdev, 0); in xilinx_cpm_setup_irq()
421 if (port->irq < 0) in xilinx_cpm_setup_irq()
422 return port->irq; in xilinx_cpm_setup_irq()
430 irq = irq_create_mapping(port->cpm_domain, i); in xilinx_cpm_setup_irq()
433 return -ENXIO; in xilinx_cpm_setup_irq()
444 port->intx_irq = irq_create_mapping(port->cpm_domain, in xilinx_cpm_setup_irq()
446 if (!port->intx_irq) { in xilinx_cpm_setup_irq()
448 return -ENXIO; in xilinx_cpm_setup_irq()
452 irq_set_chained_handler_and_data(port->intx_irq, in xilinx_cpm_setup_irq()
456 irq_set_chained_handler_and_data(port->irq, in xilinx_cpm_setup_irq()
463 * xilinx_cpm_pcie_init_port - Initialize hardware
469 dev_info(port->dev, "PCIe Link is UP\n"); in xilinx_cpm_pcie_init_port()
471 dev_info(port->dev, "PCIe Link is DOWN\n"); in xilinx_cpm_pcie_init_port()
484 * CPM SLCR block. in xilinx_cpm_pcie_init_port()
487 port->cpm_base + XILINX_CPM_PCIE_MISC_IR_ENABLE); in xilinx_cpm_pcie_init_port()
489 if (port->variant->version == CPM5) { in xilinx_cpm_pcie_init_port()
491 port->cpm_base + XILINX_CPM_PCIE_IR_ENABLE); in xilinx_cpm_pcie_init_port()
501 * xilinx_cpm_pcie_parse_dt - Parse Device tree
510 struct device *dev = port->dev; in xilinx_cpm_pcie_parse_dt()
514 port->cpm_base = devm_platform_ioremap_resource_byname(pdev, in xilinx_cpm_pcie_parse_dt()
516 if (IS_ERR(port->cpm_base)) in xilinx_cpm_pcie_parse_dt()
517 return PTR_ERR(port->cpm_base); in xilinx_cpm_pcie_parse_dt()
521 return -ENXIO; in xilinx_cpm_pcie_parse_dt()
523 port->cfg = pci_ecam_create(dev, res, bus_range, in xilinx_cpm_pcie_parse_dt()
525 if (IS_ERR(port->cfg)) in xilinx_cpm_pcie_parse_dt()
526 return PTR_ERR(port->cfg); in xilinx_cpm_pcie_parse_dt()
528 if (port->variant->version == CPM5) { in xilinx_cpm_pcie_parse_dt()
529 port->reg_base = devm_platform_ioremap_resource_byname(pdev, in xilinx_cpm_pcie_parse_dt()
531 if (IS_ERR(port->reg_base)) in xilinx_cpm_pcie_parse_dt()
532 return PTR_ERR(port->reg_base); in xilinx_cpm_pcie_parse_dt()
534 port->reg_base = port->cfg->win; in xilinx_cpm_pcie_parse_dt()
542 irq_set_chained_handler_and_data(port->intx_irq, NULL, NULL); in xilinx_cpm_free_interrupts()
543 irq_set_chained_handler_and_data(port->irq, NULL, NULL); in xilinx_cpm_free_interrupts()
547 * xilinx_cpm_pcie_probe - Probe function
555 struct device *dev = &pdev->dev; in xilinx_cpm_pcie_probe()
562 return -ENODEV; in xilinx_cpm_pcie_probe()
566 port->dev = dev; in xilinx_cpm_pcie_probe()
572 bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); in xilinx_cpm_pcie_probe()
574 return -ENODEV; in xilinx_cpm_pcie_probe()
576 port->variant = of_device_get_match_data(dev); in xilinx_cpm_pcie_probe()
578 err = xilinx_cpm_pcie_parse_dt(port, bus->res); in xilinx_cpm_pcie_probe()
592 bridge->sysdata = port->cfg; in xilinx_cpm_pcie_probe()
593 bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops; in xilinx_cpm_pcie_probe()
604 pci_ecam_free(port->cfg); in xilinx_cpm_pcie_probe()
611 .version = CPM,
620 .compatible = "xlnx,versal-cpm-host-1.00",
624 .compatible = "xlnx,versal-cpm5-host",
632 .name = "xilinx-cpm-pcie",