aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2015-11-26 07:00:49 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2015-12-22 05:32:16 -0500
commit04a5ae6fdd018af29675eb8b6c2550c87f471570 (patch)
treedd1c9160a5196b467217fc4beac52c7d6bd46a3f /drivers/mmc
parent347ea32dc118326c4f2636928239a29d192cc9b8 (diff)
mmc: sdhci: 64-bit DMA actually has 4-byte alignment
The version 3.00 SDHCI spec. was a bit unclear about the required data alignment for 64-bit DMA, whereas the version 4.10 spec. uses different language and indicates that only 4-byte alignment is required rather than the 8-byte alignment currently implemented. That make no difference to SD and EMMC which invariably transfer data in sector-aligned blocks. However with SDIO, it results in using more DMA descriptors than necessary. Theoretically that slows DMA slightly although DMA is not the limiting factor for throughput, so there is no discernable impact on performance. Nevertheless, the driver should follw the spec unless there is good reason not to, so this patch corrects the alignment criterion. There is a more complicated criterion for the DMA descriptor table itself. However the table is allocated by dma_alloc_coherent() which allocates pages (i.e. aligned to a page boundary). For simplicity just check it is 8-byte aligned, but add a comment that some Intel controllers actually require 8-byte alignment even when using 32-bit DMA. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c31
-rw-r--r--drivers/mmc/host/sdhci.h21
2 files changed, 24 insertions, 28 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8df0ba0f63f4..1a8f42eb8c50 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -492,7 +492,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
492 host->align_buffer, host->align_buffer_sz, direction); 492 host->align_buffer, host->align_buffer_sz, direction);
493 if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) 493 if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
494 goto fail; 494 goto fail;
495 BUG_ON(host->align_addr & host->align_mask); 495 BUG_ON(host->align_addr & SDHCI_ADMA2_MASK);
496 496
497 host->sg_count = sdhci_pre_dma_transfer(host, data); 497 host->sg_count = sdhci_pre_dma_transfer(host, data);
498 if (host->sg_count < 0) 498 if (host->sg_count < 0)
@@ -514,8 +514,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
514 * the (up to three) bytes that screw up the 514 * the (up to three) bytes that screw up the
515 * alignment. 515 * alignment.
516 */ 516 */
517 offset = (host->align_sz - (addr & host->align_mask)) & 517 offset = (SDHCI_ADMA2_ALIGN - (addr & SDHCI_ADMA2_MASK)) &
518 host->align_mask; 518 SDHCI_ADMA2_MASK;
519 if (offset) { 519 if (offset) {
520 if (data->flags & MMC_DATA_WRITE) { 520 if (data->flags & MMC_DATA_WRITE) {
521 buffer = sdhci_kmap_atomic(sg, &flags); 521 buffer = sdhci_kmap_atomic(sg, &flags);
@@ -529,8 +529,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
529 529
530 BUG_ON(offset > 65536); 530 BUG_ON(offset > 65536);
531 531
532 align += host->align_sz; 532 align += SDHCI_ADMA2_ALIGN;
533 align_addr += host->align_sz; 533 align_addr += SDHCI_ADMA2_ALIGN;
534 534
535 desc += host->desc_sz; 535 desc += host->desc_sz;
536 536
@@ -611,7 +611,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
611 /* Do a quick scan of the SG list for any unaligned mappings */ 611 /* Do a quick scan of the SG list for any unaligned mappings */
612 has_unaligned = false; 612 has_unaligned = false;
613 for_each_sg(data->sg, sg, host->sg_count, i) 613 for_each_sg(data->sg, sg, host->sg_count, i)
614 if (sg_dma_address(sg) & host->align_mask) { 614 if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) {
615 has_unaligned = true; 615 has_unaligned = true;
616 break; 616 break;
617 } 617 }
@@ -623,15 +623,15 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
623 align = host->align_buffer; 623 align = host->align_buffer;
624 624
625 for_each_sg(data->sg, sg, host->sg_count, i) { 625 for_each_sg(data->sg, sg, host->sg_count, i) {
626 if (sg_dma_address(sg) & host->align_mask) { 626 if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) {
627 size = host->align_sz - 627 size = SDHCI_ADMA2_ALIGN -
628 (sg_dma_address(sg) & host->align_mask); 628 (sg_dma_address(sg) & SDHCI_ADMA2_MASK);
629 629
630 buffer = sdhci_kmap_atomic(sg, &flags); 630 buffer = sdhci_kmap_atomic(sg, &flags);
631 memcpy(buffer, align, size); 631 memcpy(buffer, align, size);
632 sdhci_kunmap_atomic(buffer, &flags); 632 sdhci_kunmap_atomic(buffer, &flags);
633 633
634 align += host->align_sz; 634 align += SDHCI_ADMA2_ALIGN;
635 } 635 }
636 } 636 }
637 } 637 }
@@ -2961,24 +2961,17 @@ int sdhci_add_host(struct sdhci_host *host)
2961 if (host->flags & SDHCI_USE_64_BIT_DMA) { 2961 if (host->flags & SDHCI_USE_64_BIT_DMA) {
2962 host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * 2962 host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
2963 SDHCI_ADMA2_64_DESC_SZ; 2963 SDHCI_ADMA2_64_DESC_SZ;
2964 host->align_buffer_sz = SDHCI_MAX_SEGS *
2965 SDHCI_ADMA2_64_ALIGN;
2966 host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; 2964 host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
2967 host->align_sz = SDHCI_ADMA2_64_ALIGN;
2968 host->align_mask = SDHCI_ADMA2_64_ALIGN - 1;
2969 } else { 2965 } else {
2970 host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * 2966 host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
2971 SDHCI_ADMA2_32_DESC_SZ; 2967 SDHCI_ADMA2_32_DESC_SZ;
2972 host->align_buffer_sz = SDHCI_MAX_SEGS *
2973 SDHCI_ADMA2_32_ALIGN;
2974 host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; 2968 host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
2975 host->align_sz = SDHCI_ADMA2_32_ALIGN;
2976 host->align_mask = SDHCI_ADMA2_32_ALIGN - 1;
2977 } 2969 }
2978 host->adma_table = dma_alloc_coherent(mmc_dev(mmc), 2970 host->adma_table = dma_alloc_coherent(mmc_dev(mmc),
2979 host->adma_table_sz, 2971 host->adma_table_sz,
2980 &host->adma_addr, 2972 &host->adma_addr,
2981 GFP_KERNEL); 2973 GFP_KERNEL);
2974 host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
2982 host->align_buffer = kmalloc(host->align_buffer_sz, GFP_KERNEL); 2975 host->align_buffer = kmalloc(host->align_buffer_sz, GFP_KERNEL);
2983 if (!host->adma_table || !host->align_buffer) { 2976 if (!host->adma_table || !host->align_buffer) {
2984 if (host->adma_table) 2977 if (host->adma_table)
@@ -2992,7 +2985,7 @@ int sdhci_add_host(struct sdhci_host *host)
2992 host->flags &= ~SDHCI_USE_ADMA; 2985 host->flags &= ~SDHCI_USE_ADMA;
2993 host->adma_table = NULL; 2986 host->adma_table = NULL;
2994 host->align_buffer = NULL; 2987 host->align_buffer = NULL;
2995 } else if (host->adma_addr & host->align_mask) { 2988 } else if (host->adma_addr & (SDHCI_ADMA2_DESC_ALIGN - 1)) {
2996 pr_warn("%s: unable to allocate aligned ADMA descriptor\n", 2989 pr_warn("%s: unable to allocate aligned ADMA descriptor\n",
2997 mmc_hostname(mmc)); 2990 mmc_hostname(mmc));
2998 host->flags &= ~SDHCI_USE_ADMA; 2991 host->flags &= ~SDHCI_USE_ADMA;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 9d4aa31b683a..7654ae5d2b4e 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -272,22 +272,27 @@
272/* ADMA2 32-bit DMA descriptor size */ 272/* ADMA2 32-bit DMA descriptor size */
273#define SDHCI_ADMA2_32_DESC_SZ 8 273#define SDHCI_ADMA2_32_DESC_SZ 8
274 274
275/* ADMA2 32-bit DMA alignment */
276#define SDHCI_ADMA2_32_ALIGN 4
277
278/* ADMA2 32-bit descriptor */ 275/* ADMA2 32-bit descriptor */
279struct sdhci_adma2_32_desc { 276struct sdhci_adma2_32_desc {
280 __le16 cmd; 277 __le16 cmd;
281 __le16 len; 278 __le16 len;
282 __le32 addr; 279 __le32 addr;
283} __packed __aligned(SDHCI_ADMA2_32_ALIGN); 280} __packed __aligned(4);
281
282/* ADMA2 data alignment */
283#define SDHCI_ADMA2_ALIGN 4
284#define SDHCI_ADMA2_MASK (SDHCI_ADMA2_ALIGN - 1)
285
286/*
287 * ADMA2 descriptor alignment. Some controllers (e.g. Intel) require 8 byte
288 * alignment for the descriptor table even in 32-bit DMA mode. Memory
289 * allocation is at least 8 byte aligned anyway, so just stipulate 8 always.
290 */
291#define SDHCI_ADMA2_DESC_ALIGN 8
284 292
285/* ADMA2 64-bit DMA descriptor size */ 293/* ADMA2 64-bit DMA descriptor size */
286#define SDHCI_ADMA2_64_DESC_SZ 12 294#define SDHCI_ADMA2_64_DESC_SZ 12
287 295
288/* ADMA2 64-bit DMA alignment */
289#define SDHCI_ADMA2_64_ALIGN 8
290
291/* 296/*
292 * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte 297 * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte
293 * aligned. 298 * aligned.
@@ -482,8 +487,6 @@ struct sdhci_host {
482 dma_addr_t align_addr; /* Mapped bounce buffer */ 487 dma_addr_t align_addr; /* Mapped bounce buffer */
483 488
484 unsigned int desc_sz; /* ADMA descriptor size */ 489 unsigned int desc_sz; /* ADMA descriptor size */
485 unsigned int align_sz; /* ADMA alignment */
486 unsigned int align_mask; /* ADMA alignment mask */
487 490
488 struct tasklet_struct finish_tasklet; /* Tasklet structures */ 491 struct tasklet_struct finish_tasklet; /* Tasklet structures */
489 492