1 /*
2  * Copyright 2021,2023 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT	nxp_imx_flexspi_mx25um51345g
8 
9 #include <zephyr/drivers/flash.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/irq.h>
12 #include <zephyr/sys/util.h>
13 #include "spi_nor.h"
14 #include "memc_mcux_flexspi.h"
15 
16 #ifdef CONFIG_HAS_MCUX_CACHE
17 #include <fsl_cache.h>
18 #endif
19 
20 #define NOR_ERASE_VALUE	0xff
21 
22 #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER
23 static uint8_t nor_write_buf[SPI_NOR_PAGE_SIZE];
24 #endif
25 
26 /*
27  * NOTE: If CONFIG_FLASH_MCUX_FLEXSPI_XIP is selected, Any external functions
28  * called while interacting with the flexspi MUST be relocated to SRAM or ITCM
29  * at runtime, so that the chip does not access the flexspi to read program
30  * instructions while it is being written to
31  *
32  * Additionally, no data used by this driver should be stored in flash.
33  */
34 #if defined(CONFIG_FLASH_MCUX_FLEXSPI_XIP) && (CONFIG_FLASH_LOG_LEVEL > 0)
35 #warning "Enabling flash driver logging and XIP mode simultaneously can cause \
36 	read-while-write hazards. This configuration is not recommended."
37 #endif
38 
39 /* FLASH_ENABLE_OCTAL_CMD: (01 = STR OPI Enable) , (02 = DTR OPI Enable) */
40 #if CONFIG_FLASH_MCUX_FLEXSPI_MX25UM51345G_OPI_DTR
41 #define NOR_FLASH_ENABLE_OCTAL_CMD 0x2
42 /* In OPI DTR mode, all writes must be 2 byte aligned, and multiples of 2 bytes */
43 #define NOR_WRITE_SIZE	2
44 #else
45 #define NOR_FLASH_ENABLE_OCTAL_CMD 0x1
46 #define NOR_WRITE_SIZE	1
47 #endif
48 
49 LOG_MODULE_REGISTER(flash_flexspi_nor, CONFIG_FLASH_LOG_LEVEL);
50 
51 enum {
52 	/* Instructions matching with XIP layout */
53 	READ,
54 	WRITE_ENABLE_OPI,
55 	WRITE_ENABLE,
56 	ERASE_SECTOR,
57 	PAGE_PROGRAM_INPUT,
58 	PAGE_PROGRAM,
59 	READ_ID_OPI,
60 	ENTER_OPI,
61 	READ_STATUS_REG,
62 	ERASE_CHIP,
63 };
64 
65 /* Device variables used in critical sections should be in this structure */
66 struct flash_flexspi_nor_data {
67 	const struct device *controller;
68 	flexspi_device_config_t config;
69 	flexspi_port_t port;
70 	uint64_t size;
71 	struct flash_pages_layout layout;
72 	struct flash_parameters flash_parameters;
73 };
74 
75 static const uint32_t flash_flexspi_nor_lut[][4] = {
76 	[READ_ID_OPI] = {
77 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x9F,
78 				kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x60),
79 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_DDR,	kFLEXSPI_8PAD, 0x20,
80 				kFLEXSPI_Command_DUMMY_DDR,	kFLEXSPI_8PAD, 0x16),
81 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR,	kFLEXSPI_8PAD, 0x04,
82 				kFLEXSPI_Command_STOP,		kFLEXSPI_1PAD, 0x0),
83 	},
84 
85 	[WRITE_ENABLE] = {
86 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_1PAD, 0x06,
87 				kFLEXSPI_Command_STOP,		kFLEXSPI_1PAD, 0),
88 	},
89 
90 	[ENTER_OPI] = {
91 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_1PAD, 0x72,
92 				kFLEXSPI_Command_RADDR_SDR,	kFLEXSPI_1PAD, 0x20),
93 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR,	kFLEXSPI_1PAD, 0x04,
94 				kFLEXSPI_Command_STOP,		kFLEXSPI_1PAD, 0),
95 	},
96 
97 #if (NOR_FLASH_ENABLE_OCTAL_CMD == 0x1)
98 	[READ_STATUS_REG] = {
99 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x05,
100 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0xFA),
101 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR,	kFLEXSPI_8PAD, 0x20,
102 				kFLEXSPI_Command_DUMMY_SDR,	kFLEXSPI_8PAD, 0x14),
103 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR,	kFLEXSPI_8PAD, 0x04,
104 				kFLEXSPI_Command_STOP,		kFLEXSPI_1PAD, 0x0),
105 	},
106 	[WRITE_ENABLE_OPI] = {
107 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x06,
108 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0xF9),
109 	},
110 
111 	[ERASE_SECTOR] = {
112 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x21,
113 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0xDE),
114 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR,	kFLEXSPI_8PAD, 0x20,
115 				kFLEXSPI_Command_STOP,		kFLEXSPI_8PAD, 0),
116 	},
117 
118 	[ERASE_CHIP] = {
119 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x60,
120 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x9F),
121 	},
122 
123 	[READ] = {
124 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0xEC,
125 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x13),
126 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR,	kFLEXSPI_8PAD, 0x20,
127 				kFLEXSPI_Command_DUMMY_SDR,	kFLEXSPI_8PAD, 0x14),
128 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR,	kFLEXSPI_8PAD, 0x04,
129 				kFLEXSPI_Command_STOP,		kFLEXSPI_1PAD, 0x0),
130 	},
131 
132 	[PAGE_PROGRAM] = {
133 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x12,
134 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0xED),
135 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR,	kFLEXSPI_8PAD, 0x20,
136 				kFLEXSPI_Command_WRITE_SDR,	kFLEXSPI_8PAD, 0x04),
137 	},
138 #else
139 	[READ_STATUS_REG] = {
140 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x05,
141 				kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0xFA),
142 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_DDR,	kFLEXSPI_8PAD, 0x20,
143 				kFLEXSPI_Command_READ_DDR,	kFLEXSPI_8PAD, 0x4),
144 	},
145 
146 	[WRITE_ENABLE_OPI] = {
147 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x06,
148 				kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0xF9),
149 	},
150 
151 	[ERASE_SECTOR] = {
152 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x21,
153 				kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0xDE),
154 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_DDR,	kFLEXSPI_8PAD, 0x20,
155 				kFLEXSPI_Command_STOP,		kFLEXSPI_8PAD, 0),
156 	},
157 
158 	[ERASE_CHIP] = {
159 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x60,
160 				kFLEXSPI_Command_SDR,		kFLEXSPI_8PAD, 0x9F),
161 	},
162 
163 	[READ] = {
164 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0xEE,
165 				kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x11),
166 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_DDR,	kFLEXSPI_8PAD, 0x20,
167 				kFLEXSPI_Command_DUMMY_DDR,	kFLEXSPI_8PAD, 0x08),
168 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR,	kFLEXSPI_8PAD, 0x04,
169 				kFLEXSPI_Command_STOP,		kFLEXSPI_1PAD, 0x0),
170 	},
171 
172 	[PAGE_PROGRAM] = {
173 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0x12,
174 				kFLEXSPI_Command_DDR,		kFLEXSPI_8PAD, 0xED),
175 		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_DDR,	kFLEXSPI_8PAD, 0x20,
176 				kFLEXSPI_Command_WRITE_DDR,	kFLEXSPI_8PAD, 0x04),
177 	},
178 #endif
179 
180 };
181 
flash_flexspi_nor_get_vendor_id(const struct device * dev,uint8_t * vendor_id)182 static int flash_flexspi_nor_get_vendor_id(const struct device *dev,
183 		uint8_t *vendor_id)
184 {
185 	struct flash_flexspi_nor_data *data = dev->data;
186 	uint32_t buffer = 0;
187 	int ret;
188 
189 	flexspi_transfer_t transfer = {
190 		.deviceAddress = 0,
191 		.port = data->port,
192 		.cmdType = kFLEXSPI_Read,
193 		.SeqNumber = 1,
194 		.seqIndex = READ_ID_OPI,
195 		.data = &buffer,
196 		.dataSize = 1,
197 	};
198 
199 	LOG_DBG("Reading id");
200 
201 	ret = memc_flexspi_transfer(data->controller, &transfer);
202 	*vendor_id = buffer;
203 
204 	return ret;
205 }
206 
flash_flexspi_nor_read_status(const struct device * dev,uint32_t * status)207 static int flash_flexspi_nor_read_status(const struct device *dev,
208 		uint32_t *status)
209 {
210 	struct flash_flexspi_nor_data *data = dev->data;
211 
212 	flexspi_transfer_t transfer = {
213 		.deviceAddress = 0,
214 		.port = data->port,
215 		.cmdType = kFLEXSPI_Read,
216 		.SeqNumber = 1,
217 		.seqIndex = READ_STATUS_REG,
218 		.data = status,
219 		.dataSize = 1,
220 	};
221 
222 	LOG_DBG("Reading status register");
223 
224 	return memc_flexspi_transfer(data->controller, &transfer);
225 }
226 
flash_flexspi_nor_write_status(const struct device * dev,uint32_t * status)227 static int flash_flexspi_nor_write_status(const struct device *dev,
228 		uint32_t *status)
229 {
230 	struct flash_flexspi_nor_data *data = dev->data;
231 
232 	flexspi_transfer_t transfer = {
233 		.deviceAddress = 0,
234 		.port = data->port,
235 		.cmdType = kFLEXSPI_Write,
236 		.SeqNumber = 1,
237 		.seqIndex = ENTER_OPI,
238 		.data = status,
239 		.dataSize = 1,
240 	};
241 
242 	LOG_DBG("Writing status register");
243 
244 	return memc_flexspi_transfer(data->controller, &transfer);
245 }
246 
flash_flexspi_nor_write_enable(const struct device * dev,bool enableOctal)247 static int flash_flexspi_nor_write_enable(const struct device *dev,
248 		bool enableOctal)
249 {
250 	struct flash_flexspi_nor_data *data = dev->data;
251 	flexspi_transfer_t transfer;
252 
253 	transfer.deviceAddress = 0;
254 	transfer.port = data->port;
255 	transfer.cmdType = kFLEXSPI_Command;
256 	transfer.SeqNumber = 1;
257 	if (enableOctal) {
258 		transfer.seqIndex = WRITE_ENABLE_OPI;
259 	} else {
260 		transfer.seqIndex = WRITE_ENABLE;
261 	}
262 	transfer.data = NULL;
263 	transfer.dataSize = 0;
264 
265 	LOG_DBG("Enabling write");
266 
267 	return memc_flexspi_transfer(data->controller, &transfer);
268 }
269 
flash_flexspi_nor_erase_sector(const struct device * dev,off_t offset)270 static int flash_flexspi_nor_erase_sector(const struct device *dev,
271 		off_t offset)
272 {
273 	struct flash_flexspi_nor_data *data = dev->data;
274 
275 	flexspi_transfer_t transfer = {
276 		.deviceAddress = offset,
277 		.port = data->port,
278 		.cmdType = kFLEXSPI_Command,
279 		.SeqNumber = 1,
280 		.seqIndex = ERASE_SECTOR,
281 		.data = NULL,
282 		.dataSize = 0,
283 	};
284 
285 	LOG_DBG("Erasing sector at 0x%08zx", (ssize_t) offset);
286 
287 	return memc_flexspi_transfer(data->controller, &transfer);
288 }
289 
flash_flexspi_nor_erase_chip(const struct device * dev)290 static int flash_flexspi_nor_erase_chip(const struct device *dev)
291 {
292 	struct flash_flexspi_nor_data *data = dev->data;
293 
294 	flexspi_transfer_t transfer = {
295 		.deviceAddress = 0,
296 		.port = data->port,
297 		.cmdType = kFLEXSPI_Command,
298 		.SeqNumber = 1,
299 		.seqIndex = ERASE_CHIP,
300 		.data = NULL,
301 		.dataSize = 0,
302 	};
303 
304 	LOG_DBG("Erasing chip");
305 
306 	return memc_flexspi_transfer(data->controller, &transfer);
307 }
308 
flash_flexspi_nor_page_program(const struct device * dev,off_t offset,const void * buffer,size_t len)309 static int flash_flexspi_nor_page_program(const struct device *dev,
310 		off_t offset, const void *buffer, size_t len)
311 {
312 	struct flash_flexspi_nor_data *data = dev->data;
313 
314 	flexspi_transfer_t transfer = {
315 		.deviceAddress = offset,
316 		.port = data->port,
317 		.cmdType = kFLEXSPI_Write,
318 		.SeqNumber = 1,
319 		.seqIndex = PAGE_PROGRAM,
320 		.data = (uint32_t *) buffer,
321 		.dataSize = len,
322 	};
323 
324 	LOG_DBG("Page programming %d bytes to 0x%08zx", len, (ssize_t) offset);
325 
326 	return memc_flexspi_transfer(data->controller, &transfer);
327 }
328 
flash_flexspi_nor_wait_bus_busy(const struct device * dev)329 static int flash_flexspi_nor_wait_bus_busy(const struct device *dev)
330 {
331 	uint32_t status = 0;
332 	int ret;
333 
334 	do {
335 		ret = flash_flexspi_nor_read_status(dev, &status);
336 		LOG_DBG("status: 0x%x", status);
337 		if (ret) {
338 			LOG_ERR("Could not read status");
339 			return ret;
340 		}
341 	} while (status & BIT(0));
342 
343 	return 0;
344 }
345 
flash_flexspi_enable_octal_mode(const struct device * dev)346 static int flash_flexspi_enable_octal_mode(const struct device *dev)
347 {
348 	struct flash_flexspi_nor_data *data = dev->data;
349 	/* FLASH_ENABLE_OCTAL_CMD: (01 = STR OPI Enable, 02 = DTR OPI Enable) */
350 	uint32_t status = NOR_FLASH_ENABLE_OCTAL_CMD;
351 
352 	flash_flexspi_nor_write_enable(dev, false);
353 	flash_flexspi_nor_write_status(dev, &status);
354 	flash_flexspi_nor_wait_bus_busy(dev);
355 	memc_flexspi_reset(data->controller);
356 
357 	return 0;
358 }
359 
flash_flexspi_nor_read(const struct device * dev,off_t offset,void * buffer,size_t len)360 static int flash_flexspi_nor_read(const struct device *dev, off_t offset,
361 		void *buffer, size_t len)
362 {
363 	struct flash_flexspi_nor_data *data = dev->data;
364 	uint8_t *src = memc_flexspi_get_ahb_address(data->controller,
365 						    data->port,
366 						    offset);
367 
368 	memcpy(buffer, src, len);
369 
370 	return 0;
371 }
372 
flash_flexspi_nor_write(const struct device * dev,off_t offset,const void * buffer,size_t len)373 static int flash_flexspi_nor_write(const struct device *dev, off_t offset,
374 		const void *buffer, size_t len)
375 {
376 	struct flash_flexspi_nor_data *data = dev->data;
377 	size_t size = len;
378 	uint8_t *src = (uint8_t *) buffer;
379 	int i;
380 	unsigned int key = 0;
381 
382 	uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
383 						    data->port,
384 						    offset);
385 
386 	if (memc_flexspi_is_running_xip(data->controller)) {
387 		/*
388 		 * ==== ENTER CRITICAL SECTION ====
389 		 * No flash access should be performed in critical section. All
390 		 * code and data accessed must reside in ram.
391 		 */
392 		key = irq_lock();
393 	}
394 	if (IS_ENABLED(CONFIG_FLASH_MCUX_FLEXSPI_MX25UM51345G_OPI_DTR)) {
395 		/* Check that write size and length are even */
396 		if ((offset & 0x1) || (len & 0x1)) {
397 			return -EINVAL;
398 		}
399 	}
400 
401 	while (len) {
402 		/* If the offset isn't a multiple of the NOR page size, we first need
403 		 * to write the remaining part that fits, otherwise the write could
404 		 * be wrapped around within the same page
405 		 */
406 		i = MIN(SPI_NOR_PAGE_SIZE - (offset % SPI_NOR_PAGE_SIZE), len);
407 #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER
408 		memcpy(nor_write_buf, src, i);
409 #endif
410 		flash_flexspi_nor_write_enable(dev, true);
411 #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER
412 		flash_flexspi_nor_page_program(dev, offset, nor_write_buf, i);
413 #else
414 		flash_flexspi_nor_page_program(dev, offset, src, i);
415 #endif
416 		flash_flexspi_nor_wait_bus_busy(dev);
417 		memc_flexspi_reset(data->controller);
418 		src += i;
419 		offset += i;
420 		len -= i;
421 	}
422 
423 	if (memc_flexspi_is_running_xip(data->controller)) {
424 		/* ==== EXIT CRITICAL SECTION ==== */
425 		irq_unlock(key);
426 	}
427 
428 #ifdef CONFIG_HAS_MCUX_CACHE
429 	DCACHE_InvalidateByRange((uint32_t) dst, size);
430 #endif
431 
432 	return 0;
433 }
434 
flash_flexspi_nor_erase(const struct device * dev,off_t offset,size_t size)435 static int flash_flexspi_nor_erase(const struct device *dev, off_t offset,
436 		size_t size)
437 {
438 	struct flash_flexspi_nor_data *data = dev->data;
439 	int num_sectors = size / SPI_NOR_SECTOR_SIZE;
440 	int i;
441 	unsigned int key = 0;
442 
443 	uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
444 						    data->port,
445 						    offset);
446 
447 	if (offset % SPI_NOR_SECTOR_SIZE) {
448 		LOG_ERR("Invalid offset");
449 		return -EINVAL;
450 	}
451 
452 	if (size % SPI_NOR_SECTOR_SIZE) {
453 		LOG_ERR("Invalid size");
454 		return -EINVAL;
455 	}
456 
457 	if (memc_flexspi_is_running_xip(data->controller)) {
458 		/*
459 		 * ==== ENTER CRITICAL SECTION ====
460 		 * No flash access should be performed in critical section. All
461 		 * code and data accessed must reside in ram.
462 		 */
463 		key = irq_lock();
464 	}
465 
466 	if ((offset == 0) && (size == data->config.flashSize * KB(1))) {
467 		flash_flexspi_nor_write_enable(dev, true);
468 		flash_flexspi_nor_erase_chip(dev);
469 		flash_flexspi_nor_wait_bus_busy(dev);
470 		memc_flexspi_reset(data->controller);
471 	} else {
472 		for (i = 0; i < num_sectors; i++) {
473 			flash_flexspi_nor_write_enable(dev, true);
474 			flash_flexspi_nor_erase_sector(dev, offset);
475 			flash_flexspi_nor_wait_bus_busy(dev);
476 			memc_flexspi_reset(data->controller);
477 			offset += SPI_NOR_SECTOR_SIZE;
478 		}
479 	}
480 
481 	if (memc_flexspi_is_running_xip(data->controller)) {
482 		/* ==== EXIT CRITICAL SECTION ==== */
483 		irq_unlock(key);
484 	}
485 
486 #ifdef CONFIG_HAS_MCUX_CACHE
487 	DCACHE_InvalidateByRange((uint32_t) dst, size);
488 #endif
489 
490 	return 0;
491 }
492 
flash_flexspi_nor_get_parameters(const struct device * dev)493 static const struct flash_parameters *flash_flexspi_nor_get_parameters(
494 		const struct device *dev)
495 {
496 	struct flash_flexspi_nor_data *data = dev->data;
497 
498 	return &data->flash_parameters;
499 }
500 
flash_flexspi_nor_get_size(const struct device * dev,uint64_t * size)501 static int flash_flexspi_nor_get_size(const struct device *dev, uint64_t *size)
502 {
503 	const struct flash_flexspi_nor_data *data = dev->data;
504 
505 	*size = data->size;
506 
507 	return 0;
508 }
509 
510 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
flash_flexspi_nor_pages_layout(const struct device * dev,const struct flash_pages_layout ** layout,size_t * layout_size)511 static void flash_flexspi_nor_pages_layout(const struct device *dev,
512 		const struct flash_pages_layout **layout, size_t *layout_size)
513 {
514 	struct flash_flexspi_nor_data *data = dev->data;
515 
516 	*layout = &data->layout;
517 	*layout_size = 1;
518 }
519 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
520 
flash_flexspi_nor_init(const struct device * dev)521 static int flash_flexspi_nor_init(const struct device *dev)
522 {
523 	struct flash_flexspi_nor_data *data = dev->data;
524 	uint8_t vendor_id;
525 
526 	if (!device_is_ready(data->controller)) {
527 		LOG_ERR("Controller device not ready");
528 		return -ENODEV;
529 	}
530 
531 	if (memc_flexspi_is_running_xip(data->controller)) {
532 		/* Wait for bus idle before configuring */
533 		memc_flexspi_wait_bus_idle(data->controller);
534 	}
535 
536 	if (memc_flexspi_set_device_config(data->controller, &data->config,
537 	    (const uint32_t *)flash_flexspi_nor_lut,
538 	    sizeof(flash_flexspi_nor_lut) / MEMC_FLEXSPI_CMD_SIZE,
539 	    data->port)) {
540 		LOG_ERR("Could not set device configuration");
541 		return -EINVAL;
542 	}
543 
544 	memc_flexspi_reset(data->controller);
545 
546 	if (flash_flexspi_enable_octal_mode(dev)) {
547 		LOG_ERR("Could not enable octal mode");
548 		return -EIO;
549 	}
550 
551 	if (flash_flexspi_nor_get_vendor_id(dev, &vendor_id)) {
552 		LOG_ERR("Could not read vendor id");
553 		return -EIO;
554 	}
555 	LOG_DBG("Vendor id: 0x%0x", vendor_id);
556 
557 	return 0;
558 }
559 
560 static DEVICE_API(flash, flash_flexspi_nor_api) = {
561 	.erase = flash_flexspi_nor_erase,
562 	.write = flash_flexspi_nor_write,
563 	.read = flash_flexspi_nor_read,
564 	.get_parameters = flash_flexspi_nor_get_parameters,
565 	.get_size = flash_flexspi_nor_get_size,
566 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
567 	.page_layout = flash_flexspi_nor_pages_layout,
568 #endif
569 };
570 
571 #define CONCAT3(x, y, z) x ## y ## z
572 
573 #define CS_INTERVAL_UNIT(unit)						\
574 	CONCAT3(kFLEXSPI_CsIntervalUnit, unit, SckCycle)
575 
576 #define AHB_WRITE_WAIT_UNIT(unit)					\
577 	CONCAT3(kFLEXSPI_AhbWriteWaitUnit, unit, AhbCycle)
578 
579 #define FLASH_FLEXSPI_DEVICE_CONFIG(n)					\
580 	{								\
581 		.flexspiRootClk = MHZ(120),				\
582 		.flashSize = DT_INST_PROP(n, size) / 8 / KB(1),		\
583 		.CSIntervalUnit =					\
584 			CS_INTERVAL_UNIT(				\
585 				DT_INST_PROP(n, cs_interval_unit)),	\
586 		.CSInterval = DT_INST_PROP(n, cs_interval),		\
587 		.CSHoldTime = DT_INST_PROP(n, cs_hold_time),		\
588 		.CSSetupTime = DT_INST_PROP(n, cs_setup_time),		\
589 		.dataValidTime = DT_INST_PROP(n, data_valid_time),	\
590 		.columnspace = DT_INST_PROP(n, column_space),		\
591 		.enableWordAddress = DT_INST_PROP(n, word_addressable),	\
592 		.AWRSeqIndex = 0,					\
593 		.AWRSeqNumber = 0,					\
594 		.ARDSeqIndex = READ,					\
595 		.ARDSeqNumber = 1,					\
596 		.AHBWriteWaitUnit =					\
597 			AHB_WRITE_WAIT_UNIT(				\
598 				DT_INST_PROP(n, ahb_write_wait_unit)),	\
599 		.AHBWriteWaitInterval =					\
600 			DT_INST_PROP(n, ahb_write_wait_interval),	\
601 	}								\
602 
603 #define FLASH_FLEXSPI_NOR(n)						\
604 	static struct flash_flexspi_nor_data				\
605 		flash_flexspi_nor_data_##n = {				\
606 		.controller = DEVICE_DT_GET(DT_INST_BUS(n)),		\
607 		.config = FLASH_FLEXSPI_DEVICE_CONFIG(n),		\
608 		.port = DT_INST_REG_ADDR(n),				\
609 		.size = DT_INST_PROP(n, size) / 8,			\
610 		.layout = {						\
611 			.pages_count = DT_INST_PROP(n, size) / 8	\
612 				/ SPI_NOR_SECTOR_SIZE,			\
613 			.pages_size = SPI_NOR_SECTOR_SIZE,		\
614 		},							\
615 		.flash_parameters = {					\
616 			.write_block_size = NOR_WRITE_SIZE,		\
617 			.erase_value = NOR_ERASE_VALUE,			\
618 		},							\
619 	};								\
620 									\
621 	DEVICE_DT_INST_DEFINE(n,					\
622 			      flash_flexspi_nor_init,			\
623 			      NULL,					\
624 			      &flash_flexspi_nor_data_##n,		\
625 			      NULL,					\
626 			      POST_KERNEL,				\
627 			      CONFIG_FLASH_INIT_PRIORITY,		\
628 			      &flash_flexspi_nor_api);
629 
630 DT_INST_FOREACH_STATUS_OKAY(FLASH_FLEXSPI_NOR)
631