Module Name:    src
Committed By:   macallan
Date:           Wed May  1 14:24:49 UTC 2013

Modified Files:
        src/sys/arch/macppc/pci: uninorth.c

Log Message:
add G5 support
from Phileas Fogg


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/macppc/pci/uninorth.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/macppc/pci/uninorth.c
diff -u src/sys/arch/macppc/pci/uninorth.c:1.16 src/sys/arch/macppc/pci/uninorth.c:1.17
--- src/sys/arch/macppc/pci/uninorth.c:1.16	Wed Oct 26 04:56:23 2011
+++ src/sys/arch/macppc/pci/uninorth.c	Wed May  1 14:24:48 2013
@@ -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 int uninorth_match(device_t, cfda
 
 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 @@ uninorth_match(device_t parent, cfdata_t
 
 	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 @@ uninorth_attach(device_t parent, device_
 	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 @@ uninorth_attach(device_t parent, device_
 	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 @@ uninorth_attach(device_t parent, device_
 	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 @@ uninorth_attach(device_t parent, device_
 	/* 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_attach(device_t parent, device_
 	    "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 @@ uninorth_attach(device_t parent, device_
 
 	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 @@ uninorth_conf_write(void *cookie, pcitag
 
 	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);
+}

Reply via email to