Please read more comment in the mxs-dma.h. In the new GPMI version(0x05010000 used by MX6Q/MX50), we should set the WAIT4END bit in the middle one of this chain, which enables the BCH module and reads out the NAND page. If we do not do this, a DMA timeout occurs. This bug has been catched in the MX6Q board. We have changed the DMA interface to fix the bug, now use the new interface. Signed-off-by: Huang Shijie <b32955@xxxxxxxxxxxxx> --- drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 5b73ae5..84abd49 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -842,7 +842,7 @@ 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, MXS_DMA_F_LASTONE); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -884,7 +884,7 @@ 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, MXS_DMA_F_LASTONE); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -920,7 +920,7 @@ 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, MXS_DMA_F_LASTONE); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -967,7 +967,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, + MXS_DMA_F_WAIT4END); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -987,6 +988,7 @@ int gpmi_read_page(struct gpmi_nand_data *this, struct dma_async_tx_descriptor *desc; struct dma_chan *channel = get_dma_chan(this); int chip = this->current_chip; + unsigned long flags; u32 pio[6]; /* [1] Wait for the chip to report ready. */ @@ -1029,9 +1031,14 @@ int gpmi_read_page(struct gpmi_nand_data *this, pio[3] = geo->page_size; pio[4] = payload; pio[5] = auxiliary; + + /* If the GPMI is new version, set MXS_DMA_F_WAIT4END here. */ + flags = MXS_DMA_F_APPEND; + if (this->gpmi_version == GPMI_VERSION_0501) + flags |= MXS_DMA_F_WAIT4END; desc = channel->device->device_prep_slave_sg(channel, (struct scatterlist *)pio, - ARRAY_SIZE(pio), DMA_TRANS_NONE, 1); + ARRAY_SIZE(pio), DMA_TRANS_NONE, flags); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -1048,9 +1055,10 @@ int gpmi_read_page(struct gpmi_nand_data *this, | BF_GPMI_CTRL0_ADDRESS(address) | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size); pio[1] = 0; + pio[2] = 0; desc = channel->device->device_prep_slave_sg(channel, (struct scatterlist *)pio, 2, - DMA_TRANS_NONE, 1); + DMA_TRANS_NONE, MXS_DMA_F_LASTONE); if (!desc) { pr_err("step 3 error\n"); return -1; -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html