1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "hifb_graphic_drv.h"
20 #include "proc_ext.h"
21 #include "hi_debug.h"
22 #include "hifb_vou_graphics.h"
23 #include "mm_ext.h"
24 #include "mod_ext.h"
25 #include "sys_ext.h"
26 #include "securec.h"
27 #include "hifb_comm.h"
28
29 #define VOU_INTMSK_G0WBC 0x400
30 #define VOU_INTMSK_G4WBC 0x800
31
32 #define VOU1_IRQ_NR 91
33
34 #define GFX_CSC_SCALE 0xd
35 #define GFX_CSC_CLIP_MIN 0x0
36 #define GFX_CSC_CLIP_MAX 0x3ff
37
38 #define HIFB_DATEARR_RANGE 4
39
40 #define HIFB_CSC_COEF_ALG_DATA 100
41 #define HIFB_CSC_STATU_ALG_DATA 1000
42 #define HIFB_CSC_HUE_ALG_DATA 10000
43 #define HIFB_COEF_CSC_DEX 8
44 #define HIFB_COEF_CSC_DC_ALG_DATA 4
45 #define HIFB_COEF_CSC_GFX 1024
46
47 static hifb_coef_addr g_hifb_coef_buf_addr;
48
49 /* vou interrupt mask type */
50 typedef enum {
51 HIFB_INTMSK_NONE = 0,
52 HIFB_INTMSK_DHD0_VTTHD1 = 0x1,
53 HIFB_INTMSK_DHD0_VTTHD2 = 0x2,
54 HIFB_INTMSK_DHD0_VTTHD3 = 0x4,
55 HIFB_INTMSK_DHD0_UFINT = 0x8,
56
57 HIFB_INTMSK_DHD1_VTTHD1 = 0x10,
58 HIFB_INTMSK_DHD1_VTTHD2 = 0x20,
59 HIFB_INTMSK_DHD1_VTTHD3 = 0x40,
60 HIFB_INTMSK_DHD1_UFINT = 0x80,
61
62 HIFB_INTMSK_DSD_VTTHD1 = 0x100,
63 HIFB_INTMSK_DSD_VTTHD2 = 0x200,
64 HIFB_INTMSK_DSD_VTTHD3 = 0x400,
65 HIFB_INTMSK_DSD_UFINT = 0x800,
66
67 HIFB_INTMSK_B0_ERR = 0x1000,
68 HIFB_INTMSK_B1_ERR = 0x2000,
69 HIFB_INTMSK_B2_ERR = 0x4000,
70
71 HIFB_INTMSK_WBC_DHDOVER = 0x8000,
72 HIFB_INTREPORT_ALL = 0xffffffff
73 } hifb_int_mask;
74
75 /* RGB->YUV601 Constant coefficient matrix */
76 const csc_coef g_fb_csc_rgb2yuv601_tv = {
77 /* csc coef */
78 258,
79 504,
80 98,
81 -148,
82 -291,
83 439,
84 439,
85 -368,
86 -71,
87 /* csc Input DC(IDC) */
88 0,
89 0,
90 0,
91 /* csc Output DC(ODC) */
92 16,
93 128,
94 128,
95 /* new */
96 0,
97 0,
98 0,
99 };
100
101 /* RGB->YUV601 Constant coefficient matrix */
102 const csc_coef g_fb_csc_rgb2yuv601_pc = {
103 /* csc coef */
104 299, 587, 114, -172, -339, 511, 511, -428, -83,
105 /* csc Input DC(IDC) */
106 0, 0, 0,
107 /* csc Output DC(ODC) */
108 0, 128, 128, /* 64, 512, 512, */
109 0, 0, 0, /* new */
110 };
111
112 /* RGB->YUV709 Constant coefficient matrix */
113 const csc_coef g_fb_csc_rgb2yuv709_tv = {
114 /* csc coef */
115 184,
116 614,
117 62,
118 -101,
119 -338,
120 439,
121 439,
122 -399,
123 -40,
124 /* csc Input DC(IDC) */
125 0,
126 0,
127 0,
128 /* csc Output DC(ODC) */
129 16,
130 128,
131 128,
132 /* new */
133 0,
134 0,
135 0,
136 };
137
138 /* RGB->YUV709 Constant coefficient matrix, output full[0,255] */
139 const csc_coef g_fb_csc_rgb2yuv709_pc = {
140 /* csc coef */
141 213,
142 715,
143 72,
144 -117,
145 -394,
146 511,
147 511,
148 -464,
149 -47,
150 /* csc Input DC(IDC) */
151 0,
152 0,
153 0,
154 /* csc Output DC(ODC) */
155 0,
156 128,
157 128,
158 /* new */
159 0,
160 0,
161 0,
162 };
163
164 /* YUV601->RGB Constant coefficient matrix */
165 const csc_coef g_csc_yuv6012rgb_pc = {
166 /* csc coef */
167 1164,
168 0,
169 1596,
170 1164,
171 -391,
172 -813,
173 1164,
174 2018,
175 0,
176 /* csc Input DC(IDC) */
177 -16,
178 -128,
179 -128,
180 /* csc Output DC(ODC) */
181 0,
182 0,
183 0,
184 /* new */
185 0,
186 0,
187 0,
188 };
189
190 /* YUV709->RGB Constant coefficient matrix */
191 const csc_coef g_csc_yuv7092rgb_pc = {
192 /* csc coef */
193 1164,
194 0,
195 1793,
196 1164,
197 -213,
198 -534,
199 1164,
200 2115,
201 0,
202 /* csc Input DC(IDC) */
203 -16,
204 -128,
205 -128,
206 /* csc Output DC(ODC) */
207 0,
208 0,
209 0,
210 /* new */
211 0,
212 0,
213 0,
214 };
215
216 /* YUV601->YUV709 Constant coefficient matrix, output full[0,255] */
217 const csc_coef g_fb_csc_yuv2yuv_601_709 = {
218 /* csc coef */
219 1000,
220 -116,
221 208,
222 0,
223 1017,
224 114,
225 0,
226 75,
227 1025,
228 /* csc Input DC(IDC) */
229 -16,
230 -128,
231 -128,
232 /* csc Output DC(ODC) */
233 16,
234 128,
235 128,
236 /* new */
237 0,
238 0,
239 0,
240 };
241
242 /* YUV709->YUV601 Constant coefficient matrix,output full[0,255] */
243 const csc_coef g_fb_csc_yuv2yuv_709_601 = {
244 /* csc coef */
245 1000,
246 99,
247 192,
248 0,
249 990,
250 -111,
251 0,
252 -72,
253 983,
254 /* csc Input DC(IDC) */
255 -16,
256 -128,
257 -128,
258 /* csc Output DC(ODC) */
259 16,
260 128,
261 128,
262 /* new */
263 0,
264 0,
265 0,
266 };
267
268 /* YUV601->YUV709 Constant coefficient matrix */
269 const csc_coef g_fb_csc_init = {
270 /* csc coef */
271 1000,
272 0,
273 0,
274 0,
275 1000,
276 0,
277 0,
278 0,
279 1000,
280 /* csc Input DC(IDC) */
281 -16,
282 -128,
283 -128,
284 /* csc Output DC(ODC) */
285 16,
286 128,
287 128,
288 /* new */
289 0,
290 0,
291 0,
292 };
293
294 #define HIFB_SIN_TAB_RANGE 61
295 #define HIFB_COS_TAB_RANGE 61
296
297 const int g_hifb_sin_table[HIFB_SIN_TAB_RANGE] = {
298 -500, -485, -469, -454, -438, -422, -407, -391, -374,
299 -358, -342, -325, -309, -292, -276, -259, -242, -225, -208,
300 -191, -174, -156, -139, -122, -104, -87, -70, -52, -35, -17,
301 0, 17, 35, 52, 70, 87, 104, 122, 139, 156, 174, 191, 208, 225,
302 242, 259, 276, 292, 309, 325, 342, 358, 374, 391, 407, 422, 438,
303 454, 469, 485, 500
304 };
305
306 const int g_hifb_cos_table[HIFB_COS_TAB_RANGE] = {
307 866, 875, 883, 891, 899, 906, 914, 921, 927, 934, 940,
308 946, 951, 956, 961, 966, 970, 974, 978, 982, 985, 988, 990,
309 993, 995, 996, 998, 999, 999, 1000, 1000, 1000, 999, 999, 998,
310 996, 995, 993, 990, 988, 985, 982, 978, 974, 970, 966, 961,
311 956, 951, 946, 940, 934, 927, 921, 914, 906, 899, 891, 883, 875, 866
312 };
313
fb_graphic_drv_get_layer_index(hal_disp_layer disp_layer,hi_u32 * layer)314 hi_s32 fb_graphic_drv_get_layer_index(hal_disp_layer disp_layer, hi_u32 *layer)
315 {
316 switch (disp_layer) {
317 case HAL_DISP_LAYER_GFX0:
318 *layer = 0;
319 break;
320 case HAL_DISP_LAYER_GFX1:
321 *layer = 1;
322 break;
323 case HAL_DISP_LAYER_GFX3:
324 *layer = 2; /* 2 is 2 Layer */
325 break;
326 default:
327 return HI_ERR_VO_GFX_INVALID_ID;
328 }
329
330 return HI_SUCCESS;
331 }
332
fb_graphic_drv_get_layer_id(hi_u32 layer,hal_disp_layer * disp_layer)333 hi_s32 fb_graphic_drv_get_layer_id(hi_u32 layer, hal_disp_layer *disp_layer)
334 {
335 switch (layer) {
336 case VO_LAYER_G0:
337 *disp_layer = HAL_DISP_LAYER_GFX0;
338 break;
339 case VO_LAYER_G1:
340 *disp_layer = HAL_DISP_LAYER_GFX1;
341 break;
342 case VO_LAYER_G3:
343 *disp_layer = HAL_DISP_LAYER_GFX3;
344 break;
345 default:
346 return HI_FAILURE;
347 }
348
349 return HI_SUCCESS;
350 }
351
graphic_drv_set_gfx_key_mode(hal_disp_layer layer,hi_u32 key_out)352 hi_bool graphic_drv_set_gfx_key_mode(hal_disp_layer layer, hi_u32 key_out)
353 {
354 return hal_graphic_set_gfx_key_mode(layer, key_out);
355 }
356
graphic_drv_set_gfx_ext(hal_disp_layer layer,hal_gfx_bitextend mode)357 hi_bool graphic_drv_set_gfx_ext(hal_disp_layer layer, hal_gfx_bitextend mode)
358 {
359 return hal_graphic_set_gfx_ext(layer, mode);
360 }
361
graphic_drv_set_gfx_palpha(hal_disp_layer layer,hi_u32 alpha_en,hi_u32 arange,hi_u8 alpha0,hi_u8 alpha1)362 hi_bool graphic_drv_set_gfx_palpha(hal_disp_layer layer, hi_u32 alpha_en, hi_u32 arange, hi_u8 alpha0,
363 hi_u8 alpha1)
364 {
365 hi_unused(arange);
366 return hal_graphic_set_gfx_palpha(layer, alpha_en, HI_TRUE, alpha0, alpha1);
367 }
368
graphic_drv_layer_set_layer_galpha(hal_disp_layer layer,hi_u8 alpha0)369 hi_bool graphic_drv_layer_set_layer_galpha(hal_disp_layer layer, hi_u8 alpha0)
370 {
371 return hal_layer_set_layer_galpha(layer, alpha0);
372 }
373
graphic_drv_layer_set_csc_en(hal_disp_layer layer,hi_bool csc_en)374 hi_bool graphic_drv_layer_set_csc_en(hal_disp_layer layer, hi_bool csc_en)
375 {
376 if (fb_hal_layer_set_csc_en(layer, csc_en) == HI_FALSE) {
377 return HI_FALSE;
378 }
379
380 if (layer == HAL_DISP_LAYER_GFX0) {
381 return HI_TRUE;
382 }
383 return HI_TRUE;
384 }
385
graphic_drv_set_layer_addr(hal_disp_layer layer_id,hi_u64 addr)386 hi_bool graphic_drv_set_layer_addr(hal_disp_layer layer_id, hi_u64 addr)
387 {
388 hi_u32 layer_index;
389
390 if (fb_graphic_drv_get_layer_index(layer_id, &layer_index) != HI_SUCCESS) {
391 graphics_drv_trace(HI_DBG_ERR, "gfx_layer(%u) is invalid!\n", (hi_u32)layer_id);
392 return HI_FALSE;
393 }
394
395 if (hal_graphic_set_gfx_addr(layer_id, addr) == HI_FALSE) {
396 return HI_FALSE;
397 }
398 return HI_TRUE;
399 }
400
graphic_drv_set_gfx_stride(hal_disp_layer layer,hi_u16 pitch)401 hi_bool graphic_drv_set_gfx_stride(hal_disp_layer layer, hi_u16 pitch)
402 {
403 hi_u32 layer_index = 0;
404 hi_u16 depth;
405
406 if (fb_graphic_drv_get_layer_index(layer, &layer_index) != HI_SUCCESS) {
407 graphics_drv_trace(HI_DBG_ERR, "gfx_layer(%u) is invalid!\n", (hi_u32)layer);
408 return HI_FALSE;
409 }
410 /* Stride need be divided by 16(2^4) before setting the register */
411 depth = pitch >> 4;
412 if (hal_graphic_set_gfx_stride(layer, depth) == HI_FALSE) {
413 return HI_FALSE;
414 }
415
416 return HI_TRUE;
417 }
418
graphic_drv_get_gfx_pre_mult(hal_disp_layer layer,hi_u32 * enable)419 hi_bool graphic_drv_get_gfx_pre_mult(hal_disp_layer layer, hi_u32 *enable)
420 {
421 return hal_graphic_get_gfx_premult(layer, enable);
422 }
423
graphic_drv_set_gfx_pre_mult(hal_disp_layer layer,hi_u32 enable)424 hi_bool graphic_drv_set_gfx_pre_mult(hal_disp_layer layer, hi_u32 enable)
425 {
426 return hal_graphic_set_gfx_pre_mult(layer, enable);
427 }
428
graphic_drv_set_layer_data_fmt(hal_disp_layer layer,hal_disp_pixel_format data_fmt)429 hi_bool graphic_drv_set_layer_data_fmt(hal_disp_layer layer, hal_disp_pixel_format data_fmt)
430 {
431 hi_u32 layer_index = 0;
432 if (fb_graphic_drv_get_layer_index(layer, &layer_index) != HI_SUCCESS) {
433 graphics_drv_trace(HI_DBG_ERR, "gfx_layer(%u) is invalid!\n", (hi_u32)layer);
434 return HI_FALSE;
435 }
436
437 if (fb_hal_layer_set_layer_data_fmt(layer, data_fmt) == HI_FALSE) {
438 return HI_FALSE;
439 }
440 graphics_drv_trace(HI_DBG_INFO, "set layer(%u) DataFmt: %d!\n", (hi_u32)layer, data_fmt);
441 return HI_TRUE;
442 }
443
graphic_drv_set_layer_in_rect(hal_disp_layer layer,HIFB_RECT * rect)444 hi_bool graphic_drv_set_layer_in_rect(hal_disp_layer layer, HIFB_RECT *rect)
445 {
446 hi_u32 layer_index = 0;
447
448 if (fb_graphic_drv_get_layer_index(layer, &layer_index) != HI_SUCCESS) {
449 graphics_drv_trace(HI_DBG_ERR, "gfx_layer(%u) is invalid!\n", (hi_u32)layer);
450 return HI_FALSE;
451 }
452
453 if (fb_hal_layer_set_layer_in_rect(layer, rect) == HI_FALSE) {
454 return HI_FALSE;
455 }
456
457 if (fb_hal_video_set_layer_disp_rect(layer, rect) == HI_FALSE) {
458 return HI_FALSE;
459 }
460 if (fb_hal_video_set_layer_video_rect(layer, rect) == HI_FALSE) {
461 return HI_FALSE;
462 }
463
464 return HI_TRUE;
465 }
466
467 /*
468 * Name : graphic_drv_set_src_image_resolution
469 * Desc : set the original resolution of the frame.
470 */
graphic_drv_set_src_image_resolution(hal_disp_layer layer,HIFB_RECT * rect)471 hi_bool graphic_drv_set_src_image_resolution(hal_disp_layer layer, HIFB_RECT *rect)
472 {
473 if (fb_hal_layer_set_src_resolution(layer, rect) == HI_FALSE) {
474 return HI_FALSE;
475 }
476
477 if (fb_hal_layer_set_layer_in_rect(layer, rect) == HI_FALSE) {
478 return HI_FALSE;
479 }
480
481 return HI_TRUE;
482 }
483
graphic_drv_set_layer_out_rect(hal_disp_layer layer,HIFB_RECT * rect)484 hi_bool graphic_drv_set_layer_out_rect(hal_disp_layer layer, HIFB_RECT *rect)
485 {
486 return fb_hal_layer_set_layer_out_rect(layer, rect);
487 }
488
graphic_drv_set_color_key_value(hal_disp_layer layer,hal_gfx_key_max key_max,hal_gfx_key_min key_min)489 hi_bool graphic_drv_set_color_key_value(hal_disp_layer layer, hal_gfx_key_max key_max, hal_gfx_key_min key_min)
490 {
491 return hal_graphic_set_color_key_value(layer, key_max, key_min);
492 }
493
graphic_drv_set_color_key_mask(hal_disp_layer layer,hal_gfx_mask msk)494 hi_bool graphic_drv_set_color_key_mask(hal_disp_layer layer, hal_gfx_mask msk)
495 {
496 return hal_graphic_set_color_key_mask(layer, msk);
497 }
498
graphic_drv_set_gfx_key_en(hal_disp_layer layer,hi_u32 key_enable)499 hi_bool graphic_drv_set_gfx_key_en(hal_disp_layer layer, hi_u32 key_enable)
500 {
501 return hal_graphic_set_gfx_key_en(layer, key_enable);
502 }
503
graphic_drv_set_reg_up(hal_disp_layer layer)504 hi_bool graphic_drv_set_reg_up(hal_disp_layer layer)
505 {
506 return fb_hal_layer_set_reg_up(layer);
507 }
508
graphic_drv_get_layer_galpha(hal_disp_layer layer,hi_u8 * alpha0)509 hi_bool graphic_drv_get_layer_galpha(hal_disp_layer layer, hi_u8 *alpha0)
510 {
511 return hal_layer_get_layer_galpha(layer, alpha0);
512 }
513
graphic_drv_get_layer_data_fmt(hal_disp_layer layer,hi_u32 * fmt)514 hi_bool graphic_drv_get_layer_data_fmt(hal_disp_layer layer, hi_u32 *fmt)
515 {
516 return fb_hal_layer_get_layer_data_fmt(layer, fmt);
517 }
518
graphic_drv_get_gfx_addr(hal_disp_layer layer,hi_u64 * gfx_addr)519 hi_bool graphic_drv_get_gfx_addr(hal_disp_layer layer, hi_u64 *gfx_addr)
520 {
521 return hal_graphic_get_gfx_addr(layer, gfx_addr);
522 }
523
graphic_drv_get_gfx_stride(hal_disp_layer layer,hi_u32 * gfx_stride)524 hi_bool graphic_drv_get_gfx_stride(hal_disp_layer layer, hi_u32 *gfx_stride)
525 {
526 return hal_graphic_get_gfx_stride(layer, gfx_stride);
527 }
528
fb_graphic_drv_get_scan_mode(hifb_vo_dev vo_dev,hi_bool * iop)529 hi_bool fb_graphic_drv_get_scan_mode(hifb_vo_dev vo_dev, hi_bool *iop)
530 {
531 return fb_hal_disp_get_disp_iop(vo_dev, iop);
532 }
533
graphic_drv_enable_dcmp(hal_disp_layer layer,hi_bool enable)534 hi_bool graphic_drv_enable_dcmp(hal_disp_layer layer, hi_bool enable)
535 {
536 hi_u32 layer_index = 0;
537 if (fb_graphic_drv_get_layer_index(layer, &layer_index) != HI_SUCCESS) {
538 graphics_drv_trace(HI_DBG_ERR, "gfx_layer(%u) is invalid!\n", (hi_u32)layer);
539 return HI_FALSE;
540 }
541 if (hal_graphic_set_gfx_dcmp_enable(layer, enable) == HI_FALSE) {
542 return HI_FALSE;
543 }
544 hal_fdr_gfx_set_dcmp_en(layer_index, enable);
545 return HI_TRUE;
546 }
547
graphic_drv_get_dcmp_enable_state(hal_disp_layer layer,hi_bool * enable)548 hi_bool graphic_drv_get_dcmp_enable_state(hal_disp_layer layer, hi_bool *enable)
549 {
550 return hal_graphic_get_gfx_dcmp_enable_state(layer, enable);
551 }
552
graphic_drv_get_vt_thd_mode(hifb_vo_dev vo_dev,hi_bool * feild_update)553 hi_bool graphic_drv_get_vt_thd_mode(hifb_vo_dev vo_dev, hi_bool *feild_update)
554 {
555 return hal_disp_get_vt_thd_mode(vo_dev, feild_update);
556 }
557
fb_graphic_drv_get_int_state(hal_disp_layer gfx_layer,hi_bool * bottom)558 hi_bool fb_graphic_drv_get_int_state(hal_disp_layer gfx_layer, hi_bool *bottom)
559 {
560 return fb_hal_disp_get_int_state((hal_disp_outputchannel)gfx_layer, bottom);
561 }
562
vo_drv_get_csc_matrix(hal_csc_mode csc_mode,const csc_coef ** csc_tmp)563 static hi_s32 vo_drv_get_csc_matrix(hal_csc_mode csc_mode, const csc_coef **csc_tmp)
564 {
565 hi_u32 loop;
566 hi_u32 len;
567
568 vo_drv_csc_mode_coef csc_mode_coef[] = {
569 { HAL_CSC_MODE_BT601_TO_BT601, &g_fb_csc_init },
570 { HAL_CSC_MODE_BT709_TO_BT709, &g_fb_csc_init },
571 { HAL_CSC_MODE_RGB_TO_RGB, &g_fb_csc_init },
572 { HAL_CSC_MODE_BT709_TO_BT601, &g_fb_csc_yuv2yuv_709_601 },
573 { HAL_CSC_MODE_BT601_TO_BT709, &g_fb_csc_yuv2yuv_601_709 },
574 { HAL_CSC_MODE_BT601_TO_RGB_PC, &g_csc_yuv6012rgb_pc },
575 { HAL_CSC_MODE_BT709_TO_RGB_PC, &g_csc_yuv7092rgb_pc },
576 { HAL_CSC_MODE_RGB_TO_BT601_PC, &g_fb_csc_rgb2yuv601_pc },
577 { HAL_CSC_MODE_RGB_TO_BT709_PC, &g_fb_csc_rgb2yuv709_pc },
578 { HAL_CSC_MODE_RGB_TO_BT601_TV, &g_fb_csc_rgb2yuv601_tv },
579 { HAL_CSC_MODE_RGB_TO_BT709_TV, &g_fb_csc_rgb2yuv709_tv },
580 };
581
582 len = sizeof(csc_mode_coef) / sizeof(vo_drv_csc_mode_coef);
583 for (loop = 0; loop < len; loop++) {
584 if (csc_mode_coef[loop].csc_mode == csc_mode) {
585 *csc_tmp = csc_mode_coef[loop].coef;
586 return HI_SUCCESS;
587 }
588 }
589 return HI_FAILURE;
590 }
591
hifb_drv_yuvtorgb(hi_s32 hue,hi_s32 contrast,hi_s32 satu,csc_coef * cstcoef,const csc_coef * csctmp)592 static hi_void hifb_drv_yuvtorgb(hi_s32 hue, hi_s32 contrast, hi_s32 satu, csc_coef *cstcoef,
593 const csc_coef *csctmp)
594 {
595 cstcoef->csc_coef00 = (contrast * csctmp->csc_coef00) / HIFB_CSC_COEF_ALG_DATA;
596
597 cstcoef->csc_coef01 = (contrast * satu * ((csctmp->csc_coef01 * g_hifb_cos_table[hue] - csctmp->csc_coef02 *
598 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
599
600 cstcoef->csc_coef02 = (contrast * satu * ((csctmp->csc_coef01 * g_hifb_sin_table[hue] + csctmp->csc_coef02 *
601 g_hifb_cos_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
602
603 cstcoef->csc_coef10 = (contrast * csctmp->csc_coef10) / HIFB_CSC_COEF_ALG_DATA;
604
605 cstcoef->csc_coef11 = (contrast * satu * ((csctmp->csc_coef11 * g_hifb_cos_table[hue] - csctmp->csc_coef12 *
606 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
607
608 cstcoef->csc_coef12 = (contrast * satu * ((csctmp->csc_coef11 * g_hifb_sin_table[hue] + csctmp->csc_coef12 *
609 g_hifb_cos_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
610
611 cstcoef->csc_coef20 = (contrast * csctmp->csc_coef20) / HIFB_CSC_COEF_ALG_DATA;
612
613 cstcoef->csc_coef21 = (contrast * satu * ((csctmp->csc_coef21 * g_hifb_cos_table[hue] - csctmp->csc_coef22 *
614 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
615
616 cstcoef->csc_coef22 = (contrast * satu * ((csctmp->csc_coef21 * g_hifb_sin_table[hue] + csctmp->csc_coef22 *
617 g_hifb_cos_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
618
619 return;
620 }
621
hifb_drv_rgbtoyuv(hi_s32 hue,hi_s32 contrast,hi_s32 satu,csc_coef * cstcoef,const csc_coef * csctmp)622 static hi_void hifb_drv_rgbtoyuv(hi_s32 hue, hi_s32 contrast, hi_s32 satu, csc_coef *cstcoef,
623 const csc_coef *csctmp)
624 {
625 cstcoef->csc_coef00 = (contrast * csctmp->csc_coef00) / HIFB_CSC_COEF_ALG_DATA;
626
627 cstcoef->csc_coef01 = (contrast * csctmp->csc_coef01) / HIFB_CSC_COEF_ALG_DATA;
628
629 cstcoef->csc_coef02 = (contrast * csctmp->csc_coef02) / HIFB_CSC_COEF_ALG_DATA;
630
631 cstcoef->csc_coef10 = (contrast * satu * ((csctmp->csc_coef10 * g_hifb_cos_table[hue] + csctmp->csc_coef20 *
632 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
633
634 cstcoef->csc_coef11 = (contrast * satu * ((csctmp->csc_coef11 * g_hifb_cos_table[hue] + csctmp->csc_coef21 *
635 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
636
637 cstcoef->csc_coef12 = (contrast * satu * ((csctmp->csc_coef12 * g_hifb_cos_table[hue] + csctmp->csc_coef22 *
638 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
639
640 cstcoef->csc_coef20 = (contrast * satu * ((csctmp->csc_coef20 * g_hifb_cos_table[hue] - csctmp->csc_coef10 *
641 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
642
643 cstcoef->csc_coef21 = (contrast * satu * ((csctmp->csc_coef21 * g_hifb_cos_table[hue] - csctmp->csc_coef11 *
644 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
645
646 cstcoef->csc_coef22 = (contrast * satu * ((csctmp->csc_coef22 * g_hifb_cos_table[hue] - csctmp->csc_coef12 *
647 g_hifb_sin_table[hue]) / HIFB_CSC_STATU_ALG_DATA)) / HIFB_CSC_HUE_ALG_DATA;
648
649 return;
650 }
651
652 /*
653 * Name : fb_vou_drv_calc_csc_matrix
654 * Desc : Calculate csc matrix.
655 */
fb_vou_drv_calc_csc_matrix(fb_vo_csc * gfx_csc,hal_csc_mode csd_mode,csc_coef * coef)656 hi_s32 fb_vou_drv_calc_csc_matrix(fb_vo_csc *gfx_csc, hal_csc_mode csd_mode, csc_coef *coef)
657 {
658 hi_s32 luma, contrast, hue, satu;
659
660 const csc_coef *csc_tmp = HI_NULL;
661 luma = (hi_s32)gfx_csc->luma * 64 / 100 - 32; /* 100 64 32 alg data */
662 contrast = ((hi_s32)gfx_csc->contrast - 50) * 2 + 100; /* 100 50 2 alg data */
663 hue = (hi_s32)gfx_csc->hue * 60 / 100; /* 100 60 alg data */
664 satu = ((hi_s32)gfx_csc->satuature - 50) * 2 + 100; /* 100 50 2 alg data */
665
666 if (vo_drv_get_csc_matrix(csd_mode, (const csc_coef **)&csc_tmp) != HI_SUCCESS) {
667 return HI_FAILURE;
668 }
669 coef->csc_in_dc0 = csc_tmp->csc_in_dc0;
670 coef->csc_in_dc1 = csc_tmp->csc_in_dc1;
671 coef->csc_in_dc2 = csc_tmp->csc_in_dc2;
672 coef->csc_out_dc0 = csc_tmp->csc_out_dc0;
673 coef->csc_out_dc1 = csc_tmp->csc_out_dc1;
674 coef->csc_out_dc2 = csc_tmp->csc_out_dc2;
675 /*
676 * C_ratio normally is 0~1.99, C_ratio=contrast/100
677 * S normally is 0~1.99,S=satu/100
678 * Hue -30~30, using the lut to get COS and SIN and then /1000
679 */
680 if ((csd_mode == HAL_CSC_MODE_BT601_TO_RGB_PC) || (csd_mode == HAL_CSC_MODE_BT709_TO_RGB_PC) ||
681 (csd_mode == HAL_CSC_MODE_BT601_TO_RGB_TV) || (csd_mode == HAL_CSC_MODE_BT709_TO_RGB_TV)) {
682 /* YUV->RGB convert, RGB->YUV convert */
683 hifb_drv_yuvtorgb(hue, contrast, satu, coef, csc_tmp);
684 coef->csc_in_dc0 += (contrast != 0) ? (luma * 100 / contrast) : luma * 100; /* 100 contrast data */
685 } else {
686 /* RGB->YUV convert, YUV->RGB convert, YUV->YUV */
687 hifb_drv_rgbtoyuv(hue, contrast, satu, coef, csc_tmp);
688 coef->csc_out_dc0 += luma;
689 }
690
691 return HI_SUCCESS;
692 }
693
graphic_drv_get_dev_enable(hifb_vo_dev vo_dev,hi_bool * intf_en)694 hi_bool graphic_drv_get_dev_enable(hifb_vo_dev vo_dev, hi_bool *intf_en)
695 {
696 return fb_hal_disp_get_intf_enable(vo_dev, intf_en);
697 }
698
graphic_drv_get_intf_sync(hifb_vo_dev vo_dev,hal_disp_syncinfo * sync_info)699 hi_bool graphic_drv_get_intf_sync(hifb_vo_dev vo_dev, hal_disp_syncinfo *sync_info)
700 {
701 return hal_disp_get_intf_sync(vo_dev, sync_info);
702 }
703
graphic_drv_get_intf_mux_sel(hifb_vo_dev vo_dev,VO_INTF_TYPE_E * ben_intf_type)704 hi_bool graphic_drv_get_intf_mux_sel(hifb_vo_dev vo_dev, VO_INTF_TYPE_E *ben_intf_type)
705 {
706 return hal_disp_get_intf_mux_sel(vo_dev, ben_intf_type);
707 }
708
graphic_drv_allocate_mem(hi_u32 size,hifb_mmz_buffer * vdp_mmz_buffer)709 hi_s32 graphic_drv_allocate_mem(hi_u32 size, hifb_mmz_buffer *vdp_mmz_buffer)
710 {
711 hi_s32 ret;
712
713 hi_void *mmz_name = HI_NULL;
714 hi_mpp_chn chn;
715
716 chn.mod_id = HI_ID_FB;
717 chn.dev_id = 0;
718 chn.chn_id = 0;
719
720 if (func_entry(sys_export_func, HI_ID_SYS)->pfn_get_mmz_name(&chn, &mmz_name)) {
721 hifb_graphics_trace(HI_DBG_ERR, "get mmz name fail!\n");
722 return HI_FAILURE;
723 }
724
725 ret = cmpi_mmz_malloc_nocache(mmz_name, "HIFB COEF", &vdp_mmz_buffer->start_phy_addr,
726 &vdp_mmz_buffer->start_vir_addr, size);
727 if (ret != 0) {
728 hifb_graphics_trace(HI_DBG_ERR, "HIFB DDR CFG failed\n");
729 return HI_FAILURE;
730 }
731 (hi_void)memset_s(vdp_mmz_buffer->start_vir_addr, size, 0, size);
732 return HI_SUCCESS;
733 }
734
graphic_drv_delete_mem(hifb_mmz_buffer * vdp_mmz_buffer)735 hi_void graphic_drv_delete_mem(hifb_mmz_buffer *vdp_mmz_buffer)
736 {
737 if (vdp_mmz_buffer != HI_NULL) {
738 cmpi_mmz_free(vdp_mmz_buffer->start_phy_addr, vdp_mmz_buffer->start_vir_addr);
739 vdp_mmz_buffer->start_phy_addr = 0;
740 vdp_mmz_buffer->start_vir_addr = HI_NULL;
741 }
742 }
743
graphic_drv_vhd_coef_buf_addr_distribute(hifb_coef_addr * vdp_coef_buf_addr)744 hi_s32 graphic_drv_vhd_coef_buf_addr_distribute(hifb_coef_addr *vdp_coef_buf_addr)
745 {
746 vdp_coef_buf_addr->coef_vir_addr[HIFB_COEF_BUF_G0ZME] = vdp_coef_buf_addr->buf_base_addr.start_vir_addr;
747 vdp_coef_buf_addr->coef_phy_addr[HIFB_COEF_BUF_G0ZME] = vdp_coef_buf_addr->buf_base_addr.start_phy_addr;
748
749 hal_para_set_para_addr_vhd_chn06(vdp_coef_buf_addr->coef_phy_addr[HIFB_COEF_BUF_G0ZME]);
750
751 return HI_SUCCESS;
752 }
753
graphic_zme_coef_init(hi_void)754 hi_s32 graphic_zme_coef_init(hi_void)
755 {
756 /* hifb only need zme coef size */
757 if (graphic_drv_allocate_mem(COEF_SIZE_G0ZME, &g_hifb_coef_buf_addr.buf_base_addr) != HI_SUCCESS ||
758 graphic_drv_vhd_coef_buf_addr_distribute(&g_hifb_coef_buf_addr) != HI_SUCCESS) {
759 return HI_FAILURE;
760 }
761 return HI_SUCCESS;
762 }
763
fb_graphic_drv_init(hi_void)764 hi_s32 fb_graphic_drv_init(hi_void)
765 {
766 hi_s32 i;
767 vo_gfxlayer_context *vo_gfx_ctx = HI_NULL;
768 vo_gfxlayer_context *gfx_layer = get_gfx_layer_ctx();
769
770 for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
771 vo_gfx_ctx = &gfx_layer[i];
772
773 vo_gfx_ctx->layer_id = HAL_DISP_LAYER_GFX0 + i; /* HAL_DISP_LAYER_GFX0+1 */
774 vo_gfx_ctx->binded_dev = i; /* 0 */
775 vo_gfx_ctx->binded = HI_TRUE;
776 }
777
778 for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
779 vo_gfx_ctx = &gfx_layer[i];
780 vo_gfx_ctx->gfx_csc.csc_matrix = FB_VO_CSC_MATRIX_RGB_TO_BT601_TV;
781 vo_gfx_ctx->gfx_csc.luma = 50; /* 50 is gfx csc date */
782 vo_gfx_ctx->gfx_csc.contrast = 50; /* 50 is gfx csc date */
783 vo_gfx_ctx->gfx_csc.hue = 50; /* 50 is gfx csc date */
784 vo_gfx_ctx->gfx_csc.satuature = 50; /* 50 is gfx csc date */
785
786 /* CSC extra coef */
787 vo_gfx_ctx->coef_param.csc_scale2p = GFX_CSC_SCALE;
788 vo_gfx_ctx->coef_param.csc_clip_min = GFX_CSC_CLIP_MIN;
789 vo_gfx_ctx->coef_param.csc_clip_max = GFX_CSC_CLIP_MAX;
790 }
791
792 /* DDR detect coef */
793 gfx_layer[0].start_section = 0;
794 gfx_layer[0].zone_nums = 16; /* 16 is alg date */
795 return HI_SUCCESS;
796 }
797
graphic_drv_get_bind_dev(hi_s32 layer_id)798 hi_s32 graphic_drv_get_bind_dev(hi_s32 layer_id)
799 {
800 vo_gfxlayer_context *gfx_layer = get_gfx_layer_ctx();
801 return gfx_layer[layer_id].binded_dev;
802 }
803
fb_graphic_drv_exit(hi_void)804 hi_s32 fb_graphic_drv_exit(hi_void)
805 {
806 return HI_SUCCESS;
807 }
808
graphic_drv_resource_init(hi_void)809 hi_s32 graphic_drv_resource_init(hi_void)
810 {
811 hi_s32 i, j;
812 vo_gfxlayer_context *gfx_layer = get_gfx_layer_ctx();
813
814 if (fb_hal_vou_init() != HI_SUCCESS) {
815 return HI_FAILURE;
816 }
817 /* lock init */
818 for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
819 (hi_void)memset_s(&gfx_layer[i], sizeof(vo_gfxlayer_context), 0, sizeof(vo_gfxlayer_context));
820 if (gfx_spin_lock_init(&gfx_layer[i].spin_lock) != 0) {
821 for (j = 0; j < i; j++) {
822 gfx_spin_lock_deinit(&gfx_layer[j].spin_lock);
823 }
824 return HI_FAILURE;
825 }
826 }
827 /* mem alloc */
828 if (graphic_zme_coef_init() != HI_SUCCESS) {
829 return HI_FAILURE;
830 }
831
832 return HI_SUCCESS;
833 }
834
graphic_drv_resource_exit(hi_void)835 hi_s32 graphic_drv_resource_exit(hi_void)
836 {
837 hi_s32 i;
838 vo_gfxlayer_context *vo_gfx_ctx = HI_NULL;
839 vo_gfxlayer_context *gfx_layer = get_gfx_layer_ctx();
840 /* lock deinit */
841 for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
842 vo_gfx_ctx = &gfx_layer[i];
843 gfx_spin_lock_deinit(&vo_gfx_ctx->spin_lock);
844 }
845 /* mem delete */
846 graphic_drv_delete_mem(&g_hifb_coef_buf_addr.buf_base_addr);
847 fb_hal_vou_exit();
848
849 return HI_SUCCESS;
850 }
851
graphic_drv_enable_layer(hal_disp_layer gfx_layer,hi_bool enabled)852 hi_s32 graphic_drv_enable_layer(hal_disp_layer gfx_layer, hi_bool enabled)
853 {
854 if (fb_hal_layer_enable_layer(gfx_layer, enabled) == HI_FALSE) {
855 graphics_drv_trace(HI_DBG_ERR, "graphics layer %d Enable failed!\n", gfx_layer);
856 return HI_FAILURE;
857 }
858 return HI_SUCCESS;
859 }
860
drv_csc_coef(csc_coef * coef)861 static hi_void drv_csc_coef(csc_coef *coef)
862 {
863 coef->new_csc_clip_max = GFX_CSC_CLIP_MAX;
864 coef->new_csc_clip_min = GFX_CSC_CLIP_MIN;
865 coef->new_csc_scale2p = GFX_CSC_SCALE;
866
867 coef->csc_coef00 = HIFB_COEF_CSC_DEX * coef->csc_coef00 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
868 coef->csc_coef01 = HIFB_COEF_CSC_DEX * coef->csc_coef01 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
869 coef->csc_coef02 = HIFB_COEF_CSC_DEX * coef->csc_coef02 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
870 coef->csc_coef10 = HIFB_COEF_CSC_DEX * coef->csc_coef10 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
871 coef->csc_coef11 = HIFB_COEF_CSC_DEX * coef->csc_coef11 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
872 coef->csc_coef12 = HIFB_COEF_CSC_DEX * coef->csc_coef12 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
873 coef->csc_coef20 = HIFB_COEF_CSC_DEX * coef->csc_coef20 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
874 coef->csc_coef21 = HIFB_COEF_CSC_DEX * coef->csc_coef21 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
875 coef->csc_coef22 = HIFB_COEF_CSC_DEX * coef->csc_coef22 * HIFB_COEF_CSC_GFX / HIFB_CSC_STATU_ALG_DATA;
876
877 coef->csc_in_dc0 = HIFB_COEF_CSC_DC_ALG_DATA * coef->csc_in_dc0;
878 coef->csc_in_dc1 = HIFB_COEF_CSC_DC_ALG_DATA * coef->csc_in_dc1;
879 coef->csc_in_dc2 = HIFB_COEF_CSC_DC_ALG_DATA * coef->csc_in_dc2;
880
881 coef->csc_out_dc0 = HIFB_COEF_CSC_DC_ALG_DATA * coef->csc_out_dc0;
882 coef->csc_out_dc1 = HIFB_COEF_CSC_DC_ALG_DATA * coef->csc_out_dc1;
883 coef->csc_out_dc2 = HIFB_COEF_CSC_DC_ALG_DATA * coef->csc_out_dc2;
884
885 return;
886 }
887
fb_graphic_drv_set_csc_coef(hal_disp_layer gfx_layer,fb_vo_csc * gfx_csc,csc_coef_param * coef_param)888 hi_s32 fb_graphic_drv_set_csc_coef(hal_disp_layer gfx_layer, fb_vo_csc *gfx_csc, csc_coef_param *coef_param)
889 {
890 csc_coef coef;
891 hal_csc_mode csc_mode;
892 hi_u32 layer_index;
893 hi_s32 ret;
894 vo_gfxlayer_context *gfx_layer_ctx = get_gfx_layer_ctx();
895 if ((gfx_csc == HI_NULL) || (coef_param == HI_NULL)) {
896 return HI_FAILURE;
897 }
898
899 if (fb_graphic_drv_get_layer_index(gfx_layer, &layer_index) != HI_SUCCESS) {
900 graphics_drv_trace(HI_DBG_ERR, "gfx_layer(%u) is invalid!\n", (hi_u32)gfx_layer);
901 return HI_FAILURE;
902 }
903 if (gfx_csc->csc_matrix == FB_VO_CSC_MATRIX_RGB_TO_BT601_PC) {
904 csc_mode = HAL_CSC_MODE_RGB_TO_BT601_PC;
905 } else if (gfx_csc->csc_matrix == FB_VO_CSC_MATRIX_RGB_TO_BT709_PC) {
906 csc_mode = HAL_CSC_MODE_RGB_TO_BT709_PC;
907 } else if (gfx_csc->csc_matrix == FB_VO_CSC_MATRIX_RGB_TO_BT601_TV) {
908 csc_mode = HAL_CSC_MODE_RGB_TO_BT601_TV;
909 } else if (gfx_csc->csc_matrix == FB_VO_CSC_MATRIX_RGB_TO_BT709_TV) {
910 csc_mode = HAL_CSC_MODE_RGB_TO_BT709_TV;
911 } else {
912 graphics_drv_trace(HI_DBG_ERR, "csc_matrix %d err, should only be RGB to YUV matrix\n", gfx_csc->csc_matrix);
913 return HI_ERR_VO_ILLEGAL_PARAM;
914 }
915 /* cal CSC coef and CSC dc coef */
916 if (fb_vou_drv_calc_csc_matrix(gfx_csc, csc_mode, &coef) != HI_SUCCESS) {
917 return HI_FAILURE;
918 }
919 drv_csc_coef(&coef);
920
921 /* set CSC coef and CSC dc coef */
922 fb_hal_layer_set_csc_coef(gfx_layer, &coef);
923
924 /* copy to drv */
925 if (layer_index >= VO_MAX_GRAPHICS_LAYER_NUM) {
926 return HI_FAILURE;
927 }
928
929 ret = memcpy_s(&gfx_layer_ctx[layer_index].gfx_csc, sizeof(gfx_layer_ctx[layer_index].gfx_csc),
930 gfx_csc, sizeof(fb_vo_csc));
931 hifb_unequal_eok_return(ret);
932 ret = memcpy_s(&gfx_layer_ctx[layer_index].coef_param, sizeof(gfx_layer_ctx[layer_index].coef_param),
933 coef_param, sizeof(csc_coef_param));
934 hifb_unequal_eok_return(ret);
935
936 return HI_SUCCESS;
937 }
938
gf_func_set_g0zme_mode(hi_u32 layer,gf_g0_zme_mode g0zme_mode,gf_g0_zme_cfg * cfg)939 hi_void gf_func_set_g0zme_mode(hi_u32 layer, gf_g0_zme_mode g0zme_mode, gf_g0_zme_cfg *cfg)
940 {
941 /* filed declare */
942 hi_u32 hfir_order = 1;
943 hi_s32 lhfir_offset = 0;
944 hi_s32 chfir_offset = 0;
945 hi_s32 vtp_offset = 0;
946 hi_s32 vbtm_offset = 0;
947 hi_u32 hratio, vratio;
948 const hi_ulong zme_hprec = (1 << 20); /* 20 bit data */
949 const hi_ulong zme_vprec = (1 << 12); /* 12 bit data */
950 hi_unused(layer);
951
952 if ((cfg->out_width == 0) || (cfg->out_height == 0)) {
953 return;
954 }
955 hratio = (cfg->in_width * zme_hprec) / cfg->out_width;
956 vratio = (cfg->in_height * zme_vprec) / cfg->out_height;
957
958 if (g0zme_mode == VDP_G0_ZME_TYP) {
959 lhfir_offset = 0;
960 chfir_offset = 0;
961 vtp_offset = 0;
962 vbtm_offset = (-1) * (hi_s64)zme_vprec / 2; /* 2 offset data */
963 }
964
965 /* drv transfer */
966 hal_g0_zme_set_ck_gt_en(cfg->ck_gt_en);
967 hal_g0_zme_set_out_width(cfg->out_width);
968 hal_g0_zme_set_hfir_en(cfg->hfir_en);
969 hal_g0_zme_set_ahfir_mid_en(cfg->ahmid_en);
970 hal_g0_zme_set_lhfir_mid_en(cfg->lhmid_en);
971 hal_g0_zme_set_chfir_mid_en(cfg->lhmid_en);
972 hal_g0_zme_set_lhfir_mode(cfg->lhfir_mode);
973 hal_g0_zme_set_ahfir_mode(cfg->ahfir_mode);
974 hal_g0_zme_set_hfir_order(hfir_order);
975 hal_g0_zme_set_hratio(hratio);
976 hal_g0_zme_set_lhfir_offset(lhfir_offset);
977 hal_g0_zme_set_chfir_offset(chfir_offset);
978 hal_g0_zme_set_out_pro(cfg->out_pro);
979 hal_g0_zme_set_out_height(cfg->out_height);
980 hal_g0_zme_set_vfir_en(cfg->vfir_en);
981 hal_g0_zme_set_avfir_mid_en(cfg->avmid_en);
982 hal_g0_zme_set_lvfir_mid_en(cfg->lvmid_en);
983 hal_g0_zme_set_cvfir_mid_en(cfg->lvmid_en);
984 hal_g0_zme_set_lvfir_mode(cfg->lvfir_mode);
985 hal_g0_zme_set_vafir_mode(cfg->avfir_mode);
986 hal_g0_zme_set_vratio(vratio);
987 hal_g0_zme_set_vtp_offset(vtp_offset);
988 hal_g0_zme_set_vbtm_offset(vbtm_offset);
989 }
990
vo_drv_write_ddr(hi_u8 * addr,hifb_drv_u128 * data128)991 hi_u32 vo_drv_write_ddr(hi_u8 *addr, hifb_drv_u128 *data128)
992 {
993 hi_u32 ii;
994 hi_u32 data_arr[HIFB_DATEARR_RANGE] = {
995 data128->data0, data128->data1,
996 data128->data2, data128->data3
997 };
998 hi_u8 *addr_tmp = HI_NULL;
999
1000 hi_u32 data_tmp;
1001
1002 for (ii = 0; ii < HIFB_DATEARR_RANGE; ii++) {
1003 addr_tmp = addr + ii * HIFB_DATEARR_RANGE;
1004 data_tmp = data_arr[ii];
1005 *(hi_u32 *)addr_tmp = data_tmp;
1006 }
1007
1008 return 0;
1009 }
1010
vo_drv_push128(hifb_drv_u128 * data128,hi_u32 coef_data,hi_u32 bit_len)1011 hi_void vo_drv_push128(hifb_drv_u128 *data128, hi_u32 coef_data, hi_u32 bit_len)
1012 {
1013 coef_data = coef_data & (0xFFFFFFFF >> (32 - bit_len)); /* 0xFFFFFFFF 32 bit len */
1014
1015 if (data128->depth < 32) { /* 32 max depth */
1016 if ((data128->depth + bit_len) <= 32) { /* 32 bit len */
1017 data128->data0 = (coef_data << data128->depth) | data128->data0;
1018 } else {
1019 data128->data0 = (coef_data << data128->depth) | data128->data0;
1020 data128->data1 = coef_data >> (32 - data128->depth % 32); /* 32 depth data */
1021 }
1022 } else if ((data128->depth >= 32) && (data128->depth < 64)) { /* 32 64 depth data */
1023 if ((data128->depth + bit_len) <= 64) {
1024 data128->data1 = (coef_data << (data128->depth % 32)) | data128->data1; /* 32 depth data */
1025 } else {
1026 data128->data1 = (coef_data << (data128->depth % 32)) | data128->data1; /* 32 depth data */
1027 data128->data2 = coef_data >> (32 - data128->depth % 32); /* 32 depth data */
1028 }
1029 } else if ((data128->depth >= 64) && (data128->depth < 96)) { /* 96 64 depth data */
1030 if ((data128->depth + bit_len) <= 96) { /* 96 depth data */
1031 data128->data2 = (coef_data << (data128->depth % 32)) | data128->data2; /* 32 depth data */
1032 } else {
1033 data128->data2 = (coef_data << (data128->depth % 32)) | data128->data2; /* 32 depth data */
1034 data128->data3 = coef_data >> (32 - data128->depth % 32); /* 32 depth data */
1035 }
1036 } else if (data128->depth >= 96) { /* 96 depth data */
1037 if ((data128->depth + bit_len) <= 128) { /* 128 depth data */
1038 data128->data3 = (coef_data << (data128->depth % 32)) | data128->data3; /* 32 depth data */
1039 }
1040 }
1041
1042 data128->depth = data128->depth + bit_len;
1043 return;
1044 }
1045
vo_drv_find_max(hi_u32 * array,hi_u32 num)1046 hi_u32 vo_drv_find_max(hi_u32 *array, hi_u32 num)
1047 {
1048 hi_u32 ii;
1049 hi_u32 tmp_data = array[0];
1050
1051 for (ii = 1; ii < num; ii++) {
1052 if (tmp_data < array[ii]) {
1053 tmp_data = array[ii];
1054 }
1055 }
1056
1057 return tmp_data;
1058 }
1059
send_coef_coef_array(hifb_drv_coef_send_cfg * cfg,hifb_drv_u128 * data128,hi_u32 coef_cnt)1060 hi_void send_coef_coef_array(hifb_drv_coef_send_cfg *cfg, hifb_drv_u128 *data128, hi_u32 coef_cnt)
1061 {
1062 hi_s32 tmp_data = 0;
1063 hi_u32 nn;
1064 for (nn = 0; nn < cfg->lut_num; nn++) {
1065 switch (cfg->data_type) {
1066 case DRV_COEF_DATA_TYPE_S16:
1067 if (coef_cnt < cfg->lut_length[nn]) {
1068 tmp_data = (((hi_s16 **)cfg->coef_array)[nn][coef_cnt]);
1069 }
1070 break;
1071 case DRV_COEF_DATA_TYPE_U16:
1072 if (coef_cnt < cfg->lut_length[nn]) {
1073 tmp_data = (((hi_u16 **)cfg->coef_array)[nn][coef_cnt]);
1074 }
1075 break;
1076 case DRV_COEF_DATA_TYPE_U32:
1077 if (coef_cnt < cfg->lut_length[nn]) {
1078 tmp_data = (((hi_u32 **)cfg->coef_array)[nn][coef_cnt]);
1079 }
1080 break;
1081 case DRV_COEF_DATA_TYPE_S32:
1082 if (coef_cnt < cfg->lut_length[nn]) {
1083 tmp_data = (((hi_s32 **)cfg->coef_array)[nn][coef_cnt]);
1084 }
1085 break;
1086 case DRV_COEF_DATA_TYPE_S8:
1087 if (coef_cnt < cfg->lut_length[nn]) {
1088 tmp_data = (((hi_s8 **)cfg->coef_array)[nn][coef_cnt]);
1089 }
1090 break;
1091 case DRV_COEF_DATA_TYPE_U8:
1092 if (coef_cnt < cfg->lut_length[nn]) {
1093 tmp_data = (((hi_u8 **)cfg->coef_array)[nn][coef_cnt]);
1094 }
1095 break;
1096 default:
1097 break;
1098 }
1099
1100 vo_drv_push128(data128, tmp_data, cfg->coef_bit_length[nn]);
1101 }
1102 return;
1103 }
1104
vo_drv_send_coef(hifb_drv_coef_send_cfg * cfg)1105 hi_u8 *vo_drv_send_coef(hifb_drv_coef_send_cfg *cfg)
1106 {
1107 hi_u32 ii, kk, mm;
1108 hi_u8 *addr_base = cfg->coef_addr;
1109 hi_u32 addr_offset = 0;
1110 hi_u8 *addr = HI_NULL;
1111 hi_u32 cycle_num, coef_cnt, total_burst_num, max_len;
1112 hi_u32 total_bit_len = 0;
1113 hifb_drv_u128 data128 = { 0 };
1114
1115 addr_base = cfg->coef_addr;
1116
1117 /* data type conversion */
1118 addr = addr_base;
1119
1120 cycle_num = cfg->cycle_num;
1121
1122 for (ii = 0; ii < cfg->lut_num; ii++) {
1123 total_bit_len = total_bit_len + cfg->coef_bit_length[ii];
1124 }
1125
1126 /* send data */
1127 max_len = vo_drv_find_max(cfg->lut_length, cfg->lut_num);
1128 if ((cfg->burst_num == 1) && ((cfg->data_type < DRV_COEF_DATA_TYPE_BUTT) && (cfg->data_type >= 0))) {
1129 if (cycle_num == 0) {
1130 return HI_NULL;
1131 }
1132 total_burst_num = (max_len + cycle_num - 1) / cycle_num;
1133 for (kk = 0; kk < total_burst_num; kk++) {
1134 (hi_void)memset_s((hi_void *)&data128, sizeof(data128), 0, sizeof(data128));
1135 for (mm = 0; mm < cycle_num; mm++) {
1136 coef_cnt = kk * cycle_num + mm;
1137 send_coef_coef_array(cfg, &data128, coef_cnt);
1138 }
1139 addr = addr_base + addr_offset;
1140 addr_offset = addr_offset + 16; /* 16 alg data */
1141 vo_drv_write_ddr(addr, &data128);
1142 }
1143 }
1144
1145 return (addr_base + addr_offset);
1146 }
1147
gf_drv_set_g0zme_coef(hi_s16 * coef_h,hi_s16 * coef_v)1148 hi_void gf_drv_set_g0zme_coef(hi_s16 *coef_h, hi_s16 *coef_v)
1149 {
1150 hifb_drv_coef_send_cfg coef_send;
1151 hi_u8 *addr = HI_NULL;
1152
1153 hi_void *coef_array[1] = { coef_h };
1154 hi_u32 lut_length[1] = { 64 }; /* 64 is max lut length */
1155 hi_u32 coef_bit_length[1] = { 16 }; /* 16 is max bit length */
1156
1157 addr = g_hifb_coef_buf_addr.coef_vir_addr[HIFB_COEF_BUF_G0ZME];
1158
1159 coef_send.coef_addr = addr;
1160 coef_send.lut_num = 1;
1161 coef_send.burst_num = 1;
1162 coef_send.cycle_num = 8; /* 8 is cycle NUM */
1163 coef_send.coef_array = coef_array;
1164 coef_send.lut_length = lut_length;
1165 coef_send.coef_bit_length = coef_bit_length;
1166 coef_send.data_type = DRV_COEF_DATA_TYPE_S16;
1167
1168 addr = vo_drv_send_coef(&coef_send);
1169 coef_array[0] = coef_v;
1170 lut_length[0] = 128; /* 128 is length */
1171 coef_bit_length[0] = 16; /* 16 is length */
1172
1173 coef_send.coef_addr = addr;
1174 coef_send.cycle_num = 8; /* 8 is cycle NUM */
1175 coef_send.coef_array = coef_array;
1176 coef_send.lut_length = lut_length;
1177 coef_send.coef_bit_length = coef_bit_length;
1178 coef_send.data_type = DRV_COEF_DATA_TYPE_S16;
1179
1180 addr = vo_drv_send_coef(&coef_send);
1181 if (addr == HI_NULL) {
1182 hifb_error(" vo_drv_send_coef HI_NULL\r\n");
1183 }
1184 }
1185
1186 #define HIFB_COEF_V_RANGE 16
1187 #define HIFB_COEF_H_RANGE 8
1188 #define HIFB_COEF_RANGE 8
1189 #define HIFB_COEF_V_NEW_RANGE 128
1190 #define HIFB_COEF_H_NEW_RANGE 64
1191
1192 hi_s16 g_coef_v[HIFB_COEF_V_RANGE][HIFB_COEF_RANGE] = {
1193 { 0, 0, 0, 0, 0, 63, 0, 0 }, { 0, 0, 0, 0, 6, 51, 13, -6 },
1194 { 0, 0, 0, 0, 4, 51, 16, -7 }, { 0, 0, 0, 0, 1, 50, 20, -7 },
1195 { 0, 0, 0, 0, -1, 49, 24, -8 }, { 0, 0, 0, 0, -3, 47, 28, -8 },
1196 { 0, 0, 0, 0, -4, 45, 31, -8 }, { 0, 0, 0, 0, -6, 42, 35, -7 },
1197 { 0, 0, 0, 0, -7, 39, 39, -7 }, { 0, 0, 0, 0, -7, 35, 42, -6 },
1198 { 0, 0, 0, 0, -8, 31, 45, -4 }, { 0, 0, 0, 0, -8, 28, 47, -3 },
1199 { 0, 0, 0, 0, -8, 24, 49, -1 }, { 0, 0, 0, 0, -7, 20, 50, 1 },
1200 { 0, 0, 0, 0, -7, 16, 51, 4 }, { 0, 0, 0, 0, -6, 13, 51, 6 }
1201 };
1202
1203 hi_s16 g_coef_h[HIFB_COEF_H_RANGE][HIFB_COEF_RANGE] = {
1204 { 0, 0, 0, 0, 63, 0, 0, 0 }, { 0, 0, -4, 4, 52, 16, -6, 2 },
1205 { 0, 0, -2, -1, 48, 24, -7, 2 }, { 0, 0, -1, -4, 44, 31, -7, 1 },
1206 { 0, 0, 1, -7, 38, 38, -7, 1 }, { 0, 0, 1, -7, 31, 44, -4, -1 },
1207 { 0, 0, 2, -7, 24, 48, -1, -2 }, { 0, 0, 2, -6, 16, 52, 4, -4 }
1208 };
1209
1210 hi_s16 g_coef_h_new[HIFB_COEF_H_NEW_RANGE];
1211 hi_s16 g_coef_v_new[HIFB_COEF_V_NEW_RANGE];
1212
gf_vset_g0zme_coef(gf_rm_coef_mode coef_mode)1213 hi_void gf_vset_g0zme_coef(gf_rm_coef_mode coef_mode)
1214 {
1215 hi_u32 ii;
1216
1217 if (coef_mode == GF_RM_COEF_MODE_TYP) {
1218 for (ii = 0; ii < 8; ii++) { /* 8 order buffer */
1219 g_coef_h_new[ii * 8 + 0] = g_coef_h[ii][7]; /* calc 0index coef for 8 order coef from 7index old */
1220 g_coef_h_new[ii * 8 + 1] = g_coef_h[ii][6]; /* calc 1index coef for 8 order coef from 6index old */
1221 g_coef_h_new[ii * 8 + 2] = g_coef_h[ii][5]; /* calc 2index coef for 8 order coef from 5index old */
1222 g_coef_h_new[ii * 8 + 3] = g_coef_h[ii][4]; /* calc 3index coef for 8 order coef from 4index old */
1223 g_coef_h_new[ii * 8 + 4] = g_coef_h[ii][3]; /* calc 4index coef for 8 order coef from 3index old */
1224 g_coef_h_new[ii * 8 + 5] = g_coef_h[ii][2]; /* calc 5index coef for 8 order coef from 2index old */
1225 g_coef_h_new[ii * 8 + 6] = g_coef_h[ii][1]; /* calc 6index coef for 8 order coef from 1index old */
1226 g_coef_h_new[ii * 8 + 7] = g_coef_h[ii][0]; /* calc 7index coef for 8 order coef from 0index old */
1227 }
1228
1229 for (ii = 0; ii < 16; ii++) { /* 16 order buffer */
1230 g_coef_v_new[ii * 8 + 0] = g_coef_v[ii][7]; /* calc 0index coef for 8 order coef from 7index old */
1231 g_coef_v_new[ii * 8 + 1] = g_coef_v[ii][6]; /* calc 1index coef for 8 order coef from 6index old */
1232 g_coef_v_new[ii * 8 + 2] = g_coef_v[ii][5]; /* calc 2index coef for 8 order coef from 5index old */
1233 g_coef_v_new[ii * 8 + 3] = g_coef_v[ii][4]; /* calc 3index coef for 8 order coef from 4index old */
1234 g_coef_v_new[ii * 8 + 4] = g_coef_v[ii][3]; /* calc 4index coef for 8 order coef from 3index old */
1235 g_coef_v_new[ii * 8 + 5] = g_coef_v[ii][2]; /* calc 5index coef for 8 order coef from 2index old */
1236 g_coef_v_new[ii * 8 + 6] = g_coef_v[ii][1]; /* calc 6index coef for 8 order coef from 1index old */
1237 g_coef_v_new[ii * 8 + 7] = g_coef_v[ii][0]; /* calc 7index coef for 8 order coef from 0index old */
1238 }
1239 }
1240
1241 /* send coef to DDR */
1242 gf_drv_set_g0zme_coef(g_coef_h_new, g_coef_v_new);
1243 }
1244
graphic_drv_enable_zme(hi_u32 layer,gf_g0_zme_cfg * zme_cfg,hi_bool enable_zme)1245 hi_bool graphic_drv_enable_zme(hi_u32 layer, gf_g0_zme_cfg *zme_cfg, hi_bool enable_zme)
1246 {
1247 gf_g0_zme_cfg cfg;
1248 hi_unused(layer);
1249
1250 if ((zme_cfg->in_width == 0) || (zme_cfg->in_height == 0) || (zme_cfg->out_width == 0) ||
1251 (zme_cfg->out_height == 0)) {
1252 return HI_FALSE;
1253 }
1254
1255 cfg.ck_gt_en = 1;
1256 cfg.out_pro = VDP_RMODE_PROGRESSIVE;
1257
1258 cfg.in_width = zme_cfg->in_width;
1259 cfg.in_height = zme_cfg->in_height;
1260 cfg.out_width = zme_cfg->out_width;
1261 cfg.out_height = zme_cfg->out_height;
1262 cfg.lhmid_en = 1;
1263 cfg.ahmid_en = 1;
1264 cfg.lhfir_mode = 1;
1265 cfg.ahfir_mode = 1;
1266 cfg.lvmid_en = 1;
1267 cfg.avmid_en = 1;
1268 cfg.lvfir_mode = 1;
1269 cfg.avfir_mode = 1;
1270
1271 if (enable_zme) {
1272 cfg.hfir_en = 1;
1273 cfg.vfir_en = 1;
1274
1275 gf_func_set_g0zme_mode(HAL_DISP_LAYER_GFX0, VDP_G0_ZME_TYP, &cfg);
1276
1277 /* It will be reset when VO exit, so config again */
1278 graphic_drv_vhd_coef_buf_addr_distribute(&g_hifb_coef_buf_addr);
1279 gf_vset_g0zme_coef(GF_RM_COEF_MODE_TYP);
1280 hal_para_set_para_up_vhd_chn(HIFB_COEF_BUF_G0ZME);
1281 } else {
1282 cfg.hfir_en = 0;
1283 cfg.vfir_en = 0;
1284
1285 gf_func_set_g0zme_mode(HAL_DISP_LAYER_GFX0, VDP_G0_ZME_TYP, &cfg);
1286 }
1287
1288 return HI_TRUE;
1289 }
1290
graphic_drv_dev_int_enable(hifb_vo_dev vo_dev,hi_bool enable)1291 hi_void graphic_drv_dev_int_enable(hifb_vo_dev vo_dev, hi_bool enable)
1292 {
1293 hifb_int_mask int_type;
1294
1295 switch (vo_dev) {
1296 case VO_DEV_DHD0:
1297 int_type = HIFB_INTMSK_DHD0_VTTHD2;
1298 break;
1299
1300 case VO_DEV_DHD1:
1301 int_type = HIFB_INTMSK_DHD1_VTTHD2;
1302 break;
1303
1304 default:
1305 return;
1306 }
1307
1308 if (enable == HI_TRUE) {
1309 fb_hal_disp_set_int_mask(int_type);
1310 } else {
1311 fb_hal_disp_clr_int_mask(int_type);
1312 }
1313
1314 return;
1315 }
1316
graphic_drv_int_clear(hi_u32 int_clear,hi_s32 irq)1317 hi_void graphic_drv_int_clear(hi_u32 int_clear, hi_s32 irq)
1318 {
1319 hi_unused(irq);
1320 /* vo double interrupt, read and mask use interrupt 1, but clear use interrupt 0 as video */
1321 fb_hal_disp_clear_int_status(int_clear);
1322 return;
1323 }
1324
graphic_drv_int_get_status(hi_void)1325 hi_u32 graphic_drv_int_get_status(hi_void)
1326 {
1327 return fb_hal_disp_get_int_status(HIFB_INTREPORT_ALL);
1328 }
1329
graphic_drv_clr_int_status(hi_u32 int_status)1330 hi_void graphic_drv_clr_int_status(hi_u32 int_status)
1331 {
1332 if (int_status & HIFB_INTMSK_DHD0_VTTHD2) {
1333 graphic_drv_int_clear(HIFB_INTMSK_DHD0_VTTHD2, VOU1_IRQ_NR);
1334 }
1335
1336 if (int_status & HIFB_INTMSK_DHD0_VTTHD3) {
1337 graphic_drv_int_clear(HIFB_INTMSK_DHD0_VTTHD3, VOU1_IRQ_NR);
1338 }
1339
1340 if (int_status & HIFB_INTMSK_DHD1_VTTHD2) {
1341 graphic_drv_int_clear(HIFB_INTMSK_DHD1_VTTHD2, VOU1_IRQ_NR);
1342 }
1343
1344 if (int_status & HIFB_INTMSK_DHD1_VTTHD3) {
1345 graphic_drv_int_clear(HIFB_INTMSK_DHD1_VTTHD3, VOU1_IRQ_NR);
1346 }
1347
1348 return;
1349 }
1350
graphic_drv_get_interrupt_dev(hi_u32 int_status,hifb_vo_dev * vo_dev)1351 hi_s32 graphic_drv_get_interrupt_dev(hi_u32 int_status, hifb_vo_dev *vo_dev)
1352 {
1353 if (int_status & HIFB_INTMSK_DHD0_VTTHD2) {
1354 graphics_drv_trace(HI_DBG_DEBUG, "Graphic: DHD0 INTERRUPT\n");
1355 graphic_drv_int_clear(HIFB_INTMSK_DHD0_VTTHD2, VOU1_IRQ_NR);
1356 *vo_dev = VO_DEV_DHD0;
1357 } else if (int_status & HIFB_INTMSK_DHD0_VTTHD3) {
1358 graphics_drv_trace(HI_DBG_DEBUG, "Graphic: DHD0 INTERRUPT\n");
1359 graphic_drv_int_clear(HIFB_INTMSK_DHD0_VTTHD3, VOU1_IRQ_NR);
1360 *vo_dev = VO_DEV_DHD0;
1361 } else if (int_status & HIFB_INTMSK_DHD1_VTTHD2) {
1362 graphics_drv_trace(HI_DBG_DEBUG, "Graphic: DHD1 INTERRUPT\n");
1363 graphic_drv_int_clear(HIFB_INTMSK_DHD1_VTTHD2, VOU1_IRQ_NR);
1364 *vo_dev = VO_DEV_DHD1;
1365 } else if (int_status & HIFB_INTMSK_DHD1_VTTHD3) {
1366 graphics_drv_trace(HI_DBG_DEBUG, "Graphic: DHD1 INTERRUPT\n");
1367 graphic_drv_int_clear(HIFB_INTMSK_DHD1_VTTHD3, VOU1_IRQ_NR);
1368 *vo_dev = VO_DEV_DHD1;
1369 } else {
1370 return HI_FAILURE;
1371 }
1372 return HI_SUCCESS;
1373 }
1374