|
@@ -219,6 +219,22 @@ struct stfsm_seq {
|
|
|
uint32_t seq_cfg;
|
|
|
} __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)
|
|
|
{
|
|
|
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)
|
|
|
{
|
|
|
int ret, timeout = 10;
|
|
@@ -436,6 +488,9 @@ static int stfsm_probe(struct platform_device *pdev)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ /* Detect SPI FLASH device */
|
|
|
+ stfsm_jedec_probe(fsm);
|
|
|
+
|
|
|
fsm->mtd.dev.parent = &pdev->dev;
|
|
|
fsm->mtd.type = MTD_NORFLASH;
|
|
|
fsm->mtd.writesize = 4;
|