Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/broadcom Mailbox improvements from mlelstv@
details: https://anonhg.NetBSD.org/src/rev/c1d46dbb2e57
branches: trunk
changeset: 332739:c1d46dbb2e57
user: skrll <skrll%NetBSD.org@localhost>
date: Tue Oct 07 08:30:05 2014 +0000
description:
Mailbox improvements from mlelstv@
Serialise access to the mailbox and use interrupts.
XXX if (cold) should go
diffstat:
sys/arch/arm/broadcom/bcm2835_mbox.c | 116 ++++++++++++++++++++++++++---
sys/arch/arm/broadcom/bcm2835_mbox.h | 11 ++-
sys/arch/arm/broadcom/bcm2835_mbox_subr.c | 10 +--
sys/arch/arm/broadcom/bcm2835_obio.c | 6 +-
4 files changed, 116 insertions(+), 27 deletions(-)
diffs (278 lines):
diff -r 52888ef39713 -r c1d46dbb2e57 sys/arch/arm/broadcom/bcm2835_mbox.c
--- a/sys/arch/arm/broadcom/bcm2835_mbox.c Tue Oct 07 07:04:35 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_mbox.c Tue Oct 07 08:30:05 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_mbox.c,v 1.7 2014/10/02 11:58:12 skrll Exp $ */
+/* $NetBSD: bcm2835_mbox.c,v 1.8 2014/10/07 08:30:05 skrll Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_mbox.c,v 1.7 2014/10/02 11:58:12 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_mbox.c,v 1.8 2014/10/07 08:30:05 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -52,14 +52,20 @@
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_dma_tag_t sc_dmat;
+ void *sc_intrh;
kmutex_t sc_lock;
+ kmutex_t sc_intr_lock;
+ kcondvar_t sc_chan[BCM2835_MBOX_NUMCHANNELS];
+ uint32_t sc_mbox[BCM2835_MBOX_NUMCHANNELS];
};
static struct bcm2835mbox_softc *bcm2835mbox_sc;
static int bcmmbox_match(device_t, cfdata_t, void *);
static void bcmmbox_attach(device_t, device_t, void *);
+static int bcmmbox_intr1(struct bcm2835mbox_softc *, int);
+static int bcmmbox_intr(void *);
CFATTACH_DECL_NEW(bcmmbox, sizeof(struct bcm2835mbox_softc),
bcmmbox_match, bcmmbox_attach, NULL, NULL);
@@ -82,17 +88,18 @@
struct bcm2835mbox_softc *sc = device_private(self);
struct amba_attach_args *aaa = aux;
struct bcmmbox_attach_args baa;
+ int i;
aprint_naive("\n");
aprint_normal(": VC mailbox\n");
- if (bcm2835mbox_sc == NULL)
- bcm2835mbox_sc = sc;
-
sc->sc_dev = self;
sc->sc_iot = aaa->aaa_iot;
sc->sc_dmat = aaa->aaa_dmat;
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_VM);
+ for (i = 0; i < BCM2835_MBOX_NUMCHANNELS; ++i)
+ cv_init(&sc->sc_chan[i], "bcmmbox");
if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_MBOX_SIZE, 0,
&sc->sc_ioh)) {
@@ -100,10 +107,74 @@
return;
}
+ sc->sc_intrh = bcm2835_intr_establish(aaa->aaa_intr, IPL_VM,
+ bcmmbox_intr, sc);
+ if (sc->sc_intrh == NULL) {
+ aprint_error_dev(sc->sc_dev, "unable to establish interrupt\n");
+ return;
+ }
+
+ /* enable mbox interrupt */
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_MBOX_CFG,
+ BCM2835_MBOX_CFG_DATAIRQEN);
+
+ if (bcm2835mbox_sc == NULL)
+ bcm2835mbox_sc = sc;
+
baa.baa_dmat = aaa->aaa_dmat;
sc->sc_platdev = config_found_ia(self, "bcmmboxbus", &baa, NULL);
}
+static int
+bcmmbox_intr1(struct bcm2835mbox_softc *sc, int cv)
+{
+ uint32_t mbox, chan, data;
+ int ret = 0;
+
+ KASSERT(mutex_owned(&sc->sc_intr_lock));
+
+ bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, BCM2835_MBOX_SIZE,
+ BUS_SPACE_BARRIER_READ);
+
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ BCM2835_MBOX0_STATUS) & BCM2835_MBOX_STATUS_EMPTY) == 0) {
+
+ mbox = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ BCM2835_MBOX0_READ);
+
+ chan = BCM2835_MBOX_CHAN(mbox);
+ data = BCM2835_MBOX_DATA(mbox);
+ ret = 1;
+
+ if (BCM2835_MBOX_CHAN(sc->sc_mbox[chan]) != 0) {
+ aprint_error("bcmmbox_intr: chan %d overflow\n",chan);
+ continue;
+ }
+
+ sc->sc_mbox[chan] = data | BCM2835_MBOX_CHANMASK;
+
+ if (cv)
+ cv_broadcast(&sc->sc_chan[chan]);
+ }
+
+ return ret;
+}
+
+static int
+bcmmbox_intr(void *cookie)
+{
+ struct bcm2835mbox_softc *sc = cookie;
+ int ret;
+
+ mutex_enter(&sc->sc_intr_lock);
+
+ ret = bcmmbox_intr1(sc, 1);
+
+ mutex_exit(&sc->sc_intr_lock);
+
+ return ret;
+}
+
void
bcmmbox_read(uint8_t chan, uint32_t *data)
{
@@ -111,7 +182,20 @@
KASSERT(sc != NULL);
- return bcm2835_mbox_read(sc->sc_iot, sc->sc_ioh, chan, data);
+ mutex_enter(&sc->sc_lock);
+
+ mutex_enter(&sc->sc_intr_lock);
+ while (BCM2835_MBOX_CHAN(sc->sc_mbox[chan]) == 0) {
+ if (cold)
+ bcmmbox_intr1(sc, 0);
+ else
+ cv_wait(&sc->sc_chan[chan], &sc->sc_intr_lock);
+ }
+ *data = BCM2835_MBOX_DATA(sc->sc_mbox[chan]);
+ sc->sc_mbox[chan] = 0;
+ mutex_exit(&sc->sc_intr_lock);
+
+ mutex_exit(&sc->sc_lock);
}
void
@@ -120,8 +204,14 @@
struct bcm2835mbox_softc *sc = bcm2835mbox_sc;
KASSERT(sc != NULL);
+ KASSERT(BCM2835_MBOX_CHAN(chan) == chan);
+ KASSERT(BCM2835_MBOX_CHAN(data) == 0);
- return bcm2835_mbox_write(sc->sc_iot, sc->sc_ioh, chan, data);
+ mutex_enter(&sc->sc_lock);
+
+ bcm2835_mbox_write(sc->sc_iot, sc->sc_ioh, chan, data);
+
+ mutex_exit(&sc->sc_lock);
}
int
@@ -155,16 +245,12 @@
memcpy(dma_buf, buf, buflen);
- mutex_enter(&sc->sc_lock);
-
- bus_dmamap_sync(sc->sc_dmat, map, 0, buflen, BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, map, 0, buflen,
+ BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
bcmmbox_write(chan, map->dm_segs[0].ds_addr);
- bus_dmamap_sync(sc->sc_dmat, map, 0, buflen, BUS_DMASYNC_POSTWRITE);
- bus_dmamap_sync(sc->sc_dmat, map, 0, buflen, BUS_DMASYNC_PREREAD);
bcmmbox_read(chan, pres);
- bus_dmamap_sync(sc->sc_dmat, map, 0, buflen, BUS_DMASYNC_POSTREAD);
-
- mutex_exit(&sc->sc_lock);
+ bus_dmamap_sync(sc->sc_dmat, map, 0, buflen,
+ BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
memcpy(buf, dma_buf, buflen);
diff -r 52888ef39713 -r c1d46dbb2e57 sys/arch/arm/broadcom/bcm2835_mbox.h
--- a/sys/arch/arm/broadcom/bcm2835_mbox.h Tue Oct 07 07:04:35 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_mbox.h Tue Oct 07 08:30:05 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_mbox.h,v 1.4 2013/01/07 20:15:32 jmcneill Exp $ */
+/* $NetBSD: bcm2835_mbox.h,v 1.5 2014/10/07 08:30:05 skrll Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -34,6 +34,15 @@
#include <sys/bus.h>
+#define BCM2835_MBOX_NUMCHANNELS 16
+#define BCM2835_MBOX_CHANMASK 0xf
+
+#define BCM2835_MBOX_CHAN(chan) ((chan) & BCM2835_MBOX_CHANMASK)
+#define BCM2835_MBOX_DATA(data) ((data) & ~BCM2835_MBOX_CHANMASK)
+
+#define BCM2835_MBOX_MSG(chan, data) \
+ (BCM2835_MBOX_CHAN(chan) | BCM2835_MBOX_DATA(data))
+
void bcm2835_mbox_read(bus_space_tag_t, bus_space_handle_t, uint8_t,
uint32_t *);
void bcm2835_mbox_write(bus_space_tag_t, bus_space_handle_t, uint8_t,
diff -r 52888ef39713 -r c1d46dbb2e57 sys/arch/arm/broadcom/bcm2835_mbox_subr.c
--- a/sys/arch/arm/broadcom/bcm2835_mbox_subr.c Tue Oct 07 07:04:35 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_mbox_subr.c Tue Oct 07 08:30:05 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_mbox_subr.c,v 1.3 2012/10/13 08:42:50 skrll Exp $ */
+/* $NetBSD: bcm2835_mbox_subr.c,v 1.4 2014/10/07 08:30:05 skrll Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_mbox_subr.c,v 1.3 2012/10/13 08:42:50 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_mbox_subr.c,v 1.4 2014/10/07 08:30:05 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -44,12 +44,6 @@
#include <arm/broadcom/bcm2835_mboxreg.h>
#include <arm/broadcom/bcm2835reg.h>
-
-#define BCM2835_MBOX_CHAN(chan) ((chan) & 0xf)
-#define BCM2835_MBOX_DATA(data) ((data) & ~0xf)
-
-#define BCM2835_MBOX_MSG(chan, data) (((chan) & 0xf) | ((data) & ~0xf))
-
void
bcm2835_mbox_read(bus_space_tag_t iot, bus_space_handle_t ioh, uint8_t chan,
uint32_t *data)
diff -r 52888ef39713 -r c1d46dbb2e57 sys/arch/arm/broadcom/bcm2835_obio.c
--- a/sys/arch/arm/broadcom/bcm2835_obio.c Tue Oct 07 07:04:35 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_obio.c Tue Oct 07 08:30:05 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_obio.c,v 1.21 2014/09/07 14:16:44 jmcneill Exp $ */
+/* $NetBSD: bcm2835_obio.c,v 1.22 2014/10/07 08:30:05 skrll Exp $ */
/*-
* Copyright (c) 2012, 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.21 2014/09/07 14:16:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.22 2014/10/07 08:30:05 skrll Exp $");
#include "locators.h"
#include "obio.h"
@@ -81,7 +81,7 @@
.ad_name = "bcmmbox",
.ad_addr = BCM2835_ARMMBOX_BASE,
.ad_size = BCM2835_ARMMBOX_SIZE,
- .ad_intr = -1, /* BCM2835_INT_ARMMAILBOX */
+ .ad_intr = BCM2835_INT_ARMMAILBOX
},
{
/* System Timer */
Home |
Main Index |
Thread Index |
Old Index