1 /*
2  * Copyright (c) 2015 Intel Corporation.
3  * Copyright (c) 2023 Synopsys, Inc. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT snps_designware_spi
9 
10 /* spi_dw.c - Designware SPI driver implementation */
11 
12 #define LOG_LEVEL CONFIG_SPI_LOG_LEVEL
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(spi_dw);
15 
16 #if (CONFIG_SPI_LOG_LEVEL == 4)
17 #define DBG_COUNTER_INIT()	\
18 	uint32_t __cnt = 0
19 #define DBG_COUNTER_INC()	\
20 	(__cnt++)
21 #define DBG_COUNTER_RESULT()	\
22 	(__cnt)
23 #else
24 #define DBG_COUNTER_INIT() {; }
25 #define DBG_COUNTER_INC() {; }
26 #define DBG_COUNTER_RESULT() 0
27 #endif
28 
29 #include <errno.h>
30 
31 #include <zephyr/kernel.h>
32 #include <zephyr/arch/cpu.h>
33 
34 #include <zephyr/device.h>
35 #include <zephyr/init.h>
36 #include <zephyr/pm/device.h>
37 
38 #include <zephyr/sys/sys_io.h>
39 #include <zephyr/sys/util.h>
40 
41 #ifdef CONFIG_IOAPIC
42 #include <zephyr/drivers/interrupt_controller/ioapic.h>
43 #endif
44 
45 #include <zephyr/drivers/spi.h>
46 #include <zephyr/irq.h>
47 
48 #include "spi_dw.h"
49 #include "spi_context.h"
50 
51 #ifdef CONFIG_PINCTRL
52 #include <zephyr/drivers/pinctrl.h>
53 #endif
54 
spi_dw_is_slave(struct spi_dw_data * spi)55 static inline bool spi_dw_is_slave(struct spi_dw_data *spi)
56 {
57 	return (IS_ENABLED(CONFIG_SPI_SLAVE) &&
58 		spi_context_is_slave(&spi->ctx));
59 }
60 
completed(const struct device * dev,int error)61 static void completed(const struct device *dev, int error)
62 {
63 	const struct spi_dw_config *info = dev->config;
64 	struct spi_dw_data *spi = dev->data;
65 
66 	if (error) {
67 		goto out;
68 	}
69 
70 	if (spi_context_tx_on(&spi->ctx) ||
71 	    spi_context_rx_on(&spi->ctx)) {
72 		return;
73 	}
74 
75 out:
76 	/* need to give time for FIFOs to drain before issuing more commands */
77 	while (test_bit_sr_busy(info)) {
78 	}
79 
80 	/* Disabling interrupts */
81 	write_imr(info, DW_SPI_IMR_MASK);
82 	/* Disabling the controller */
83 	clear_bit_ssienr(info);
84 
85 	spi_context_cs_control(&spi->ctx, false);
86 
87 	LOG_DBG("SPI transaction completed %s error",
88 		    error ? "with" : "without");
89 
90 	spi_context_complete(&spi->ctx, dev, error);
91 }
92 
push_data(const struct device * dev)93 static void push_data(const struct device *dev)
94 {
95 	const struct spi_dw_config *info = dev->config;
96 	struct spi_dw_data *spi = dev->data;
97 	uint32_t data = 0U;
98 	uint32_t f_tx;
99 
100 	DBG_COUNTER_INIT();
101 
102 	if (spi_context_rx_on(&spi->ctx)) {
103 		f_tx = info->fifo_depth - read_txflr(info) -
104 			read_rxflr(info);
105 		if ((int)f_tx < 0) {
106 			f_tx = 0U; /* if rx-fifo is full, hold off tx */
107 		}
108 	} else {
109 		f_tx = info->fifo_depth - read_txflr(info);
110 	}
111 
112 	while (f_tx) {
113 		if (spi_context_tx_buf_on(&spi->ctx)) {
114 			switch (spi->dfs) {
115 			case 1:
116 				data = UNALIGNED_GET((uint8_t *)
117 						     (spi->ctx.tx_buf));
118 				break;
119 			case 2:
120 				data = UNALIGNED_GET((uint16_t *)
121 						     (spi->ctx.tx_buf));
122 				break;
123 #ifndef CONFIG_ARC
124 			case 4:
125 				data = UNALIGNED_GET((uint32_t *)
126 						     (spi->ctx.tx_buf));
127 				break;
128 #endif
129 			}
130 		} else if (spi_context_rx_on(&spi->ctx)) {
131 			/* No need to push more than necessary */
132 			if ((int)(spi->ctx.rx_len - spi->fifo_diff) <= 0) {
133 				break;
134 			}
135 
136 			data = 0U;
137 		} else if (spi_context_tx_on(&spi->ctx)) {
138 			data = 0U;
139 		} else {
140 			/* Nothing to push anymore */
141 			break;
142 		}
143 
144 		write_dr(info, data);
145 
146 		spi_context_update_tx(&spi->ctx, spi->dfs, 1);
147 		spi->fifo_diff++;
148 
149 		f_tx--;
150 
151 		DBG_COUNTER_INC();
152 	}
153 
154 	if (!spi_context_tx_on(&spi->ctx)) {
155 		/* prevents any further interrupts demanding TX fifo fill */
156 		write_txftlr(info, 0);
157 	}
158 
159 	LOG_DBG("Pushed: %d", DBG_COUNTER_RESULT());
160 }
161 
pull_data(const struct device * dev)162 static void pull_data(const struct device *dev)
163 {
164 	const struct spi_dw_config *info = dev->config;
165 	struct spi_dw_data *spi = dev->data;
166 
167 	DBG_COUNTER_INIT();
168 
169 	while (read_rxflr(info)) {
170 		uint32_t data = read_dr(info);
171 
172 		DBG_COUNTER_INC();
173 
174 		if (spi_context_rx_buf_on(&spi->ctx)) {
175 			switch (spi->dfs) {
176 			case 1:
177 				UNALIGNED_PUT(data, (uint8_t *)spi->ctx.rx_buf);
178 				break;
179 			case 2:
180 				UNALIGNED_PUT(data, (uint16_t *)spi->ctx.rx_buf);
181 				break;
182 #ifndef CONFIG_ARC
183 			case 4:
184 				UNALIGNED_PUT(data, (uint32_t *)spi->ctx.rx_buf);
185 				break;
186 #endif
187 			}
188 		}
189 
190 		spi_context_update_rx(&spi->ctx, spi->dfs, 1);
191 		spi->fifo_diff--;
192 	}
193 
194 	if (!spi->ctx.rx_len && spi->ctx.tx_len < info->fifo_depth) {
195 		write_rxftlr(info, spi->ctx.tx_len - 1);
196 	} else if (read_rxftlr(info) >= spi->ctx.rx_len) {
197 		write_rxftlr(info, spi->ctx.rx_len - 1);
198 	}
199 
200 	LOG_DBG("Pulled: %d", DBG_COUNTER_RESULT());
201 }
202 
spi_dw_configure(const struct spi_dw_config * info,struct spi_dw_data * spi,const struct spi_config * config)203 static int spi_dw_configure(const struct spi_dw_config *info,
204 			    struct spi_dw_data *spi,
205 			    const struct spi_config *config)
206 {
207 	uint32_t ctrlr0 = 0U;
208 
209 	LOG_DBG("%p (prev %p)", config, spi->ctx.config);
210 
211 	if (spi_context_configured(&spi->ctx, config)) {
212 		/* Nothing to do */
213 		return 0;
214 	}
215 
216 	if (config->operation & SPI_HALF_DUPLEX) {
217 		LOG_ERR("Half-duplex not supported");
218 		return -ENOTSUP;
219 	}
220 
221 	/* Verify if requested op mode is relevant to this controller */
222 	if (config->operation & SPI_OP_MODE_SLAVE) {
223 		if (!(info->op_modes & SPI_CTX_RUNTIME_OP_MODE_SLAVE)) {
224 			LOG_ERR("Slave mode not supported");
225 			return -ENOTSUP;
226 		}
227 	} else {
228 		if (!(info->op_modes & SPI_CTX_RUNTIME_OP_MODE_MASTER)) {
229 			LOG_ERR("Master mode not supported");
230 			return -ENOTSUP;
231 		}
232 	}
233 
234 	if ((config->operation & SPI_TRANSFER_LSB) ||
235 	    (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) &&
236 	     (config->operation & (SPI_LINES_DUAL |
237 				   SPI_LINES_QUAD | SPI_LINES_OCTAL)))) {
238 		LOG_ERR("Unsupported configuration");
239 		return -EINVAL;
240 	}
241 
242 	/* Word size */
243 	ctrlr0 |= DW_SPI_CTRLR0_DFS(SPI_WORD_SIZE_GET(config->operation));
244 
245 	/* Determine how many bytes are required per-frame */
246 	spi->dfs = SPI_WS_TO_DFS(SPI_WORD_SIZE_GET(config->operation));
247 
248 	/* SPI mode */
249 	if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) {
250 		ctrlr0 |= DW_SPI_CTRLR0_SCPOL;
251 	}
252 
253 	if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) {
254 		ctrlr0 |= DW_SPI_CTRLR0_SCPH;
255 	}
256 
257 	if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) {
258 		ctrlr0 |= DW_SPI_CTRLR0_SRL;
259 	}
260 
261 	/* Installing the configuration */
262 	write_ctrlr0(info, ctrlr0);
263 
264 	/* At this point, it's mandatory to set this on the context! */
265 	spi->ctx.config = config;
266 
267 	if (!spi_dw_is_slave(spi)) {
268 		/* Baud rate and Slave select, for master only */
269 		write_baudr(info, SPI_DW_CLK_DIVIDER(info->clock_frequency,
270 					       config->frequency));
271 		write_ser(info, 1 << config->slave);
272 	}
273 
274 	if (spi_dw_is_slave(spi)) {
275 		LOG_DBG("Installed slave config %p:"
276 			    " ws/dfs %u/%u, mode %u/%u/%u",
277 			    config,
278 			    SPI_WORD_SIZE_GET(config->operation), spi->dfs,
279 			    (SPI_MODE_GET(config->operation) &
280 			     SPI_MODE_CPOL) ? 1 : 0,
281 			    (SPI_MODE_GET(config->operation) &
282 			     SPI_MODE_CPHA) ? 1 : 0,
283 			    (SPI_MODE_GET(config->operation) &
284 			     SPI_MODE_LOOP) ? 1 : 0);
285 	} else {
286 		LOG_DBG("Installed master config %p: freq %uHz (div = %u),"
287 			    " ws/dfs %u/%u, mode %u/%u/%u, slave %u",
288 			    config, config->frequency,
289 			    SPI_DW_CLK_DIVIDER(info->clock_frequency,
290 					       config->frequency),
291 			    SPI_WORD_SIZE_GET(config->operation), spi->dfs,
292 			    (SPI_MODE_GET(config->operation) &
293 			     SPI_MODE_CPOL) ? 1 : 0,
294 			    (SPI_MODE_GET(config->operation) &
295 			     SPI_MODE_CPHA) ? 1 : 0,
296 			    (SPI_MODE_GET(config->operation) &
297 			     SPI_MODE_LOOP) ? 1 : 0,
298 			    config->slave);
299 	}
300 
301 	return 0;
302 }
303 
spi_dw_compute_ndf(const struct spi_buf * rx_bufs,size_t rx_count,uint8_t dfs)304 static uint32_t spi_dw_compute_ndf(const struct spi_buf *rx_bufs,
305 				   size_t rx_count, uint8_t dfs)
306 {
307 	uint32_t len = 0U;
308 
309 	for (; rx_count; rx_bufs++, rx_count--) {
310 		if (len > (UINT16_MAX - rx_bufs->len)) {
311 			goto error;
312 		}
313 
314 		len += rx_bufs->len;
315 	}
316 
317 	if (len) {
318 		return (len / dfs) - 1;
319 	}
320 error:
321 	return UINT32_MAX;
322 }
323 
spi_dw_update_txftlr(const struct spi_dw_config * info,struct spi_dw_data * spi)324 static void spi_dw_update_txftlr(const struct spi_dw_config *info,
325 				 struct spi_dw_data *spi)
326 {
327 	uint32_t dw_spi_txftlr_dflt = (info->fifo_depth * 1) / 2;
328 	uint32_t reg_data = dw_spi_txftlr_dflt;
329 
330 	if (spi_dw_is_slave(spi)) {
331 		if (!spi->ctx.tx_len) {
332 			reg_data = 0U;
333 		} else if (spi->ctx.tx_len < dw_spi_txftlr_dflt) {
334 			reg_data = spi->ctx.tx_len - 1;
335 		}
336 	}
337 
338 	LOG_DBG("TxFTLR: %u", reg_data);
339 
340 	write_txftlr(info, reg_data);
341 }
342 
transceive(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,bool asynchronous,spi_callback_t cb,void * userdata)343 static int transceive(const struct device *dev,
344 		      const struct spi_config *config,
345 		      const struct spi_buf_set *tx_bufs,
346 		      const struct spi_buf_set *rx_bufs,
347 		      bool asynchronous,
348 		      spi_callback_t cb,
349 		      void *userdata)
350 {
351 	const struct spi_dw_config *info = dev->config;
352 	struct spi_dw_data *spi = dev->data;
353 	uint32_t tmod = DW_SPI_CTRLR0_TMOD_TX_RX;
354 	uint32_t dw_spi_rxftlr_dflt = (info->fifo_depth * 5) / 8;
355 	uint32_t reg_data;
356 	int ret;
357 
358 	spi_context_lock(&spi->ctx, asynchronous, cb, userdata, config);
359 
360 #ifdef CONFIG_PM_DEVICE
361 	if (!pm_device_is_busy(dev)) {
362 		pm_device_busy_set(dev);
363 	}
364 #endif /* CONFIG_PM_DEVICE */
365 
366 	/* Configure */
367 	ret = spi_dw_configure(info, spi, config);
368 	if (ret) {
369 		goto out;
370 	}
371 
372 	if (!rx_bufs || !rx_bufs->buffers) {
373 		tmod = DW_SPI_CTRLR0_TMOD_TX;
374 	} else if (!tx_bufs || !tx_bufs->buffers) {
375 		tmod = DW_SPI_CTRLR0_TMOD_RX;
376 	}
377 
378 	/* ToDo: add a way to determine EEPROM mode */
379 
380 	if (tmod >= DW_SPI_CTRLR0_TMOD_RX &&
381 	    !spi_dw_is_slave(spi)) {
382 		reg_data = spi_dw_compute_ndf(rx_bufs->buffers,
383 					      rx_bufs->count,
384 					      spi->dfs);
385 		if (reg_data == UINT32_MAX) {
386 			ret = -EINVAL;
387 			goto out;
388 		}
389 
390 		write_ctrlr1(info, reg_data);
391 	} else {
392 		write_ctrlr1(info, 0);
393 	}
394 
395 	if (spi_dw_is_slave(spi)) {
396 		/* Enabling MISO line relevantly */
397 		if (tmod == DW_SPI_CTRLR0_TMOD_RX) {
398 			tmod |= DW_SPI_CTRLR0_SLV_OE;
399 		} else {
400 			tmod &= ~DW_SPI_CTRLR0_SLV_OE;
401 		}
402 	}
403 
404 	/* Updating TMOD in CTRLR0 register */
405 	reg_data = read_ctrlr0(info);
406 	reg_data &= ~DW_SPI_CTRLR0_TMOD_RESET;
407 	reg_data |= tmod;
408 
409 	write_ctrlr0(info, reg_data);
410 
411 	/* Set buffers info */
412 	spi_context_buffers_setup(&spi->ctx, tx_bufs, rx_bufs, spi->dfs);
413 
414 	spi->fifo_diff = 0U;
415 
416 	/* Tx Threshold */
417 	spi_dw_update_txftlr(info, spi);
418 
419 	/* Does Rx thresholds needs to be lower? */
420 	reg_data = dw_spi_rxftlr_dflt;
421 
422 	if (spi_dw_is_slave(spi)) {
423 		if (spi->ctx.rx_len &&
424 		    spi->ctx.rx_len < dw_spi_rxftlr_dflt) {
425 			reg_data = spi->ctx.rx_len - 1;
426 		}
427 	} else {
428 		if (spi->ctx.rx_len && spi->ctx.rx_len < info->fifo_depth) {
429 			reg_data = spi->ctx.rx_len - 1;
430 		}
431 	}
432 
433 	/* Rx Threshold */
434 	write_rxftlr(info, reg_data);
435 
436 	/* Enable interrupts */
437 	reg_data = !rx_bufs ?
438 		DW_SPI_IMR_UNMASK & DW_SPI_IMR_MASK_RX :
439 		DW_SPI_IMR_UNMASK;
440 	write_imr(info, reg_data);
441 
442 	spi_context_cs_control(&spi->ctx, true);
443 
444 	LOG_DBG("Enabling controller");
445 	set_bit_ssienr(info);
446 
447 	ret = spi_context_wait_for_completion(&spi->ctx);
448 out:
449 	spi_context_release(&spi->ctx, ret);
450 
451 	pm_device_busy_clear(dev);
452 
453 	return ret;
454 }
455 
spi_dw_transceive(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)456 static int spi_dw_transceive(const struct device *dev,
457 			     const struct spi_config *config,
458 			     const struct spi_buf_set *tx_bufs,
459 			     const struct spi_buf_set *rx_bufs)
460 {
461 	LOG_DBG("%p, %p, %p", dev, tx_bufs, rx_bufs);
462 
463 	return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL);
464 }
465 
466 #ifdef CONFIG_SPI_ASYNC
spi_dw_transceive_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,spi_callback_t cb,void * userdata)467 static int spi_dw_transceive_async(const struct device *dev,
468 				   const struct spi_config *config,
469 				   const struct spi_buf_set *tx_bufs,
470 				   const struct spi_buf_set *rx_bufs,
471 				   spi_callback_t cb,
472 				   void *userdata)
473 {
474 	LOG_DBG("%p, %p, %p, %p, %p", dev, tx_bufs, rx_bufs, cb, userdata);
475 
476 	return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata);
477 }
478 #endif /* CONFIG_SPI_ASYNC */
479 
spi_dw_release(const struct device * dev,const struct spi_config * config)480 static int spi_dw_release(const struct device *dev,
481 			  const struct spi_config *config)
482 {
483 	struct spi_dw_data *spi = dev->data;
484 
485 	if (!spi_context_configured(&spi->ctx, config)) {
486 		return -EINVAL;
487 	}
488 
489 	spi_context_unlock_unconditionally(&spi->ctx);
490 
491 	return 0;
492 }
493 
spi_dw_isr(const struct device * dev)494 void spi_dw_isr(const struct device *dev)
495 {
496 	const struct spi_dw_config *info = dev->config;
497 	uint32_t int_status;
498 	int error;
499 
500 	int_status = read_isr(info);
501 
502 	LOG_DBG("SPI %p int_status 0x%x - (tx: %d, rx: %d)", dev, int_status,
503 		read_txflr(info), read_rxflr(info));
504 
505 	if (int_status & DW_SPI_ISR_ERRORS_MASK) {
506 		error = -EIO;
507 		goto out;
508 	}
509 
510 	error = 0;
511 
512 	if (int_status & DW_SPI_ISR_RXFIS) {
513 		pull_data(dev);
514 	}
515 
516 	if (int_status & DW_SPI_ISR_TXEIS) {
517 		push_data(dev);
518 	}
519 
520 out:
521 	clear_interrupts(info);
522 	completed(dev, error);
523 }
524 
525 static const struct spi_driver_api dw_spi_api = {
526 	.transceive = spi_dw_transceive,
527 #ifdef CONFIG_SPI_ASYNC
528 	.transceive_async = spi_dw_transceive_async,
529 #endif /* CONFIG_SPI_ASYNC */
530 	.release = spi_dw_release,
531 };
532 
spi_dw_init(const struct device * dev)533 int spi_dw_init(const struct device *dev)
534 {
535 	int err;
536 	const struct spi_dw_config *info = dev->config;
537 	struct spi_dw_data *spi = dev->data;
538 
539 #ifdef CONFIG_PINCTRL
540 	pinctrl_apply_state(info->pcfg, PINCTRL_STATE_DEFAULT);
541 #endif
542 
543 	info->config_func();
544 
545 	/* Masking interrupt and making sure controller is disabled */
546 	write_imr(info, DW_SPI_IMR_MASK);
547 	clear_bit_ssienr(info);
548 
549 	LOG_DBG("Designware SPI driver initialized on device: %p", dev);
550 
551 	err = spi_context_cs_configure_all(&spi->ctx);
552 	if (err < 0) {
553 		return err;
554 	}
555 
556 	spi_context_unlock_unconditionally(&spi->ctx);
557 
558 	return 0;
559 }
560 
561 
562 #if DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay)
563 void spi_config_0_irq(void);
564 
565 struct spi_dw_data spi_dw_data_port_0 = {
566 	SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_0, ctx),
567 	SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_0, ctx),
568 	SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(0), ctx)
569 };
570 
571 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency)
572 #define INST_0_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
573 	DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency)
574 #else
575 #define INST_0_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
576 	DT_INST_PROP(0, clock_frequency)
577 #endif
578 
579 #ifdef CONFIG_PINCTRL
580 PINCTRL_DT_INST_DEFINE(0);
581 #endif
582 const struct spi_dw_config spi_dw_config_0 = {
583 	.regs = DT_INST_REG_ADDR(0),
584 	.clock_frequency = INST_0_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
585 	.config_func = spi_config_0_irq,
586 	.op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
587 	.fifo_depth = DT_INST_PROP(0, fifo_depth),
588 #ifdef CONFIG_PINCTRL
589 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
590 #endif
591 #if DT_INST_PROP(0, aux_reg)
592 	.read_func = aux_reg_read,
593 	.write_func = aux_reg_write,
594 	.set_bit_func = aux_reg_set_bit,
595 	.clear_bit_func = aux_reg_clear_bit,
596 	.test_bit_func = aux_reg_test_bit
597 #else
598 	.read_func = reg_read,
599 	.write_func = reg_write,
600 	.set_bit_func = reg_set_bit,
601 	.clear_bit_func = reg_clear_bit,
602 	.test_bit_func = reg_test_bit
603 #endif
604 };
605 
606 DEVICE_DT_INST_DEFINE(0, spi_dw_init, NULL,
607 		    &spi_dw_data_port_0, &spi_dw_config_0,
608 		    POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
609 		    &dw_spi_api);
610 
spi_config_0_irq(void)611 void spi_config_0_irq(void)
612 {
613 #if DT_NUM_IRQS(DT_DRV_INST(0)) == 1
614 #if DT_INST_IRQ_HAS_NAME(0, flags)
615 #define INST_0_IRQ_FLAGS DT_INST_IRQ_BY_NAME(0, flags, irq)
616 #else
617 #define INST_0_IRQ_FLAGS 0
618 #endif
619 	IRQ_CONNECT(DT_INST_IRQN(0),
620 		    DT_INST_IRQ(0, priority),
621 		    spi_dw_isr, DEVICE_DT_INST_GET(0),
622 		    INST_0_IRQ_FLAGS);
623 	irq_enable(DT_INST_IRQN(0));
624 #else
625 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, rx_avail, irq),
626 		    DT_INST_IRQ_BY_NAME(0, rx_avail, priority),
627 		    spi_dw_isr, DEVICE_DT_INST_GET(0),
628 		    0);
629 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, tx_req, irq),
630 		    DT_INST_IRQ_BY_NAME(0, tx_req, priority),
631 		    spi_dw_isr, DEVICE_DT_INST_GET(0),
632 		    0);
633 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, err_int, irq),
634 		    DT_INST_IRQ_BY_NAME(0, err_int, priority),
635 		    spi_dw_isr, DEVICE_DT_INST_GET(0),
636 		    0);
637 
638 	irq_enable(DT_INST_IRQ_BY_NAME(0, rx_avail, irq));
639 	irq_enable(DT_INST_IRQ_BY_NAME(0, tx_req, irq));
640 	irq_enable(DT_INST_IRQ_BY_NAME(0, err_int, irq));
641 
642 #endif
643 }
644 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) */
645 
646 #if DT_NODE_HAS_STATUS(DT_DRV_INST(1), okay)
647 void spi_config_1_irq(void);
648 
649 struct spi_dw_data spi_dw_data_port_1 = {
650 	SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_1, ctx),
651 	SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_1, ctx),
652 	SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(1), ctx)
653 };
654 
655 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(1, clocks), clock_frequency)
656 #define INST_1_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
657 	DT_INST_PROP_BY_PHANDLE(1, clocks, clock_frequency)
658 #else
659 #define INST_1_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
660 	DT_INST_PROP(1, clock_frequency)
661 #endif
662 
663 #ifdef CONFIG_PINCTRL
664 PINCTRL_DT_INST_DEFINE(1);
665 #endif
666 static const struct spi_dw_config spi_dw_config_1 = {
667 	.regs = DT_INST_REG_ADDR(1),
668 	.clock_frequency = INST_1_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
669 	.config_func = spi_config_1_irq,
670 	.op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
671 	.fifo_depth = DT_INST_PROP(1, fifo_depth),
672 #ifdef CONFIG_PINCTRL
673 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(1),
674 #endif
675 #if DT_INST_PROP(1, aux_reg)
676 	.read_func = aux_reg_read,
677 	.write_func = aux_reg_write,
678 	.set_bit_func = aux_reg_set_bit,
679 	.clear_bit_func = aux_reg_clear_bit,
680 	.test_bit_func = aux_reg_test_bit
681 #else
682 	.read_func = reg_read,
683 	.write_func = reg_write,
684 	.set_bit_func = reg_set_bit,
685 	.clear_bit_func = reg_clear_bit,
686 	.test_bit_func = reg_test_bit
687 #endif
688 };
689 
690 DEVICE_DT_INST_DEFINE(1, spi_dw_init, NULL,
691 		    &spi_dw_data_port_1, &spi_dw_config_1,
692 		    POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
693 		    &dw_spi_api);
694 
spi_config_1_irq(void)695 void spi_config_1_irq(void)
696 {
697 #if DT_NUM_IRQS(DT_DRV_INST(1)) == 1
698 #if DT_INST_IRQ_HAS_NAME(1, flags)
699 #define INST_1_IRQ_FLAGS DT_INST_IRQ_BY_NAME(1, flags, irq)
700 #else
701 #define INST_1_IRQ_FLAGS 0
702 #endif
703 	IRQ_CONNECT(DT_INST_IRQN(1),
704 		    DT_INST_IRQ(1, priority),
705 		    spi_dw_isr, DEVICE_DT_INST_GET(1),
706 		    INST_1_IRQ_FLAGS);
707 	irq_enable(DT_INST_IRQN(1));
708 #else
709 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, rx_avail, irq),
710 		    DT_INST_IRQ_BY_NAME(1, rx_avail, priority),
711 		    spi_dw_isr, DEVICE_DT_INST_GET(1),
712 		    0);
713 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, tx_req, irq),
714 		    DT_INST_IRQ_BY_NAME(1, tx_req, priority),
715 		    spi_dw_isr, DEVICE_DT_INST_GET(1),
716 		    0);
717 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, err_int, irq),
718 		    DT_INST_IRQ_BY_NAME(1, err_int, priority),
719 		    spi_dw_isr, DEVICE_DT_INST_GET(1),
720 		    0);
721 
722 	irq_enable(DT_INST_IRQ_BY_NAME(1, rx_avail, irq));
723 	irq_enable(DT_INST_IRQ_BY_NAME(1, tx_req, irq));
724 	irq_enable(DT_INST_IRQ_BY_NAME(1, err_int, irq));
725 
726 #endif
727 }
728 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(1), okay) */
729 
730 #if DT_NODE_HAS_STATUS(DT_DRV_INST(2), okay)
731 void spi_config_2_irq(void);
732 
733 struct spi_dw_data spi_dw_data_port_2 = {
734 	SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_2, ctx),
735 	SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_2, ctx),
736 	SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(2), ctx)
737 };
738 
739 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(2, clocks), clock_frequency)
740 #define INST_2_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
741 	DT_INST_PROP_BY_PHANDLE(2, clocks, clock_frequency)
742 #else
743 #define INST_2_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
744 	DT_INST_PROP(2, clock_frequency)
745 #endif
746 
747 #ifdef CONFIG_PINCTRL
748 PINCTRL_DT_INST_DEFINE(2);
749 #endif
750 static const struct spi_dw_config spi_dw_config_2 = {
751 	.regs = DT_INST_REG_ADDR(2),
752 	.clock_frequency = INST_2_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
753 	.config_func = spi_config_2_irq,
754 	.op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
755 	.fifo_depth = DT_INST_PROP(2, fifo_depth),
756 #ifdef CONFIG_PINCTRL
757 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(2),
758 #endif
759 #if DT_INST_PROP(2, aux_reg)
760 	.read_func = aux_reg_read,
761 	.write_func = aux_reg_write,
762 	.set_bit_func = aux_reg_set_bit,
763 	.clear_bit_func = aux_reg_clear_bit,
764 	.test_bit_func = aux_reg_test_bit
765 #else
766 	.read_func = reg_read,
767 	.write_func = reg_write,
768 	.set_bit_func = reg_set_bit,
769 	.clear_bit_func = reg_clear_bit,
770 	.test_bit_func = reg_test_bit
771 #endif
772 };
773 
774 DEVICE_DT_INST_DEFINE(2, spi_dw_init, NULL,
775 		    &spi_dw_data_port_2, &spi_dw_config_2,
776 		    POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
777 		    &dw_spi_api);
778 
spi_config_2_irq(void)779 void spi_config_2_irq(void)
780 {
781 #if DT_NUM_IRQS(DT_DRV_INST(2)) == 1
782 #if DT_INST_IRQ_HAS_NAME(2, flags)
783 #define INST_2_IRQ_FLAGS DT_INST_IRQ_BY_NAME(2, flags, irq)
784 #else
785 #define INST_2_IRQ_FLAGS 0
786 #endif
787 	IRQ_CONNECT(DT_INST_IRQN(2),
788 		    DT_INST_IRQ(2, priority),
789 		    spi_dw_isr, DEVICE_DT_INST_GET(2),
790 		    INST_2_IRQ_FLAGS);
791 	irq_enable(DT_INST_IRQN(2));
792 #else
793 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, rx_avail, irq),
794 		    DT_INST_IRQ_BY_NAME(2, rx_avail, priority),
795 		    spi_dw_isr, DEVICE_DT_INST_GET(2),
796 		    0);
797 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, tx_req, irq),
798 		    DT_INST_IRQ_BY_NAME(2, tx_req, priority),
799 		    spi_dw_isr, DEVICE_DT_INST_GET(2),
800 		    0);
801 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, err_int, irq),
802 		    DT_INST_IRQ_BY_NAME(2, err_int, priority),
803 		    spi_dw_isr, DEVICE_DT_INST_GET(2),
804 		    0);
805 
806 	irq_enable(DT_INST_IRQ_BY_NAME(2, rx_avail, irq));
807 	irq_enable(DT_INST_IRQ_BY_NAME(2, tx_req, irq));
808 	irq_enable(DT_INST_IRQ_BY_NAME(2, err_int, irq));
809 
810 #endif
811 }
812 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(2), okay) */
813 
814 #if DT_NODE_HAS_STATUS(DT_DRV_INST(3), okay)
815 void spi_config_3_irq(void);
816 
817 struct spi_dw_data spi_dw_data_port_3 = {
818 	SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_3, ctx),
819 	SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_3, ctx),
820 	SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(3), ctx)
821 };
822 
823 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(3, clocks), clock_frequency)
824 #define INST_3_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
825 	DT_INST_PROP_BY_PHANDLE(3, clocks, clock_frequency)
826 #else
827 #define INST_3_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
828 	DT_INST_PROP(3, clock_frequency)
829 #endif
830 
831 #ifdef CONFIG_PINCTRL
832 PINCTRL_DT_INST_DEFINE(3);
833 #endif
834 static const struct spi_dw_config spi_dw_config_3 = {
835 	.regs = DT_INST_REG_ADDR(3),
836 	.clock_frequency = INST_3_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
837 	.config_func = spi_config_3_irq,
838 	.op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
839 	.fifo_depth = DT_INST_PROP(3, fifo_depth),
840 #ifdef CONFIG_PINCTRL
841 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(3),
842 #endif
843 #if DT_INST_PROP(3, aux_reg)
844 	.read_func = aux_reg_read,
845 	.write_func = aux_reg_write,
846 	.set_bit_func = aux_reg_set_bit,
847 	.clear_bit_func = aux_reg_clear_bit,
848 	.test_bit_func = aux_reg_test_bit
849 #else
850 	.read_func = reg_read,
851 	.write_func = reg_write,
852 	.set_bit_func = reg_set_bit,
853 	.clear_bit_func = reg_clear_bit,
854 	.test_bit_func = reg_test_bit
855 #endif
856 };
857 
858 DEVICE_DT_INST_DEFINE(3, spi_dw_init, NULL,
859 		    &spi_dw_data_port_3, &spi_dw_config_3,
860 		    POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
861 		    &dw_spi_api);
862 
spi_config_3_irq(void)863 void spi_config_3_irq(void)
864 {
865 #if DT_NUM_IRQS(DT_DRV_INST(3)) == 1
866 #if DT_INST_IRQ_HAS_NAME(3, flags)
867 #define INST_3_IRQ_FLAGS DT_INST_IRQ_BY_NAME(3, flags, irq)
868 #else
869 #define INST_3_IRQ_FLAGS 0
870 #endif
871 	IRQ_CONNECT(DT_INST_IRQN(3),
872 		    DT_INST_IRQ(3, priority),
873 		    spi_dw_isr, DEVICE_DT_INST_GET(3),
874 		    INST_3_IRQ_FLAGS);
875 	irq_enable(DT_INST_IRQN(3));
876 #else
877 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, rx_avail, irq),
878 		    DT_INST_IRQ_BY_NAME(3, rx_avail, priority),
879 		    spi_dw_isr, DEVICE_DT_INST_GET(3),
880 		    0);
881 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, tx_req, irq),
882 		    DT_INST_IRQ_BY_NAME(3, tx_req, priority),
883 		    spi_dw_isr, DEVICE_DT_INST_GET(3),
884 		    0);
885 	IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, err_int, irq),
886 		    DT_INST_IRQ_BY_NAME(3, err_int, priority),
887 		    spi_dw_isr, DEVICE_DT_INST_GET(3),
888 		    0);
889 
890 	irq_enable(DT_INST_IRQ_BY_NAME(3, rx_avail, irq));
891 	irq_enable(DT_INST_IRQ_BY_NAME(3, tx_req, irq));
892 	irq_enable(DT_INST_IRQ_BY_NAME(3, err_int, irq));
893 
894 #endif
895 }
896 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(3), okay) */
897