Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2006, Segher Boessenkool, IBM Corporation.
0004  * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
0005  */
0006 
0007 #include <linux/irq.h>
0008 #include <linux/irqdomain.h>
0009 #include <linux/msi.h>
0010 #include <asm/mpic.h>
0011 #include <asm/hw_irq.h>
0012 #include <asm/ppc-pci.h>
0013 #include <asm/msi_bitmap.h>
0014 
0015 #include "mpic.h"
0016 
0017 /* A bit ugly, can we get this from the pci_dev somehow? */
0018 static struct mpic *msi_mpic;
0019 
0020 static void mpic_u3msi_mask_irq(struct irq_data *data)
0021 {
0022     pci_msi_mask_irq(data);
0023     mpic_mask_irq(data);
0024 }
0025 
0026 static void mpic_u3msi_unmask_irq(struct irq_data *data)
0027 {
0028     mpic_unmask_irq(data);
0029     pci_msi_unmask_irq(data);
0030 }
0031 
0032 static struct irq_chip mpic_u3msi_chip = {
0033     .irq_shutdown       = mpic_u3msi_mask_irq,
0034     .irq_mask       = mpic_u3msi_mask_irq,
0035     .irq_unmask     = mpic_u3msi_unmask_irq,
0036     .irq_eoi        = mpic_end_irq,
0037     .irq_set_type       = mpic_set_irq_type,
0038     .irq_set_affinity   = mpic_set_affinity,
0039     .name           = "MPIC-U3MSI",
0040 };
0041 
0042 static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
0043 {
0044     u8 flags;
0045     u32 tmp;
0046     u64 addr;
0047 
0048     pci_read_config_byte(pdev, pos + HT_MSI_FLAGS, &flags);
0049 
0050     if (flags & HT_MSI_FLAGS_FIXED)
0051         return HT_MSI_FIXED_ADDR;
0052 
0053     pci_read_config_dword(pdev, pos + HT_MSI_ADDR_LO, &tmp);
0054     addr = tmp & HT_MSI_ADDR_LO_MASK;
0055     pci_read_config_dword(pdev, pos + HT_MSI_ADDR_HI, &tmp);
0056     addr = addr | ((u64)tmp << 32);
0057 
0058     return addr;
0059 }
0060 
0061 static u64 find_ht_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
0062 {
0063     struct pci_bus *bus;
0064     unsigned int pos;
0065 
0066     for (bus = pdev->bus; bus && bus->self; bus = bus->parent) {
0067         pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING);
0068         if (pos)
0069             return read_ht_magic_addr(bus->self, pos);
0070     }
0071 
0072     return 0;
0073 }
0074 
0075 static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
0076 {
0077     struct pci_controller *hose = pci_bus_to_host(pdev->bus);
0078 
0079     /* U4 PCIe MSIs need to write to the special register in
0080      * the bridge that generates interrupts. There should be
0081      * theoretically a register at 0xf8005000 where you just write
0082      * the MSI number and that triggers the right interrupt, but
0083      * unfortunately, this is busted in HW, the bridge endian swaps
0084      * the value and hits the wrong nibble in the register.
0085      *
0086      * So instead we use another register set which is used normally
0087      * for converting HT interrupts to MPIC interrupts, which decodes
0088      * the interrupt number as part of the low address bits
0089      *
0090      * This will not work if we ever use more than one legacy MSI in
0091      * a block but we never do. For one MSI or multiple MSI-X where
0092      * each interrupt address can be specified separately, it works
0093      * just fine.
0094      */
0095     if (of_device_is_compatible(hose->dn, "u4-pcie") ||
0096         of_device_is_compatible(hose->dn, "U4-pcie"))
0097         return 0xf8004000 | (hwirq << 4);
0098 
0099     return 0;
0100 }
0101 
0102 static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
0103 {
0104     struct msi_desc *entry;
0105     irq_hw_number_t hwirq;
0106 
0107     msi_for_each_desc(entry, &pdev->dev, MSI_DESC_ASSOCIATED) {
0108         hwirq = virq_to_hw(entry->irq);
0109         irq_set_msi_desc(entry->irq, NULL);
0110         irq_dispose_mapping(entry->irq);
0111         msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
0112     }
0113 }
0114 
0115 static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
0116 {
0117     unsigned int virq;
0118     struct msi_desc *entry;
0119     struct msi_msg msg;
0120     u64 addr;
0121     int hwirq;
0122 
0123     if (type == PCI_CAP_ID_MSIX)
0124         pr_debug("u3msi: MSI-X untested, trying anyway.\n");
0125 
0126     /* If we can't find a magic address then MSI ain't gonna work */
0127     if (find_ht_magic_addr(pdev, 0) == 0 &&
0128         find_u4_magic_addr(pdev, 0) == 0) {
0129         pr_debug("u3msi: no magic address found for %s\n",
0130              pci_name(pdev));
0131         return -ENXIO;
0132     }
0133 
0134     msi_for_each_desc(entry, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
0135         hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
0136         if (hwirq < 0) {
0137             pr_debug("u3msi: failed allocating hwirq\n");
0138             return hwirq;
0139         }
0140 
0141         addr = find_ht_magic_addr(pdev, hwirq);
0142         if (addr == 0)
0143             addr = find_u4_magic_addr(pdev, hwirq);
0144         msg.address_lo = addr & 0xFFFFFFFF;
0145         msg.address_hi = addr >> 32;
0146 
0147         virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
0148         if (!virq) {
0149             pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq);
0150             msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
0151             return -ENOSPC;
0152         }
0153 
0154         irq_set_msi_desc(virq, entry);
0155         irq_set_chip(virq, &mpic_u3msi_chip);
0156         irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
0157 
0158         pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
0159               virq, hwirq, (unsigned long)addr);
0160 
0161         printk("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
0162               virq, hwirq, (unsigned long)addr);
0163         msg.data = hwirq;
0164         pci_write_msi_msg(virq, &msg);
0165 
0166         hwirq++;
0167     }
0168 
0169     return 0;
0170 }
0171 
0172 int __init mpic_u3msi_init(struct mpic *mpic)
0173 {
0174     int rc;
0175     struct pci_controller *phb;
0176 
0177     rc = mpic_msi_init_allocator(mpic);
0178     if (rc) {
0179         pr_debug("u3msi: Error allocating bitmap!\n");
0180         return rc;
0181     }
0182 
0183     pr_debug("u3msi: Registering MPIC U3 MSI callbacks.\n");
0184 
0185     BUG_ON(msi_mpic);
0186     msi_mpic = mpic;
0187 
0188     list_for_each_entry(phb, &hose_list, list_node) {
0189         WARN_ON(phb->controller_ops.setup_msi_irqs);
0190         phb->controller_ops.setup_msi_irqs = u3msi_setup_msi_irqs;
0191         phb->controller_ops.teardown_msi_irqs = u3msi_teardown_msi_irqs;
0192     }
0193 
0194     return 0;
0195 }