aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2015-02-10 13:59:58 -0500
committerBrian Norris <computersforpeace@gmail.com>2015-03-11 18:20:29 -0400
commitc4ca3997ef954bcba009cce0e325f3155bdde01a (patch)
treed1074b773013f41fd9acb1506a0e9b0ce6fa54c8 /drivers/mtd
parent3f410690f511f9531fdc0865a931522b049d7b29 (diff)
mtd: mxc-nand: Allow to use column addresses different from 0
The mxc-nand controller works pagewise and so usually only sends commands to the flash chip with column == 0. A request with column != 0 from the upper layer is then fulfilled by indexing appropriately into the device's RAM buffer. To be able to access the ONFI marker at offset 0x20 in reply to the READID command however it's invalid to read 32 bytes starting from column 0. So let the function used to send the address cycles send the column address actually passed instead of 0 and fix all callers to pass 0 instead appropriately. Also add some warnings in case this patch changes the drivers semantics. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/mxc_nand.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index aa98a0dddcfb..0afe5904a337 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -836,6 +836,12 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
836 } 836 }
837} 837}
838 838
839/*
840 * MXC NANDFC can only perform full page+spare or spare-only read/write. When
841 * the upper layers perform a read/write buf operation, the saved column address
842 * is used to index into the full page. So usually this function is called with
843 * column == 0 (unless no column cycle is needed indicated by column == -1)
844 */
839static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) 845static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
840{ 846{
841 struct nand_chip *nand_chip = mtd->priv; 847 struct nand_chip *nand_chip = mtd->priv;
@@ -843,16 +849,13 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
843 849
844 /* Write out column address, if necessary */ 850 /* Write out column address, if necessary */
845 if (column != -1) { 851 if (column != -1) {
846 /* 852 host->devtype_data->send_addr(host, column & 0xff,
847 * MXC NANDFC can only perform full page+spare or 853 page_addr == -1);
848 * spare-only read/write. When the upper layers
849 * perform a read/write buf operation, the saved column
850 * address is used to index into the full page.
851 */
852 host->devtype_data->send_addr(host, 0, page_addr == -1);
853 if (mtd->writesize > 512) 854 if (mtd->writesize > 512)
854 /* another col addr cycle for 2k page */ 855 /* another col addr cycle for 2k page */
855 host->devtype_data->send_addr(host, 0, false); 856 host->devtype_data->send_addr(host,
857 (column >> 8) & 0xff,
858 false);
856 } 859 }
857 860
858 /* Write out page address, if necessary */ 861 /* Write out page address, if necessary */
@@ -1077,6 +1080,9 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
1077 host->status_request = true; 1080 host->status_request = true;
1078 1081
1079 host->devtype_data->send_cmd(host, command, true); 1082 host->devtype_data->send_cmd(host, command, true);
1083 WARN_ONCE(column != -1 || page_addr != -1,
1084 "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
1085 command, column, page_addr);
1080 mxc_do_addr_cycle(mtd, column, page_addr); 1086 mxc_do_addr_cycle(mtd, column, page_addr);
1081 break; 1087 break;
1082 1088
@@ -1090,7 +1096,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
1090 command = NAND_CMD_READ0; /* only READ0 is valid */ 1096 command = NAND_CMD_READ0; /* only READ0 is valid */
1091 1097
1092 host->devtype_data->send_cmd(host, command, false); 1098 host->devtype_data->send_cmd(host, command, false);
1093 mxc_do_addr_cycle(mtd, column, page_addr); 1099 WARN_ONCE(column < 0,
1100 "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
1101 command, column, page_addr);
1102 mxc_do_addr_cycle(mtd, 0, page_addr);
1094 1103
1095 if (mtd->writesize > 512) 1104 if (mtd->writesize > 512)
1096 host->devtype_data->send_cmd(host, 1105 host->devtype_data->send_cmd(host,
@@ -1111,7 +1120,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
1111 host->buf_start = column; 1120 host->buf_start = column;
1112 1121
1113 host->devtype_data->send_cmd(host, command, false); 1122 host->devtype_data->send_cmd(host, command, false);
1114 mxc_do_addr_cycle(mtd, column, page_addr); 1123 WARN_ONCE(column < -1,
1124 "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
1125 command, column, page_addr);
1126 mxc_do_addr_cycle(mtd, 0, page_addr);
1115 break; 1127 break;
1116 1128
1117 case NAND_CMD_PAGEPROG: 1129 case NAND_CMD_PAGEPROG:
@@ -1119,6 +1131,9 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
1119 copy_spare(mtd, false); 1131 copy_spare(mtd, false);
1120 host->devtype_data->send_page(mtd, NFC_INPUT); 1132 host->devtype_data->send_page(mtd, NFC_INPUT);
1121 host->devtype_data->send_cmd(host, command, true); 1133 host->devtype_data->send_cmd(host, command, true);
1134 WARN_ONCE(column != -1 || page_addr != -1,
1135 "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
1136 command, column, page_addr);
1122 mxc_do_addr_cycle(mtd, column, page_addr); 1137 mxc_do_addr_cycle(mtd, column, page_addr);
1123 break; 1138 break;
1124 1139
@@ -1126,12 +1141,15 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
1126 host->devtype_data->send_cmd(host, command, true); 1141 host->devtype_data->send_cmd(host, command, true);
1127 mxc_do_addr_cycle(mtd, column, page_addr); 1142 mxc_do_addr_cycle(mtd, column, page_addr);
1128 host->devtype_data->send_read_id(host); 1143 host->devtype_data->send_read_id(host);
1129 host->buf_start = column; 1144 host->buf_start = 0;
1130 break; 1145 break;
1131 1146
1132 case NAND_CMD_ERASE1: 1147 case NAND_CMD_ERASE1:
1133 case NAND_CMD_ERASE2: 1148 case NAND_CMD_ERASE2:
1134 host->devtype_data->send_cmd(host, command, false); 1149 host->devtype_data->send_cmd(host, command, false);
1150 WARN_ONCE(column != -1,
1151 "Unexpected column value (cmd=%u, col=%d)\n",
1152 command, column);
1135 mxc_do_addr_cycle(mtd, column, page_addr); 1153 mxc_do_addr_cycle(mtd, column, page_addr);
1136 1154
1137 break; 1155 break;