From d62e9caaaf7e6f5c7d86c9ea19170bfa5adda8be Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Mon, 19 Mar 2012 15:35:25 +0100 Subject: mtd: support ONFI multi lun NAND With onfi a flash is organized into one or more logical units (LUNs). A logical unit (LUN) is the minimum unit that can independently execute commands and report status. Mtd does not exploit LUN, so make it see a big single flash where size is lun_size * number_of_lun. Without this patch MT29F8G08ADBDAH4 size is 512MiB instead of 1GiB. Artem: split long line on 2 shorter ones. This is commit 637957551c0ac80de8dfc7650d320c5a98c2c0c0 from Linux Signed-off-by: Matthieu Castet Acked-by: Florian Fainelli Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse [scottwood@freescale.com: picked from Linux into U-Boot] Reported-by: Rafael Beims Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bfd668f..50bfb65 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2573,7 +2573,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; + chip->chipsize = le32_to_cpu(p->blocks_per_lun); + chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; *busw = 0; if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; -- cgit v1.1 From eee623a5049963d0c085be37128bbd22bee1ba1e Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:42 -0500 Subject: nand: Add support for unlock.invert NAND unlock command allows an invert bit to be set to unlock all but the selected page range. Signed-off-by: Joe Hershberger [scottwood@freescale.com: updated docs and added comment about invert bit] Signed-off-by: Scott Wood --- common/cmd_nand.c | 13 ++++++++++--- doc/README.nand | 2 ++ drivers/mtd/nand/nand_util.c | 17 ++++++++++++++--- include/nand.h | 4 ++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index a91ccf4..f737c06 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -749,11 +749,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 0; } - if (strcmp(cmd, "unlock") == 0) { + if (strncmp(cmd, "unlock", 5) == 0) { + int allexcept = 0; + + s = strchr(cmd, '.'); + + if (s && !strcmp(s, ".allexcept")) + allexcept = 1; + if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0) return 1; - if (!nand_unlock(&nand_info[dev], off, size)) { + if (!nand_unlock(&nand_info[dev], off, size, allexcept)) { puts("NAND flash successfully unlocked\n"); } else { puts("Error unlocking NAND flash, " @@ -807,7 +814,7 @@ U_BOOT_CMD( "\n" "nand lock [tight] [status]\n" " bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section" + "nand unlock[.allexcept] [offset] [size] - unlock section" #endif #ifdef CONFIG_ENV_OFFSET_OOB "\n" diff --git a/doc/README.nand b/doc/README.nand index 1602b5e..c130189 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -228,6 +228,8 @@ NAND locking command (for chips with active LOCKPRE pin) "nand unlock [offset] [size]" unlock consecutive area (can be called multiple times for different areas) + "nand unlock.allexcept [offset] [size]" + unlock all except specified consecutive area I have tested the code with board containing 128MiB NAND large page chips and 32MiB small page chips. diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 7ed8b18..c66eeef 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -317,18 +317,20 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) * @param start start byte address * @param length number of bytes to unlock (must be a multiple of * page size nand->writesize) + * @param allexcept if set, unlock everything not selected * * @return 0 on success, -1 in case of error */ -int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) +int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept) { int ret = 0; int chipnr; int status; int page; struct nand_chip *chip = mtd->priv; - printf ("nand_unlock: start: %08x, length: %d!\n", - (int)start, (int)length); + + debug("nand_unlock%s: start: %08x, length: %d!\n", + allexcept ? " (allexcept)" : "", start, length); /* select the NAND device */ chipnr = (int)(start >> chip->chip_shift); @@ -368,6 +370,15 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) /* submit ADDRESS of LAST page to unlock */ page += (int)(length >> chip->page_shift); + + /* + * Page addresses for unlocking are supposed to be block-aligned. + * At least some NAND chips use the low bit to indicate that the + * page range should be inverted. + */ + if (allexcept) + page |= 1; + chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1, page & chip->pagemask); /* call wait ready function */ diff --git a/include/nand.h b/include/nand.h index c554c55..e9b47f1 100644 --- a/include/nand.h +++ b/include/nand.h @@ -144,8 +144,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_LOCK 0x02 #define NAND_LOCK_STATUS_UNLOCK 0x04 -int nand_lock( nand_info_t *meminfo, int tight ); -int nand_unlock( nand_info_t *meminfo, ulong start, ulong length ); +int nand_lock(nand_info_t *meminfo, int tight); +int nand_unlock(nand_info_t *meminfo, ulong start, ulong length, int allexcept); int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); -- cgit v1.1 From e331ab2ee9b141f1de2a8fb0bfaf52f6273022f9 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:43 -0500 Subject: nand: Change ulong to loff_t and size_t Missed in previous cleanup. Signed-off-by: Joe Hershberger Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_util.c | 5 +++-- include/nand.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index c66eeef..5ef7df7 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -321,7 +321,8 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) * * @return 0 on success, -1 in case of error */ -int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept) +int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length, + int allexcept) { int ret = 0; int chipnr; @@ -329,7 +330,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept) int page; struct nand_chip *chip = mtd->priv; - debug("nand_unlock%s: start: %08x, length: %d!\n", + debug("nand_unlock%s: start: %08llx, length: %d!\n", allexcept ? " (allexcept)" : "", start, length); /* select the NAND device */ diff --git a/include/nand.h b/include/nand.h index e9b47f1..ff061c0 100644 --- a/include/nand.h +++ b/include/nand.h @@ -145,7 +145,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_UNLOCK 0x04 int nand_lock(nand_info_t *meminfo, int tight); -int nand_unlock(nand_info_t *meminfo, ulong start, ulong length, int allexcept); +int nand_unlock(nand_info_t *meminfo, loff_t start, size_t length, + int allexcept); int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); -- cgit v1.1 From 33b1d5cae3defdbeb30333ffac41bcbff85c5019 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:44 -0500 Subject: nand: consolidate duplicated constants NAND_CMD_ constants for lock/unlock should be in the header Signed-off-by: Joe Hershberger Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_util.c | 6 ------ include/linux/mtd/nand.h | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 5ef7df7..ffcb4f6 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -207,12 +207,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) * Support for locking / unlocking operations of some NAND devices *****************************************************************************/ -#define NAND_CMD_LOCK 0x2a -#define NAND_CMD_LOCK_TIGHT 0x2c -#define NAND_CMD_UNLOCK1 0x23 -#define NAND_CMD_UNLOCK2 0x24 -#define NAND_CMD_LOCK_STATUS 0x7a - /** * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT * state diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 82704de..6c40531 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -85,8 +85,10 @@ extern void nand_wait_ready(struct mtd_info *mtd); #define NAND_CMD_RESET 0xff #define NAND_CMD_LOCK 0x2a +#define NAND_CMD_LOCK_TIGHT 0x2c #define NAND_CMD_UNLOCK1 0x23 #define NAND_CMD_UNLOCK2 0x24 +#define NAND_CMD_LOCK_STATUS 0x7a /* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30 -- cgit v1.1 From e70bfa2986f9c028e3c21e0995285047a9baec27 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:45 -0500 Subject: nand: Make NAND lock status compatible with Micron Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is not the same as others. Instead of bit 1 being lock, it is #lock_tight. To make the driver support either format, ignore bit 1 and use only bit 0 and bit 2. Signed-off-by: Joe Hershberger Signed-off-by: Scott Wood --- common/cmd_nand.c | 8 +++++++- drivers/mtd/nand/nand_util.c | 2 -- include/nand.h | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index f737c06..9c6dabe 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -231,12 +231,18 @@ print: #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status(ulong start, ulong end, ulong erasesize, int status) { + /* + * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is + * not the same as others. Instead of bit 1 being lock, it is + * #lock_tight. To make the driver support either format, ignore bit 1 + * and use only bit 0 and bit 2. + */ printf("%08lx - %08lx: %08lx blocks %s%s%s\n", start, end - 1, (end - start) / erasesize, ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), - ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), + (!(status & NAND_LOCK_STATUS_UNLOCK) ? "LOCK " : ""), ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index ffcb4f6..c4752a7 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -265,7 +265,6 @@ int nand_lock(struct mtd_info *mtd, int tight) * >0 lock status: * bitfield with the following combinations: * NAND_LOCK_STATUS_TIGHT: page in tight state - * NAND_LOCK_STATUS_LOCK: page locked * NAND_LOCK_STATUS_UNLOCK: page unlocked * */ @@ -294,7 +293,6 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask); ret = chip->read_byte(mtd) & (NAND_LOCK_STATUS_TIGHT - | NAND_LOCK_STATUS_LOCK | NAND_LOCK_STATUS_UNLOCK); out: diff --git a/include/nand.h b/include/nand.h index ff061c0..bbe28b2 100644 --- a/include/nand.h +++ b/include/nand.h @@ -141,7 +141,6 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_TIGHT 0x01 -#define NAND_LOCK_STATUS_LOCK 0x02 #define NAND_LOCK_STATUS_UNLOCK 0x04 int nand_lock(nand_info_t *meminfo, int tight); -- cgit v1.1 From 9c790a748f6b61e36f7aaf0c8d5ed35c9b09f454 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 30 Aug 2012 13:39:38 +0000 Subject: mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver This is based on Linux kernel -next: commit 14f44abf1dafc20ba42ce8616a8fc8fbd1b3712b Author: Brian Norris Date: Fri Jul 13 09:28:24 2012 -0700 mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver The NAND_CHIPOPTIONS_MSK has limited utility and is causing real bugs. It silently masks off at least one flag that might be set by the driver (NAND_NO_SUBPAGE_WRITE). This breaks the GPMI NAND driver and possibly others. Really, as long as driver writers exercise a small amount of care with NAND_* options, this mask is not necessary at all; it was only here to prevent certain options from accidentally being set by the driver. But the original thought turns out to be a bad idea occasionally. Thus, kill it. Note, this patch fixes some major gpmi-nand breakage. Signed-off-by: Marek Vasut Cc: Brian Norris Cc: Eric Nelson Cc: Fabio Estevam Cc: Otavio Salvador Cc: Scott Wood Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 7 ++----- include/linux/mtd/nand.h | 3 --- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 50bfb65..390ff90 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2579,9 +2579,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= (NAND_NO_READRDY | - NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; + chip->options |= NAND_NO_READRDY | NAND_NO_AUTOINCR; return 1; } @@ -2753,8 +2751,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, } } /* Get chip options, preserve non chip based options */ - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= type->options & NAND_CHIPOPTIONS_MSK; + chip->options |= type->options; /* Check if chip is a not a samsung device. Do not clear the * options for chips which are not having an extended id. diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 6c40531..c06866b 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -207,9 +207,6 @@ typedef enum { #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \ && (chip->page_shift > 9)) -/* Mask to zero out the chip options, which come from the id table */ -#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) - /* Non chip related options */ /* * Use a flash based bad block table. OOB identifier is saved in OOB area. -- cgit v1.1 From 80c8ab7b25579529809792eef51fe660308fecb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:48:12 +0200 Subject: mxc nand: Merge mtd and spl register definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patches fixes the TODO to use same register definitions in mtd mxc_nand and nand_spl fsl nfc drivers. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 247 +++++++++---------------------------------- include/fsl_nfc.h | 97 +++++++++-------- nand_spl/nand_boot_fsl_nfc.c | 58 +++++----- 3 files changed, 128 insertions(+), 274 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 936186f..9a9260c 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -25,168 +25,23 @@ #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) #include #endif +#include #define DRIVER_NAME "mxc_nand" -/* - * TODO: Use same register defs here as nand_spl mxc nand driver. - */ -/* - * Register map and bit definitions for the Freescale NAND Flash Controller - * present in various i.MX devices. - * - * MX31 and MX27 have version 1 which has - * 4 512 byte main buffers and - * 4 16 byte spare buffers - * to support up to 2K byte pagesize nand. - * Reading or writing a 2K page requires 4 FDI/FDO cycles. - * - * MX25 has version 1.1 which has - * 8 512 byte main buffers and - * 8 64 byte spare buffers - * to support up to 4K byte pagesize nand. - * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. - * Also some of registers are moved and/or changed meaning as seen below. - */ -#if defined(CONFIG_MX31) || defined(CONFIG_MX27) -#define MXC_NFC_V1 -#elif defined(CONFIG_MX25) || defined(CONFIG_MX35) -#define MXC_NFC_V1_1 -#else -#warning "MXC NFC version not defined" -#endif - -#if defined(MXC_NFC_V1) -#define NAND_MXC_NR_BUFS 4 -#define NAND_MXC_SPARE_BUF_SIZE 16 -#define NAND_MXC_REG_OFFSET 0xe00 -#define is_mxc_nfc_11() 0 -#elif defined(MXC_NFC_V1_1) -#define NAND_MXC_NR_BUFS 8 -#define NAND_MXC_SPARE_BUF_SIZE 64 -#define NAND_MXC_REG_OFFSET 0x1e00 -#define is_mxc_nfc_11() 1 -#else -#error "define CONFIG_NAND_MXC_VXXX to use mtd mxc nand driver" -#endif -struct nfc_regs { - uint8_t main_area[NAND_MXC_NR_BUFS][0x200]; - uint8_t spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE]; - /* - * reserved size is offset of nfc registers - * minus total main and spare sizes - */ - uint8_t reserved1[NAND_MXC_REG_OFFSET - - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)]; -#if defined(MXC_NFC_V1) - uint16_t nfc_buf_size; - uint16_t reserved2; - uint16_t nfc_buf_addr; - uint16_t nfc_flash_addr; - uint16_t nfc_flash_cmd; - uint16_t nfc_config; - uint16_t nfc_ecc_status_result; - uint16_t nfc_rsltmain_area; - uint16_t nfc_rsltspare_area; - uint16_t nfc_wrprot; - uint16_t nfc_unlockstart_blkaddr; - uint16_t nfc_unlockend_blkaddr; - uint16_t nfc_nf_wrprst; - uint16_t nfc_config1; - uint16_t nfc_config2; -#elif defined(MXC_NFC_V1_1) - uint16_t reserved2[2]; - uint16_t nfc_buf_addr; - uint16_t nfc_flash_addr; - uint16_t nfc_flash_cmd; - uint16_t nfc_config; - uint16_t nfc_ecc_status_result; - uint16_t nfc_ecc_status_result2; - uint16_t nfc_spare_area_size; - uint16_t nfc_wrprot; - uint16_t reserved3[2]; - uint16_t nfc_nf_wrprst; - uint16_t nfc_config1; - uint16_t nfc_config2; - uint16_t reserved4; - uint16_t nfc_unlockstart_blkaddr; - uint16_t nfc_unlockend_blkaddr; - uint16_t nfc_unlockstart_blkaddr1; - uint16_t nfc_unlockend_blkaddr1; - uint16_t nfc_unlockstart_blkaddr2; - uint16_t nfc_unlockend_blkaddr2; - uint16_t nfc_unlockstart_blkaddr3; - uint16_t nfc_unlockend_blkaddr3; -#endif -}; - -/* - * Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register - * for Command operation - */ -#define NFC_CMD 0x1 - -/* - * Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register - * for Address operation - */ -#define NFC_ADDR 0x2 - -/* - * Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register - * for Input operation - */ -#define NFC_INPUT 0x4 - -/* - * Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register - * for Data Output operation - */ -#define NFC_OUTPUT 0x8 - -/* - * Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register - * for Read ID operation - */ -#define NFC_ID 0x10 - -/* - * Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register - * for Read Status operation - */ -#define NFC_STATUS 0x20 - -/* - * Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read - * Status operation - */ -#define NFC_INT 0x8000 - -#ifdef MXC_NFC_V1_1 -#define NFC_4_8N_ECC (1 << 0) -#else -#define NFC_4_8N_ECC 0 -#endif -#define NFC_SP_EN (1 << 2) -#define NFC_ECC_EN (1 << 3) -#define NFC_BIG (1 << 5) -#define NFC_RST (1 << 6) -#define NFC_CE (1 << 7) -#define NFC_ONE_CYCLE (1 << 8) - typedef enum {false, true} bool; struct mxc_nand_host { - struct mtd_info mtd; - struct nand_chip *nand; - - struct nfc_regs __iomem *regs; - int spare_only; - int status_request; - int pagesize_2k; - int clk_act; - uint16_t col_addr; - unsigned int page_addr; + struct mtd_info mtd; + struct nand_chip *nand; + + struct fsl_nfc_regs __iomem *regs; + int spare_only; + int status_request; + int pagesize_2k; + int clk_act; + uint16_t col_addr; + unsigned int page_addr; }; static struct mxc_nand_host mxc_host; @@ -304,10 +159,10 @@ static void wait_op_done(struct mxc_nand_host *host, int max_retries, uint32_t tmp; while (max_retries-- > 0) { - if (readw(&host->regs->nfc_config2) & NFC_INT) { - tmp = readw(&host->regs->nfc_config2); + if (readw(&host->regs->config2) & NFC_INT) { + tmp = readw(&host->regs->config2); tmp &= ~NFC_INT; - writew(tmp, &host->regs->nfc_config2); + writew(tmp, &host->regs->config2); break; } udelay(1); @@ -326,8 +181,8 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd) { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd); - writew(cmd, &host->regs->nfc_flash_cmd); - writew(NFC_CMD, &host->regs->nfc_config2); + writew(cmd, &host->regs->flash_cmd); + writew(NFC_CMD, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, cmd); @@ -342,8 +197,8 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr) { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr); - writew(addr, &host->regs->nfc_flash_addr); - writew(NFC_ADDR, &host->regs->nfc_config2); + writew(addr, &host->regs->flash_addr); + writew(NFC_ADDR, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, addr); @@ -375,19 +230,19 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, } } - writew(buf_id, &host->regs->nfc_buf_addr); + writew(buf_id, &host->regs->buf_addr); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint16_t config1 = readw(&host->regs->nfc_config1); + uint16_t config1 = readw(&host->regs->config1); if (spare_only) config1 |= NFC_SP_EN; else config1 &= ~(NFC_SP_EN); - writew(config1, &host->regs->nfc_config1); + writew(config1, &host->regs->config1); } - writew(NFC_INPUT, &host->regs->nfc_config2); + writew(NFC_INPUT, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); @@ -402,19 +257,19 @@ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); - writew(buf_id, &host->regs->nfc_buf_addr); + writew(buf_id, &host->regs->buf_addr); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint32_t config1 = readw(&host->regs->nfc_config1); + uint32_t config1 = readw(&host->regs->config1); if (spare_only) config1 |= NFC_SP_EN; else config1 &= ~NFC_SP_EN; - writew(config1, &host->regs->nfc_config1); + writew(config1, &host->regs->config1); } - writew(NFC_OUTPUT, &host->regs->nfc_config2); + writew(NFC_OUTPUT, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); @@ -442,14 +297,14 @@ static void send_read_id(struct mxc_nand_host *host) uint16_t tmp; /* NANDFC buffer 0 is used for device ID output */ - writew(0x0, &host->regs->nfc_buf_addr); + writew(0x0, &host->regs->buf_addr); /* Read ID into main buffer */ - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_SP_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); - writew(NFC_ID, &host->regs->nfc_config2); + writew(NFC_ID, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0); @@ -469,14 +324,14 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) /* store the main area1 first word, later do recovery */ store = readl(main_buf); /* NANDFC buffer 1 is used for device status */ - writew(1, &host->regs->nfc_buf_addr); + writew(1, &host->regs->buf_addr); /* Read status into main buffer */ - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_SP_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); - writew(NFC_STATUS, &host->regs->nfc_config2); + writew(NFC_STATUS, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0); @@ -515,13 +370,13 @@ static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t tmp = readw(&host->regs->nfc_config1); + uint16_t tmp = readw(&host->regs->config1); if (on) tmp |= NFC_ECC_EN; else tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); } static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, @@ -799,7 +654,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result); + uint16_t ecc_status = readw(&host->regs->ecc_status_result); int subpages = mtd->writesize / nand_chip->subpagesize; int pg2blk_shift = nand_chip->phys_erase_shift - nand_chip->page_shift; @@ -845,7 +700,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, * additional correction. 2-Bit errors cannot be corrected by * HW ECC, so we need to return failure */ - uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result); + uint16_t ecc_status = readw(&host->regs->ecc_status_result); if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { MTDDEBUG(MTD_DEBUG_LEVEL0, @@ -1289,14 +1144,14 @@ static void mxc_setup_config1(void) { uint16_t tmp; - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp |= NFC_ONE_CYCLE; tmp |= NFC_4_8N_ECC; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); if (host->pagesize_2k) - writew(64/2, &host->regs->nfc_spare_area_size); + writew(64/2, &host->regs->spare_area_size); else - writew(16/2, &host->regs->nfc_spare_area_size); + writew(16/2, &host->regs->spare_area_size); } #else #define mxc_setup_config1() @@ -1359,7 +1214,7 @@ int board_nand_init(struct nand_chip *this) this->read_buf = mxc_nand_read_buf; this->verify_buf = mxc_nand_verify_buf; - host->regs = (struct nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; + host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; host->clk_act = 1; #ifdef CONFIG_MXC_NAND_HWECC @@ -1383,15 +1238,15 @@ int board_nand_init(struct nand_chip *this) host->pagesize_2k = 0; this->ecc.size = 512; - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp |= NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); #else this->ecc.layout = &nand_soft_eccoob; this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); #endif /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); @@ -1400,10 +1255,10 @@ int board_nand_init(struct nand_chip *this) * preset operation * Unlock the internal RAM Buffer */ - writew(0x2, &host->regs->nfc_config); + writew(0x2, &host->regs->config); /* Blocks to be unlocked */ - writew(0x0, &host->regs->nfc_unlockstart_blkaddr); + writew(0x0, &host->regs->unlockstart_blkaddr); /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the * unlockend_blkaddr, but the magic 0x4000 does not always work * when writing more than some 32 megabytes (on 2k page nands) @@ -1415,10 +1270,10 @@ int board_nand_init(struct nand_chip *this) * This might be NAND chip specific and the i.MX31 datasheet is * extremely vague about the semantics of this register. */ - writew(0xFFFF, &host->regs->nfc_unlockend_blkaddr); + writew(0xFFFF, &host->regs->unlockend_blkaddr); /* Unlock Block Command for given address range */ - writew(0x4, &host->regs->nfc_wrprot); + writew(0x4, &host->regs->wrprot); /* NAND bus width determines access functions used by upper layer */ if (is_16bit_nand()) diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 279aaa5..6691e41 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -24,28 +24,25 @@ #define __FSL_NFC_H /* - * TODO: Use same register defs for nand_spl mxc nand driver - * and mtd mxc nand driver. + * Register map and bit definitions for the Freescale NAND Flash Controller + * present in various i.MX devices. * - * Register map and bit definitions for the Freescale NAND Flash - * Controller present in various i.MX devices. + * MX31 and MX27 have version 1, which has: + * 4 512-byte main buffers and + * 4 16-byte spare buffers + * to support up to 2K byte pagesize nand. + * Reading or writing a 2K page requires 4 FDI/FDO cycles. * - * MX31 and MX27 have version 1 which has - * 4 512 byte main buffers and - * 4 16 byte spare buffers - * to support up to 2K byte pagesize nand. - * Reading or writing a 2K page requires 4 FDI/FDO cycles. - * - * MX25 has version 1.1 which has - * 8 512 byte main buffers and - * 8 64 byte spare buffers - * to support up to 4K byte pagesize nand. - * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. - * Also some of registers are moved and/or changed meaning as seen below. + * MX25 and MX35 have version 1.1, which has: + * 8 512-byte main buffers and + * 8 64-byte spare buffers + * to support up to 4K byte pagesize nand. + * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. + * Also some of registers are moved and/or changed meaning as seen below. */ -#if defined(CONFIG_MX31) || defined(CONFIG_MX27) +#if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 -#elif defined(CONFIG_MX25) +#elif defined(CONFIG_MX25) || defined(CONFIG_MX35) #define MXC_NFC_V1_1 #else #warning "MXC NFC version not defined" @@ -55,18 +52,20 @@ #define NAND_MXC_NR_BUFS 4 #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 -#define NAND_MXC_2K_MULTI_CYCLE 1 +#define NAND_MXC_2K_MULTI_CYCLE +#define is_mxc_nfc_11() 0 #elif defined(MXC_NFC_V1_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 +#define is_mxc_nfc_11() 1 #else -#error "define CONFIG_NAND_MXC_VXXX to use the mxc spl_nand driver" +#error "define CONFIG_NAND_MXC_VXXX to use the mxc nand driver" #endif struct fsl_nfc_regs { - u32 main_area[NAND_MXC_NR_BUFS][512/4]; - u32 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE/4]; + u8 main_area[NAND_MXC_NR_BUFS][0x200]; + u8 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE]; /* * reserved size is offset of nfc registers * minus total main and spare sizes @@ -74,44 +73,44 @@ struct fsl_nfc_regs { u8 reserved1[NAND_MXC_REG_OFFSET - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)]; #if defined(MXC_NFC_V1) - u16 bufsiz; + u16 buf_size; u16 reserved2; - u16 buffer_address; - u16 flash_add; + u16 buf_addr; + u16 flash_addr; u16 flash_cmd; - u16 configuration; + u16 config; u16 ecc_status_result; - u16 ecc_rslt_main_area; - u16 ecc_rslt_spare_area; - u16 nf_wr_prot; - u16 unlock_start_blk_add; - u16 unlock_end_blk_add; - u16 nand_flash_wr_pr_st; - u16 nand_flash_config1; - u16 nand_flash_config2; + u16 rsltmain_area; + u16 rsltspare_area; + u16 wrprot; + u16 unlockstart_blkaddr; + u16 unlockend_blkaddr; + u16 nf_wrprst; + u16 config1; + u16 config2; #elif defined(MXC_NFC_V1_1) u16 reserved2[2]; - u16 buffer_address; - u16 flash_add; + u16 buf_addr; + u16 flash_addr; u16 flash_cmd; - u16 configuration; + u16 config; u16 ecc_status_result; u16 ecc_status_result2; u16 spare_area_size; - u16 nf_wr_prot; + u16 wrprot; u16 reserved3[2]; - u16 nand_flash_wr_pr_st; - u16 nand_flash_config1; - u16 nand_flash_config2; + u16 nf_wrprst; + u16 config1; + u16 config2; u16 reserved4; - u16 unlock_start_blk_add0; - u16 unlock_end_blk_add0; - u16 unlock_start_blk_add1; - u16 unlock_end_blk_add1; - u16 unlock_start_blk_add2; - u16 unlock_end_blk_add2; - u16 unlock_start_blk_add3; - u16 unlock_end_blk_add3; + u16 unlockstart_blkaddr; + u16 unlockend_blkaddr; + u16 unlockstart_blkaddr1; + u16 unlockend_blkaddr1; + u16 unlockstart_blkaddr2; + u16 unlockend_blkaddr2; + u16 unlockstart_blkaddr3; + u16 unlockend_blkaddr3; #endif }; diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index d6b0d9b..f437deb 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -36,13 +36,13 @@ static void nfc_wait_ready(void) { uint32_t tmp; - while (!(readw(&nfc->nand_flash_config2) & NFC_INT)) + while (!(readw(&nfc->config2) & NFC_INT)) ; /* Reset interrupt flag */ - tmp = readw(&nfc->nand_flash_config2); + tmp = readw(&nfc->config2); tmp &= ~NFC_INT; - writew(tmp, &nfc->nand_flash_config2); + writew(tmp, &nfc->config2); } void nfc_nand_init(void) @@ -54,10 +54,10 @@ void nfc_nand_init(void) writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size); /* unlocking RAM Buff */ - writew(0x2, &nfc->configuration); + writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->nand_flash_config1) | NFC_ECC_EN | 0x800; + config1 = readw(&nfc->config1) | NFC_ECC_EN | 0x800; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 @@ -66,20 +66,20 @@ void nfc_nand_init(void) config1 &= ~NFC_4_8N_ECC; else config1 |= NFC_4_8N_ECC; - writew(config1, &nfc->nand_flash_config1); + writew(config1, &nfc->config1); #elif defined(MXC_NFC_V1) /* unlocking RAM Buff */ - writew(0x2, &nfc->configuration); + writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - writew(NFC_ECC_EN, &nfc->nand_flash_config1); + writew(NFC_ECC_EN, &nfc->config1); #endif } static void nfc_nand_command(unsigned short command) { writew(command, &nfc->flash_cmd); - writew(NFC_CMD, &nfc->nand_flash_config2); + writew(NFC_CMD, &nfc->config2); nfc_wait_ready(); } @@ -87,14 +87,14 @@ static void nfc_nand_page_address(unsigned int page_address) { unsigned int page_count; - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(0x00, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); /* code only for large page flash */ if (CONFIG_SYS_NAND_PAGE_SIZE > 512) { - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(0x00, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); } @@ -103,30 +103,30 @@ static void nfc_nand_page_address(unsigned int page_address) if (page_address <= page_count) { page_count--; /* transform 0x01000000 to 0x00ffffff */ do { - writew(page_address & 0xff, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(page_address & 0xff, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); page_address = page_address >> 8; page_count = page_count >> 8; } while (page_count); } - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(0x00, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); } static void nfc_nand_data_output(void) { - int config1 = readw(&nfc->nand_flash_config1); + int config1 = readw(&nfc->config1); #ifdef NAND_MXC_2K_MULTI_CYCLE int i; #endif config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->nand_flash_config1); - writew(0, &nfc->buffer_address); - writew(NFC_OUTPUT, &nfc->nand_flash_config2); + writew(config1, &nfc->config1); + writew(0, &nfc->buf_addr); + writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); #ifdef NAND_MXC_2K_MULTI_CYCLE /* @@ -134,11 +134,11 @@ static void nfc_nand_data_output(void) * for pages larger than 512 bytes. */ for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) { - config1 = readw(&nfc->nand_flash_config1); + config1 = readw(&nfc->config1); config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->nand_flash_config1); - writew(i, &nfc->buffer_address); - writew(NFC_OUTPUT, &nfc->nand_flash_config2); + writew(config1, &nfc->config1); + writew(i, &nfc->buf_addr); + writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); } #endif @@ -155,7 +155,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) u32 *src; u32 *dst; - writew(0, &nfc->buffer_address); /* read in first 0 buffer */ + writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page_address); @@ -167,7 +167,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) if (nfc_nand_check_ecc()) return -1; - src = &nfc->main_area[0][0]; + src = (u32 *)&nfc->main_area[0][0]; dst = (u32 *)buf; /* main copy loop from NAND-buffer to SDRAM memory */ @@ -188,7 +188,7 @@ static int is_badblock(int pagenumber) /* Check the first two pages for bad block markers */ for (page = pagenumber; page < pagenumber + 2; page++) { - writew(0, &nfc->buffer_address); /* read in first 0 buffer */ + writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page); @@ -197,7 +197,7 @@ static int is_badblock(int pagenumber) nfc_nand_data_output(); /* fill the main buffer 0 */ - src = &nfc->spare_area[0][0]; + src = (u32 *)&nfc->spare_area[0][0]; /* * IMPORTANT NOTE: The nand flash controller uses a non- -- cgit v1.1 From 365b2c0761040764953e659f3385840e33823807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:48:26 +0200 Subject: mxc nand: cosmectic: Light cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 9 +++------ include/fsl_nfc.h | 1 + nand_spl/nand_boot_fsl_nfc.c | 14 +++++++------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 9a9260c..62d8c6b 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -123,8 +123,7 @@ static int is_16bit_nand(void) #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) static int is_16bit_nand(void) { - struct ccm_regs *ccm = - (struct ccm_regs *)IMX_CCM_BASE; + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; if (readl(&ccm->rcsr) & CCM_RCSR_NF_16BIT_SEL) return 1; @@ -238,7 +237,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, if (spare_only) config1 |= NFC_SP_EN; else - config1 &= ~(NFC_SP_EN); + config1 &= ~NFC_SP_EN; writew(config1, &host->regs->config1); } @@ -687,7 +686,6 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, #define mxc_nand_write_page_syndrome NULL #define mxc_nand_write_page_raw_syndrome NULL #define mxc_nand_write_oob_syndrome NULL -#define mxc_nfc_11_nand_correct_data NULL static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) @@ -1188,7 +1186,6 @@ int board_nand_init(struct nand_chip *this) { struct mtd_info *mtd; uint16_t tmp; - int err = 0; #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT this->options |= NAND_USE_FLASH_BBT; @@ -1287,5 +1284,5 @@ int board_nand_init(struct nand_chip *this) this->ecc.layout = &nand_hw_eccoob; #endif mxc_setup_config1(); - return err; + return 0; } diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 6691e41..1c16c71 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -166,5 +166,6 @@ struct fsl_nfc_regs { #define NFC_RST (1 << 6) #define NFC_CE (1 << 7) #define NFC_ONE_CYCLE (1 << 8) +#define NFC_FP_INT (1 << 11) #endif /* __FSL_NFC_H */ diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index f437deb..b90f93e 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -45,10 +45,10 @@ static void nfc_wait_ready(void) writew(tmp, &nfc->config2); } -void nfc_nand_init(void) +static void nfc_nand_init(void) { #if defined(MXC_NFC_V1_1) - int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; + int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int config1; writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size); @@ -57,12 +57,12 @@ void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->config1) | NFC_ECC_EN | 0x800; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 */ - if ((CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page) > 16) + if (CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16) config1 &= ~NFC_4_8N_ECC; else config1 |= NFC_4_8N_ECC; @@ -133,7 +133,7 @@ static void nfc_nand_data_output(void) * This NAND controller requires multiple input commands * for pages larger than 512 bytes. */ - for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) { + for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) { config1 = readw(&nfc->config1); config1 |= NFC_ECC_EN | NFC_INT_MSK; writew(config1, &nfc->config1); @@ -171,7 +171,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) dst = (u32 *)buf; /* main copy loop from NAND-buffer to SDRAM memory */ - for (i = 0; i < (CONFIG_SYS_NAND_PAGE_SIZE / 4); i++) { + for (i = 0; i < CONFIG_SYS_NAND_PAGE_SIZE / 4; i++) { writel(readl(src), dst); src++; dst++; @@ -230,7 +230,7 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf) page = from / CONFIG_SYS_NAND_PAGE_SIZE; i = 0; - while (i < (size / CONFIG_SYS_NAND_PAGE_SIZE)) { + while (i < size / CONFIG_SYS_NAND_PAGE_SIZE) { if (nfc_read_page(page, buf) < 0) return -1; -- cgit v1.1 From 5d818a2821c3c7cf350ee4a2c67a11f8e1039af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:48:56 +0200 Subject: spl mxc nand: Merge duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge duplicated code into functions, which is better for SPL size too. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 50 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index b90f93e..b98fe41 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -83,37 +83,35 @@ static void nfc_nand_command(unsigned short command) nfc_wait_ready(); } +static void nfc_nand_address(unsigned short address) +{ + writew(address, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); + nfc_wait_ready(); +} + static void nfc_nand_page_address(unsigned int page_address) { unsigned int page_count; - writew(0x00, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); + nfc_nand_address(0x00); /* code only for large page flash */ - if (CONFIG_SYS_NAND_PAGE_SIZE > 512) { - writew(0x00, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); - } + if (CONFIG_SYS_NAND_PAGE_SIZE > 512) + nfc_nand_address(0x00); page_count = CONFIG_SYS_NAND_SIZE / CONFIG_SYS_NAND_PAGE_SIZE; if (page_address <= page_count) { page_count--; /* transform 0x01000000 to 0x00ffffff */ do { - writew(page_address & 0xff, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); + nfc_nand_address(page_address & 0xff); page_address = page_address >> 8; page_count = page_count >> 8; } while (page_count); } - writew(0x00, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); + nfc_nand_address(0x00); } static void nfc_nand_data_output(void) @@ -149,12 +147,8 @@ static int nfc_nand_check_ecc(void) return readw(&nfc->ecc_status_result); } -static int nfc_read_page(unsigned int page_address, unsigned char *buf) +static void nfc_nand_read_page(unsigned int page_address) { - int i; - u32 *src; - u32 *dst; - writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page_address); @@ -163,6 +157,15 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) nfc_nand_command(NAND_CMD_READSTART); nfc_nand_data_output(); /* fill the main buffer 0 */ +} + +static int nfc_read_page(unsigned int page_address, unsigned char *buf) +{ + int i; + u32 *src; + u32 *dst; + + nfc_nand_read_page(page_address); if (nfc_nand_check_ecc()) return -1; @@ -188,14 +191,7 @@ static int is_badblock(int pagenumber) /* Check the first two pages for bad block markers */ for (page = pagenumber; page < pagenumber + 2; page++) { - writew(0, &nfc->buf_addr); /* read in first 0 buffer */ - nfc_nand_command(NAND_CMD_READ0); - nfc_nand_page_address(page); - - if (CONFIG_SYS_NAND_PAGE_SIZE > 512) - nfc_nand_command(NAND_CMD_READSTART); - - nfc_nand_data_output(); /* fill the main buffer 0 */ + nfc_nand_read_page(page); src = (u32 *)&nfc->spare_area[0][0]; -- cgit v1.1 From 0eee20fc1bb16f484771d626e1d7bde7d770a01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:15 +0200 Subject: spl mxc nand: Remove duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ECC_EN and INT_MSK bits of CONFIG1 are not volatile, so it is sufficient to set them once in nfc_nand_init(). Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index b98fe41..059969b 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -57,7 +57,7 @@ static void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_FP_INT; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 @@ -72,7 +72,7 @@ static void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - writew(NFC_ECC_EN, &nfc->config1); + writew(NFC_ECC_EN | NFC_INT_MSK, &nfc->config1); #endif } @@ -116,13 +116,10 @@ static void nfc_nand_page_address(unsigned int page_address) static void nfc_nand_data_output(void) { - int config1 = readw(&nfc->config1); #ifdef NAND_MXC_2K_MULTI_CYCLE int i; #endif - config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->config1); writew(0, &nfc->buf_addr); writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); @@ -132,9 +129,6 @@ static void nfc_nand_data_output(void) * for pages larger than 512 bytes. */ for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) { - config1 = readw(&nfc->config1); - config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->config1); writew(i, &nfc->buf_addr); writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); -- cgit v1.1 From 0e55ad7271259b1de183fb5329ea7f07774e368d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:31 +0200 Subject: spl mxc nand: Set symmetric mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the spl mxc nand driver for IP 1.1 in symmetric mode, like the mtd driver. In this way, for both drivers, one input clock period of the NFC IP will produce one R/W cycle. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 059969b..842943c 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -57,7 +57,8 @@ static void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | NFC_FP_INT; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | + NFC_ONE_CYCLE | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 -- cgit v1.1 From c1db8dd62b337372a08942e1c5945a8590afbc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:42 +0200 Subject: mxc nand: Access all ecc_status_result fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the NFC IP 1.1, the 32-bit ecc_status_result value comes from 2 consecutive 16-bit registers. This patch reads all the fields of this value, which makes a difference for 4-kiB NF pages. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 2 +- include/fsl_nfc.h | 3 +-- nand_spl/nand_boot_fsl_nfc.c | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 62d8c6b..4564b25 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -653,7 +653,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t ecc_status = readw(&host->regs->ecc_status_result); + uint32_t ecc_status = readl(&host->regs->ecc_status_result); int subpages = mtd->writesize / nand_chip->subpagesize; int pg2blk_shift = nand_chip->phys_erase_shift - nand_chip->page_shift; diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 1c16c71..c248cef 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -94,8 +94,7 @@ struct fsl_nfc_regs { u16 flash_addr; u16 flash_cmd; u16 config; - u16 ecc_status_result; - u16 ecc_status_result2; + u32 ecc_status_result; u16 spare_area_size; u16 wrprot; u16 reserved3[2]; diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 842943c..4c5a7fe 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -139,7 +139,11 @@ static void nfc_nand_data_output(void) static int nfc_nand_check_ecc(void) { +#if defined(MXC_NFC_V1) return readw(&nfc->ecc_status_result); +#elif defined(MXC_NFC_V1_1) + return readl(&nfc->ecc_status_result); +#endif } static void nfc_nand_read_page(unsigned int page_address) -- cgit v1.1 From b8fea2b27d7aeabd2e0bc4242277ff2787c7c622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:53 +0200 Subject: spl mxc nand: Fix broken boot for correctable ECC errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not stop boot as soon as an ECC error is detected. Only stop boot for uncorrectable ECC errors. This fixes boards no longer booting after some time because a NAND Flash bit has flipped. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 4c5a7fe..ea05952 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -140,9 +140,21 @@ static void nfc_nand_data_output(void) static int nfc_nand_check_ecc(void) { #if defined(MXC_NFC_V1) - return readw(&nfc->ecc_status_result); + u16 ecc_status = readw(&nfc->ecc_status_result); + return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2; #elif defined(MXC_NFC_V1_1) - return readl(&nfc->ecc_status_result); + u32 ecc_status = readl(&nfc->ecc_status_result); + int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; + int err_limit = CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16 ? 8 : 4; + int subpages = CONFIG_SYS_NAND_PAGE_SIZE / 512; + + do { + if ((ecc_status & 0xf) > err_limit) + return 1; + ecc_status >>= 4; + } while (--subpages); + + return 0; #endif } -- cgit v1.1 From 0e499b07ef417b153e3feb54c249d56edbc364b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:07 +0200 Subject: mtd mxc nand: Use _mxc_nand_enable_hwecc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use _mxc_nand_enable_hwecc() instead of duplicating its code. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 4564b25..7a180e1 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -355,16 +355,6 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd) return 1; } -#ifdef CONFIG_MXC_NAND_HWECC -static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) -{ - /* - * If HW ECC is enabled, we turn it on during init. There is - * no need to enable again here. - */ -} - -#ifdef MXC_NFC_V1_1 static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) { struct nand_chip *nand_chip = mtd->priv; @@ -378,6 +368,16 @@ static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) writew(tmp, &host->regs->config1); } +#ifdef CONFIG_MXC_NAND_HWECC +static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + /* + * If HW ECC is enabled, we turn it on during init. There is + * no need to enable again here. + */ +} + +#ifdef MXC_NFC_V1_1 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) @@ -1235,15 +1235,11 @@ int board_nand_init(struct nand_chip *this) host->pagesize_2k = 0; this->ecc.size = 512; - tmp = readw(&host->regs->config1); - tmp |= NFC_ECC_EN; - writew(tmp, &host->regs->config1); + _mxc_nand_enable_hwecc(mtd, 1); #else this->ecc.layout = &nand_soft_eccoob; this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(&host->regs->config1); - tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->config1); + _mxc_nand_enable_hwecc(mtd, 0); #endif /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); -- cgit v1.1 From 7c28a1cfdf5e919f2a09abb644f614f1b67d3322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:19 +0200 Subject: mtd mxc nand: Fix ECC state after read_page_raw_syndrome() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mxc_nand_read_page_raw_syndrome() should reenable ECC upon exit. This fixes ECC errors left uncorrected after a call to this function. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 7a180e1..2ae41dc 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -470,7 +470,7 @@ static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd, size = mtd->oobsize - (oob - chip->oob_poi); if (size) chip->read_buf(mtd, oob, size); - _mxc_nand_enable_hwecc(mtd, 0); + _mxc_nand_enable_hwecc(mtd, 1); return 0; } -- cgit v1.1 From 13927f07334ce47a975c2e2a5bcd6bb708692534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:30 +0200 Subject: mtd mxc nand: Merge init functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge mxc_setup_config1() into board_nand_init() in order to ease the addition of i.MX5 support in the following patches. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 53 ++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 2ae41dc..e743796 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1137,24 +1137,6 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, } } -#ifdef MXC_NFC_V1_1 -static void mxc_setup_config1(void) -{ - uint16_t tmp; - - tmp = readw(&host->regs->config1); - tmp |= NFC_ONE_CYCLE; - tmp |= NFC_4_8N_ECC; - writew(tmp, &host->regs->config1); - if (host->pagesize_2k) - writew(64/2, &host->regs->spare_area_size); - else - writew(16/2, &host->regs->spare_area_size); -} -#else -#define mxc_setup_config1() -#endif - #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; @@ -1244,6 +1226,29 @@ int board_nand_init(struct nand_chip *this) /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* NAND bus width determines access functions used by upper layer */ + if (is_16bit_nand()) + this->options |= NAND_BUSWIDTH_16; + +#ifdef CONFIG_SYS_NAND_LARGEPAGE + host->pagesize_2k = 1; + this->ecc.layout = &nand_hw_eccoob2k; +#else + host->pagesize_2k = 0; + this->ecc.layout = &nand_hw_eccoob; +#endif + +#ifdef MXC_NFC_V1_1 + tmp = readw(&host->regs->config1); + tmp |= NFC_ONE_CYCLE; + tmp |= NFC_4_8N_ECC; + writew(tmp, &host->regs->config1); + if (host->pagesize_2k) + writew(64/2, &host->regs->spare_area_size); + else + writew(16/2, &host->regs->spare_area_size); +#endif + /* * preset operation * Unlock the internal RAM Buffer @@ -1268,17 +1273,5 @@ int board_nand_init(struct nand_chip *this) /* Unlock Block Command for given address range */ writew(0x4, &host->regs->wrprot); - /* NAND bus width determines access functions used by upper layer */ - if (is_16bit_nand()) - this->options |= NAND_BUSWIDTH_16; - -#ifdef CONFIG_SYS_NAND_LARGEPAGE - host->pagesize_2k = 1; - this->ecc.layout = &nand_hw_eccoob2k; -#else - host->pagesize_2k = 0; - this->ecc.layout = &nand_hw_eccoob; -#endif - mxc_setup_config1(); return 0; } -- cgit v1.1 From 1884d6577e6b298ab2966d7d8fd7be888c3b7332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:42 +0200 Subject: mxc nand: Let driver detect IP revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no reason to have board configs to select the NFC IP revision. Just let the driver detect it. BTW, remove broken NFC IP revision configs from board config files. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- include/configs/flea3.h | 1 - include/configs/mx35pdk.h | 1 - include/configs/tx25.h | 1 - include/fsl_nfc.h | 8 +++----- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/configs/flea3.h b/include/configs/flea3.h index 4350518..027a5dc 100644 --- a/include/configs/flea3.h +++ b/include/configs/flea3.h @@ -213,7 +213,6 @@ * NAND FLASH driver setup */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (NFC_BASE_ADDR) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (NFC_BASE_ADDR) diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index 9bc6bd4..5816152 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -231,7 +231,6 @@ * NAND FLASH driver setup */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (NFC_BASE_ADDR) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (NFC_BASE_ADDR) diff --git a/include/configs/tx25.h b/include/configs/tx25.h index c8a49bb..71b1d32 100644 --- a/include/configs/tx25.h +++ b/include/configs/tx25.h @@ -107,7 +107,6 @@ /* NAND */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (0xBB000000) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (0xBB000000) diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index c248cef..6618089 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -42,10 +42,12 @@ */ #if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 +#define is_mxc_nfc_11() 0 #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) #define MXC_NFC_V1_1 +#define is_mxc_nfc_11() 1 #else -#warning "MXC NFC version not defined" +#error "MXC NFC implementation not supported" #endif #if defined(MXC_NFC_V1) @@ -53,14 +55,10 @@ #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 #define NAND_MXC_2K_MULTI_CYCLE -#define is_mxc_nfc_11() 0 #elif defined(MXC_NFC_V1_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 -#define is_mxc_nfc_11() 1 -#else -#error "define CONFIG_NAND_MXC_VXXX to use the mxc nand driver" #endif struct fsl_nfc_regs { -- cgit v1.1 From 9c60e75e05dab5a0197728b6a940aaac02762936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:53 +0200 Subject: mxc nand: Homogenize IP revisions with Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the same IP revisions as in Linux in order to make the comparison more clear. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 16 ++++++++-------- include/fsl_nfc.h | 16 +++++++++------- nand_spl/nand_boot_fsl_nfc.c | 4 ++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index e743796..cf2a7b0 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -77,7 +77,7 @@ static struct nand_ecclayout nand_hw_eccoob2k = { .oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} }, }; #endif -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) #ifndef CONFIG_SYS_NAND_LARGEPAGE static struct nand_ecclayout nand_hw_eccoob = { .eccbytes = 9, @@ -213,7 +213,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, if (spare_only) MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only); - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { int i; /* * The controller copies the 64 bytes of spare data from @@ -273,7 +273,7 @@ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { int i; /* @@ -377,7 +377,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) */ } -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) @@ -1061,7 +1061,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_PAGEPROG: send_prog_page(host, 0, host->spare_only); - if (host->pagesize_2k && !is_mxc_nfc_11()) { + if (host->pagesize_2k && is_mxc_nfc_1()) { /* data in 4 areas */ send_prog_page(host, 1, host->spare_only); send_prog_page(host, 2, host->spare_only); @@ -1111,7 +1111,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_cmd(host, NAND_CMD_READSTART); /* read for each AREA */ send_read_page(host, 0, host->spare_only); - if (!is_mxc_nfc_11()) { + if (is_mxc_nfc_1()) { send_read_page(host, 1, host->spare_only); send_read_page(host, 2, host->spare_only); send_read_page(host, 3, host->spare_only); @@ -1200,7 +1200,7 @@ int board_nand_init(struct nand_chip *this) this->ecc.calculate = mxc_nand_calculate_ecc; this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.correct = mxc_nand_correct_data; - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { this->ecc.mode = NAND_ECC_HW_SYNDROME; this->ecc.read_page = mxc_nand_read_page_syndrome; this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome; @@ -1238,7 +1238,7 @@ int board_nand_init(struct nand_chip *this) this->ecc.layout = &nand_hw_eccoob; #endif -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 tmp = readw(&host->regs->config1); tmp |= NFC_ONE_CYCLE; tmp |= NFC_4_8N_ECC; diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 6618089..ff537b4 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -33,7 +33,7 @@ * to support up to 2K byte pagesize nand. * Reading or writing a 2K page requires 4 FDI/FDO cycles. * - * MX25 and MX35 have version 1.1, which has: + * MX25 and MX35 have version 2.1, which has: * 8 512-byte main buffers and * 8 64-byte spare buffers * to support up to 4K byte pagesize nand. @@ -42,10 +42,12 @@ */ #if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 -#define is_mxc_nfc_11() 0 +#define is_mxc_nfc_1() 1 +#define is_mxc_nfc_21() 0 #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) -#define MXC_NFC_V1_1 -#define is_mxc_nfc_11() 1 +#define MXC_NFC_V2_1 +#define is_mxc_nfc_1() 0 +#define is_mxc_nfc_21() 1 #else #error "MXC NFC implementation not supported" #endif @@ -55,7 +57,7 @@ #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 #define NAND_MXC_2K_MULTI_CYCLE -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 @@ -86,7 +88,7 @@ struct fsl_nfc_regs { u16 nf_wrprst; u16 config1; u16 config2; -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) u16 reserved2[2]; u16 buf_addr; u16 flash_addr; @@ -153,7 +155,7 @@ struct fsl_nfc_regs { */ #define NFC_INT 0x8000 -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 #define NFC_4_8N_ECC (1 << 0) #endif #define NFC_SP_EN (1 << 2) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index ea05952..a40c998 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -47,7 +47,7 @@ static void nfc_wait_ready(void) static void nfc_nand_init(void) { -#if defined(MXC_NFC_V1_1) +#if defined(MXC_NFC_V2_1) int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int config1; @@ -142,7 +142,7 @@ static int nfc_nand_check_ecc(void) #if defined(MXC_NFC_V1) u16 ecc_status = readw(&nfc->ecc_status_result); return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2; -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) u32 ecc_status = readl(&nfc->ecc_status_result); int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int err_limit = CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16 ? 8 : 4; -- cgit v1.1