diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-03-21 12:07:11 +0100 |
---|---|---|
committer | Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com> | 2011-03-23 13:34:42 +0100 |
commit | ef8f5593a666639a7448564374f8fc51d5d82a1f (patch) | |
tree | 572cfaca025737141bcc18090bf8b8087d46bbe2 /drivers/mmc | |
parent | e4ff84354661f9b6f9585141b108d141fd41392a (diff) |
MMCI: DMA support for SDIO
When the data size is less than fifosize the DMA job will
not be setup and then we fallback to pio mode. Move setup of
SDIO specific things to be done before the DMA might be setup.
Change-Id: I8daab38afe8e77a1416293cb34bbdbffd42b80c9
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18730
Reviewed-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmci.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f06f708dace..25dc5df1ca7 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -444,6 +444,10 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) unsigned int irqmask0; int sg_len; + /* If less than or equal to the fifo size, don't bother with DMA */ + if (host->size <= variant->fifosize) + return -EINVAL; + datactrl |= MCI_DPSM_DMAENABLE; datactrl |= variant->dmareg_enable; @@ -607,6 +611,38 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) writel(clk, (base + MMCICLOCK)); } + if (variant->sdio && + host->mmc->card && + mmc_card_sdio(host->mmc->card)) { + /* + * The ST Micro variants has a special bit + * to enable SDIO mode. This bit is set the first time + * a SDIO data transfer is done and must remain set + * after the data transfer is completed. The reason is + * because of otherwise no SDIO interrupts can be + * received. + */ + datactrl |= MCI_ST_DPSM_SDIOEN; + + /* + * The ST Micro variant for SDIO transfer sizes + * less than or equal to 8 bytes needs to have clock + * H/W flow control disabled. Since flow control is + * not really needed for anything that fits in the + * FIFO, we can disable it for any write smaller + * than the FIFO size. + */ + if ((host->size <= variant->fifosize) && + (data->flags & MMC_DATA_WRITE)) + writel(readl(host->base + MMCICLOCK) & + ~variant->clkreg_enable, + host->base + MMCICLOCK); + else + writel(readl(host->base + MMCICLOCK) | + variant->clkreg_enable, + host->base + MMCICLOCK); + } + if (host->dma_enable) { int ret; @@ -640,37 +676,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) irqmask1 = MCI_TXFIFOHALFEMPTYMASK; } - if (variant->sdio && host->mmc->card) - if (mmc_card_sdio(host->mmc->card)) { - /* - * The ST Micro variants has a special bit - * to enable SDIO mode. This bit is set the first time - * a SDIO data transfer is done and must remain set - * after the data transfer is completed. The reason is - * because of otherwise no SDIO interrupts can be - * received. - */ - datactrl |= MCI_ST_DPSM_SDIOEN; - - /* - * The ST Micro variant for SDIO transfer sizes - * less then or equal to 8 bytes needs to have clock - * H/W flow control disabled. Since flow control is - * not really needed for anything that fits in the - * FIFO, we can disable it for any write smaller - * than the FIFO size. - */ - if ((host->size <= variant->fifosize) && - (data->flags & MMC_DATA_WRITE)) - writel(readl(host->base + MMCICLOCK) & - ~variant->clkreg_enable, - host->base + MMCICLOCK); - else - writel(readl(host->base + MMCICLOCK) | - variant->clkreg_enable, - host->base + MMCICLOCK); - } - /* Setup IRQ */ irqmask0 = readl(base + MMCIMASK0); if (variant->broken_blockend) { |