diff options
-rw-r--r-- | sys/arch/i386/pci/pci_intr_fixup.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/pci/via8231.c | 113 | ||||
-rw-r--r-- | sys/arch/i386/pci/via8231reg.h | 50 |
3 files changed, 112 insertions, 55 deletions
diff --git a/sys/arch/i386/pci/pci_intr_fixup.c b/sys/arch/i386/pci/pci_intr_fixup.c index 82716b98715..63c034aa19c 100644 --- a/sys/arch/i386/pci/pci_intr_fixup.c +++ b/sys/arch/i386/pci/pci_intr_fixup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_intr_fixup.c,v 1.41 2005/10/17 19:17:24 mickey Exp $ */ +/* $OpenBSD: pci_intr_fixup.c,v 1.42 2005/10/20 15:09:31 mickey Exp $ */ /* $NetBSD: pci_intr_fixup.c,v 1.10 2000/08/10 21:18:27 soda Exp $ */ /* @@ -182,6 +182,8 @@ const struct pciintr_icu_table { { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8231_ISA, via8231_init }, + { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8237_ISA, + via8231_init }, { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_85C503, sis85c503_init }, diff --git a/sys/arch/i386/pci/via8231.c b/sys/arch/i386/pci/via8231.c index 62f52919f55..110519c149a 100644 --- a/sys/arch/i386/pci/via8231.c +++ b/sys/arch/i386/pci/via8231.c @@ -1,4 +1,4 @@ -/* $OpenBSD: via8231.c,v 1.1 2003/07/30 05:26:33 mickey Exp $ */ +/* $OpenBSD: via8231.c,v 1.2 2005/10/20 15:09:31 mickey Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -36,8 +36,8 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - /* + * Copyright (c) 2005, by Michael Shalayeff * Copyright (c) 2003, by Matthew Gream * Copyright (c) 1999, by UCHIYAMA Yasushi * All rights reserved. @@ -65,7 +65,9 @@ /* * Support for the VIA Technologies Inc. VIA8231 PCI to ISA Bridge - * Based upon documentation: VIA VT8231 South Bridge, Revision 1.85 (March 11, 2002), pg 73 + * Based upon documentation: + * 1. VIA VT8231 South Bridge, Revision 1.85 (March 11, 2002), pg 73 + * 2. VIA VT8237R South Bridge, Revision 2.06 (December 15, 2004), pg 100 * Derived from amd756.c */ @@ -89,6 +91,8 @@ struct via8231_handle { bus_space_handle_t ph_regs_ioh; pci_chipset_tag_t ph_pc; pcitag_t ph_tag; + int flags; +#define VT8237 0x0001 }; int via8231_getclink(pciintr_icu_handle_t, int, int *); @@ -112,12 +116,7 @@ struct mask_shft_pair { int mask; int shft; }; -static const struct mask_shft_pair via8231_trigger_cnfg[VIA8231_LINK_MAX+1] = { - { (1<<3), 3 }, /*PINTA#*/ - { (1<<2), 2 }, /*PINTB#*/ - { (1<<1), 1 }, /*PINTC#*/ - { (1<<0), 0 } /*PINTD#*/ -}; + static const struct mask_shft_pair via8231_routing_cnfg[VIA8231_LINK_MAX+1] = { { 0x0f, 0+4 }, /*PINTA#*/ { 0x0f, 8+0 }, /*PINTB#*/ @@ -126,23 +125,19 @@ static const struct mask_shft_pair via8231_routing_cnfg[VIA8231_LINK_MAX+1] = { }; #define VIA8231_GET_TRIGGER_CNFG(reg, pirq) \ - ((reg & via8231_trigger_cnfg[pirq].mask) >> \ - via8231_trigger_cnfg[pirq].shft) - -#define VIA8231_SET_TRIGGER_CNFG(reg, pirq, cfg) \ - reg = (reg & ~via8231_trigger_cnfg[pirq].mask) | \ - ((cfg << via8231_trigger_cnfg[pirq].shft) & \ - via8231_trigger_cnfg[pirq].mask) + ((reg) & (1 << (3 - (clink & 3)))) +#define VIA8231_SET_TRIGGER_CNFG(reg, clink, cfg) \ + (((reg) & ~(1 << (3 - (clink & 3)))) | ((cfg) << (3 - (clink & 3)))) #define VIA8231_GET_ROUTING_CNFG(reg, pirq) \ - (((reg) & via8231_routing_cnfg[pirq].mask) >> \ - via8231_routing_cnfg[pirq].shft) + (((reg) >> via8231_routing_cnfg[(pirq)].shft) & \ + via8231_routing_cnfg[(pirq)].mask) #define VIA8231_SET_ROUTING_CNFG(reg, pirq, cfg) \ - reg = (reg & ~via8231_routing_cnfg[pirq].mask) | \ - ((cfg << via8231_routing_cnfg[pirq].shft) & \ - via8231_routing_cnfg[pirq].mask) - + (((reg) & ~(via8231_routing_cnfg[(pirq)].mask << \ + via8231_routing_cnfg[(pirq)].shft)) | \ + (((cfg) & via8231_routing_cnfg[(pirq)].mask) << \ + via8231_routing_cnfg[(pirq)].shft)) int via8231_init(pc, iot, tag, ptagp, phandp) @@ -153,6 +148,7 @@ via8231_init(pc, iot, tag, ptagp, phandp) pciintr_icu_handle_t *phandp; { struct via8231_handle *ph; + pcireg_t id; ph = malloc(sizeof(*ph), M_DEVBUF, M_NOWAIT); if (ph == NULL) @@ -161,6 +157,9 @@ via8231_init(pc, iot, tag, ptagp, phandp) ph->ph_iot = iot; ph->ph_pc = pc; ph->ph_tag = tag; + id = pci_conf_read(pc, tag, PCI_ID_REG); + ph->flags = PCI_VENDOR(id) == PCI_VENDOR_VIATECH && + PCI_PRODUCT(id) == PCI_PRODUCT_VIATECH_VT8231_ISA? 0 : VT8237; *ptagp = &via8231_pci_icu; *phandp = ph; @@ -177,7 +176,12 @@ via8231_getclink(v, link, clinkp) pciintr_icu_handle_t v; int link, *clinkp; { - if (VIA8231_LINK_LEGAL(link - 1) == 0) + struct via8231_handle *ph = v; + + if ((ph->flags & VT8237) && !VIA8237_LINK_LEGAL(link - 1)) + return (1); + + if (!(ph->flags & VT8237) && !VIA8231_LINK_LEGAL(link - 1)) return (1); *clinkp = link - 1; @@ -192,11 +196,17 @@ via8231_get_intr(v, clink, irqp) struct via8231_handle *ph = v; int reg, val; - if (VIA8231_LINK_LEGAL(clink) == 0) + if (VIA8237_LINK_LEGAL(clink) == 0) return (1); - reg = VIA8231_GET_ROUTING(ph); - val = VIA8231_GET_ROUTING_CNFG(reg, clink); + if (VIA8231_LINK_LEGAL(clink)) { + reg = VIA8231_GET_ROUTING(ph); + val = VIA8231_GET_ROUTING_CNFG(reg, clink); + } else { + reg = VIA8237_GET_ROUTING(ph); + val = (reg >> ((clink & 3) * 4)) & 0xf; + } + *irqp = (val == VIA8231_ROUTING_CNFG_DISABLED) ? I386_PCI_INTERRUPT_LINE_NO_CONNECTION : val; @@ -211,7 +221,7 @@ via8231_set_intr(v, clink, irq) struct via8231_handle *ph = v; int reg; - if (VIA8231_LINK_LEGAL(clink) == 0 || VIA8231_PIRQ_LEGAL(irq) == 0) + if (VIA8237_LINK_LEGAL(clink) == 0 || VIA8231_PIRQ_LEGAL(irq) == 0) return (1); #ifdef VIA8231_DEBUG @@ -219,9 +229,15 @@ via8231_set_intr(v, clink, irq) via8231_pir_dump("via8231_set_intr: ", ph); #endif - reg = VIA8231_GET_ROUTING(ph); - VIA8231_SET_ROUTING_CNFG(reg, clink, irq); - VIA8231_SET_ROUTING(ph, reg); + if (VIA8231_LINK_LEGAL(clink)) { + reg = VIA8231_GET_ROUTING(ph); + VIA8231_SET_ROUTING(ph, + VIA8231_SET_ROUTING_CNFG(reg, clink, irq)); + } else { + reg = VIA8237_GET_ROUTING(ph); + VIA8237_SET_ROUTING(ph, (reg & ~(0xf << (clink & 3))) | + ((irq & 0xf) << (clink & 3))); + } return (0); } @@ -232,25 +248,20 @@ via8231_get_trigger(v, irq, triggerp) int irq, *triggerp; { struct via8231_handle *ph = v; - int reg, clink, pciirq; + int reg, clink, max, pciirq; if (VIA8231_PIRQ_LEGAL(irq) == 0) return (1); - for (clink = 0; clink <= VIA8231_LINK_MAX; clink++) { + max = ph->flags & VT8237? VIA8237_LINK_MAX : VIA8231_LINK_MAX; + for (clink = 0; clink <= max; clink++) { via8231_get_intr(v, clink, &pciirq); if (pciirq == irq) { - reg = VIA8231_GET_TRIGGER(ph); - switch (VIA8231_GET_TRIGGER_CNFG(reg, clink)) { - case VIA8231_TRIGGER_CNFG_LEVEL: - *triggerp = IST_LEVEL; - break; - case VIA8231_TRIGGER_CNFG_EDGE: - *triggerp = IST_EDGE; - break; - default: - return (1); - } + reg = VIA8231_LINK_LEGAL(clink)? + VIA8231_GET_TRIGGER(ph): + VIA8237_GET_TRIGGER(ph); + *triggerp = VIA8231_GET_TRIGGER_CNFG(reg, clink)? + IST_EDGE : IST_LEVEL; return (0); } } @@ -264,7 +275,7 @@ via8231_set_trigger(v, irq, trigger) int irq, trigger; { struct via8231_handle *ph = v; - int reg, clink, pciirq; + int reg, clink, max, pciirq; if (VIA8231_PIRQ_LEGAL(irq) == 0 || VIA8231_TRIG_LEGAL(trigger) == 0) return (1); @@ -274,23 +285,29 @@ via8231_set_trigger(v, irq, trigger) via8231_pir_dump("via8231_set_trig: ", ph); #endif + max = ph->flags & VT8237? VIA8237_LINK_MAX : VIA8231_LINK_MAX; for (clink = 0; clink <= VIA8231_LINK_MAX; clink++) { via8231_get_intr(v, clink, &pciirq); if (pciirq == irq) { - reg = VIA8231_GET_ROUTING(ph); + reg = VIA8231_LINK_LEGAL(clink)? + VIA8231_GET_TRIGGER(ph): + VIA8237_GET_TRIGGER(ph); switch (trigger) { case IST_LEVEL: - VIA8231_SET_TRIGGER_CNFG(reg, clink, + reg = VIA8231_SET_TRIGGER_CNFG(reg, clink, VIA8231_TRIGGER_CNFG_LEVEL); break; case IST_EDGE: - VIA8231_SET_TRIGGER_CNFG(reg, clink, + reg = VIA8231_SET_TRIGGER_CNFG(reg, clink, VIA8231_TRIGGER_CNFG_EDGE); break; default: return (1); } - VIA8231_SET_ROUTING(ph, reg); + if (VIA8231_LINK_LEGAL(clink)) + VIA8231_SET_ROUTING(ph, reg); + else + VIA8237_SET_ROUTING(ph, reg); return (0); } } diff --git a/sys/arch/i386/pci/via8231reg.h b/sys/arch/i386/pci/via8231reg.h index d8f563fab40..c7cbd7cdba8 100644 --- a/sys/arch/i386/pci/via8231reg.h +++ b/sys/arch/i386/pci/via8231reg.h @@ -1,6 +1,7 @@ -/* $OpenBSD: via8231reg.h,v 1.1 2003/07/30 05:26:33 mickey Exp $ */ +/* $OpenBSD: via8231reg.h,v 1.2 2005/10/20 15:09:31 mickey Exp $ */ /* + * Copyright (c) 2005, by Michael Shalayeff * Copyright (c) 2003, by Matthew Gream * Copyright (c) 1999, by UCHIYAMA Yasushi * All rights reserved. @@ -50,49 +51,86 @@ * (0x57) * bits 7-4: PINTD# Routing * bits 3-0: reserved + * PIRQ Select register. (0x44 - 0x47) + * (0x44) + * bits 7-4: PINTF# Routing + * bits 3-0: PINTE# Routing + * (0x45) + * bits 7-4: PINTH# Routing + * bits 3-0: PINTG# Routing + * (0x46) + * bit 4: EFGH/ABCD share (1 -- use above mappings) + * bit 3: Edge Triggered Interrupt Select for PCI Interrupt H + * bit 2: Edge Triggered Interrupt Select for PCI Interrupt G + * bit 1: Edge Triggered Interrupt Select for PCI Interrupt F + * bit 0: Edge Triggered Interrupt Select for PCI Interrupt E + * * 0000: Disabled 0100: IRQ4 1000: Reserved 1100: IRQ12 * 0001: IRQ1 0101: IRQ5 1001: IRQ9 1101: Reserved * 0010: Reserved 0110: IRQ6 1010: IRQ10 1110: IRQ14 * 0011: IRQ3 0111: IRQ7 1011: IRQ11 1111: IRQ15 */ -#define VIA8231_CFG_PIR 0x54 - +#define VIA8231_CFG_PIR 0x54 +#define VIA8237_CFG_PIR 0x44 #define VIA8231_TRIGGER_CNFG_MASK 0x000000ff #define VIA8231_TRIGGER_CNFG_SHFT 0 +#define VIA8237_TRIGGER_CNFG_MASK 0x00ff0000 +#define VIA8237_TRIGGER_CNFG_SHFT 16 #define VIA8231_TRIGGER_CNFG_LEVEL 0 #define VIA8231_TRIGGER_CNFG_EDGE 1 +#define VIA8237_TRIGGER_CNFG_ENA 0x100000 #define VIA8231_GET_TRIGGER(ph) \ ((pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8231_CFG_PIR) \ - & VIA8231_TRIGGER_CNFG_MASK) >> VIA8231_TRIGGER_CNFG_SHFT) + & VIA8231_TRIGGER_CNFG_MASK) >> VIA8231_TRIGGER_CNFG_SHFT) +#define VIA8237_GET_TRIGGER(ph) \ + ((pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8237_CFG_PIR) \ + & VIA8237_TRIGGER_CNFG_MASK) >> VIA8237_TRIGGER_CNFG_SHFT) #define VIA8231_SET_TRIGGER(ph, n) \ pci_conf_write((ph)->ph_pc, (ph)->ph_tag, VIA8231_CFG_PIR, \ (pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8231_CFG_PIR) \ & ~VIA8231_TRIGGER_CNFG_MASK) | ((n) << VIA8231_TRIGGER_CNFG_SHFT)) +#define VIA8237_SET_TRIGGER(ph, n) \ + pci_conf_write((ph)->ph_pc, (ph)->ph_tag, VIA8237_CFG_PIR, \ + (pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8237_CFG_PIR) \ + & ~VIA8237_TRIGGER_CNFG_MASK) | ((n) << VIA8237_TRIGGER_CNFG_SHFT)) #define VIA8231_ROUTING_CNFG_MASK 0xffffff00 #define VIA8231_ROUTING_CNFG_SHFT 8 /* skip 0x54 triggers */ #define VIA8231_ROUTING_CNFG_DISABLED 0 +#define VIA8237_ROUTING_CNFG_MASK 0xffff +#define VIA8237_ROUTING_CNFG_SHFT 0 #define VIA8231_GET_ROUTING(ph) \ ((pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8231_CFG_PIR) \ - & VIA8231_ROUTING_CNFG_MASK) >> VIA8231_ROUTING_CNFG_SHFT) + & VIA8237_ROUTING_CNFG_MASK) >> VIA8231_ROUTING_CNFG_SHFT) +#define VIA8237_GET_ROUTING(ph) \ + ((pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8237_CFG_PIR) \ + & VIA8231_ROUTING_CNFG_MASK) >> VIA8237_ROUTING_CNFG_SHFT) #define VIA8231_SET_ROUTING(ph, n) \ pci_conf_write((ph)->ph_pc, (ph)->ph_tag, VIA8231_CFG_PIR, \ (pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8231_CFG_PIR) \ & ~VIA8231_ROUTING_CNFG_MASK) | ((n) << VIA8231_ROUTING_CNFG_SHFT)) +#define VIA8237_SET_ROUTING(ph, n) \ + pci_conf_write((ph)->ph_pc, (ph)->ph_tag, VIA8237_CFG_PIR, \ + (pci_conf_read((ph)->ph_pc, (ph)->ph_tag, VIA8237_CFG_PIR) \ + & ~VIA8237_ROUTING_CNFG_MASK) | \ + ((n) << VIA8237_ROUTING_CNFG_SHFT) | VIA8237_TRIGGER_CNFG_ENA) #define VIA8231_PIRQ_MASK 0xdefa #define VIA8231_PIRQ_LEGAL(irq) \ - ((irq) >= 0 && (irq) <= 15 && ((1 << (irq)) & VIA8231_PIRQ_MASK) != 0) + ((irq) >= 0 && (irq) <= 15 && ((1 << (irq)) & VIA8231_PIRQ_MASK)) #define VIA8231_LINK_MAX 3 +#define VIA8237_LINK_MAX 7 #define VIA8231_LINK_LEGAL(link) \ ((link) >= 0 && (link) <= VIA8231_LINK_MAX) +#define VIA8237_LINK_LEGAL(link) \ + ((link) >= 0 && (link) <= VIA8237_LINK_MAX) #define VIA8231_TRIG_LEGAL(trig) \ ((trig) == IST_LEVEL || (trig) == IST_EDGE) |