diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-02-09 21:31:48 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-02-09 21:31:48 +0000 |
commit | 721729e58c8be07fe413bd0be2c80a414dd19d97 (patch) | |
tree | fec6c0187f34382ad452f22073205616581b23ea /sys/arch/loongson | |
parent | 93c7d2be883100bf4bd91acc3da5acb2225a9bbd (diff) |
Make the bonito_pci_attach_hook per-platform, as a new callback in struct
bonito_config. Move the Geode initalization code previously found there
to yeeloong-specific code; and on Gdium, clear all the BAR of the internal
mini pci slot - it does not get initialized by PMON and the MI PCI code
complains about the bogus values it finds there on cold boots.
Diffstat (limited to 'sys/arch/loongson')
-rw-r--r-- | sys/arch/loongson/dev/bonito.c | 23 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonitovar.h | 5 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/gdium_machdep.c | 101 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/yeeloong_machdep.c | 31 |
4 files changed, 124 insertions, 36 deletions
diff --git a/sys/arch/loongson/dev/bonito.c b/sys/arch/loongson/dev/bonito.c index 16d3e1850cf..7780cab46a1 100644 --- a/sys/arch/loongson/dev/bonito.c +++ b/sys/arch/loongson/dev/bonito.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bonito.c,v 1.7 2010/02/05 20:53:24 miod Exp $ */ +/* $OpenBSD: bonito.c,v 1.8 2010/02/09 21:31:46 miod Exp $ */ /* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */ /* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */ @@ -74,7 +74,6 @@ #include <loongson/dev/bonitoreg.h> #include <loongson/dev/bonitovar.h> #include <loongson/dev/bonito_irq.h> -#include <loongson/dev/glxvar.h> int bonito_match(struct device *, void *, void *); void bonito_attach(struct device *, struct device *, void *); @@ -763,27 +762,13 @@ bonito_attach_hook(struct device *parent, struct device *self, struct pcibus_attach_args *pba) { pci_chipset_tag_t pc = pba->pba_pc; - pcireg_t id; - pcitag_t tag; - int dev; + struct bonito_softc *sc = pc->pc_conf_v; + const struct bonito_config *bc = sc->sc_bonito; if (pba->pba_bus != 0) return; - /* - * Check for an AMD CS5536 chip; if one is found, register - * the proper PCI configuration space hooks. - */ - - for (dev = pci_bus_maxdevs(pc, pba->pba_bus); dev >= 0; dev--) { - tag = pci_make_tag(pc, pba->pba_bus, dev, 0); - id = pci_conf_read(pc, tag, PCI_ID_REG); - if (id == PCI_ID_CODE(PCI_VENDOR_AMD, - PCI_PRODUCT_AMD_CS5536_PCISB)) { - glx_init(pc, tag, dev); - break; - } - } + (*bc->bc_attach_hook)(pc); } /* diff --git a/sys/arch/loongson/dev/bonitovar.h b/sys/arch/loongson/dev/bonitovar.h index 061950cfa4f..400d8ccfcc8 100644 --- a/sys/arch/loongson/dev/bonitovar.h +++ b/sys/arch/loongson/dev/bonitovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bonitovar.h,v 1.2 2010/02/05 20:51:22 miod Exp $ */ +/* $OpenBSD: bonitovar.h,v 1.3 2010/02/09 21:31:46 miod Exp $ */ /* $NetBSD: bonitovar.h,v 1.4 2008/04/28 20:23:28 martin Exp $ */ /*- @@ -46,6 +46,9 @@ struct bonito_config { uint32_t bc_intSteer; uint32_t bc_intPol; + /* PCI Attach hook for the first bus */ + void (*bc_attach_hook)(pci_chipset_tag_t); + /* PCI Interrupt Assignment for the first bus */ int (*bc_intr_map)(int, int, int); }; diff --git a/sys/arch/loongson/loongson/gdium_machdep.c b/sys/arch/loongson/loongson/gdium_machdep.c index c01c9f04159..dfd1355def7 100644 --- a/sys/arch/loongson/loongson/gdium_machdep.c +++ b/sys/arch/loongson/loongson/gdium_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gdium_machdep.c,v 1.1 2010/02/05 20:51:22 miod Exp $ */ +/* $OpenBSD: gdium_machdep.c,v 1.2 2010/02/09 21:31:47 miod Exp $ */ /* * Copyright (c) 2010 Miodrag Vallat. @@ -27,11 +27,15 @@ #include <machine/autoconf.h> #include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> #include <loongson/dev/bonitovar.h> #include <loongson/dev/bonito_irq.h> -int gdium_intr_map(int, int, int); +int gdium_revision = 0; + +void gdium_attach_hook(pci_chipset_tag_t); +int gdium_intr_map(int, int, int); const struct bonito_config gdium_bonito = { .bc_adbase = 11, @@ -43,9 +47,80 @@ const struct bonito_config gdium_bonito = { .bc_intPol = LOONGSON_INTRMASK_DRAM_PARERR | LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR, + .bc_attach_hook = gdium_attach_hook, .bc_intr_map = gdium_intr_map }; +void +gdium_attach_hook(pci_chipset_tag_t pc) +{ + pcireg_t id; + pcitag_t tag; + int bar; +#if 0 + pcireg_t reg; + int dev, func; +#endif + + /* + * Clear all BAR of the mini PCI slot; PMON did not initialize + * it, and we do not want it to conflict with anything. + */ + + tag = pci_make_tag(pc, 0, 13, 0); + for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END; bar += 4) + pci_conf_write(pc, tag, bar, 0); + + /* + * Figure out which motherboard we are running on. + * Might not be good enough... + */ + + tag = pci_make_tag(pc, 0, 17, 0); + id = pci_conf_read(pc, tag, PCI_ID_REG); + if (id == PCI_ID_CODE(PCI_VENDOR_NEC, PCI_PRODUCT_NEC_USB)) + gdium_revision = 1; + +#if 0 /* XXX Linux does this... but this causes enumeration to fail */ + /* + * Tweak the usb controller capabilities. + */ + + for (dev = pci_bus_maxdevs(pc, 0); dev >= 0; dev--) { + tag = pci_make_tag(pc, 0, dev, 0); + id = pci_conf_read(pc, tag, PCI_ID_REG); + if (id != PCI_ID_CODE(PCI_VENDOR_NEC, PCI_PRODUCT_NEC_USB)) + continue; + if (gdium_revision == 0) { + reg = pci_conf_read(pc, tag, 0xe0); + reg |= 0x00000003; + pci_conf_write(pc, tag, 0xe0, reg); + } else { + for (func = 0; func < 2; func++) { + tag = pci_make_tag(pc, 0, dev, func); + id = pci_conf_read(pc, tag, PCI_ID_REG); + if (PCI_VENDOR(id) != PCI_VENDOR_NEC) + continue; + if (PCI_PRODUCT(id) != PCI_PRODUCT_NEC_USB && + PCI_PRODUCT(id) != PCI_PRODUCT_NEC_USB2) + continue; + + /* 0114331f -> 0114331d */ + reg = pci_conf_read(pc, tag, 0xe0); + reg &= ~0x00000007; + reg |= 0x00000005; + pci_conf_write(pc, tag, 0xe0, reg); + + /* 00006c42 -> 00006c62 */ + reg = pci_conf_read(pc, tag, 0xe4); + reg |= 0x00000020; + pci_conf_write(pc, tag, 0xe4, reg); + } + } + } +#endif +} + int gdium_intr_map(int dev, int fn, int pin) { @@ -58,22 +133,20 @@ gdium_intr_map(int dev, int fn, int pin) return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA); /* USB */ case 15: -#if 0 /* on revision 1 -- how to tell them apart? */ - return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + - (pa->pa_intrpin - 1)); -#else - return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIB); -#endif + if (gdium_revision == 0) + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + + (pin - 1)); + else + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIB); /* Ethernet */ case 16: return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCID); - /* USB */ + /* USB, not present in old motherboard revision */ case 17: -#if 0 /* not present on revision 1 */ - break; -#else - return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIC); -#endif + if (gdium_revision != 0) + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIC); + else + break; default: break; } diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c index 1f812872159..b70383a63bb 100644 --- a/sys/arch/loongson/loongson/yeeloong_machdep.c +++ b/sys/arch/loongson/loongson/yeeloong_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yeeloong_machdep.c,v 1.1 2010/02/05 20:51:22 miod Exp $ */ +/* $OpenBSD: yeeloong_machdep.c,v 1.2 2010/02/09 21:31:47 miod Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -27,11 +27,14 @@ #include <machine/autoconf.h> #include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> #include <loongson/dev/bonitovar.h> #include <loongson/dev/bonito_irq.h> +#include <loongson/dev/glxvar.h> -int yeeloong_intr_map(int, int, int); +void yeeloong_attach_hook(pci_chipset_tag_t); +int yeeloong_intr_map(int, int, int); const struct bonito_config yeeloong_bonito = { .bc_adbase = 11, @@ -44,9 +47,33 @@ const struct bonito_config yeeloong_bonito = { LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR | LOONGSON_INTRMASK_INT0 | LOONGSON_INTRMASK_INT1, + .bc_attach_hook = yeeloong_attach_hook, .bc_intr_map = yeeloong_intr_map }; +void +yeeloong_attach_hook(pci_chipset_tag_t pc) +{ + pcireg_t id; + pcitag_t tag; + int dev; + + /* + * Check for an AMD CS5536 chip; if one is found, register + * the proper PCI configuration space hooks. + */ + + for (dev = pci_bus_maxdevs(pc, 0); dev >= 0; dev--) { + tag = pci_make_tag(pc, 0, dev, 0); + id = pci_conf_read(pc, tag, PCI_ID_REG); + if (id == PCI_ID_CODE(PCI_VENDOR_AMD, + PCI_PRODUCT_AMD_CS5536_PCISB)) { + glx_init(pc, tag, dev); + break; + } + } +} + int yeeloong_intr_map(int dev, int fn, int pin) { |