summaryrefslogtreecommitdiff
path: root/sys/arch/loongson
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-02-09 21:31:48 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-02-09 21:31:48 +0000
commit721729e58c8be07fe413bd0be2c80a414dd19d97 (patch)
treefec6c0187f34382ad452f22073205616581b23ea /sys/arch/loongson
parent93c7d2be883100bf4bd91acc3da5acb2225a9bbd (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.c23
-rw-r--r--sys/arch/loongson/dev/bonitovar.h5
-rw-r--r--sys/arch/loongson/loongson/gdium_machdep.c101
-rw-r--r--sys/arch/loongson/loongson/yeeloong_machdep.c31
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)
{