Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/macppc/pci add G5 support



details:   https://anonhg.NetBSD.org/src/rev/201c1cb7e342
branches:  trunk
changeset: 786558:201c1cb7e342
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed May 01 14:24:48 2013 +0000

description:
add G5 support
from Phileas Fogg

diffstat:

 sys/arch/macppc/pci/uninorth.c |  103 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 95 insertions(+), 8 deletions(-)

diffs (181 lines):

diff -r ab584894c9cc -r 201c1cb7e342 sys/arch/macppc/pci/uninorth.c
--- a/sys/arch/macppc/pci/uninorth.c    Wed May 01 13:11:59 2013 +0000
+++ b/sys/arch/macppc/pci/uninorth.c    Wed May 01 14:24:48 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uninorth.c,v 1.16 2011/10/26 04:56:23 macallan Exp $   */
+/*     $NetBSD: uninorth.c,v 1.17 2013/05/01 14:24:48 macallan Exp $   */
 
 /*-
  * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uninorth.c,v 1.16 2011/10/26 04:56:23 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uninorth.c,v 1.17 2013/05/01 14:24:48 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -52,6 +52,8 @@
 
 static pcireg_t uninorth_conf_read(void *, pcitag_t, int);
 static void uninorth_conf_write(void *, pcitag_t, int, pcireg_t);
+static pcireg_t uninorth_conf_read_v3(void *, pcitag_t, int);
+static void uninorth_conf_write_v3(void *, pcitag_t, int, pcireg_t);
 
 CFATTACH_DECL_NEW(uninorth, sizeof(struct uninorth_softc),
     uninorth_match, uninorth_attach, NULL, NULL);
@@ -67,7 +69,9 @@
 
        memset(compat, 0, sizeof(compat));
        OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
-       if (strcmp(compat, "uni-north") != 0)
+       if (strcmp(compat, "uni-north") != 0 &&
+           strcmp(compat, "u3-agp") != 0 &&
+           strcmp(compat, "u4-pcie") != 0)
                return 0;
 
        return 1;
@@ -82,6 +86,8 @@
        struct pcibus_attach_args pba;
        int len, child, node = ca->ca_node;
        uint32_t reg[2], busrange[2];
+       char compat[32];
+       int ver;
        struct ranges {
                uint32_t pci_hi, pci_mid, pci_lo;
                uint32_t host;
@@ -91,6 +97,15 @@
        printf("\n");
        sc->sc_dev = self;
 
+       memset(compat, 0, sizeof(compat));
+       OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
+       if (strcmp(compat, "u3-agp") == 0)
+               ver = 3;
+       else if (strcmp(compat, "u4-pcie") == 0)
+               ver = 4;
+       else
+               ver = 0;
+
        /* UniNorth address */
        if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8)
                return;
@@ -99,6 +114,8 @@
        if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
                return;
 
+       memset(&sc->sc_iot, 0, sizeof(sc->sc_iot));
+
        /* find i/o tag */
        len = OF_getprop(node, "ranges", ranges, sizeof(ranges));
        if (len == -1)
@@ -117,7 +134,6 @@
        /* XXX enable gmac ethernet */
        for (child = OF_child(node); child; child = OF_peer(child)) {
                volatile int *gmac_gbclock_en = (void *)0xf8000020;
-               char compat[32];
 
                memset(compat, 0, sizeof(compat));
                OF_getprop(child, "compatible", compat, sizeof(compat));
@@ -131,6 +147,7 @@
            "uninorth io-space") != 0)
                panic("Can't init uninorth io tag");
 
+       memset(&sc->sc_memt, 0, sizeof(sc->sc_memt));
        sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE;
        sc->sc_memt.pbs_base = 0x00000000;
        if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt,
@@ -139,14 +156,22 @@
 
        macppc_pci_get_chipset_tag(pc);
        pc->pc_node = node;
-       pc->pc_addr = mapiodev(reg[0] + 0x800000, 4, false);
-       pc->pc_data = mapiodev(reg[0] + 0xc00000, 8, false);
        pc->pc_bus = busrange[0];
-       pc->pc_conf_read = uninorth_conf_read;
-       pc->pc_conf_write = uninorth_conf_write;
        pc->pc_iot = &sc->sc_iot;
        pc->pc_memt = &sc->sc_memt;
 
+       if (ver < 3) {
+               pc->pc_addr = mapiodev(reg[0] + 0x800000, 4, false);
+               pc->pc_data = mapiodev(reg[0] + 0xc00000, 8, false);
+               pc->pc_conf_read = uninorth_conf_read;
+               pc->pc_conf_write = uninorth_conf_write;
+       } else {
+               pc->pc_addr = mapiodev(reg[1] + 0x800000, 4, false);
+               pc->pc_data = mapiodev(reg[1] + 0xc00000, 8, false);
+               pc->pc_conf_read = uninorth_conf_read_v3;
+               pc->pc_conf_write = uninorth_conf_write_v3;
+       }
+
        memset(&pba, 0, sizeof(pba));
        pba.pba_memt = pc->pc_memt;
        pba.pba_iot = pc->pc_iot;
@@ -237,3 +262,65 @@
 
        splx(s);
 }
+
+static pcireg_t
+uninorth_conf_read_v3(void *cookie, pcitag_t tag, int reg)
+{
+       pci_chipset_tag_t pc = cookie;
+       int32_t *daddr = pc->pc_data;
+       pcireg_t data;
+       int bus, dev, func, s;
+       uint32_t x;
+
+       /* UniNorth seems to have a 64bit data port */
+       if (reg & 0x04)
+               daddr++;
+
+       pci_decompose_tag(pc, tag, &bus, &dev, &func);
+
+       x = (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 1;
+       /* Set extended register bits */
+       x |= (reg >> 8) << 28;
+
+       s = splhigh();
+
+       out32rb(pc->pc_addr, x);
+       in32rb(pc->pc_addr);
+       data = 0xffffffff;
+       if (!badaddr(daddr, 4))
+               data = in32rb(daddr);
+       out32rb(pc->pc_addr, 0);
+       in32rb(pc->pc_addr);
+       splx(s);
+
+       return data;
+}
+
+static void
+uninorth_conf_write_v3(void *cookie, pcitag_t tag, int reg, pcireg_t data)
+{
+       pci_chipset_tag_t pc = cookie;
+       int32_t *daddr = pc->pc_data;
+       int bus, dev, func, s;
+       uint32_t x;
+
+       /* UniNorth seems to have a 64bit data port */
+       if (reg & 0x04)
+               daddr++;
+
+       pci_decompose_tag(pc, tag, &bus, &dev, &func);
+
+       x = (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 1;
+       /* Set extended register bits */
+       x |= (reg >> 8) << 28;
+
+       s = splhigh();
+
+       out32rb(pc->pc_addr, x);
+       in32rb(pc->pc_addr);
+       out32rb(daddr, data);
+       out32rb(pc->pc_addr, 0);
+       in32rb(pc->pc_addr);
+
+       splx(s);
+}



Home | Main Index | Thread Index | Old Index