aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@stericsson.com>2011-03-21 12:07:11 +0100
committerSebastian RASMUSSEN <sebastian.rasmussen@stericsson.com>2011-03-23 13:34:42 +0100
commitef8f5593a666639a7448564374f8fc51d5d82a1f (patch)
tree572cfaca025737141bcc18090bf8b8087d46bbe2 /drivers/mmc
parente4ff84354661f9b6f9585141b108d141fd41392a (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.c67
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) {