[U-Boot] [PATCH v5 2/5] mtd: nand: force NAND_CMD_READID onto 8-bit bus

Pekon Gupta pekon at ti.com
Mon May 5 21:16:17 CEST 2014


From: Brian Norris <computersforpeace at gmail.com>

As per following Sections in ONFI Spec, NAND_CMD_READID should use only
lower 8-bit for transfering command, address and data even on x16 NAND device.

*Section: Target Initialization"
"The Read ID and Read Parameter Page commands only use the lower 8-bits of the
 data bus. The host shall not issue commands that use a word data width on x16
 devices until the host determines the device supports a 16-bit data bus width
 in the parameter page."

*Section: Bus Width Requirements*
"When the host supports a 16-bit bus width, only data is transferred at the
 16-bit width. All address and command line transfers shall use only the lower
 8-bits of the data bus. During command transfers, the host may place any value
 on the upper 8-bits of the data bus. During address transfers, the host shall
 set the upper 8-bits of the data bus to 00h."

Thus porting  following commit from linux-kernel to ensure that column address
is not altered to align to x16 bus when issuing NAND_CMD_READID command.

    commit 3dad2344e92c6e1aeae42df1c4824f307c51bcc7
    mtd: nand: force NAND_CMD_READID onto 8-bit bus
    Author: Brian Norris <computersforpeace at gmail.com> (preserving authorship)

    The NAND command helpers tend to automatically shift the column address
    for x16 bus devices, since most commands expect a word address, not a
    byte address. The Read ID command, however, expects an 8-bit address
    (i.e., 0x00, 0x20, or 0x40 should not be translated to 0x00, 0x10, or
    0x20).

    This fixes the column address for a few drivers which imitate the
    nand_base defaults.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/am335x_spl_bch.c  |  2 +-
 drivers/mtd/nand/atmel_nand.c      |  2 +-
 drivers/mtd/nand/nand_base.c       |  6 ++++--
 drivers/mtd/nand/nand_spl_simple.c |  2 +-
 include/linux/mtd/nand.h           | 10 ++++++++++
 5 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
index c84851b..86572a2 100644
--- a/drivers/mtd/nand/am335x_spl_bch.c
+++ b/drivers/mtd/nand/am335x_spl_bch.c
@@ -55,7 +55,7 @@ static int nand_command(int block, int page, uint32_t offs,
 	}
 
 	/* Shift the offset from byte addressing to word addressing. */
-	if (this->options & NAND_BUSWIDTH_16)
+	if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
 		offs >>= 1;
 
 	/* Set ALE and clear CLE to start address cycle */
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index e1fc48f..e73834d 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -1195,7 +1195,7 @@ static int nand_command(int block, int page, uint32_t offs, u8 cmd)
 
 	hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
 
-	if (this->options & NAND_BUSWIDTH_16)
+	if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
 		offs >>= 1;
 
 	hwctrl(&mtd, offs & 0xff, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5d3232c..376976d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -575,7 +575,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 	/* Serially input address */
 	if (column != -1) {
 		/* Adjust columns for 16 bit buswidth */
-		if (chip->options & NAND_BUSWIDTH_16)
+		if ((chip->options & NAND_BUSWIDTH_16) &&
+				!nand_opcode_8bits(command))
 			column >>= 1;
 		chip->cmd_ctrl(mtd, column, ctrl);
 		ctrl &= ~NAND_CTRL_CHANGE;
@@ -668,7 +669,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
 		/* Serially input address */
 		if (column != -1) {
 			/* Adjust columns for 16 bit buswidth */
-			if (chip->options & NAND_BUSWIDTH_16)
+			if ((chip->options & NAND_BUSWIDTH_16) &&
+					!nand_opcode_8bits(command))
 				column >>= 1;
 			chip->cmd_ctrl(mtd, column, ctrl);
 			ctrl &= ~NAND_CTRL_CHANGE;
diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c
index cead4b5..700ca32 100644
--- a/drivers/mtd/nand/nand_spl_simple.c
+++ b/drivers/mtd/nand/nand_spl_simple.c
@@ -78,7 +78,7 @@ static int nand_command(int block, int page, uint32_t offs,
 	}
 
 	/* Shift the offset from byte addressing to word addressing. */
-	if (this->options & NAND_BUSWIDTH_16)
+	if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
 		offs >>= 1;
 
 	/* Begin command latch cycle */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 0546565..4be8858 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -719,4 +719,14 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
 }
 #endif
 
+/**
+ * Check if the opcode's address should be sent only on the lower 8 bits
+ * @command: opcode to check
+ */
+static inline int nand_opcode_8bits(unsigned int command)
+{
+	return command == NAND_CMD_READID;
+}
+
+
 #endif /* __LINUX_MTD_NAND_H */
-- 
1.8.5.1.163.gd7aced9



More information about the U-Boot mailing list