summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-08-02 12:01:05 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-08-03 19:32:07 +0200
commit85f4fe32cfccf06223d55dc5751e0c644b119a9b (patch)
tree29ab6438c1717768c2a4a9d3ef3cf255f5e1a9ab /drivers/mtd
parent5a693051df54d9c690d141095089449346e748e5 (diff)
downloadbarebox-85f4fe32cfccf06223d55dc5751e0c644b119a9b.tar.gz
barebox-85f4fe32cfccf06223d55dc5751e0c644b119a9b.tar.xz
mtd nand: implement buswidth detection
This introduces a new NAND_BUSWIDTH_AUTO flag which can be used to automatically detect the nand buswidth. The id is always read in 8bit mode. An additional callback is needed to switch the nand controller into 16bit mode. This currently depends on a safe read_byte (always) and read_buf (for onfi-only flashes) callback. It has been tested on OMAP, but is not something that generally works. For this reason the existence of the set_buswidth callback is used to determine whether we are able to do autodetection or not. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/nand_base.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index a5bf757e47..37e57b32ce 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1000,7 +1000,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;
@@ -1009,12 +1009,12 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
#ifdef CONFIG_MTD_WRITE
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;
#endif
- 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;
#ifdef CONFIG_NAND_BBT
if (!chip->scan_bbt)
@@ -1258,6 +1258,13 @@ ident_done:
break;
}
+ if (chip->options & NAND_BUSWIDTH_AUTO) {
+ chip->options |= busw;
+ nand_set_defaults(chip, busw);
+ if (chip->set_buswidth)
+ chip->set_buswidth(mtd, chip, busw);
+ }
+
/*
* Check, if buswidth is correct. Hardware drivers should set
* chip correct !
@@ -1326,6 +1333,11 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
struct nand_chip *chip = mtd->priv;
struct nand_flash_dev *type;
+ if (chip->options & NAND_BUSWIDTH_AUTO && !chip->set_buswidth) {
+ printk(KERN_ERR "buswidth detection but no buswidth callback\n");
+ return -EINVAL;
+ }
+
/* Get buswidth to select the correct functions */
busw = chip->options & NAND_BUSWIDTH_16;
/* Set the default functions */