summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreast <andreast@FreeBSD.org>2014-01-20 21:54:05 +0000
committerandreast <andreast@FreeBSD.org>2014-01-20 21:54:05 +0000
commit3ee38761c871d6373b596fdb00e2c16fdf220a81 (patch)
tree60d412bb51249d90b002b7212082faaf660b1b43
parent4b39f65469a275c097466f63395672a37eec2481 (diff)
downloadFreeBSD-src-3ee38761c871d6373b596fdb00e2c16fdf220a81.zip
FreeBSD-src-3ee38761c871d6373b596fdb00e2c16fdf220a81.tar.gz
Fix the resource information for the i2s-a node on certain G5 PowerMacs.
This is the first step needed to get the snapper codec working on those machines. The second step is to enable the corresponding I2S device and its clock. Tested on machines where the snapper codec was already working, a G4 PowerBook and a PowerMac9,1 with a Shasta based macio. The PowerMac7,2/7,3 with a K2 based macio can now also play sound. MFC after: 1 month
-rw-r--r--sys/powerpc/powermac/macio.c55
-rw-r--r--sys/powerpc/powermac/maciovar.h3
2 files changed, 56 insertions, 2 deletions
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c
index dad261c..6a0b913 100644
--- a/sys/powerpc/powermac/macio.c
+++ b/sys/powerpc/powermac/macio.c
@@ -236,13 +236,45 @@ macio_add_intr(phandle_t devnode, struct macio_devinfo *dinfo)
static void
macio_add_reg(phandle_t devnode, struct macio_devinfo *dinfo)
{
- struct macio_reg *reg;
- int i, nreg;
+ struct macio_reg *reg, *regp;
+ phandle_t child;
+ char buf[8];
+ int i, layout_id = 0, nreg, res;
nreg = OF_getprop_alloc(devnode, "reg", sizeof(*reg), (void **)&reg);
if (nreg == -1)
return;
+ /*
+ * Some G5's have broken properties in the i2s-a area. If so we try
+ * to fix it. Right now we know of two different cases, one for
+ * sound layout-id 36 and the other one for sound layout-id 76.
+ * What is missing is the base address for the memory addresses.
+ * We take them from the parent node (i2s) and use the size
+ * information from the child.
+ */
+
+ if (reg[0].mr_base == 0) {
+ child = OF_child(devnode);
+ while (child != 0) {
+ res = OF_getprop(child, "name", buf, sizeof(buf));
+ if (res > 0 && strcmp(buf, "sound") == 0)
+ break;
+ child = OF_peer(child);
+ }
+
+ res = OF_getprop(child, "layout-id", &layout_id,
+ sizeof(layout_id));
+
+ if (res > 0 && (layout_id == 36 || layout_id == 76)) {
+ res = OF_getprop_alloc(OF_parent(devnode), "reg",
+ sizeof(*regp), (void **)&regp);
+ reg[0] = regp[0];
+ reg[1].mr_base = regp[1].mr_base;
+ reg[2].mr_base = regp[1].mr_base + reg[1].mr_size;
+ }
+ }
+
for (i = 0; i < nreg; i++) {
resource_list_add(&dinfo->mdi_resources, SYS_RES_MEMORY, i,
reg[i].mr_base, reg[i].mr_base + reg[i].mr_size,
@@ -284,6 +316,7 @@ macio_attach(device_t dev)
phandle_t subchild;
device_t cdev;
u_int reg[3];
+ char compat[32];
int error, quirks;
sc = device_get_softc(dev);
@@ -297,6 +330,9 @@ macio_attach(device_t dev)
return (ENXIO);
}
+ /* Used later to see if we have to enable the I2S part. */
+ OF_getprop(root, "compatible", compat, sizeof(compat));
+
sc->sc_base = reg[2];
sc->sc_size = MACIO_REG_SIZE;
@@ -378,6 +414,21 @@ macio_attach(device_t dev)
bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
}
+
+ /*
+ * Make sure the I2S0 and the I2S0_CLK are enabled.
+ * On certain G5's they are not.
+ */
+ if ((strcmp(ofw_bus_get_name(cdev), "i2s") == 0) &&
+ (strcmp(compat, "K2-Keylargo") == 0)) {
+
+ uint32_t fcr1;
+
+ fcr1 = bus_read_4(sc->sc_memr, KEYLARGO_FCR1);
+ fcr1 |= FCR1_I2S0_CLK_ENABLE | FCR1_I2S0_ENABLE;
+ bus_write_4(sc->sc_memr, KEYLARGO_FCR1, fcr1);
+ }
+
}
return (bus_generic_attach(dev));
diff --git a/sys/powerpc/powermac/maciovar.h b/sys/powerpc/powermac/maciovar.h
index 61fac46..ed9c15d 100644
--- a/sys/powerpc/powermac/maciovar.h
+++ b/sys/powerpc/powermac/maciovar.h
@@ -48,6 +48,9 @@
#define FCR_ENET_ENABLE 0x60000000
#define FCR_ENET_RESET 0x80000000
+#define FCR1_I2S0_CLK_ENABLE 0x00001000
+#define FCR1_I2S0_ENABLE 0x00002000
+
/* Used only by macio_enable_wireless() for now. */
#define KEYLARGO_GPIO_BASE 0x6a
#define KEYLARGO_EXTINT_GPIO_REG_BASE 0x58
OpenPOWER on IntegriCloud