tegra: mmc: Support operation with dcache enabled
authorSimon Glass <sjg@chromium.org>
Mon, 9 Jan 2012 13:20:40 +0000 (13:20 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Sun, 12 Feb 2012 09:11:22 +0000 (10:11 +0100)
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>
drivers/mmc/tegra2_mmc.c

index 5b4c9f69a18fe34b7f0033ce8799225e60045ad4..3191557c5be62e08304444149ea0983884516abe 100644 (file)
@@ -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);