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