[U-Boot] [PATCH v4 2/6] mtd: nand: mxs_nand: use self init

Stefan Agner stefan at agner.ch
Fri Jun 22 15:19:47 UTC 2018


From: Stefan Agner <stefan.agner at toradex.com>

Instead of completing initialization via scan_bbt callback use
NAND self init to initialize the GPMI (MXS) NAND controller.

Suggested-by: Scott Wood <oss at buserror.net>
Signed-off-by: Stefan Agner <stefan.agner at toradex.com>
---

Changes in v4:
- Update SPL driver accordingly

Changes in v3:
- Fix indentation

Changes in v2: None

 drivers/mtd/nand/Kconfig    |  1 +
 drivers/mtd/nand/mxs_nand.c | 53 ++++++++++++++++++++-----------------
 drivers/mtd/nand/mxs_nand.h |  1 +
 3 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 94fbf89e4b..4db259fcb2 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -143,6 +143,7 @@ config NAND_MXC
 config NAND_MXS
 	bool "MXS NAND support"
 	depends on MX23 || MX28 || MX6 || MX7
+	select SYS_NAND_SELF_INIT
 	imply CMD_NAND
 	select APBH_DMA
 	select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index 5b7ad18c42..14d3210017 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -17,6 +17,7 @@
 #include <linux/mtd/rawnand.h>
 #include <linux/types.h>
 #include <malloc.h>
+#include <nand.h>
 #include <linux/errno.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -47,6 +48,7 @@
 #define	MXS_NAND_BCH_TIMEOUT			10000
 
 struct mxs_nand_info {
+	struct nand_chip chip;
 	int		cur_chip;
 
 	uint32_t	cmd_queue_len;
@@ -972,20 +974,15 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs)
 }
 
 /*
- * Nominally, the purpose of this function is to look for or create the bad
- * block table. In fact, since the we call this function at the very end of
- * the initialization process started by nand_scan(), and we doesn't have a
- * more formal mechanism, we "hook" this function to continue init process.
- *
  * At this point, the physical NAND Flash chips have been identified and
  * counted, so we know the physical geometry. This enables us to make some
  * important configuration decisions.
  *
  * The return value of this function propagates directly back to this driver's
- * call to nand_scan(). Anything other than zero will cause this driver to
+ * board_nand_init(). Anything other than zero will cause this driver to
  * tear everything down and declare failure.
  */
-static int mxs_nand_scan_bbt(struct mtd_info *mtd)
+int mxs_nand_setup_ecc(struct mtd_info *mtd)
 {
 	struct nand_chip *nand = mtd_to_nand(mtd);
 	struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
@@ -1047,8 +1044,7 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
 		mtd->_block_markbad = mxs_nand_hook_block_markbad;
 	}
 
-	/* We use the reference implementation for bad block management. */
-	return nand_default_bbt(mtd);
+	return 0;
 }
 
 /*
@@ -1177,7 +1173,6 @@ int mxs_nand_init_spl(struct nand_chip *nand)
 	nand->cmd_ctrl		= mxs_nand_cmd_ctrl;
 	nand->dev_ready		= mxs_nand_device_ready;
 	nand->select_chip	= mxs_nand_select_chip;
-	nand->scan_bbt		= mxs_nand_scan_bbt;
 
 	nand->read_byte		= mxs_nand_read_byte;
 	nand->read_buf		= mxs_nand_read_buf;
@@ -1192,27 +1187,22 @@ int mxs_nand_init_spl(struct nand_chip *nand)
 	return 0;
 }
 
-/*!
- * This function is called during the driver binding process.
- *
- * @param   pdev  the device structure used to store device specific
- *                information that is used by the suspend, resume and
- *                remove functions
- *
- * @return  The function always returns 0.
- */
-int board_nand_init(struct nand_chip *nand)
+void board_nand_init(void)
 {
+	struct mtd_info *mtd;
 	struct mxs_nand_info *nand_info;
+	struct nand_chip *nand;
 	int err;
 
 	nand_info = malloc(sizeof(struct mxs_nand_info));
 	if (!nand_info) {
 		printf("MXS NAND: Failed to allocate private data\n");
-		return -ENOMEM;
+			return;
 	}
 	memset(nand_info, 0, sizeof(struct mxs_nand_info));
 
+	nand = &nand_info->chip;
+	mtd = nand_to_mtd(nand);
 	err = mxs_nand_alloc_buffers(nand_info);
 	if (err)
 		goto err1;
@@ -1231,13 +1221,19 @@ int board_nand_init(struct nand_chip *nand)
 	nand->dev_ready		= mxs_nand_device_ready;
 	nand->select_chip	= mxs_nand_select_chip;
 	nand->block_bad		= mxs_nand_block_bad;
-	nand->scan_bbt		= mxs_nand_scan_bbt;
 
 	nand->read_byte		= mxs_nand_read_byte;
 
 	nand->read_buf		= mxs_nand_read_buf;
 	nand->write_buf		= mxs_nand_write_buf;
 
+	/* first scan to find the device and get the page size */
+	if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL))
+		goto err2;
+
+	if (mxs_nand_setup_ecc(mtd))
+		goto err2;
+
 	nand->ecc.read_page	= mxs_nand_ecc_read_page;
 	nand->ecc.write_page	= mxs_nand_ecc_write_page;
 	nand->ecc.read_oob	= mxs_nand_ecc_read_oob;
@@ -1249,12 +1245,21 @@ int board_nand_init(struct nand_chip *nand)
 	nand->ecc.size		= 512;
 	nand->ecc.strength	= 8;
 
-	return 0;
+	/* second phase scan */
+	err = nand_scan_tail(mtd);
+	if (err)
+		goto err2;
+
+	err = nand_register(0, mtd);
+	if (err)
+		goto err2;
+
+	return;
 
 err2:
 	free(nand_info->data_buf);
 	free(nand_info->cmd_buf);
 err1:
 	free(nand_info);
-	return err;
+	return;
 }
diff --git a/drivers/mtd/nand/mxs_nand.h b/drivers/mtd/nand/mxs_nand.h
index 9bb7148d98..379ed24f05 100644
--- a/drivers/mtd/nand/mxs_nand.h
+++ b/drivers/mtd/nand/mxs_nand.h
@@ -8,3 +8,4 @@
  */
 
 int mxs_nand_init_spl(struct nand_chip *nand);
+int mxs_nand_setup_ecc(struct mtd_info *mtd);
-- 
2.17.1



More information about the U-Boot mailing list