|
1 | 1 | /* |
2 | 2 | * Copyright (c) 2020 Piotr Mienkowski |
3 | 3 | * Copyright (c) 2020 Linaro Limited |
| 4 | + * Copyright (c) 2022 Georgij Cernysiov |
4 | 5 | * |
5 | 6 | * SPDX-License-Identifier: Apache-2.0 |
6 | 7 | */ |
@@ -91,6 +92,7 @@ struct flash_stm32_qspi_data { |
91 | 92 | uint16_t page_size; |
92 | 93 | int cmd_status; |
93 | 94 | struct stream dma; |
| 95 | + uint8_t qspi_write_cmd; |
94 | 96 | uint8_t qspi_read_cmd; |
95 | 97 | uint8_t qspi_read_cmd_latency; |
96 | 98 | /* |
@@ -144,25 +146,30 @@ static inline void qspi_prepare_quad_read(const struct device *dev, |
144 | 146 | } |
145 | 147 | } |
146 | 148 |
|
147 | | -static inline void qspi_prepare_quad_program(const struct device *dev, |
| 149 | +static inline int qspi_prepare_quad_program(const struct device *dev, |
148 | 150 | QSPI_CommandTypeDef *cmd) |
149 | 151 | { |
150 | 152 | struct flash_stm32_qspi_data *dev_data = dev->data; |
151 | | - /* |
152 | | - * There is no info about PP/4PP command in the SFDP tables, |
153 | | - * hence it has been assumed that NOR flash memory supporting |
154 | | - * 1-4-4 mode also would support fast page programming. |
155 | | - */ |
| 153 | + |
156 | 154 | if (IS_ENABLED(STM32_QSPI_USE_QUAD_IO) && dev_data->flag_quad_io_en) { |
157 | | - cmd->Instruction = SPI_NOR_CMD_4PP; |
158 | | - cmd->AddressMode = QSPI_ADDRESS_4_LINES; |
| 155 | + cmd->Instruction = dev_data->qspi_write_cmd; |
| 156 | + |
| 157 | + switch (cmd->Instruction) { |
| 158 | + case SPI_NOR_CMD_PP_1_1_4: |
| 159 | + cmd->AddressMode = QSPI_ADDRESS_1_LINE; |
| 160 | + break; |
| 161 | + case SPI_NOR_CMD_PP_1_4_4: |
| 162 | + cmd->AddressMode = QSPI_ADDRESS_4_LINES; |
| 163 | + break; |
| 164 | + default: |
| 165 | + return -ENOTSUP; |
| 166 | + } |
| 167 | + |
159 | 168 | cmd->DataMode = QSPI_DATA_4_LINES; |
160 | | - /* |
161 | | - * Dummy cycles are not required for 4PP command - |
162 | | - * data to be programmed are sent just after address. |
163 | | - */ |
164 | 169 | cmd->DummyCycles = 0; |
165 | 170 | } |
| 171 | + |
| 172 | + return 0; |
166 | 173 | } |
167 | 174 |
|
168 | 175 | /* |
@@ -379,7 +386,10 @@ static int flash_stm32_qspi_write(const struct device *dev, off_t addr, |
379 | 386 | }; |
380 | 387 |
|
381 | 388 | qspi_set_address_size(dev, &cmd_pp); |
382 | | - qspi_prepare_quad_program(dev, &cmd_pp); |
| 389 | + ret = qspi_prepare_quad_program(dev, &cmd_pp); |
| 390 | + if (ret < 0) { |
| 391 | + return ret; |
| 392 | + } |
383 | 393 | qspi_lock_thread(dev); |
384 | 394 |
|
385 | 395 | while (size > 0) { |
@@ -1141,6 +1151,11 @@ static int flash_stm32_qspi_init(const struct device *dev) |
1141 | 1151 |
|
1142 | 1152 | static void flash_stm32_qspi_irq_config_func(const struct device *dev); |
1143 | 1153 |
|
| 1154 | +#define DT_WRITEOC_PROP_OR(inst, default_value) \ |
| 1155 | + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, writeoc), \ |
| 1156 | + (_CONCAT(SPI_NOR_CMD_, DT_STRING_TOKEN(DT_DRV_INST(inst), writeoc))), \ |
| 1157 | + ((default_value))) |
| 1158 | + |
1144 | 1159 | #define STM32_QSPI_NODE DT_INST_PARENT(0) |
1145 | 1160 |
|
1146 | 1161 | PINCTRL_DT_DEFINE(STM32_QSPI_NODE); |
@@ -1170,6 +1185,7 @@ static struct flash_stm32_qspi_data flash_stm32_qspi_dev_data = { |
1170 | 1185 | .ClockMode = QSPI_CLOCK_MODE_0, |
1171 | 1186 | }, |
1172 | 1187 | }, |
| 1188 | + .qspi_write_cmd = DT_WRITEOC_PROP_OR(0, SPI_NOR_CMD_PP_1_4_4), |
1173 | 1189 | QSPI_DMA_CHANNEL(STM32_QSPI_NODE, tx_rx) |
1174 | 1190 | }; |
1175 | 1191 |
|
|
0 commit comments