LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* dmaengine: i.MX SDMA fixes
@ 2011-01-31 11:59 Sascha Hauer
  2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Dan Williams, linux-kernel

The following contains fixes for the i.MX SDMA driver.

Sascha

The following changes since commit 1bae4ce27c9c90344f23c65ea6966c50ffeae2f5:

  Linux 2.6.38-rc2 (2011-01-21 19:01:34 -0800)

are available in the git repository at:
  git://git.pengutronix.de/git/imx/linux-2.6 dmaengine-sdma

Sascha Hauer (5):
      dmaengine i.MX sdma: set maximum segment size for our device
      dmaengine i.MX sdma: check sg entries for valid addresses and lengths
      dmaengine i.MX SDMA: do not initialize chan_id field
      dmaengine i.MX SDMA: initialize dma capabilities outside channel loop
      dmaengine i.MX SDMA: reserve channel 0 by not registering it

 drivers/dma/imx-sdma.c |   60 ++++++++++++++++++++++++++++--------------------
 1 files changed, 35 insertions(+), 25 deletions(-)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device
  2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer
@ 2011-01-31 11:59 ` Sascha Hauer
  2011-01-31 11:59 ` [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths Sascha Hauer
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Dan Williams, linux-kernel, Sascha Hauer

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d5a5d4d..c503050 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -301,6 +301,7 @@ struct sdma_firmware_header {
 
 struct sdma_engine {
 	struct device			*dev;
+	struct device_dma_parameters	dma_parms;
 	struct sdma_channel		channel[MAX_DMA_CHANNELS];
 	struct sdma_channel_control	*channel_control;
 	void __iomem			*regs;
@@ -1317,6 +1318,8 @@ static int __init sdma_probe(struct platform_device *pdev)
 	sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
 	sdma->dma_device.device_control = sdma_control;
 	sdma->dma_device.device_issue_pending = sdma_issue_pending;
+	sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
+	dma_set_max_seg_size(sdma->dma_device.dev, 65535);
 
 	ret = dma_async_device_register(&sdma->dma_device);
 	if (ret) {
-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths
  2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer
  2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer
@ 2011-01-31 11:59 ` Sascha Hauer
  2011-01-31 11:59 ` [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field Sascha Hauer
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Dan Williams, linux-kernel, Sascha Hauer

This patch lets sdma_prep_slave_sg fail if the entries of an
sg list do not start on multiples of the word size or if the
lengths are not multiple of the word size.
Also, catch the previously unhandled DMA_SLAVE_BUSWIDTH_8_BYTES
and DMA_SLAVE_BUSWIDTH_UNDEFINED cases.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |   20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index c503050..8707723 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -925,10 +925,24 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 			ret =  -EINVAL;
 			goto err_out;
 		}
-		if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES)
+
+		switch (sdmac->word_size) {
+		case DMA_SLAVE_BUSWIDTH_4_BYTES:
 			bd->mode.command = 0;
-		else
-			bd->mode.command = sdmac->word_size;
+			if (count & 3 || sg->dma_address & 3)
+				return NULL;
+			break;
+		case DMA_SLAVE_BUSWIDTH_2_BYTES:
+			bd->mode.command = 2;
+			if (count & 1 || sg->dma_address & 1)
+				return NULL;
+			break;
+		case DMA_SLAVE_BUSWIDTH_1_BYTE:
+			bd->mode.command = 1;
+			break;
+		default:
+			return NULL;
+		}
 
 		param = BD_DONE | BD_EXTD | BD_CONT;
 
-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field
  2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer
  2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer
  2011-01-31 11:59 ` [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths Sascha Hauer
@ 2011-01-31 11:59 ` Sascha Hauer
  2011-01-31 11:59 ` [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop Sascha Hauer
  2011-01-31 11:59 ` [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it Sascha Hauer
  4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Dan Williams, linux-kernel, Sascha Hauer

This is bogus as the dmaengine core will overwrite this field.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 8707723..3e848ee 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1307,7 +1307,6 @@ static int __init sdma_probe(struct platform_device *pdev)
 		dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
 
 		sdmac->chan.device = &sdma->dma_device;
-		sdmac->chan.chan_id = i;
 		sdmac->channel = i;
 
 		/* Add the channel to the DMAC list */
-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop
  2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer
                   ` (2 preceding siblings ...)
  2011-01-31 11:59 ` [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field Sascha Hauer
@ 2011-01-31 11:59 ` Sascha Hauer
  2011-01-31 11:59 ` [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it Sascha Hauer
  4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Dan Williams, linux-kernel, Sascha Hauer

The capabilities are device specific fields, not channel specific fields.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 3e848ee..eb25068 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1295,6 +1295,9 @@ static int __init sdma_probe(struct platform_device *pdev)
 
 	sdma->version = pdata->sdma_version;
 
+	dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
+	dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
+
 	INIT_LIST_HEAD(&sdma->dma_device.channels);
 	/* Initialize channel parameters */
 	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
@@ -1303,9 +1306,6 @@ static int __init sdma_probe(struct platform_device *pdev)
 		sdmac->sdma = sdma;
 		spin_lock_init(&sdmac->lock);
 
-		dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
-		dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
-
 		sdmac->chan.device = &sdma->dma_device;
 		sdmac->channel = i;
 
-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it
  2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer
                   ` (3 preceding siblings ...)
  2011-01-31 11:59 ` [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop Sascha Hauer
@ 2011-01-31 11:59 ` Sascha Hauer
  4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Dan Williams, linux-kernel, Sascha Hauer

We need channel 0 of the sdma engine for internal purposes. We
accomplished this by calling dma_request_channel() in the probe
function. This does not work when multiple dma engines are
present which is the case when IPU support for i.MX31/35 is
compiled in. So instead of registering channel 0 and reserving
it afterwards simply do not register it in the first place.
With this the dmaengine channel counting does not match sdma
channel counting anymore, so we have to use sdma channel counting
in the driver.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |   30 ++++++++++++------------------
 1 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index eb25068..1eb3f00 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -230,7 +230,7 @@ struct sdma_engine;
  * struct sdma_channel - housekeeping for a SDMA channel
  *
  * @sdma		pointer to the SDMA engine for this channel
- * @channel		the channel number, matches dmaengine chan_id
+ * @channel		the channel number, matches dmaengine chan_id + 1
  * @direction		transfer type. Needed for setting SDMA script
  * @peripheral_type	Peripheral type. Needed for setting SDMA script
  * @event_id0		aka dma request line
@@ -799,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	cookie = sdma_assign_cookie(sdmac);
 
-	sdma_enable_channel(sdma, tx->chan->chan_id);
+	sdma_enable_channel(sdma, sdmac->channel);
 
 	spin_unlock_irq(&sdmac->lock);
 
@@ -812,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
 	struct imx_dma_data *data = chan->private;
 	int prio, ret;
 
-	/* No need to execute this for internal channel 0 */
-	if (chan->chan_id == 0)
-		return 0;
-
 	if (!data)
 		return -EINVAL;
 
@@ -880,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
 	struct sdma_engine *sdma = sdmac->sdma;
 	int ret, i, count;
-	int channel = chan->chan_id;
+	int channel = sdmac->channel;
 	struct scatterlist *sg;
 
 	if (sdmac->status == DMA_IN_PROGRESS)
@@ -978,7 +974,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
 	struct sdma_engine *sdma = sdmac->sdma;
 	int num_periods = buf_len / period_len;
-	int channel = chan->chan_id;
+	int channel = sdmac->channel;
 	int ret, i = 0, buf = 0;
 
 	dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
@@ -1252,7 +1248,6 @@ static int __init sdma_probe(struct platform_device *pdev)
 	struct resource *iores;
 	struct sdma_platform_data *pdata = pdev->dev.platform_data;
 	int i;
-	dma_cap_mask_t mask;
 	struct sdma_engine *sdma;
 
 	sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
@@ -1309,8 +1304,14 @@ static int __init sdma_probe(struct platform_device *pdev)
 		sdmac->chan.device = &sdma->dma_device;
 		sdmac->channel = i;
 
-		/* Add the channel to the DMAC list */
-		list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels);
+		/*
+		 * Add the channel to the DMAC list. Do not add channel 0 though
+		 * because we need it internally in the SDMA driver. This also means
+		 * that channel 0 in dmaengine counting matches sdma channel 1.
+		 */
+		if (i)
+			list_add_tail(&sdmac->chan.device_node,
+					&sdma->dma_device.channels);
 	}
 
 	ret = sdma_init(sdma);
@@ -1340,13 +1341,6 @@ static int __init sdma_probe(struct platform_device *pdev)
 		goto err_init;
 	}
 
-	/* request channel 0. This is an internal control channel
-	 * to the SDMA engine and not available to clients.
-	 */
-	dma_cap_zero(mask);
-	dma_cap_set(DMA_SLAVE, mask);
-	dma_request_channel(mask, NULL, NULL);
-
 	dev_info(sdma->dev, "initialized\n");
 
 	return 0;
-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-01-31 12:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer
2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer
2011-01-31 11:59 ` [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths Sascha Hauer
2011-01-31 11:59 ` [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field Sascha Hauer
2011-01-31 11:59 ` [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop Sascha Hauer
2011-01-31 11:59 ` [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).