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