MIPS: Netlogic: Add MSI support for XLP
Add MSI chip and MSIX chip definitions. For MSI, we map the link interrupt to a MSI link IRQ which will do a second level of dispatch based on the MSI status register. The MSI chip definitions use the MSI enable register to enable and disable the MSI irqs. For MSI-X, we split the 32 available MSI-X vectors across the four PCIe links (8 each). These PIC interrupts generate an IRQ per link which uses a second level dispatch as well. The MSI-X chip definition uses the standard functions to enable and disable interrupts. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Signed-off-by: John Crispin <blogic@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/6270/
This commit is contained in:

committed by
Ralf Baechle

parent
27547abf36
commit
c24a8a7a99
@@ -180,6 +180,7 @@ static void __init nlm_init_percpu_irqs(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void nlm_setup_pic_irq(int node, int picirq, int irq, int irt)
|
||||
{
|
||||
struct nlm_pic_irq *pic_data;
|
||||
@@ -207,24 +208,24 @@ void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))
|
||||
|
||||
static void nlm_init_node_irqs(int node)
|
||||
{
|
||||
int i, irt;
|
||||
uint64_t irqmask;
|
||||
struct nlm_soc_info *nodep;
|
||||
int i, irt;
|
||||
|
||||
pr_info("Init IRQ for node %d\n", node);
|
||||
nodep = nlm_get_node(node);
|
||||
irqmask = PERCPU_IRQ_MASK;
|
||||
nodep->irqmask = PERCPU_IRQ_MASK;
|
||||
for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) {
|
||||
irt = nlm_irq_to_irt(i);
|
||||
if (irt == -1)
|
||||
if (irt == -1) /* unused irq */
|
||||
continue;
|
||||
nlm_setup_pic_irq(node, i, i, irt);
|
||||
/* set interrupts to first cpu in node */
|
||||
nodep->irqmask |= 1ull << i;
|
||||
if (irt == -2) /* not a direct PIC irq */
|
||||
continue;
|
||||
|
||||
nlm_pic_init_irt(nodep->picbase, irt, i,
|
||||
node * NLM_CPUS_PER_NODE, 0);
|
||||
irqmask |= (1ull << i);
|
||||
nlm_setup_pic_irq(node, i, i, irt);
|
||||
}
|
||||
nodep->irqmask = irqmask;
|
||||
}
|
||||
|
||||
void nlm_smp_irq_init(int hwcpuid)
|
||||
@@ -256,6 +257,18 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PCI_MSI) && defined(CONFIG_CPU_XLP)
|
||||
/* PCI interrupts need a second level dispatch for MSI bits */
|
||||
if (i >= PIC_PCIE_LINK_MSI_IRQ(0) && i <= PIC_PCIE_LINK_MSI_IRQ(3)) {
|
||||
nlm_dispatch_msi(node, i);
|
||||
return;
|
||||
}
|
||||
if (i >= PIC_PCIE_MSIX_IRQ(0) && i <= PIC_PCIE_MSIX_IRQ(3)) {
|
||||
nlm_dispatch_msix(node, i);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* top level irq handling */
|
||||
do_IRQ(nlm_irq_to_xirq(node, i));
|
||||
}
|
||||
|
@@ -135,9 +135,17 @@ int nlm_irq_to_irt(int irq)
|
||||
case PIC_I2C_3_IRQ:
|
||||
irt = irt + 3; break;
|
||||
}
|
||||
} else if (irq >= PIC_PCIE_LINK_0_IRQ && irq <= PIC_PCIE_LINK_3_IRQ) {
|
||||
} else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) &&
|
||||
irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) {
|
||||
/* HW bug, PCI IRT entries are bad on early silicon, fix */
|
||||
irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ);
|
||||
irt = PIC_IRT_PCIE_LINK_INDEX(irq -
|
||||
PIC_PCIE_LINK_LEGACY_IRQ_BASE);
|
||||
} else if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) &&
|
||||
irq <= PIC_PCIE_LINK_MSI_IRQ(3)) {
|
||||
irt = -2;
|
||||
} else if (irq >= PIC_PCIE_MSIX_IRQ(0) &&
|
||||
irq <= PIC_PCIE_MSIX_IRQ(3)) {
|
||||
irt = -2;
|
||||
} else {
|
||||
irt = -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user