2012-02-13 05:24:36

by Huang Shijie

[permalink] [raw]
Subject: [PATCH v5 0/2] patch set about the MXS-DMA

patch 1: move the mxs dma header to a more common place.
Beside the mx23/mx28, the apbh-dma is also used by MX50 and MX6Q.
So move the mxs dma header file to a more common place, and rename
it to mxs-dma.h

patch 2: rewrite the last parameter of mxs_dma_prep_slave_sg().
In the new GPMI version, some hardware behavior changes.
The WAIT4END bit should be set in the middle one of the ECC READ page DMA chain.
The DMA chain should be set like this:

+-----+ +-----+ +-----+
| cmd | ------------> | cmd | ------------------> | cmd |
+-----+ +-----+ +-----+
^ ^
| |
| |
set WAIT4END here too set WAIT4END here

So rewrite the last parameter of mxs_dma_prep_slave_sg(), use the
dma_ctrl_flags to set the proper DMA bit for DMA Command Structure.
And change the relative drivers with the dma_ctrl_flags.

TEST:
Tested the mxs-mmc driver and gpmi-nand drive with the two patches
in MX28 board.

v4 --> v5:
[1] remove GPMI_IS_MX6Q(), make the mxs and mx6q use the same code.

v3 --> v4:
[1] create a new folder include/linux/fsl/ for store the Freescale's
header files.
[2] add more CCs.

v2 --> v3:
[1] remove field gpmi_version, use GPMI_IS_MX6Q() instead.

v1 --> v2:
[1] squash the trial patches into single patch.
[2] use the dma_ctrl_flags.


Huang Shijie (2):
mxs-dma : move the mxs dma.h to a more common place
mxs-dma : rewrite the last parameter of mxs_dma_prep_slave_sg()

drivers/dma/mxs-dma.c | 34 +++++++++++++++++---
drivers/mmc/host/mxs-mmc.c | 12 +++---
drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 19 +++++++---
drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 2 +-
.../mach/dma.h => include/linux/fsl/mxs-dma.h | 0
sound/soc/mxs/mxs-pcm.c | 2 +-
sound/soc/mxs/mxs-pcm.h | 2 +-
sound/soc/mxs/mxs-saif.c | 2 +-
8 files changed, 52 insertions(+), 21 deletions(-)
rename arch/arm/mach-mxs/include/mach/dma.h => include/linux/fsl/mxs-dma.h (100%)


2012-02-13 05:24:45

by Huang Shijie

[permalink] [raw]
Subject: [PATCH v5 2/2] mxs-dma : rewrite the last parameter of mxs_dma_prep_slave_sg()

[1] Background :
The GPMI does ECC read page operation with a DMA chain consist of three DMA
Command Structures. The middle one of the chain is used to enable the BCH,
and read out the NAND page.

The WAIT4END(wait for command end) is a comunication signal between
the GPMI and MXS-DMA.

[2] The current DMA code sets the WAIT4END bit at the last one, such as:

+-----+ +-----+ +-----+
| cmd | ------------> | cmd | ------------------> | cmd |
+-----+ +-----+ +-----+
^
|
|
set WAIT4END here

This chain works fine in the mx23/mx28.

[3] But in the new GPMI version (used in MX50/MX60), the WAIT4END bit should
be set not only at the last DMA Command Structure,
but also at the middle one, such as:

+-----+ +-----+ +-----+
| cmd | ------------> | cmd | ------------------> | cmd |
+-----+ +-----+ +-----+
^ ^
| |
| |
set WAIT4END here too set WAIT4END here

If we do not set WAIT4END, the BCH maybe stalls in "ECC reading page" state.
In the next ECC write page operation, a DMA-timeout occurs.
This has been catched in the MX6Q board.

[4] In order to fix the bug, rewrite the last parameter of mxs_dma_prep_slave_sg(),
and use the dma_ctrl_flags:
---------------------------------------------------------
DMA_PREP_INTERRUPT : append a new DMA Command Structrue.
DMA_CTRL_ACK : set the WAIT4END bit for this DMA Command Structure.
---------------------------------------------------------

[5] changes to the relative drivers:
<1> For mxs-mmc driver, just use the new flags, do not change any logic.
<2> For gpmi-nand driver, and use the new flags to set the DMA chain for
ecc read page.

Signed-off-by: Huang Shijie <[email protected]>
---
drivers/dma/mxs-dma.c | 32 ++++++++++++++++++++++++++++----
drivers/mmc/host/mxs-mmc.c | 10 +++++-----
drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 19 +++++++++++++------
3 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 0afcedb..0ddfd30 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -349,10 +349,32 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
clk_disable_unprepare(mxs_dma->clk);
}

+/*
+ * How to use the flags for ->device_prep_slave_sg() :
+ * [1] If there is only one DMA command in the DMA chain, the code should be:
+ * ......
+ * ->device_prep_slave_sg(DMA_CTRL_ACK);
+ * ......
+ * [2] If there are two DMA commands in the DMA chain, the code should be
+ * ......
+ * ->device_prep_slave_sg(0);
+ * ......
+ * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ * ......
+ * [3] If there are more than two DMA commands in the DMA chain, the code
+ * should be:
+ * ......
+ * ->device_prep_slave_sg(0); // First
+ * ......
+ * ->device_prep_slave_sg(DMA_PREP_INTERRUPT [| DMA_CTRL_ACK]);
+ * ......
+ * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK); // Last
+ * ......
+ */
static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
- unsigned long append)
+ unsigned long flags)
{
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -360,6 +382,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
struct scatterlist *sg;
int i, j;
u32 *pio;
+ bool append = flags & DMA_PREP_INTERRUPT;
int idx = append ? mxs_chan->desc_count : 0;

if (mxs_chan->status == DMA_IN_PROGRESS && !append)
@@ -386,7 +409,6 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits |= CCW_CHAIN;
ccw->bits &= ~CCW_IRQ;
ccw->bits &= ~CCW_DEC_SEM;
- ccw->bits &= ~CCW_WAIT4END;
} else {
idx = 0;
}
@@ -401,7 +423,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits = 0;
ccw->bits |= CCW_IRQ;
ccw->bits |= CCW_DEC_SEM;
- ccw->bits |= CCW_WAIT4END;
+ if (flags & DMA_CTRL_ACK)
+ ccw->bits |= CCW_WAIT4END;
ccw->bits |= CCW_HALT_ON_TERM;
ccw->bits |= CCW_TERM_FLUSH;
ccw->bits |= BF_CCW(sg_len, PIO_NUM);
@@ -432,7 +455,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits &= ~CCW_CHAIN;
ccw->bits |= CCW_IRQ;
ccw->bits |= CCW_DEC_SEM;
- ccw->bits |= CCW_WAIT4END;
+ if (flags & DMA_CTRL_ACK)
+ ccw->bits |= CCW_WAIT4END;
}
}
}
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index e5ea2b1..4062812 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -305,7 +305,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
}

static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
- struct mxs_mmc_host *host, unsigned int append)
+ struct mxs_mmc_host *host, unsigned long flags)
{
struct dma_async_tx_descriptor *desc;
struct mmc_data *data = host->data;
@@ -325,7 +325,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
}

desc = host->dmach->device->device_prep_slave_sg(host->dmach,
- sgl, sg_len, host->slave_dirn, append);
+ sgl, sg_len, host->slave_dirn, flags);
if (desc) {
desc->callback = mxs_mmc_dma_irq_callback;
desc->callback_param = host;
@@ -358,7 +358,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
host->ssp_pio_words[2] = cmd1;
host->dma_dir = DMA_NONE;
host->slave_dirn = DMA_TRANS_NONE;
- desc = mxs_mmc_prep_dma(host, 0);
+ desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
if (!desc)
goto out;

@@ -398,7 +398,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
host->ssp_pio_words[2] = cmd1;
host->dma_dir = DMA_NONE;
host->slave_dirn = DMA_TRANS_NONE;
- desc = mxs_mmc_prep_dma(host, 0);
+ desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
if (!desc)
goto out;

@@ -526,7 +526,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
host->data = data;
host->dma_dir = dma_data_dir;
host->slave_dirn = slave_dirn;
- desc = mxs_mmc_prep_dma(host, 1);
+ desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc)
goto out;

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index cbcf022..420ca08 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -850,7 +850,9 @@ int gpmi_send_command(struct gpmi_nand_data *this)
sg_init_one(sgl, this->cmd_buffer, this->command_length);
dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
desc = channel->device->device_prep_slave_sg(channel,
- sgl, 1, DMA_MEM_TO_DEV, 1);
+ sgl, 1, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -892,7 +894,8 @@ int gpmi_send_data(struct gpmi_nand_data *this)
/* [2] send DMA request */
prepare_data_dma(this, DMA_TO_DEVICE);
desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
- 1, DMA_MEM_TO_DEV, 1);
+ 1, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -928,7 +931,8 @@ int gpmi_read_data(struct gpmi_nand_data *this)
/* [2] : send DMA request */
prepare_data_dma(this, DMA_FROM_DEVICE);
desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
- 1, DMA_DEV_TO_MEM, 1);
+ 1, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -975,7 +979,8 @@ int gpmi_send_page(struct gpmi_nand_data *this,

desc = channel->device->device_prep_slave_sg(channel,
(struct scatterlist *)pio,
- ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
+ ARRAY_SIZE(pio), DMA_TRANS_NONE,
+ DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -1039,7 +1044,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
pio[5] = auxiliary;
desc = channel->device->device_prep_slave_sg(channel,
(struct scatterlist *)pio,
- ARRAY_SIZE(pio), DMA_TRANS_NONE, 1);
+ ARRAY_SIZE(pio), DMA_TRANS_NONE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -1059,7 +1065,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
pio[2] = 0; /* Set GPMI_HW_GPMI_ECCCTRL, disable the BCH. */
desc = channel->device->device_prep_slave_sg(channel,
(struct scatterlist *)pio, 3,
- DMA_TRANS_NONE, 1);
+ DMA_TRANS_NONE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 3 error\n");
return -1;
--
1.7.0.4

2012-02-13 05:24:54

by Huang Shijie

[permalink] [raw]
Subject: [PATCH v5 1/2] mxs-dma : move the mxs dma.h to a more common place

Move the header to a more common place.
The mxs dma engine is not only used in mx23/mx28, but also used
in mx50/mx6q. It will also be used in the future chips.

Rename it to mxs-dma.h, and create a new folder include/linux/fsl/ to
store the Freescale's header files.

change mxs-dma driver, mxs-mmc driver, gpmi-nand driver, mxs-saif driver
to the new header file.

Signed-off-by: Huang Shijie <[email protected]>
---
drivers/dma/mxs-dma.c | 2 +-
drivers/mmc/host/mxs-mmc.c | 2 +-
drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 2 +-
.../mach/dma.h => include/linux/fsl/mxs-dma.h | 0
sound/soc/mxs/mxs-pcm.c | 2 +-
sound/soc/mxs/mxs-pcm.h | 2 +-
sound/soc/mxs/mxs-saif.c | 2 +-
7 files changed, 6 insertions(+), 6 deletions(-)
rename arch/arm/mach-mxs/include/mach/dma.h => include/linux/fsl/mxs-dma.h (100%)

diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index b06cd4c..0afcedb 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -22,10 +22,10 @@
#include <linux/platform_device.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
+#include <linux/fsl/mxs-dma.h>

#include <asm/irq.h>
#include <mach/mxs.h>
-#include <mach/dma.h>
#include <mach/common.h>

/*
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 382c835..e5ea2b1 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -38,10 +38,10 @@
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
+#include <linux/fsl/mxs-dma.h>

#include <mach/mxs.h>
#include <mach/common.h>
-#include <mach/dma.h>
#include <mach/mmc.h>

#define DRIVER_NAME "mxs-mmc"
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index c93b0ae..b9002c8 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -20,7 +20,7 @@
#include <linux/mtd/nand.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <mach/dma.h>
+#include <linux/fsl/mxs-dma.h>

struct resources {
void *gpmi_regs;
diff --git a/arch/arm/mach-mxs/include/mach/dma.h b/include/linux/fsl/mxs-dma.h
similarity index 100%
rename from arch/arm/mach-mxs/include/mach/dma.h
rename to include/linux/fsl/mxs-dma.h
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 105f42a..420715e 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -28,6 +28,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
+#include <linux/fsl/mxs-dma.h>

#include <sound/core.h>
#include <sound/initval.h>
@@ -35,7 +36,6 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>

-#include <mach/dma.h>
#include "mxs-pcm.h"

static struct snd_pcm_hardware snd_mxs_hardware = {
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index f55ac4f..d2c8b12 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -19,7 +19,7 @@
#ifndef _MXS_PCM_H
#define _MXS_PCM_H

-#include <mach/dma.h>
+#include <linux/fsl/mxs-dma.h>

struct mxs_pcm_dma_params {
int chan_irq;
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index f204dba..ce59112 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -24,12 +24,12 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/time.h>
+#include <linux/fsl/mxs-dma.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/saif.h>
-#include <mach/dma.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/mxs.h>
--
1.7.0.4

2012-02-13 16:33:28

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v5 1/2] mxs-dma : move the mxs dma.h to a more common place

On Mon, Feb 13, 2012 at 01:25:55PM +0800, Huang Shijie wrote:
> Move the header to a more common place.
> The mxs dma engine is not only used in mx23/mx28, but also used
> in mx50/mx6q. It will also be used in the future chips.

Acked-by: Mark Brown <[email protected]>


Attachments:
(No filename) (289.00 B)
signature.asc (836.00 B)
Digital signature
Download all attachments

2012-02-15 19:56:04

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] mxs-dma : rewrite the last parameter of mxs_dma_prep_slave_sg()

On Mon, Feb 13, 2012 at 01:25:56PM +0800, Huang Shijie wrote:
> [1] Background :
> The GPMI does ECC read page operation with a DMA chain consist of three DMA
> Command Structures. The middle one of the chain is used to enable the BCH,
> and read out the NAND page.
>
> The WAIT4END(wait for command end) is a comunication signal between
> the GPMI and MXS-DMA.
>
> [2] The current DMA code sets the WAIT4END bit at the last one, such as:
>
> +-----+ +-----+ +-----+
> | cmd | ------------> | cmd | ------------------> | cmd |
> +-----+ +-----+ +-----+
> ^
> |
> |
> set WAIT4END here
>
> This chain works fine in the mx23/mx28.
>
> [3] But in the new GPMI version (used in MX50/MX60), the WAIT4END bit should
> be set not only at the last DMA Command Structure,
> but also at the middle one, such as:
>
> +-----+ +-----+ +-----+
> | cmd | ------------> | cmd | ------------------> | cmd |
> +-----+ +-----+ +-----+
> ^ ^
> | |
> | |
> set WAIT4END here too set WAIT4END here
>
> If we do not set WAIT4END, the BCH maybe stalls in "ECC reading page" state.
> In the next ECC write page operation, a DMA-timeout occurs.
> This has been catched in the MX6Q board.
>
> [4] In order to fix the bug, rewrite the last parameter of mxs_dma_prep_slave_sg(),
> and use the dma_ctrl_flags:
> ---------------------------------------------------------
> DMA_PREP_INTERRUPT : append a new DMA Command Structrue.
> DMA_CTRL_ACK : set the WAIT4END bit for this DMA Command Structure.
> ---------------------------------------------------------
>
> [5] changes to the relative drivers:
> <1> For mxs-mmc driver, just use the new flags, do not change any logic.
> <2> For gpmi-nand driver, and use the new flags to set the DMA chain for
> ecc read page.
>
> Signed-off-by: Huang Shijie <[email protected]>
> ---
> drivers/dma/mxs-dma.c | 32 ++++++++++++++++++++++++++++----
> drivers/mmc/host/mxs-mmc.c | 10 +++++-----
> drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 19 +++++++++++++------
> 3 files changed, 46 insertions(+), 15 deletions(-)
>
I'm trying to give it a test. But it does not apply on either mainline
or next tree. You probably had a wrong base for this patch.

> diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
> index 0afcedb..0ddfd30 100644
> --- a/drivers/dma/mxs-dma.c
> +++ b/drivers/dma/mxs-dma.c
> @@ -349,10 +349,32 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
> clk_disable_unprepare(mxs_dma->clk);
> }
>
> +/*
> + * How to use the flags for ->device_prep_slave_sg() :
> + * [1] If there is only one DMA command in the DMA chain, the code should be:
> + * ......
> + * ->device_prep_slave_sg(DMA_CTRL_ACK);
> + * ......
> + * [2] If there are two DMA commands in the DMA chain, the code should be
> + * ......
> + * ->device_prep_slave_sg(0);
> + * ......
> + * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> + * ......
> + * [3] If there are more than two DMA commands in the DMA chain, the code
> + * should be:
> + * ......
> + * ->device_prep_slave_sg(0); // First
> + * ......
> + * ->device_prep_slave_sg(DMA_PREP_INTERRUPT [| DMA_CTRL_ACK]);
> + * ......
> + * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK); // Last
> + * ......
> + */
> static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
> struct dma_chan *chan, struct scatterlist *sgl,
> unsigned int sg_len, enum dma_transfer_direction direction,
> - unsigned long append)
> + unsigned long flags)
> {
> struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
> struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
> @@ -360,6 +382,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
> struct scatterlist *sg;
> int i, j;
> u32 *pio;
> + bool append = flags & DMA_PREP_INTERRUPT;
> int idx = append ? mxs_chan->desc_count : 0;
>
> if (mxs_chan->status == DMA_IN_PROGRESS && !append)
> @@ -386,7 +409,6 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
> ccw->bits |= CCW_CHAIN;
> ccw->bits &= ~CCW_IRQ;
> ccw->bits &= ~CCW_DEC_SEM;
> - ccw->bits &= ~CCW_WAIT4END;
> } else {
> idx = 0;
> }
> @@ -401,7 +423,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
> ccw->bits = 0;
> ccw->bits |= CCW_IRQ;
> ccw->bits |= CCW_DEC_SEM;
> - ccw->bits |= CCW_WAIT4END;
> + if (flags & DMA_CTRL_ACK)
> + ccw->bits |= CCW_WAIT4END;
> ccw->bits |= CCW_HALT_ON_TERM;
> ccw->bits |= CCW_TERM_FLUSH;
> ccw->bits |= BF_CCW(sg_len, PIO_NUM);
> @@ -432,7 +455,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
> ccw->bits &= ~CCW_CHAIN;
> ccw->bits |= CCW_IRQ;
> ccw->bits |= CCW_DEC_SEM;
> - ccw->bits |= CCW_WAIT4END;
> + if (flags & DMA_CTRL_ACK)
> + ccw->bits |= CCW_WAIT4END;
> }
> }
> }
> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index e5ea2b1..4062812 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -305,7 +305,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
> }
>
> static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
> - struct mxs_mmc_host *host, unsigned int append)
> + struct mxs_mmc_host *host, unsigned long flags)
> {
> struct dma_async_tx_descriptor *desc;
> struct mmc_data *data = host->data;
> @@ -325,7 +325,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
> }
>
> desc = host->dmach->device->device_prep_slave_sg(host->dmach,
> - sgl, sg_len, host->slave_dirn, append);
> + sgl, sg_len, host->slave_dirn, flags);
> if (desc) {
> desc->callback = mxs_mmc_dma_irq_callback;
> desc->callback_param = host;
> @@ -358,7 +358,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
> host->ssp_pio_words[2] = cmd1;
> host->dma_dir = DMA_NONE;
> host->slave_dirn = DMA_TRANS_NONE;
> - desc = mxs_mmc_prep_dma(host, 0);
> + desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
> if (!desc)
> goto out;
>
> @@ -398,7 +398,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
> host->ssp_pio_words[2] = cmd1;
> host->dma_dir = DMA_NONE;
> host->slave_dirn = DMA_TRANS_NONE;
> - desc = mxs_mmc_prep_dma(host, 0);
> + desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
> if (!desc)
> goto out;
>
> @@ -526,7 +526,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
> host->data = data;
> host->dma_dir = dma_data_dir;
> host->slave_dirn = slave_dirn;
> - desc = mxs_mmc_prep_dma(host, 1);
> + desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> if (!desc)
> goto out;
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> index cbcf022..420ca08 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> @@ -850,7 +850,9 @@ int gpmi_send_command(struct gpmi_nand_data *this)
> sg_init_one(sgl, this->cmd_buffer, this->command_length);
> dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
> desc = channel->device->device_prep_slave_sg(channel,
> - sgl, 1, DMA_MEM_TO_DEV, 1);
> + sgl, 1, DMA_MEM_TO_DEV,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +
> if (!desc) {
> pr_err("step 2 error\n");
> return -1;
> @@ -892,7 +894,8 @@ int gpmi_send_data(struct gpmi_nand_data *this)
> /* [2] send DMA request */
> prepare_data_dma(this, DMA_TO_DEVICE);
> desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
> - 1, DMA_MEM_TO_DEV, 1);
> + 1, DMA_MEM_TO_DEV,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> if (!desc) {
> pr_err("step 2 error\n");
> return -1;
> @@ -928,7 +931,8 @@ int gpmi_read_data(struct gpmi_nand_data *this)
> /* [2] : send DMA request */
> prepare_data_dma(this, DMA_FROM_DEVICE);
> desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
> - 1, DMA_DEV_TO_MEM, 1);
> + 1, DMA_DEV_TO_MEM,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> if (!desc) {
> pr_err("step 2 error\n");
> return -1;
> @@ -975,7 +979,8 @@ int gpmi_send_page(struct gpmi_nand_data *this,
>
> desc = channel->device->device_prep_slave_sg(channel,
> (struct scatterlist *)pio,
> - ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
> + ARRAY_SIZE(pio), DMA_TRANS_NONE,
> + DMA_CTRL_ACK);
> if (!desc) {
> pr_err("step 2 error\n");
> return -1;
> @@ -1039,7 +1044,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
> pio[5] = auxiliary;
> desc = channel->device->device_prep_slave_sg(channel,
> (struct scatterlist *)pio,
> - ARRAY_SIZE(pio), DMA_TRANS_NONE, 1);
> + ARRAY_SIZE(pio), DMA_TRANS_NONE,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> if (!desc) {
> pr_err("step 2 error\n");
> return -1;
> @@ -1059,7 +1065,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
> pio[2] = 0; /* Set GPMI_HW_GPMI_ECCCTRL, disable the BCH. */
> desc = channel->device->device_prep_slave_sg(channel,
> (struct scatterlist *)pio, 3,

I have the mainline code show above line as

(struct scatterlist *)pio, 2,

That's why I think you got a wrong base. But I tested it with manually
applying it. So other than the base issue,

Acked-by: Shawn Guo <[email protected]>

Regards,
Shawn

> - DMA_TRANS_NONE, 1);
> + DMA_TRANS_NONE,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> if (!desc) {
> pr_err("step 3 error\n");
> return -1;
> --
> 1.7.0.4
>
>

2012-02-15 19:56:37

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH v5 1/2] mxs-dma : move the mxs dma.h to a more common place

On Mon, Feb 13, 2012 at 01:25:55PM +0800, Huang Shijie wrote:
> Move the header to a more common place.
> The mxs dma engine is not only used in mx23/mx28, but also used
> in mx50/mx6q. It will also be used in the future chips.
>
> Rename it to mxs-dma.h, and create a new folder include/linux/fsl/ to
> store the Freescale's header files.
>
> change mxs-dma driver, mxs-mmc driver, gpmi-nand driver, mxs-saif driver
> to the new header file.
>
> Signed-off-by: Huang Shijie <[email protected]>

Acked-by: Shawn Guo <[email protected]>

2012-02-16 02:03:45

by Huang Shijie

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] mxs-dma : rewrite the last parameter of mxs_dma_prep_slave_sg()

Hi Shawn:
> I'm trying to give it a test. But it does not apply on either mainline
> or next tree. You probably had a wrong base for this patch.
>
thanks for your work.

As the previous email said, this patch set bases on :[PATCH v2] mtd/gpmi
: add gpmi support for mx6q.

BR
Huang Shijie

2012-02-16 02:12:32

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] mxs-dma : rewrite the last parameter of mxs_dma_prep_slave_sg()

On Thu, Feb 16, 2012 at 10:05:26AM +0800, Huang Shijie wrote:
> Hi Shawn:
> >I'm trying to give it a test. But it does not apply on either mainline
> >or next tree. You probably had a wrong base for this patch.
> >
> thanks for your work.
>
> As the previous email said, this patch set bases on :[PATCH v2]
> mtd/gpmi : add gpmi support for mx6q.
>
Then you are doing something wrong. This series should be based on
mainline, and then you add imx6q support on top of this series.

--
Regards,
Shawn

2012-02-16 02:25:46

by Huang Shijie

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] mxs-dma : rewrite the last parameter of mxs_dma_prep_slave_sg()

Hi,
>> Hi Shawn:
>>> I'm trying to give it a test. But it does not apply on either mainline
>>> or next tree. You probably had a wrong base for this patch.
>>>
>> thanks for your work.
>>
>> As the previous email said, this patch set bases on :[PATCH v2]
>> mtd/gpmi : add gpmi support for mx6q.
>>
> Then you are doing something wrong. This series should be based on
> mainline, and then you add imx6q support on top of this series.
sorry for the inconvenience.
I send the two patches at the same time.

The mtd/gpmi patch is just a small patch, I think it will be merged
before this patch set.

BR
Huang Shijie