diff mbox

[U-Boot,v2] tegra: mmc: Support operation with dcache enabled

Message ID 1326151240-20789-1-git-send-email-sjg@chromium.org
State Accepted, archived
Commit 98450d0220eea0ab32385063e2e27fb1eb92a746
Delegated to: Andy Fleming
Headers show

Commit Message

Simon Glass Jan. 9, 2012, 11:20 p.m. UTC
When the data cache is enabled we must flush on write and invalidate
on read. We also check that buffers are aligned to data cache lines
boundaries. With recent work in U-Boot this should generally be the case
but the warnings will catch problems.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Add casts to avoid compile warning

 drivers/mmc/tegra2_mmc.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

Comments

Stephen Warren Jan. 10, 2012, 9:48 p.m. UTC | #1
On 01/09/2012 04:20 PM, Simon Glass wrote:
> When the data cache is enabled we must flush on write and invalidate
> on read. We also check that buffers are aligned to data cache lines
> boundaries. With recent work in U-Boot this should generally be the case
> but the warnings will catch problems.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Seems reasonable to me.

Acked-by: Stephen Warren <swarren@nvidia.com>
diff mbox

Patch

diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
index 035a868..17a988a 100644
--- a/drivers/mmc/tegra2_mmc.c
+++ b/drivers/mmc/tegra2_mmc.c
@@ -114,6 +114,14 @@  static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data)
 	if (data->flags & MMC_DATA_READ)
 		mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
 
+	if (data->flags & MMC_DATA_WRITE) {
+		if ((uintptr_t)data->src & (ARCH_DMA_MINALIGN - 1))
+			printf("Warning: unaligned write to %p may fail\n",
+			       data->src);
+		flush_dcache_range((ulong)data->src, (ulong)data->src +
+			data->blocks * data->blocksize);
+	}
+
 	writew(mode, &host->reg->trnmod);
 }
 
@@ -310,6 +318,14 @@  static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 			}
 		}
 		writel(mask, &host->reg->norintsts);
+		if (data->flags & MMC_DATA_READ) {
+			if ((uintptr_t)data->dest & (ARCH_DMA_MINALIGN - 1))
+				printf("Warning: unaligned read from %p "
+					"may fail\n", data->dest);
+			invalidate_dcache_range((ulong)data->dest,
+				(ulong)data->dest +
+					data->blocks * data->blocksize);
+		}
 	}
 
 	udelay(1000);