Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-7]: src/sys Pull up following revision(s) (requested by skrll in ...
details: https://anonhg.NetBSD.org/src/rev/365d20935728
branches: netbsd-7
changeset: 798393:365d20935728
user: martin <martin%NetBSD.org@localhost>
date: Fri Oct 03 18:53:56 2014 +0000
description:
Pull up following revision(s) (requested by skrll in ticket #126):
sys/arch/evbarm/rpi/rpi_machdep.c: revision 1.47
sys/arch/arm/broadcom/bcm2835reg.h: revision 1.12
sys/arch/evbarm/conf/RPI: revision 1.52
sys/arch/evbarm/conf/RPI: revision 1.53
sys/arch/evbarm/conf/RPI: revision 1.54
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.10
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.11
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.12
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.13
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.14
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.15
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.3
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.4
sys/arch/arm/broadcom/bcm2835_dmac.h: revision 1.2
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.5
sys/arch/arm/broadcom/bcm2835_emmc.c: revision 1.18
sys/arch/arm/broadcom/bcm2835_dmac.h: revision 1.3
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.6
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.7
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.8
sys/arch/arm/broadcom/bcm2835_dmac.c: revision 1.9
sys/arch/arm/broadcom/files.bcm2835: revision 1.23
sys/dev/sdmmc/sdhc.c: revision 1.45
sys/dev/sdmmc/sdhc.c: revision 1.46
sys/dev/sdmmc/sdhc.c: revision 1.47
sys/dev/sdmmc/sdhcvar.h: revision 1.14
Various RPI DMAC and sdhc improvements.
diffstat:
sys/arch/arm/broadcom/bcm2835_dmac.c | 40 ++++--
sys/arch/arm/broadcom/bcm2835_dmac.h | 10 +-
sys/arch/arm/broadcom/bcm2835_emmc.c | 206 +++++++++++++++++++++++++++++++++-
sys/arch/arm/broadcom/bcm2835reg.h | 5 +-
sys/arch/arm/broadcom/files.bcm2835 | 4 +-
sys/arch/evbarm/conf/RPI | 4 +-
sys/arch/evbarm/rpi/rpi_machdep.c | 9 +-
sys/dev/sdmmc/sdhc.c | 35 +++--
sys/dev/sdmmc/sdhcvar.h | 5 +-
9 files changed, 271 insertions(+), 47 deletions(-)
diffs (truncated from 642 to 300 lines):
diff -r b3addb240c4a -r 365d20935728 sys/arch/arm/broadcom/bcm2835_dmac.c
--- a/sys/arch/arm/broadcom/bcm2835_dmac.c Fri Oct 03 16:42:46 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_dmac.c Fri Oct 03 18:53:56 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_dmac.c,v 1.2.2.2 2014/09/11 14:20:11 martin Exp $ */
+/* $NetBSD: bcm2835_dmac.c,v 1.2.2.3 2014/10/03 18:53:56 martin Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_dmac.c,v 1.2.2.2 2014/09/11 14:20:11 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_dmac.c,v 1.2.2.3 2014/10/03 18:53:56 martin Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -45,7 +45,7 @@
#include <arm/broadcom/bcm2835_dmac.h>
-#define BCM_DMAC_CHANNELMASK 0x00000ff2
+#define BCM_DMAC_CHANNELMASK 0x00000fff
struct bcm_dmac_softc;
@@ -109,6 +109,7 @@
bcm_dmac_attach(device_t parent, device_t self, void *aux)
{
struct bcm_dmac_softc *sc = device_private(self);
+ const prop_dictionary_t cfg = device_properties(self);
struct bcm_dmac_channel *ch;
struct amba_attach_args *aaa = aux;
uint32_t val;
@@ -123,12 +124,12 @@
return;
}
- sc->sc_channelmask = BCM_DMAC_CHANNELMASK;
- sc->sc_nchannels = 31 - __builtin_clz(sc->sc_channelmask);
+ prop_dictionary_get_uint32(cfg, "chanmask", &sc->sc_channelmask);
+ sc->sc_channelmask &= BCM_DMAC_CHANNELMASK;
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SCHED);
- sc->sc_nchannels = 31 - __builtin_clz(BCM_DMAC_CHANNELMASK);
+ sc->sc_nchannels = 31 - __builtin_clz(sc->sc_channelmask);
sc->sc_channels = kmem_alloc(
sizeof(*sc->sc_channels) * sc->sc_nchannels, KM_SLEEP);
if (sc->sc_channels == NULL) {
@@ -143,6 +144,7 @@
ch->ch_index = index;
ch->ch_callback = NULL;
ch->ch_callbackarg = NULL;
+ ch->ch_ih = NULL;
if ((__BIT(index) & sc->sc_channelmask) == 0)
continue;
@@ -153,13 +155,6 @@
val = DMAC_READ(sc, DMAC_CS(index));
val |= DMAC_CS_RESET;
DMAC_WRITE(sc, DMAC_CS(index), val);
-
- ch->ch_ih = bcm2835_intr_establish(BCM2835_INT_DMA0 + index,
- IPL_SCHED, bcm_dmac_intr, ch);
- if (ch->ch_ih == NULL) {
- aprint_error("(err)");
- sc->sc_channelmask &= ~__BIT(index);
- }
}
aprint_normal("\n");
aprint_naive("\n");
@@ -185,7 +180,8 @@
}
struct bcm_dmac_channel *
-bcm_dmac_alloc(enum bcm_dmac_type type, void (*cb)(void *), void *cbarg)
+bcm_dmac_alloc(enum bcm_dmac_type type, int ipl, void (*cb)(void *),
+ void *cbarg)
{
struct bcm_dmac_softc *sc;
struct bcm_dmac_channel *ch = NULL;
@@ -213,6 +209,20 @@
}
mutex_exit(&sc->sc_lock);
+ if (ch == NULL)
+ return NULL;
+
+ KASSERT(ch->ch_ih == NULL);
+ ch->ch_ih = bcm2835_intr_establish(BCM2835_INT_DMA0 + ch->ch_index,
+ ipl, bcm_dmac_intr, ch);
+ if (ch->ch_ih == NULL) {
+ aprint_error_dev(sc->sc_dev,
+ "failed to establish interrupt for DMA%d\n", ch->ch_index);
+ ch->ch_callback = NULL;
+ ch->ch_callbackarg = NULL;
+ ch = NULL;
+ }
+
return ch;
}
@@ -231,6 +241,8 @@
DMAC_WRITE(sc, DMAC_CS(ch->ch_index), val);
mutex_enter(&sc->sc_lock);
+ intr_disestablish(ch->ch_ih);
+ ch->ch_ih = NULL;
ch->ch_callback = NULL;
ch->ch_callbackarg = NULL;
mutex_exit(&sc->sc_lock);
diff -r b3addb240c4a -r 365d20935728 sys/arch/arm/broadcom/bcm2835_dmac.h
--- a/sys/arch/arm/broadcom/bcm2835_dmac.h Fri Oct 03 16:42:46 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_dmac.h Fri Oct 03 18:53:56 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_dmac.h,v 1.1.2.2 2014/09/11 14:20:11 martin Exp $ */
+/* $NetBSD: bcm2835_dmac.h,v 1.1.2.3 2014/10/03 18:53:56 martin Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -46,6 +46,12 @@
#define DMAC_CS_ACTIVE __BIT(0)
#define DMAC_CS_INTMASK (DMAC_CS_INT|DMAC_CS_END)
#define DMAC_CONBLK_AD(n) (0x04 + (0x100 * (n)))
+#define DMAC_TI(n) (0x08 + (0x100 * (n)))
+#define DMAC_SOURCE_AD(n) (0x0c + (0x100 * (n)))
+#define DMAC_DEST_AD(n) (0x10 + (0x100 * (n)))
+#define DMAC_TXFR_LEN(n) (0x14 + (0x100 * (n)))
+#define DMAC_STRIDE(n) (0x18 + (0x100 * (n)))
+#define DMAC_NEXTCONBK(n) (0x1c + (0x100 * (n)))
#define DMAC_DEBUG(n) (0x20 + (0x100 * (n)))
#define DMAC_DEBUG_LITE __BIT(28)
#define DMAC_DEBUG_VERSION __BITS(27,25)
@@ -95,7 +101,7 @@
struct bcm_dmac_channel;
-struct bcm_dmac_channel *bcm_dmac_alloc(enum bcm_dmac_type,
+struct bcm_dmac_channel *bcm_dmac_alloc(enum bcm_dmac_type, int,
void (*)(void *), void *);
void bcm_dmac_free(struct bcm_dmac_channel *);
void bcm_dmac_set_conblk_addr(struct bcm_dmac_channel *, bus_addr_t);
diff -r b3addb240c4a -r 365d20935728 sys/arch/arm/broadcom/bcm2835_emmc.c
--- a/sys/arch/arm/broadcom/bcm2835_emmc.c Fri Oct 03 16:42:46 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_emmc.c Fri Oct 03 18:53:56 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_emmc.c,v 1.9 2013/09/05 07:06:37 skrll Exp $ */
+/* $NetBSD: bcm2835_emmc.c,v 1.9.4.1 2014/10/03 18:53:56 martin Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,32 +30,61 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_emmc.c,v 1.9 2013/09/05 07:06:37 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_emmc.c,v 1.9.4.1 2014/10/03 18:53:56 martin Exp $");
+
+#include "bcmdmac.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/bus.h>
+#include <sys/condvar.h>
+#include <sys/mutex.h>
+#include <sys/kernel.h>
#include <arm/broadcom/bcm2835reg.h>
#include <arm/broadcom/bcm_amba.h>
+#include <arm/broadcom/bcm2835_dmac.h>
#include <dev/sdmmc/sdhcreg.h>
#include <dev/sdmmc/sdhcvar.h>
#include <dev/sdmmc/sdmmcvar.h>
+enum bcmemmc_dma_state {
+ EMMC_DMA_STATE_IDLE,
+ EMMC_DMA_STATE_BUSY,
+};
+
struct bcmemmc_softc {
struct sdhc_softc sc;
- device_t sc_sdmmc;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ bus_size_t sc_ios;
struct sdhc_host *sc_hosts[1];
void *sc_ih;
+
+ kmutex_t sc_lock;
+ kcondvar_t sc_cv;
+
+ enum bcmemmc_dma_state sc_state;
+
+ struct bcm_dmac_channel *sc_dmac;
+
+ bus_dmamap_t sc_dmamap;
+ bus_dma_segment_t sc_segs[1]; /* XXX assumes enough descriptors fit in one page */
+ struct bcm_dmac_conblk *sc_cblk;
+
+ uint32_t sc_physaddr;
};
static int bcmemmc_match(device_t, struct cfdata *, void *);
static void bcmemmc_attach(device_t, device_t, void *);
+static void bcmemmc_attach_i(device_t);
+#if NBCMDMAC > 0
+static int bcmemmc_xfer_data_dma(struct sdhc_host *, struct sdmmc_command *);
+static void bcmemmc_dma_done(void *);
+#endif
CFATTACH_DECL_NEW(bcmemmc, sizeof(struct bcmemmc_softc),
bcmemmc_match, bcmemmc_attach, NULL, NULL);
@@ -89,11 +118,8 @@
sc->sc.sc_flags |= SDHC_FLAG_HOSTCAPS;
sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_3V | SDHC_HIGH_SPEED_SUPP |
- SDHC_MAX_BLK_LEN_1024;
-#if notyet
- sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
- sc->sc.sc_caps |= SDHC_DMA_SUPPORT;
-#endif
+ (SDHC_MAX_BLK_LEN_1024 << SDHC_MAX_BLK_LEN_SHIFT);
+
sc->sc.sc_host = sc->sc_hosts;
sc->sc.sc_clkbase = 50000; /* Default to 50MHz */
sc->sc_iot = aaa->aaa_iot;
@@ -111,6 +137,8 @@
"can't map registers for %s: %d\n", aaa->aaa_name, error);
return;
}
+ sc->sc_ios = aaa->aaa_size;
+ sc->sc_physaddr = aaa->aaa_addr;
aprint_naive(": SDHC controller\n");
aprint_normal(": SDHC controller\n");
@@ -125,8 +153,74 @@
}
aprint_normal_dev(self, "interrupting on intr %d\n", aaa->aaa_intr);
- error = sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh,
- aaa->aaa_size);
+#if NBCMDMAC > 0
+ sc->sc_dmac = bcm_dmac_alloc(BCM_DMAC_TYPE_NORMAL, IPL_SDMMC,
+ bcmemmc_dma_done, sc);
+ if (sc->sc_dmac == NULL)
+ goto done;
+
+ sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
+ sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
+ sc->sc.sc_caps |= SDHC_DMA_SUPPORT;
+ sc->sc.sc_vendor_transfer_data_dma = bcmemmc_xfer_data_dma;
+
+ sc->sc_state = EMMC_DMA_STATE_IDLE;
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SDMMC);
+ cv_init(&sc->sc_cv, "bcmemmcdma");
+
+ int rseg;
+ error = bus_dmamem_alloc(sc->sc.sc_dmat, PAGE_SIZE, PAGE_SIZE,
+ PAGE_SIZE, sc->sc_segs, 1, &rseg, BUS_DMA_WAITOK);
+ if (error) {
+ aprint_error_dev(self, "dmamem_alloc failed (%d)\n", error);
+ goto fail;
+ }
+
+ error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_segs, rseg, PAGE_SIZE,
+ (void **)&sc->sc_cblk, BUS_DMA_WAITOK);
+ if (error) {
+ aprint_error_dev(self, "dmamem_map failed (%d)\n", error);
+ goto fail;
+ }
+ KASSERT(sc->sc_cblk != NULL);
+
+ memset(sc->sc_cblk, 0, PAGE_SIZE);
+
+ error = bus_dmamap_create(sc->sc.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
+ BUS_DMA_WAITOK, &sc->sc_dmamap);
+ if (error) {
+ aprint_error_dev(self, "dmamap_create failed (%d)\n", error);
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_dmamap, sc->sc_cblk,
+ PAGE_SIZE, NULL, BUS_DMA_WAITOK|BUS_DMA_WRITE);
+ if (error) {
+ aprint_error_dev(self, "dmamap_load failed (%d)\n", error);
+ goto fail;
+ }
+
+done:
+#endif
+ config_interrupts(self, bcmemmc_attach_i);
+ return;
+
+fail:
+ /* XXX add bus_dma failure cleanup */
Home |
Main Index |
Thread Index |
Old Index