Skip to content

Commit 6c308a7

Browse files
committed
[nrf fromtree] drivers: flash_mspi_nor: Get info from dts SFDP arrays
Get parameters for used flash commands and requirements for enabling Quad and Octal modes from dts uint8-arrays containing data read from SFDP tables for particular flash chips. Also introduce `pre_init` quirk that allows alteration of the above parameters or complementation of them in a specific way for particular flash chip families. Signed-off-by: Andrzej Głąbek <[email protected]> (cherry picked from commit 29bc5bf)
1 parent 0868478 commit 6c308a7

File tree

8 files changed

+577
-18
lines changed

8 files changed

+577
-18
lines changed

boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ slot3_partition: &cpurad_slot1_partition {
285285
30 b0 30 b0 f4 bd d5 5c 00 00 00 ff 10 10 00 20
286286
00 00 00 00 00 00 7c 23 48 00 00 00 00 00 88 88
287287
];
288+
sfdp-ff05 = [
289+
00 ee c0 69 72 72 71 71 00 d8 f7 f6 00 0a 00 00
290+
14 45 98 80
291+
];
292+
sfdp-ff84 = [
293+
43 06 0f 00 21 dc ff ff
294+
];
288295
size = <67108864>;
289296
has-dpd;
290297
t-enter-dpd = <10000>;

boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,13 @@ ipc0: &cpuapp_cpurad_ipc {
265265
30 b0 30 b0 f4 bd d5 5c 00 00 00 ff 10 10 00 20
266266
00 00 00 00 00 00 7c 23 48 00 00 00 00 00 88 88
267267
];
268+
sfdp-ff05 = [
269+
00 ee c0 69 72 72 71 71 00 d8 f7 f6 00 0a 00 00
270+
14 45 98 80
271+
];
272+
sfdp-ff84 = [
273+
43 06 0f 00 21 dc ff ff
274+
];
268275
size = <67108864>;
269276
has-dpd;
270277
t-enter-dpd = <10000>;

drivers/flash/Kconfig.mspi

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ menuconfig FLASH_MSPI_NOR
3939

4040
if FLASH_MSPI_NOR
4141

42+
config FLASH_MSPI_NOR_USE_SFDP
43+
bool "Use Serial Flash Discoverable Parameters (SFDP)"
44+
default $(dt_compat_any_has_prop,$(DT_COMPAT_JEDEC_MSPI_NOR),sfdp-bfp)
45+
help
46+
Use information from SFDP for setting up flash command transfers
47+
and for configuring the flash chip.
48+
49+
Currently, only build time processing of SFDP structures is supported,
50+
based on dts arrays provided as flash node properties like `sfdp-bfp`,
51+
`sfdp-ff05`, and `sfdp-ff84`. Depending on the IO mode used, some or
52+
all of these properties are required for building the flash driver.
53+
Data for these properties can be obtained with the `drivers/jesd216`
54+
sample. If a given SFDP table is not available in a flash chip,
55+
the related property can be defined as an empty array - this will
56+
prevent a related build assertion from failing and default values
57+
will be assigned to parameters that would otherwise be read from
58+
that SFDP table.
59+
4260
config FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE
4361
int "Page size to use for FLASH_LAYOUT feature"
4462
depends on FLASH_PAGE_LAYOUT

drivers/flash/flash_mspi_nor.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
#include <zephyr/pm/device_runtime.h>
1313

1414
#include "flash_mspi_nor.h"
15-
#include "flash_mspi_nor_quirks.h"
15+
#include "flash_mspi_nor_sfdp.h"
1616

1717
LOG_MODULE_REGISTER(flash_mspi_nor, CONFIG_FLASH_LOG_LEVEL);
1818

19+
#include "flash_mspi_nor_quirks.h"
20+
1921
void flash_mspi_command_set(const struct device *dev, const struct flash_mspi_nor_cmd *cmd)
2022
{
2123
struct flash_mspi_nor_data *dev_data = dev->data;
@@ -110,7 +112,9 @@ static inline uint32_t dev_flash_size(const struct device *dev)
110112

111113
static inline uint16_t dev_page_size(const struct device *dev)
112114
{
113-
return SPI_NOR_PAGE_SIZE;
115+
const struct flash_mspi_nor_config *dev_config = dev->config;
116+
117+
return dev_config->page_size;
114118
}
115119

116120
static int api_read(const struct device *dev, off_t addr, void *dest,
@@ -534,7 +538,7 @@ static int quad_enable_set(const struct device *dev, bool enable)
534538
return rc;
535539
}
536540

537-
if (dev_config->dw15_qer == JESD216_DW15_QER_VAL_S1B6) {
541+
if (dev_data->switch_info.quad_enable_req == JESD216_DW15_QER_VAL_S1B6) {
538542
const struct flash_mspi_nor_cmd cmd_status = {
539543
.dir = MSPI_TX,
540544
.cmd = SPI_NOR_CMD_WRSR,
@@ -570,10 +574,11 @@ static int quad_enable_set(const struct device *dev, bool enable)
570574
static int default_io_mode(const struct device *dev)
571575
{
572576
const struct flash_mspi_nor_config *dev_config = dev->config;
577+
struct flash_mspi_nor_data *dev_data = dev->data;
573578
enum mspi_io_mode io_mode = dev_config->mspi_nor_cfg.io_mode;
574579
int rc = 0;
575580

576-
if (dev_config->dw15_qer != JESD216_DW15_QER_VAL_NONE) {
581+
if (dev_data->switch_info.quad_enable_req != JESD216_DW15_QER_VAL_NONE) {
577582
/* For Quad 1-1-4 and 1-4-4, entering or leaving mode is defined
578583
* in JEDEC216 BFP DW15 QER
579584
*/
@@ -657,7 +662,7 @@ static int flash_chip_init(const struct device *dev)
657662
/* Some chips reuse RESET pin for data in Quad modes:
658663
* force single line mode before resetting.
659664
*/
660-
if (dev_config->dw15_qer != JESD216_DW15_QER_VAL_NONE &&
665+
if (dev_data->switch_info.quad_enable_req != JESD216_DW15_QER_VAL_NONE &&
661666
(io_mode == MSPI_IO_MODE_SINGLE ||
662667
io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
663668
io_mode == MSPI_IO_MODE_QUAD_1_4_4)) {
@@ -685,6 +690,11 @@ static int flash_chip_init(const struct device *dev)
685690
}
686691
#endif
687692

693+
if (dev_config->quirks != NULL &&
694+
dev_config->quirks->pre_init != NULL) {
695+
rc = dev_config->quirks->pre_init(dev);
696+
}
697+
688698
flash_mspi_command_set(dev, &commands_single.id);
689699
dev_data->packet.data_buf = id;
690700
dev_data->packet.num_bytes = sizeof(id);
@@ -749,6 +759,11 @@ static int drv_init(const struct device *dev)
749759
return -ENODEV;
750760
}
751761

762+
memcpy(dev_data->erase_types, dev_config->default_erase_types,
763+
sizeof(dev_data->erase_types));
764+
dev_data->cmd_info = dev_config->default_cmd_info;
765+
dev_data->switch_info = dev_config->default_switch_info;
766+
752767
rc = pm_device_runtime_get(dev_config->bus);
753768
if (rc < 0) {
754769
LOG_ERR("pm_device_runtime_get() failed: %d", rc);
@@ -800,8 +815,6 @@ static DEVICE_API(flash, drv_api) = {
800815
.dqs_enable = false, \
801816
}
802817

803-
#define FLASH_SIZE_INST(inst) (DT_INST_PROP(inst, size) / 8)
804-
805818
/* Define copies of mspi_io_mode enum values, so they can be used inside
806819
* the COND_CODE_1 macros.
807820
*/
@@ -836,23 +849,17 @@ extern const struct flash_mspi_nor_cmds mspi_io_mode_not_supported;
836849

837850
#define FLASH_QUIRKS(inst) FLASH_MSPI_QUIRKS_GET(DT_DRV_INST(inst))
838851

839-
#define FLASH_DW15_QER_VAL(inst) _CONCAT(JESD216_DW15_QER_VAL_, \
840-
DT_INST_STRING_TOKEN(inst, quad_enable_requirements))
841-
#define FLASH_DW15_QER(inst) COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, quad_enable_requirements), \
842-
(FLASH_DW15_QER_VAL(inst)), (JESD216_DW15_QER_VAL_NONE))
843-
844-
845852
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
846853
BUILD_ASSERT((CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE % 4096) == 0,
847854
"MSPI_NOR_FLASH_LAYOUT_PAGE_SIZE must be multiple of 4096");
848855
#define FLASH_PAGE_LAYOUT_DEFINE(inst) \
849856
.layout = { \
850857
.pages_size = CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE, \
851-
.pages_count = FLASH_SIZE_INST(inst) \
858+
.pages_count = FLASH_SIZE(inst) \
852859
/ CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE, \
853860
},
854861
#define FLASH_PAGE_LAYOUT_CHECK(inst) \
855-
BUILD_ASSERT((FLASH_SIZE_INST(inst) % CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE) == 0, \
862+
BUILD_ASSERT((FLASH_SIZE(inst) % CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE) == 0, \
856863
"MSPI_NOR_FLASH_LAYOUT_PAGE_SIZE incompatible with flash size, instance " #inst);
857864
#else
858865
#define FLASH_PAGE_LAYOUT_DEFINE(inst)
@@ -874,11 +881,14 @@ BUILD_ASSERT((FLASH_SIZE_INST(inst) % CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE) ==
874881
(DT_INST_ENUM_IDX(inst, mspi_io_mode) == \
875882
MSPI_IO_MODE_OCTAL), \
876883
"Only 1x, 1-4-4 and 8x I/O modes are supported for now"); \
884+
SFDP_BUILD_ASSERTS(inst); \
877885
PM_DEVICE_DT_INST_DEFINE(inst, dev_pm_action_cb); \
886+
DEFAULT_ERASE_TYPES_DEFINE(inst); \
878887
static struct flash_mspi_nor_data dev##inst##_data; \
879888
static const struct flash_mspi_nor_config dev##inst##_config = { \
880889
.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
881-
.flash_size = FLASH_SIZE_INST(inst), \
890+
.flash_size = FLASH_SIZE(inst), \
891+
.page_size = FLASH_PAGE_SIZE(inst), \
882892
.mspi_id = MSPI_DEVICE_ID_DT_INST(inst), \
883893
.mspi_nor_cfg = MSPI_DEVICE_CONFIG_DT_INST(inst), \
884894
.mspi_nor_init_cfg = FLASH_INITIAL_CONFIG(inst), \
@@ -899,7 +909,9 @@ BUILD_ASSERT((FLASH_SIZE_INST(inst) % CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE) ==
899909
.jedec_id = DT_INST_PROP(inst, jedec_id), \
900910
.jedec_cmds = FLASH_CMDS(inst), \
901911
.quirks = FLASH_QUIRKS(inst), \
902-
.dw15_qer = FLASH_DW15_QER(inst), \
912+
.default_erase_types = DEFAULT_ERASE_TYPES(inst), \
913+
.default_cmd_info = DEFAULT_CMD_INFO(inst), \
914+
.default_switch_info = DEFAULT_SWITCH_INFO(inst), \
903915
}; \
904916
FLASH_PAGE_LAYOUT_CHECK(inst) \
905917
DEVICE_DT_INST_DEFINE(inst, \

drivers/flash/flash_mspi_nor.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,52 @@ extern "C" {
2020
#define WITH_RESET_GPIO 1
2121
#endif
2222

23+
#define CMD_EXTENSION_NONE 0
24+
#define CMD_EXTENSION_SAME 1
25+
#define CMD_EXTENSION_INVERSE 2
26+
27+
#define OCTAL_ENABLE_REQ_NONE 0
28+
#define OCTAL_ENABLE_REQ_S2B3 1
29+
30+
#define ENTER_4BYTE_ADDR_NONE 0
31+
#define ENTER_4BYTE_ADDR_B7 1
32+
#define ENTER_4BYTE_ADDR_06_B7 2
33+
34+
struct flash_mspi_nor_cmd_info {
35+
uint8_t read_cmd;
36+
uint8_t read_mode_bit_cycles : 3;
37+
uint8_t read_dummy_cycles : 5;
38+
uint8_t pp_cmd;
39+
bool uses_4byte_addr : 1;
40+
/* BFP, 18th DWORD, bits 30-29 */
41+
uint8_t cmd_extension : 2;
42+
/* xSPI Profile 1.0 (ID FF05), 1st DWORD: */
43+
/* - Read SFDP command address bytes: 4 (true) or 3 */
44+
bool sfdp_addr_4 : 1;
45+
/* - Read SDFP command dummy cycles: 20 (true) or 8 */
46+
bool sfdp_dummy_20 : 1;
47+
/* - Read Status Register command address bytes: 4 (true) or 0 */
48+
bool rdsr_addr_4 : 1;
49+
/* - Read Status Register command dummy cycles: 0, 4, or 8 */
50+
uint8_t rdsr_dummy : 4;
51+
/* - Read JEDEC ID command parameters; not sure where to get their
52+
* values from, but since for many flash chips they are the same
53+
* as for RDSR, those are taken as defaults, see DEFAULT_CMD_INFO()
54+
*/
55+
bool rdid_addr_4 : 1;
56+
uint8_t rdid_dummy : 4;
57+
};
58+
59+
struct flash_mspi_nor_switch_info {
60+
uint8_t quad_enable_req : 3;
61+
uint8_t octal_enable_req : 3;
62+
uint8_t enter_4byte_addr : 2;
63+
};
64+
2365
struct flash_mspi_nor_config {
2466
const struct device *bus;
2567
uint32_t flash_size;
68+
uint16_t page_size;
2669
struct mspi_dev_id mspi_id;
2770
struct mspi_dev_cfg mspi_nor_cfg;
2871
struct mspi_dev_cfg mspi_nor_init_cfg;
@@ -42,14 +85,19 @@ struct flash_mspi_nor_config {
4285
uint8_t jedec_id[SPI_NOR_MAX_ID_LEN];
4386
const struct flash_mspi_nor_cmds *jedec_cmds;
4487
struct flash_mspi_nor_quirks *quirks;
45-
uint8_t dw15_qer;
88+
const struct jesd216_erase_type *default_erase_types;
89+
struct flash_mspi_nor_cmd_info default_cmd_info;
90+
struct flash_mspi_nor_switch_info default_switch_info;
4691
};
4792

4893
struct flash_mspi_nor_data {
4994
struct k_sem acquired;
5095
struct mspi_xfer_packet packet;
5196
struct mspi_xfer xfer;
5297
struct mspi_dev_cfg *curr_cfg;
98+
struct jesd216_erase_type erase_types[JESD216_NUM_ERASE_TYPES];
99+
struct flash_mspi_nor_cmd_info cmd_info;
100+
struct flash_mspi_nor_switch_info switch_info;
53101
};
54102

55103
struct flash_mspi_nor_cmd {

drivers/flash/flash_mspi_nor_quirks.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99

1010
/* Flash chip specific quirks */
1111
struct flash_mspi_nor_quirks {
12+
/* Called at the beginning of the flash chip initialization,
13+
* right after reset if any is performed. Can be used to alter
14+
* structures that define communication with the chip, like
15+
* `cmd_info`, `switch_info`, and `erase_types`, which are set
16+
* to default values at this point.
17+
*/
18+
int (*pre_init)(const struct device *dev);
1219
/* Called after switching to default IO mode. */
1320
int (*post_switch_mode)(const struct device *dev);
1421
};
@@ -176,7 +183,56 @@ static inline int mxicy_mx25u_post_switch_mode(const struct device *dev)
176183
return rc;
177184
}
178185

186+
static int mxicy_mx25u_pre_init(const struct device *dev)
187+
{
188+
const struct flash_mspi_nor_config *dev_config = dev->config;
189+
struct flash_mspi_nor_data *dev_data = dev->data;
190+
static const uint8_t dummy_cycles[8] = {
191+
20, 18, 16, 14, 12, 10, 8, 6
192+
};
193+
uint8_t cfg_reg;
194+
int rc;
195+
196+
if (dev_config->mspi_nor_cfg.io_mode != MSPI_IO_MODE_OCTAL) {
197+
return 0;
198+
}
199+
200+
if (dev_config->mspi_nor_cfg.data_rate == MSPI_DATA_RATE_SINGLE) {
201+
dev_data->cmd_info.cmd_extension = CMD_EXTENSION_INVERSE;
202+
}
203+
204+
/*
205+
* TODO - replace this with a generic routine that uses information
206+
* from SFDP header FF87 (Status, Control and Configuration
207+
* Register Map)
208+
*/
209+
210+
/* Read configured number of dummy cycles for memory reading commands. */
211+
const struct flash_mspi_nor_cmd cmd_rd_cr2 = {
212+
.dir = MSPI_RX,
213+
.cmd = SPI_NOR_CMD_RD_CFGREG2,
214+
.cmd_length = 1,
215+
.addr_length = 4,
216+
};
217+
218+
flash_mspi_command_set(dev, &cmd_rd_cr2);
219+
dev_data->packet.address = 0x300;
220+
dev_data->packet.data_buf = &cfg_reg;
221+
dev_data->packet.num_bytes = sizeof(cfg_reg);
222+
rc = mspi_transceive(dev_config->bus, &dev_config->mspi_id, &dev_data->xfer);
223+
if (rc < 0) {
224+
LOG_ERR("Failed to read Dummy Cycle from CFGREG2");
225+
return rc;
226+
}
227+
228+
dev_data->cmd_info.read_mode_bit_cycles = 0;
229+
dev_data->cmd_info.read_dummy_cycles = dummy_cycles[cfg_reg & 0x7];
230+
231+
return 0;
232+
}
233+
179234
struct flash_mspi_nor_quirks flash_quirks_mxicy_mx25u = {
235+
.pre_init = mxicy_mx25u_pre_init,
180236
.post_switch_mode = mxicy_mx25u_post_switch_mode,
181237
};
182238

0 commit comments

Comments
 (0)