aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-07-02 11:51:35 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-07-02 11:51:35 -0400
commitbab7696184bbf0ea48d56902bd1f9ac983079ad2 (patch)
treef8b90b4c561858c47624307df4d1e67498f23df2
parenta406f5a3b68ee1db2306a2ba1c9b00dbd3505d05 (diff)
[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>
-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 8e480140cd28..95fe0fdac484 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)
326 DBG("tsac %d ms nsac %d clk\n", 326 DBG("tsac %d ms nsac %d clk\n",
327 data->timeout_ns / 1000000, data->timeout_clks); 327 data->timeout_ns / 1000000, data->timeout_clks);
328 328
329 /* Sanity checks */
330 BUG_ON(data->blksz * data->blocks > 524288);
331
329 /* timeout in us */ 332 /* timeout in us */
330 target_timeout = data->timeout_ns / 1000 + 333 target_timeout = data->timeout_ns / 1000 +
331 data->timeout_clks / host->clock; 334 data->timeout_clks / host->clock;
@@ -375,7 +378,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
375 host->remain = host->cur_sg->length; 378 host->remain = host->cur_sg->length;
376 } 379 }
377 380
378 writew(data->blksz, host->ioaddr + SDHCI_BLOCK_SIZE); 381 /* We do not handle DMA boundaries, so set it to max (512 KiB) */
382 writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
383 host->ioaddr + SDHCI_BLOCK_SIZE);
379 writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT); 384 writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
380} 385}
381 386
@@ -1188,10 +1193,10 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1188 mmc->max_phys_segs = 16; 1193 mmc->max_phys_segs = 16;
1189 1194
1190 /* 1195 /*
1191 * Maximum number of sectors in one transfer. Limited by sector 1196 * Maximum number of sectors in one transfer. Limited by DMA boundary
1192 * count register. 1197 * size (512KiB), which means (512 KiB/512=) 1024 entries.
1193 */ 1198 */
1194 mmc->max_sectors = 0x3FFF; 1199 mmc->max_sectors = 1024;
1195 1200
1196 /* 1201 /*
1197 * Maximum segment size. Could be one segment with the maximum number 1202 * Maximum segment size. Could be one segment with the maximum number
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index f8df28f8d6dd..8ed2a8973db6 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -23,6 +23,7 @@
23#define SDHCI_DMA_ADDRESS 0x00 23#define SDHCI_DMA_ADDRESS 0x00
24 24
25#define SDHCI_BLOCK_SIZE 0x04 25#define SDHCI_BLOCK_SIZE 0x04
26#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
26 27
27#define SDHCI_BLOCK_COUNT 0x06 28#define SDHCI_BLOCK_COUNT 0x06
28 29