int             cur_chip;
 
        uint32_t        cmd_queue_len;
+       uint32_t        data_buf_size;
 
        uint8_t         *cmd_buf;
        uint8_t         *data_buf;
 
 struct nand_ecclayout fake_ecc_layout;
 
+/*
+ * Cache management functions
+ */
+#ifndef        CONFIG_SYS_DCACHE_OFF
+static void mxs_nand_flush_data_buf(struct mxs_nand_info *info)
+{
+       uint32_t addr = (uint32_t)info->data_buf;
+
+       flush_dcache_range(addr, addr + info->data_buf_size);
+}
+
+static void mxs_nand_inval_data_buf(struct mxs_nand_info *info)
+{
+       uint32_t addr = (uint32_t)info->data_buf;
+
+       invalidate_dcache_range(addr, addr + info->data_buf_size);
+}
+
+static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info)
+{
+       uint32_t addr = (uint32_t)info->cmd_buf;
+
+       flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE);
+}
+#else
+static inline void mxs_nand_flush_data_buf(struct mxs_nand_info *info) {}
+static inline void mxs_nand_inval_data_buf(struct mxs_nand_info *info) {}
+static inline void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) {}
+#endif
+
 static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
 {
        struct mxs_dma_desc *desc;
 
        mxs_dma_desc_append(channel, d);
 
+       /* Flush caches */
+       mxs_nand_flush_cmd_buf(nand_info);
+
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret)
                goto rtn;
        }
 
+       /* Invalidate caches */
+       mxs_nand_inval_data_buf(nand_info);
+
        memcpy(buf, nand_info->data_buf, length);
 
 rtn:
 
        mxs_dma_desc_append(channel, d);
 
+       /* Flush caches */
+       mxs_nand_flush_data_buf(nand_info);
+
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret)
                goto rtn;
        }
 
+       /* Invalidate caches */
+       mxs_nand_inval_data_buf(nand_info);
+
        /* Read DMA completed, now do the mark swapping. */
        mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
 
 
        mxs_dma_desc_append(channel, d);
 
+       /* Flush caches */
+       mxs_nand_flush_data_buf(nand_info);
+
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
        uint8_t *buf;
        const int size = NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE;
 
+       nand_info->data_buf_size = roundup(size, MXS_DMA_ALIGNMENT);
+
        /* DMA buffers */
-       buf = memalign(MXS_DMA_ALIGNMENT, size);
+       buf = memalign(MXS_DMA_ALIGNMENT, nand_info->data_buf_size);
        if (!buf) {
                printf("MXS NAND: Error allocating DMA buffers\n");
                return -ENOMEM;
        }
 
-       memset(buf, 0, size);
+       memset(buf, 0, nand_info->data_buf_size);
 
        nand_info->data_buf = buf;
        nand_info->oob_buf = buf + NAND_MAX_PAGESIZE;
-
        /* Command buffers */
        nand_info->cmd_buf = memalign(MXS_DMA_ALIGNMENT,
                                MXS_NAND_COMMAND_BUFFER_SIZE);