Lines Matching +full:versal2 +full:- +full:mdb +full:- +full:host
1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe host controller driver for AMD MDB PCIe Bridge
5 * Copyright (C) 2024-2025, Advanced Micro Devices, Inc.
22 #include "pcie-designware.h"
55 * struct amd_mdb_pcie - PCIe port information
57 * @slcr: MDB System Level Control and Status Register (SLCR) base
59 * @mdb_domain: MDB IRQ domain pointer
78 struct dw_pcie *pci = &pcie->pci; in amd_mdb_intx_irq_mask()
79 struct dw_pcie_rp *port = &pci->pp; in amd_mdb_intx_irq_mask()
83 raw_spin_lock_irqsave(&port->lock, flags); in amd_mdb_intx_irq_mask()
85 AMD_MDB_PCIE_INTR_INTX_ASSERT(data->hwirq)); in amd_mdb_intx_irq_mask()
91 writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_DISABLE_MISC); in amd_mdb_intx_irq_mask()
92 raw_spin_unlock_irqrestore(&port->lock, flags); in amd_mdb_intx_irq_mask()
98 struct dw_pcie *pci = &pcie->pci; in amd_mdb_intx_irq_unmask()
99 struct dw_pcie_rp *port = &pci->pp; in amd_mdb_intx_irq_unmask()
103 raw_spin_lock_irqsave(&port->lock, flags); in amd_mdb_intx_irq_unmask()
105 AMD_MDB_PCIE_INTR_INTX_ASSERT(data->hwirq)); in amd_mdb_intx_irq_unmask()
111 writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_ENABLE_MISC); in amd_mdb_intx_irq_unmask()
112 raw_spin_unlock_irqrestore(&port->lock, flags); in amd_mdb_intx_irq_unmask()
116 .name = "AMD MDB INTx",
122 * amd_mdb_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid
134 irq_set_chip_data(irq, domain->host_data); in amd_mdb_pcie_intx_map()
151 val = readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC); in dw_pcie_rp_intx()
156 generic_handle_domain_irq(pcie->intx_domain, i); in dw_pcie_rp_intx()
179 struct dw_pcie *pci = &pcie->pci; in amd_mdb_event_irq_mask()
180 struct dw_pcie_rp *port = &pci->pp; in amd_mdb_event_irq_mask()
184 raw_spin_lock_irqsave(&port->lock, flags); in amd_mdb_event_irq_mask()
185 val = BIT(d->hwirq); in amd_mdb_event_irq_mask()
186 writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_DISABLE_MISC); in amd_mdb_event_irq_mask()
187 raw_spin_unlock_irqrestore(&port->lock, flags); in amd_mdb_event_irq_mask()
193 struct dw_pcie *pci = &pcie->pci; in amd_mdb_event_irq_unmask()
194 struct dw_pcie_rp *port = &pci->pp; in amd_mdb_event_irq_unmask()
198 raw_spin_lock_irqsave(&port->lock, flags); in amd_mdb_event_irq_unmask()
199 val = BIT(d->hwirq); in amd_mdb_event_irq_unmask()
200 writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_ENABLE_MISC); in amd_mdb_event_irq_unmask()
201 raw_spin_unlock_irqrestore(&port->lock, flags); in amd_mdb_event_irq_unmask()
205 .name = "AMD MDB RC-Event",
215 irq_set_chip_data(irq, domain->host_data); in amd_mdb_pcie_event_map()
231 val = readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC); in amd_mdb_pcie_event()
232 val &= ~readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_MASK_MISC); in amd_mdb_pcie_event()
234 generic_handle_domain_irq(pcie->mdb_domain, i); in amd_mdb_pcie_event()
235 writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC); in amd_mdb_pcie_event()
242 if (pcie->intx_domain) { in amd_mdb_pcie_free_irq_domains()
243 irq_domain_remove(pcie->intx_domain); in amd_mdb_pcie_free_irq_domains()
244 pcie->intx_domain = NULL; in amd_mdb_pcie_free_irq_domains()
247 if (pcie->mdb_domain) { in amd_mdb_pcie_free_irq_domains()
248 irq_domain_remove(pcie->mdb_domain); in amd_mdb_pcie_free_irq_domains()
249 pcie->mdb_domain = NULL; in amd_mdb_pcie_free_irq_domains()
259 pcie->slcr + AMD_MDB_TLP_IR_DISABLE_MISC); in amd_mdb_pcie_init_port()
262 val = readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC); in amd_mdb_pcie_init_port()
264 writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC); in amd_mdb_pcie_init_port()
268 pcie->slcr + AMD_MDB_TLP_IR_ENABLE_MISC); in amd_mdb_pcie_init_port()
274 * amd_mdb_pcie_init_irq_domains - Initialize IRQ domain
283 struct dw_pcie *pci = &pcie->pci; in amd_mdb_pcie_init_irq_domains()
284 struct dw_pcie_rp *pp = &pci->pp; in amd_mdb_pcie_init_irq_domains()
285 struct device *dev = &pdev->dev; in amd_mdb_pcie_init_irq_domains()
286 struct device_node *node = dev->of_node; in amd_mdb_pcie_init_irq_domains()
290 pcie_intc_node = of_get_child_by_name(node, "interrupt-controller"); in amd_mdb_pcie_init_irq_domains()
293 return -ENODEV; in amd_mdb_pcie_init_irq_domains()
296 pcie->mdb_domain = irq_domain_create_linear(of_fwnode_handle(pcie_intc_node), 32, in amd_mdb_pcie_init_irq_domains()
298 if (!pcie->mdb_domain) { in amd_mdb_pcie_init_irq_domains()
299 err = -ENOMEM; in amd_mdb_pcie_init_irq_domains()
300 dev_err(dev, "Failed to add MDB domain\n"); in amd_mdb_pcie_init_irq_domains()
304 irq_domain_update_bus_token(pcie->mdb_domain, DOMAIN_BUS_NEXUS); in amd_mdb_pcie_init_irq_domains()
306 pcie->intx_domain = irq_domain_create_linear(of_fwnode_handle(pcie_intc_node), in amd_mdb_pcie_init_irq_domains()
308 if (!pcie->intx_domain) { in amd_mdb_pcie_init_irq_domains()
309 err = -ENOMEM; in amd_mdb_pcie_init_irq_domains()
315 irq_domain_update_bus_token(pcie->intx_domain, DOMAIN_BUS_WIRED); in amd_mdb_pcie_init_irq_domains()
317 raw_spin_lock_init(&pp->lock); in amd_mdb_pcie_init_irq_domains()
333 dev = pcie->pci.dev; in amd_mdb_pcie_intr_handler()
339 d = irq_domain_get_irq_data(pcie->mdb_domain, irq); in amd_mdb_pcie_intr_handler()
340 if (intr_cause[d->hwirq].str) in amd_mdb_pcie_intr_handler()
341 dev_warn(dev, "%s\n", intr_cause[d->hwirq].str); in amd_mdb_pcie_intr_handler()
343 dev_warn_once(dev, "Unknown IRQ %ld\n", d->hwirq); in amd_mdb_pcie_intr_handler()
351 struct dw_pcie *pci = &pcie->pci; in amd_mdb_setup_irq()
352 struct dw_pcie_rp *pp = &pci->pp; in amd_mdb_setup_irq()
353 struct device *dev = &pdev->dev; in amd_mdb_setup_irq()
358 pp->irq = platform_get_irq(pdev, 0); in amd_mdb_setup_irq()
359 if (pp->irq < 0) in amd_mdb_setup_irq()
360 return pp->irq; in amd_mdb_setup_irq()
366 irq = irq_create_mapping(pcie->mdb_domain, i); in amd_mdb_setup_irq()
368 dev_err(dev, "Failed to map MDB domain interrupt\n"); in amd_mdb_setup_irq()
369 return -ENOMEM; in amd_mdb_setup_irq()
381 pcie->intx_irq = irq_create_mapping(pcie->mdb_domain, in amd_mdb_setup_irq()
383 if (!pcie->intx_irq) { in amd_mdb_setup_irq()
385 return -ENXIO; in amd_mdb_setup_irq()
388 err = devm_request_irq(dev, pcie->intx_irq, dw_pcie_rp_intx, in amd_mdb_setup_irq()
397 err = devm_request_irq(dev, pp->irq, amd_mdb_pcie_event, IRQF_NO_THREAD, in amd_mdb_setup_irq()
401 pp->irq, err); in amd_mdb_setup_irq()
410 struct device *dev = pcie->pci.dev; in amd_mdb_parse_pcie_port()
418 for_each_child_of_node_with_prefix(dev->of_node, pcie_port_node, "pcie") { in amd_mdb_parse_pcie_port()
419 pcie->perst_gpio = devm_fwnode_gpiod_get(dev, of_fwnode_handle(pcie_port_node), in amd_mdb_parse_pcie_port()
421 if (IS_ERR(pcie->perst_gpio)) in amd_mdb_parse_pcie_port()
422 return dev_err_probe(dev, PTR_ERR(pcie->perst_gpio), in amd_mdb_parse_pcie_port()
427 return -ENODEV; in amd_mdb_parse_pcie_port()
433 struct dw_pcie *pci = &pcie->pci; in amd_mdb_add_pcie_port()
434 struct dw_pcie_rp *pp = &pci->pp; in amd_mdb_add_pcie_port()
435 struct device *dev = &pdev->dev; in amd_mdb_add_pcie_port()
438 pcie->slcr = devm_platform_ioremap_resource_byname(pdev, "slcr"); in amd_mdb_add_pcie_port()
439 if (IS_ERR(pcie->slcr)) in amd_mdb_add_pcie_port()
440 return PTR_ERR(pcie->slcr); in amd_mdb_add_pcie_port()
452 pp->ops = &amd_mdb_pcie_host_ops; in amd_mdb_add_pcie_port()
454 if (pcie->perst_gpio) { in amd_mdb_add_pcie_port()
456 gpiod_set_value_cansleep(pcie->perst_gpio, 0); in amd_mdb_add_pcie_port()
462 dev_err(dev, "Failed to initialize host, err=%d\n", err); in amd_mdb_add_pcie_port()
475 struct device *dev = &pdev->dev; in amd_mdb_pcie_probe()
482 return -ENOMEM; in amd_mdb_pcie_probe()
484 pci = &pcie->pci; in amd_mdb_pcie_probe()
485 pci->dev = dev; in amd_mdb_pcie_probe()
491 * If amd_mdb_parse_pcie_port returns -ENODEV, it indicates that the in amd_mdb_pcie_probe()
494 * reset GPIO is acquired directly from the PCIe Host Bridge node. in amd_mdb_pcie_probe()
497 if (ret != -ENODEV) in amd_mdb_pcie_probe()
500 pcie->perst_gpio = devm_gpiod_get_optional(dev, "reset", in amd_mdb_pcie_probe()
502 if (IS_ERR(pcie->perst_gpio)) in amd_mdb_pcie_probe()
503 return dev_err_probe(dev, PTR_ERR(pcie->perst_gpio), in amd_mdb_pcie_probe()
512 .compatible = "amd,versal2-mdb-host",
519 .name = "amd-mdb-pcie",