]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/nand/denali_spl.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / drivers / mtd / nand / denali_spl.c
index e98f537c2c36fa1d8035b4cfbc91ed2c6c0a98ee..dbaba3cab2a784363479553b3bf6d5f9138a7d6c 100644 (file)
@@ -1,15 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2014       Panasonic Corporation
- *
- * SPDX-License-Identifier:    GPL-2.0+
+ * Copyright (C) 2014-2015  Masahiro Yamada <yamada.masahiro@socionext.com>
  */
 
 #include <common.h>
 #include <asm/io.h>
 #include <asm/unaligned.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
 #include "denali.h"
 
+#define DENALI_MAP01           (1 << 26)       /* read/write pages in PIO */
+#define DENALI_MAP10           (2 << 26)       /* high-level control plane */
+
+#define INDEX_CTRL_REG         0x0
+#define INDEX_DATA_REG         0x10
+
 #define SPARE_ACCESS           0x41
 #define MAIN_ACCESS            0x42
 #define PIPELINE_ACCESS                0x2000
@@ -22,7 +28,6 @@ static void __iomem *denali_flash_reg =
                        (void __iomem *)CONFIG_SYS_NAND_REGS_BASE;
 
 static const int flash_bank;
-static uint8_t page_buffer[NAND_MAX_PAGESIZE];
 static int page_size, oob_size, pages_per_block;
 
 static void index_addr(uint32_t address, uint32_t data)
@@ -39,9 +44,9 @@ static int wait_for_irq(uint32_t irq_mask)
        do {
                intr_status = readl(denali_flash_reg + INTR_STATUS(flash_bank));
 
-               if (intr_status & INTR_STATUS__ECC_UNCOR_ERR) {
+               if (intr_status & INTR__ECC_UNCOR_ERR) {
                        debug("Uncorrected ECC detected\n");
-                       return -EIO;
+                       return -EBADMSG;
                }
 
                if (intr_status & irq_mask)
@@ -106,16 +111,16 @@ int denali_send_pipeline_cmd(int page, int ecc_en, int access_type)
        addr = BANK(flash_bank) | page;
 
        /* setup the acccess type */
-       cmd = MODE_10 | addr;
+       cmd = DENALI_MAP10 | addr;
        index_addr(cmd, access_type);
 
        /* setup the pipeline command */
        index_addr(cmd, PIPELINE_ACCESS | page_count);
 
-       cmd = MODE_01 | addr;
+       cmd = DENALI_MAP01 | addr;
        writel(cmd, denali_flash_mem + INDEX_CTRL_REG);
 
-       return wait_for_irq(INTR_STATUS__LOAD_COMP);
+       return wait_for_irq(INTR__LOAD_COMP);
 }
 
 static int nand_read_oob(void *buf, int page)
@@ -144,15 +149,15 @@ static int nand_read_page(void *buf, int page)
        return 0;
 }
 
-static int nand_block_isbad(int block)
+static int nand_block_isbad(void *buf, int block)
 {
        int ret;
 
-       ret = nand_read_oob(page_buffer, block * pages_per_block);
+       ret = nand_read_oob(buf, block * pages_per_block);
        if (ret < 0)
                return ret;
 
-       return page_buffer[CONFIG_SYS_NAND_BAD_BLOCK_POS] != 0xff;
+       return *((uint8_t *)buf + CONFIG_SYS_NAND_BAD_BLOCK_POS) != 0xff;
 }
 
 /* nand_init() - initialize data to make nand usable by SPL */
@@ -184,7 +189,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
 
        while (size) {
                if (force_bad_block_check || page == 0) {
-                       ret = nand_block_isbad(block);
+                       ret = nand_block_isbad(dst, block);
                        if (ret < 0)
                                return ret;
 
@@ -196,24 +201,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
 
                force_bad_block_check = 0;
 
-               if (unlikely(column || size < page_size)) {
-                       /* Partial page read */
-                       ret = nand_read_page(page_buffer,
-                                            block * pages_per_block + page);
-                       if (ret < 0)
-                               return ret;
+               ret = nand_read_page(dst, block * pages_per_block + page);
+               if (ret < 0)
+                       return ret;
 
-                       readlen = min(page_size - column, (int)size);
-                       memcpy(dst, page_buffer, readlen);
+               readlen = min(page_size - column, (int)size);
 
+               if (unlikely(column)) {
+                       /* Partial page read */
+                       memmove(dst, dst + column, readlen);
                        column = 0;
-               } else {
-                       ret = nand_read_page(dst,
-                                            block * pages_per_block + page);
-                       if (ret < 0)
-                               return ret;
-
-                       readlen = page_size;
                }
 
                size -= readlen;