All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 13/13] mxc nand: Add support for i.MX5
Date: Tue, 21 Aug 2012 23:04:14 +0200 (CEST)	[thread overview]
Message-ID: <684093264.2662811.1345583054386.JavaMail.root@advansee.com> (raw)
In-Reply-To: <1297105590.2375011.1344891064392.JavaMail.root@advansee.com>

Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
---
Changes for v2:
 - Fix warning for unused tmp variable in board_nand_init() for NFC V1.

 .../arch/arm/include/asm/arch-mx5/imx-regs.h       |    9 +
 .../drivers/mtd/nand/mxc_nand.c                    |  219 +++++++++++++++-----
 .../include/fsl_nfc.h                              |  149 ++++++++-----
 .../nand_spl/nand_boot_fsl_nfc.c                   |  114 +++++++---
 4 files changed, 365 insertions(+), 126 deletions(-)

diff --git u-boot-imx-88e73dd.orig/arch/arm/include/asm/arch-mx5/imx-regs.h u-boot-imx-88e73dd/arch/arm/include/asm/arch-mx5/imx-regs.h
index c53465f..ca73dea 100644
--- u-boot-imx-88e73dd.orig/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ u-boot-imx-88e73dd/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -232,6 +232,15 @@
 #define CS0_32M_CS1_32M_CS2_32M_CS3_32M		3
 
 /*
+ * SRC register definitions
+ */
+#if defined(CONFIG_MX51)
+#define SRC_SBMR_NF16B		(1 << 2)
+#elif defined(CONFIG_MX53)
+#define SRC_SBMR_NF16B		(1 << 13)
+#endif
+
+/*
  * CSPI register definitions
  */
 #define MXC_ECSPI
diff --git u-boot-imx-88e73dd.orig/drivers/mtd/nand/mxc_nand.c u-boot-imx-88e73dd/drivers/mtd/nand/mxc_nand.c
index cf2a7b0..cead757 100644
--- u-boot-imx-88e73dd.orig/drivers/mtd/nand/mxc_nand.c
+++ u-boot-imx-88e73dd/drivers/mtd/nand/mxc_nand.c
@@ -22,7 +22,8 @@
 #include <nand.h>
 #include <linux/err.h>
 #include <asm/io.h>
-#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35)
+#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) || \
+	defined(CONFIG_MX51) || defined(CONFIG_MX53)
 #include <asm/arch/imx-regs.h>
 #endif
 #include <fsl_nfc.h>
@@ -36,6 +37,9 @@ struct mxc_nand_host {
 	struct nand_chip		*nand;
 
 	struct fsl_nfc_regs __iomem	*regs;
+#ifdef MXC_NFC_V3_2
+	struct fsl_nfc_ip_regs __iomem	*ip_regs;
+#endif
 	int				spare_only;
 	int				status_request;
 	int				pagesize_2k;
@@ -77,7 +81,7 @@ static struct nand_ecclayout nand_hw_eccoob2k = {
 	.oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} },
 };
 #endif
-#elif defined(MXC_NFC_V2_1)
+#elif defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
 #ifndef CONFIG_SYS_NAND_LARGEPAGE
 static struct nand_ecclayout nand_hw_eccoob = {
 	.eccbytes = 9,
@@ -130,6 +134,16 @@ static int is_16bit_nand(void)
 	else
 		return 0;
 }
+#elif defined(CONFIG_MX51) || defined(CONFIG_MX53)
+static int is_16bit_nand(void)
+{
+	struct src *src = (struct src *)SRC_BASE_ADDR;
+
+	if (readl(&src->sbmr) & SRC_SBMR_NF16B)
+		return 1;
+	else
+		return 0;
+}
 #else
 #warning "8/16 bit NAND autodetection not supported"
 static int is_16bit_nand(void)
@@ -150,7 +164,7 @@ static uint32_t *mxc_nand_memcpy32(uint32_t *dest, uint32_t *source, size_t size
 
 /*
  * This function polls the NANDFC to wait for the basic operation to
- * complete by checking the INT bit of config2 register.
+ * complete by checking the INT bit.
  */
 static void wait_op_done(struct mxc_nand_host *host, int max_retries,
 				uint16_t param)
@@ -158,10 +172,17 @@ static void wait_op_done(struct mxc_nand_host *host, int max_retries,
 	uint32_t tmp;
 
 	while (max_retries-- > 0) {
-		if (readw(&host->regs->config2) & NFC_INT) {
-			tmp = readw(&host->regs->config2);
-			tmp  &= ~NFC_INT;
-			writew(tmp, &host->regs->config2);
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+		tmp = readnfc(&host->regs->config2);
+		if (tmp & NFC_V1_V2_CONFIG2_INT) {
+			tmp &= ~NFC_V1_V2_CONFIG2_INT;
+			writenfc(tmp, &host->regs->config2);
+#elif defined(MXC_NFC_V3_2)
+		tmp = readnfc(&host->ip_regs->ipc);
+		if (tmp & NFC_V3_IPC_INT) {
+			tmp &= ~NFC_V3_IPC_INT;
+			writenfc(tmp, &host->ip_regs->ipc);
+#endif
 			break;
 		}
 		udelay(1);
@@ -180,8 +201,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->flash_cmd);
-	writew(NFC_CMD, &host->regs->config2);
+	writenfc(cmd, &host->regs->flash_cmd);
+	writenfc(NFC_CMD, &host->regs->operation);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, cmd);
@@ -196,8 +217,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->flash_addr);
-	writew(NFC_ADDR, &host->regs->config2);
+	writenfc(addr, &host->regs->flash_addr);
+	writenfc(NFC_ADDR, &host->regs->operation);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, addr);
@@ -213,7 +234,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_21()) {
+	if (is_mxc_nfc_21() || is_mxc_nfc_32()) {
 		int i;
 		/*
 		 *  The controller copies the 64 bytes of spare data from
@@ -229,19 +250,26 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
 		}
 	}
 
-	writew(buf_id, &host->regs->buf_addr);
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+	writenfc(buf_id, &host->regs->buf_addr);
+#elif defined(MXC_NFC_V3_2)
+	uint32_t tmp = readnfc(&host->regs->config1);
+	tmp &= ~NFC_V3_CONFIG1_RBA_MASK;
+	tmp |= NFC_V3_CONFIG1_RBA(buf_id);
+	writenfc(tmp, &host->regs->config1);
+#endif
 
 	/* Configure spare or page+spare access */
 	if (!host->pagesize_2k) {
-		uint16_t config1 = readw(&host->regs->config1);
+		uint32_t config1 = readnfc(&host->regs->config1);
 		if (spare_only)
-			config1 |= NFC_SP_EN;
+			config1 |= NFC_CONFIG1_SP_EN;
 		else
-			config1 &= ~NFC_SP_EN;
-		writew(config1, &host->regs->config1);
+			config1 &= ~NFC_CONFIG1_SP_EN;
+		writenfc(config1, &host->regs->config1);
 	}
 
-	writew(NFC_INPUT, &host->regs->config2);
+	writenfc(NFC_INPUT, &host->regs->operation);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, spare_only);
@@ -256,24 +284,31 @@ 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->buf_addr);
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+	writenfc(buf_id, &host->regs->buf_addr);
+#elif defined(MXC_NFC_V3_2)
+	uint32_t tmp = readnfc(&host->regs->config1);
+	tmp &= ~NFC_V3_CONFIG1_RBA_MASK;
+	tmp |= NFC_V3_CONFIG1_RBA(buf_id);
+	writenfc(tmp, &host->regs->config1);
+#endif
 
 	/* Configure spare or page+spare access */
 	if (!host->pagesize_2k) {
-		uint32_t config1 = readw(&host->regs->config1);
+		uint32_t config1 = readnfc(&host->regs->config1);
 		if (spare_only)
-			config1 |= NFC_SP_EN;
+			config1 |= NFC_CONFIG1_SP_EN;
 		else
-			config1 &= ~NFC_SP_EN;
-		writew(config1, &host->regs->config1);
+			config1 &= ~NFC_CONFIG1_SP_EN;
+		writenfc(config1, &host->regs->config1);
 	}
 
-	writew(NFC_OUTPUT, &host->regs->config2);
+	writenfc(NFC_OUTPUT, &host->regs->operation);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, spare_only);
 
-	if (is_mxc_nfc_21()) {
+	if (is_mxc_nfc_21() || is_mxc_nfc_32()) {
 		int i;
 
 		/*
@@ -293,17 +328,23 @@ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
 /* Request the NANDFC to perform a read of the NAND device ID. */
 static void send_read_id(struct mxc_nand_host *host)
 {
-	uint16_t tmp;
+	uint32_t tmp;
 
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 	/* NANDFC buffer 0 is used for device ID output */
-	writew(0x0, &host->regs->buf_addr);
+	writenfc(0x0, &host->regs->buf_addr);
+#elif defined(MXC_NFC_V3_2)
+	tmp = readnfc(&host->regs->config1);
+	tmp &= ~NFC_V3_CONFIG1_RBA_MASK;
+	writenfc(tmp, &host->regs->config1);
+#endif
 
 	/* Read ID into main buffer */
-	tmp = readw(&host->regs->config1);
-	tmp &= ~NFC_SP_EN;
-	writew(tmp, &host->regs->config1);
+	tmp = readnfc(&host->regs->config1);
+	tmp &= ~NFC_CONFIG1_SP_EN;
+	writenfc(tmp, &host->regs->config1);
 
-	writew(NFC_ID, &host->regs->config2);
+	writenfc(NFC_ID, &host->regs->operation);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, 0);
@@ -315,32 +356,40 @@ static void send_read_id(struct mxc_nand_host *host)
  */
 static uint16_t get_dev_status(struct mxc_nand_host *host)
 {
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 	void __iomem *main_buf = host->regs->main_area[1];
 	uint32_t store;
-	uint16_t ret, tmp;
+#endif
+	uint32_t ret, tmp;
 	/* Issue status request to NAND device */
 
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 	/* 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->buf_addr);
+	writenfc(1, &host->regs->buf_addr);
+#endif
 
 	/* Read status into main buffer */
-	tmp = readw(&host->regs->config1);
-	tmp &= ~NFC_SP_EN;
-	writew(tmp, &host->regs->config1);
+	tmp = readnfc(&host->regs->config1);
+	tmp &= ~NFC_CONFIG1_SP_EN;
+	writenfc(tmp, &host->regs->config1);
 
-	writew(NFC_STATUS, &host->regs->config2);
+	writenfc(NFC_STATUS, &host->regs->operation);
 
 	/* Wait for operation to complete */
 	wait_op_done(host, TROP_US_DELAY, 0);
 
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 	/*
 	 *  Status is placed in first word of main buffer
 	 * get status, then recovery area 1 data
 	 */
 	ret = readw(main_buf);
 	writel(store, main_buf);
+#elif defined(MXC_NFC_V3_2)
+	ret = readnfc(&host->regs->config1) >> 16;
+#endif
 
 	return ret;
 }
@@ -359,13 +408,23 @@ 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->config1);
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+	uint16_t tmp = readnfc(&host->regs->config1);
+
+	if (on)
+		tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
+	else
+		tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
+	writenfc(tmp, &host->regs->config1);
+#elif defined(MXC_NFC_V3_2)
+	uint32_t tmp = readnfc(&host->ip_regs->config2);
 
 	if (on)
-		tmp |= NFC_ECC_EN;
+		tmp |= NFC_V3_CONFIG2_ECC_EN;
 	else
-		tmp &= ~NFC_ECC_EN;
-	writew(tmp, &host->regs->config1);
+		tmp &= ~NFC_V3_CONFIG2_ECC_EN;
+	writenfc(tmp, &host->ip_regs->config2);
+#endif
 }
 
 #ifdef CONFIG_MXC_NAND_HWECC
@@ -377,7 +436,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 	 */
 }
 
-#ifdef MXC_NFC_V2_1
+#if defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
 				      struct nand_chip *chip,
 				      int page, int sndcmd)
@@ -698,7 +757,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->ecc_status_result);
+	uint16_t ecc_status = readnfc(&host->regs->ecc_status_result);
 
 	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
 		MTDDEBUG(MTD_DEBUG_LEVEL0,
@@ -1167,7 +1226,9 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 int board_nand_init(struct nand_chip *this)
 {
 	struct mtd_info *mtd;
-	uint16_t tmp;
+#if defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
+	uint32_t tmp;
+#endif
 
 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
 	this->options |= NAND_USE_FLASH_BBT;
@@ -1194,13 +1255,17 @@ int board_nand_init(struct nand_chip *this)
 	this->verify_buf = mxc_nand_verify_buf;
 
 	host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
+#ifdef MXC_NFC_V3_2
+	host->ip_regs =
+		(struct fsl_nfc_ip_regs __iomem *)CONFIG_MXC_NAND_IP_REGS_BASE;
+#endif
 	host->clk_act = 1;
 
 #ifdef CONFIG_MXC_NAND_HWECC
 	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_21()) {
+	if (is_mxc_nfc_21() || is_mxc_nfc_32()) {
 		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,25 +1303,26 @@ int board_nand_init(struct nand_chip *this)
 	this->ecc.layout = &nand_hw_eccoob;
 #endif
 
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 #ifdef MXC_NFC_V2_1
-	tmp = readw(&host->regs->config1);
-	tmp |= NFC_ONE_CYCLE;
-	tmp |= NFC_4_8N_ECC;
-	writew(tmp, &host->regs->config1);
+	tmp = readnfc(&host->regs->config1);
+	tmp |= NFC_V2_CONFIG1_ONE_CYCLE;
+	tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
+	writenfc(tmp, &host->regs->config1);
 	if (host->pagesize_2k)
-		writew(64/2, &host->regs->spare_area_size);
+		writenfc(64/2, &host->regs->spare_area_size);
 	else
-		writew(16/2, &host->regs->spare_area_size);
+		writenfc(16/2, &host->regs->spare_area_size);
 #endif
 
 	/*
 	 * preset operation
 	 * Unlock the internal RAM Buffer
 	 */
-	writew(0x2, &host->regs->config);
+	writenfc(0x2, &host->regs->config);
 
 	/* Blocks to be unlocked */
-	writew(0x0, &host->regs->unlockstart_blkaddr);
+	writenfc(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)
@@ -1268,10 +1334,53 @@ 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->unlockend_blkaddr);
+	writenfc(0xFFFF, &host->regs->unlockend_blkaddr);
 
 	/* Unlock Block Command for given address range */
-	writew(0x4, &host->regs->wrprot);
+	writenfc(0x4, &host->regs->wrprot);
+#elif defined(MXC_NFC_V3_2)
+	writenfc(NFC_V3_CONFIG1_RBA(0), &host->regs->config1);
+	writenfc(NFC_V3_IPC_CREQ, &host->ip_regs->ipc);
+
+	/* Unlock the internal RAM Buffer */
+	writenfc(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK,
+			&host->ip_regs->wrprot);
+
+	/* Blocks to be unlocked */
+	for (tmp = 0; tmp < CONFIG_SYS_NAND_MAX_CHIPS; tmp++)
+		writenfc(0x0 | 0xFFFF << 16,
+				&host->ip_regs->wrprot_unlock_blkaddr[tmp]);
+
+	writenfc(0, &host->ip_regs->ipc);
+
+	tmp = readnfc(&host->ip_regs->config2);
+	tmp &= ~(NFC_V3_CONFIG2_SPAS_MASK | NFC_V3_CONFIG2_EDC_MASK |
+			NFC_V3_CONFIG2_ECC_MODE_8 | NFC_V3_CONFIG2_PS_MASK);
+	tmp |= NFC_V3_CONFIG2_ONE_CYCLE;
+
+	if (host->pagesize_2k) {
+		tmp |= NFC_V3_CONFIG2_SPAS(64/2);
+		tmp |= NFC_V3_CONFIG2_PS_2048;
+	} else {
+		tmp |= NFC_V3_CONFIG2_SPAS(16/2);
+		tmp |= NFC_V3_CONFIG2_PS_512;
+	}
+
+	writenfc(tmp, &host->ip_regs->config2);
+
+	tmp = NFC_V3_CONFIG3_NUM_OF_DEVS(0) |
+			NFC_V3_CONFIG3_NO_SDMA |
+			NFC_V3_CONFIG3_RBB_MODE |
+			NFC_V3_CONFIG3_SBB(6) | /* Reset default */
+			NFC_V3_CONFIG3_ADD_OP(0);
+
+	if (!(this->options & NAND_BUSWIDTH_16))
+		tmp |= NFC_V3_CONFIG3_FW8;
+
+	writenfc(tmp, &host->ip_regs->config3);
+
+	writenfc(0, &host->ip_regs->delay_line);
+#endif
 
 	return 0;
 }
diff --git u-boot-imx-88e73dd.orig/include/fsl_nfc.h u-boot-imx-88e73dd/include/fsl_nfc.h
index ff537b4..48a6448 100644
--- u-boot-imx-88e73dd.orig/include/fsl_nfc.h
+++ u-boot-imx-88e73dd/include/fsl_nfc.h
@@ -33,7 +33,8 @@
  *	to support up to 2K byte pagesize nand.
  *	Reading or writing a 2K page requires 4 FDI/FDO cycles.
  *
- * MX25 and MX35 have version 2.1, which has:
+ * MX25 and MX35 have version 2.1, and MX51 and MX53 have version 3.2, which
+ * have:
  *	8 512-byte main buffers and
  *	8 64-byte spare buffers
  *	to support up to 4K byte pagesize nand.
@@ -44,20 +45,29 @@
 #define MXC_NFC_V1
 #define is_mxc_nfc_1()		1
 #define is_mxc_nfc_21()		0
+#define is_mxc_nfc_32()		0
 #elif defined(CONFIG_MX25) || defined(CONFIG_MX35)
 #define MXC_NFC_V2_1
 #define is_mxc_nfc_1()		0
 #define is_mxc_nfc_21()		1
+#define is_mxc_nfc_32()		0
+#elif defined(CONFIG_MX51) || defined(CONFIG_MX53)
+#define MXC_NFC_V3
+#define MXC_NFC_V3_2
+#define is_mxc_nfc_1()		0
+#define is_mxc_nfc_21()		0
+#define is_mxc_nfc_32()		1
 #else
 #error "MXC NFC implementation not supported"
 #endif
+#define is_mxc_nfc_3()		is_mxc_nfc_32()
 
 #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 NAND_MXC_2K_MULTI_CYCLE
-#elif defined(MXC_NFC_V2_1)
+#elif defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
 #define NAND_MXC_NR_BUFS		8
 #define NAND_MXC_SPARE_BUF_SIZE		64
 #define NAND_MXC_REG_OFFSET		0x1e00
@@ -110,61 +120,106 @@ struct fsl_nfc_regs {
 	u16 unlockend_blkaddr2;
 	u16 unlockstart_blkaddr3;
 	u16 unlockend_blkaddr3;
+#elif defined(MXC_NFC_V3_2)
+	u32 flash_cmd;
+	u32 flash_addr[12];
+	u32 config1;
+	u32 ecc_status_result;
+	u32 status_sum;
+	u32 launch;
 #endif
 };
 
-/*
- * Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register for Command
- * operation
- */
-#define NFC_CMD		0x1
+#ifdef MXC_NFC_V3_2
+struct fsl_nfc_ip_regs {
+	u32 wrprot;
+	u32 wrprot_unlock_blkaddr[8];
+	u32 config2;
+	u32 config3;
+	u32 ipc;
+	u32 err_addr;
+	u32 delay_line;
+};
+#endif
 
-/*
- * Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register for Address
- * operation
- */
-#define NFC_ADDR	0x2
+/* Set FCMD to 1, rest to 0 for Command operation */
+#define NFC_CMD				0x1
 
-/*
- * Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register for Input
- * operation
- */
-#define NFC_INPUT	0x4
+/* Set FADD to 1, rest to 0 for Address operation */
+#define NFC_ADDR			0x2
 
-/*
- * Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register for Data
- * Output operation
- */
-#define NFC_OUTPUT	0x8
+/* Set FDI to 1, rest to 0 for Input operation */
+#define NFC_INPUT			0x4
 
-/*
- * Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register for Read ID
- * operation
- */
-#define NFC_ID		0x10
+/* Set FDO to 001, rest to 0 for Data Output operation */
+#define NFC_OUTPUT			0x8
 
-/*
- * Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register for Read
- * Status operation
- */
-#define NFC_STATUS	0x20
+/* Set FDO to 010, rest to 0 for Read ID operation */
+#define NFC_ID				0x10
 
-/*
- * Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read Status
- * operation
- */
-#define NFC_INT		0x8000
+/* Set FDO to 100, rest to 0 for Read Status operation */
+#define NFC_STATUS			0x20
+
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+#define NFC_CONFIG1_SP_EN		(1 << 2)
+#define NFC_CONFIG1_RST			(1 << 6)
+#define NFC_CONFIG1_CE			(1 << 7)
+#elif defined(MXC_NFC_V3_2)
+#define NFC_CONFIG1_SP_EN		(1 << 0)
+#define NFC_CONFIG1_CE			(1 << 1)
+#define NFC_CONFIG1_RST			(1 << 2)
+#endif
+#define NFC_V1_V2_CONFIG1_ECC_EN	(1 << 3)
+#define NFC_V1_V2_CONFIG1_INT_MSK	(1 << 4)
+#define NFC_V1_V2_CONFIG1_BIG		(1 << 5)
+#define NFC_V2_CONFIG1_ECC_MODE_4	(1 << 0)
+#define NFC_V2_CONFIG1_ONE_CYCLE	(1 << 8)
+#define NFC_V2_CONFIG1_FP_INT		(1 << 11)
+#define NFC_V3_CONFIG1_RBA_MASK		(0x7 << 4)
+#define NFC_V3_CONFIG1_RBA(x)		(((x) & 0x7) << 4)
+
+#define NFC_V1_V2_CONFIG2_INT		(1 << 15)
+#define NFC_V3_CONFIG2_PS_MASK		(0x3 << 0)
+#define NFC_V3_CONFIG2_PS_512		(0 << 0)
+#define NFC_V3_CONFIG2_PS_2048		(1 << 0)
+#define NFC_V3_CONFIG2_PS_4096		(2 << 0)
+#define NFC_V3_CONFIG2_ONE_CYCLE	(1 << 2)
+#define NFC_V3_CONFIG2_ECC_EN		(1 << 3)
+#define NFC_V3_CONFIG2_2CMD_PHASES	(1 << 4)
+#define NFC_V3_CONFIG2_NUM_ADDR_PH0	(1 << 5)
+#define NFC_V3_CONFIG2_ECC_MODE_8	(1 << 6)
+#define NFC_V3_CONFIG2_PPB_MASK		(0x3 << 7)
+#define NFC_V3_CONFIG2_PPB(x)		(((x) & 0x3) << 7)
+#define NFC_V3_CONFIG2_EDC_MASK		(0x7 << 9)
+#define NFC_V3_CONFIG2_EDC(x)		(((x) & 0x7) << 9)
+#define NFC_V3_CONFIG2_NUM_ADDR_PH1(x)	(((x) & 0x3) << 12)
+#define NFC_V3_CONFIG2_INT_MSK		(1 << 15)
+#define NFC_V3_CONFIG2_SPAS_MASK	(0xff << 16)
+#define NFC_V3_CONFIG2_SPAS(x)		(((x) & 0xff) << 16)
+#define NFC_V3_CONFIG2_ST_CMD_MASK	(0xff << 24)
+#define NFC_V3_CONFIG2_ST_CMD(x)	(((x) & 0xff) << 24)
+
+#define NFC_V3_CONFIG3_ADD_OP(x)	(((x) & 0x3) << 0)
+#define NFC_V3_CONFIG3_FW8		(1 << 3)
+#define NFC_V3_CONFIG3_SBB(x)		(((x) & 0x7) << 8)
+#define NFC_V3_CONFIG3_NUM_OF_DEVS(x)	(((x) & 0x7) << 12)
+#define NFC_V3_CONFIG3_RBB_MODE		(1 << 15)
+#define NFC_V3_CONFIG3_NO_SDMA		(1 << 20)
+
+#define NFC_V3_WRPROT_UNLOCK		(1 << 2)
+#define NFC_V3_WRPROT_BLS_UNLOCK	(2 << 6)
+
+#define NFC_V3_IPC_CREQ			(1 << 0)
+#define NFC_V3_IPC_INT			(1 << 31)
 
-#ifdef MXC_NFC_V2_1
-#define NFC_4_8N_ECC	(1 << 0)
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+#define operation	config2
+#define readnfc		readw
+#define writenfc	writew
+#elif defined(MXC_NFC_V3_2)
+#define operation	launch
+#define readnfc		readl
+#define writenfc	writel
 #endif
-#define NFC_SP_EN	(1 << 2)
-#define NFC_ECC_EN	(1 << 3)
-#define NFC_INT_MSK	(1 << 4)
-#define NFC_BIG		(1 << 5)
-#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 u-boot-imx-88e73dd.orig/nand_spl/nand_boot_fsl_nfc.c u-boot-imx-88e73dd/nand_spl/nand_boot_fsl_nfc.c
index a40c998..1096727 100644
--- u-boot-imx-88e73dd.orig/nand_spl/nand_boot_fsl_nfc.c
+++ u-boot-imx-88e73dd/nand_spl/nand_boot_fsl_nfc.c
@@ -30,64 +30,117 @@
 #include <asm/io.h>
 #include <fsl_nfc.h>
 
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 static struct fsl_nfc_regs *const nfc = (void *)NFC_BASE_ADDR;
+#elif defined(MXC_NFC_V3_2)
+static struct fsl_nfc_regs *const nfc = (void *)NFC_BASE_ADDR_AXI;
+static struct fsl_nfc_ip_regs *const nfc_ip = (void *)NFC_BASE_ADDR;
+#endif
 
 static void nfc_wait_ready(void)
 {
 	uint32_t tmp;
 
-	while (!(readw(&nfc->config2) & NFC_INT))
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+	while (!(readnfc(&nfc->config2) & NFC_V1_V2_CONFIG2_INT))
 		;
 
 	/* Reset interrupt flag */
-	tmp = readw(&nfc->config2);
-	tmp &= ~NFC_INT;
-	writew(tmp, &nfc->config2);
+	tmp = readnfc(&nfc->config2);
+	tmp &= ~NFC_V1_V2_CONFIG2_INT;
+	writenfc(tmp, &nfc->config2);
+#elif defined(MXC_NFC_V3_2)
+	while (!(readnfc(&nfc_ip->ipc) & NFC_V3_IPC_INT))
+		;
+
+	/* Reset interrupt flag */
+	tmp = readnfc(&nfc_ip->ipc);
+	tmp &= ~NFC_V3_IPC_INT;
+	writenfc(tmp, &nfc_ip->ipc);
+#endif
 }
 
 static void nfc_nand_init(void)
 {
-#if defined(MXC_NFC_V2_1)
+#if defined(MXC_NFC_V3_2)
+	int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
+	int tmp;
+
+	tmp = (readnfc(&nfc_ip->config2) & ~(NFC_V3_CONFIG2_SPAS_MASK |
+			NFC_V3_CONFIG2_EDC_MASK | NFC_V3_CONFIG2_PS_MASK)) |
+		NFC_V3_CONFIG2_SPAS(CONFIG_SYS_NAND_SPARE_SIZE / 2) |
+		NFC_V3_CONFIG2_INT_MSK | NFC_V3_CONFIG2_ECC_EN |
+		NFC_V3_CONFIG2_ONE_CYCLE;
+	if (CONFIG_SYS_NAND_PAGE_SIZE == 4096)
+		tmp |= NFC_V3_CONFIG2_PS_4096;
+	else if (CONFIG_SYS_NAND_PAGE_SIZE == 2048)
+		tmp |= NFC_V3_CONFIG2_PS_2048;
+	else if (CONFIG_SYS_NAND_PAGE_SIZE == 512)
+		tmp |= NFC_V3_CONFIG2_PS_512;
+	/*
+	 * 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)
+		tmp |= NFC_V3_CONFIG2_ECC_MODE_8;
+	else
+		tmp &= ~NFC_V3_CONFIG2_ECC_MODE_8;
+	writenfc(tmp, &nfc_ip->config2);
+
+	tmp = NFC_V3_CONFIG3_NUM_OF_DEVS(0) |
+			NFC_V3_CONFIG3_NO_SDMA |
+			NFC_V3_CONFIG3_RBB_MODE |
+			NFC_V3_CONFIG3_SBB(6) | /* Reset default */
+			NFC_V3_CONFIG3_ADD_OP(0);
+#ifndef CONFIG_SYS_NAND_BUSWIDTH_16
+	tmp |= NFC_V3_CONFIG3_FW8;
+#endif
+	writenfc(tmp, &nfc_ip->config3);
+
+	writenfc(0, &nfc_ip->delay_line);
+#elif defined(MXC_NFC_V2_1)
 	int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
 	int config1;
 
-	writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size);
+	writenfc(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size);
 
 	/* unlocking RAM Buff */
-	writew(0x2, &nfc->config);
+	writenfc(0x2, &nfc->config);
 
 	/* hardware ECC checking and correct */
-	config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK |
-			NFC_ONE_CYCLE | NFC_FP_INT;
+	config1 = readnfc(&nfc->config1) | NFC_V1_V2_CONFIG1_ECC_EN |
+			NFC_V1_V2_CONFIG1_INT_MSK | NFC_V2_CONFIG1_ONE_CYCLE |
+			NFC_V2_CONFIG1_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)
-		config1 &= ~NFC_4_8N_ECC;
+		config1 &= ~NFC_V2_CONFIG1_ECC_MODE_4;
 	else
-		config1 |= NFC_4_8N_ECC;
-	writew(config1, &nfc->config1);
+		config1 |= NFC_V2_CONFIG1_ECC_MODE_4;
+	writenfc(config1, &nfc->config1);
 #elif defined(MXC_NFC_V1)
 	/* unlocking RAM Buff */
-	writew(0x2, &nfc->config);
+	writenfc(0x2, &nfc->config);
 
 	/* hardware ECC checking and correct */
-	writew(NFC_ECC_EN | NFC_INT_MSK, &nfc->config1);
+	writenfc(NFC_V1_V2_CONFIG1_ECC_EN | NFC_V1_V2_CONFIG1_INT_MSK,
+			&nfc->config1);
 #endif
 }
 
 static void nfc_nand_command(unsigned short command)
 {
-	writew(command, &nfc->flash_cmd);
-	writew(NFC_CMD, &nfc->config2);
+	writenfc(command, &nfc->flash_cmd);
+	writenfc(NFC_CMD, &nfc->operation);
 	nfc_wait_ready();
 }
 
 static void nfc_nand_address(unsigned short address)
 {
-	writew(address, &nfc->flash_addr);
-	writew(NFC_ADDR, &nfc->config2);
+	writenfc(address, &nfc->flash_addr);
+	writenfc(NFC_ADDR, &nfc->operation);
 	nfc_wait_ready();
 }
 
@@ -121,8 +174,14 @@ static void nfc_nand_data_output(void)
 	int i;
 #endif
 
-	writew(0, &nfc->buf_addr);
-	writew(NFC_OUTPUT, &nfc->config2);
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+	writenfc(0, &nfc->buf_addr);
+#elif defined(MXC_NFC_V3_2)
+	int config1 = readnfc(&nfc->config1);
+	config1 &= ~NFC_V3_CONFIG1_RBA_MASK;
+	writenfc(config1, &nfc->config1);
+#endif
+	writenfc(NFC_OUTPUT, &nfc->operation);
 	nfc_wait_ready();
 #ifdef NAND_MXC_2K_MULTI_CYCLE
 	/*
@@ -130,8 +189,8 @@ static void nfc_nand_data_output(void)
 	 * for pages larger than 512 bytes.
 	 */
 	for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) {
-		writew(i, &nfc->buf_addr);
-		writew(NFC_OUTPUT, &nfc->config2);
+		writenfc(i, &nfc->buf_addr);
+		writenfc(NFC_OUTPUT, &nfc->operation);
 		nfc_wait_ready();
 	}
 #endif
@@ -142,7 +201,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_V2_1)
+#elif defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
 	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;
@@ -160,7 +219,14 @@ static int nfc_nand_check_ecc(void)
 
 static void nfc_nand_read_page(unsigned int page_address)
 {
-	writew(0, &nfc->buf_addr); /* read in first 0 buffer */
+	/* read in first 0 buffer */
+#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
+	writenfc(0, &nfc->buf_addr);
+#elif defined(MXC_NFC_V3_2)
+	int config1 = readnfc(&nfc->config1);
+	config1 &= ~NFC_V3_CONFIG1_RBA_MASK;
+	writenfc(config1, &nfc->config1);
+#endif
 	nfc_nand_command(NAND_CMD_READ0);
 	nfc_nand_page_address(page_address);
 

  parent reply	other threads:[~2012-08-21 21:04 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-13 20:47 [U-Boot] [PATCH 00/13] mxc nand: Add support for i.MX5 Benoît Thébaudeau
2012-08-13 20:48 ` [U-Boot] [PATCH 01/13] mxc nand: Merge mtd and spl register definitions Benoît Thébaudeau
2012-08-14  8:37   ` Stefano Babic
2012-08-14 10:15     ` Benoît Thébaudeau
2012-08-14 10:46       ` Stefano Babic
2012-08-14 11:13         ` Benoît Thébaudeau
2012-08-14 14:02           ` Stefano Babic
2012-08-14 14:29             ` Benoît Thébaudeau
2012-08-15 18:11               ` Benoît Thébaudeau
2012-08-16  7:27                 ` Stefano Babic
2012-08-14 16:01     ` Scott Wood
2012-08-13 20:48 ` [U-Boot] [PATCH 02/13] mxc nand: cosmectic: Light cleanup Benoît Thébaudeau
2012-08-14  8:41   ` Stefano Babic
2012-08-13 20:48 ` [U-Boot] [PATCH 03/13] spl mxc nand: Merge duplicated code Benoît Thébaudeau
2012-08-14  9:25   ` Stefano Babic
2012-08-13 20:49 ` [U-Boot] [PATCH 04/13] spl mxc nand: Remove " Benoît Thébaudeau
2012-08-13 20:49 ` [U-Boot] [PATCH 05/13] spl mxc nand: Set symmetric mode Benoît Thébaudeau
2012-08-13 20:49 ` [U-Boot] [PATCH 06/13] mxc nand: Access all ecc_status_result fields Benoît Thébaudeau
2012-09-18  0:39   ` Scott Wood
2012-09-18  0:50     ` Scott Wood
2012-08-13 20:49 ` [U-Boot] [PATCH 07/13] spl mxc nand: Fix broken boot for correctable ECC errors Benoît Thébaudeau
2012-08-13 20:50 ` [U-Boot] [PATCH 08/13] mtd mxc nand: Use _mxc_nand_enable_hwecc() Benoît Thébaudeau
2012-08-14  8:50   ` Stefano Babic
2012-08-14 10:04     ` Benoît Thébaudeau
2012-08-13 20:50 ` [U-Boot] [PATCH 09/13] mtd mxc nand: Fix ECC state after read_page_raw_syndrome() Benoît Thébaudeau
2012-08-13 20:50 ` [U-Boot] [PATCH 10/13] mtd mxc nand: Merge init functions Benoît Thébaudeau
2012-08-13 20:50 ` [U-Boot] [PATCH 11/13] mxc nand: Let driver detect IP revision Benoît Thébaudeau
2012-08-14  9:28   ` Stefano Babic
2012-08-13 20:50 ` [U-Boot] [PATCH 12/13] mxc nand: Homogenize IP revisions with Linux Benoît Thébaudeau
2012-08-13 20:51 ` [U-Boot] [PATCH 13/13] mxc nand: Add support for i.MX5 Benoît Thébaudeau
2012-08-13 21:04   ` Troy Kisky
2012-08-13 21:06     ` Troy Kisky
2012-08-21 21:04   ` Benoît Thébaudeau [this message]
2012-08-21 21:21     ` [U-Boot] [PATCH v2 " Scott Wood
2012-09-18  0:36     ` Scott Wood
2012-09-18 18:11       ` Tom Rini
2012-11-15 22:22         ` Scott Wood
2012-11-16 20:15           ` Benoît Thébaudeau
2012-11-16 20:18             ` Scott Wood
2012-11-16 20:19               ` Scott Wood
2012-11-16 20:28             ` Benoît Thébaudeau
2012-11-17  0:01               ` Scott Wood
2012-11-17  1:43                 ` Benoît Thébaudeau
2012-11-20 23:03                   ` Scott Wood
2012-11-20 23:31                     ` Benoît Thébaudeau
2012-11-17 18:37             ` Fabio Estevam
2012-11-20 20:33               ` Matt Sealey
2012-09-18  1:01     ` Scott Wood
2012-09-18 10:18       ` Benoît Thébaudeau
2012-09-18  1:19 ` [U-Boot] [PATCH 00/13] " Scott Wood
2013-01-07 13:02 ` Marek Vasut
2013-01-07 13:37   ` Benoît Thébaudeau
2013-01-07 13:47     ` Marek Vasut
2013-01-08  0:49       ` Scott Wood
2013-01-08  6:59         ` Marek Vasut
2013-01-07 14:36     ` Fabio Estevam
2013-01-07 15:08       ` Marek Vasut
2013-01-07 15:30         ` Benoît Thébaudeau
2013-01-07 15:33           ` Marek Vasut
2013-01-07 16:42           ` Marek Vasut
2013-01-07 16:55             ` Benoît Thébaudeau
2013-01-08  7:15               ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=684093264.2662811.1345583054386.JavaMail.root@advansee.com \
    --to=benoit.thebaudeau@advansee.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.