diff options
author | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-05-23 17:25:53 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-05-23 17:25:53 -0400 |
commit | 7abd3ef9875eb2afcdcd4f450680298a2983a55e (patch) | |
tree | 64c19d2e5ecca182938acfcb8a172efb7d907d85 /drivers/mtd/nand/diskonchip.c | |
parent | 3821720d51b5f304d2c33021a82c8da70f6d6ac9 (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.c | 77 |
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 | ||
98 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); | 98 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, |
99 | unsigned int bitmask); | ||
99 | static void doc200x_select_chip(struct mtd_info *mtd, int chip); | 100 | static void doc200x_select_chip(struct mtd_info *mtd, int chip); |
100 | 101 | ||
101 | static int debug = 0; | 102 | static 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 | ||
704 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) | 702 | #define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE) |
703 | |||
704 | static 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 | ||
743 | static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) | 724 | static 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; |