PERFORCE change 181303 for review
Jakub Wojciech Klama
jceel at FreeBSD.org
Thu Jul 22 10:23:13 UTC 2010
http://p4web.freebsd.org/@@181303?ac=10
Change 181303 by jceel at jceel on 2010/07/22 10:22:43
EDMA3 driver improvements and refactoring.
Affected files ...
.. //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edma.c#5 edit
.. //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edmareg.h#5 edit
Differences ...
==== //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edma.c#5 (text+ko) ====
@@ -66,9 +66,9 @@
#include <arm/davinci/davincireg.h>
#include <arm/davinci/davinci_edmareg.h>
-#include <dev/dmae/dmae.h>
+#include <dev/gpdma/gpdma.h>
-#include "dmae_if.h"
+#include "gpdma_if.h"
#define DEBUG
//#undef DEBUG
@@ -87,10 +87,11 @@
int dc_status;
#define CHANNEL_ACTIVE 1
#define CHANNEL_ACTIVE_LINKED 2
+#define CHANNEL_STOPPED 3
#define CHANNEL_IDLE 0
int dc_laststatus;
- struct dmae_transfer * dc_xfer;
- struct dmae_transfer * dc_linkxfer;
+ struct gpdma_transfer * dc_xfer;
+ struct gpdma_transfer * dc_linkxfer;
};
struct davinci_edma_softc {
@@ -113,16 +114,16 @@
{ -1, 0 }
};
-static const struct dmae_capabilities davinci_edma_caps = {
+static const struct gpdma_capabilities davinci_edma_caps = {
.dc_nchannels = DAVINCI_EDMA_NCHANNELS,
- .dc_ops = DMAE_COPY,
- .dc_buffers = DMAEBUF_BLOCK | DMAEBUF_FRAME | DMAEBUF_FIFO,
- .dc_flags = DMAECAP_REPEAT | DMAECAP_LINK,
+ .dc_ops = GPDMA_COPY,
+ .dc_buffers = GPDMABUF_BLOCK | GPDMABUF_FRAME | GPDMABUF_FIFO,
+ .dc_flags = GPDMACAP_REPEAT | GPDMACAP_LINK,
};
static int davinci_edma_probe(device_t);
static int davinci_edma_attach(device_t);
-static int davinci_edma_setup_channel(device_t, int, struct dmae_transfer *);
+static int davinci_edma_setup_channel(device_t, int, struct gpdma_transfer *);
static int davinci_edma_clear_channel(device_t, int);
static int davinci_edma_start_channel(device_t, int);
static int davinci_edma_stop_channel(device_t, int);
@@ -134,8 +135,9 @@
static void davinci_edma_intr_tcerr1(void *);
static void davinci_edma_tcerr(struct davinci_edma_softc *, int);
-static int davinci_edma_setupdesc(struct dmae_transfer *,
+static int davinci_edma_setupdesc(struct gpdma_transfer *,
struct davinci_edma_desc *);
+static void davinci_edma_printdesc(struct davinci_edma_softc *, int);
static uint64_t ffs64(uint64_t);
#define davinci_edma_lock(sc) \
@@ -153,12 +155,11 @@
bus_space_write_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMACC_BASE + (_reg), (_data))
#define davinci_read_edmatc_4(_sc, _tc, _reg) \
bus_space_read_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMATC ## _tc ## _BASE + (_reg))
-#define davinci_write_edmatc_4(_sc, _tc, _reg) \
+#define davinci_write_edmatc_4(_sc, _tc, _reg, _data) \
bus_space_write_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMATC ## _tc ## _BASE + (_reg), (_data))
#define davinci_edma_copydesc(_sc, _desc, _idx) \
memcpy((uint8_t *)(DAVINCI_EDMA_BASE + DAVINCI_EDMA_PARAM(_idx)), (_desc), sizeof(param_desc))
-
static int
davinci_edma_probe(device_t dev)
{
@@ -231,7 +232,11 @@
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_DRAE0, 0xffffffff);
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_DRAEH0, 0xffffffff);
- dmae_register_driver(dev, &davinci_edma_caps, sc->ds_dmatag);
+ /* Enable TC error interrupts */
+ davinci_write_edmatc_4(sc, 0, DAVINCI_EDMATC_ERREN, 0xffff);
+ davinci_write_edmatc_4(sc, 1, DAVINCI_EDMATC_ERREN, 0xffff);
+
+ gpdma_register_driver(dev, &davinci_edma_caps, sc->ds_dmatag);
return (0);
@@ -248,7 +253,7 @@
}
static int
-davinci_edma_setup_channel(device_t dev, int chno, struct dmae_transfer *xfer)
+davinci_edma_setup_channel(device_t dev, int chno, struct gpdma_transfer *xfer)
{
struct davinci_edma_softc *sc = device_get_softc(dev);
struct davinci_edma_channel *ch;
@@ -261,6 +266,10 @@
ch = &sc->ds_channels[chno];
ch->dc_xfer = xfer;
+ /* Zero param_desc and link_desc */
+ memset(¶m_desc, 0, sizeof(struct davinci_edma_desc));
+ memset(&link_desc, 0, sizeof(struct davinci_edma_desc));
+
/* Allow at most one linked transfer */
if (xfer->dt_next != NULL && xfer->dt_next->dt_next != NULL)
return (EINVAL);
@@ -278,21 +287,29 @@
ret = davinci_edma_setupdesc(xfer->dt_next, &link_desc);
if (ret)
return (ret);
- printf("calling davinci_edma_copydesc(&link_desc=%p, chno=%d)\n", &link_desc, chno + 64);
+ debugf("calling davinci_edma_copydesc(&link_desc=%p, chno=%d)\n", &link_desc, chno + 64);
davinci_edma_copydesc(sc, &link_desc, chno + 64);
}
/* Enable channel interrupts */
-// if ((xfer->dt_flags & DMAE_TRANSFER_EXTTRIG) == 0)
+// if ((xfer->dt_flags & GPDMA_TRANSFER_EXTTRIG) == 0)
// davinci_edma_enable_channel(sc, chno);
if (chno > 31) {
chno -= 32;
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_IESRH, (1 << chno));
+ davinci_write_edmacc_4(sc, DAVINCI_EDMACC_EESRH, (1 << chno));
} else {
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_IESR, (1 << chno));
+ davinci_write_edmacc_4(sc, DAVINCI_EDMACC_EESR, (1 << chno));
}
+
+ bus_dmamap_sync(xfer->dt_src.db_dmatag, xfer->dt_src.db_dmamap,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(xfer->dt_dst.db_dmatag, xfer->dt_dst.db_dmamap,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
debugf("channel setup done.");
return (0);
@@ -345,7 +362,13 @@
static int
davinci_edma_stop_channel(device_t dev, int chno)
{
- return (ENOTSUP);
+ struct davinci_edma_softc *sc = device_get_softc(dev);
+ struct davinci_edma_channel *ch;
+
+ ch = &sc->ds_channels[chno];
+ ch->dc_status = CHANNEL_STOPPED;
+
+ return (0);
}
static int
@@ -369,7 +392,7 @@
}
if (active)
- return (DMAE_TRANSFER_INPROGRESS);
+ return (GPDMA_TRANSFER_INPROGRESS);
else
return (ch->dc_laststatus);
}
@@ -379,7 +402,7 @@
{
struct davinci_edma_softc *sc = (struct davinci_edma_softc *)arg;
struct davinci_edma_channel *ch;
- struct dmae_transfer *xfer = NULL;
+ struct gpdma_transfer *xfer = NULL;
uint64_t ipr;
uint32_t iprl, iprh;
int chno;
@@ -402,23 +425,38 @@
KASSERT(ch->dc_status != CHANNEL_IDLE, ("invalid channel state"));
+ printf("src dmatag=%p dst dmatag=%p src dmamap=%p dst dmamap=%p\n", xfer->dt_src.db_dmatag, xfer->dt_dst.db_dmatag, xfer->dt_src.db_dmamap, xfer->dt_dst.db_dmamap);
+ bus_dmamap_sync(xfer->dt_src.db_dmatag, xfer->dt_src.db_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_sync(xfer->dt_dst.db_dmatag, xfer->dt_dst.db_dmamap, BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTWRITE);
+
+
+
if (xfer->dt_callback != NULL) {
- xfer->dt_callback(DMAE_TRANSFER_COMPLETED,
+ xfer->dt_callback(GPDMA_TRANSFER_COMPLETED,
xfer->dt_callback_arg);
}
- if (chno > 32)
+ if (chno > 32) {
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_ICRH, (1 << (chno - 32)));
- else
+ // davinci_write_edmacc_4(sc, DAVINCI_EDMACC_ECRH, (1 << (chno - 32)));
+ } else {
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_ICR, (1 << chno));
+ // davinci_write_edmacc_4(sc, DAVINCI_EDMACC_ECR, (1 << chno));
+ }
ipr &= ~(1ULL << chno);
+
+ if (ch->dc_status == CHANNEL_STOPPED)
+ continue;
+
ch->dc_status = CHANNEL_IDLE;
+ if (xfer->dt_flags & GPDMA_TRANSFER_REPEAT)
+ davinci_edma_start_channel(sc->ds_dev, chno);
+
if (xfer->dt_next != NULL) {
ch->dc_xfer = xfer->dt_next;
davinci_edma_start_channel(sc->ds_dev, chno);
- return;
}
}
}
@@ -429,7 +467,7 @@
{
struct davinci_edma_softc *sc = (struct davinci_edma_softc *)arg;
struct davinci_edma_channel *ch;
- struct dmae_transfer *xfer = NULL;
+ struct gpdma_transfer *xfer = NULL;
uint64_t emr;
uint32_t emrl, emrh;
int chno;
@@ -450,7 +488,7 @@
KASSERT(ch->dc_status != CHANNEL_IDLE, ("invalid channel state"));
if (xfer->dt_callback != NULL) {
- xfer->dt_callback(DMAE_TRANSFER_ERROR,
+ xfer->dt_callback(GPDMA_TRANSFER_ERROR,
xfer->dt_callback_arg);
}
@@ -484,8 +522,8 @@
static void
davinci_edma_tcerr(struct davinci_edma_softc *sc, int tc)
{
- struct davinci_edma_channel *ch;
- struct dmae_transfer *xfer;
+// struct davinci_edma_channel *ch;
+// struct gpdma_transfer *xfer;
uint32_t errstat, errdet;
int chno;
@@ -497,24 +535,28 @@
errdet = davinci_read_edmatc_4(sc, 1, DAVINCI_EDMATC_ERRDET);
}
- chno = (errstat >> DAVINCI_EDMATC_ERRDET_TCCSHIFT) &
- DAVINCI_EDMATC_ERRDET_TCCMASK;
+ chno = ((errdet >> DAVINCI_EDMATC_ERRDET_TCCSHIFT) &
+ DAVINCI_EDMATC_ERRDET_TCCMASK);
+
+ device_printf(sc->ds_dev, "TC error: tc=%d, chno=%d, errstat=%08x, "
+ "errdet=%08x\n", tc, chno, errstat, errdet);
+
+ device_printf(sc->ds_dev, "Transfer descriptor that has failed:\n");
+ davinci_edma_printdesc(sc, chno);
- ch = &sc->ds_channels[chno];
- xfer = ch->dc_xfer;
+// ch = &sc->ds_channels[chno];
+// xfer = ch->dc_xfer;
- if (xfer->dt_callback != NULL) {
- xfer->dt_callback(DMAE_TRANSFER_ERROR,
- xfer->dt_callback_arg);
- }
+ panic("DMA transfer controller error");
}
static int
-davinci_edma_setupdesc(struct dmae_transfer *xfer,
+davinci_edma_setupdesc(struct gpdma_transfer *xfer,
struct davinci_edma_desc *desc)
{
int chno;
- uint32_t acnt, bcnt, srcbidx, dstbidx;
+ uint32_t acnt = 0, bcnt = 0, ccnt = 0;
+ uint32_t srcbidx, dstbidx, srccidx, dstcidx;
chno = rman_get_start(xfer->dt_res);
@@ -526,56 +568,115 @@
if (xfer->dt_src.db_length == 0 || xfer->dt_dst.db_length == 0)
return (EINVAL);
- if (xfer->dt_src.db_type == DMAEBUF_FRAME ||
- xfer->dt_dst.db_type == DMAEBUF_FRAME) {
- if (xfer->dt_src.db_type == DMAEBUF_FRAME &&
- xfer->dt_dst.db_type == DMAEBUF_FRAME &&
- xfer->dt_src.db_stride_width !=
- xfer->dt_dst.db_stride_width)
+ srccidx = 0;
+ dstcidx = 0;
+
+ /* block-to-block transfer */
+ if (xfer->dt_src.db_type == GPDMABUF_BLOCK && xfer->dt_dst.db_type == GPDMABUF_BLOCK)
+ {
+ if (xfer->dt_src.db_length != xfer->dt_dst.db_length)
return (EINVAL);
- acnt = (xfer->dt_src.db_type == DMAEBUF_FRAME
- ? xfer->dt_src.db_stride_width
- : xfer->dt_dst.db_stride_width);
- bcnt = (xfer->dt_src.db_type == DMAEBUF_FRAME
- ? xfer->dt_src.db_length /
- (acnt + xfer->dt_src.db_stride_spacing)
- : xfer->dt_dst.db_length /
- (acnt + xfer->dt_dst.db_stride_spacing));
-
- srcbidx = dstbidx = acnt;
+ acnt = xfer->dt_src.db_length;
+ bcnt = 1;
+ ccnt = 1;
+ srcbidx = dstbidx = srccidx = dstcidx = 1;
+ }
+
+ /* block-to-frame transfer */
+ if (xfer->dt_src.db_type == GPDMABUF_BLOCK && xfer->dt_dst.db_type == GPDMABUF_FRAME)
+ {
+ acnt = xfer->dt_dst.db_stride_width;
+ bcnt = xfer->dt_dst.db_length / xfer->dt_dst.db_stride_width; //xfer->dt_dst.db_nstrides;
+ ccnt = 1;
+ srcbidx = acnt;
+ dstbidx = acnt + xfer->dt_dst.db_stride_spacing;
+ srccidx = dstcidx = 0;
+ }
+
+ /* frame-to-block transfer */
+ if (xfer->dt_src.db_type == GPDMABUF_FRAME && xfer->dt_dst.db_type == GPDMABUF_BLOCK)
+ {
+ acnt = xfer->dt_src.db_stride_width;
+ bcnt = xfer->dt_src.db_length / xfer->dt_src.db_stride_width; //xfer->dt_src.db_nstrides;
+ ccnt = 1;
+ srcbidx = acnt + xfer->dt_src.db_stride_spacing;
+ dstbidx = acnt;
+ srccidx = dstcidx = 0;
+ }
+
+ /* frame-to-frame transfer */
+ if (xfer->dt_src.db_type == GPDMABUF_FRAME && xfer->dt_dst.db_type == GPDMABUF_FRAME)
+ {
+ if (xfer->dt_src.db_stride_width != xfer->dt_dst.db_stride_width)
+ return (EINVAL);
- if (xfer->dt_src.db_type == DMAEBUF_FRAME)
- srcbidx += xfer->dt_src.db_stride_spacing;
+ acnt = xfer->dt_src.db_stride_width;
+ bcnt = xfer->dt_dst.db_length / xfer->dt_dst.db_stride_width; //xfer->dt_src.db_nstrides;
+ ccnt = 1;
+ srcbidx = acnt + xfer->dt_src.db_stride_spacing;
+ dstbidx = acnt + xfer->dt_dst.db_stride_spacing;
+ srccidx = dstcidx = 0;
+ }
- if (xfer->dt_dst.db_type == DMAEBUF_FRAME)
- dstbidx += xfer->dt_dst.db_stride_spacing;
- } else {
- acnt = xfer->dt_dst.db_length;
+ if (bcnt <= 0)
bcnt = 1;
+
+ if (xfer->dt_src.db_flags & GPDMA_BUFFER_FIFO) {
+ ccnt = bcnt;
+ bcnt = acnt / xfer->dt_src.db_fifo_width;
+ acnt = xfer->dt_src.db_fifo_width;
+ srccidx = 0;
srcbidx = 0;
+ dstcidx = acnt * bcnt;
+ dstbidx = acnt;
+ }
+
+ if (xfer->dt_dst.db_flags & GPDMA_BUFFER_FIFO) {
+ ccnt = bcnt;
+ bcnt = acnt / xfer->dt_dst.db_fifo_width;
+ acnt = xfer->dt_dst.db_fifo_width;
+ dstcidx = 0;
dstbidx = 0;
+ srccidx = acnt * bcnt;
+ srcbidx = acnt;
}
+ //if ((xfer->dt_flags & GPDMA_TRANSFER_STRIDE_SYNC) == 0)
+ desc->edma_opt |= DAVINCI_EDMA_OPT_SYNCDIM;
+
/* Set up DMA descriptor */
desc->edma_src = xfer->dt_src.db_addr;
desc->edma_dst = xfer->dt_dst.db_addr;
- desc->edma_opt =
+ desc->edma_opt |=
DAVINCI_EDMA_OPT_TCINTEN |
- /* DAVINCI_EDMA_OPT_ITCINTEN | */
- DAVINCI_EDMA_OPT_SYNCDIM |
(chno << DAVINCI_EDMA_OPT_TCCSHIFT);
desc->edma_abcnt = (bcnt << 16) | acnt;
desc->edma_bidx = (dstbidx << 16) | srcbidx;
- desc->edma_cidx = 0;
- desc->edma_ccnt = 1;
+ desc->edma_cidx = (dstcidx << 16) | srccidx;
+ desc->edma_ccnt = ccnt;
desc->edma_link = (xfer->dt_next != NULL)
- ? ((chno + 64) * sizeof(*desc)) + 0x4000
+ ? DAVINCI_EDMA_PARAM(chno + 64)
: 0xffff;
+ if (xfer->dt_flags & GPDMA_TRANSFER_REPEAT)
+ desc->edma_link = DAVINCI_EDMA_PARAM(chno);
+
return (0);
}
+static void
+davinci_edma_printdesc(struct davinci_edma_softc *sc, int chno)
+{
+ struct davinci_edma_desc *desc = (struct davinci_edma_desc *)
+ (sc->ds_bsh + DAVINCI_EDMA_PARAM(chno));
+
+ printf("src=%08x\tdst=%08x\n", desc->edma_src, desc->edma_dst);
+ printf("acnt=%d\tbcnt=%d\tccnt=%d\n", 0, 0, 0);
+ printf("srcbidx=%d dstbidx=%d srccidx=%d dstcidx=%d\n", 0, 0, 0, 0);
+ printf("link=%08x (set %d) opt=%d\n", 0, 0, 0);
+}
+
static __inline uint64_t
ffs64(uint64_t mask)
{
@@ -595,12 +696,12 @@
DEVMETHOD(device_probe, davinci_edma_probe),
DEVMETHOD(device_attach, davinci_edma_attach),
- /* DMAE methods */
- DEVMETHOD(dmae_setup_channel, davinci_edma_setup_channel),
- DEVMETHOD(dmae_clear_channel, davinci_edma_clear_channel),
- DEVMETHOD(dmae_start_channel, davinci_edma_start_channel),
- DEVMETHOD(dmae_start_channel, davinci_edma_stop_channel),
- DEVMETHOD(dmae_poll_channel, davinci_edma_poll_channel),
+ /* GPDMA methods */
+ DEVMETHOD(gpdma_setup_channel, davinci_edma_setup_channel),
+ DEVMETHOD(gpdma_clear_channel, davinci_edma_clear_channel),
+ DEVMETHOD(gpdma_start_channel, davinci_edma_start_channel),
+ DEVMETHOD(gpdma_start_channel, davinci_edma_stop_channel),
+ DEVMETHOD(gpdma_poll_channel, davinci_edma_poll_channel),
{ 0, 0 }
};
==== //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edmareg.h#5 (text+ko) ====
@@ -74,7 +74,7 @@
#define DAVINCI_EDMACC_CER 0x1018
#define DAVINCI_EDMACC_CERH 0x101C
#define DAVINCI_EDMACC_EER 0x1020
-#define DAVINCI_EDMACC_CEERH 0x1024
+#define DAVINCI_EDMACC_EERH 0x1024
#define DAVINCI_EDMACC_EECR 0x1028
#define DAVINCI_EDMACC_EECRH 0x102C
#define DAVINCI_EDMACC_EESR 0x1030
More information about the p4-projects
mailing list