diff options
author | Jayeeta Banerjee <jayeeta.banerjee@stericsson.com> | 2010-06-23 16:18:36 +0530 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2010-09-02 22:45:48 -0600 |
commit | 71a14cad06ffcec597c99c9fbfb1a1e7d44fe7df (patch) | |
tree | 95a9963a39d0b2190e083bf8968d49d6e2195215 /drivers/mmc | |
parent | 307783b375d2f14e8e43dcb3e8b69cbc54552a47 (diff) |
SDIO: Fix for non word-aligned address for SDIO host in DMA mode
For SDIO host in DMA mode, when memory address is not aligned
to DMA element size, switch to polling mode for that transfer.
ST-Ericsson Id:ER 264340
Signed-off-by: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/1922
Reviewed-by: Jayeeta BANDYOPADHYAY <jayeeta.banerjee@stericsson.com>
Tested-by: Jayeeta BANDYOPADHYAY <jayeeta.banerjee@stericsson.com>
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Change-Id: I9fa83f070f11a272c2a8cce299bfe81b769edf8b
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/2638
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmc-u8500.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/mmc/host/mmc-u8500.c b/drivers/mmc/host/mmc-u8500.c index 9316c6d3224..dc8617ceeb5 100644 --- a/drivers/mmc/host/mmc-u8500.c +++ b/drivers/mmc/host/mmc-u8500.c @@ -137,6 +137,10 @@ static void u8500_mmci_cmd_irq(struct u8500_mmci_host *host, static struct u8500_mmci_host *sdio_host_ptr; #define CARD_DETECT_DELAY_MSEC (10) +/* For SDIO host DMA mode, min data transfer size in bytes */ +#define MIN_DATA_SIZE_DMA 32 +/* DMA element size in bytes */ +#define DMA_ELEMENT_SZ 4 /** * u8500_sdio_detect_card() - Initiates card scan for sdio host * @@ -1148,6 +1152,7 @@ static void u8500_mmci_start_data(struct u8500_mmci_host *host, u32 temp_reg; u32 polling_freq_clk_div = 0x0; unsigned long flag_lock = 0; + unsigned int mem_addr; spin_lock_irqsave(&host->lock, flag_lock); host->data = data; @@ -1162,13 +1167,21 @@ static void u8500_mmci_start_data(struct u8500_mmci_host *host, /** * Required for SDIO DMA mode, dynamic switching between polling - * and DMA mode, depending on transfer size + * and DMA mode, depending on transfer size, and address alignment. + * For transfer size < 32 and for element size unaligned address + * SDIO host is configured in polling mode. */ - if ((host->cmd->opcode == SD_IO_RW_EXTENDED) && (sdio_mode == MCI_DMAMODE)) { - if (host->size >= 32) - host->devicemode = MCI_DMAMODE; - else + if ((host->cmd->opcode == SD_IO_RW_EXTENDED) && + (sdio_mode == MCI_DMAMODE)) { + mem_addr = (unsigned int)(page_address(sg_page(host->sg_ptr)) + + host->sg_ptr->offset) + host->sg_off; + + if ((mem_addr % DMA_ELEMENT_SZ) || + (host->size < MIN_DATA_SIZE_DMA)) host->devicemode = MCI_POLLINGMODE; + else + host->devicemode = MCI_DMAMODE; + } #ifdef SDIO_MULTIBYTE_WORKAROUND /** |