Patchwork [U-Boot,v2,1/4] mtd: nand: add NAND_BUSWIDTH_AUTO to autodetect bus width

login
register
mail settings
Submitter pekon gupta
Date Sept. 30, 2013, 6:22 p.m.
Message ID <1380565372-4312-2-git-send-email-pekon@ti.com>
Download mbox | patch
Permalink /patch/279210/
State Changes Requested
Delegated to: Scott Wood
Headers show

Comments

pekon gupta - Sept. 30, 2013, 6:22 p.m.
From: Matthieu CASTET <matthieu.castet@parrot.com>

This patch is modified version from following linux patch
http://lists.infradead.org/pipermail/linux-mtd/2012-November/044803.html
So retaining the authorship to Matthieu CASTET <matthieu.castet@parrot.com>

*Modifications from original patch*
(1) use CONFIG_SYS_NAND_ONFI_DETECTION instead of (chip->options & NAND_BUSWIDTH_AUTO)
(2) allow re-assigning of callbacks in nand_set_defaults() depending on bus-width

*Original patch message*
The driver call nand_scan_ident in 8 bit mode, then
readid or onfi detection are done (and detect bus width).
The driver should update its bus width before calling nand_scan_tail.

This work because readid and onfi are read work 8 byte mode.

Note that nand_scan_ident send command (NAND_CMD_RESET, NAND_CMD_READID, NAND_CMD_PARAM), address and read data
The ONFI specificication is not very clear for x16 device if high byte of address should be driven to 0,
but according to [1] it should be ok to not drive it during autodetection.

[1]
3.3.2. 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.

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/nand/nand_base.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
Scott Wood - Oct. 8, 2013, 9:08 p.m.
On Mon, 2013-09-30 at 23:52 +0530, Pekon Gupta wrote:
> From: Matthieu CASTET <matthieu.castet@parrot.com>
> 
> This patch is modified version from following linux patch
> http://lists.infradead.org/pipermail/linux-mtd/2012-November/044803.html
> So retaining the authorship to Matthieu CASTET <matthieu.castet@parrot.com>
> 
> *Modifications from original patch*
> (1) use CONFIG_SYS_NAND_ONFI_DETECTION instead of (chip->options & NAND_BUSWIDTH_AUTO)
> (2) allow re-assigning of callbacks in nand_set_defaults() depending on bus-width
> 
> *Original patch message*
> The driver call nand_scan_ident in 8 bit mode, then
> readid or onfi detection are done (and detect bus width).
> The driver should update its bus width before calling nand_scan_tail.
> 
> This work because readid and onfi are read work 8 byte mode.
> 
> Note that nand_scan_ident send command (NAND_CMD_RESET, NAND_CMD_READID, NAND_CMD_PARAM), address and read data
> The ONFI specificication is not very clear for x16 device if high byte of address should be driven to 0,
> but according to [1] it should be ok to not drive it during autodetection.
> 
> [1]
> 3.3.2. 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.
> 
> Signed-off-by: Pekon Gupta <pekon@ti.com>
> ---
>  drivers/mtd/nand/nand_base.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 9e05cef..4ef0edb 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2514,7 +2514,7 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
>  
>  	if (!chip->select_chip)
>  		chip->select_chip = nand_select_chip;
> -	if (!chip->read_byte)
> +	if ((!chip->read_byte) || (chip->read_byte == nand_read_byte))
>  		chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;

Unnecessary parens (and doesn't match equivalent Linux code).

This change corresponds to Linux commit
68e8078072e802e77134664f11d2ffbfbd2f8fbe.

-Scott
Scott Wood - Oct. 8, 2013, 9:26 p.m.
On Mon, 2013-09-30 at 23:52 +0530, Pekon Gupta wrote:
> @@ -2575,6 +2575,10 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
>  	int i;
>  	int val;
>  
> +	if (chip->options & NAND_BUSWIDTH_16) {
> +		printf("nand: error: ONFI detection works only in x8 mode\n");
> +		return 0;
> +	}

This should just fail silently, as I may be trying to probe a non-ONFI
16-bit chip (but don't want to disable ONFI support at compile time).

-Scott

Patch

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 9e05cef..4ef0edb 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2514,7 +2514,7 @@  static void nand_set_defaults(struct nand_chip *chip, int busw)
 
 	if (!chip->select_chip)
 		chip->select_chip = nand_select_chip;
-	if (!chip->read_byte)
+	if ((!chip->read_byte) || (chip->read_byte == nand_read_byte))
 		chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
 	if (!chip->read_word)
 		chip->read_word = nand_read_word;
@@ -2522,11 +2522,11 @@  static void nand_set_defaults(struct nand_chip *chip, int busw)
 		chip->block_bad = nand_block_bad;
 	if (!chip->block_markbad)
 		chip->block_markbad = nand_default_block_markbad;
-	if (!chip->write_buf)
+	if ((!chip->write_buf) || (chip->write_buf == nand_write_buf))
 		chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
-	if (!chip->read_buf)
+	if ((!chip->read_buf) || (chip->read_buf == nand_read_buf))
 		chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
-	if (!chip->verify_buf)
+	if ((!chip->verify_buf) || (chip->verify_buf == nand_verify_buf))
 		chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
 	if (!chip->scan_bbt)
 		chip->scan_bbt = nand_default_bbt;
@@ -2575,6 +2575,10 @@  static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 	int i;
 	int val;
 
+	if (chip->options & NAND_BUSWIDTH_16) {
+		printf("nand: error: ONFI detection works only in x8 mode\n");
+		return 0;
+	}
 	/* Try ONFI for unknown chip or LP */
 	chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
 	if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
@@ -2976,6 +2980,14 @@  ident_done:
 		if (nand_manuf_ids[maf_idx].id == *maf_id)
 			break;
 	}
+#if defined(CONFIG_SYS_NAND_ONFI_DETECTION)
+	if (chip->options & NAND_BUSWIDTH_16) {
+		return ERR_PTR(-EINVAL);
+	} else {
+		chip->options |= busw;
+		nand_set_defaults(chip, busw);
+	}
+#endif
 
 	/*
 	 * Check, if buswidth is correct. Hardware drivers should set