mtd: st_spi_fsm: Prepare the read/write FSM message sequence(s)

The FSM Serial Flash Controller is driven by issuing a standard set of
register writes we call a message sequence. This patch supplies a method
to prepare read/write FSM message sequence(s) based on chip capability
and configuration.

Acked-by Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
This commit is contained in:
Lee Jones 2014-03-20 09:20:44 +00:00 committed by Brian Norris
parent 3b5d198193
commit 97ccf2d253
1 changed files with 69 additions and 0 deletions

View File

@ -489,6 +489,75 @@ stfsm_search_seq_rw_configs(struct stfsm *fsm,
return NULL;
}
/* Prepare a READ/WRITE sequence according to configuration parameters */
static void stfsm_prepare_rw_seq(struct stfsm *fsm,
struct stfsm_seq *seq,
struct seq_rw_config *cfg)
{
int addr1_cycles, addr2_cycles;
int i = 0;
memset(seq, 0, sizeof(*seq));
/* Add READ/WRITE OPC */
seq->seq_opc[i++] = (SEQ_OPC_PADS_1 |
SEQ_OPC_CYCLES(8) |
SEQ_OPC_OPCODE(cfg->cmd));
/* Add WREN OPC for a WRITE sequence */
if (cfg->write)
seq->seq_opc[i++] = (SEQ_OPC_PADS_1 |
SEQ_OPC_CYCLES(8) |
SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
SEQ_OPC_CSDEASSERT);
/* Address configuration (24 or 32-bit addresses) */
addr1_cycles = (fsm->info->flags & FLASH_FLAG_32BIT_ADDR) ? 16 : 8;
addr1_cycles /= cfg->addr_pads;
addr2_cycles = 16 / cfg->addr_pads;
seq->addr_cfg = ((addr1_cycles & 0x3f) << 0 | /* ADD1 cycles */
(cfg->addr_pads - 1) << 6 | /* ADD1 pads */
(addr2_cycles & 0x3f) << 16 | /* ADD2 cycles */
((cfg->addr_pads - 1) << 22)); /* ADD2 pads */
/* Data/Sequence configuration */
seq->seq_cfg = ((cfg->data_pads - 1) << 16 |
SEQ_CFG_STARTSEQ |
SEQ_CFG_CSDEASSERT);
if (!cfg->write)
seq->seq_cfg |= SEQ_CFG_READNOTWRITE;
/* Mode configuration (no. of pads taken from addr cfg) */
seq->mode = ((cfg->mode_data & 0xff) << 0 | /* data */
(cfg->mode_cycles & 0x3f) << 16 | /* cycles */
(cfg->addr_pads - 1) << 22); /* pads */
/* Dummy configuration (no. of pads taken from addr cfg) */
seq->dummy = ((cfg->dummy_cycles & 0x3f) << 16 | /* cycles */
(cfg->addr_pads - 1) << 22); /* pads */
/* Instruction sequence */
i = 0;
if (cfg->write)
seq->seq[i++] = STFSM_INST_CMD2;
seq->seq[i++] = STFSM_INST_CMD1;
seq->seq[i++] = STFSM_INST_ADD1;
seq->seq[i++] = STFSM_INST_ADD2;
if (cfg->mode_cycles)
seq->seq[i++] = STFSM_INST_MODE;
if (cfg->dummy_cycles)
seq->seq[i++] = STFSM_INST_DUMMY;
seq->seq[i++] =
cfg->write ? STFSM_INST_DATA_WRITE : STFSM_INST_DATA_READ;
seq->seq[i++] = STFSM_INST_STOP;
}
static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
{
const struct stfsm_seq *seq = &stfsm_seq_read_jedec;