No subject
Fri Oct 1 10:42:22 EDT 2010
Hottinger Baldwin Messtechnik GmbH, Im Tiefen See 45, 64293 Darmstadt, =
Germany | www.hbm.com=20
Registered as GmbH (German limited liability corporation) in the =
commercial register at the local court of Darmstadt, HRB 1147 =20
Company domiciled in Darmstadt | CEO: Andreas Huellhorst | Chairman of =
the board: James Charles Webster
Als Gesellschaft mit beschraenkter Haftung eingetragen im =
Handelsregister des Amtsgerichts Darmstadt unter HRB 1147=20
Sitz der Gesellschaft: Darmstadt | Geschaeftsfuehrung: Andreas =
Huellhorst | Aufsichtsratsvorsitzender: James Charles Webster
The information in this email is confidential. It is intended solely for =
the addressee. If you are not the intended recipient, please let me know =
and delete this email.
Die in dieser E-Mail enthaltene Information ist vertraulich und =
lediglich fur den Empfaenger bestimmt. Sollten Sie nicht der eigentliche =
Empfaenger sein, informieren Sie mich bitte kurz und loeschen diese =
E-Mail.
From: Tobias Wirtl <wirtl at H-27099-0.(none)>
Date: Thu, 16 Sep 2010 16:04:23 +0200
Subject: [PATCH 1/3] added support for memory to memory transfers using
the async-tx-api
see sdma_prep_dma_memcpy function
---
drivers/dma/imx-sdma.c | 61
++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index be61803..1091047 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -4,7 +4,8 @@
* This file contains a driver for the Freescale Smart DMA engine
*
* Copyright 2010 Sascha Hauer, Pengutronix <s.hauer at pengutronix.de>
- *
+ * Copyright 2010 Tobias Wirtl, HBM <tobias.wirtl at hbm.com>
+ *=20
* Based on code from Freescale:
*
* Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights
Reserved.
@@ -643,8 +644,13 @@ static void sdma_get_pc(struct sdma_channel *sdma,
break;
}
=20
- sdma->pc_from_device =3D per_2_emi;
- sdma->pc_to_device =3D emi_2_per;
+ if (peripheral_type =3D=3D IMX_DMATYPE_MEMORY){
+ sdma->pc_from_device =3D emi_2_emi;
+ sdma->pc_to_device =3D emi_2_emi;
+ } else {
+ sdma->pc_from_device =3D per_2_emi;
+ sdma->pc_to_device =3D emi_2_per;
+ }
}
=20
static int sdma_load_context(int channel)
@@ -1015,6 +1021,51 @@ static void sdma_free_chan_resources(struct
dma_chan *chan)
clk_disable(sdma_clk);
}
=20
+static struct dma_async_tx_descriptor *sdma_prep_dma_memcpy(
+ struct dma_chan *chan,=20
+ dma_addr_t dest, dma_addr_t src,
+ size_t len, unsigned long flags)
+{
+ struct sdma_channel *sdma =3D to_sdma_chan(chan);
+ struct sdma_buffer_descriptor *bd;
+ int ret;
+ int chan_id =3D chan->chan_id;
+=09
+ pr_debug("SDMA: preparing memcpy src: 0x%08x dst: 0x%08x len: %i
on channel %i\n",src,dest,len,chan->chan_id);
+
+ sdma_config_channel(chan_id);
+=09
+ if (sdma->busy)
+ return NULL;
+ sdma->busy =3D 1;
+ sdma->flags =3D 0;
+=09
+ sdma->direction =3D DMA_FROM_DEVICE; //doesn't matter
+=09
+ ret =3D sdma_load_context(chan_id);
+ if (ret)
+ {
+ pr_debug("SDMA: can't load channel context for channel
%i\n",chan_id);
+ goto err_out;
+ }
+ bd =3D &sdma->bd[0];
+=09
+ bd->buffer_addr =3D src;
+ bd->ext_buffer_addr =3D dest;
+ bd->mode.count =3D len;
+ bd->mode.command =3D 0;
+ bd->mode.status =3D BD_DONE | BD_EXTD | BD_CONT | BD_INTR;
+
+ sdma->num_bd =3D 1;
+
+ channel_control[chan_id].current_bd_ptr =3D sdma->bd_phys;
+
+ return &sdma->desc;
+err_out:
+ return NULL;
+=09
+}
+
#define NUM_BD (int)(PAGE_SIZE / sizeof(struct sdma_buffer_descriptor))
=20
static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
@@ -1051,9 +1102,7 @@ static struct dma_async_tx_descriptor
*sdma_prep_slave_sg(
for_each_sg(sgl, sg, sg_len, i) {
struct sdma_buffer_descriptor *bd =3D &sdma->bd[i];
int param;
-
bd->buffer_addr =3D sgl->dma_address;
-
count =3D sg->length;
=20
if (count > 0xffff) {
@@ -1312,6 +1361,7 @@ static int __devinit sdma_probe(struct
platform_device *pdev)
=20
dma_cap_set(DMA_SLAVE, sdma_dma_device->cap_mask);
dma_cap_set(DMA_CYCLIC, sdma_dma_device->cap_mask);
+ dma_cap_set(DMA_MEMCPY, sdma_dma_device->cap_mask);
=20
sdma->chan.device =3D sdma_dma_device;
sdma->chan.chan_id =3D i;
@@ -1325,6 +1375,7 @@ static int __devinit sdma_probe(struct
platform_device *pdev)
sdma_dma_device->device_alloc_chan_resources =3D
sdma_alloc_chan_resources;
sdma_dma_device->device_free_chan_resources =3D
sdma_free_chan_resources;
sdma_dma_device->device_tx_status =3D sdma_tx_status;
+ sdma_dma_device->device_prep_dma_memcpy =3D sdma_prep_dma_memcpy;
sdma_dma_device->device_prep_slave_sg =3D sdma_prep_slave_sg;
sdma_dma_device->device_prep_dma_cyclic =3D sdma_prep_dma_cyclic;
sdma_dma_device->device_control =3D sdma_control;
--=20
1.7.0.4
More information about the linux-arm-kernel
mailing list