]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - drivers/mtd/nand/sunxi_nand_spl.c
sunxi_nand_spl: Add proper cache flusing
[karo-tx-uboot.git] / drivers / mtd / nand / sunxi_nand_spl.c
index f6f49289f8f69a3ad47965fab482d222256a27fa..663c03ec4fdf2c91a9411a56228c3fa6da910c26 100644 (file)
@@ -5,9 +5,10 @@
  * SPDX-License-Identifier:     GPL-2.0+
  */
 
+#include <asm/arch/clock.h>
+#include <asm/io.h>
 #include <common.h>
 #include <config.h>
-#include <asm/io.h>
 #include <nand.h>
 
 /* registers */
@@ -153,6 +154,8 @@ void nand_init(void)
 {
        uint32_t val;
 
+       board_nand_init();
+
        val = readl(SUNXI_NFC_BASE + NFC_CTL);
        /* enable and reset CTL */
        writel(val | NFC_CTL_EN | NFC_CTL_RESET,
@@ -263,6 +266,10 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst,
                writel(oob_offset, SUNXI_NFC_BASE + NFC_SPARE_AREA);
        }
 
+       flush_dcache_range(dst,
+                          ALIGN(dst + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
+                                ARCH_DMA_MINALIGN));
+
        /* SUNXI_DMA */
        writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
        /* read from REG_IO_DATA */
@@ -308,6 +315,10 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst,
                return;
        }
 
+       invalidate_dcache_range(dst,
+                       ALIGN(dst + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
+                             ARCH_DMA_MINALIGN));
+
        if (readl(SUNXI_NFC_BASE + NFC_ECC_ST))
                (*ecc_errors)++;
 }
@@ -328,4 +339,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
        return ecc_errors ? -1 : 0;
 }
 
-void nand_deselect(void) {}
+void nand_deselect(void)
+{
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+       clrbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
+#ifdef CONFIG_MACH_SUN9I
+       clrbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
+#else
+       clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
+#endif
+       clrbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
+}