aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-05-02 07:26:37 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-05-02 07:26:37 -0400
commit048c37b4907ecf0e55100365e20758667f0bd27d (patch)
tree19ed5e6fb007cb94b58377408eb4fdd24b1dc4f0
parent14448005abd10887a2d361e20e04760dc3d8482f (diff)
[MTD] [NAND] Support multiple chips in CAFÉ driver
The CAFÉ can handle two chip on separate chipselect lines. Hook up the undocumented chipselect bits in the driver and probe both. In the case of OLPC, it's not actually two separate devices -- it's a single '1GiB' package with two 512MiB dies internally. So clear the NAND_BBT_PERCHIP flag to treat it as a single chip for BBT purposes, and make life easier for the firmware. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r--drivers/mtd/nand/cafe_nand.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 05f6ec9f5aa7..cff969d05d4a 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -47,6 +47,9 @@
47#define CAFE_GLOBAL_IRQ_MASK 0x300c 47#define CAFE_GLOBAL_IRQ_MASK 0x300c
48#define CAFE_NAND_RESET 0x3034 48#define CAFE_NAND_RESET 0x3034
49 49
50/* Missing from the datasheet: bit 19 of CTRL1 sets CE0 vs. CE1 */
51#define CTRL1_CHIPSELECT (1<<19)
52
50struct cafe_priv { 53struct cafe_priv {
51 struct nand_chip nand; 54 struct nand_chip nand;
52 struct pci_dev *pdev; 55 struct pci_dev *pdev;
@@ -194,8 +197,8 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
194 197
195 cafe->data_pos = cafe->datalen = 0; 198 cafe->data_pos = cafe->datalen = 0;
196 199
197 /* Set command valid bit */ 200 /* Set command valid bit, mask in the chip select bit */
198 ctl1 = 0x80000000 | command; 201 ctl1 = 0x80000000 | command | (cafe->ctl1 & CTRL1_CHIPSELECT);
199 202
200 /* Set RD or WR bits as appropriate */ 203 /* Set RD or WR bits as appropriate */
201 if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) { 204 if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) {
@@ -308,8 +311,16 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
308 311
309static void cafe_select_chip(struct mtd_info *mtd, int chipnr) 312static void cafe_select_chip(struct mtd_info *mtd, int chipnr)
310{ 313{
311 //struct cafe_priv *cafe = mtd->priv; 314 struct cafe_priv *cafe = mtd->priv;
312 // cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); 315
316 cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
317
318 /* Mask the appropriate bit into the stored value of ctl1
319 which will be used by cafe_nand_cmdfunc() */
320 if (chipnr)
321 cafe->ctl1 |= CTRL1_CHIPSELECT;
322 else
323 cafe->ctl1 &= ~CTRL1_CHIPSELECT;
313} 324}
314 325
315static int cafe_nand_interrupt(int irq, void *id) 326static int cafe_nand_interrupt(int irq, void *id)
@@ -453,7 +464,7 @@ static uint8_t cafe_mirror_pattern_512[] = { 0xBC };
453 464
454static struct nand_bbt_descr cafe_bbt_main_descr_2048 = { 465static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
455 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 466 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
456 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 467 | NAND_BBT_2BIT | NAND_BBT_VERSION,
457 .offs = 14, 468 .offs = 14,
458 .len = 4, 469 .len = 4,
459 .veroffs = 18, 470 .veroffs = 18,
@@ -463,7 +474,7 @@ static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
463 474
464static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = { 475static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = {
465 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 476 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
466 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 477 | NAND_BBT_2BIT | NAND_BBT_VERSION,
467 .offs = 14, 478 .offs = 14,
468 .len = 4, 479 .len = 4,
469 .veroffs = 18, 480 .veroffs = 18,
@@ -479,7 +490,7 @@ static struct nand_ecclayout cafe_oobinfo_512 = {
479 490
480static struct nand_bbt_descr cafe_bbt_main_descr_512 = { 491static struct nand_bbt_descr cafe_bbt_main_descr_512 = {
481 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 492 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
482 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 493 | NAND_BBT_2BIT | NAND_BBT_VERSION,
483 .offs = 14, 494 .offs = 14,
484 .len = 1, 495 .len = 1,
485 .veroffs = 15, 496 .veroffs = 15,
@@ -489,7 +500,7 @@ static struct nand_bbt_descr cafe_bbt_main_descr_512 = {
489 500
490static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = { 501static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
491 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 502 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
492 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 503 | NAND_BBT_2BIT | NAND_BBT_VERSION,
493 .offs = 14, 504 .offs = 14,
494 .len = 1, 505 .len = 1,
495 .veroffs = 15, 506 .veroffs = 15,
@@ -731,7 +742,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
731 cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); 742 cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK));
732 743
733 /* Scan to find existence of the device */ 744 /* Scan to find existence of the device */
734 if (nand_scan_ident(mtd, 1)) { 745 if (nand_scan_ident(mtd, 2)) {
735 err = -ENXIO; 746 err = -ENXIO;
736 goto out_irq; 747 goto out_irq;
737 } 748 }