1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_PDMA_DRV_H
9 #define HPM_PDMA_DRV_H
10 #include "hpm_soc_feature.h"
11 #include "hpm_display_common.h"
12 #include "hpm_pdma_regs.h"
13
14 /**
15 * @brief PDMA driver APIs
16 * @defgroup pdma_interface PDMA driver APIs
17 * @ingroup io_interfaces
18 * @{
19 */
20
21 /**
22 * @brief PDMA status
23 */
24 enum {
25 status_pdma_done = status_success,
26 status_pdma_error = MAKE_STATUS(status_group_pdma, 1),
27 status_pdma_busy = MAKE_STATUS(status_group_pdma, 2),
28 status_pdma_idle = MAKE_STATUS(status_group_pdma, 3),
29 };
30
31 /**
32 * @brief PDMA plane
33 */
34 typedef enum pdma_plane {
35 pdma_plane_src = 0,
36 pdma_plane_dst = 1,
37 pdma_plane_both,
38 pdma_plane_none,
39 } pdma_plane_t;
40
41 /**
42 * @brief PDMA flip
43 */
44 typedef enum pdma_flip {
45 pdma_flip_none = 0,
46 pdma_flip_horizontal = 1 << 0,
47 pdma_flip_vertical = 1 << 1,
48 pdma_flip_both = pdma_flip_horizontal | pdma_flip_vertical,
49 } pdma_flip_t;
50
51 /**
52 * @brief PDMA rotate
53 */
54 typedef enum pdma_rotate {
55 pdma_rotate_0_degree = 0,
56 pdma_rotate_90_degree = 1,
57 pdma_rotate_180_degree = 2,
58 pdma_rotate_270_degree = 3,
59 } pdma_rotate_t;
60
61 /**
62 * @brief PDMA decimation
63 */
64 typedef enum pdma_decimation {
65 pdma_decimation_by_1 = 0,
66 pdma_decimation_by_2 = 1,
67 pdma_decimation_by_4 = 2,
68 pdma_decimation_by_8 = 3,
69 } pdma_decimation_t;
70
71 /**
72 * @brief PDMA block size
73 */
74 typedef enum pdma_blocksize {
75 pdma_blocksize_16x16,
76 pdma_blocksize_8x8,
77 } pdma_blocksize_t;
78
79 /**
80 * @brief PDMA make scale value
81 */
82 #define PDMA_MAKE_SCALE_SET(integer, fractional) \
83 (((integer) & 0x3) << 12 | ((fractional) & 0xFFF))
84
85 /**
86 * @brief PDMA plane config
87 */
88 typedef struct pdma_plane_config {
89 bool swap_byte3_byte1; /**< set true to swap byte [31:24] and byte [15:8] */
90 bool use_background_as_clear; /**< set true to use background color at blending clear mode */
91 bool ycbcr_mode; /**< set true if it is YCbCr mode */
92 bool bypass_colorspace_conversion; /**< set true to bypass color space conversion */
93 bool byte_swap; /**< set true to swap [31:16] and [15:0] */
94 display_byteorder_t byteorder; /**< packing byte order type */
95 pdma_flip_t flip; /**< flip type */
96 pdma_rotate_t rotate; /**< rotate type */
97 pdma_decimation_t x_dec; /**< horizontal decimation */
98 pdma_decimation_t y_dec; /**< vertical decimation */
99 display_pixel_format_t pixel_format; /**< pixel format */
100 uint32_t buffer; /**< buffer address */
101 uint32_t background; /**< background color */
102 uint32_t colorkey_high; /**< colorkey high limit */
103 uint32_t colorkey_low; /**< colorkey low limit */
104 uint16_t x_scale; /**< 14-bit horizontal scale */
105 uint16_t y_scale; /**< 14-bit vertical scale */
106 uint16_t pitch; /**< pitch value */
107 uint16_t x_offset; /**< horizontal offset */
108 uint16_t y_offset; /**< vertical offset */
109 uint16_t width; /**< width */
110 uint16_t height; /**< height */
111 } pdma_plane_config_t;
112
113 /**
114 * @brief PDMA output config
115 */
116 typedef struct pdma_output_config {
117 display_alphablend_option_t alphablend; /**< alpha blending mode */
118 display_pixel_format_t pixel_format; /**< pixel format */
119 display_rgb2yuv_config_t rgb2yuv_config; /**< RGB to YUV config */
120 uint32_t buffer; /**< buffer */
121 struct {
122 uint16_t x; /**< plane origin X coord */
123 uint16_t y; /**< plane origin Y coord */
124 uint16_t width; /**< plane width */
125 uint16_t height; /**< plane height */
126 } plane[PDMA_SOC_PS_MAX_COUNT]; /**< plane config */
127 uint16_t width; /**< output plane width */
128 uint16_t height; /**< output plane height */
129 uint16_t pitch;
130 } pdma_output_config_t;
131
132 /**
133 * @brief PDMA config
134 */
135 typedef struct pdma_config {
136 display_byteorder_t byteorder; /**< byte order */
137 pdma_blocksize_t block_size; /**< block size */
138 pdma_plane_t enable_plane; /**< plane to be enabled */
139 } pdma_config_t;
140
141 /**
142 * @brief PDMA plane info
143 */
144 typedef struct pdma_plane_info {
145 uint32_t buffer; /**< buffer */
146 uint32_t x; /**< plane origin X coord */
147 uint32_t y; /**< plane origin Y coord */
148 uint32_t width; /**< plane width */
149 uint32_t height; /**< plane height */
150 display_pixel_format_t format; /**< pixel format */
151 } pdma_plane_info_t;
152
153
154 typedef struct pdma_blit_option {
155 display_alphablend_mode_t blend;
156 struct {
157 uint16_t x;
158 uint16_t y;
159 } translate;
160 pdma_flip_t flip;
161 pdma_rotate_t rotate;
162 struct {
163 float x; /* 0.0625 - 4095 */
164 float y; /* 0.0625 - 4095 */
165 } scale;
166 } pdma_blit_option_t;
167
168 #ifdef __cplusplus
169 extern "C" {
170 #endif
171
172 /**
173 * @brief Get default configuration according to input pixel format
174 *
175 * @param [in] ptr PDMA base address
176 * @param [out] config pdma_config_t
177 * @param [in] pixel_format display_pixel_format_t
178 */
179 void pdma_get_default_config(PDMA_Type *ptr, pdma_config_t *config, display_pixel_format_t pixel_format);
180
181 /**
182 * @brief Get default plane configuration according input pixel format
183 *
184 * @param [in] ptr PDMA base address
185 * @param [out] config pdma_plane_config_t
186 * @param [in] pixel_format display_pixel_format_t
187 */
188 void pdma_get_default_plane_config(PDMA_Type *ptr, pdma_plane_config_t *config, display_pixel_format_t pixel_format);
189
190 /**
191 * @brief Get default YUV2RGB coefficient configuration according to input pixel format
192 *
193 * @note The two plane share one YUV2RGB_COEF, so not support convert one plane YUV422 format
194 * and another plane YCbCr422 format at same time
195 *
196 * @param [in] ptr PDMA base address
197 * @param [out] yuv2rgb_coef display_yuv2rgb_coef_t
198 * @param [in] source_format the YUV2RGB input source pixel format
199 */
200 void pdma_get_default_yuv2rgb_coef_config(PDMA_Type *ptr, display_yuv2rgb_coef_t *yuv2rgb_coef, display_pixel_format_t source_format);
201
202 /**
203 * @brief Get default output configuration
204 *
205 * @param [in] ptr PDMA base address
206 * @param [out] config pdma_output_config_t
207 * @param [in] pixel_format output data pixel format
208 */
209 void pdma_get_default_output_config(PDMA_Type *ptr,
210 pdma_output_config_t *config, display_pixel_format_t pixel_format);
211
212 /**
213 * @brief PDMA enable/disable irq
214 *
215 * @param [in] ptr PDMA base address
216 * @param [in] mask irq mask
217 * @param [in] enable :
218 * @arg true: enable
219 * @arg false: disable
220 */
221 void pdma_enable_irq(PDMA_Type *ptr, uint32_t mask, bool enable);
222
223 /**
224 * @brief PDMA config output
225 *
226 * @param [in] ptr PDMA base address
227 * @param [in] config pdma_output_config_t
228 */
229 void pdma_config_output(PDMA_Type *ptr, pdma_output_config_t *config);
230
231 /**
232 * @brief Configure PDMA planes
233 *
234 * Note: The plane_src and plane_dst share one YUV2RGB_COEF, so not support convert one plane YUV422 format
235 * and another plane YCbCr422 format at same time
236 *
237 * @param [in] ptr PDMA base address
238 * @param [in] plane_src_config Pointer to plane_src configuration structure
239 * @param [in] plane_dst_config Pointer to plan_dst configuration structure
240 * @param [in] yuv2rgb_coef Pointer to yuv2rgb_coef configuration structure
241 */
242 void pdma_config_planes(PDMA_Type *ptr, void *plane_src_config, void *plane_dst_config, void *yuv2rgb_coef);
243
244 /**
245 * @brief PDMA initialization
246 *
247 * @param [in] ptr PDMA base address
248 * @param [in] config pdma_output_config_t
249 */
250 void pdma_init(PDMA_Type *ptr, pdma_config_t *config);
251
252 /**
253 * @brief PDMA check status
254 *
255 * @param [in] ptr PDMA base address
256 * @param [out] status pdma status
257 */
258 hpm_stat_t pdma_check_status(PDMA_Type *ptr, uint32_t *status);
259
260 /**
261 * @brief PDMA fill color
262 *
263 * @param [in] ptr PDMA base address
264 * @param [in] dst target buff address
265 * @param [in] dst_width target buff pixel width
266 * @param [in] width output image width
267 * @param [in] height output image height
268 * @param [in] color color value
269 * @param [in] alpha alpha value
270 * @param [in] format display_pixel_format_t
271 * @param [in] wait wait for execution to complete
272 * @param [out] status pdma status
273 * @retval hpm_stat_t: status_success if flip and rotate plane without any error
274 */
275 hpm_stat_t pdma_fill_color(PDMA_Type *ptr, uint32_t dst, uint32_t dst_width,
276 uint32_t width, uint32_t height,
277 uint32_t color, uint8_t alpha,
278 display_pixel_format_t format,
279 bool wait, uint32_t *status);
280
281 /**
282 * @brief PDMA flip rotate plane
283 *
284 * @param [in] ptr PDMA base address
285 * @param [in] dst target buff address
286 * @param [in] dst_width target buff pixel width
287 * @param [in] src source buff address
288 * @param [in] src_width source buff pixel width
289 * @param [in] x x coordinate n buffer
290 * @param [in] y y coordinate n buffer
291 * @param [in] width output image width
292 * @param [in] height output image height
293 * @param [in] flip pdma_flip_t
294 * @param [in] rotate pdma_rotate_t
295 * @param [in] alpha alpha value
296 * @param [in] format display_pixel_format_t
297 * @param [in] wait wait for execution to complete
298 * @param [out] status pdma status
299 * @retval hpm_stat_t: status_success if flip and rotate plane without any error
300 */
301 hpm_stat_t pdma_flip_rotate(PDMA_Type *ptr, uint32_t dst, uint32_t dst_width,
302 uint32_t src, uint32_t src_width, uint32_t x, uint32_t y,
303 uint32_t width, uint32_t height,
304 pdma_flip_t flip, pdma_rotate_t rotate, uint8_t alpha,
305 display_pixel_format_t format,
306 bool wait, uint32_t *status);
307
308 /**
309 * @brief PDMA blit plane
310 *
311 * @param [in] ptr PDMA base address
312 * @param [in] dst target buff address
313 * @param [in] dst_width target buff pixel width
314 * @param [in] src source buff address
315 * @param [in] src_width source buff pixel width
316 * @param [in] x x coordinate n buffer
317 * @param [in] y y coordinate n buffer
318 * @param [in] width output image width
319 * @param [in] height output image height
320 * @param [in] alpha alpha value
321 * @param [in] format display_pixel_format_t
322 * @param [in] wait wait for execution to complete
323 * @param [out] status pdma status
324 * @retval hpm_stat_t: status_success if flip and rotate plane without any error
325 */
326 hpm_stat_t pdma_blit(PDMA_Type *ptr,
327 uint32_t dst, uint32_t dst_width,
328 uint32_t src, uint32_t src_width,
329 uint32_t x, uint32_t y, uint32_t width, uint32_t height,
330 uint8_t alpha,
331 display_pixel_format_t format,
332 bool wait, uint32_t *status);
333
334 /**
335 * @brief PDMA scale plane
336 *
337 * @param [in] ptr PDMA base address
338 * @param [in] dst target buff address
339 * @param [in] dst_width target buff pixel width
340 * @param [in] src source buff address
341 * @param [in] src_width source buff pixel width
342 * @param [in] x x coordinate n buffer
343 * @param [in] y y coordinate n buffer
344 * @param [in] width input image width
345 * @param [in] height input image height
346 * @param [in] target_width output image width
347 * @param [in] target_height output image height
348 * @param [in] alpha alpha value
349 * @param [in] format display_pixel_format_t
350 * @param [in] wait wait for execution to complete
351 * @param [out] status pdma status
352 * @retval hpm_stat_t: status_success if flip and rotate plane without any error
353 */
354 hpm_stat_t pdma_scale(PDMA_Type *ptr,
355 uint32_t dst, uint32_t dst_width,
356 uint32_t src, uint32_t src_width,
357 uint32_t x, uint32_t y, uint32_t width, uint32_t height,
358 uint32_t target_width, uint32_t target_height,
359 uint8_t alpha,
360 display_pixel_format_t format,
361 bool wait, uint32_t *status);
362 /**
363 * @brief PDMA get default blit option
364 *
365 * @param op option of blit
366 */
367 void pdma_get_default_blit_option(pdma_blit_option_t *op);
368
369 /**
370 * @brief PDMA blit plane by option
371 *
372 * @param ptr PDMA base address
373 * @param dst target buff address
374 * @param src source buff address
375 * @param op option of blit
376 * @param wait wait for execution to complete
377 * @param status pdma status
378 * @retval hpm_stat_t: status_success if flip and rotate plane without any error
379 */
380 hpm_stat_t pdma_blit_ex(PDMA_Type *ptr,
381 display_buf_t *dst,
382 display_buf_t *src,
383 pdma_blit_option_t *op,
384 bool wait, uint32_t *status);
385
386 /**
387 * @brief PDMA set block size
388 *
389 * @param [in] ptr PDMA base address
390 * @param [in] size pdma_blocksize_t
391 */
392 void pdma_set_block_size(PDMA_Type *ptr, pdma_blocksize_t size);
393
394 /**
395 * @brief PDMA stop
396 *
397 * @param [in] ptr PDMA base address
398 */
399 void pdma_stop(PDMA_Type *ptr);
400
401 /**
402 * @brief PDMA stop
403 *
404 * @param [in] ptr PDMA base address
405 *
406 * @retval STAT register value
407 */
pdma_get_status(PDMA_Type * ptr)408 static inline uint32_t pdma_get_status(PDMA_Type *ptr)
409 {
410 return ptr->STAT;
411 }
412
413 /**
414 * @brief PDMA start
415 *
416 * @param [in] ptr PDMA base address
417 */
pdma_start(PDMA_Type * ptr)418 static inline void pdma_start(PDMA_Type *ptr)
419 {
420 ptr->CTRL |= PDMA_CTRL_PDMA_EN_MASK;
421 __asm volatile ("" : : "r" (ptr->CTRL));
422 }
423
424 /**
425 * @brief PDMA software reset
426 *
427 * @param [in] ptr PDMA base address
428 */
pdma_software_reset(PDMA_Type * ptr)429 static inline void pdma_software_reset(PDMA_Type *ptr)
430 {
431 ptr->CTRL |= PDMA_CTRL_PDMA_SFTRST_MASK;
432 ptr->CTRL &= ~(PDMA_CTRL_PDMA_SFTRST_MASK);
433 __asm volatile ("" : : "r" (ptr->CTRL));
434 }
435
436 /**
437 * @brief PDMA set plane color key limits
438 *
439 * @param [in] ptr PDMA base address
440 * @param [in] plane_index plane index
441 * @param [in] key_high color key high limits
442 * @param [in] key_low color key low limits
443 */
pdma_set_plane_colorkey(PDMA_Type * ptr,uint8_t plane_index,uint32_t key_high,uint32_t key_low)444 static inline void pdma_set_plane_colorkey(PDMA_Type *ptr,
445 uint8_t plane_index,
446 uint32_t key_high,
447 uint32_t key_low)
448 {
449 ptr->PS[plane_index].CLRKEY_LOW = PDMA_PS_CLRKEY_LOW_LIMIT_SET(key_low);
450 ptr->PS[plane_index].CLRKEY_HIGH = PDMA_PS_CLRKEY_HIGH_LIMIT_SET(key_high);
451 }
452
453 /**
454 * @}
455 */
456
457 #ifdef __cplusplus
458 }
459 #endif
460 #endif /* HPM_PDMA_DRV_H */
461