aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngus Clark <angus.clark@st.com>2014-03-26 12:39:18 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-04-14 14:22:59 -0400
commit5d0bddab397ff705d66e6f87b61ea8abc3c62948 (patch)
tree0ba81ad4a2aa8dce22d41364751df2da8886e9f6
parentcc6668637ebed620eaafc807802f3d85b193f534 (diff)
mtd: st_spi_fsm: Refactor status register operations
This patch refactors the fsm_read_status() and fsm_write_status() code to support 1 or 2 byte operations, with a specified command. This allows us to remove device/register specific code, such as the N25Q fsm_wrvcr() function. The 'QE' configuration code is updated accordingly, with minor tweaks to ensure the register values are only written if actually required. One notable change in this area is that the 'W25Q_STATUS_QE' bit-field is now defined with respect to the 'SR2' register, rather than the combined 'SR1+SR2' register which is only used for write operations. Signed-off-by: Angus Clark <angus.clark@st.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/devices/st_spi_fsm.c152
1 files changed, 68 insertions, 84 deletions
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index f86d3e01433b..ced73b13f46b 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -212,8 +212,6 @@
212#define FLASH_CMD_SE_32K 0x52 212#define FLASH_CMD_SE_32K 0x52
213#define FLASH_CMD_SE 0xd8 213#define FLASH_CMD_SE 0xd8
214#define FLASH_CMD_CHIPERASE 0xc7 214#define FLASH_CMD_CHIPERASE 0xc7
215#define FLASH_CMD_WRVCR 0x81
216#define FLASH_CMD_RDVCR 0x85
217 215
218#define FLASH_CMD_READ 0x03 /* READ */ 216#define FLASH_CMD_READ 0x03 /* READ */
219#define FLASH_CMD_READ_FAST 0x0b /* FAST READ */ 217#define FLASH_CMD_READ_FAST 0x0b /* FAST READ */
@@ -261,6 +259,12 @@
261#define S25FL_STATUS_E_ERR 0x20 259#define S25FL_STATUS_E_ERR 0x20
262#define S25FL_STATUS_P_ERR 0x40 260#define S25FL_STATUS_P_ERR 0x40
263 261
262#define N25Q_CMD_WRVCR 0x81
263#define N25Q_CMD_RDVCR 0x85
264#define N25Q_CMD_RDVECR 0x65
265#define N25Q_CMD_RDNVCR 0xb5
266#define N25Q_CMD_WRNVCR 0xb1
267
264#define FLASH_PAGESIZE 256 /* In Bytes */ 268#define FLASH_PAGESIZE 256 /* In Bytes */
265#define FLASH_PAGESIZE_32 (FLASH_PAGESIZE / 4) /* In uint32_t */ 269#define FLASH_PAGESIZE_32 (FLASH_PAGESIZE / 4) /* In uint32_t */
266#define FLASH_MAX_BUSY_WAIT (300 * HZ) /* Maximum 'CHIPERASE' time */ 270#define FLASH_MAX_BUSY_WAIT (300 * HZ) /* Maximum 'CHIPERASE' time */
@@ -592,7 +596,7 @@ static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
592/* 596/*
593 * [W25Qxxx] Configuration 597 * [W25Qxxx] Configuration
594 */ 598 */
595#define W25Q_STATUS_QE (0x1 << 9) 599#define W25Q_STATUS_QE (0x1 << 1)
596 600
597static struct stfsm_seq stfsm_seq_read_jedec = { 601static struct stfsm_seq stfsm_seq_read_jedec = {
598 .data_size = TRANSFER_SIZE(8), 602 .data_size = TRANSFER_SIZE(8),
@@ -686,23 +690,6 @@ static struct stfsm_seq stfsm_seq_write_status = {
686 SEQ_CFG_STARTSEQ), 690 SEQ_CFG_STARTSEQ),
687}; 691};
688 692
689static struct stfsm_seq stfsm_seq_wrvcr = {
690 .seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
691 SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
692 .seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
693 SEQ_OPC_OPCODE(FLASH_CMD_WRVCR)),
694 .seq = {
695 STFSM_INST_CMD1,
696 STFSM_INST_CMD2,
697 STFSM_INST_STA_WR1,
698 STFSM_INST_STOP,
699 },
700 .seq_cfg = (SEQ_CFG_PADS_1 |
701 SEQ_CFG_READNOTWRITE |
702 SEQ_CFG_CSDEASSERT |
703 SEQ_CFG_STARTSEQ),
704};
705
706static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq) 693static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
707{ 694{
708 seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) | 695 seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
@@ -891,60 +878,57 @@ static uint8_t stfsm_wait_busy(struct stfsm *fsm)
891} 878}
892 879
893static int stfsm_read_status(struct stfsm *fsm, uint8_t cmd, 880static int stfsm_read_status(struct stfsm *fsm, uint8_t cmd,
894 uint8_t *status) 881 uint8_t *data, int bytes)
895{ 882{
896 struct stfsm_seq *seq = &stfsm_seq_read_status_fifo; 883 struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
897 uint32_t tmp; 884 uint32_t tmp;
885 uint8_t *t = (uint8_t *)&tmp;
886 int i;
898 887
899 dev_dbg(fsm->dev, "reading STA[%s]\n", 888 dev_dbg(fsm->dev, "read 'status' register [0x%02x], %d byte(s)\n",
900 (cmd == FLASH_CMD_RDSR) ? "1" : "2"); 889 cmd, bytes);
901 890
902 seq->seq_opc[0] = (SEQ_OPC_PADS_1 | 891 BUG_ON(bytes != 1 && bytes != 2);
903 SEQ_OPC_CYCLES(8) | 892
893 seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
904 SEQ_OPC_OPCODE(cmd)), 894 SEQ_OPC_OPCODE(cmd)),
905 895
906 stfsm_load_seq(fsm, seq); 896 stfsm_load_seq(fsm, seq);
907 897
908 stfsm_read_fifo(fsm, &tmp, 4); 898 stfsm_read_fifo(fsm, &tmp, 4);
909 899
910 *status = (uint8_t)(tmp >> 24); 900 for (i = 0; i < bytes; i++)
901 data[i] = t[i];
911 902
912 stfsm_wait_seq(fsm); 903 stfsm_wait_seq(fsm);
913 904
914 return 0; 905 return 0;
915} 906}
916 907
917static int stfsm_write_status(struct stfsm *fsm, uint16_t status, 908static int stfsm_write_status(struct stfsm *fsm, uint8_t cmd,
918 int sta_bytes) 909 uint16_t data, int bytes, int wait_busy)
919{ 910{
920 struct stfsm_seq *seq = &stfsm_seq_write_status; 911 struct stfsm_seq *seq = &stfsm_seq_write_status;
921 912
922 dev_dbg(fsm->dev, "writing STA[%s] 0x%04x\n", 913 dev_dbg(fsm->dev,
923 (sta_bytes == 1) ? "1" : "1+2", status); 914 "write 'status' register [0x%02x], %d byte(s), 0x%04x\n"
924 915 " %s wait-busy\n", cmd, bytes, data, wait_busy ? "with" : "no");
925 seq->status = (uint32_t)status | STA_PADS_1 | STA_CSDEASSERT;
926 seq->seq[2] = (sta_bytes == 1) ?
927 STFSM_INST_STA_WR1 : STFSM_INST_STA_WR1_2;
928
929 stfsm_load_seq(fsm, seq);
930
931 stfsm_wait_seq(fsm);
932
933 return 0;
934};
935 916
936static int stfsm_wrvcr(struct stfsm *fsm, uint8_t data) 917 BUG_ON(bytes != 1 && bytes != 2);
937{
938 struct stfsm_seq *seq = &stfsm_seq_wrvcr;
939 918
940 dev_dbg(fsm->dev, "writing VCR 0x%02x\n", data); 919 seq->seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
920 SEQ_OPC_OPCODE(cmd));
941 921
942 seq->status = (STA_DATA_BYTE1(data) | STA_PADS_1 | STA_CSDEASSERT); 922 seq->status = (uint32_t)data | STA_PADS_1 | STA_CSDEASSERT;
923 seq->seq[2] = (bytes == 1) ? STFSM_INST_STA_WR1 : STFSM_INST_STA_WR1_2;
943 924
944 stfsm_load_seq(fsm, seq); 925 stfsm_load_seq(fsm, seq);
945 926
946 stfsm_wait_seq(fsm); 927 stfsm_wait_seq(fsm);
947 928
929 if (wait_busy)
930 stfsm_wait_busy(fsm);
931
948 return 0; 932 return 0;
949} 933}
950 934
@@ -1164,26 +1148,22 @@ static int stfsm_mx25_config(struct stfsm *fsm)
1164 CFG_ERASESEC_TOGGLE_32BIT_ADDR); 1148 CFG_ERASESEC_TOGGLE_32BIT_ADDR);
1165 } 1149 }
1166 1150
1167 /* Check status of 'QE' bit */ 1151 /* Check status of 'QE' bit, update if required. */
1168 stfsm_read_status(fsm, FLASH_CMD_RDSR, &sta); 1152 stfsm_read_status(fsm, FLASH_CMD_RDSR, &sta, 1);
1169 data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1; 1153 data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
1170 if (data_pads == 4) { 1154 if (data_pads == 4) {
1171 if (!(sta & MX25_STATUS_QE)) { 1155 if (!(sta & MX25_STATUS_QE)) {
1172 /* Set 'QE' */ 1156 /* Set 'QE' */
1173 sta |= MX25_STATUS_QE; 1157 sta |= MX25_STATUS_QE;
1174 1158
1175 stfsm_write_status(fsm, sta, 1); 1159 stfsm_write_status(fsm, FLASH_CMD_WRSR, sta, 1, 1);
1176
1177 stfsm_wait_busy(fsm);
1178 } 1160 }
1179 } else { 1161 } else {