1 /*
2  * Copyright (c) 2016 Linaro Limited.
3  * Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @brief Common part of DMA drivers for stm32.
10  * @note  Functions named with stm32_dma_* are SoCs related functions
11  *        implemented in dma_stm32_v*.c
12  */
13 
14 #include "dma_stm32.h"
15 
16 #include <zephyr/init.h>
17 #include <zephyr/drivers/clock_control.h>
18 #include <zephyr/drivers/dma/dma_stm32.h>
19 
20 #include <zephyr/logging/log.h>
21 #include <zephyr/irq.h>
22 LOG_MODULE_REGISTER(dma_stm32, CONFIG_DMA_LOG_LEVEL);
23 
24 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_dma_v1)
25 #define DT_DRV_COMPAT st_stm32_dma_v1
26 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_dma_v2)
27 #define DT_DRV_COMPAT st_stm32_dma_v2
28 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_dma_v2bis)
29 #define DT_DRV_COMPAT st_stm32_dma_v2bis
30 #endif
31 
32 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0))
33 #if DT_INST_IRQ_HAS_IDX(0, 7)
34 #define DMA_STM32_0_STREAM_COUNT 8
35 #elif DT_INST_IRQ_HAS_IDX(0, 6)
36 #define DMA_STM32_0_STREAM_COUNT 7
37 #elif DT_INST_IRQ_HAS_IDX(0, 5)
38 #define DMA_STM32_0_STREAM_COUNT 6
39 #elif DT_INST_IRQ_HAS_IDX(0, 4)
40 #define DMA_STM32_0_STREAM_COUNT 5
41 #else
42 #define DMA_STM32_0_STREAM_COUNT 3
43 #endif
44 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0)) */
45 
46 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(1))
47 #if DT_INST_IRQ_HAS_IDX(1, 7)
48 #define DMA_STM32_1_STREAM_COUNT 8
49 #elif DT_INST_IRQ_HAS_IDX(1, 6)
50 #define DMA_STM32_1_STREAM_COUNT 7
51 #elif DT_INST_IRQ_HAS_IDX(1, 5)
52 #define DMA_STM32_1_STREAM_COUNT 6
53 #else
54 #define DMA_STM32_1_STREAM_COUNT 5
55 #endif
56 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(1)) */
57 
58 static const uint32_t table_m_size[] = {
59 	LL_DMA_MDATAALIGN_BYTE,
60 	LL_DMA_MDATAALIGN_HALFWORD,
61 	LL_DMA_MDATAALIGN_WORD,
62 };
63 
64 static const uint32_t table_p_size[] = {
65 	LL_DMA_PDATAALIGN_BYTE,
66 	LL_DMA_PDATAALIGN_HALFWORD,
67 	LL_DMA_PDATAALIGN_WORD,
68 };
69 
dma_stm32_dump_stream_irq(const struct device * dev,uint32_t id)70 static void dma_stm32_dump_stream_irq(const struct device *dev, uint32_t id)
71 {
72 	const struct dma_stm32_config *config = dev->config;
73 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
74 
75 	stm32_dma_dump_stream_irq(dma, id);
76 }
77 
dma_stm32_clear_stream_irq(const struct device * dev,uint32_t id)78 static void dma_stm32_clear_stream_irq(const struct device *dev, uint32_t id)
79 {
80 	const struct dma_stm32_config *config = dev->config;
81 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
82 
83 	dma_stm32_clear_tc(dma, id);
84 	dma_stm32_clear_ht(dma, id);
85 	stm32_dma_clear_stream_irq(dma, id);
86 }
87 
dma_stm32_irq_handler(const struct device * dev,uint32_t id)88 static void dma_stm32_irq_handler(const struct device *dev, uint32_t id)
89 {
90 	const struct dma_stm32_config *config = dev->config;
91 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
92 	struct dma_stm32_stream *stream;
93 	uint32_t callback_arg;
94 
95 	__ASSERT_NO_MSG(id < config->max_streams);
96 
97 	stream = &config->streams[id];
98 
99 	/* The busy channel is pertinent if not overridden by the HAL */
100 	if ((stream->hal_override != true) && (stream->busy == false)) {
101 		/*
102 		 * When DMA channel is not overridden by HAL,
103 		 * ignore irq if the channel is not busy anymore
104 		 */
105 		dma_stm32_clear_stream_irq(dev, id);
106 		return;
107 	}
108 #ifdef CONFIG_DMAMUX_STM32
109 	callback_arg = stream->mux_channel;
110 #else
111 	callback_arg = id + STM32_DMA_STREAM_OFFSET;
112 #endif /* CONFIG_DMAMUX_STM32 */
113 
114 	/* The dma stream id is in range from STM32_DMA_STREAM_OFFSET..<dma-requests> */
115 	if (stm32_dma_is_ht_irq_active(dma, id)) {
116 		/* Let HAL DMA handle flags on its own */
117 		if (!stream->hal_override) {
118 			dma_stm32_clear_ht(dma, id);
119 		}
120 		stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_BLOCK);
121 	} else if (stm32_dma_is_tc_irq_active(dma, id)) {
122 		/* Circular buffer never stops receiving as long as peripheral is enabled */
123 		if (!stream->cyclic) {
124 			stream->busy = false;
125 		}
126 		/* Let HAL DMA handle flags on its own */
127 		if (!stream->hal_override) {
128 			dma_stm32_clear_tc(dma, id);
129 		}
130 		stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_COMPLETE);
131 	} else if (stm32_dma_is_unexpected_irq_happened(dma, id)) {
132 		LOG_ERR("Unexpected irq happened.");
133 		stream->dma_callback(dev, stream->user_data,
134 				     callback_arg, -EIO);
135 	} else {
136 		LOG_ERR("Transfer Error.");
137 		stream->busy = false;
138 		dma_stm32_dump_stream_irq(dev, id);
139 		dma_stm32_clear_stream_irq(dev, id);
140 		stream->dma_callback(dev, stream->user_data,
141 				     callback_arg, -EIO);
142 	}
143 }
144 
145 #ifdef CONFIG_DMA_STM32_SHARED_IRQS
146 
147 #define HANDLE_IRQS(index)						       \
148 	static const struct device *const dev_##index =			       \
149 		DEVICE_DT_INST_GET(index);				       \
150 	const struct dma_stm32_config *cfg_##index = dev_##index->config;      \
151 	DMA_TypeDef *dma_##index = (DMA_TypeDef *)(cfg_##index->base);	       \
152 									       \
153 	for (id = 0; id < cfg_##index->max_streams; ++id) {		       \
154 		if (stm32_dma_is_irq_active(dma_##index, id)) {		       \
155 			dma_stm32_irq_handler(dev_##index, id);		       \
156 		}							       \
157 	}
158 
dma_stm32_shared_irq_handler(const struct device * dev)159 static void dma_stm32_shared_irq_handler(const struct device *dev)
160 {
161 	ARG_UNUSED(dev);
162 	uint32_t id = 0;
163 
164 	DT_INST_FOREACH_STATUS_OKAY(HANDLE_IRQS)
165 }
166 
167 #endif /* CONFIG_DMA_STM32_SHARED_IRQS */
168 
dma_stm32_get_priority(uint8_t priority,uint32_t * ll_priority)169 static int dma_stm32_get_priority(uint8_t priority, uint32_t *ll_priority)
170 {
171 	switch (priority) {
172 	case 0x0:
173 		*ll_priority = LL_DMA_PRIORITY_LOW;
174 		break;
175 	case 0x1:
176 		*ll_priority = LL_DMA_PRIORITY_MEDIUM;
177 		break;
178 	case 0x2:
179 		*ll_priority = LL_DMA_PRIORITY_HIGH;
180 		break;
181 	case 0x3:
182 		*ll_priority = LL_DMA_PRIORITY_VERYHIGH;
183 		break;
184 	default:
185 		LOG_ERR("Priority error. %d", priority);
186 		return -EINVAL;
187 	}
188 
189 	return 0;
190 }
191 
dma_stm32_get_direction(enum dma_channel_direction direction,uint32_t * ll_direction)192 static int dma_stm32_get_direction(enum dma_channel_direction direction,
193 				   uint32_t *ll_direction)
194 {
195 	switch (direction) {
196 	case MEMORY_TO_MEMORY:
197 		*ll_direction = LL_DMA_DIRECTION_MEMORY_TO_MEMORY;
198 		break;
199 	case MEMORY_TO_PERIPHERAL:
200 		*ll_direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
201 		break;
202 	case PERIPHERAL_TO_MEMORY:
203 		*ll_direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
204 		break;
205 	default:
206 		LOG_ERR("Direction error. %d", direction);
207 		return -EINVAL;
208 	}
209 
210 	return 0;
211 }
212 
dma_stm32_get_memory_increment(enum dma_addr_adj increment,uint32_t * ll_increment)213 static int dma_stm32_get_memory_increment(enum dma_addr_adj increment,
214 					  uint32_t *ll_increment)
215 {
216 	switch (increment) {
217 	case DMA_ADDR_ADJ_INCREMENT:
218 		*ll_increment = LL_DMA_MEMORY_INCREMENT;
219 		break;
220 	case DMA_ADDR_ADJ_NO_CHANGE:
221 		*ll_increment = LL_DMA_MEMORY_NOINCREMENT;
222 		break;
223 	case DMA_ADDR_ADJ_DECREMENT:
224 		return -ENOTSUP;
225 	default:
226 		LOG_ERR("Memory increment error. %d", increment);
227 		return -EINVAL;
228 	}
229 
230 	return 0;
231 }
232 
dma_stm32_get_periph_increment(enum dma_addr_adj increment,uint32_t * ll_increment)233 static int dma_stm32_get_periph_increment(enum dma_addr_adj increment,
234 					  uint32_t *ll_increment)
235 {
236 	switch (increment) {
237 	case DMA_ADDR_ADJ_INCREMENT:
238 		*ll_increment = LL_DMA_PERIPH_INCREMENT;
239 		break;
240 	case DMA_ADDR_ADJ_NO_CHANGE:
241 		*ll_increment = LL_DMA_PERIPH_NOINCREMENT;
242 		break;
243 	case DMA_ADDR_ADJ_DECREMENT:
244 		return -ENOTSUP;
245 	default:
246 		LOG_ERR("Periph increment error. %d", increment);
247 		return -EINVAL;
248 	}
249 
250 	return 0;
251 }
252 
dma_stm32_disable_stream(DMA_TypeDef * dma,uint32_t id)253 static int dma_stm32_disable_stream(DMA_TypeDef *dma, uint32_t id)
254 {
255 	int count = 0;
256 
257 	for (;;) {
258 		if (stm32_dma_disable_stream(dma, id) == 0) {
259 			return 0;
260 		}
261 		/* After trying for 5 seconds, give up */
262 		if (count++ > (5 * 1000)) {
263 			return -EBUSY;
264 		}
265 		k_sleep(K_MSEC(1));
266 	}
267 
268 	return 0;
269 }
270 
dma_stm32_configure(const struct device * dev,uint32_t id,struct dma_config * config)271 DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev,
272 					     uint32_t id,
273 					     struct dma_config *config)
274 {
275 	const struct dma_stm32_config *dev_config = dev->config;
276 	struct dma_stm32_stream *stream =
277 				&dev_config->streams[id - STM32_DMA_STREAM_OFFSET];
278 	DMA_TypeDef *dma = (DMA_TypeDef *)dev_config->base;
279 	LL_DMA_InitTypeDef DMA_InitStruct;
280 	int ret;
281 
282 	LL_DMA_StructInit(&DMA_InitStruct);
283 
284 	/* Give channel from index 0 */
285 	id = id - STM32_DMA_STREAM_OFFSET;
286 
287 	if (id >= dev_config->max_streams) {
288 		LOG_ERR("cannot configure the dma stream %d.", id);
289 		return -EINVAL;
290 	}
291 
292 	if (stream->busy) {
293 		LOG_ERR("dma stream %d is busy.", id);
294 		return -EBUSY;
295 	}
296 
297 	if (dma_stm32_disable_stream(dma, id) != 0) {
298 		LOG_ERR("could not disable dma stream %d.", id);
299 		return -EBUSY;
300 	}
301 
302 	dma_stm32_clear_stream_irq(dev, id);
303 
304 	/* Check potential DMA override (if id parameters and stream are valid) */
305 	if (config->linked_channel == STM32_DMA_HAL_OVERRIDE) {
306 		/* DMA channel is overridden by HAL DMA
307 		 * Retain that the channel is busy and proceed to the minimal
308 		 * configuration to properly route the IRQ
309 		 */
310 		stream->busy = true;
311 		stream->hal_override = true;
312 		stream->dma_callback = config->dma_callback;
313 		stream->user_data = config->user_data;
314 		stream->cyclic = false;
315 		return 0;
316 	}
317 
318 	if (config->head_block->block_size > DMA_STM32_MAX_DATA_ITEMS) {
319 		LOG_ERR("Data size too big: %d\n",
320 		       config->head_block->block_size);
321 		return -EINVAL;
322 	}
323 
324 #ifdef CONFIG_DMA_STM32_V1
325 	if ((config->channel_direction == MEMORY_TO_MEMORY) &&
326 		(!dev_config->support_m2m)) {
327 		LOG_ERR("Memcopy not supported for device %s",
328 			dev->name);
329 		return -ENOTSUP;
330 	}
331 #endif /* CONFIG_DMA_STM32_V1 */
332 
333 	/* Support only the same data width for source and dest */
334 	if ((config->dest_data_size != config->source_data_size)) {
335 		LOG_ERR("source and dest data size differ.");
336 		return -EINVAL;
337 	}
338 
339 	if (config->source_data_size != 4U &&
340 	    config->source_data_size != 2U &&
341 	    config->source_data_size != 1U) {
342 		LOG_ERR("source and dest unit size error, %d",
343 			config->source_data_size);
344 		return -EINVAL;
345 	}
346 
347 	/*
348 	 * STM32's circular mode will auto reset both source address
349 	 * counter and destination address counter.
350 	 */
351 	if (config->head_block->source_reload_en !=
352 		config->head_block->dest_reload_en) {
353 		LOG_ERR("source_reload_en and dest_reload_en must "
354 			"be the same.");
355 		return -EINVAL;
356 	}
357 
358 	stream->busy		= true;
359 	stream->dma_callback	= config->dma_callback;
360 	stream->direction	= config->channel_direction;
361 	stream->user_data       = config->user_data;
362 	stream->src_size	= config->source_data_size;
363 	stream->dst_size	= config->dest_data_size;
364 	stream->cyclic		= config->head_block->source_reload_en;
365 
366 	/* Check dest or source memory address, warn if 0 */
367 	if (config->head_block->source_address == 0) {
368 		LOG_WRN("source_buffer address is null.");
369 	}
370 
371 	if (config->head_block->dest_address == 0) {
372 		LOG_WRN("dest_buffer address is null.");
373 	}
374 
375 	if (stream->direction == MEMORY_TO_PERIPHERAL) {
376 		DMA_InitStruct.MemoryOrM2MDstAddress =
377 					config->head_block->source_address;
378 		DMA_InitStruct.PeriphOrM2MSrcAddress =
379 					config->head_block->dest_address;
380 	} else {
381 		DMA_InitStruct.PeriphOrM2MSrcAddress =
382 					config->head_block->source_address;
383 		DMA_InitStruct.MemoryOrM2MDstAddress =
384 					config->head_block->dest_address;
385 	}
386 
387 	uint16_t memory_addr_adj = 0, periph_addr_adj = 0;
388 
389 	ret = dma_stm32_get_priority(config->channel_priority,
390 				     &DMA_InitStruct.Priority);
391 	if (ret < 0) {
392 		return ret;
393 	}
394 
395 	ret = dma_stm32_get_direction(config->channel_direction,
396 				      &DMA_InitStruct.Direction);
397 	if (ret < 0) {
398 		return ret;
399 	}
400 
401 	switch (config->channel_direction) {
402 	case MEMORY_TO_MEMORY:
403 	case PERIPHERAL_TO_MEMORY:
404 		memory_addr_adj = config->head_block->dest_addr_adj;
405 		periph_addr_adj = config->head_block->source_addr_adj;
406 		break;
407 	case MEMORY_TO_PERIPHERAL:
408 		memory_addr_adj = config->head_block->source_addr_adj;
409 		periph_addr_adj = config->head_block->dest_addr_adj;
410 		break;
411 	/* Direction has been asserted in dma_stm32_get_direction. */
412 	default:
413 		LOG_ERR("Channel direction error (%d).",
414 				config->channel_direction);
415 		return -EINVAL;
416 	}
417 
418 	ret = dma_stm32_get_memory_increment(memory_addr_adj,
419 					&DMA_InitStruct.MemoryOrM2MDstIncMode);
420 	if (ret < 0) {
421 		return ret;
422 	}
423 
424 	LOG_DBG("Channel (%d) memory inc (%x).",
425 				id, DMA_InitStruct.MemoryOrM2MDstIncMode);
426 
427 	ret = dma_stm32_get_periph_increment(periph_addr_adj,
428 					&DMA_InitStruct.PeriphOrM2MSrcIncMode);
429 	if (ret < 0) {
430 		return ret;
431 	}
432 
433 	LOG_DBG("Channel (%d) peripheral inc (%x).",
434 				id, DMA_InitStruct.PeriphOrM2MSrcIncMode);
435 
436 	if (stream->cyclic) {
437 		DMA_InitStruct.Mode = LL_DMA_MODE_CIRCULAR;
438 	} else {
439 		DMA_InitStruct.Mode = LL_DMA_MODE_NORMAL;
440 	}
441 
442 	stream->source_periph = (stream->direction == PERIPHERAL_TO_MEMORY);
443 
444 	/* set the data width, when source_data_size equals dest_data_size */
445 	int index = find_lsb_set(config->source_data_size) - 1;
446 	DMA_InitStruct.PeriphOrM2MSrcDataSize = table_p_size[index];
447 	index = find_lsb_set(config->dest_data_size) - 1;
448 	DMA_InitStruct.MemoryOrM2MDstDataSize = table_m_size[index];
449 
450 #if defined(CONFIG_DMA_STM32_V1)
451 	DMA_InitStruct.MemBurst = stm32_dma_get_mburst(config,
452 						       stream->source_periph);
453 	DMA_InitStruct.PeriphBurst = stm32_dma_get_pburst(config,
454 							stream->source_periph);
455 
456 #if !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32MP1X)
457 	if (config->channel_direction != MEMORY_TO_MEMORY) {
458 		if (config->dma_slot >= 8) {
459 			LOG_ERR("dma slot error.");
460 			return -EINVAL;
461 		}
462 	} else {
463 		if (config->dma_slot >= 8) {
464 			LOG_ERR("dma slot is too big, using 0 as default.");
465 			config->dma_slot = 0;
466 		}
467 	}
468 
469 	DMA_InitStruct.Channel = dma_stm32_slot_to_channel(config->dma_slot);
470 #endif
471 
472 	DMA_InitStruct.FIFOThreshold = stm32_dma_get_fifo_threshold(
473 					config->head_block->fifo_mode_control);
474 
475 	if (stm32_dma_check_fifo_mburst(&DMA_InitStruct)) {
476 		DMA_InitStruct.FIFOMode = LL_DMA_FIFOMODE_ENABLE;
477 	} else {
478 		DMA_InitStruct.FIFOMode = LL_DMA_FIFOMODE_DISABLE;
479 	}
480 #endif
481 	if (stream->source_periph) {
482 		DMA_InitStruct.NbData = config->head_block->block_size /
483 					config->source_data_size;
484 	} else {
485 		DMA_InitStruct.NbData = config->head_block->block_size /
486 					config->dest_data_size;
487 	}
488 
489 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_dma_v2) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32_dmamux)
490 	/* With dma V2 and dmamux,the request ID is stored in the dma_slot */
491 	DMA_InitStruct.PeriphRequest = config->dma_slot;
492 #endif
493 	LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct);
494 
495 	LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id));
496 
497 	/* Enable Half-Transfer irq if circular mode is enabled */
498 	if (stream->cyclic) {
499 		LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id));
500 	}
501 
502 #if defined(CONFIG_DMA_STM32_V1)
503 	if (DMA_InitStruct.FIFOMode == LL_DMA_FIFOMODE_ENABLE) {
504 		LL_DMA_EnableFifoMode(dma, dma_stm32_id_to_stream(id));
505 		LL_DMA_EnableIT_FE(dma, dma_stm32_id_to_stream(id));
506 	} else {
507 		LL_DMA_DisableFifoMode(dma, dma_stm32_id_to_stream(id));
508 		LL_DMA_DisableIT_FE(dma, dma_stm32_id_to_stream(id));
509 	}
510 #endif
511 	return ret;
512 }
513 
dma_stm32_reload(const struct device * dev,uint32_t id,uint32_t src,uint32_t dst,size_t size)514 DMA_STM32_EXPORT_API int dma_stm32_reload(const struct device *dev, uint32_t id,
515 					  uint32_t src, uint32_t dst,
516 					  size_t size)
517 {
518 	const struct dma_stm32_config *config = dev->config;
519 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
520 	struct dma_stm32_stream *stream;
521 
522 	/* Give channel from index 0 */
523 	id = id - STM32_DMA_STREAM_OFFSET;
524 
525 	if (id >= config->max_streams) {
526 		return -EINVAL;
527 	}
528 
529 	stream = &config->streams[id];
530 
531 	if (dma_stm32_disable_stream(dma, id) != 0) {
532 		return -EBUSY;
533 	}
534 
535 	switch (stream->direction) {
536 	case MEMORY_TO_PERIPHERAL:
537 		LL_DMA_SetMemoryAddress(dma, dma_stm32_id_to_stream(id), src);
538 		LL_DMA_SetPeriphAddress(dma, dma_stm32_id_to_stream(id), dst);
539 		break;
540 	case MEMORY_TO_MEMORY:
541 	case PERIPHERAL_TO_MEMORY:
542 		LL_DMA_SetPeriphAddress(dma, dma_stm32_id_to_stream(id), src);
543 		LL_DMA_SetMemoryAddress(dma, dma_stm32_id_to_stream(id), dst);
544 		break;
545 	default:
546 		return -EINVAL;
547 	}
548 
549 	if (stream->source_periph) {
550 		LL_DMA_SetDataLength(dma, dma_stm32_id_to_stream(id),
551 				     size / stream->src_size);
552 	} else {
553 		LL_DMA_SetDataLength(dma, dma_stm32_id_to_stream(id),
554 				     size / stream->dst_size);
555 	}
556 
557 	/* When reloading the dma, the stream is busy again before enabling */
558 	stream->busy = true;
559 
560 	stm32_dma_enable_stream(dma, id);
561 
562 	return 0;
563 }
564 
dma_stm32_start(const struct device * dev,uint32_t id)565 DMA_STM32_EXPORT_API int dma_stm32_start(const struct device *dev, uint32_t id)
566 {
567 	const struct dma_stm32_config *config = dev->config;
568 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
569 	struct dma_stm32_stream *stream;
570 
571 	/* Give channel from index 0 */
572 	id = id - STM32_DMA_STREAM_OFFSET;
573 
574 	/* Only M2P or M2M mode can be started manually. */
575 	if (id >= config->max_streams) {
576 		return -EINVAL;
577 	}
578 
579 	/* Repeated start : return now if channel is already started */
580 	if (stm32_dma_is_enabled_stream(dma, id)) {
581 		return 0;
582 	}
583 
584 	/* When starting the dma, the stream is busy before enabling */
585 	stream = &config->streams[id];
586 	stream->busy = true;
587 
588 	dma_stm32_clear_stream_irq(dev, id);
589 	stm32_dma_enable_stream(dma, id);
590 
591 	return 0;
592 }
593 
dma_stm32_stop(const struct device * dev,uint32_t id)594 DMA_STM32_EXPORT_API int dma_stm32_stop(const struct device *dev, uint32_t id)
595 {
596 	const struct dma_stm32_config *config = dev->config;
597 	struct dma_stm32_stream *stream = &config->streams[id - STM32_DMA_STREAM_OFFSET];
598 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
599 
600 	/* Give channel from index 0 */
601 	id = id - STM32_DMA_STREAM_OFFSET;
602 
603 	if (id >= config->max_streams) {
604 		return -EINVAL;
605 	}
606 
607 	if (stream->hal_override) {
608 		stream->busy = false;
609 		return 0;
610 	}
611 
612 	/* Repeated stop : return now if channel is already stopped */
613 	if (!stm32_dma_is_enabled_stream(dma, id)) {
614 		return 0;
615 	}
616 
617 #if !defined(CONFIG_DMAMUX_STM32) \
618 	|| defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32MP1X)
619 	LL_DMA_DisableIT_TC(dma, dma_stm32_id_to_stream(id));
620 #endif /* CONFIG_DMAMUX_STM32 */
621 
622 #if defined(CONFIG_DMA_STM32_V1)
623 	stm32_dma_disable_fifo_irq(dma, id);
624 #endif
625 
626 	dma_stm32_clear_stream_irq(dev, id);
627 	dma_stm32_disable_stream(dma, id);
628 
629 	/* Finally, flag stream as free */
630 	stream->busy = false;
631 
632 	return 0;
633 }
634 
dma_stm32_init(const struct device * dev)635 static int dma_stm32_init(const struct device *dev)
636 {
637 	const struct dma_stm32_config *config = dev->config;
638 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
639 
640 	if (!device_is_ready(clk)) {
641 		LOG_ERR("clock control device not ready");
642 		return -ENODEV;
643 	}
644 
645 	if (clock_control_on(clk,
646 		(clock_control_subsys_t) &config->pclken) != 0) {
647 		LOG_ERR("clock op failed\n");
648 		return -EIO;
649 	}
650 
651 	config->config_irq(dev);
652 
653 	for (uint32_t i = 0; i < config->max_streams; i++) {
654 		config->streams[i].busy = false;
655 #ifdef CONFIG_DMAMUX_STM32
656 		/* Each further stream->mux_channel is fixed here */
657 		config->streams[i].mux_channel = i + config->offset;
658 #endif /* CONFIG_DMAMUX_STM32 */
659 	}
660 
661 	((struct dma_stm32_data *)dev->data)->dma_ctx.magic = 0;
662 	((struct dma_stm32_data *)dev->data)->dma_ctx.dma_channels = 0;
663 	((struct dma_stm32_data *)dev->data)->dma_ctx.atomic = 0;
664 
665 	return 0;
666 }
667 
dma_stm32_get_status(const struct device * dev,uint32_t id,struct dma_status * stat)668 DMA_STM32_EXPORT_API int dma_stm32_get_status(const struct device *dev,
669 				uint32_t id, struct dma_status *stat)
670 {
671 	const struct dma_stm32_config *config = dev->config;
672 	DMA_TypeDef *dma = (DMA_TypeDef *)(config->base);
673 	struct dma_stm32_stream *stream;
674 
675 	/* Give channel from index 0 */
676 	id = id - STM32_DMA_STREAM_OFFSET;
677 	if (id >= config->max_streams) {
678 		return -EINVAL;
679 	}
680 
681 	stream = &config->streams[id];
682 	stat->pending_length = LL_DMA_GetDataLength(dma, dma_stm32_id_to_stream(id));
683 	stat->dir = stream->direction;
684 	stat->busy = stream->busy;
685 
686 	return 0;
687 }
688 
689 static DEVICE_API(dma, dma_funcs) = {
690 	.reload		 = dma_stm32_reload,
691 	.config		 = dma_stm32_configure,
692 	.start		 = dma_stm32_start,
693 	.stop		 = dma_stm32_stop,
694 	.get_status	 = dma_stm32_get_status,
695 };
696 
697 #define DMA_STM32_INIT_DEV(index)					\
698 static struct dma_stm32_stream						\
699 	dma_stm32_streams_##index[DMA_STM32_##index##_STREAM_COUNT];	\
700 									\
701 const struct dma_stm32_config dma_stm32_config_##index = {		\
702 	.pclken = { .bus = DT_INST_CLOCKS_CELL(index, bus),		\
703 		    .enr = DT_INST_CLOCKS_CELL(index, bits) },		\
704 	.config_irq = dma_stm32_config_irq_##index,			\
705 	.base = DT_INST_REG_ADDR(index),				\
706 	IF_ENABLED(CONFIG_DMA_STM32_V1,					\
707 		(.support_m2m = DT_INST_PROP(index, st_mem2mem),))	\
708 	.max_streams = DMA_STM32_##index##_STREAM_COUNT,		\
709 	.streams = dma_stm32_streams_##index,				\
710 	IF_ENABLED(CONFIG_DMAMUX_STM32,					\
711 		(.offset = DT_INST_PROP(index, dma_offset),))		\
712 };									\
713 									\
714 static struct dma_stm32_data dma_stm32_data_##index = {			\
715 };									\
716 									\
717 DEVICE_DT_INST_DEFINE(index,						\
718 		    &dma_stm32_init,					\
719 		    NULL,						\
720 		    &dma_stm32_data_##index, &dma_stm32_config_##index,	\
721 		    PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY,		\
722 		    &dma_funcs)
723 
724 #ifdef CONFIG_DMA_STM32_SHARED_IRQS
725 
726 #define DMA_STM32_DEFINE_IRQ_HANDLER(dma, chan) /* nothing */
727 
728 /** Connect and enable IRQ @p chan of DMA instance @p dma */
729 #define DMA_STM32_IRQ_CONNECT(dma, chan)				\
730 	do {								\
731 		IRQ_CONNECT(DT_INST_IRQ_BY_IDX(dma, chan, irq),		\
732 			    DT_INST_IRQ_BY_IDX(dma, chan, priority),	\
733 			    dma_stm32_shared_irq_handler,		\
734 			    DEVICE_DT_INST_GET(dma), 0);		\
735 		irq_enable(DT_INST_IRQ_BY_IDX(dma, chan, irq));		\
736 	} while (false)
737 
738 
739 #else /* CONFIG_DMA_STM32_SHARED_IRQS */
740 
741 #define DMA_STM32_DEFINE_IRQ_HANDLER(dma, chan)				\
742 static void dma_stm32_irq_##dma##_##chan(const struct device *dev)	\
743 {									\
744 	dma_stm32_irq_handler(dev, chan);				\
745 }
746 
747 /**
748  * Connect and enable IRQ @p chan of DMA instance @p dma
749  *
750  * @note Arguments order is reversed for compatibility with LISTIFY!
751  */
752 #define DMA_STM32_IRQ_CONNECT(chan, dma)				\
753 	do {								\
754 		IRQ_CONNECT(DT_INST_IRQ_BY_IDX(dma, chan, irq),		\
755 			    DT_INST_IRQ_BY_IDX(dma, chan, priority),	\
756 			    dma_stm32_irq_##dma##_##chan,		\
757 			    DEVICE_DT_INST_GET(dma), 0);		\
758 		irq_enable(DT_INST_IRQ_BY_IDX(dma, chan, irq));		\
759 	} while (false)
760 
761 #endif /* CONFIG_DMA_STM32_SHARED_IRQS */
762 
763 
764 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0))
765 
766 DMA_STM32_DEFINE_IRQ_HANDLER(0, 0);
767 DMA_STM32_DEFINE_IRQ_HANDLER(0, 1);
768 DMA_STM32_DEFINE_IRQ_HANDLER(0, 2);
769 #if DT_INST_IRQ_HAS_IDX(0, 3)
770 DMA_STM32_DEFINE_IRQ_HANDLER(0, 3);
771 DMA_STM32_DEFINE_IRQ_HANDLER(0, 4);
772 #if DT_INST_IRQ_HAS_IDX(0, 5)
773 DMA_STM32_DEFINE_IRQ_HANDLER(0, 5);
774 #if DT_INST_IRQ_HAS_IDX(0, 6)
775 DMA_STM32_DEFINE_IRQ_HANDLER(0, 6);
776 #if DT_INST_IRQ_HAS_IDX(0, 7)
777 DMA_STM32_DEFINE_IRQ_HANDLER(0, 7);
778 #endif /* DT_INST_IRQ_HAS_IDX(0, 3) */
779 #endif /* DT_INST_IRQ_HAS_IDX(0, 5) */
780 #endif /* DT_INST_IRQ_HAS_IDX(0, 6) */
781 #endif /* DT_INST_IRQ_HAS_IDX(0, 7) */
782 
dma_stm32_config_irq_0(const struct device * dev)783 static void dma_stm32_config_irq_0(const struct device *dev)
784 {
785 	ARG_UNUSED(dev);
786 
787 #if !defined(CONFIG_DMA_STM32_SHARED_IRQS)
788 	/* No shared IRQs: call IRQ_CONNECT for each IRQn in DTS */
789 	LISTIFY(
790 		DT_INST_NUM_IRQS(0),
791 		DMA_STM32_IRQ_CONNECT,
792 		(;), /* instance: */ 0
793 	);
794 #else
795 	/* All DMAs have at least one IRQ line */
796 	DMA_STM32_IRQ_CONNECT(0, 0);
797 
798 	/* On STM32WB0 series, there is a single IRQ line for all channels */
799 #if !defined(CONFIG_SOC_SERIES_STM32WB0X)
800 	/* On other series, the sharing follows a pattern:
801 	 *	IRQn (X+0) is not shared (assigned to DMA1 channel 1)
802 	 *	IRQn (X+1) is shared by DMA1 channels 2 and 3
803 	 *	IRQn (X+2) is shared by DMA1 channels >= 4
804 	 *
805 	 * If present, DMA2 channels may also share IRQn (X+1) and (X+2);
806 	 * this works fine because shared ISR checks all channels of all DMAs.
807 	 */
808 
809 	/* Connect IRQ line shared by CH2 and CH3 */
810 	DMA_STM32_IRQ_CONNECT(0, 1);
811 
812 	/* If DMA has more than 3 channels, connect IRQ line shared by CH4+ */
813 #if DT_INST_IRQ_HAS_IDX(0, 3)
814 	DMA_STM32_IRQ_CONNECT(0, 3);
815 #endif /* DT_INST_IRQ_HAS_IDX(0, 3) */
816 #endif /* !CONFIG_SOC_SERIES_STM32WB0X */
817 #endif /* !CONFIG_DMA_STM32_SHARED_IRQS */
818 }
819 
820 DMA_STM32_INIT_DEV(0);
821 
822 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0)) */
823 
824 
825 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(1))
826 
827 DMA_STM32_DEFINE_IRQ_HANDLER(1, 0);
828 DMA_STM32_DEFINE_IRQ_HANDLER(1, 1);
829 DMA_STM32_DEFINE_IRQ_HANDLER(1, 2);
830 DMA_STM32_DEFINE_IRQ_HANDLER(1, 3);
831 #if DT_INST_IRQ_HAS_IDX(1, 4)
832 DMA_STM32_DEFINE_IRQ_HANDLER(1, 4);
833 #if DT_INST_IRQ_HAS_IDX(1, 5)
834 DMA_STM32_DEFINE_IRQ_HANDLER(1, 5);
835 #if DT_INST_IRQ_HAS_IDX(1, 6)
836 DMA_STM32_DEFINE_IRQ_HANDLER(1, 6);
837 #if DT_INST_IRQ_HAS_IDX(1, 7)
838 DMA_STM32_DEFINE_IRQ_HANDLER(1, 7);
839 #endif /* DT_INST_IRQ_HAS_IDX(1, 4) */
840 #endif /* DT_INST_IRQ_HAS_IDX(1, 5) */
841 #endif /* DT_INST_IRQ_HAS_IDX(1, 6) */
842 #endif /* DT_INST_IRQ_HAS_IDX(1, 7) */
843 
dma_stm32_config_irq_1(const struct device * dev)844 static void dma_stm32_config_irq_1(const struct device *dev)
845 {
846 	ARG_UNUSED(dev);
847 
848 #ifndef CONFIG_DMA_STM32_SHARED_IRQS
849 	/* No shared IRQs: call IRQ_CONNECT for each IRQn in DTS */
850 	LISTIFY(
851 		DT_INST_NUM_IRQS(1),
852 		DMA_STM32_IRQ_CONNECT,
853 		(;), /* instance: */ 1
854 	);
855 #else
856 	/**
857 	 * Series with 2 DMAs and SHARED_IRQS are STM32F0 and STM32G0.
858 	 * On both of these series, the DMA2 interrupt lines are shared with DMA1,
859 	 * so they have already been IRQ_CONNECT()'ed and there's nothing to do here.
860 	 */
861 #endif /* !CONFIG_DMA_STM32_SHARED_IRQS */
862 }
863 
864 DMA_STM32_INIT_DEV(1);
865 
866 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(1)) */
867