aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nandsim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nandsim.c')
-rw-r--r--drivers/mtd/nand/nandsim.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index ecd70e2504f..556e8131ecd 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -28,6 +28,7 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <asm/div64.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32#include <linux/errno.h> 33#include <linux/errno.h>
33#include <linux/string.h> 34#include <linux/string.h>
@@ -207,13 +208,16 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I
207#define STATE_CMD_READID 0x0000000A /* read ID */ 208#define STATE_CMD_READID 0x0000000A /* read ID */
208#define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */ 209#define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */
209#define STATE_CMD_RESET 0x0000000C /* reset */ 210#define STATE_CMD_RESET 0x0000000C /* reset */
211#define STATE_CMD_RNDOUT 0x0000000D /* random output command */
212#define STATE_CMD_RNDOUTSTART 0x0000000E /* random output start command */
210#define STATE_CMD_MASK 0x0000000F /* command states mask */ 213#define STATE_CMD_MASK 0x0000000F /* command states mask */
211 214
212/* After an address is input, the simulator goes to one of these states */ 215/* After an address is input, the simulator goes to one of these states */
213#define STATE_ADDR_PAGE 0x00000010 /* full (row, column) address is accepted */ 216#define STATE_ADDR_PAGE 0x00000010 /* full (row, column) address is accepted */
214#define STATE_ADDR_SEC 0x00000020 /* sector address was accepted */ 217#define STATE_ADDR_SEC 0x00000020 /* sector address was accepted */
215#define STATE_ADDR_ZERO 0x00000030 /* one byte zero address was accepted */ 218#define STATE_ADDR_COLUMN 0x00000030 /* column address was accepted */
216#define STATE_ADDR_MASK 0x00000030 /* address states mask */ 219#define STATE_ADDR_ZERO 0x00000040 /* one byte zero address was accepted */
220#define STATE_ADDR_MASK 0x00000070 /* address states mask */
217 221
218/* Durind data input/output the simulator is in these states */ 222/* Durind data input/output the simulator is in these states */
219#define STATE_DATAIN 0x00000100 /* waiting for data input */ 223#define STATE_DATAIN 0x00000100 /* waiting for data input */
@@ -240,7 +244,7 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I
240#define ACTION_OOBOFF 0x00600000 /* add to address OOB offset */ 244#define ACTION_OOBOFF 0x00600000 /* add to address OOB offset */
241#define ACTION_MASK 0x00700000 /* action mask */ 245#define ACTION_MASK 0x00700000 /* action mask */
242 246
243#define NS_OPER_NUM 12 /* Number of operations supported by the simulator */ 247#define NS_OPER_NUM 13 /* Number of operations supported by the simulator */
244#define NS_OPER_STATES 6 /* Maximum number of states in operation */ 248#define NS_OPER_STATES 6 /* Maximum number of states in operation */
245 249
246#define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */ 250#define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */
@@ -373,7 +377,10 @@ static struct nandsim_operations {
373 {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}}, 377 {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}},
374 /* Large page devices read page */ 378 /* Large page devices read page */
375 {OPT_LARGEPAGE, {STATE_CMD_READ0, STATE_ADDR_PAGE, STATE_CMD_READSTART | ACTION_CPY, 379 {OPT_LARGEPAGE, {STATE_CMD_READ0, STATE_ADDR_PAGE, STATE_CMD_READSTART | ACTION_CPY,
376 STATE_DATAOUT, STATE_READY}} 380 STATE_DATAOUT, STATE_READY}},
381 /* Large page devices random page read */
382 {OPT_LARGEPAGE, {STATE_CMD_RNDOUT, STATE_ADDR_COLUMN, STATE_CMD_RNDOUTSTART | ACTION_CPY,
383 STATE_DATAOUT, STATE_READY}},
377}; 384};
378 385
379struct weak_block { 386struct weak_block {
@@ -579,7 +586,8 @@ static int init_nandsim(struct mtd_info *mtd)
579 if (ns->busw == 16) 586 if (ns->busw == 16)
580 NS_WARN("16-bit flashes support wasn't tested\n"); 587 NS_WARN("16-bit flashes support wasn't tested\n");
581 588
582 printk("flash size: %llu MiB\n", ns->geom.totsz >> 20); 589 printk("flash size: %llu MiB\n",
590 (unsigned long long)ns->geom.totsz >> 20);
583 printk("page size: %u bytes\n", ns->geom.pgsz); 591 printk("page size: %u bytes\n", ns->geom.pgsz);
584 printk("OOB area size: %u bytes\n", ns->geom.oobsz); 592 printk("OOB area size: %u bytes\n", ns->geom.oobsz);
585 printk("sector size: %u KiB\n", ns->geom.secsz >> 10); 593 printk("sector size: %u KiB\n", ns->geom.secsz >> 10);
@@ -588,8 +596,9 @@ static int init_nandsim(struct mtd_info *mtd)
588 printk("bus width: %u\n", ns->busw); 596 printk("bus width: %u\n", ns->busw);
589 printk("bits in sector size: %u\n", ns->geom.secshift); 597 printk("bits in sector size: %u\n", ns->geom.secshift);
590 printk("bits in page size: %u\n", ns->geom.pgshift); 598 printk("bits in page size: %u\n", ns->geom.pgshift);
591 printk("bits in OOB size: %u\n", ns->geom.oobshift); 599 printk("bits in OOB size: %u\n", ns->geom.oobshift);
592 printk("flash size with OOB: %llu KiB\n", ns->geom.totszoob >> 10); 600 printk("flash size with OOB: %llu KiB\n",
601 (unsigned long long)ns->geom.totszoob >> 10);
593 printk("page address bytes: %u\n", ns->geom.pgaddrbytes); 602 printk("page address bytes: %u\n", ns->geom.pgaddrbytes);
594 printk("sector address bytes: %u\n", ns->geom.secaddrbytes); 603 printk("sector address bytes: %u\n", ns->geom.secaddrbytes);
595 printk("options: %#x\n", ns->options); 604 printk("options: %#x\n", ns->options);
@@ -937,12 +946,18 @@ static char *get_state_name(uint32_t state)
937 return "STATE_CMD_ERASE2"; 946 return "STATE_CMD_ERASE2";
938 case STATE_CMD_RESET: 947 case STATE_CMD_RESET:
939 return "STATE_CMD_RESET"; 948 return "STATE_CMD_RESET";
949 case STATE_CMD_RNDOUT:
950 return "STATE_CMD_RNDOUT";
951 case STATE_CMD_RNDOUTSTART:
952 return "STATE_CMD_RNDOUTSTART";
940 case STATE_ADDR_PAGE: 953 case STATE_ADDR_PAGE:
941 return "STATE_ADDR_PAGE"; 954 return "STATE_ADDR_PAGE";
942 case STATE_ADDR_SEC: 955 case STATE_ADDR_SEC:
943 return "STATE_ADDR_SEC"; 956 return "STATE_ADDR_SEC";
944 case STATE_ADDR_ZERO: 957 case STATE_ADDR_ZERO:
945 return "STATE_ADDR_ZERO"; 958 return "STATE_ADDR_ZERO";
959 case STATE_ADDR_COLUMN:
960 return "STATE_ADDR_COLUMN";
946 case STATE_DATAIN: 961 case STATE_DATAIN:
947 return "STATE_DATAIN"; 962 return "STATE_DATAIN";
948 case STATE_DATAOUT: 963 case STATE_DATAOUT:
@@ -973,6 +988,7 @@ static int check_command(int cmd)
973 switch (cmd) { 988 switch (cmd) {
974 989
975 case NAND_CMD_READ0: 990 case NAND_CMD_READ0:
991 case NAND_CMD_READ1:
976 case NAND_CMD_READSTART: 992 case NAND_CMD_READSTART:
977 case NAND_CMD_PAGEPROG: 993 case NAND_CMD_PAGEPROG:
978 case NAND_CMD_READOOB: 994 case NAND_CMD_READOOB:
@@ -982,7 +998,8 @@ static int check_command(int cmd)
982 case NAND_CMD_READID: 998 case NAND_CMD_READID:
983 case NAND_CMD_ERASE2: 999 case NAND_CMD_ERASE2:
984 case NAND_CMD_RESET: 1000 case NAND_CMD_RESET:
985 case NAND_CMD_READ1: 1001 case NAND_CMD_RNDOUT:
1002 case NAND_CMD_RNDOUTSTART:
986 return 0; 1003 return 0;
987 1004
988 case NAND_CMD_STATUS_MULTI: 1005 case NAND_CMD_STATUS_MULTI:
@@ -1021,6 +1038,10 @@ static uint32_t get_state_by_command(unsigned command)
1021 return STATE_CMD_ERASE2; 1038 return STATE_CMD_ERASE2;
1022 case NAND_CMD_RESET: 1039 case NAND_CMD_RESET:
1023 return STATE_CMD_RESET; 1040 return STATE_CMD_RESET;
1041 case NAND_CMD_RNDOUT:
1042 return STATE_CMD_RNDOUT;
1043 case NAND_CMD_RNDOUTSTART:
1044 return STATE_CMD_RNDOUTSTART;
1024 } 1045 }
1025 1046
1026 NS_ERR("get_state_by_command: unknown command, BUG\n"); 1047 NS_ERR("get_state_by_command: unknown command, BUG\n");
@@ -1582,6 +1603,11 @@ static void switch_state(struct nandsim *ns)
1582 ns->regs.num = 1; 1603 ns->regs.num = 1;
1583 break; 1604 break;
1584 1605
1606 case STATE_ADDR_COLUMN:
1607 /* Column address is always 2 bytes */
1608 ns->regs.num = ns->geom.pgaddrbytes - ns->geom.secaddrbytes;
1609 break;
1610
1585 default: 1611 default:
1586 NS_ERR("switch_state: BUG! unknown address state\n"); 1612 NS_ERR("switch_state: BUG! unknown address state\n");
1587 } 1613 }
@@ -1693,15 +1719,21 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1693 return; 1719 return;
1694 } 1720 }
1695 1721
1696 /* 1722 /* Check that the command byte is correct */
1697 * Chip might still be in STATE_DATAOUT 1723 if (check_command(byte)) {
1698 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or 1724 NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
1699 * STATE_DATAOUT_STATUS_M state. If so, switch state. 1725 return;
1700 */ 1726 }
1727
1701 if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS 1728 if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS
1702 || NS_STATE(ns->state) == STATE_DATAOUT_STATUS_M 1729 || NS_STATE(ns->state) == STATE_DATAOUT_STATUS_M
1703 || ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT)) 1730 || NS_STATE(ns->state) == STATE_DATAOUT) {
1731 int row = ns->regs.row;
1732
1704 switch_state(ns); 1733 switch_state(ns);
1734 if (byte == NAND_CMD_RNDOUT)
1735 ns->regs.row = row;
1736 }
1705 1737
1706 /* Check if chip is expecting command */ 1738 /* Check if chip is expecting command */
1707 if (NS_STATE(ns->nxstate) != STATE_UNKNOWN && !(ns->nxstate & STATE_CMD_MASK)) { 1739 if (NS_STATE(ns->nxstate) != STATE_UNKNOWN && !(ns->nxstate & STATE_CMD_MASK)) {
@@ -1715,12 +1747,6 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1715 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1747 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1716 } 1748 }
1717 1749
1718 /* Check that the command byte is correct */
1719 if (check_command(byte)) {
1720 NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
1721 return;
1722 }
1723
1724 NS_DBG("command byte corresponding to %s state accepted\n", 1750 NS_DBG("command byte corresponding to %s state accepted\n",
1725 get_state_name(get_state_by_command(byte))); 1751 get_state_name(get_state_by_command(byte)));
1726 ns->regs.command = byte; 1752 ns->regs.command = byte;