host->data = data;
host->data_early = 0;
+ host->data->bytes_xfered = 0;
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
host->flags |= SDHCI_REQ_USE_DMA;
sdhci_set_transfer_irqs(host);
- /* We do not handle DMA boundaries, so set it to max (512 KiB) */
- sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+ /* Set the DMA boundary value and block size */
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+ data->blksz), SDHCI_BLOCK_SIZE);
sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
}
* We currently don't do anything fancy with DMA
* boundaries, but as we can't disable the feature
* we need to at least restart the transfer.
+ *
+ * According to the spec sdhci_readl(host, SDHCI_DMA_ADDRESS)
+ * should return a valid address to continue from, but as
+ * some controllers are faulty, don't trust them.
*/
- if (intmask & SDHCI_INT_DMA_END)
- sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
- SDHCI_DMA_ADDRESS);
+ if (intmask & SDHCI_INT_DMA_END) {
+ u32 dmastart, dmanow;
+ dmastart = sg_dma_address(host->data->sg);
+ dmanow = dmastart + host->data->bytes_xfered;
+ /*
+ * Force update to the next DMA block boundary.
+ */
+ dmanow = (dmanow &
+ ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
+ SDHCI_DEFAULT_BOUNDARY_SIZE;
+ host->data->bytes_xfered = dmanow - dmastart;
+ DBG("%s: DMA base 0x%08x, transferred 0x%06x bytes,"
+ " next 0x%08x\n",
+ mmc_hostname(host->mmc), dmastart,
+ host->data->bytes_xfered, dmanow);
+ sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+ }
if (intmask & SDHCI_INT_DATA_END) {
if (host->cmd) {
#define SDHCI_MAX_DIV_SPEC_200 256
#define SDHCI_MAX_DIV_SPEC_300 2046
+/*
+ * Host SDMA buffer boundary. Valid values from 4K to 512K in powers of 2.
+ */
+#define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024)
+#define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12)
+
struct sdhci_ops {
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
u32 (*read_l)(struct sdhci_host *host, int reg);