sunxi_nand_spl: Drop unnecessary temp buf
authorHans de Goede <hdegoede@redhat.com>
Sat, 15 Aug 2015 07:33:41 +0000 (09:33 +0200)
committerHans de Goede <hdegoede@redhat.com>
Mon, 31 Aug 2015 06:43:41 +0000 (08:43 +0200)
nand_spl_load_image() always gets called with either CONFIG_SYS_TEXT_BASE
or spl_image.load_addr as destination, both of which are properly aligened,
and have plenty of space for "overshooting" up to
CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes, as we read in
CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes chunks.

This saves CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE (typically 1k) in
SPL size, which is a lot on the total 24k we have.

Note this changes the dma destination from SRAM to DRAM, so this patch
updates the DDMA_DST_TYPE bits in the dma controller cfg0 reg accordingly.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
drivers/mtd/nand/sunxi_nand_spl.c

index ac5f56d066fef5245050b4604f84e5155a064732..46654e4ef66a884468ea9eaa2d02e349794ef703 100644 (file)
@@ -85,6 +85,7 @@
 
 #define SUNXI_DMA_DDMA_CFG_REG_LOADING  (1 << 31)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
+#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
 #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
 
 /* minimal "boot0" style NAND support for Allwinner A20 */
 
-/* temporary buffer in internal ram */
-unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE]
-       __aligned(0x10) __section(".text#");
-
 /* random seed used by linux */
 const uint16_t random_seed[128] = {
        0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
@@ -167,8 +164,8 @@ void nand_init(void)
        }
 }
 
-static void nand_read_page(unsigned int real_addr, int syndrome,
-                          uint32_t *ecc_errors)
+static void nand_read_page(unsigned int real_addr, dma_addr_t dst,
+                          int syndrome, uint32_t *ecc_errors)
 {
        uint32_t val;
        int ecc_off = 0;
@@ -226,9 +223,6 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
                return;
        }
 
-       /* clear temp_buf */
-       memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE);
-
        /* set CMD  */
        writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
               SUNXI_NFC_BASE + NFC_CMD);
@@ -278,8 +272,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
        writel(SUNXI_NFC_BASE + NFC_IO_DATA,
               SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
        /* read to RAM */
-       writel((uint32_t)temp_buf,
-              SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
+       writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
        writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC
                        | SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
                        SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
@@ -287,6 +280,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
               SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */
        writel(SUNXI_DMA_DDMA_CFG_REG_LOADING
                | SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32
+               | SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM
                | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32
                | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO
                | SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
@@ -324,27 +318,14 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
 {
        void *current_dest;
-       uint32_t count;
-       uint32_t current_count;
        uint32_t ecc_errors = 0;
 
-       memset(dest, 0x0, size); /* clean destination memory */
        for (current_dest = dest;
                        current_dest < (dest + size);
                        current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) {
-               nand_read_page(offs, offs
-                               < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END,
-                              &ecc_errors);
-               count = current_dest - dest;
-
-               if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
-                       current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
-               else
-                       current_count = size - count;
-
-               memcpy(current_dest,
-                      temp_buf,
-                      current_count);
+               nand_read_page(offs, (dma_addr_t)current_dest,
+                       offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END,
+                       &ecc_errors);
                offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
        }
        return ecc_errors ? -1 : 0;