summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2012-01-09 13:20:40 +0000
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2012-02-12 10:11:22 +0100
commit98450d0220eea0ab32385063e2e27fb1eb92a746 (patch)
treeea2c58cf115b996a502d27fff9f5e03323778257
parentca28090d2114eba17fb30579a69691d2b3aadf74 (diff)
downloadu-boot-imx-98450d0220eea0ab32385063e2e27fb1eb92a746.zip
u-boot-imx-98450d0220eea0ab32385063e2e27fb1eb92a746.tar.gz
u-boot-imx-98450d0220eea0ab32385063e2e27fb1eb92a746.tar.bz2
tegra: mmc: Support operation with dcache enabled
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> Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Tom Warren <twarren@nvidia.com>
-rw-r--r--drivers/mmc/tegra2_mmc.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
index 5b4c9f6..3191557 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);