mtd: st_spi_fsm: Add support for JEDEC ID extraction
Once we start supporting devices it will be handy go detect them dynamically. This will be done using the chip's unique JEDEC ID. This patch allows us to extract a device's JEDEC ID using the a predefined FSM register write sequence. 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:
parent
030e82dc63
commit
1bd512b562
|
@ -219,6 +219,22 @@ struct stfsm_seq {
|
||||||
uint32_t seq_cfg;
|
uint32_t seq_cfg;
|
||||||
} __packed __aligned(4);
|
} __packed __aligned(4);
|
||||||
|
|
||||||
|
static struct stfsm_seq stfsm_seq_read_jedec = {
|
||||||
|
.data_size = TRANSFER_SIZE(8),
|
||||||
|
.seq_opc[0] = (SEQ_OPC_PADS_1 |
|
||||||
|
SEQ_OPC_CYCLES(8) |
|
||||||
|
SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
|
||||||
|
.seq = {
|
||||||
|
STFSM_INST_CMD1,
|
||||||
|
STFSM_INST_DATA_READ,
|
||||||
|
STFSM_INST_STOP,
|
||||||
|
},
|
||||||
|
.seq_cfg = (SEQ_CFG_PADS_1 |
|
||||||
|
SEQ_CFG_READNOTWRITE |
|
||||||
|
SEQ_CFG_CSDEASSERT |
|
||||||
|
SEQ_CFG_STARTSEQ),
|
||||||
|
};
|
||||||
|
|
||||||
static inline int stfsm_is_idle(struct stfsm *fsm)
|
static inline int stfsm_is_idle(struct stfsm *fsm)
|
||||||
{
|
{
|
||||||
return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
|
return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
|
||||||
|
@ -307,6 +323,42 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
|
||||||
|
{
|
||||||
|
const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
|
||||||
|
uint32_t tmp[2];
|
||||||
|
|
||||||
|
stfsm_load_seq(fsm, seq);
|
||||||
|
|
||||||
|
stfsm_read_fifo(fsm, tmp, 8);
|
||||||
|
|
||||||
|
memcpy(jedec, tmp, 5);
|
||||||
|
|
||||||
|
stfsm_wait_seq(fsm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
|
||||||
|
{
|
||||||
|
u16 ext_jedec;
|
||||||
|
u32 jedec;
|
||||||
|
u8 id[5];
|
||||||
|
|
||||||
|
stfsm_read_jedec(fsm, id);
|
||||||
|
|
||||||
|
jedec = id[0] << 16 | id[1] << 8 | id[2];
|
||||||
|
/*
|
||||||
|
* JEDEC also defines an optional "extended device information"
|
||||||
|
* string for after vendor-specific data, after the three bytes
|
||||||
|
* we use here. Supporting some chips might require using it.
|
||||||
|
*/
|
||||||
|
ext_jedec = id[3] << 8 | id[4];
|
||||||
|
|
||||||
|
dev_dbg(fsm->dev, "JEDEC = 0x%08x [%02x %02x %02x %02x %02x]\n",
|
||||||
|
jedec, id[0], id[1], id[2], id[3], id[4]);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int stfsm_set_mode(struct stfsm *fsm, uint32_t mode)
|
static int stfsm_set_mode(struct stfsm *fsm, uint32_t mode)
|
||||||
{
|
{
|
||||||
int ret, timeout = 10;
|
int ret, timeout = 10;
|
||||||
|
@ -436,6 +488,9 @@ static int stfsm_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Detect SPI FLASH device */
|
||||||
|
stfsm_jedec_probe(fsm);
|
||||||
|
|
||||||
fsm->mtd.dev.parent = &pdev->dev;
|
fsm->mtd.dev.parent = &pdev->dev;
|
||||||
fsm->mtd.type = MTD_NORFLASH;
|
fsm->mtd.type = MTD_NORFLASH;
|
||||||
fsm->mtd.writesize = 4;
|
fsm->mtd.writesize = 4;
|
||||||
|
|
Loading…
Reference in a new issue