1 /*
2  * Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief DMA low level driver implementation for F2/F4/F7 series SoCs.
9  */
10 
11 #include "dma_stm32.h"
12 
13 #define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
14 #include <logging/log.h>
15 LOG_MODULE_REGISTER(dma_stm32_v1);
16 
17 /* DMA burst length */
18 #define BURST_TRANS_LENGTH_1			0
19 
dma_stm32_id_to_stream(uint32_t id)20 uint32_t dma_stm32_id_to_stream(uint32_t id)
21 {
22 	static const uint32_t stream_nr[] = {
23 		LL_DMA_STREAM_0,
24 		LL_DMA_STREAM_1,
25 		LL_DMA_STREAM_2,
26 		LL_DMA_STREAM_3,
27 		LL_DMA_STREAM_4,
28 		LL_DMA_STREAM_5,
29 		LL_DMA_STREAM_6,
30 		LL_DMA_STREAM_7,
31 	};
32 
33 	__ASSERT_NO_MSG(id < ARRAY_SIZE(stream_nr));
34 
35 	return stream_nr[id];
36 }
37 
38 #if !defined(CONFIG_DMAMUX_STM32)
dma_stm32_slot_to_channel(uint32_t slot)39 uint32_t dma_stm32_slot_to_channel(uint32_t slot)
40 {
41 	static const uint32_t channel_nr[] = {
42 		LL_DMA_CHANNEL_0,
43 		LL_DMA_CHANNEL_1,
44 		LL_DMA_CHANNEL_2,
45 		LL_DMA_CHANNEL_3,
46 		LL_DMA_CHANNEL_4,
47 		LL_DMA_CHANNEL_5,
48 		LL_DMA_CHANNEL_6,
49 		LL_DMA_CHANNEL_7,
50 	};
51 
52 	__ASSERT_NO_MSG(slot < ARRAY_SIZE(channel_nr));
53 
54 	return channel_nr[slot];
55 }
56 #endif
57 
dma_stm32_clear_ht(DMA_TypeDef * DMAx,uint32_t id)58 void dma_stm32_clear_ht(DMA_TypeDef *DMAx, uint32_t id)
59 {
60 	static const dma_stm32_clear_flag_func func[] = {
61 		LL_DMA_ClearFlag_HT0,
62 		LL_DMA_ClearFlag_HT1,
63 		LL_DMA_ClearFlag_HT2,
64 		LL_DMA_ClearFlag_HT3,
65 		LL_DMA_ClearFlag_HT4,
66 		LL_DMA_ClearFlag_HT5,
67 		LL_DMA_ClearFlag_HT6,
68 		LL_DMA_ClearFlag_HT7,
69 	};
70 
71 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
72 
73 	func[id](DMAx);
74 }
75 
dma_stm32_clear_tc(DMA_TypeDef * DMAx,uint32_t id)76 void dma_stm32_clear_tc(DMA_TypeDef *DMAx, uint32_t id)
77 {
78 	static const dma_stm32_clear_flag_func func[] = {
79 		LL_DMA_ClearFlag_TC0,
80 		LL_DMA_ClearFlag_TC1,
81 		LL_DMA_ClearFlag_TC2,
82 		LL_DMA_ClearFlag_TC3,
83 		LL_DMA_ClearFlag_TC4,
84 		LL_DMA_ClearFlag_TC5,
85 		LL_DMA_ClearFlag_TC6,
86 		LL_DMA_ClearFlag_TC7,
87 	};
88 
89 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
90 
91 	func[id](DMAx);
92 }
93 
dma_stm32_is_ht_active(DMA_TypeDef * DMAx,uint32_t id)94 bool dma_stm32_is_ht_active(DMA_TypeDef *DMAx, uint32_t id)
95 {
96 	static const dma_stm32_check_flag_func func[] = {
97 		LL_DMA_IsActiveFlag_HT0,
98 		LL_DMA_IsActiveFlag_HT1,
99 		LL_DMA_IsActiveFlag_HT2,
100 		LL_DMA_IsActiveFlag_HT3,
101 		LL_DMA_IsActiveFlag_HT4,
102 		LL_DMA_IsActiveFlag_HT5,
103 		LL_DMA_IsActiveFlag_HT6,
104 		LL_DMA_IsActiveFlag_HT7,
105 	};
106 
107 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
108 
109 	return func[id](DMAx);
110 }
111 
dma_stm32_is_tc_active(DMA_TypeDef * DMAx,uint32_t id)112 bool dma_stm32_is_tc_active(DMA_TypeDef *DMAx, uint32_t id)
113 {
114 	static const dma_stm32_check_flag_func func[] = {
115 		LL_DMA_IsActiveFlag_TC0,
116 		LL_DMA_IsActiveFlag_TC1,
117 		LL_DMA_IsActiveFlag_TC2,
118 		LL_DMA_IsActiveFlag_TC3,
119 		LL_DMA_IsActiveFlag_TC4,
120 		LL_DMA_IsActiveFlag_TC5,
121 		LL_DMA_IsActiveFlag_TC6,
122 		LL_DMA_IsActiveFlag_TC7,
123 	};
124 
125 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
126 
127 	return func[id](DMAx);
128 }
129 
dma_stm32_clear_te(DMA_TypeDef * DMAx,uint32_t id)130 void dma_stm32_clear_te(DMA_TypeDef *DMAx, uint32_t id)
131 {
132 	static const dma_stm32_clear_flag_func func[] = {
133 		LL_DMA_ClearFlag_TE0,
134 		LL_DMA_ClearFlag_TE1,
135 		LL_DMA_ClearFlag_TE2,
136 		LL_DMA_ClearFlag_TE3,
137 		LL_DMA_ClearFlag_TE4,
138 		LL_DMA_ClearFlag_TE5,
139 		LL_DMA_ClearFlag_TE6,
140 		LL_DMA_ClearFlag_TE7,
141 	};
142 
143 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
144 
145 	func[id](DMAx);
146 }
147 
dma_stm32_clear_dme(DMA_TypeDef * DMAx,uint32_t id)148 void dma_stm32_clear_dme(DMA_TypeDef *DMAx, uint32_t id)
149 {
150 	static const dma_stm32_clear_flag_func func[] = {
151 		LL_DMA_ClearFlag_DME0,
152 		LL_DMA_ClearFlag_DME1,
153 		LL_DMA_ClearFlag_DME2,
154 		LL_DMA_ClearFlag_DME3,
155 		LL_DMA_ClearFlag_DME4,
156 		LL_DMA_ClearFlag_DME5,
157 		LL_DMA_ClearFlag_DME6,
158 		LL_DMA_ClearFlag_DME7,
159 	};
160 
161 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
162 
163 	func[id](DMAx);
164 }
165 
dma_stm32_clear_fe(DMA_TypeDef * DMAx,uint32_t id)166 void dma_stm32_clear_fe(DMA_TypeDef *DMAx, uint32_t id)
167 {
168 	static const dma_stm32_clear_flag_func func[] = {
169 		LL_DMA_ClearFlag_FE0,
170 		LL_DMA_ClearFlag_FE1,
171 		LL_DMA_ClearFlag_FE2,
172 		LL_DMA_ClearFlag_FE3,
173 		LL_DMA_ClearFlag_FE4,
174 		LL_DMA_ClearFlag_FE5,
175 		LL_DMA_ClearFlag_FE6,
176 		LL_DMA_ClearFlag_FE7,
177 	};
178 
179 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
180 
181 	func[id](DMAx);
182 }
183 
dma_stm32_is_te_active(DMA_TypeDef * DMAx,uint32_t id)184 bool dma_stm32_is_te_active(DMA_TypeDef *DMAx, uint32_t id)
185 {
186 	static const dma_stm32_check_flag_func func[] = {
187 		LL_DMA_IsActiveFlag_TE0,
188 		LL_DMA_IsActiveFlag_TE1,
189 		LL_DMA_IsActiveFlag_TE2,
190 		LL_DMA_IsActiveFlag_TE3,
191 		LL_DMA_IsActiveFlag_TE4,
192 		LL_DMA_IsActiveFlag_TE5,
193 		LL_DMA_IsActiveFlag_TE6,
194 		LL_DMA_IsActiveFlag_TE7,
195 	};
196 
197 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
198 
199 	return func[id](DMAx);
200 }
201 
dma_stm32_is_dme_active(DMA_TypeDef * DMAx,uint32_t id)202 bool dma_stm32_is_dme_active(DMA_TypeDef *DMAx, uint32_t id)
203 {
204 	static const dma_stm32_check_flag_func func[] = {
205 		LL_DMA_IsActiveFlag_DME0,
206 		LL_DMA_IsActiveFlag_DME1,
207 		LL_DMA_IsActiveFlag_DME2,
208 		LL_DMA_IsActiveFlag_DME3,
209 		LL_DMA_IsActiveFlag_DME4,
210 		LL_DMA_IsActiveFlag_DME5,
211 		LL_DMA_IsActiveFlag_DME6,
212 		LL_DMA_IsActiveFlag_DME7,
213 	};
214 
215 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
216 
217 	return func[id](DMAx);
218 }
219 
dma_stm32_is_fe_active(DMA_TypeDef * DMAx,uint32_t id)220 bool dma_stm32_is_fe_active(DMA_TypeDef *DMAx, uint32_t id)
221 {
222 	static const dma_stm32_check_flag_func func[] = {
223 		LL_DMA_IsActiveFlag_FE0,
224 		LL_DMA_IsActiveFlag_FE1,
225 		LL_DMA_IsActiveFlag_FE2,
226 		LL_DMA_IsActiveFlag_FE3,
227 		LL_DMA_IsActiveFlag_FE4,
228 		LL_DMA_IsActiveFlag_FE5,
229 		LL_DMA_IsActiveFlag_FE6,
230 		LL_DMA_IsActiveFlag_FE7,
231 	};
232 
233 	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));
234 
235 	return func[id](DMAx);
236 }
237 
stm32_dma_dump_stream_irq(DMA_TypeDef * dma,uint32_t id)238 void stm32_dma_dump_stream_irq(DMA_TypeDef *dma, uint32_t id)
239 {
240 	LOG_INF("tc: %d, ht: %d, te: %d, dme: %d, fe: %d",
241 		dma_stm32_is_tc_active(dma, id),
242 		dma_stm32_is_ht_active(dma, id),
243 		dma_stm32_is_te_active(dma, id),
244 		dma_stm32_is_dme_active(dma, id),
245 		dma_stm32_is_fe_active(dma, id));
246 }
247 
stm32_dma_is_tc_irq_active(DMA_TypeDef * dma,uint32_t id)248 inline bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
249 {
250 	return LL_DMA_IsEnabledIT_TC(dma, dma_stm32_id_to_stream(id)) &&
251 	       dma_stm32_is_tc_active(dma, id);
252 }
253 
stm32_dma_is_ht_irq_active(DMA_TypeDef * dma,uint32_t id)254 inline bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
255 {
256 	return LL_DMA_IsEnabledIT_HT(dma, dma_stm32_id_to_stream(id)) &&
257 	       dma_stm32_is_ht_active(dma, id);
258 }
259 
stm32_dma_is_te_irq_active(DMA_TypeDef * dma,uint32_t id)260 static inline bool stm32_dma_is_te_irq_active(DMA_TypeDef *dma, uint32_t id)
261 {
262 	return LL_DMA_IsEnabledIT_TE(dma, dma_stm32_id_to_stream(id)) &&
263 	       dma_stm32_is_te_active(dma, id);
264 }
265 
stm32_dma_is_dme_irq_active(DMA_TypeDef * dma,uint32_t id)266 static inline bool stm32_dma_is_dme_irq_active(DMA_TypeDef *dma, uint32_t id)
267 {
268 	return LL_DMA_IsEnabledIT_DME(dma, dma_stm32_id_to_stream(id)) &&
269 	       dma_stm32_is_dme_active(dma, id);
270 }
271 
stm32_dma_is_fe_irq_active(DMA_TypeDef * dma,uint32_t id)272 static inline bool stm32_dma_is_fe_irq_active(DMA_TypeDef *dma, uint32_t id)
273 {
274 	return LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
275 	       dma_stm32_is_fe_active(dma, id);
276 }
277 
stm32_dma_is_irq_active(DMA_TypeDef * dma,uint32_t id)278 bool stm32_dma_is_irq_active(DMA_TypeDef *dma, uint32_t id)
279 {
280 	return stm32_dma_is_tc_irq_active(dma, id) ||
281 	       stm32_dma_is_ht_irq_active(dma, id) ||
282 	       stm32_dma_is_te_irq_active(dma, id) ||
283 	       stm32_dma_is_dme_irq_active(dma, id) ||
284 	       stm32_dma_is_fe_irq_active(dma, id);
285 }
286 
stm32_dma_clear_stream_irq(DMA_TypeDef * dma,uint32_t id)287 void stm32_dma_clear_stream_irq(DMA_TypeDef *dma, uint32_t id)
288 {
289 	dma_stm32_clear_te(dma, id);
290 	dma_stm32_clear_dme(dma, id);
291 	dma_stm32_clear_fe(dma, id);
292 }
293 
stm32_dma_is_irq_happened(DMA_TypeDef * dma,uint32_t id)294 bool stm32_dma_is_irq_happened(DMA_TypeDef *dma, uint32_t id)
295 {
296 	if (LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
297 	    dma_stm32_is_fe_active(dma, id)) {
298 		return true;
299 	}
300 
301 	return false;
302 }
303 
stm32_dma_is_unexpected_irq_happened(DMA_TypeDef * dma,uint32_t id)304 bool stm32_dma_is_unexpected_irq_happened(DMA_TypeDef *dma, uint32_t id)
305 {
306 	if (LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
307 	    dma_stm32_is_fe_active(dma, id)) {
308 		LOG_ERR("FiFo error.");
309 		stm32_dma_dump_stream_irq(dma, id);
310 		stm32_dma_clear_stream_irq(dma, id);
311 
312 		return true;
313 	}
314 
315 	return false;
316 }
317 
stm32_dma_enable_stream(DMA_TypeDef * dma,uint32_t id)318 void stm32_dma_enable_stream(DMA_TypeDef *dma, uint32_t id)
319 {
320 	LL_DMA_EnableStream(dma, dma_stm32_id_to_stream(id));
321 }
322 
stm32_dma_disable_stream(DMA_TypeDef * dma,uint32_t id)323 int stm32_dma_disable_stream(DMA_TypeDef *dma, uint32_t id)
324 {
325 	LL_DMA_DisableStream(dma, dma_stm32_id_to_stream(id));
326 
327 	if (!LL_DMA_IsEnabledStream(dma, dma_stm32_id_to_stream(id))) {
328 		return 0;
329 	}
330 
331 	return -EAGAIN;
332 }
333 
stm32_dma_disable_fifo_irq(DMA_TypeDef * dma,uint32_t id)334 void stm32_dma_disable_fifo_irq(DMA_TypeDef *dma, uint32_t id)
335 {
336 	LL_DMA_DisableIT_FE(dma, dma_stm32_id_to_stream(id));
337 }
338 
339 #if !defined(CONFIG_DMAMUX_STM32)
stm32_dma_config_channel_function(DMA_TypeDef * dma,uint32_t id,uint32_t slot)340 void stm32_dma_config_channel_function(DMA_TypeDef *dma, uint32_t id,
341 					uint32_t slot)
342 {
343 	LL_DMA_SetChannelSelection(dma, dma_stm32_id_to_stream(id),
344 			dma_stm32_slot_to_channel(slot));
345 }
346 #endif
347 
stm32_dma_get_mburst(struct dma_config * config,bool source_periph)348 uint32_t stm32_dma_get_mburst(struct dma_config *config, bool source_periph)
349 {
350 	uint32_t memory_burst;
351 
352 	if (source_periph) {
353 		memory_burst = config->dest_burst_length;
354 	} else {
355 		memory_burst = config->source_burst_length;
356 	}
357 
358 	switch (memory_burst) {
359 	case 1:
360 		return LL_DMA_MBURST_SINGLE;
361 	case 4:
362 		return LL_DMA_MBURST_INC4;
363 	case 8:
364 		return LL_DMA_MBURST_INC8;
365 	case 16:
366 		return LL_DMA_MBURST_INC16;
367 	default:
368 		LOG_ERR("Memory burst size error,"
369 			"using single burst as default");
370 		return LL_DMA_MBURST_SINGLE;
371 	}
372 }
373 
stm32_dma_get_pburst(struct dma_config * config,bool source_periph)374 uint32_t stm32_dma_get_pburst(struct dma_config *config, bool source_periph)
375 {
376 	uint32_t periph_burst;
377 
378 	if (source_periph) {
379 		periph_burst = config->source_burst_length;
380 	} else {
381 		periph_burst = config->dest_burst_length;
382 	}
383 
384 	switch (periph_burst) {
385 	case 1:
386 		return LL_DMA_PBURST_SINGLE;
387 	case 4:
388 		return LL_DMA_PBURST_INC4;
389 	case 8:
390 		return LL_DMA_PBURST_INC8;
391 	case 16:
392 		return LL_DMA_PBURST_INC16;
393 	default:
394 		LOG_ERR("Peripheral burst size error,"
395 			"using single burst as default");
396 		return LL_DMA_PBURST_SINGLE;
397 	}
398 }
399 
400 /*
401  * This function checks if the msize, mburst and fifo level is
402  * compitable. If they are not compitable, refer to the 'FIFO'
403  * section in the 'DMA' chapter in the Reference Manual for more
404  * information.
405  * break is emitted since every path of the code has 'return'.
406  * This function does not have the obligation of checking the parameters.
407  */
stm32_dma_check_fifo_mburst(LL_DMA_InitTypeDef * DMAx)408 bool stm32_dma_check_fifo_mburst(LL_DMA_InitTypeDef *DMAx)
409 {
410 	uint32_t msize = DMAx->MemoryOrM2MDstDataSize;
411 	uint32_t fifo_level = DMAx->FIFOThreshold;
412 	uint32_t mburst = DMAx->MemBurst;
413 
414 	switch (msize) {
415 	case LL_DMA_MDATAALIGN_BYTE:
416 		switch (mburst) {
417 		case LL_DMA_MBURST_INC4:
418 			return true;
419 		case LL_DMA_MBURST_INC8:
420 			if (fifo_level == LL_DMA_FIFOTHRESHOLD_1_2 ||
421 			    fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
422 				return true;
423 			} else {
424 				return false;
425 			}
426 		case LL_DMA_MBURST_INC16:
427 			if (fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
428 				return true;
429 			} else {
430 				return false;
431 			}
432 		}
433 	case LL_DMA_MDATAALIGN_HALFWORD:
434 		switch (mburst) {
435 		case LL_DMA_MBURST_INC4:
436 			if (fifo_level == LL_DMA_FIFOTHRESHOLD_1_2 ||
437 			    fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
438 				return true;
439 			} else {
440 				return false;
441 			}
442 		case LL_DMA_MBURST_INC8:
443 			if (fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
444 				return true;
445 			} else {
446 				return false;
447 			}
448 		case LL_DMA_MBURST_INC16:
449 			return false;
450 		}
451 	case LL_DMA_MDATAALIGN_WORD:
452 		if (mburst == LL_DMA_MBURST_INC4 &&
453 		    fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
454 			return true;
455 		} else {
456 			return false;
457 		}
458 	default:
459 		return false;
460 	}
461 }
462 
stm32_dma_get_fifo_threshold(uint16_t fifo_mode_control)463 uint32_t stm32_dma_get_fifo_threshold(uint16_t fifo_mode_control)
464 {
465 	switch (fifo_mode_control) {
466 	case 0:
467 		return LL_DMA_FIFOTHRESHOLD_1_4;
468 	case 1:
469 		return LL_DMA_FIFOTHRESHOLD_1_2;
470 	case 2:
471 		return LL_DMA_FIFOTHRESHOLD_3_4;
472 	case 3:
473 		return LL_DMA_FIFOTHRESHOLD_FULL;
474 	default:
475 		LOG_WRN("FIFO threshold parameter error, reset to 1/4");
476 		return LL_DMA_FIFOTHRESHOLD_1_4;
477 	}
478 }
479