fix: nand: pxa3xx: Remove hardcode values from the driver
authorKonstantin Porotchkin <kostap@marvell.com>
Tue, 28 Mar 2017 15:16:54 +0000 (18:16 +0300)
committerStefan Roese <sr@denx.de>
Tue, 9 May 2017 11:38:18 +0000 (13:38 +0200)
Obtain NAND controller setup parameters from the device
tree instead of using hardcoded values.

Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
Cc: Scott Wood <oss@buserror.net>
Cc: Stefan Roese <sr@denx.de>
Cc: Igal Liberman <igall@marvell.com>
Cc: Nadav Haklai <nadavh@marvell.com>
Signed-off-by: Stefan Roese <sr@denx.de>
drivers/mtd/nand/pxa3xx_nand.c

index dfe8966b56b69b7b896b5cc51ae14bf80108ff7f..0042a7ba11df12a82c18a372d7c495deaf169b8a 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <fdtdec.h>
 #include <nand.h>
 #include <linux/errno.h>
 #include <asm/io.h>
@@ -19,6 +20,8 @@
 
 #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
@@ -1510,8 +1513,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 +1534,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) {
+                       error("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 +1649,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;