summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/fsl_upm.c
diff options
context:
space:
mode:
authorWolfgang Grandegger <wg@grandegger.com>2009-02-11 18:38:23 +0100
committerScott Wood <scottwood@freescale.com>2009-03-23 15:53:40 -0500
commit33846df28fa1f4cf96a96c18142d48d813caa892 (patch)
tree12db31d9d2321af9c1a4e728eb070d4b4c372e1c /drivers/mtd/nand/fsl_upm.c
parent06e9f7df054d26d7f49c56bf9a6844b193ad6313 (diff)
downloadu-boot-imx-33846df28fa1f4cf96a96c18142d48d813caa892.zip
u-boot-imx-33846df28fa1f4cf96a96c18142d48d813caa892.tar.gz
u-boot-imx-33846df28fa1f4cf96a96c18142d48d813caa892.tar.bz2
Add wait flags to support board/chip specific delays
The NAND flash on the TQM8548_BE modules requires a short delay after running the UPM pattern like the MPC8360ERDK board does. The TQM8548_BE requires a further short delay after writing out a buffer. Normally the R/B pin should be checked, but it's not connected on the TQM8548_BE. The corresponding Linux FSL UPM driver uses similar delay points at the same locations. To manage these extra delays in a more general way, I introduced the "wait_flags" field allowing the board-specific driver to specify various types of extra delay. Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers/mtd/nand/fsl_upm.c')
-rw-r--r--drivers/mtd/nand/fsl_upm.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index e7e746b..7cb99cb 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -48,6 +48,20 @@ static void fsl_upm_run_pattern(struct fsl_upm *upm, int width,
}
}
+static void fun_wait(struct fsl_upm_nand *fun)
+{
+ if (fun->dev_ready) {
+ while (!fun->dev_ready(fun->chip_nr))
+ debug("unexpected busy state\n");
+ } else {
+ /*
+ * If the R/B pin is not connected, like on the TQM8548,
+ * a short delay is necessary.
+ */
+ udelay(1);
+ }
+}
+
#if CONFIG_SYS_NAND_MAX_CHIPS > 1
static void fun_select_chip(struct mtd_info *mtd, int chip_nr)
{
@@ -99,15 +113,13 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
fsl_upm_run_pattern(&fun->upm, fun->width, io_addr, mar);
/*
- * Some boards/chips needs this. At least on MPC8360E-RDK we
- * need it. Probably weird chip, because I don't see any need
- * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are
- * 0-2 unexpected busy states per block read.
+ * Some boards/chips needs this. At least the MPC8360E-RDK and
+ * TQM8548 need it. Probably weird chip, because I don't see
+ * any need for this on MPC8555E + Samsung K9F1G08U0A. Usually
+ * here are 0-2 unexpected busy states per block read.
*/
- if (fun->wait_pattern) {
- while (!fun->dev_ready(fun->chip_nr))
- debug("unexpected busy state\n");
- }
+ if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+ fun_wait(fun);
}
static u8 nand_read_byte(struct mtd_info *mtd)
@@ -121,9 +133,16 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
int i;
struct nand_chip *chip = mtd->priv;
+ struct fsl_upm_nand *fun = chip->priv;
- for (i = 0; i < len; i++)
+ for (i = 0; i < len; i++) {
out_8(chip->IO_ADDR_W, buf[i]);
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+ fun_wait(fun);
+ }
+
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+ fun_wait(fun);
}
static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)