mtd: rawnand: fsl_ifc: fixup SRAM init for newer ctrl versions
authorKurt Kanzenbach <kurt@linutronix.de>
Mon, 13 Aug 2018 07:18:46 +0000 (09:18 +0200)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Tue, 4 Sep 2018 21:37:38 +0000 (23:37 +0200)
Newer versions of the IFC controller use a different method of initializing the
internal SRAM: Instead of reading from flash, a bit in the NAND configuration
register has to be set in order to trigger the self-initializing process.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
drivers/mtd/nand/raw/fsl_ifc_nand.c
include/linux/fsl_ifc.h

index e4f5792..7e7729d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/fsl_ifc.h>
+#include <linux/iopoll.h>
 
 #define ERR_BYTE               0xFF /* Value returned for read
                                        bytes when read failed  */
@@ -769,6 +770,27 @@ static int fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
        uint32_t csor = 0, csor_8k = 0, csor_ext = 0;
        uint32_t cs = priv->bank;
 
+       if (ctrl->version < FSL_IFC_VERSION_1_1_0)
+               return 0;
+
+       if (ctrl->version > FSL_IFC_VERSION_1_1_0) {
+               u32 ncfgr, status;
+               int ret;
+
+               /* Trigger auto initialization */
+               ncfgr = ifc_in32(&ifc_runtime->ifc_nand.ncfgr);
+               ifc_out32(ncfgr | IFC_NAND_NCFGR_SRAM_INIT_EN, &ifc_runtime->ifc_nand.ncfgr);
+
+               /* Wait until done */
+               ret = readx_poll_timeout(ifc_in32, &ifc_runtime->ifc_nand.ncfgr,
+                                        status, !(status & IFC_NAND_NCFGR_SRAM_INIT_EN),
+                                        10, IFC_TIMEOUT_MSECS * 1000);
+               if (ret)
+                       dev_err(priv->dev, "Failed to initialize SRAM!\n");
+
+               return ret;
+       }
+
        /* Save CSOR and CSOR_ext */
        csor = ifc_in32(&ifc_global->csor_cs[cs].csor);
        csor_ext = ifc_in32(&ifc_global->csor_cs[cs].csor_ext);
@@ -825,6 +847,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
        struct nand_chip *chip = &priv->chip;
        struct mtd_info *mtd = nand_to_mtd(&priv->chip);
        u32 csor;
+       int ret;
 
        /* Fill in fsl_ifc_mtd structure */
        mtd->dev.parent = priv->dev;
@@ -918,13 +941,9 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
                chip->ecc.algo = NAND_ECC_HAMMING;
        }
 
-       if (ctrl->version >= FSL_IFC_VERSION_1_1_0) {
-               int ret;
-
-               ret = fsl_ifc_sram_init(priv);
-               if (ret)
-                       return ret;
-       }
+       ret = fsl_ifc_sram_init(priv);
+       if (ret)
+               return ret;
 
        /*
         * As IFC version 2.0.0 has 16KB of internal SRAM as compared to older
index 3fdfede..5f343b7 100644 (file)
  */
 /* Auto Boot Mode */
 #define IFC_NAND_NCFGR_BOOT            0x80000000
+/* SRAM Initialization */
+#define IFC_NAND_NCFGR_SRAM_INIT_EN    0x20000000
 /* Addressing Mode-ROW0+n/COL0 */
 #define IFC_NAND_NCFGR_ADDR_MODE_RC0   0x00000000
 /* Addressing Mode-ROW0+n/COL0+n */