aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nandsim.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index ecd70e2504f6..7428a6c1135e 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -207,13 +207,16 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I
207#define STATE_CMD_READID 0x0000000A /* read ID */ 207#define STATE_CMD_READID 0x0000000A /* read ID */
208#define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */ 208#define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */
209#define STATE_CMD_RESET 0x0000000C /* reset */ 209#define STATE_CMD_RESET 0x0000000C /* reset */
210#define STATE_CMD_RNDOUT 0x0000000D /* random output command */
211#define STATE_CMD_RNDOUTSTART 0x0000000E /* random output start command */
210#define STATE_CMD_MASK 0x0000000F /* command states mask */ 212#define STATE_CMD_MASK 0x0000000F /* command states mask */
211 213
212/* After an address is input, the simulator goes to one of these states */ 214/* 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 */ 215#define STATE_ADDR_PAGE 0x00000010 /* full (row, column) address is accepted */
214#define STATE_ADDR_SEC 0x00000020 /* sector address was accepted */ 216#define STATE_ADDR_SEC 0x00000020 /* sector address was accepted */
215#define STATE_ADDR_ZERO 0x00000030 /* one byte zero address was accepted */ 217#define STATE_ADDR_COLUMN 0x00000030 /* column address was accepted */
216#define STATE_ADDR_MASK 0x00000030 /* address states mask */ 218#define STATE_ADDR_ZERO 0x00000040 /* one byte zero address was accepted */
219#define STATE_ADDR_MASK 0x00000070 /* address states mask */
217 220
218/* Durind data input/output the simulator is in these states */ 221/* Durind data input/output the simulator is in these states */
219#define STATE_DATAIN 0x00000100 /* waiting for data input */ 222#define STATE_DATAIN 0x00000100 /* waiting for data input */
@@ -240,7 +243,7 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I
240#define ACTION_OOBOFF 0x00600000 /* add to address OOB offset */ 243#define ACTION_OOBOFF 0x00600000 /* add to address OOB offset */
241#define ACTION_MASK 0x00700000 /* action mask */ 244#define ACTION_MASK 0x00700000 /* action mask */
242 245
243#define NS_OPER_NUM 12 /* Number of operations supported by the simulator */ 246#define NS_OPER_NUM 13 /* Number of operations supported by the simulator */
244#define NS_OPER_STATES 6 /* Maximum number of states in operation */ 247#define NS_OPER_STATES 6 /* Maximum number of states in operation */
245 248
246#define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */ 249#define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */
@@ -373,7 +376,10 @@ static struct nandsim_operations {
373 {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}}, 376 {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}},
374 /* Large page devices read page */ 377 /* Large page devices read page */
375 {OPT_LARGEPAGE, {STATE_CMD_READ0, STATE_ADDR_PAGE, STATE_CMD_READSTART | ACTION_CPY, 378 {OPT_LARGEPAGE, {STATE_CMD_READ0, STATE_ADDR_PAGE, STATE_CMD_READSTART | ACTION_CPY,
376 STATE_DATAOUT, STATE_READY}} 379 STATE_DATAOUT, STATE_READY}},
380 /* Large page devices random page read */
381 {OPT_LARGEPAGE, {STATE_CMD_RNDOUT, STATE_ADDR_COLUMN, STATE_CMD_RNDOUTSTART | ACTION_CPY,
382 STATE_DATAOUT, STATE_READY}},
377}; 383};
378 384
379struct weak_block { 385struct weak_block {
@@ -937,12 +943,18 @@ static char *get_state_name(uint32_t state)
937 return "STATE_CMD_ERASE2"; 943 return "STATE_CMD_ERASE2";
938 case STATE_CMD_RESET: 944 case STATE_CMD_RESET:
939 return "STATE_CMD_RESET"; 945 return "STATE_CMD_RESET";
946 case STATE_CMD_RNDOUT:
947 return "STATE_CMD_RNDOUT";
948 case STATE_CMD_RNDOUTSTART:
949 return "STATE_CMD_RNDOUTSTART";
940 case STATE_ADDR_PAGE: 950 case STATE_ADDR_PAGE:
941 return "STATE_ADDR_PAGE"; 951 return "STATE_ADDR_PAGE";
942 case STATE_ADDR_SEC: 952 case STATE_ADDR_SEC:
943 return "STATE_ADDR_SEC"; 953 return "STATE_ADDR_SEC";
944 case STATE_ADDR_ZERO: 954 case STATE_ADDR_ZERO:
945 return "STATE_ADDR_ZERO"; 955 return "STATE_ADDR_ZERO";
956 case STATE_ADDR_COLUMN:
957 return "STATE_ADDR_COLUMN";
946 case STATE_DATAIN: 958 case STATE_DATAIN:
947 return "STATE_DATAIN"; 959 return "STATE_DATAIN";
948 case STATE_DATAOUT: 960 case STATE_DATAOUT:
@@ -973,6 +985,7 @@ static int check_command(int cmd)
973 switch (cmd) { 985 switch (cmd) {
974 986
975 case NAND_CMD_READ0: 987 case NAND_CMD_READ0:
988 case NAND_CMD_READ1:
976 case NAND_CMD_READSTART: 989 case NAND_CMD_READSTART:
977 case NAND_CMD_PAGEPROG: 990 case NAND_CMD_PAGEPROG:
978 case NAND_CMD_READOOB: 991 case NAND_CMD_READOOB:
@@ -982,7 +995,8 @@ static int check_command(int cmd)
982 case NAND_CMD_READID: 995 case NAND_CMD_READID:
983 case NAND_CMD_ERASE2: 996 case NAND_CMD_ERASE2:
984 case NAND_CMD_RESET: 997 case NAND_CMD_RESET:
985 case NAND_CMD_READ1: 998 case NAND_CMD_RNDOUT:
999 case NAND_CMD_RNDOUTSTART:
986 return 0; 1000 return 0;
987 1001
988 case NAND_CMD_STATUS_MULTI: 1002 case NAND_CMD_STATUS_MULTI:
@@ -1021,6 +1035,10 @@ static uint32_t get_state_by_command(unsigned command)
1021 return STATE_CMD_ERASE2; 1035 return STATE_CMD_ERASE2;
1022 case NAND_CMD_RESET: 1036 case NAND_CMD_RESET:
1023 return STATE_CMD_RESET; 1037 return STATE_CMD_RESET;
1038 case NAND_CMD_RNDOUT:
1039 return STATE_CMD_RNDOUT;
1040 case NAND_CMD_RNDOUTSTART:
1041 return STATE_CMD_RNDOUTSTART;
1024 } 1042 }
1025 1043
1026 NS_ERR("get_state_by_command: unknown command, BUG\n"); 1044 NS_ERR("get_state_by_command: unknown command, BUG\n");
@@ -1582,6 +1600,11 @@ static void switch_state(struct nandsim *ns)
1582 ns->regs.num = 1; 1600 ns->regs.num = 1;
1583 break; 1601 break;
1584 1602
1603 case STATE_ADDR_COLUMN:
1604 /* Column address is always 2 bytes */
1605 ns->regs.num = ns->geom.pgaddrbytes - ns->geom.secaddrbytes;
1606 break;
1607
1585 default: 1608 default:
1586 NS_ERR("switch_state: BUG! unknown address state\n"); 1609 NS_ERR("switch_state: BUG! unknown address state\n");
1587 } 1610 }
@@ -1693,15 +1716,21 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1693 return; 1716 return;
1694 } 1717 }
1695 1718
1696 /* 1719 /* Check that the command byte is correct */
1697 * Chip might still be in STATE_DATAOUT 1720 if (check_command(byte)) {
1698 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or 1721 NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
1699 * STATE_DATAOUT_STATUS_M state. If so, switch state. 1722 return;
1700 */ 1723 }
1724
1701 if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS 1725 if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS
1702 || NS_STATE(ns->state) == STATE_DATAOUT_STATUS_M 1726 || NS_STATE(ns->state) == STATE_DATAOUT_STATUS_M
1703 || ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT)) 1727 || NS_STATE(ns->state) == STATE_DATAOUT) {
1728 int row = ns->regs.row;
1729
1704 switch_state(ns); 1730 switch_state(ns);
1731 if (byte == NAND_CMD_RNDOUT)
1732 ns->regs.row = row;
1733 }
1705 1734
1706 /* Check if chip is expecting command */ 1735 /* Check if chip is expecting command */
1707 if (NS_STATE(ns->nxstate) != STATE_UNKNOWN && !(ns->nxstate & STATE_CMD_MASK)) { 1736 if (NS_STATE(ns->nxstate) != STATE_UNKNOWN && !(ns->nxstate & STATE_CMD_MASK)) {
@@ -1715,12 +1744,6 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1715 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1744 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1716 } 1745 }
1717 1746
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", 1747 NS_DBG("command byte corresponding to %s state accepted\n",
1725 get_state_name(get_state_by_command(byte))); 1748 get_state_name(get_state_by_command(byte)));
1726 ns->regs.command = byte; 1749 ns->regs.command = byte;