• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef __cplusplus
154 extern "C" {
155 #endif
156 
157 /**
158  * @brief Get default configuration according to input pixel format
159  *
160  * @param [in] ptr PDMA base address
161  * @param [out] config pdma_config_t
162  * @param [in] pixel_format display_pixel_format_t
163  */
164 void pdma_get_default_config(PDMA_Type *ptr, pdma_config_t *config, display_pixel_format_t pixel_format);
165 
166 /**
167  * @brief Get default plane configuration according input pixel format
168  *
169  * @param [in] ptr PDMA base address
170  * @param [out] config pdma_plane_config_t
171  * @param [in] pixel_format display_pixel_format_t
172  */
173 void pdma_get_default_plane_config(PDMA_Type *ptr, pdma_plane_config_t *config, display_pixel_format_t pixel_format);
174 
175 /**
176  * @brief Get default YUV2RGB coefficient configuration according to input pixel format
177  *
178  * @note The two plane share one YUV2RGB_COEF, so not support convert one plane YUV422 format
179  * and another plane YCbCr422 format at same time
180  *
181  * @param [in] ptr PDMA base address
182  * @param [out] yuv2rgb_coef display_yuv2rgb_coef_t
183  * @param [in] source_format the YUV2RGB input source pixel format
184  */
185 void pdma_get_default_yuv2rgb_coef_config(PDMA_Type *ptr, display_yuv2rgb_coef_t *yuv2rgb_coef, display_pixel_format_t source_format);
186 
187 /**
188  * @brief Get default output configuration
189  *
190  * @param [in] ptr PDMA base address
191  * @param [out] config pdma_output_config_t
192  * @param [in] pixel_format output data pixel format
193  */
194 void pdma_get_default_output_config(PDMA_Type *ptr,
195                                     pdma_output_config_t *config, display_pixel_format_t pixel_format);
196 
197 /**
198  * @brief PDMA enable/disable irq
199  *
200  * @param [in] ptr PDMA base address
201  * @param [in] mask irq mask
202  * @param [in] enable :
203  *  @arg true: enable
204  *  @arg false: disable
205  */
206 void pdma_enable_irq(PDMA_Type *ptr, uint32_t mask, bool enable);
207 
208 /**
209  * @brief PDMA config output
210  *
211  * @param [in] ptr PDMA base address
212  * @param [in] config pdma_output_config_t
213  */
214 void pdma_config_output(PDMA_Type *ptr, pdma_output_config_t *config);
215 
216 /**
217  * @brief Configure PDMA planes
218  *
219  * Note: The plane_src and plane_dst share one YUV2RGB_COEF, so not support convert one plane YUV422 format
220  * and another plane YCbCr422 format at same time
221  *
222  * @param [in] ptr PDMA base address
223  * @param [in] plane_src_config Pointer to plane_src configuration structure
224  * @param [in] plane_dst_config Pointer to plan_dst configuration structure
225  * @param [in] yuv2rgb_coef Pointer to yuv2rgb_coef configuration structure
226  */
227 void pdma_config_planes(PDMA_Type *ptr, void *plane_src_config, void *plane_dst_config, void *yuv2rgb_coef);
228 
229 /**
230  * @brief PDMA initialization
231  *
232  * @param [in] ptr PDMA base address
233  * @param [in] config pdma_output_config_t
234  */
235 void pdma_init(PDMA_Type *ptr, pdma_config_t *config);
236 
237 /**
238  * @brief PDMA check status
239  *
240  * @param [in] ptr PDMA base address
241  * @param [out] status pdma status
242  */
243 hpm_stat_t pdma_check_status(PDMA_Type *ptr, uint32_t *status);
244 
245 /**
246  * @brief PDMA fill color
247  *
248  * @param [in] ptr PDMA base address
249  * @param [in] dst target buff address
250  * @param [in] dst_width target buff pixel width
251  * @param [in] width output image width
252  * @param [in] height output image height
253  * @param [in] color color value
254  * @param [in] alpha alpha value
255  * @param [in] format display_pixel_format_t
256  * @param [in] wait wait for execution to complete
257  * @param [out] status pdma status
258  * @retval hpm_stat_t: status_success if flip and rotate plane without any error
259  */
260 hpm_stat_t pdma_fill_color(PDMA_Type *ptr, uint32_t dst, uint32_t dst_width,
261                            uint32_t width, uint32_t height,
262                            uint32_t color, uint8_t alpha,
263                            display_pixel_format_t format,
264                            bool wait, uint32_t *status);
265 
266 /**
267  * @brief PDMA flip rotate plane
268  *
269  * @param [in] ptr PDMA base address
270  * @param [in] dst target buff address
271  * @param [in] dst_width target buff pixel width
272  * @param [in] src source buff address
273  * @param [in] src_width source buff pixel width
274  * @param [in] x x coordinate n buffer
275  * @param [in] y y coordinate n buffer
276  * @param [in] width output image width
277  * @param [in] height output image height
278  * @param [in] flip pdma_flip_t
279  * @param [in] rotate pdma_rotate_t
280  * @param [in] alpha alpha value
281  * @param [in] format display_pixel_format_t
282  * @param [in] wait wait for execution to complete
283  * @param [out] status pdma status
284  * @retval hpm_stat_t: status_success if flip and rotate plane without any error
285  */
286 hpm_stat_t pdma_flip_rotate(PDMA_Type *ptr, uint32_t dst, uint32_t dst_width,
287                     uint32_t src, uint32_t src_width, uint32_t x, uint32_t y,
288                     uint32_t width, uint32_t height,
289                     pdma_flip_t flip, pdma_rotate_t rotate, uint8_t alpha,
290                     display_pixel_format_t format,
291                     bool wait, uint32_t *status);
292 
293 /**
294  * @brief PDMA blit plane
295  *
296  * @param [in] ptr PDMA base address
297  * @param [in] dst target buff address
298  * @param [in] dst_width target buff pixel width
299  * @param [in] src source buff address
300  * @param [in] src_width source buff pixel width
301  * @param [in] x x coordinate n buffer
302  * @param [in] y y coordinate n buffer
303  * @param [in] width output image width
304  * @param [in] height output image height
305  * @param [in] alpha alpha value
306  * @param [in] format display_pixel_format_t
307  * @param [in] wait wait for execution to complete
308  * @param [out] status pdma status
309  * @retval hpm_stat_t: status_success if flip and rotate plane without any error
310  */
311 hpm_stat_t pdma_blit(PDMA_Type *ptr,
312                      uint32_t dst, uint32_t dst_width,
313                      uint32_t src, uint32_t src_width,
314                      uint32_t x, uint32_t y, uint32_t width, uint32_t height,
315                      uint8_t alpha,
316                      display_pixel_format_t format,
317                      bool wait, uint32_t *status);
318 
319 /**
320  * @brief PDMA scale plane
321  *
322  * @param [in] ptr PDMA base address
323  * @param [in] dst target buff address
324  * @param [in] dst_width target buff pixel width
325  * @param [in] src source buff address
326  * @param [in] src_width source buff pixel width
327  * @param [in] x x coordinate n buffer
328  * @param [in] y y coordinate n buffer
329  * @param [in] width input image width
330  * @param [in] height input image height
331  * @param [in] target_width output image width
332  * @param [in] target_height output image height
333  * @param [in] alpha alpha value
334  * @param [in] format display_pixel_format_t
335  * @param [in] wait wait for execution to complete
336  * @param [out] status pdma status
337  * @retval hpm_stat_t: status_success if flip and rotate plane without any error
338  */
339 hpm_stat_t pdma_scale(PDMA_Type *ptr,
340                      uint32_t dst, uint32_t dst_width,
341                      uint32_t src, uint32_t src_width,
342                      uint32_t x, uint32_t y, uint32_t width, uint32_t height,
343                      uint32_t target_width, uint32_t target_height,
344                      uint8_t alpha,
345                      display_pixel_format_t format,
346                      bool wait, uint32_t *status);
347 
348 /**
349  * @brief PDMA set block size
350  *
351  * @param [in] ptr PDMA base address
352  * @param [in] size pdma_blocksize_t
353  */
354 void pdma_set_block_size(PDMA_Type *ptr, pdma_blocksize_t size);
355 
356 /**
357  * @brief PDMA stop
358  *
359  * @param [in] ptr PDMA base address
360  */
361 void pdma_stop(PDMA_Type *ptr);
362 
363 /**
364  * @brief PDMA stop
365  *
366  * @param [in] ptr PDMA base address
367  *
368  * @retval STAT register value
369  */
pdma_get_status(PDMA_Type * ptr)370 static inline uint32_t pdma_get_status(PDMA_Type *ptr)
371 {
372     return ptr->STAT;
373 }
374 
375 /**
376  * @brief PDMA start
377  *
378  * @param [in] ptr PDMA base address
379  */
pdma_start(PDMA_Type * ptr)380 static inline void pdma_start(PDMA_Type *ptr)
381 {
382     ptr->CTRL |= PDMA_CTRL_PDMA_EN_MASK;
383     __asm volatile ("" : : "r" (ptr->CTRL));
384 }
385 
386 /**
387  * @brief PDMA software reset
388  *
389  * @param [in] ptr PDMA base address
390  */
pdma_software_reset(PDMA_Type * ptr)391 static inline void pdma_software_reset(PDMA_Type *ptr)
392 {
393     ptr->CTRL |= PDMA_CTRL_PDMA_SFTRST_MASK;
394     ptr->CTRL &= ~(PDMA_CTRL_PDMA_SFTRST_MASK);
395     __asm volatile ("" : : "r" (ptr->CTRL));
396 }
397 
398 /**
399  * @brief PDMA set plane color key limits
400  *
401  * @param [in] ptr PDMA base address
402  * @param [in] plane_index plane index
403  * @param [in] key_high color key high limits
404  * @param [in] key_low color key low limits
405  */
pdma_set_plane_colorkey(PDMA_Type * ptr,uint8_t plane_index,uint32_t key_high,uint32_t key_low)406 static inline void pdma_set_plane_colorkey(PDMA_Type *ptr,
407                                            uint8_t plane_index,
408                                            uint32_t key_high,
409                                            uint32_t key_low)
410 {
411     ptr->PS[plane_index].CLRKEY_LOW = PDMA_PS_CLRKEY_LOW_LIMIT_SET(key_low);
412     ptr->PS[plane_index].CLRKEY_HIGH = PDMA_PS_CLRKEY_HIGH_LIMIT_SET(key_high);
413 }
414 
415 /**
416  * @}
417  */
418 
419 #ifdef __cplusplus
420 }
421 #endif
422 #endif /* HPM_PDMA_DRV_H */
423