Lines Matching +full:pcie +full:- +full:root +full:- +full:port +full:- +full:2

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.
21 #include <linux/pci-ecam.h>
26 #include "../pci-host-common.h"
27 #include "pcie-plda.h"
32 /* PCIe Bridge Phy and Controller Phy offsets */
36 /* PCIe Controller Phy Regs */
58 #define ECC_CONTROL_TX_RAM_INJ_ERROR_2 BIT(2)
79 #define PCIE_EVENT_INT_DLUP_EXIT_INT BIT(2)
80 #define PCIE_EVENT_INT_MASK GENMASK(2, 0)
88 /* PCIe Config space MSI capability structure */
94 #define EVENT_PCIE_DLUP_EXIT 2
209 LOCAL_EVENT_CAUSE(P_ATR_EVT_POST_ERR, "pcie write request error"),
210 LOCAL_EVENT_CAUSE(P_ATR_EVT_FETCH_ERR, "pcie read request error"),
211 LOCAL_EVENT_CAUSE(P_ATR_EVT_DISCARD_ERR, "pcie read timeout"),
297 static struct mc_pcie *port; variable
299 static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam) in mc_pcie_enable_msi() argument
301 struct plda_msi *msi = &port->plda.msi; in mc_pcie_enable_msi()
316 writel_relaxed(lower_32_bits(msi->vector_phy), in mc_pcie_enable_msi()
318 writel_relaxed(upper_32_bits(msi->vector_phy), in mc_pcie_enable_msi()
327 static u32 pcie_events(struct mc_pcie *port) in pcie_events() argument
329 u32 reg = readl_relaxed(port->ctrl_base_addr + PCIE_EVENT_INT); in pcie_events()
339 static u32 sec_errors(struct mc_pcie *port) in sec_errors() argument
341 u32 reg = readl_relaxed(port->ctrl_base_addr + SEC_ERROR_INT); in sec_errors()
351 static u32 ded_errors(struct mc_pcie *port) in ded_errors() argument
353 u32 reg = readl_relaxed(port->ctrl_base_addr + DED_ERROR_INT); in ded_errors()
363 static u32 local_events(struct mc_pcie *port) in local_events() argument
365 u32 reg = readl_relaxed(port->bridge_base_addr + ISTATUS_LOCAL); in local_events()
375 static u32 mc_get_events(struct plda_pcie_rp *port) in mc_get_events() argument
377 struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda); in mc_get_events()
390 struct plda_pcie_rp *port = dev_id; in mc_event_handler() local
391 struct device *dev = port->dev; in mc_event_handler()
394 data = irq_domain_get_irq_data(port->event_domain, irq); in mc_event_handler()
396 if (event_cause[data->hwirq].str) in mc_event_handler()
397 dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str); in mc_event_handler()
399 dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq); in mc_event_handler()
406 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data); in mc_ack_event_irq() local
407 struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda); in mc_ack_event_irq()
408 u32 event = data->hwirq; in mc_ack_event_irq()
413 addr = mc_port->bridge_base_addr; in mc_ack_event_irq()
415 addr = mc_port->ctrl_base_addr; in mc_ack_event_irq()
426 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data); in mc_mask_event_irq() local
427 struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda); in mc_mask_event_irq()
428 u32 event = data->hwirq; in mc_mask_event_irq()
434 addr = mc_port->bridge_base_addr; in mc_mask_event_irq()
436 addr = mc_port->ctrl_base_addr; in mc_mask_event_irq()
448 raw_spin_lock(&port->lock); in mc_mask_event_irq()
456 raw_spin_unlock(&port->lock); in mc_mask_event_irq()
461 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data); in mc_unmask_event_irq() local
462 struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda); in mc_unmask_event_irq()
463 u32 event = data->hwirq; in mc_unmask_event_irq()
469 addr = mc_port->bridge_base_addr; in mc_unmask_event_irq()
471 addr = mc_port->ctrl_base_addr; in mc_unmask_event_irq()
485 raw_spin_lock(&port->lock); in mc_unmask_event_irq()
492 raw_spin_unlock(&port->lock); in mc_unmask_event_irq()
496 .name = "Microchip PCIe EVENT",
535 * PCIe may be clocked via Fabric Interface using between 1 and 4 in mc_pcie_init_clks()
550 return devm_request_irq(plda->dev, event_irq, mc_event_handler, in mc_request_event_irq()
564 static inline void mc_clear_secs(struct mc_pcie *port) in mc_clear_secs() argument
567 port->ctrl_base_addr + SEC_ERROR_INT); in mc_clear_secs()
568 writel_relaxed(0, port->ctrl_base_addr + SEC_ERROR_EVENT_CNT); in mc_clear_secs()
571 static inline void mc_clear_deds(struct mc_pcie *port) in mc_clear_deds() argument
574 port->ctrl_base_addr + DED_ERROR_INT); in mc_clear_deds()
575 writel_relaxed(0, port->ctrl_base_addr + DED_ERROR_EVENT_CNT); in mc_clear_deds()
578 static void mc_disable_interrupts(struct mc_pcie *port) in mc_disable_interrupts() argument
587 writel_relaxed(val, port->ctrl_base_addr + ECC_CONTROL); in mc_disable_interrupts()
591 port->ctrl_base_addr + SEC_ERROR_INT_MASK); in mc_disable_interrupts()
592 mc_clear_secs(port); in mc_disable_interrupts()
596 port->ctrl_base_addr + DED_ERROR_INT_MASK); in mc_disable_interrupts()
597 mc_clear_deds(port); in mc_disable_interrupts()
600 writel_relaxed(0, port->bridge_base_addr + IMASK_LOCAL); in mc_disable_interrupts()
601 writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_LOCAL); in mc_disable_interrupts()
602 writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_MSI); in mc_disable_interrupts()
604 /* Disable PCIe events and clear any outstanding */ in mc_disable_interrupts()
611 writel_relaxed(val, port->ctrl_base_addr + PCIE_EVENT_INT); in mc_disable_interrupts()
614 writel_relaxed(0, port->bridge_base_addr + IMASK_HOST); in mc_disable_interrupts()
615 writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_HOST); in mc_disable_interrupts()
618 static void mc_pcie_setup_inbound_atr(struct mc_pcie *port, int window_index, in mc_pcie_setup_inbound_atr() argument
622 void __iomem *table_addr = port->bridge_base_addr + table_offset; in mc_pcie_setup_inbound_atr()
626 atr_sz = ilog2(size) - 1; in mc_pcie_setup_inbound_atr()
643 struct mc_pcie *port) in mc_pcie_setup_inbound_ranges() argument
645 struct device *dev = &pdev->dev; in mc_pcie_setup_inbound_ranges()
646 struct device_node *dn = dev->of_node; in mc_pcie_setup_inbound_ranges()
652 * MPFS PCIe Root Port is 32-bit only, behind a Fabric Interface in mc_pcie_setup_inbound_ranges()
653 * Controller FPGA logic block which contains the AXI-S interface. in mc_pcie_setup_inbound_ranges()
655 * From the point of view of the PCIe Root Port, there are only two in mc_pcie_setup_inbound_ranges()
656 * supported Root Port configurations: in mc_pcie_setup_inbound_ranges()
659 * window from 0x0 (CPU space) to specified PCIe space. in mc_pcie_setup_inbound_ranges()
661 * Configuration 2: for use with non-coherent designs; supports two in mc_pcie_setup_inbound_ranges()
662 * 1 GB windows to CPU space; one mapping CPU space 0 to PCIe space in mc_pcie_setup_inbound_ranges()
663 * 0x80000000 and a second mapping CPU space 0x40000000 to PCIe in mc_pcie_setup_inbound_ranges()
665 * MSI space is allocated in the AXI-S range on MPFS. in mc_pcie_setup_inbound_ranges()
667 * The FIC interface outside the PCIe block *must* complete the in mc_pcie_setup_inbound_ranges()
671 if (device_property_read_bool(dev, "dma-noncoherent")) { in mc_pcie_setup_inbound_ranges()
676 mc_pcie_setup_inbound_atr(port, 0, 0, in mc_pcie_setup_inbound_ranges()
678 mc_pcie_setup_inbound_atr(port, 1, SZ_1G, in mc_pcie_setup_inbound_ranges()
683 /* No DMA range property - setup default */ in mc_pcie_setup_inbound_ranges()
684 mc_pcie_setup_inbound_atr(port, 0, 0, 0, SZ_4G); in mc_pcie_setup_inbound_ranges()
692 return -EINVAL; in mc_pcie_setup_inbound_ranges()
694 mc_pcie_setup_inbound_atr(port, atr_index, 0, in mc_pcie_setup_inbound_ranges()
705 struct device *dev = cfg->parent; in mc_platform_init()
710 /* Configure address translation table 0 for PCIe config space */ in mc_platform_init()
711 plda_pcie_setup_window(port->bridge_base_addr, 0, cfg->res.start, in mc_platform_init()
712 cfg->res.start, in mc_platform_init()
713 resource_size(&cfg->res)); in mc_platform_init()
716 mc_pcie_enable_msi(port, cfg->win); in mc_platform_init()
718 /* Configure non-config space outbound ranges */ in mc_platform_init()
719 ret = plda_pcie_setup_iomems(bridge, &port->plda); in mc_platform_init()
723 ret = mc_pcie_setup_inbound_ranges(pdev, port); in mc_platform_init()
727 port->plda.event_ops = &mc_event_ops; in mc_platform_init()
728 port->plda.event_irq_chip = &mc_event_irq_chip; in mc_platform_init()
729 port->plda.events_bitmap = GENMASK(NUM_EVENTS - 1, 0); in mc_platform_init()
732 ret = plda_init_interrupts(pdev, &port->plda, &mc_event); in mc_platform_init()
741 struct device *dev = &pdev->dev; in mc_host_probe()
747 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); in mc_host_probe()
748 if (!port) in mc_host_probe()
749 return -ENOMEM; in mc_host_probe()
751 plda = &port->plda; in mc_host_probe()
752 plda->dev = dev; in mc_host_probe()
754 port->bridge_base_addr = devm_platform_ioremap_resource_byname(pdev, in mc_host_probe()
756 port->ctrl_base_addr = devm_platform_ioremap_resource_byname(pdev, in mc_host_probe()
758 if (!IS_ERR(port->bridge_base_addr) && !IS_ERR(port->ctrl_base_addr)) in mc_host_probe()
770 port->bridge_base_addr = apb_base_addr + MC_PCIE1_BRIDGE_ADDR; in mc_host_probe()
771 port->ctrl_base_addr = apb_base_addr + MC_PCIE1_CTRL_ADDR; in mc_host_probe()
774 mc_disable_interrupts(port); in mc_host_probe()
776 plda->bridge_addr = port->bridge_base_addr; in mc_host_probe()
777 plda->num_events = NUM_EVENTS; in mc_host_probe()
779 /* Allow enabling MSI by disabling MSI-X */ in mc_host_probe()
780 val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0); in mc_host_probe()
782 writel(val, port->bridge_base_addr + PCIE_PCI_IRQ_DW0); in mc_host_probe()
785 val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0); in mc_host_probe()
789 plda->msi.num_vectors = 1 << val; in mc_host_probe()
792 plda->msi.vector_phy = readl_relaxed(port->bridge_base_addr + IMSI_ADDR); in mc_host_probe()
797 return -ENODEV; in mc_host_probe()
814 .compatible = "microchip,pcie-host-1.0",
825 .name = "microchip-pcie",
833 MODULE_DESCRIPTION("Microchip PCIe host controller driver");