]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/nand/omap_gpmc.c
mtd/nand:Fix wrong usage of is_blank() in fsl_ifc_run_command
[u-boot] / drivers / mtd / nand / omap_gpmc.c
index 5f8ed3984d8236b74cc698e2d5d0039ed4e9b86c..1dfe074e1e13c4e64f760bdcd91a5b7d95780c7b 100644 (file)
@@ -30,8 +30,6 @@
 #include <nand.h>
 
 static uint8_t cs;
-static gpmc_t *gpmc_base = (gpmc_t *)GPMC_BASE;
-static gpmc_csx_t *gpmc_cs_base;
 static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT;
 
 /*
@@ -49,13 +47,13 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
         */
        switch (ctrl) {
        case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
-               this->IO_ADDR_W = (void __iomem *)&gpmc_cs_base->nand_cmd;
+               this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
                break;
        case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
-               this->IO_ADDR_W = (void __iomem *)&gpmc_cs_base->nand_adr;
+               this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
                break;
        case NAND_CTRL_CHANGE | NAND_NCE:
-               this->IO_ADDR_W = (void __iomem *)&gpmc_cs_base->nand_dat;
+               this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
                break;
        }
 
@@ -63,6 +61,14 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
                writeb(cmd, this->IO_ADDR_W);
 }
 
+#ifdef CONFIG_SPL_BUILD
+/* Check wait pin as dev ready indicator */
+int omap_spl_dev_ready(struct mtd_info *mtd)
+{
+       return gpmc_cfg->status & (1 << 8);
+}
+#endif
+
 /*
  * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
  *                   GPMC controller
@@ -75,8 +81,8 @@ static void omap_hwecc_init(struct nand_chip *chip)
         * Init ECC Control Register
         * Clear all ECC | Enable Reg1
         */
-       writel(ECCCLEAR | ECCRESULTREG1, &gpmc_base->ecc_control);
-       writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL, &gpmc_base->ecc_size_config);
+       writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
+       writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL, &gpmc_cfg->ecc_size_config);
 }
 
 /*
@@ -179,7 +185,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
        u_int32_t val;
 
        /* Start Reading from HW ECC1_Result = 0x200 */
-       val = readl(&gpmc_base->ecc1_result);
+       val = readl(&gpmc_cfg->ecc1_result);
 
        ecc_code[0] = val & 0xFF;
        ecc_code[1] = (val >> 16) & 0xFF;
@@ -189,7 +195,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
         * Stop reading anymore ECC vals and clear old results
         * enable will be called if more reads are required
         */
-       writel(0x000, &gpmc_base->ecc_config);
+       writel(0x000, &gpmc_cfg->ecc_config);
 
        return 0;
 }
@@ -208,7 +214,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
        case NAND_ECC_READ:
        case NAND_ECC_WRITE:
                /* Clear the ecc result registers, select ecc reg as 1 */
-               writel(ECCCLEAR | ECCRESULTREG1, &gpmc_base->ecc_control);
+               writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
 
                /*
                 * Size 0 = 0xFF, Size1 is 0xFF - both are 512 bytes
@@ -216,9 +222,9 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
                 * we just have a single ECC engine for all CS
                 */
                writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL,
-                       &gpmc_base->ecc_size_config);
+                       &gpmc_cfg->ecc_size_config);
                val = (dev_width << 7) | (cs << 1) | (0x1);
-               writel(val, &gpmc_base->ecc_config);
+               writel(val, &gpmc_cfg->ecc_config);
                break;
        default:
                printf("Error: Unrecognized Mode[%d]!\n", mode);
@@ -226,6 +232,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
        }
 }
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
  * The default is to come up on s/w ecc
@@ -282,6 +289,7 @@ void omap_nand_switch_ecc(int32_t hardware)
 
        nand->options &= ~NAND_OWN_BUFFERS;
 }
+#endif /* CONFIG_SPL_BUILD */
 
 /*
  * Board-specific NAND initialization. The following members of the
@@ -311,15 +319,8 @@ int board_nand_init(struct nand_chip *nand)
         * devices.
         */
        while (cs < GPMC_MAX_CS) {
-               /*
-                * Each GPMC set for a single CS is at offset 0x30
-                * - already remapped for us
-                */
-               gpmc_cs_base = (gpmc_csx_t *)(GPMC_CONFIG_CS0_BASE +
-                               (cs * GPMC_CONFIG_WIDTH));
                /* Check if NAND type is set */
-               if ((readl(&gpmc_cs_base->config1) & 0xC00) ==
-                    0x800) {
+               if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
                        /* Found it!! */
                        break;
                }
@@ -331,23 +332,42 @@ int board_nand_init(struct nand_chip *nand)
                return -ENODEV;
        }
 
-       gpmc_config = readl(&gpmc_base->config);
+       gpmc_config = readl(&gpmc_cfg->config);
        /* Disable Write protect */
        gpmc_config |= 0x10;
-       writel(gpmc_config, &gpmc_base->config);
+       writel(gpmc_config, &gpmc_cfg->config);
 
-       nand->IO_ADDR_R = (void __iomem *)&gpmc_cs_base->nand_dat;
-       nand->IO_ADDR_W = (void __iomem *)&gpmc_cs_base->nand_cmd;
+       nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
+       nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
 
        nand->cmd_ctrl = omap_nand_hwcontrol;
        nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR;
        /* If we are 16 bit dev, our gpmc config tells us that */
-       if ((readl(gpmc_cs_base) & 0x3000) == 0x1000)
+       if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
                nand->options |= NAND_BUSWIDTH_16;
 
        nand->chip_delay = 100;
        /* Default ECC mode */
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
        nand->ecc.mode = NAND_ECC_SOFT;
+#else
+       nand->ecc.mode = NAND_ECC_HW;
+       nand->ecc.layout = &hw_nand_oob;
+       nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+       nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+       nand->ecc.hwctl = omap_enable_hwecc;
+       nand->ecc.correct = omap_correct_data;
+       nand->ecc.calculate = omap_calculate_ecc;
+       omap_hwecc_init(nand);
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+       if (nand->options & NAND_BUSWIDTH_16)
+               nand->read_buf = nand_read_buf16;
+       else
+               nand->read_buf = nand_read_buf;
+       nand->dev_ready = omap_spl_dev_ready;
+#endif
 
        return 0;
 }