summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2018-06-22 17:19:47 +0200
committerStefano Babic <sbabic@denx.de>2018-06-27 09:07:55 +0200
commit5346c31e305a37d39f535cc0d5ae87d8b7e81230 (patch)
tree7bd09e4a57d63cc2508ed182de14bcc8633e8c8c /drivers
parent9345943b2b5ea890cb479770c3c802cf851ed3e6 (diff)
downloadu-boot-5346c31e305a37d39f535cc0d5ae87d8b7e81230.tar.gz
u-boot-5346c31e305a37d39f535cc0d5ae87d8b7e81230.tar.bz2
u-boot-5346c31e305a37d39f535cc0d5ae87d8b7e81230.zip
mtd: nand: mxs_nand: use self init
Instead of completing initialization via scan_bbt callback use NAND self init to initialize the GPMI (MXS) NAND controller. Suggested-by: Scott Wood <oss@buserror.net> Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/Kconfig1
-rw-r--r--drivers/mtd/nand/mxs_nand.c53
-rw-r--r--drivers/mtd/nand/mxs_nand.h1
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);