Skip to content

Commit 767fd62

Browse files
committed
drivers: flash: stm32: qspi: support 1-4-4 and 1-1-4 quad read modes
Adds support for 1-4-4 and 1-1-4 read modes. SFDP is used to query for available read instructions, then the fastest one is used. Signed-off-by: Georgij Cernysiov <[email protected]>
1 parent 7a65dc2 commit 767fd62

File tree

1 file changed

+58
-22
lines changed

1 file changed

+58
-22
lines changed

drivers/flash/flash_stm32_qspi.c

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ LOG_MODULE_REGISTER(flash_stm32_qspi, CONFIG_FLASH_LOG_LEVEL);
4343
#define STM32_QSPI_FIFO_THRESHOLD 8
4444
#define STM32_QSPI_CLOCK_PRESCALER_MAX 255
4545

46+
#define STM32_QSPI_UNKNOWN_MODE (0xFF)
47+
4648
#define STM32_QSPI_USE_DMA DT_NODE_HAS_PROP(DT_INST_PARENT(0), dmas)
4749

4850
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor)
@@ -90,6 +92,7 @@ struct flash_stm32_qspi_data {
9092
struct jesd216_erase_type erase_types[JESD216_NUM_ERASE_TYPES];
9193
/* Number of bytes per page */
9294
uint16_t page_size;
95+
enum jesd216_mode_type mode;
9396
int cmd_status;
9497
struct stream dma;
9598
uint8_t qspi_write_cmd;
@@ -133,17 +136,29 @@ static inline void qspi_set_address_size(const struct device *dev,
133136
cmd->AddressSize = QSPI_ADDRESS_24_BITS;
134137
}
135138

136-
static inline void qspi_prepare_quad_read(const struct device *dev,
139+
static inline int qspi_prepare_quad_read(const struct device *dev,
137140
QSPI_CommandTypeDef *cmd)
138141
{
139142
struct flash_stm32_qspi_data *dev_data = dev->data;
140143

141144
if (IS_ENABLED(STM32_QSPI_USE_QUAD_IO) && dev_data->flag_quad_io_en) {
145+
switch (dev_data->mode) {
146+
case JESD216_MODE_114:
147+
cmd->AddressMode = QSPI_ADDRESS_1_LINE;
148+
break;
149+
case JESD216_MODE_144:
150+
cmd->AddressMode = QSPI_ADDRESS_4_LINES;
151+
break;
152+
default:
153+
return -ENOTSUP;
154+
}
155+
142156
cmd->Instruction = dev_data->qspi_read_cmd;
143-
cmd->AddressMode = QSPI_ADDRESS_4_LINES;
144157
cmd->DataMode = QSPI_DATA_4_LINES;
145158
cmd->DummyCycles = dev_data->qspi_read_cmd_latency;
146159
}
160+
161+
return 0;
147162
}
148163

149164
static inline int qspi_prepare_quad_program(const struct device *dev,
@@ -329,7 +344,10 @@ static int flash_stm32_qspi_read(const struct device *dev, off_t addr,
329344
};
330345

331346
qspi_set_address_size(dev, &cmd);
332-
qspi_prepare_quad_read(dev, &cmd);
347+
ret = qspi_prepare_quad_read(dev, &cmd);
348+
if (ret < 0) {
349+
return ret;
350+
}
333351
qspi_lock_thread(dev);
334352

335353
ret = qspi_read_access(dev, &cmd, data, size);
@@ -884,34 +902,52 @@ static int spi_nor_process_bfp(const struct device *dev,
884902
}
885903
}
886904
}
905+
887906
/*
888-
* Only check if the 1-4-4 (i.e. 4READ) fast read operation is
889-
* supported - other modes - e.g. 1-1-4 (QREAD) or 1-1-2 (DREAD) are
890-
* not.
907+
* Only check if the 1-4-4 (i.e. 4READ) or 1-1-4 (QREAD)
908+
* is supported - other modes are not.
891909
*/
892910
if (IS_ENABLED(STM32_QSPI_USE_QUAD_IO)) {
911+
const enum jesd216_mode_type supported_modes[] = { JESD216_MODE_114,
912+
JESD216_MODE_144 };
913+
struct jesd216_bfp_dw15 dw15;
893914
struct jesd216_instr res;
894915

895-
rc = jesd216_bfp_read_support(php, bfp, JESD216_MODE_144, &res);
896-
if (rc > 0) {
897-
/* Program flash memory to use SIO[0123] */
898-
rc = qspi_program_quad_io(dev);
899-
if (rc) {
900-
LOG_ERR("Unable to enable QUAD IO mode: %d\n",
901-
rc);
902-
return rc;
903-
}
916+
/* reset active mode */
917+
data->mode = STM32_QSPI_UNKNOWN_MODE;
904918

905-
LOG_INF("Mode: 1-4-4 with instr:[0x%x] supported!",
906-
res.instr);
919+
/* query supported read modes, begin from the slowest */
920+
for (size_t i = 0; i < ARRAY_SIZE(supported_modes); ++i) {
921+
rc = jesd216_bfp_read_support(php, bfp, supported_modes[i], &res);
922+
if (rc >= 0) {
923+
LOG_INF("Quad read mode %d instr [0x%x] supported",
924+
supported_modes[i], res.instr);
907925

908-
data->qspi_read_cmd = res.instr;
909-
data->qspi_read_cmd_latency = res.wait_states;
910-
if (res.mode_clocks) {
911-
data->qspi_read_cmd_latency +=
912-
res.mode_clocks;
926+
data->mode = supported_modes[i];
927+
data->qspi_read_cmd = res.instr;
928+
data->qspi_read_cmd_latency = res.wait_states;
929+
930+
if (res.mode_clocks) {
931+
data->qspi_read_cmd_latency += res.mode_clocks;
932+
}
913933
}
914934
}
935+
936+
/* don't continue when there is no supported mode */
937+
if (data->mode == STM32_QSPI_UNKNOWN_MODE) {
938+
LOG_ERR("No supported flash read mode found");
939+
return -ENOTSUP;
940+
}
941+
942+
LOG_INF("Quad read mode %d instr [0x%x] will be used", data->mode, res.instr);
943+
944+
/* enable QE */
945+
rc = qspi_program_quad_io(dev);
946+
if (rc < 0) {
947+
LOG_ERR("Failed to enable Quad mode: %d", rc);
948+
return rc;
949+
}
950+
915951
}
916952

917953
return 0;

0 commit comments

Comments
 (0)