diff options
author | Wolfgang Grandegger <wg@grandegger.com> | 2009-02-11 18:38:23 +0100 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2009-03-23 15:53:40 -0500 |
commit | 33846df28fa1f4cf96a96c18142d48d813caa892 (patch) | |
tree | 12db31d9d2321af9c1a4e728eb070d4b4c372e1c | |
parent | 06e9f7df054d26d7f49c56bf9a6844b193ad6313 (diff) | |
download | u-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>
-rw-r--r-- | board/freescale/mpc8360erdk/nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_upm.c | 37 | ||||
-rw-r--r-- | include/linux/mtd/fsl_upm.h | 6 |
3 files changed, 34 insertions, 11 deletions
diff --git a/board/freescale/mpc8360erdk/nand.c b/board/freescale/mpc8360erdk/nand.c index aa43350..9ffffb4 100644 --- a/board/freescale/mpc8360erdk/nand.c +++ b/board/freescale/mpc8360erdk/nand.c @@ -76,7 +76,7 @@ static struct fsl_upm_nand fun = { .upm_cmd_offset = 8, .upm_addr_offset = 16, .dev_ready = dev_ready, - .wait_pattern = 1, + .wait_flags = FSL_UPM_WAIT_RUN_PATTERN, .chip_delay = 50, }; 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) diff --git a/include/linux/mtd/fsl_upm.h b/include/linux/mtd/fsl_upm.h index 10f5ddd..5d7156f 100644 --- a/include/linux/mtd/fsl_upm.h +++ b/include/linux/mtd/fsl_upm.h @@ -15,6 +15,10 @@ #include <linux/mtd/nand.h> +#define FSL_UPM_WAIT_RUN_PATTERN 0x1 +#define FSL_UPM_WAIT_WRITE_BYTE 0x2 +#define FSL_UPM_WAIT_WRITE_BUFFER 0x4 + struct fsl_upm { void __iomem *mdr; void __iomem *mxmr; @@ -29,7 +33,7 @@ struct fsl_upm_nand { int upm_cmd_offset; int upm_addr_offset; int upm_mar_chip_offset; - int wait_pattern; + int wait_flags; int (*dev_ready)(int chip_nr); int chip_delay; int chip_offset; |