]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/nand/pxa3xx_nand.c
Merge branch 'master' of git://git.denx.de/u-boot-spi
[u-boot] / drivers / mtd / nand / pxa3xx_nand.c
index b1d58e036a1dab6adb50b5369ceb6521090c552f..9d02fd8eb1133afbbccc6e8dd114413c1807a2a0 100644 (file)
@@ -1,24 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/mtd/nand/pxa3xx_nand.c
  *
  * Copyright © 2005 Intel Corporation
  * Copyright © 2006 Marvell International Ltd.
- *
- * SPDX-License-Identifier:    GPL-2.0
  */
 
 #include <common.h>
 #include <malloc.h>
+#include <fdtdec.h>
 #include <nand.h>
-#include <asm/errno.h>
+#include <linux/errno.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
 #include <linux/types.h>
 
 #include "pxa3xx_nand.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define TIMEOUT_DRAIN_FIFO     5       /* in ms */
 #define        CHIP_DELAY_TIMEOUT      200
 #define NAND_STOP_DELAY                40
@@ -230,6 +232,7 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
        { 0xba20, 16, 16, &timing[3] },
 };
 
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
 static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
 static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
 
@@ -252,6 +255,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
        .maxblocks = 8,         /* Last 8 blocks in each chip */
        .pattern = bbt_mirror_pattern
 };
+#endif
 
 static struct nand_ecclayout ecc_layout_2KB_bch4bit = {
        .eccbytes = 32,
@@ -1510,8 +1514,6 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info)
                chip->cmdfunc           = nand_cmdfunc;
        }
 
-       info->mmio_base = (void __iomem *)MVEBU_NAND_BASE;
-
        /* Allocate a buffer to allow flash detection */
        info->buf_size = INIT_BUFFER_SIZE;
        info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
@@ -1533,17 +1535,62 @@ fail_disable_clk:
 static int pxa3xx_nand_probe_dt(struct pxa3xx_nand_info *info)
 {
        struct pxa3xx_nand_platform_data *pdata;
+       const void *blob = gd->fdt_blob;
+       int node = -1;
 
        pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return -ENOMEM;
 
-       pdata->enable_arbiter = 1;
-       pdata->num_cs = 1;
+       /* Get address decoding nodes from the FDT blob */
+       do {
+               node = fdt_node_offset_by_compatible(blob, node,
+                                                    "marvell,mvebu-pxa3xx-nand");
+               if (node < 0)
+                       break;
+
+               /* Bypass disabeld nodes */
+               if (!fdtdec_get_is_enabled(blob, node))
+                       continue;
 
-       info->pdata = pdata;
+               /* Get the first enabled NAND controler base address */
+               info->mmio_base =
+                       (void __iomem *)fdtdec_get_addr_size_auto_noparent(
+                                       blob, node, "reg", 0, NULL, true);
 
-       return 0;
+               pdata->num_cs = fdtdec_get_int(blob, node, "num-cs", 1);
+               if (pdata->num_cs != 1) {
+                       pr_err("pxa3xx driver supports single CS only\n");
+                       break;
+               }
+
+               if (fdtdec_get_bool(blob, node, "nand-enable-arbiter"))
+                       pdata->enable_arbiter = 1;
+
+               if (fdtdec_get_bool(blob, node, "nand-keep-config"))
+                       pdata->keep_config = 1;
+
+               /*
+                * ECC parameters.
+                * If these are not set, they will be selected according
+                * to the detected flash type.
+                */
+               /* ECC strength */
+               pdata->ecc_strength = fdtdec_get_int(blob, node,
+                                                    "nand-ecc-strength", 0);
+
+               /* ECC step size */
+               pdata->ecc_step_size = fdtdec_get_int(blob, node,
+                                                     "nand-ecc-step-size", 0);
+
+               info->pdata = pdata;
+
+               /* Currently support only a single NAND controller */
+               return 0;
+
+       } while (node >= 0);
+
+       return -EINVAL;
 }
 
 static int pxa3xx_nand_probe(struct pxa3xx_nand_info *info)
@@ -1603,8 +1650,8 @@ void board_nand_init(void)
        int ret;
 
        info = kzalloc(sizeof(*info) +
-                               sizeof(*host) * CONFIG_SYS_MAX_NAND_DEVICE,
-                       GFP_KERNEL);
+                      sizeof(*host) * CONFIG_SYS_MAX_NAND_DEVICE,
+                      GFP_KERNEL);
        if (!info)
                return;