aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/diskonchip.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-05-23 17:25:53 -0400
committerThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-05-23 17:25:53 -0400
commit7abd3ef9875eb2afcdcd4f450680298a2983a55e (patch)
tree64c19d2e5ecca182938acfcb8a172efb7d907d85 /drivers/mtd/nand/diskonchip.c
parent3821720d51b5f304d2c33021a82c8da70f6d6ac9 (diff)
[MTD] Refactor NAND hwcontrol to cmd_ctrl
The hwcontrol function enforced a step by step state machine for any kind of hardware chip access. Let the hardware driver know which control bits are set and inform it about a change of the control lines. Let the hardware driver write out the command and address bytes directly. This gives a peformance advantage for address bus controlled chips and simplifies the quirks in the hardware drivers. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/nand/diskonchip.c')
-rw-r--r--drivers/mtd/nand/diskonchip.c77
1 files changed, 29 insertions, 48 deletions
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index f77298f3af60..e4bb6b429f87 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -95,7 +95,8 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
95#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) 95#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
96#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) 96#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
97 97
98static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); 98static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,
99 unsigned int bitmask);
99static void doc200x_select_chip(struct mtd_info *mtd, int chip); 100static void doc200x_select_chip(struct mtd_info *mtd, int chip);
100 101
101static int debug = 0; 102static int debug = 0;
@@ -402,12 +403,10 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
402 uint16_t ret; 403 uint16_t ret;
403 404
404 doc200x_select_chip(mtd, nr); 405 doc200x_select_chip(mtd, nr);
405 doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); 406 doc200x_hwcontrol(mtd, NAND_CMD_READID,
406 this->write_byte(mtd, NAND_CMD_READID); 407 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
407 doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); 408 doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
408 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 409 doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
409 this->write_byte(mtd, 0);
410 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
411 410
412 /* We cant' use dev_ready here, but at least we wait for the 411 /* We cant' use dev_ready here, but at least we wait for the
413 * command to complete 412 * command to complete
@@ -425,12 +424,11 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
425 } ident; 424 } ident;
426 void __iomem *docptr = doc->virtadr; 425 void __iomem *docptr = doc->virtadr;
427 426
428 doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); 427 doc200x_hwcontrol(mtd, NAND_CMD_READID,
429 doc2000_write_byte(mtd, NAND_CMD_READID); 428 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
430 doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); 429 doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
431 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 430 doc200x_hwcontrol(mtd, NAND_CMD_NONE,
432 doc2000_write_byte(mtd, 0); 431 NAND_NCE | NAND_CTRL_CHANGE);
433 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
434 432
435 udelay(50); 433 udelay(50);
436 434
@@ -690,54 +688,37 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
690 chip -= (floor * doc->chips_per_floor); 688 chip -= (floor * doc->chips_per_floor);
691 689
692 /* 11.4.4 -- deassert CE before changing chip */ 690 /* 11.4.4 -- deassert CE before changing chip */
693 doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); 691 doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
694 692
695 WriteDOC(floor, docptr, FloorSelect); 693 WriteDOC(floor, docptr, FloorSelect);
696 WriteDOC(chip, docptr, CDSNDeviceSelect); 694 WriteDOC(chip, docptr, CDSNDeviceSelect);
697 695
698 doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); 696 doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
699 697
700 doc->curchip = chip; 698 doc->curchip = chip;
701 doc->curfloor = floor; 699 doc->curfloor = floor;
702} 700}
703 701
704static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) 702#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE)
703
704static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,
705 unsigned int ctrl)
705{ 706{
706 struct nand_chip *this = mtd->priv; 707 struct nand_chip *this = mtd->priv;
707 struct doc_priv *doc = this->priv; 708 struct doc_priv *doc = this->priv;
708 void __iomem *docptr = doc->virtadr; 709 void __iomem *docptr = doc->virtadr;
709 710
710 switch (cmd) { 711 if (ctrl & NAND_CTRL_CHANGE) {
711 case NAND_CTL_SETNCE: 712 doc->CDSNControl &= ~CDSN_CTRL_MSK;
712 doc->CDSNControl |= CDSN_CTRL_CE; 713 doc->CDSNControl |= ctrl & CDSN_CTRL_MSK;
713 break; 714 if (debug)
714 case NAND_CTL_CLRNCE: 715 printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
715 doc->CDSNControl &= ~CDSN_CTRL_CE; 716 WriteDOC(doc->CDSNControl, docptr, CDSNControl);
716 break; 717 /* 11.4.3 -- 4 NOPs after CSDNControl write */
717 case NAND_CTL_SETCLE: 718 DoC_Delay(doc, 4);
718 doc->CDSNControl |= CDSN_CTRL_CLE;
719 break;
720 case NAND_CTL_CLRCLE:
721 doc->CDSNControl &= ~CDSN_CTRL_CLE;
722 break;
723 case NAND_CTL_SETALE:
724 doc->CDSNControl |= CDSN_CTRL_ALE;
725 break;
726 case NAND_CTL_CLRALE:
727 doc->CDSNControl &= ~CDSN_CTRL_ALE;
728 break;
729 case NAND_CTL_SETWP:
730 doc->CDSNControl |= CDSN_CTRL_WP;
731 break;
732 case NAND_CTL_CLRWP:
733 doc->CDSNControl &= ~CDSN_CTRL_WP;
734 break;
735 } 719 }
736 if (debug) 720 if (cmd != NAND_CMD_NONE)
737 printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); 721 this->write_byte(mtd, cmd);
738 WriteDOC(doc->CDSNControl, docptr, CDSNControl);
739 /* 11.4.3 -- 4 NOPs after CSDNControl write */
740 DoC_Delay(doc, 4);
741} 722}
742 723
743static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) 724static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
@@ -1510,7 +1491,7 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
1510 this->read_buf = doc2001plus_readbuf; 1491 this->read_buf = doc2001plus_readbuf;
1511 this->verify_buf = doc2001plus_verifybuf; 1492 this->verify_buf = doc2001plus_verifybuf;
1512 this->scan_bbt = inftl_scan_bbt; 1493 this->scan_bbt = inftl_scan_bbt;
1513 this->hwcontrol = NULL; 1494 this->cmd_ctrl = NULL;
1514 this->select_chip = doc2001plus_select_chip; 1495 this->select_chip = doc2001plus_select_chip;
1515 this->cmdfunc = doc2001plus_command; 1496 this->cmdfunc = doc2001plus_command;
1516 this->ecc.hwctl = doc2001plus_enable_hwecc; 1497 this->ecc.hwctl = doc2001plus_enable_hwecc;
@@ -1670,7 +1651,7 @@ static int __init doc_probe(unsigned long physadr)
1670 1651
1671 nand->priv = doc; 1652 nand->priv = doc;
1672 nand->select_chip = doc200x_select_chip; 1653 nand->select_chip = doc200x_select_chip;
1673 nand->hwcontrol = doc200x_hwcontrol; 1654 nand->cmd_ctrl = doc200x_hwcontrol;
1674 nand->dev_ready = doc200x_dev_ready; 1655 nand->dev_ready = doc200x_dev_ready;
1675 nand->waitfunc = doc200x_wait; 1656 nand->waitfunc = doc200x_wait;
1676 nand->block_bad = doc200x_block_bad; 1657 nand->block_bad = doc200x_block_bad;