mtd: nand: Wait tCCS after a column change

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Dec 16 11:59:03 PST 2016


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=6ea40a3ba93e1b14ffb349e276f9dfefc4334b99
Commit:     6ea40a3ba93e1b14ffb349e276f9dfefc4334b99
Parent:     204e7ecd47e26cc12d9e8e8a7e7a2eeb9573f0ba
Author:     Boris Brezillon <boris.brezillon at free-electrons.com>
AuthorDate: Sat Oct 1 10:24:03 2016 +0200
Committer:  Boris Brezillon <boris.brezillon at free-electrons.com>
CommitDate: Mon Nov 7 14:48:37 2016 +0100

    mtd: nand: Wait tCCS after a column change
    
    Drivers implementing ->cmd_ctrl() and relying on the default ->cmdfunc()
    implementation usually don't wait tCCS when a column change (RNDIN or
    RNDOUT) is requested.
    Add an option flag to ask the core to do so (note that we keep this as
    an opt-in to avoid breaking existing implementations), and make use of
    the ->data_interface information is available (otherwise, wait 500ns).
    
    Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
    Tested-by: Marc Gonzalez <marc_gonzalez at sigmadesigns.com>
---
 drivers/mtd/nand/nand_base.c | 26 +++++++++++++++++++++++++-
 include/linux/mtd/nand.h     | 10 ++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e5718e5..0acb007 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -709,6 +709,25 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 	nand_wait_ready(mtd);
 }
 
+static void nand_ccs_delay(struct nand_chip *chip)
+{
+	/*
+	 * The controller already takes care of waiting for tCCS when the RNDIN
+	 * or RNDOUT command is sent, return directly.
+	 */
+	if (!(chip->options & NAND_WAIT_TCCS))
+		return;
+
+	/*
+	 * Wait tCCS_min if it is correctly defined, otherwise wait 500ns
+	 * (which should be safe for all NANDs).
+	 */
+	if (chip->data_interface && chip->data_interface->timings.sdr.tCCS_min)
+		ndelay(chip->data_interface->timings.sdr.tCCS_min / 1000);
+	else
+		ndelay(500);
+}
+
 /**
  * nand_command_lp - [DEFAULT] Send command to NAND large page device
  * @mtd: MTD device structure
@@ -773,10 +792,13 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
 	case NAND_CMD_ERASE1:
 	case NAND_CMD_ERASE2:
 	case NAND_CMD_SEQIN:
-	case NAND_CMD_RNDIN:
 	case NAND_CMD_STATUS:
 		return;
 
+	case NAND_CMD_RNDIN:
+		nand_ccs_delay(chip);
+		return;
+
 	case NAND_CMD_RESET:
 		if (chip->dev_ready)
 			break;
@@ -795,6 +817,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
 			       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
 		chip->cmd_ctrl(mtd, NAND_CMD_NONE,
 			       NAND_NCE | NAND_CTRL_CHANGE);
+
+		nand_ccs_delay(chip);
 		return;
 
 	case NAND_CMD_READ0:
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 6fe83bc..970ceb9 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -210,6 +210,16 @@ enum nand_ecc_algo {
  */
 #define NAND_USE_BOUNCE_BUFFER	0x00100000
 
+/*
+ * In case your controller is implementing ->cmd_ctrl() and is relying on the
+ * default ->cmdfunc() implementation, you may want to let the core handle the
+ * tCCS delay which is required when a column change (RNDIN or RNDOUT) is
+ * requested.
+ * If your controller already takes care of this delay, you don't need to set
+ * this flag.
+ */
+#define NAND_WAIT_TCCS		0x00200000
+
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
 #define NAND_CONTROLLER_ALLOC	0x80000000



More information about the linux-mtd-cvs mailing list