summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-07-02 16:51:35 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-07-02 16:51:35 +0100
commitbab7696184bbf0ea48d56902bd1f9ac983079ad2 (patch)
treef8b90b4c561858c47624307df4d1e67498f23df2 /drivers/mmc
parenta406f5a3b68ee1db2306a2ba1c9b00dbd3505d05 (diff)
downloadlinux-3.10-bab7696184bbf0ea48d56902bd1f9ac983079ad2.tar.gz
linux-3.10-bab7696184bbf0ea48d56902bd1f9ac983079ad2.tar.bz2
linux-3.10-bab7696184bbf0ea48d56902bd1f9ac983079ad2.zip
[MMC] sdhci: Avoid sdhci DMA boundaries
The sdhci controllers will issue an interrupt when a configurable number of bytes have been transfered using DMA. The purpose is to handle multiple, scattered memory pages. Unfortunately, it requires that all transfers are completely aligned to memory pages, which we cannot guarantee. So we just disable the function. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/sdhci.c13
-rw-r--r--drivers/mmc/sdhci.h1
2 files changed, 10 insertions, 4 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 8e480140cd2..95fe0fdac48 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -326,6 +326,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
DBG("tsac %d ms nsac %d clk\n",
data->timeout_ns / 1000000, data->timeout_clks);
+ /* Sanity checks */
+ BUG_ON(data->blksz * data->blocks > 524288);
+
/* timeout in us */
target_timeout = data->timeout_ns / 1000 +
data->timeout_clks / host->clock;
@@ -375,7 +378,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->remain = host->cur_sg->length;
}
- writew(data->blksz, host->ioaddr + SDHCI_BLOCK_SIZE);
+ /* We do not handle DMA boundaries, so set it to max (512 KiB) */
+ writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
+ host->ioaddr + SDHCI_BLOCK_SIZE);
writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
}
@@ -1188,10 +1193,10 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
mmc->max_phys_segs = 16;
/*
- * Maximum number of sectors in one transfer. Limited by sector
- * count register.
+ * Maximum number of sectors in one transfer. Limited by DMA boundary
+ * size (512KiB), which means (512 KiB/512=) 1024 entries.
*/
- mmc->max_sectors = 0x3FFF;
+ mmc->max_sectors = 1024;
/*
* Maximum segment size. Could be one segment with the maximum number
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index f8df28f8d6d..8ed2a8973db 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -23,6 +23,7 @@
#define SDHCI_DMA_ADDRESS 0x00
#define SDHCI_BLOCK_SIZE 0x04
+#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
#define SDHCI_BLOCK_COUNT 0x06