summaryrefslogtreecommitdiff
path: root/sys/arch/armish/dev/iq80321_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/armish/dev/iq80321_pci.c')
-rw-r--r--sys/arch/armish/dev/iq80321_pci.c202
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 *