1 /*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef __DMA350_LIB_H__
9 #define __DMA350_LIB_H__
10
11 #include "dma350_ch_drv.h"
12
13 #include <stdint.h>
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /* DMA350 DMA Channel execution enumeration types */
20 enum dma350_lib_exec_type_t {
21 DMA350_LIB_EXEC_BLOCKING = 0, /*!< Start command, return only when operation
22 * is completed (or failed) */
23 DMA350_LIB_EXEC_START_ONLY, /*!< Start command, return immediately */
24 DMA350_LIB_EXEC_IRQ, /*!< Enable channel interrupt, Start command,
25 * then return immediately */
26 };
27
28 /* DMA350 DMA Library enumeration types */
29 enum dma350_lib_error_t {
30 DMA350_LIB_ERR_NONE = 0, /*!< No error */
31 DMA350_LIB_ERR_CMD_ERR, /*!< Error while executing command */
32 DMA350_LIB_ERR_CH_NOT_INIT, /*!< Error Channel not initialized */
33 DMA350_LIB_ERR_CH_NOT_READY, /*!< Error Channel not ready */
34 DMA350_LIB_ERR_RANGE_NOT_ACCESSIBLE, /*!< Error Range cannot be accessed from this security level */
35 DMA350_LIB_ERR_INVALID_CONFIG_TYPE, /*!< Error Config type is invalid */
36 DMA350_LIB_ERR_CHANNEL_INVALID, /*!< Error Channel number is invalid */
37 DMA350_LIB_ERR_DEVICE_INVALID, /*!< Error Device pointer is invalid */
38 DMA350_LIB_ERR_INVALID_EXEC_TYPE, /*!< Error Execution type is invalid */
39 DMA350_LIB_ERR_CFG_ERR, /*!< Error Invalid config */
40 };
41
42 /* DMA350 DMA Library transformation enumeration type */
43 enum dma350_lib_transform_t {
44 DMA350_LIB_TRANSFORM_NONE = 0,
45 DMA350_LIB_TRANSFORM_ROTATE_90, /*!< Rotate 90 degrees clockwise */
46 DMA350_LIB_TRANSFORM_ROTATE_180, /*!< Rotate 180 degrees clockwise */
47 DMA350_LIB_TRANSFORM_ROTATE_270, /*!< Rotate 270 degrees clockwise */
48 DMA350_LIB_TRANSFORM_MIRROR_VER, /*!< Mirror along X axis. Top to bottom */
49 DMA350_LIB_TRANSFORM_MIRROR_HOR, /*!< Mirror along Y axis. Left to right */
50 DMA350_LIB_TRANSFORM_MIRROR_TLBR, /*!< Mirror along diagonal. TopLeft to BottomRight */
51 DMA350_LIB_TRANSFORM_MIRROR_TRBL, /*!< Mirror along diagonal. TopRight to BottomLeft */
52 };
53
54 /* DMA350 DMA Address remap structure */
55 struct dma350_remap_range_t {
56 uint32_t begin;
57 uint32_t end;
58 uint32_t offset;
59 };
60
61 /* DMA350 DMA Address remap list */
62 struct dma350_remap_list_t {
63 uint32_t size;
64 const struct dma350_remap_range_t* const map;
65 };
66
67 /* DMA350 lib needs an externally defined, device specific remap struct */
68 extern const struct dma350_remap_list_t dma350_address_remap;
69
70 /**
71 * \brief Set src address with memory attributes based on MPU
72 *
73 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
74 * \param[in] src Source address, where to copy from
75 *
76 * \return Result of the operation \ref dma350_lib_error_t
77 *
78 * \note This function should only be called from privileged level.
79 */
80 enum dma350_lib_error_t dma350_lib_set_src(struct dma350_ch_dev_t* dev,
81 const void* src);
82
83 /**
84 * \brief Set des address with memory attributes based on MPU
85 *
86 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
87 * \param[in] des Destination address, where to copy to
88 *
89 * \return Result of the operation \ref dma350_lib_error_t
90 *
91 * \note This function should only be called from privileged level.
92 */
93 enum dma350_lib_error_t dma350_lib_set_des(struct dma350_ch_dev_t* dev,
94 void* des);
95
96 /**
97 * \brief Set src, des and memory attributes based on MPU, with range check
98 *
99 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
100 * \param[in] src Source address, where to copy from
101 * \param[in] des Destination address, where to copy to
102 * \param[in] src_size Source size in bytes
103 * \param[in] des_size Destination size in bytes
104 *
105 * \return Result of the operation \ref dma350_lib_error_t
106 *
107 * \note This function should only be called from privileged level.
108 */
109 enum dma350_lib_error_t dma350_lib_set_src_des(struct dma350_ch_dev_t* dev,
110 const void* src, void* des,
111 uint32_t src_size,
112 uint32_t des_size);
113
114 /**
115 * \brief Copy a specified number of bytes from one memory to another
116 *
117 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
118 * \param[in] src Source address, where to copy from
119 * \param[in] des Destination address, where to copy to
120 * \param[in] size Number of bytes to copy
121 * \param[in] exec_type Execution type as in \ref dma350_lib_exec_type_t
122 *
123 * \return Result of the operation \ref dma350_lib_error_t
124 *
125 * \note This function should only be called from privileged level.
126 */
127 enum dma350_lib_error_t dma350_memcpy(struct dma350_ch_dev_t* dev,
128 const void* src, void* des, uint32_t size,
129 enum dma350_lib_exec_type_t exec_type);
130
131 /**
132 * \brief Copy a specified number of bytes from one memory to another
133 * or overlap on same memory.
134 *
135 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
136 * \param[in] src Source address, where to move from
137 * \param[in] des Destination address, where to move to
138 * \param[in] size Number of bytes to move
139 * \param[in] exec_type Execution type as in \ref dma350_lib_exec_type_t
140 *
141 * \return Result of the operation \ref dma350_lib_error_t
142 *
143 * \note This function should only be called from privileged level.
144 */
145 enum dma350_lib_error_t dma350_memmove(struct dma350_ch_dev_t* dev,
146 const void* src, void* des, uint32_t size,
147 enum dma350_lib_exec_type_t exec_type);
148
149 /**
150 * \brief Copy a specified number of elements from one memory to another, while
151 * reversing the byte order.
152 *
153 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
154 * \param[in] src Source address, where to copy from
155 * \param[in] des Destination address, where to copy to
156 * \param[in] size Number of bytes in element
157 * \param[in] count Number of elements to copy
158 *
159 * \return Result of the operation \ref dma350_lib_error_t
160 */
161 enum dma350_lib_error_t dma350_endian_swap(struct dma350_ch_dev_t* dev,
162 const void* src, void* des,
163 uint8_t size, uint32_t count);
164
165 /**
166 * \brief 2D Copy from canvas (area within a source bitmap) to within a
167 * destination bitmap, while applying various possible transformations.
168 * If the destination size is larger than the source, the source image
169 * will be wrapped (repeated).
170 *
171 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
172 * \param[in] src Source address, top left corner
173 * \param[in] des Destination address, top left corner
174 * \param[in] src_width Source width
175 * \param[in] src_height Source height
176 * \param[in] src_line_width Source line width
177 * \param[in] des_width Destination width
178 * \param[in] des_height Destination height
179 * \param[in] des_line_width Destination line width
180 * \param[in] pixelsize Size of a pixel as in \ref dma350_ch_transize_t
181 * \param[in] transform Transform type as in \ref dma350_lib_transform_t
182 * \param[in] exec_type Execution type as in \ref dma350_lib_exec_type_t
183 *
184 * \return Result of the operation \ref dma350_lib_error_t
185 *
186 * \note Destination width and height denote the area which will be filled at
187 * the destination address. The copy always starts from the top left
188 * corner of the source. If the requested destination size does not match
189 * the source, the resulting image will be repeated / cropped.
190 */
191 enum dma350_lib_error_t dma350_draw_from_canvas(struct dma350_ch_dev_t* dev,
192 const void* src, void* des,
193 uint32_t src_width, uint16_t src_height,
194 uint16_t src_line_width,
195 uint32_t des_width, uint16_t des_height,
196 uint16_t des_line_width,
197 enum dma350_ch_transize_t pixelsize,
198 enum dma350_lib_transform_t transform,
199 enum dma350_lib_exec_type_t exec_type);
200
201 /**
202 * \brief 2D Copy from a bitmap to within a destination bitmap, while applying
203 * various possible transformations.
204 *
205 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
206 * \param[in] src Source address, top left corner
207 * \param[in] des Destination address, top left corner
208 * \param[in] src_width Source width
209 * \param[in] src_height Source height
210 * \param[in] des_width Destination width
211 * \param[in] des_height Destination height
212 * \param[in] des_line_width Destination line width
213 * \param[in] pixelsize Size of a pixel as in \ref dma350_ch_transize_t
214 * \param[in] transform Transform type as in \ref dma350_lib_transform_t
215 * \param[in] exec_type Execution type as in \ref dma350_lib_exec_type_t
216 *
217 * \return Result of the operation \ref dma350_lib_error_t
218 *
219 * \note Destination width and height denote the area which will be filled at
220 * the destination address. The copy always starts from the top left
221 * corner of the source. If the requested destination size does not match
222 * the source, the resulting image will be repeated / cropped.
223 */
224 __STATIC_INLINE
225 enum dma350_lib_error_t dma350_draw_from_bitmap(struct dma350_ch_dev_t* dev,
226 const void* src, void* des,
227 uint32_t src_width, uint16_t src_height,
228 uint32_t des_width, uint16_t des_height,
229 uint16_t des_line_width,
230 enum dma350_ch_transize_t pixelsize,
231 enum dma350_lib_transform_t transform,
232 enum dma350_lib_exec_type_t exec_type);
233
234 /**
235 * \brief 2D Copy a source bitmap to a destination bitmap, while applying
236 * various possible transformations.
237 *
238 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
239 * \param[in] src Source address, top left corner
240 * \param[in] des Destination address, top left corner
241 * \param[in] width Width
242 * \param[in] height Height
243 * \param[in] pixelsize Size of a pixel as in \ref dma350_ch_transize_t
244 * \param[in] transform Transform type as in \ref dma350_lib_transform_t
245 * \param[in] exec_type Execution type as in \ref dma350_lib_exec_type_t
246 *
247 * \return Result of the operation \ref dma350_lib_error_t
248 *
249 * \note Destination width and height are calculated from source size and
250 * requested transform type.
251 */
252 __STATIC_INLINE
253 enum dma350_lib_error_t dma350_2d_copy(
254 struct dma350_ch_dev_t* dev,
255 const void* src, void* des,
256 uint32_t width, uint16_t height,
257 enum dma350_ch_transize_t pixelsize,
258 enum dma350_lib_transform_t transform,
259 enum dma350_lib_exec_type_t exec_type);
260
261 /**
262 * \brief Clear a status bit of the dma channel
263 *
264 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
265 *
266 * \return Result of the operation \ref dma350_lib_error_t
267 *
268 * \note This function should only be called from privileged level.
269 */
270 __STATIC_INLINE
271 enum dma350_lib_error_t dma350_clear_done_irq(struct dma350_ch_dev_t* dev);
272
273 /**
274 * \brief Check and init channel device if necessary
275 *
276 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
277 *
278 * \return Result of the operation \ref dma350_lib_error_t
279 *
280 * \note This function should only be called from privileged level.
281 */
282 __STATIC_INLINE
283 enum dma350_lib_error_t verify_dma350_ch_dev_init(struct dma350_ch_dev_t* dev);
284
285 /**
286 * \brief Check if channel device is ready, init if necessary
287 *
288 * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t
289 *
290 * \return Result of the operation \ref dma350_lib_error_t
291 *
292 * \note This function should only be called from privileged level.
293 */
294 __STATIC_INLINE
295 enum dma350_lib_error_t verify_dma350_ch_dev_ready(struct dma350_ch_dev_t* dev);
296
297 /**
298 * \brief Get the status of the dma channel
299 *
300 * \param[in] channel DMA350 channel number
301 * \param[out] status DMA350 channel status
302 *
303 * \return Result of the operation \ref dma350_lib_error_t
304 *
305 * \note This function should only be called from privileged level.
306 */
307 __STATIC_INLINE
308 enum dma350_lib_error_t dma350_get_status(struct dma350_ch_dev_t* dev,
309 union dma350_ch_status_t *status);
310
311 __STATIC_INLINE
dma350_clear_done_irq(struct dma350_ch_dev_t * dev)312 enum dma350_lib_error_t dma350_clear_done_irq(struct dma350_ch_dev_t* dev)
313 {
314 enum dma350_lib_error_t lib_err;
315 lib_err = verify_dma350_ch_dev_init(dev);
316 if(lib_err != DMA350_LIB_ERR_NONE) {
317 return lib_err;
318 }
319 dma350_ch_clear_stat(dev, DMA350_CH_STAT_DONE);
320
321 return DMA350_LIB_ERR_NONE;
322 }
323
324 __STATIC_INLINE
verify_dma350_ch_dev_init(struct dma350_ch_dev_t * dev)325 enum dma350_lib_error_t verify_dma350_ch_dev_init(struct dma350_ch_dev_t* dev)
326 {
327 enum dma350_ch_error_t ch_err;
328 if(!dev) {
329 return DMA350_LIB_ERR_DEVICE_INVALID;
330 }
331 if(!dma350_ch_is_init(dev)) {
332 ch_err = dma350_ch_init(dev);
333 if (ch_err != DMA350_CH_ERR_NONE) {
334 return DMA350_LIB_ERR_CHANNEL_INVALID;
335 }
336 }
337 return DMA350_LIB_ERR_NONE;
338 }
339
340 __STATIC_INLINE
verify_dma350_ch_dev_ready(struct dma350_ch_dev_t * dev)341 enum dma350_lib_error_t verify_dma350_ch_dev_ready(struct dma350_ch_dev_t* dev)
342 {
343 enum dma350_lib_error_t lib_err;
344 lib_err = verify_dma350_ch_dev_init(dev);
345 if(lib_err != DMA350_LIB_ERR_NONE) {
346 return lib_err;
347 }
348 if(!dma350_ch_is_ready(dev)) {
349 return DMA350_LIB_ERR_CH_NOT_READY;
350 }
351
352 return DMA350_LIB_ERR_NONE;
353 }
354
355 __STATIC_INLINE
dma350_get_status(struct dma350_ch_dev_t * dev,union dma350_ch_status_t * status)356 enum dma350_lib_error_t dma350_get_status(struct dma350_ch_dev_t* dev,
357 union dma350_ch_status_t *status)
358 {
359 enum dma350_lib_error_t lib_err;
360 lib_err = verify_dma350_ch_dev_init(dev);
361 if(lib_err != DMA350_LIB_ERR_NONE) {
362 return lib_err;
363 }
364 *status = dma350_ch_get_status(dev);
365 return DMA350_LIB_ERR_NONE;
366 }
367
368 __STATIC_INLINE
dma350_draw_from_bitmap(struct dma350_ch_dev_t * dev,const void * src,void * des,uint32_t src_width,uint16_t src_height,uint32_t des_width,uint16_t des_height,uint16_t des_line_width,enum dma350_ch_transize_t pixelsize,enum dma350_lib_transform_t transform,enum dma350_lib_exec_type_t exec_type)369 enum dma350_lib_error_t dma350_draw_from_bitmap(struct dma350_ch_dev_t* dev,
370 const void* src, void* des,
371 uint32_t src_width, uint16_t src_height,
372 uint32_t des_width, uint16_t des_height,
373 uint16_t des_line_width,
374 enum dma350_ch_transize_t pixelsize,
375 enum dma350_lib_transform_t transform,
376 enum dma350_lib_exec_type_t exec_type)
377 {
378 return dma350_draw_from_canvas(dev, src, des,
379 src_width, src_height, (uint16_t)src_width,
380 des_width, des_height, des_line_width,
381 pixelsize, transform, exec_type);
382 }
383
384 __STATIC_INLINE
dma350_2d_copy(struct dma350_ch_dev_t * dev,const void * src,void * des,uint32_t width,uint16_t height,enum dma350_ch_transize_t pixelsize,enum dma350_lib_transform_t transform,enum dma350_lib_exec_type_t exec_type)385 enum dma350_lib_error_t dma350_2d_copy(
386 struct dma350_ch_dev_t* dev,
387 const void* src, void* des,
388 uint32_t width, uint16_t height,
389 enum dma350_ch_transize_t pixelsize,
390 enum dma350_lib_transform_t transform,
391 enum dma350_lib_exec_type_t exec_type)
392 {
393 return dma350_draw_from_canvas(dev, src, des,
394 width, height, (uint16_t)width,
395 width, height, (uint16_t)width,
396 pixelsize, transform, exec_type);
397 }
398
399 #ifdef __cplusplus
400 }
401 #endif
402 #endif /* __DMA350_LIB_H__ */
403