Skip to content

Commit a9962be

Browse files
utsavm9anangl
authored andcommitted
[nrf fromtree] driver: flash_mspi_nor: Allow specific read/write IO modes and frequencies
The driver currently provides no way to use Dual IO Read and Single IO for the rest of the commands currently, and would erroneously use Single IO PP command in Dual IO mode. This PR fixes and adds support for that. Signed-off-by: Utsav Munendra <[email protected]> (cherry picked from commit c696414)
1 parent d72398f commit a9962be

File tree

3 files changed

+132
-26
lines changed

3 files changed

+132
-26
lines changed

drivers/flash/flash_mspi_nor.c

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ static bool in_octal_io(const struct device *dev)
4343
dev_data->last_applied_cfg->io_mode == MSPI_IO_MODE_OCTAL;
4444
}
4545

46+
static bool is_quad_enable_needed(const struct mspi_dev_cfg *cfg)
47+
{
48+
return cfg && (cfg->io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
49+
cfg->io_mode == MSPI_IO_MODE_QUAD_1_4_4);
50+
}
51+
52+
static bool is_octal_enable_needed(const struct mspi_dev_cfg *cfg)
53+
{
54+
return cfg && (cfg->io_mode == MSPI_IO_MODE_OCTAL_1_1_8 ||
55+
cfg->io_mode == MSPI_IO_MODE_OCTAL_1_8_8);
56+
}
57+
4658
static void set_up_xfer(const struct device *dev, enum mspi_xfer_direction dir)
4759
{
4860
const struct flash_mspi_nor_config *dev_config = dev->config;
@@ -89,8 +101,6 @@ static int perform_xfer(const struct device *dev, uint8_t cmd)
89101
const struct flash_mspi_nor_config *dev_config = dev->config;
90102
struct flash_mspi_nor_data *dev_data = dev->data;
91103
const struct mspi_dev_cfg *cfg = NULL;
92-
bool mem_access = (cmd == dev_data->cmd_info.read_cmd ||
93-
cmd == dev_data->cmd_info.pp_cmd);
94104
int rc;
95105

96106
if (dev_data->cmd_info.cmd_extension != CMD_EXTENSION_NONE &&
@@ -102,25 +112,21 @@ static int perform_xfer(const struct device *dev, uint8_t cmd)
102112
dev_data->packet.cmd = cmd;
103113
}
104114

105-
if (!dev_data->chip_initialized ||
106-
dev_config->multi_io_cmd ||
107-
dev_config->mspi_nor_cfg.io_mode == MSPI_IO_MODE_SINGLE) {
108-
/* Commands before chip is initialized manually apply a MSPI config
109-
* which all flash chips support by JEDEC standard. Do not switch
110-
* to device tree config yet.
111-
* If multiple IO lines are used in all the transfer phases
112-
* there's no need to switch the IO mode.
113-
*/
114-
} else if (mem_access) {
115-
/* For commands accessing the flash memory (read and program),
116-
* ensure that the target IO mode is active.
117-
*/
118-
if (!in_octal_io(dev)) {
119-
cfg = &dev_config->mspi_nor_cfg;
115+
/* Commands before chip is initialized manually apply a MSPI config
116+
* which all flash chips support by JEDEC standard. Do not switch
117+
* to device tree config yet.
118+
* If multiple IO lines are used in all the transfer phases
119+
* there's no need to switch the IO mode.
120+
*/
121+
if (dev_data->chip_initialized && !dev_config->multi_io_cmd) {
122+
if (cmd == dev_data->cmd_info.read_cmd) {
123+
cfg = dev_data->read_cfg;
124+
} else if (cmd == dev_data->cmd_info.pp_cmd) {
125+
cfg = dev_data->write_cfg;
126+
} else {
127+
/* For all other commands, use control command config */
128+
cfg = &dev_config->mspi_control_cfg;
120129
}
121-
} else {
122-
/* For all other commands, use control command config */
123-
cfg = &dev_config->mspi_control_cfg;
124130
}
125131

126132
if (cfg && cfg != dev_data->last_applied_cfg) {
@@ -824,12 +830,11 @@ static int switch_to_target_io_mode(const struct device *dev)
824830
{
825831
const struct flash_mspi_nor_config *dev_config = dev->config;
826832
struct flash_mspi_nor_data *dev_data = dev->data;
827-
enum mspi_io_mode io_mode = dev_config->mspi_nor_cfg.io_mode;
828833
int rc = 0;
829834

830835
if (dev_data->switch_info.quad_enable_req != JESD216_DW15_QER_VAL_NONE) {
831-
bool quad_needed = io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
832-
io_mode == MSPI_IO_MODE_QUAD_1_4_4;
836+
bool quad_needed = is_quad_enable_needed(dev_data->read_cfg) ||
837+
is_quad_enable_needed(dev_data->write_cfg);
833838

834839
rc = quad_enable_set(dev, quad_needed);
835840
if (rc < 0) {
@@ -839,8 +844,8 @@ static int switch_to_target_io_mode(const struct device *dev)
839844
}
840845

841846
if (dev_data->switch_info.octal_enable_req != OCTAL_ENABLE_REQ_NONE) {
842-
bool octal_needed = io_mode == MSPI_IO_MODE_OCTAL_1_1_8 ||
843-
io_mode == MSPI_IO_MODE_OCTAL_1_8_8;
847+
bool octal_needed = is_octal_enable_needed(dev_data->read_cfg) ||
848+
is_octal_enable_needed(dev_data->write_cfg);
844849

845850
rc = octal_enable_set(dev, octal_needed);
846851
if (rc < 0) {
@@ -1089,6 +1094,33 @@ static int flash_chip_init(const struct device *dev)
10891094
}
10901095
}
10911096

1097+
/* If read/write commands and frequency do not match the default
1098+
* MSPI device configuration, store new ones for those commands
1099+
* specifically.
1100+
*/
1101+
if (dev_config->read_io_mode == dev_config->mspi_nor_cfg.io_mode &&
1102+
dev_config->read_freq == dev_config->mspi_nor_cfg.freq) {
1103+
dev_data->read_cfg = &dev_config->mspi_nor_cfg;
1104+
} else {
1105+
memcpy(&dev_data->mspi_dev_read_cfg, &dev_config->mspi_nor_cfg,
1106+
sizeof(dev_config->mspi_nor_cfg));
1107+
dev_data->mspi_dev_read_cfg.io_mode = dev_config->read_io_mode;
1108+
dev_data->mspi_dev_read_cfg.freq = dev_config->read_freq;
1109+
dev_data->read_cfg = &dev_data->mspi_dev_read_cfg;
1110+
}
1111+
1112+
if (dev_config->write_io_mode == dev_config->mspi_nor_cfg.io_mode &&
1113+
dev_config->write_freq == dev_config->mspi_nor_cfg.freq) {
1114+
dev_data->write_cfg = &dev_config->mspi_nor_cfg;
1115+
} else {
1116+
memcpy(&dev_data->mspi_dev_write_cfg, &dev_config->mspi_nor_cfg,
1117+
sizeof(dev_config->mspi_nor_cfg));
1118+
dev_data->mspi_dev_write_cfg.io_mode = dev_config->write_io_mode;
1119+
dev_data->mspi_dev_write_cfg.freq = dev_config->write_freq;
1120+
dev_data->write_cfg = &dev_data->mspi_dev_write_cfg;
1121+
}
1122+
1123+
10921124
if (dev_config->jedec_id_specified) {
10931125
rc = read_jedec_id(dev, id);
10941126
if (rc < 0) {
@@ -1263,10 +1295,12 @@ static DEVICE_API(flash, drv_api) = {
12631295
#endif
12641296
};
12651297

1298+
#define FLASH_MSPI_MAX_FREQ(inst) DT_INST_PROP(inst, mspi_max_frequency)
1299+
12661300
#define FLASH_CONTROL_CMD_CONFIG(inst) \
12671301
{ \
12681302
.ce_num = DT_INST_PROP_OR(inst, mspi_hardware_ce_num, 0), \
1269-
.freq = DT_INST_PROP(inst, mspi_max_frequency), \
1303+
.freq = FLASH_MSPI_MAX_FREQ(inst), \
12701304
.io_mode = MSPI_IO_MODE_SINGLE, \
12711305
.data_rate = MSPI_DATA_RATE_SINGLE, \
12721306
.cpp = MSPI_CPP_MODE_0, \
@@ -1350,6 +1384,14 @@ BUILD_ASSERT((FLASH_SIZE(inst) % CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE) == 0, \
13501384
.default_erase_types = DEFAULT_ERASE_TYPES(inst), \
13511385
.default_cmd_info = DEFAULT_CMD_INFO(inst), \
13521386
.default_switch_info = DEFAULT_SWITCH_INFO(inst), \
1387+
.read_freq = DT_INST_PROP_OR(inst, read_frequency, \
1388+
FLASH_MSPI_MAX_FREQ(inst)), \
1389+
.read_io_mode = DT_INST_ENUM_IDX_OR(inst, read_io_mode, \
1390+
DT_INST_ENUM_IDX(inst, mspi_io_mode)), \
1391+
.write_freq = DT_INST_PROP_OR(inst, write_frequency, \
1392+
FLASH_MSPI_MAX_FREQ(inst)), \
1393+
.write_io_mode = DT_INST_ENUM_IDX_OR(inst, write_io_mode, \
1394+
DT_INST_ENUM_IDX(inst, mspi_io_mode)), \
13531395
.jedec_id_specified = DT_INST_NODE_HAS_PROP(inst, jedec_id), \
13541396
.rx_dummy_specified = DT_INST_NODE_HAS_PROP(inst, rx_dummy), \
13551397
.multiperipheral_bus = DT_PROP(DT_INST_BUS(inst), \

drivers/flash/flash_mspi_nor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ struct flash_mspi_nor_config {
9696
const struct jesd216_erase_type *default_erase_types;
9797
struct flash_mspi_nor_cmd_info default_cmd_info;
9898
struct flash_mspi_nor_switch_info default_switch_info;
99+
uint32_t read_freq;
100+
enum mspi_io_mode read_io_mode;
101+
uint32_t write_freq;
102+
enum mspi_io_mode write_io_mode;
99103
bool jedec_id_specified : 1;
100104
bool rx_dummy_specified : 1;
101105
bool multiperipheral_bus : 1;
@@ -115,6 +119,10 @@ struct flash_mspi_nor_data {
115119
struct flash_mspi_nor_switch_info switch_info;
116120
const struct mspi_dev_cfg *last_applied_cfg;
117121
bool chip_initialized;
122+
const struct mspi_dev_cfg *read_cfg;
123+
struct mspi_dev_cfg mspi_dev_read_cfg;
124+
const struct mspi_dev_cfg *write_cfg;
125+
struct mspi_dev_cfg mspi_dev_write_cfg;
118126
};
119127

120128
#ifdef __cplusplus

dts/bindings/mtd/jedec,mspi-nor.yaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,62 @@ include:
2121
- t-exit-dpd
2222

2323
properties:
24+
read-frequency:
25+
type: int
26+
description: |
27+
Clock frequency of device to configure in Hz for read
28+
command, when reads are desired to be in a different
29+
frequency than the rest of the commands.
30+
31+
read-io-mode:
32+
type: string
33+
enum:
34+
- "MSPI_IO_MODE_SINGLE"
35+
- "MSPI_IO_MODE_DUAL"
36+
- "MSPI_IO_MODE_DUAL_1_1_2"
37+
- "MSPI_IO_MODE_DUAL_1_2_2"
38+
- "MSPI_IO_MODE_QUAD"
39+
- "MSPI_IO_MODE_QUAD_1_1_4"
40+
- "MSPI_IO_MODE_QUAD_1_4_4"
41+
- "MSPI_IO_MODE_OCTAL"
42+
- "MSPI_IO_MODE_OCTAL_1_1_8"
43+
- "MSPI_IO_MODE_OCTAL_1_8_8"
44+
- "MSPI_IO_MODE_HEX"
45+
- "MSPI_IO_MODE_HEX_8_8_16"
46+
- "MSPI_IO_MODE_HEX_8_16_16"
47+
description: |
48+
MSPI I/O mode setting for read command when desired to
49+
be different from base device `mspi-io-mode` for the rest
50+
of the commands.
51+
52+
write-frequency:
53+
type: int
54+
description: |
55+
Clock frequency of device to configure in Hz for write
56+
command, when write are desired to be in a different
57+
frequency than the rest of the commands.
58+
59+
write-io-mode:
60+
type: string
61+
enum:
62+
- "MSPI_IO_MODE_SINGLE"
63+
- "MSPI_IO_MODE_DUAL"
64+
- "MSPI_IO_MODE_DUAL_1_1_2"
65+
- "MSPI_IO_MODE_DUAL_1_2_2"
66+
- "MSPI_IO_MODE_QUAD"
67+
- "MSPI_IO_MODE_QUAD_1_1_4"
68+
- "MSPI_IO_MODE_QUAD_1_4_4"
69+
- "MSPI_IO_MODE_OCTAL"
70+
- "MSPI_IO_MODE_OCTAL_1_1_8"
71+
- "MSPI_IO_MODE_OCTAL_1_8_8"
72+
- "MSPI_IO_MODE_HEX"
73+
- "MSPI_IO_MODE_HEX_8_8_16"
74+
- "MSPI_IO_MODE_HEX_8_16_16"
75+
description: |
76+
MSPI I/O mode setting for write command when desired to
77+
be different from base device `mspi-io-mode` for the rest
78+
of the commands.
79+
2480
reset-gpios:
2581
type: phandle-array
2682
description: |

0 commit comments

Comments
 (0)