diff options
Diffstat (limited to 'sys/arch/armish/dev/iq80321_pci.c')
-rw-r--r-- | sys/arch/armish/dev/iq80321_pci.c | 202 |
1 files changed, 116 insertions, 86 deletions
diff --git a/sys/arch/armish/dev/iq80321_pci.c b/sys/arch/armish/dev/iq80321_pci.c index a3433f55dac..e252ea0c4f9 100644 --- a/sys/arch/armish/dev/iq80321_pci.c +++ b/sys/arch/armish/dev/iq80321_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iq80321_pci.c,v 1.2 2006/05/29 17:30:26 drahn Exp $ */ +/* $OpenBSD: iq80321_pci.c,v 1.3 2006/05/31 05:49:54 drahn Exp $ */ /* $NetBSD: iq80321_pci.c,v 1.5 2005/12/11 12:17:09 christos Exp $ */ /* @@ -62,15 +62,113 @@ void *iq80321_pci_intr_establish(void *, pci_intr_handle_t, int, int (*func)(void *), void *, char *); void iq80321_pci_intr_disestablish(void *, void *); +struct irq_map { + uint8_t dev; + uint8_t intrpin; + uint8_t irq; +}; + + +struct pci_id_list { + uint8_t bus; + uint8_t dev; + pci_vendor_id_t vend; + pci_product_id_t prod; +}; + +struct board_id { + char *name; + struct irq_map *irq_map; + struct pci_id_list list[]; +}; + +struct irq_map *iq80321_irq_map; + +struct irq_map iq80321_thecus_irq_map[] = { + { 1, 1, ICU_INT_XINT(2) }, /* thecus re0 29 ??? */ + { 2, 1, ICU_INT_XINT(2) }, /* thecus re1 29 ??? */ + { 3, 1, ICU_INT_XINT(2) }, /* thecus sata 29 */ +#if 0 + { 4, 1, ICU_INT_XINT(2) }, /* thecus uhci0 29 ??? */ +#endif + { 4, 2, ICU_INT_XINT(2) }, /* thecus uhci1 29 ??? */ + { 4, 3, ICU_INT_XINT(2) }, /* thecus ehci0 29 */ + { 5, 1, ICU_INT_XINT(2) }, /* thecus minipci slot */ + + { 0, 0, 255} +}; + +struct irq_map iq80321_hdlg_irq_map[] = { + { 1, 1, ICU_INT_XINT(0) }, /* em0 27 ??? */ + { 2, 1, ICU_INT_XINT(1) }, /* wdc0 28 ??? */ + { 3, 1, ICU_INT_XINT(2) }, /* ochi0 29 */ + { 3, 2, ICU_INT_XINT(2) }, /* ochi0 29 */ + { 3, 3, ICU_INT_XINT(2) }, /* echi0 29 */ + + { 0, 0, 255} +}; +struct board_id thecus = { + "Thecus Nx100", + iq80321_thecus_irq_map, + { + { 0, 1, PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169 }, + /* fill in the rest of the devices */ + { 0, 0, 0, 0 } + } +}; +struct board_id iodata = { + "I/O Data HDL-G", + iq80321_hdlg_irq_map, + { + { 0, 1, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82541GI }, + /* fill in the rest of the devices */ + { 0, 0, 0, 0 } + } +}; + +struct board_id *systems[] = { + &thecus, + &iodata, + NULL +}; + void iq80321_pci_init(pci_chipset_tag_t pc, void *cookie) { - pc->pc_intr_v = cookie; /* the i80321 softc */ pc->pc_intr_map = iq80321_pci_intr_map; pc->pc_intr_string = iq80321_pci_intr_string; pc->pc_intr_establish = iq80321_pci_intr_establish; pc->pc_intr_disestablish = iq80321_pci_intr_disestablish; + +} +void +iq80321_pci_init2(pci_chipset_tag_t pc, void *cookie) +{ + pcitag_t tag; + int i, j; + struct board_id *sys; + + tag = pci_make_tag(pc, 0, 1, 0); + + for (i = 0; systems[i] != NULL; i++) { + sys = systems[i]; + for (j = 0; sys->list[j].vend != 0; j++) { + if ((sys->list[j].vend | sys->list[j].prod << 16) != + pci_conf_read(pc, tag, 0 /* ID */)) { + sys = NULL; + break; + } + } + if (sys != NULL) + break; + } + if (sys == NULL) + printf("board id failed\n"); + else + printf(": %s", sys->name); + iq80321_irq_map = sys->irq_map; + } int @@ -79,23 +177,12 @@ iq80321_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) struct i80321_softc *sc = pa->pa_pc->pc_intr_v; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_intrtag; + int i; int b, d, f; uint32_t busno; uint32_t intr; - /* - * The IQ80321's interrupts are routed like so: - * - * XINT0 i82544 Gig-E - * - * XINT1 UART - * - * XINT2 INTA# from S-PCI-X slot - * - * XINT3 INTB# from S-PCI-X slot - */ - busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); busno = PCIXSR_BUSNO(busno); if (busno == 0xff) @@ -107,83 +194,26 @@ iq80321_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) if (b != busno) goto no_mapping; - switch (d) { -#if 1 - case 1: /* theucs re(4) 0 */ - if (pa->pa_intrpin == 1) { - *ihp = ICU_INT_XINT(2); /* 29 */ - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - - return (0); - } - goto no_mapping; - case 2: /* theucs re(4) 1 */ - if (pa->pa_intrpin == 1) { - *ihp = ICU_INT_XINT(2); /* 30 */ - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); + for (i = 0; iq80321_irq_map[i].irq != 255; i++) { + if (d == iq80321_irq_map[i].dev && + pa->pa_intrpin == iq80321_irq_map[i].intrpin) { + *ihp = iq80321_irq_map[i].irq; + intr = pci_conf_read(pa->pa_pc, pa->pa_intrtag, + PCI_INTERRUPT_REG); + intr = (intr & ~0xff) | iq80321_irq_map[i].irq; + pci_conf_write(pa->pa_pc, pa->pa_intrtag, + PCI_INTERRUPT_REG, intr); return (0); } - goto no_mapping; -#endif - case 3: /* thecus sata */ - if (pa->pa_intrpin == 1) { - *ihp = ICU_INT_XINT(2); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } - goto no_mapping; - case 4: /* thecus */ -#if 0 - if (pa->pa_intrpin == 1) { /* thecus uhci1 */ - *ihp = ICU_INT_XINT(2); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } -#endif -#if 0 - if (pa->pa_intrpin == 2) { /* thecus uhci1 */ - *ihp = ICU_INT_XINT(2); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } -#endif - if (pa->pa_intrpin == 3) { /* thecus ehci1 */ - *ihp = ICU_INT_XINT(2); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } - goto no_mapping; - case 5: /* thecus minipci slot */ - if (pa->pa_intrpin == 1) { - *ihp = ICU_INT_XINT(3); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } - goto no_mapping; - case 6: /* S-PCI-X slot */ - if (pa->pa_intrpin == 1) { - *ihp = ICU_INT_XINT(2); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } - if (pa->pa_intrpin == 2) { - *ihp = ICU_INT_XINT(3); - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, *ihp); - return (0); - } - goto no_mapping; + } - default: no_mapping: - intr = pci_conf_read(pa->pa_pc, pa->pa_intrtag, - PCI_INTERRUPT_REG); - - printf("iq80321_pci_intr_map: no mapping for %d/%d/%d (%d, %d, %d)\n", - pa->pa_bus, pa->pa_device, pa->pa_function, d, pa->pa_intrpin, intr); - return (1); - } + intr = pci_conf_read(pa->pa_pc, pa->pa_intrtag, + PCI_INTERRUPT_REG); - return (0); + printf("iq80321_pci_intr_map: no mapping for %d/%d/%d (%d, %d, %d)\n", + pa->pa_bus, pa->pa_device, pa->pa_function, d, pa->pa_intrpin, intr); + return (1); } const char * |