summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/modules/sound/driver/ai2s/Makefile2
-rw-r--r--sys/powerpc/include/atomic.h37
-rw-r--r--sys/powerpc/powermac/macio.c55
-rw-r--r--sys/powerpc/powermac/maciovar.h3
4 files changed, 94 insertions, 3 deletions
diff --git a/sys/modules/sound/driver/ai2s/Makefile b/sys/modules/sound/driver/ai2s/Makefile
index d693ddf..5f56ba6 100644
--- a/sys/modules/sound/driver/ai2s/Makefile
+++ b/sys/modules/sound/driver/ai2s/Makefile
@@ -5,6 +5,6 @@
KMOD= snd_ai2s
SRCS= device_if.h bus_if.h ofw_bus_if.h
SRCS+= channel_if.h feeder_if.h mixer_if.h
-SRCS+= snapper.c tumbler.c aoa.c i2s.c
+SRCS+= onyx.c snapper.c tumbler.c aoa.c i2s.c
.include <bsd.kmod.mk>
diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h
index c2a9921..d467381 100644
--- a/sys/powerpc/include/atomic.h
+++ b/sys/powerpc/include/atomic.h
@@ -684,10 +684,47 @@ atomic_fetchadd_long(volatile u_long *p, u_long v)
return (value);
}
+static __inline u_int
+atomic_swap_32(volatile u_int *p, u_int v)
+{
+ u_int prev;
+
+ __asm __volatile(
+ "1: lwarx %0,0,%2\n"
+ " stwcx. %3,0,%2\n"
+ " bne- 1b\n"
+ : "=&r" (prev), "+m" (*(volatile u_int *)p)
+ : "r" (p), "r" (v)
+ : "cc", "memory");
+
+ return (prev);
+}
+
+#ifdef __powerpc64__
+static __inline u_long
+atomic_swap_64(volatile u_long *p, u_long v)
+{
+ u_long prev;
+
+ __asm __volatile(
+ "1: ldarx %0,0,%2\n"
+ " stdcx. %3,0,%2\n"
+ " bne- 1b\n"
+ : "=&r" (prev), "+m" (*(volatile u_long *)p)
+ : "r" (p), "r" (v)
+ : "cc", "memory");
+
+ return (prev);
+}
+#endif
+
#define atomic_fetchadd_32 atomic_fetchadd_int
+#define atomic_swap_int atomic_swap_32
#ifdef __powerpc64__
#define atomic_fetchadd_64 atomic_fetchadd_long
+#define atomic_swap_long atomic_swap_64
+#define atomic_swap_ptr atomic_swap_64
#endif
#undef __ATOMIC_REL
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c
index b31cf15..8a980ba 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