mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
Remove run-time allocation of XLP IRQs
Follow the same static IRQ to Interrupt Table Entry mapping as the other OS supported on XLP.
This commit is contained in:
parent
70abc1ff8e
commit
5441635eb0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=279306
@ -62,7 +62,7 @@
|
||||
current-speed = <115200>;
|
||||
clock-frequency = <133000000>;
|
||||
interrupt-parent = <&pic>;
|
||||
interrupts = <9>;
|
||||
interrupts = <17>;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -43,13 +43,26 @@
|
||||
#define XLP_IRQ_IS_PICINTR(irq) ((irq) >= PIC_IRQ_BASE && \
|
||||
(irq) <= PIC_IRT_LAST_IRQ)
|
||||
|
||||
#define PIC_UART_0_IRQ 9
|
||||
#define PIC_PCIE_0_IRQ 11
|
||||
#define PIC_PCIE_1_IRQ 12
|
||||
#define PIC_PCIE_2_IRQ 13
|
||||
#define PIC_PCIE_3_IRQ 14
|
||||
#define PIC_EHCI_0_IRQ 16
|
||||
#define PIC_MMC_IRQ 21
|
||||
#define PIC_UART_0_IRQ 17
|
||||
#define PIC_UART_1_IRQ 18
|
||||
|
||||
#define PIC_PCIE_0_IRQ 19
|
||||
#define PIC_PCIE_1_IRQ 20
|
||||
#define PIC_PCIE_2_IRQ 21
|
||||
#define PIC_PCIE_3_IRQ 22
|
||||
#define PIC_PCIE_IRQ(l) (PIC_PCIE_0_IRQ + (l))
|
||||
|
||||
#define PIC_USB_0_IRQ 23
|
||||
#define PIC_USB_1_IRQ 24
|
||||
#define PIC_USB_2_IRQ 25
|
||||
#define PIC_USB_3_IRQ 26
|
||||
#define PIC_USB_4_IRQ 27
|
||||
#define PIC_USB_IRQ(n) (PIC_USB_0_IRQ + (n))
|
||||
|
||||
#define PIC_MMC_IRQ 29
|
||||
#define PIC_I2C_0_IRQ 30
|
||||
#define PIC_I2C_1_IRQ 31
|
||||
#define PIC_I2C_IRQ(n) (PIC_I2C_0_IRQ + (n))
|
||||
|
||||
/*
|
||||
* XLR needs custom pre and post handlers for PCI/PCI-e interrupts
|
||||
|
@ -61,12 +61,46 @@ struct xlp_intrsrc {
|
||||
void (*busack)(int); /* Additional ack */
|
||||
struct intr_event *ie; /* event corresponding to intr */
|
||||
int irq;
|
||||
int irt;
|
||||
};
|
||||
|
||||
static struct xlp_intrsrc xlp_interrupts[XLR_MAX_INTR];
|
||||
static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
|
||||
static int intrcnt_index;
|
||||
|
||||
int
|
||||
xlp_irq_to_irt(int irq)
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
switch (irq) {
|
||||
case PIC_UART_0_IRQ:
|
||||
case PIC_UART_1_IRQ:
|
||||
offset = XLP_IO_UART_OFFSET(0, irq - PIC_UART_0_IRQ);
|
||||
return (xlp_socdev_irt(offset));
|
||||
case PIC_PCIE_0_IRQ:
|
||||
case PIC_PCIE_1_IRQ:
|
||||
case PIC_PCIE_2_IRQ:
|
||||
case PIC_PCIE_3_IRQ:
|
||||
offset = XLP_IO_PCIE_OFFSET(0, irq - PIC_PCIE_0_IRQ);
|
||||
return (xlp_socdev_irt(offset));
|
||||
case PIC_USB_0_IRQ:
|
||||
case PIC_USB_1_IRQ:
|
||||
case PIC_USB_2_IRQ:
|
||||
case PIC_USB_3_IRQ:
|
||||
case PIC_USB_4_IRQ:
|
||||
offset = XLP_IO_USB_OFFSET(0, irq - PIC_USB_0_IRQ);
|
||||
return (xlp_socdev_irt(offset));
|
||||
case PIC_I2C_0_IRQ:
|
||||
case PIC_I2C_1_IRQ:
|
||||
offset = XLP_IO_I2C0_OFFSET(0);
|
||||
return (xlp_socdev_irt(offset) + irq - PIC_I2C_0_IRQ);
|
||||
default:
|
||||
printf("ERROR: %s: unknown irq %d\n", __func__, irq);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xlp_enable_irq(int irq)
|
||||
{
|
||||
@ -102,7 +136,7 @@ xlp_post_filter(void *source)
|
||||
|
||||
if (src->busack)
|
||||
src->busack(src->irq);
|
||||
nlm_pic_ack(xlp_pic_base, xlp_irq_to_irt(src->irq));
|
||||
nlm_pic_ack(xlp_pic_base, src->irt);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -119,7 +153,7 @@ xlp_post_ithread(void *source)
|
||||
{
|
||||
struct xlp_intrsrc *src = source;
|
||||
|
||||
nlm_pic_ack(xlp_pic_base, xlp_irq_to_irt(src->irq));
|
||||
nlm_pic_ack(xlp_pic_base, src->irt);
|
||||
}
|
||||
|
||||
void
|
||||
@ -163,6 +197,13 @@ xlp_establish_intr(const char *name, driver_filter_t filt,
|
||||
src->busack = busack;
|
||||
src->ie = ie;
|
||||
}
|
||||
if (XLP_IRQ_IS_PICINTR(irq)) {
|
||||
/* Set all irqs to CPU 0 for now */
|
||||
src->irt = xlp_irq_to_irt(irq);
|
||||
nlm_pic_write_irt_direct(xlp_pic_base, src->irt, 1, 0,
|
||||
PIC_LOCAL_SCHEDULING, irq, 0);
|
||||
}
|
||||
|
||||
intr_event_add_handler(ie, name, filt, handler, arg,
|
||||
intr_priority(flags), flags, cookiep);
|
||||
xlp_enable_irq(irq);
|
||||
|
@ -62,7 +62,6 @@ extern void xlp_enable_threads(int code);
|
||||
#endif
|
||||
uint32_t xlp_get_cpu_frequency(int node, int core);
|
||||
int nlm_set_device_frequency(int node, int devtype, int frequency);
|
||||
int xlp_irt_to_irq(int irt);
|
||||
int xlp_irq_to_irt(int irq);
|
||||
|
||||
static __inline int nlm_processor_id(void)
|
||||
@ -127,5 +126,12 @@ static __inline int nlm_is_xlp8xx_b0(void)
|
||||
rev == XLP_REVISION_B0);
|
||||
}
|
||||
|
||||
static __inline int xlp_socdev_irt(uint32_t offset)
|
||||
{
|
||||
uint64_t base;
|
||||
|
||||
base = nlm_pcicfg_base(offset);
|
||||
return (nlm_irtstart(base));
|
||||
}
|
||||
#endif /* LOCORE */
|
||||
#endif /* __NLM_XLP_H__ */
|
||||
|
@ -74,31 +74,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define EMUL_MEM_START 0x16000000UL
|
||||
#define EMUL_MEM_END 0x18ffffffUL
|
||||
|
||||
/* SoC device qurik handling */
|
||||
static int irt_irq_map[4 * 256];
|
||||
static int irq_irt_map[64];
|
||||
|
||||
static void
|
||||
xlp_add_irq(int node, int irt, int irq)
|
||||
{
|
||||
int nodeirt = node * 256 + irt;
|
||||
|
||||
irt_irq_map[nodeirt] = irq;
|
||||
irq_irt_map[irq] = nodeirt;
|
||||
}
|
||||
|
||||
int
|
||||
xlp_irq_to_irt(int irq)
|
||||
{
|
||||
return irq_irt_map[irq];
|
||||
}
|
||||
|
||||
int
|
||||
xlp_irt_to_irq(int nodeirt)
|
||||
{
|
||||
return irt_irq_map[nodeirt];
|
||||
}
|
||||
|
||||
/* Override PCI a bit for SoC devices */
|
||||
|
||||
enum {
|
||||
@ -108,24 +83,6 @@ enum {
|
||||
DEV_MMIO32 = 0x8, /* byte access not allowed to mmio */
|
||||
};
|
||||
|
||||
struct soc_dev_desc {
|
||||
u_int devid; /* device ID */
|
||||
int irqbase; /* start IRQ */
|
||||
u_int flags; /* flags */
|
||||
int ndevs; /* to keep track of number of devices */
|
||||
};
|
||||
|
||||
struct soc_dev_desc xlp_dev_desc[] = {
|
||||
{ PCI_DEVICE_ID_NLM_ICI, 0, INTERNAL_DEV },
|
||||
{ PCI_DEVICE_ID_NLM_PIC, 0, INTERNAL_DEV },
|
||||
{ PCI_DEVICE_ID_NLM_FMN, 0, INTERNAL_DEV },
|
||||
{ PCI_DEVICE_ID_NLM_UART, PIC_UART_0_IRQ, MEM_RES_EMUL | DEV_MMIO32},
|
||||
{ PCI_DEVICE_ID_NLM_I2C, 0, MEM_RES_EMUL | DEV_MMIO32 },
|
||||
{ PCI_DEVICE_ID_NLM_NOR, 0, MEM_RES_EMUL },
|
||||
{ PCI_DEVICE_ID_NLM_MMC, PIC_MMC_IRQ, MEM_RES_EMUL },
|
||||
{ PCI_DEVICE_ID_NLM_EHCI, PIC_EHCI_0_IRQ, 0 }
|
||||
};
|
||||
|
||||
struct xlp_devinfo {
|
||||
struct pci_devinfo pcidev;
|
||||
int irq;
|
||||
@ -133,19 +90,6 @@ struct xlp_devinfo {
|
||||
u_long mem_res_start;
|
||||
};
|
||||
|
||||
static __inline struct soc_dev_desc *
|
||||
xlp_find_soc_desc(int devid)
|
||||
{
|
||||
struct soc_dev_desc *p;
|
||||
int i, n;
|
||||
|
||||
n = sizeof(xlp_dev_desc) / sizeof(xlp_dev_desc[0]);
|
||||
for (i = 0, p = xlp_dev_desc; i < n; i++, p++)
|
||||
if (p->devid == devid)
|
||||
return (p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
xlp_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
@ -219,9 +163,7 @@ xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
struct xlp_devinfo *xlp_dinfo;
|
||||
struct soc_dev_desc *si;
|
||||
uint64_t pcibase;
|
||||
int domain, node, irt, irq, flags, devoffset, num;
|
||||
int domain, node, irq, devoffset, flags;
|
||||
uint16_t devid;
|
||||
|
||||
domain = pcib_get_domain(dev);
|
||||
@ -232,36 +174,35 @@ xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f)
|
||||
|
||||
/* Find if there is a desc for the SoC device */
|
||||
devid = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVICE, 2);
|
||||
si = xlp_find_soc_desc(devid);
|
||||
|
||||
/* update flags and irq from desc if available */
|
||||
irq = 0;
|
||||
flags = 0;
|
||||
if (si != NULL) {
|
||||
if (si->irqbase != 0)
|
||||
irq = si->irqbase + si->ndevs;
|
||||
flags = si->flags;
|
||||
si->ndevs++;
|
||||
}
|
||||
|
||||
/* skip internal devices */
|
||||
if ((flags & INTERNAL_DEV) != 0)
|
||||
irq = 0;
|
||||
switch (devid) {
|
||||
case PCI_DEVICE_ID_NLM_UART:
|
||||
irq = PIC_UART_0_IRQ + f;
|
||||
flags = MEM_RES_EMUL | DEV_MMIO32;
|
||||
break;
|
||||
case PCI_DEVICE_ID_NLM_I2C:
|
||||
flags = MEM_RES_EMUL | DEV_MMIO32;
|
||||
break;
|
||||
case PCI_DEVICE_ID_NLM_NOR:
|
||||
flags = MEM_RES_EMUL;
|
||||
break;
|
||||
case PCI_DEVICE_ID_NLM_MMC:
|
||||
irq = PIC_MMC_IRQ;
|
||||
flags = MEM_RES_EMUL;
|
||||
break;
|
||||
case PCI_DEVICE_ID_NLM_EHCI:
|
||||
irq = PIC_USB_0_IRQ + f;
|
||||
break;
|
||||
case PCI_DEVICE_ID_NLM_PCIE:
|
||||
break;
|
||||
case PCI_DEVICE_ID_NLM_ICI:
|
||||
case PCI_DEVICE_ID_NLM_PIC:
|
||||
case PCI_DEVICE_ID_NLM_FMN:
|
||||
default:
|
||||
return;
|
||||
|
||||
/* PCIe interfaces are special, bug in Ax */
|
||||
if (devid == PCI_DEVICE_ID_NLM_PCIE) {
|
||||
xlp_add_irq(node, xlp_pcie_link_irt(f), PIC_PCIE_0_IRQ + f);
|
||||
} else {
|
||||
/* Stash intline and pin in shadow reg for devices */
|
||||
pcibase = nlm_pcicfg_base(devoffset);
|
||||
irt = nlm_irtstart(pcibase);
|
||||
num = nlm_irtnum(pcibase);
|
||||
if (irq != 0 && num > 0) {
|
||||
xlp_add_irq(node, irt, irq);
|
||||
nlm_write_reg(pcibase, XLP_PCI_DEVSCRATCH_REG0,
|
||||
(1 << 8) | irq);
|
||||
}
|
||||
}
|
||||
|
||||
dinfo = pci_read_device(pcib, domain, b, s, f, sizeof(*xlp_dinfo));
|
||||
if (dinfo == NULL)
|
||||
return;
|
||||
@ -269,6 +210,11 @@ xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f)
|
||||
xlp_dinfo->irq = irq;
|
||||
xlp_dinfo->flags = flags;
|
||||
|
||||
/* SoC device with interrupts need fixup (except PCIe controllers) */
|
||||
if (irq != 0 && devid != PCI_DEVICE_ID_NLM_PCIE)
|
||||
PCIB_WRITE_CONFIG(pcib, b, s, f, XLP_PCI_DEVSCRATCH_REG0 << 2,
|
||||
(1 << 8) | irq, 4);
|
||||
|
||||
/* memory resource from ecfg space, if MEM_RES_EMUL is set */
|
||||
if ((flags & MEM_RES_EMUL) != 0)
|
||||
xlp_dinfo->mem_res_start = XLP_DEFAULT_IO_BASE + devoffset +
|
||||
@ -601,21 +547,17 @@ static int
|
||||
xlp_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
|
||||
uint32_t *data)
|
||||
{
|
||||
int msi, irt;
|
||||
int link;
|
||||
|
||||
if (irq >= 64) {
|
||||
msi = irq - 64;
|
||||
*addr = MIPS_MSI_ADDR(0);
|
||||
|
||||
irt = xlp_pcie_link_irt(msi/32);
|
||||
if (irt != -1)
|
||||
*data = MIPS_MSI_DATA(xlp_irt_to_irq(irt));
|
||||
return (0);
|
||||
} else {
|
||||
if (irq < 64) {
|
||||
device_printf(dev, "%s: map_msi for irq %d - ignored",
|
||||
device_get_nameunit(pcib), irq);
|
||||
return (ENXIO);
|
||||
}
|
||||
link = (irq - 64) / 32;
|
||||
*addr = MIPS_MSI_ADDR(0);
|
||||
*data = MIPS_MSI_DATA(PIC_PCIE_IRQ(link));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -711,18 +653,13 @@ mips_platform_pcib_setup_intr(device_t dev, device_t child,
|
||||
nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_CAP,
|
||||
(val | (PCIM_MSICTRL_MSI_ENABLE << 16) |
|
||||
(PCIM_MSICTRL_MMC_32 << 16)));
|
||||
|
||||
xlpirq = xlp_pcie_link_irt(xlpirq / 32);
|
||||
if (xlpirq == -1)
|
||||
return (EINVAL);
|
||||
xlpirq = xlp_irt_to_irq(xlpirq);
|
||||
xlpirq = PIC_PCIE_IRQ(link);
|
||||
}
|
||||
/* Set all irqs to CPU 0 for now */
|
||||
nlm_pic_write_irt_direct(xlp_pic_base, xlp_irq_to_irt(xlpirq), 1, 0,
|
||||
PIC_LOCAL_SCHEDULING, xlpirq, 0);
|
||||
extra_ack = NULL;
|
||||
|
||||
if (xlpirq >= PIC_PCIE_0_IRQ && xlpirq <= PIC_PCIE_3_IRQ)
|
||||
extra_ack = bridge_pcie_ack;
|
||||
else
|
||||
extra_ack = NULL;
|
||||
xlp_establish_intr(device_get_name(child), filt,
|
||||
intr, arg, xlpirq, flags, cookiep, extra_ack);
|
||||
|
||||
@ -816,7 +753,7 @@ xlp_pcib_deactivate_resource(device_t bus, device_t child, int type, int rid,
|
||||
static int
|
||||
mips_pcib_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
{
|
||||
int irt, link;
|
||||
int f, d;
|
||||
|
||||
/*
|
||||
* Validate requested pin number.
|
||||
@ -826,38 +763,21 @@ mips_pcib_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
|
||||
if (pci_get_bus(dev) == 0 &&
|
||||
pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC) {
|
||||
/* SoC devices */
|
||||
uint64_t pcibase;
|
||||
int f, n, d, num;
|
||||
|
||||
f = pci_get_function(dev);
|
||||
n = pci_get_slot(dev) / 8;
|
||||
d = pci_get_slot(dev) % 8;
|
||||
|
||||
/*
|
||||
* For PCIe links, return link IRT, for other SoC devices
|
||||
* get the IRT from its PCIe header
|
||||
*/
|
||||
if (d == 1) {
|
||||
irt = xlp_pcie_link_irt(f);
|
||||
} else {
|
||||
pcibase = nlm_pcicfg_base(XLP_HDR_OFFSET(n, 0, d, f));
|
||||
irt = nlm_irtstart(pcibase);
|
||||
num = nlm_irtnum(pcibase);
|
||||
if (num != 1)
|
||||
device_printf(bus, "[%d:%d:%d] Error %d IRQs\n",
|
||||
n, d, f, num);
|
||||
}
|
||||
if (d == 1)
|
||||
return (PIC_PCIE_IRQ(f));
|
||||
else
|
||||
return (255); /* use intline, don't reroute */
|
||||
} else {
|
||||
/* Regular PCI devices */
|
||||
link = xlp_pcie_link(bus, dev);
|
||||
irt = xlp_pcie_link_irt(link);
|
||||
return (PIC_PCIE_IRQ(xlp_pcie_link(bus, dev)));
|
||||
}
|
||||
|
||||
if (irt != -1)
|
||||
return (xlp_irt_to_irq(irt));
|
||||
|
||||
return (255);
|
||||
}
|
||||
|
||||
static device_method_t xlp_pcib_methods[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user