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>
This commit is contained in:
parent
06e9f7df05
commit
33846df28f
@ -76,7 +76,7 @@ static struct fsl_upm_nand fun = {
|
|||||||
.upm_cmd_offset = 8,
|
.upm_cmd_offset = 8,
|
||||||
.upm_addr_offset = 16,
|
.upm_addr_offset = 16,
|
||||||
.dev_ready = dev_ready,
|
.dev_ready = dev_ready,
|
||||||
.wait_pattern = 1,
|
.wait_flags = FSL_UPM_WAIT_RUN_PATTERN,
|
||||||
.chip_delay = 50,
|
.chip_delay = 50,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
#if CONFIG_SYS_NAND_MAX_CHIPS > 1
|
||||||
static void fun_select_chip(struct mtd_info *mtd, int chip_nr)
|
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);
|
fsl_upm_run_pattern(&fun->upm, fun->width, io_addr, mar);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some boards/chips needs this. At least on MPC8360E-RDK we
|
* Some boards/chips needs this. At least the MPC8360E-RDK and
|
||||||
* need it. Probably weird chip, because I don't see any need
|
* TQM8548 need it. Probably weird chip, because I don't see
|
||||||
* for this on MPC8555E + Samsung K9F1G08U0A. Usually here are
|
* any need for this on MPC8555E + Samsung K9F1G08U0A. Usually
|
||||||
* 0-2 unexpected busy states per block read.
|
* here are 0-2 unexpected busy states per block read.
|
||||||
*/
|
*/
|
||||||
if (fun->wait_pattern) {
|
if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
|
||||||
while (!fun->dev_ready(fun->chip_nr))
|
fun_wait(fun);
|
||||||
debug("unexpected busy state\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 nand_read_byte(struct mtd_info *mtd)
|
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;
|
int i;
|
||||||
struct nand_chip *chip = mtd->priv;
|
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]);
|
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)
|
static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
#include <linux/mtd/nand.h>
|
#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 {
|
struct fsl_upm {
|
||||||
void __iomem *mdr;
|
void __iomem *mdr;
|
||||||
void __iomem *mxmr;
|
void __iomem *mxmr;
|
||||||
@ -29,7 +33,7 @@ struct fsl_upm_nand {
|
|||||||
int upm_cmd_offset;
|
int upm_cmd_offset;
|
||||||
int upm_addr_offset;
|
int upm_addr_offset;
|
||||||
int upm_mar_chip_offset;
|
int upm_mar_chip_offset;
|
||||||
int wait_pattern;
|
int wait_flags;
|
||||||
int (*dev_ready)(int chip_nr);
|
int (*dev_ready)(int chip_nr);
|
||||||
int chip_delay;
|
int chip_delay;
|
||||||
int chip_offset;
|
int chip_offset;
|
||||||
|
Loading…
Reference in New Issue
Block a user