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