summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powermac
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2002-09-19 04:49:58 +0000
committergrehan <grehan@FreeBSD.org>2002-09-19 04:49:58 +0000
commit91ea6a395fa1639e288bc86fdd98bf0090fc2a7f (patch)
tree966657436b6d77f5cfdd54c3380436731651699a /sys/powerpc/powermac
parent3c2938f17a82d0e9fe251467c826b57a9de9546a (diff)
downloadFreeBSD-src-91ea6a395fa1639e288bc86fdd98bf0090fc2a7f.zip
FreeBSD-src-91ea6a395fa1639e288bc86fdd98bf0090fc2a7f.tar.gz
- probe the UniNorth chip in addition to the PCI bridges
- enable GEM ethernet cell if present - allow sparse address mapping for devices Approved by: benno
Diffstat (limited to 'sys/powerpc/powermac')
-rw-r--r--sys/powerpc/powermac/uninorth.c117
1 files changed, 114 insertions, 3 deletions
diff --git a/sys/powerpc/powermac/uninorth.c b/sys/powerpc/powermac/uninorth.c
index 8d59122..5e15c27 100644
--- a/sys/powerpc/powermac/uninorth.c
+++ b/sys/powerpc/powermac/uninorth.c
@@ -86,6 +86,7 @@ static int uninorth_route_interrupt(device_t, device_t, int);
*/
static int uninorth_enable_config(struct uninorth_softc *, u_int,
u_int, u_int, u_int);
+static void unin_enable_gmac(void);
/*
* Driver methods.
@@ -145,6 +146,7 @@ uninorth_attach(device_t dev)
{
struct uninorth_softc *sc;
phandle_t node;
+ phandle_t child;
u_int32_t reg[2], busrange[2];
struct uninorth_range *rp, *io, *mem[2];
int nmem, i;
@@ -164,8 +166,6 @@ uninorth_attach(device_t dev)
sc->sc_data = (vm_offset_t)pmap_mapdev(reg[0] + 0xc00000, PAGE_SIZE);
sc->sc_bus = busrange[0];
- ofw_pci_fixup(dev, sc->sc_bus, node);
-
bzero(sc->sc_range, sizeof(sc->sc_range));
sc->sc_nrange = OF_getprop(node, "ranges", sc->sc_range,
sizeof(sc->sc_range));
@@ -228,6 +228,27 @@ uninorth_attach(device_t dev)
}
}
+ /*
+ * Enable the GMAC ethernet cell if OpenFirmware says it is
+ * used
+ */
+ for (child = OF_child(node); child; child = OF_peer(child)) {
+ char compat[32];
+
+ memset(compat, 0, sizeof(compat));
+ OF_getprop(child, "compatible", compat, sizeof(compat));
+ if (strcmp(compat, "gmac") == 0) {
+ unin_enable_gmac();
+ }
+ }
+
+ /*
+ * Write out the correct PIC interrupt values to config space
+ * of all devices on the bus. This has to be done after the GEM
+ * cell is enabled above.
+ */
+ ofw_pci_fixup(dev, sc->sc_bus, node);
+
device_add_child(dev, "pci", device_get_unit(dev));
return (bus_generic_attach(dev));
}
@@ -336,7 +357,9 @@ uninorth_alloc_resource(device_t bus, device_t child, int type, int *rid,
switch (type) {
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
- bt = sc->sc_memt;
+ bt = PPC_BUS_SPACE_MEM;
+ if (flags & PPC_BUS_SPARSE4)
+ bt |= 4;
break;
case SYS_RES_IRQ:
return (bus_alloc_resource(bus, type, rid, start, end, count,
@@ -458,3 +481,91 @@ static driver_t unhb_driver = {
static devclass_t unhb_devclass;
DRIVER_MODULE(unhb, pci, unhb_driver, unhb_devclass, 0, 0);
+
+
+/*
+ * Small stub driver for the Uninorth chip itself, to allow setting
+ * of various parameters and cell enables
+ */
+static struct unin_chip_softc *uncsc;
+
+static void
+unin_enable_gmac(void)
+{
+ volatile u_int *clkreg;
+ u_int32_t tmpl;
+
+ if (uncsc == NULL)
+ panic("unin_enable_gmac: device not found");
+
+ clkreg = (void *)(uncsc->sc_addr + UNIN_CLOCKCNTL);
+ tmpl = inl(clkreg);
+ tmpl |= UNIN_CLOCKCNTL_GMAC;
+ outl(clkreg, tmpl);
+}
+
+static int
+unin_chip_probe(device_t dev)
+{
+ char *name;
+
+ name = nexus_get_name(dev);
+
+ if (name == NULL)
+ return (ENXIO);
+
+ if (strcmp(name, "uni-n") != 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Apple UniNorth System Controller");
+ return (0);
+}
+
+static int
+unin_chip_attach(device_t dev)
+{
+ phandle_t node;
+ u_int reg[2];
+
+ uncsc = device_get_softc(dev);
+ node = nexus_get_node(dev);
+
+ if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8)
+ return (ENXIO);
+
+ uncsc->sc_physaddr = reg[0];
+ uncsc->sc_size = reg[1];
+
+ /*
+ * Only map the first page, since that is where the registers
+ * of interest lie.
+ */
+ uncsc->sc_addr = (vm_offset_t) pmap_mapdev(reg[0], PAGE_SIZE);
+
+ uncsc->sc_version = *(u_int *)uncsc->sc_addr;
+ device_printf(dev, "Version %d\n", uncsc->sc_version);
+
+ return (0);
+}
+
+static device_method_t unin_chip_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, unin_chip_probe),
+ DEVMETHOD(device_attach, unin_chip_attach),
+
+ { 0, 0 }
+};
+
+static driver_t unin_chip_driver = {
+ "unin",
+ unin_chip_methods,
+ sizeof(struct unin_chip_softc)
+};
+
+static devclass_t unin_chip_devclass;
+
+DRIVER_MODULE(unin, nexus, unin_chip_driver, unin_chip_devclass, 0, 0);
+
+
+
+
OpenPOWER on IntegriCloud