• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "graphics_drv.h"
19 #include "proc_ext.h"
20 
21 #include "vou_graphics.h"
22 
23 #include "vou.h"
24 #include "mm_ext.h"
25 
26 #define GFX_CSC_SCALE    0xd
27 #define GFX_CSC_CLIP_MIN 0x0
28 #define GFX_CSC_CLIP_MAX 0x3ff
29 
graphic_drv_get_hal_layer(hi_u32 layer,hal_disp_layer * hal_layer)30 hi_s32 graphic_drv_get_hal_layer(hi_u32 layer, hal_disp_layer *hal_layer)
31 {
32     switch (layer) {
33         case GX_LAYER_INDEX0: {
34             *hal_layer = HAL_DISP_LAYER_GFX0;
35             break;
36         }
37         default: {
38             return HI_FAILURE;
39         }
40     }
41 
42     return HI_SUCCESS;
43 }
44 
graphic_drv_get_layer_index(hal_disp_layer hal_layer,hi_u32 * layer)45 hi_s32 graphic_drv_get_layer_index(hal_disp_layer hal_layer, hi_u32 *layer)
46 {
47     switch (hal_layer) {
48         case HAL_DISP_LAYER_GFX0: {
49             *layer = GX_LAYER_INDEX0;
50             break;
51         }
52         default: {
53             return HI_ERR_VO_GFX_INVALID_ID;
54         }
55     }
56 
57     return HI_SUCCESS;
58 }
59 
60 /* graphic bind */
graphic_drv_check_graphic_bind_support(hi_graphic_layer gfx_layer,hi_vo_dev dev)61 hi_s32 graphic_drv_check_graphic_bind_support(hi_graphic_layer gfx_layer, hi_vo_dev dev)
62 {
63     vo_err_trace("graphics layer %d not support bind dev %d!\n", gfx_layer, dev);
64     return HI_ERR_VO_NOT_SUPPORT;
65 }
66 
graphic_drv_graphic_bind_dev(hi_graphic_layer gfx_layer,hi_vo_dev dev)67 hi_s32 graphic_drv_graphic_bind_dev(hi_graphic_layer gfx_layer, hi_vo_dev dev)
68 {
69     hi_unused(gfx_layer);
70     hi_unused(dev);
71     return HI_SUCCESS;
72 }
73 
graphic_drv_graphic_un_bind_dev(hi_graphic_layer gfx_layer)74 hi_s32 graphic_drv_graphic_un_bind_dev(hi_graphic_layer gfx_layer)
75 {
76     hi_unused(gfx_layer);
77     return HI_SUCCESS;
78 }
79 
graphic_drv_lock_init(hi_void)80 hi_s32 graphic_drv_lock_init(hi_void)
81 {
82     hi_s32 i;
83     vo_gfxlayer_context *gfx_layer_ctx = HI_NULL;
84 
85     for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
86         gfx_layer_ctx = vou_graphics_get_layer_ctx(i);
87         (hi_void)memset_s(gfx_layer_ctx, sizeof(vo_gfxlayer_context), 0, sizeof(vo_gfxlayer_context));
88         gfx_spin_lock_init(&gfx_layer_ctx->spin_lock);
89     }
90     return HI_SUCCESS;
91 }
92 
graphic_drv_lock_exit(hi_void)93 hi_s32 graphic_drv_lock_exit(hi_void)
94 {
95     hi_s32 i;
96     vo_gfxlayer_context *gfx_layer_ctx = HI_NULL;
97     for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
98         gfx_layer_ctx = vou_graphics_get_layer_ctx(i);
99         gfx_spin_lock_deinit(&gfx_layer_ctx->spin_lock);
100     }
101 
102     return HI_SUCCESS;
103 }
104 
graphic_drv_init(hi_void)105 hi_s32 graphic_drv_init(hi_void)
106 {
107     hi_s32 i;
108     vo_gfxlayer_context *gfx_ctx = HI_NULL;
109 
110     for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
111         gfx_ctx = vou_graphics_get_layer_ctx(i);
112 
113         gfx_ctx->layer_id = HAL_DISP_LAYER_GFX0 + i; /* HAL_DISP_LAYER_GFX0+1 */
114         gfx_ctx->binded_dev = i; /* 0 */
115         gfx_ctx->binded = HI_TRUE;
116         gfx_ctx->vo_gfx_attr.dst_dynamic_range = DYNAMIC_RANGE_BUTT;
117     }
118 
119     for (i = 0; i < VO_MAX_GRAPHICS_LAYER_NUM; ++i) {
120         gfx_ctx = vou_graphics_get_layer_ctx(i);
121         gfx_ctx->gfx_csc.csc_matrix = VO_CSC_MATRIX_RGB_TO_BT601_TV;
122         gfx_ctx->gfx_csc.luma = VO_CSC_DEF_VAL;
123         gfx_ctx->gfx_csc.contrast = VO_CSC_DEF_VAL;
124         gfx_ctx->gfx_csc.hue = VO_CSC_DEF_VAL;
125         gfx_ctx->gfx_csc.satuature = VO_CSC_DEF_VAL;
126 
127         gfx_ctx->csc_param.csc_scale2p = GFX_CSC_SCALE;
128         gfx_ctx->csc_param.csc_clip_min = GFX_CSC_CLIP_MIN;
129         gfx_ctx->csc_param.csc_clip_max = GFX_CSC_CLIP_MAX;
130     }
131 
132     return HI_SUCCESS;
133 }
134 
graphic_drv_exit(hi_void)135 hi_s32 graphic_drv_exit(hi_void)
136 {
137     return HI_SUCCESS;
138 }
139 
graphic_drv_is_chip_support_csc(hi_void)140 hi_bool graphic_drv_is_chip_support_csc(hi_void)
141 {
142     return HI_TRUE;
143 }
144 
graphic_drv_get_csc_matrix(hal_csc_mode csc_mode,const csc_coef ** csc_tmp)145 static hi_s32 graphic_drv_get_csc_matrix(hal_csc_mode csc_mode, const csc_coef **csc_tmp)
146 {
147     switch (csc_mode) {
148         case HAL_CSC_MODE_RGB_TO_RGB:
149         case HAL_CSC_MODE_RGB_TO_BT601_PC:
150         case HAL_CSC_MODE_RGB_TO_BT709_PC:
151         case HAL_CSC_MODE_RGB_TO_BT601_TV:
152         case HAL_CSC_MODE_RGB_TO_BT709_TV:
153             *csc_tmp = vo_get_csc_coef(csc_mode);
154             break;
155         default:
156             return HI_FAILURE;
157     }
158 
159     return HI_SUCCESS;
160 }
161 
graphic_drv_calculate_rgb2yuv(hal_csc_value * csc_value,const csc_coef * csc_tmp,csc_coef * coef)162 static hi_void graphic_drv_calculate_rgb2yuv(hal_csc_value *csc_value, const csc_coef *csc_tmp, csc_coef *coef)
163 {
164     hi_s32 luma;
165     hi_s32 contrast;
166     hi_s32 hue;
167     hi_s32 satu;
168     hi_s32 csc_value_times = 100;
169     hi_s32 table_times = 1000;
170     hi_s32 square_cv_times = csc_value_times * csc_value_times;
171     const int *cos_table = vo_get_cos_table();
172     const int *sin_table = vo_get_sin_table();
173 
174     luma = csc_value->luma;
175     contrast = csc_value->cont;
176     hue = csc_value->hue;
177     satu = csc_value->satu;
178 
179     coef->csc_coef00 = (contrast * csc_tmp->csc_coef00) / csc_value_times;
180     coef->csc_coef01 = (contrast * csc_tmp->csc_coef01) / csc_value_times;
181     coef->csc_coef02 = (contrast * csc_tmp->csc_coef02) / csc_value_times;
182     coef->csc_coef10 = (contrast * satu * ((csc_tmp->csc_coef10 * cos_table[hue] + csc_tmp->csc_coef20 *
183                                                 sin_table[hue]) / table_times)) / square_cv_times;
184     coef->csc_coef11 = (contrast * satu * ((csc_tmp->csc_coef11 * cos_table[hue] + csc_tmp->csc_coef21 *
185                                                 sin_table[hue]) / table_times)) / square_cv_times;
186     coef->csc_coef12 = (contrast * satu * ((csc_tmp->csc_coef12 * cos_table[hue] + csc_tmp->csc_coef22 *
187                                                 sin_table[hue]) / table_times)) / square_cv_times;
188     coef->csc_coef20 = (contrast * satu * ((csc_tmp->csc_coef20 * cos_table[hue] - csc_tmp->csc_coef10 *
189                                                 sin_table[hue]) / table_times)) / square_cv_times;
190     coef->csc_coef21 = (contrast * satu * ((csc_tmp->csc_coef21 * cos_table[hue] - csc_tmp->csc_coef11 *
191                                                 sin_table[hue]) / table_times)) / square_cv_times;
192     coef->csc_coef22 = (contrast * satu * ((csc_tmp->csc_coef22 * cos_table[hue] - csc_tmp->csc_coef12 *
193                                                 sin_table[hue]) / table_times)) / square_cv_times;
194     coef->csc_out_dc0 += luma;
195 }
196 
graphic_drv_calc_csc_matrix(hi_vo_csc * csc,hal_csc_mode csc_mode,csc_coef * coef)197 hi_void graphic_drv_calc_csc_matrix(hi_vo_csc *csc, hal_csc_mode csc_mode, csc_coef *coef)
198 {
199     hi_s32 ret;
200     hal_csc_value csc_value;
201     const csc_coef *csc_tmp = HI_NULL;
202 
203     csc_value.luma = (hi_s32)csc->luma * 64 / 100 - 32;
204     csc_value.cont = ((hi_s32)csc->contrast - 50) * 2 + 100;
205     csc_value.hue = (hi_s32)csc->hue * 60 / 100;
206     csc_value.satu = ((hi_s32)csc->satuature - 50) * 2 + 100;
207 
208     ret = graphic_drv_get_csc_matrix(csc_mode, &csc_tmp);
209     if (ret != HI_SUCCESS) {
210         return;
211     }
212 
213     coef->csc_in_dc0 = csc_tmp->csc_in_dc0;
214     coef->csc_in_dc1 = csc_tmp->csc_in_dc1;
215     coef->csc_in_dc2 = csc_tmp->csc_in_dc2;
216     coef->csc_out_dc0 = csc_tmp->csc_out_dc0;
217     coef->csc_out_dc1 = csc_tmp->csc_out_dc1;
218     coef->csc_out_dc2 = csc_tmp->csc_out_dc2;
219 
220     graphic_drv_calculate_rgb2yuv(&csc_value, csc_tmp, coef);
221 
222     return;
223 }
224 
graphic_drv_get_layer_enable(hal_disp_layer gfx_layer)225 hi_bool graphic_drv_get_layer_enable(hal_disp_layer gfx_layer)
226 {
227     hi_bool enable = HI_FALSE;
228     hal_layer_get_layer_enable(gfx_layer, &enable);
229     return enable;
230 }
231 
graphic_drv_check_csc_coef(hal_disp_layer gfx_layer,hi_vo_csc * gfx_csc)232 hi_s32 graphic_drv_check_csc_coef(hal_disp_layer gfx_layer, hi_vo_csc *gfx_csc)
233 {
234     hi_unused(gfx_layer);
235 
236     if ((gfx_csc->csc_matrix != VO_CSC_MATRIX_IDENTITY) &&
237         (gfx_csc->csc_matrix != VO_CSC_MATRIX_RGB_TO_BT601_PC) &&
238         (gfx_csc->csc_matrix != VO_CSC_MATRIX_RGB_TO_BT709_PC) &&
239         (gfx_csc->csc_matrix != VO_CSC_MATRIX_RGB_TO_BT601_TV) &&
240         (gfx_csc->csc_matrix != VO_CSC_MATRIX_RGB_TO_BT709_TV)) {
241         vo_err_trace("vo CSC matrix type(%d) should be rgb to bt601/bt709 only!\n", gfx_csc->csc_matrix);
242         return HI_ERR_VO_ILLEGAL_PARAM;
243     }
244 
245     if (gfx_csc->contrast > VO_CSC_LUMA_MAX) {
246         vo_err_trace("vo device CSC contrast value %d out of range!\n", gfx_csc->contrast);
247         return HI_ERR_VO_ILLEGAL_PARAM;
248     }
249 
250     if (gfx_csc->hue > VO_CSC_LUMA_MAX) {
251         vo_err_trace("vo device CSC hue value %d out of range!\n", gfx_csc->hue);
252         return HI_ERR_VO_ILLEGAL_PARAM;
253     }
254 
255     if (gfx_csc->luma > VO_CSC_LUMA_MAX) {
256         vo_err_trace("vo device CSC luma value %d out of range!\n", gfx_csc->luma);
257         return HI_ERR_VO_ILLEGAL_PARAM;
258     }
259 
260     if (gfx_csc->satuature > VO_CSC_LUMA_MAX) {
261         vo_err_trace("vo device CSC satuature value %d out of range!\n", gfx_csc->satuature);
262         return HI_ERR_VO_ILLEGAL_PARAM;
263     }
264 
265     return HI_SUCCESS;
266 }
267 
graphic_drv_get_hal_csc_mode(hi_vo_csc_matrix csc_matrix,hal_csc_mode * csc_mode)268 static hi_s32 graphic_drv_get_hal_csc_mode(hi_vo_csc_matrix csc_matrix, hal_csc_mode *csc_mode)
269 {
270     switch (csc_matrix) {
271         case VO_CSC_MATRIX_RGB_TO_BT601_PC:
272             *csc_mode = HAL_CSC_MODE_RGB_TO_BT601_PC;
273             break;
274         case VO_CSC_MATRIX_RGB_TO_BT709_PC:
275             *csc_mode = HAL_CSC_MODE_RGB_TO_BT709_PC;
276             break;
277         case VO_CSC_MATRIX_RGB_TO_BT601_TV:
278             *csc_mode = HAL_CSC_MODE_RGB_TO_BT601_TV;
279             break;
280         case VO_CSC_MATRIX_RGB_TO_BT709_TV:
281             *csc_mode = HAL_CSC_MODE_RGB_TO_BT709_TV;
282             break;
283         case VO_CSC_MATRIX_IDENTITY:
284             *csc_mode = HAL_CSC_MODE_RGB_TO_RGB;
285             break;
286         default:
287             vo_err_trace("csc_matrix %d err, should only be RGB to YUV matrix\n", csc_matrix);
288             return HI_ERR_VO_ILLEGAL_PARAM;
289     }
290 
291     return HI_SUCCESS;
292 }
293 
graphic_drv_set_csc_coef(hal_disp_layer gfx_layer,hi_vo_csc * gfx_csc,csc_coef_param * csc_param)294 hi_s32 graphic_drv_set_csc_coef(hal_disp_layer gfx_layer, hi_vo_csc *gfx_csc, csc_coef_param *csc_param)
295 {
296     hi_s32 ret;
297     csc_coef coef;
298     hal_csc_mode csc_mode;
299 
300     hi_u32 pre = 8;
301     hi_u32 dc_pre = 4;
302 
303     hi_u32 layer_index;
304     vo_gfxlayer_context *gfx_layer_ctx = HI_NULL;
305 
306     if (graphic_drv_get_layer_index(gfx_layer, &layer_index) != HI_SUCCESS) {
307         vo_err_trace("gfx_layer(%u) is invalid!\n", (hi_u32)gfx_layer);
308         return HI_ERR_VO_GFX_INVALID_ID;
309     }
310 
311     ret = graphic_drv_get_hal_csc_mode(gfx_csc->csc_matrix, &csc_mode);
312     if (ret != HI_SUCCESS) {
313         return ret;
314     }
315 
316     graphic_drv_calc_csc_matrix(gfx_csc, csc_mode, &coef);
317 
318     coef.new_csc_clip_max = GFX_CSC_CLIP_MAX;
319     coef.new_csc_clip_min = GFX_CSC_CLIP_MIN;
320     coef.new_csc_scale2p = GFX_CSC_SCALE;
321 
322     coef.csc_coef00 = (hi_s32)pre * coef.csc_coef00 * 1024 / 1000;
323     coef.csc_coef01 = (hi_s32)pre * coef.csc_coef01 * 1024 / 1000;
324     coef.csc_coef02 = (hi_s32)pre * coef.csc_coef02 * 1024 / 1000;
325     coef.csc_coef10 = (hi_s32)pre * coef.csc_coef10 * 1024 / 1000;
326     coef.csc_coef11 = (hi_s32)pre * coef.csc_coef11 * 1024 / 1000;
327     coef.csc_coef12 = (hi_s32)pre * coef.csc_coef12 * 1024 / 1000;
328     coef.csc_coef20 = (hi_s32)pre * coef.csc_coef20 * 1024 / 1000;
329     coef.csc_coef21 = (hi_s32)pre * coef.csc_coef21 * 1024 / 1000;
330     coef.csc_coef22 = (hi_s32)pre * coef.csc_coef22 * 1024 / 1000;
331 
332     coef.csc_in_dc0 = (hi_s32)dc_pre * coef.csc_in_dc0;
333     coef.csc_in_dc1 = (hi_s32)dc_pre * coef.csc_in_dc1;
334     coef.csc_in_dc2 = (hi_s32)dc_pre * coef.csc_in_dc2;
335 
336     coef.csc_out_dc0 = (hi_s32)dc_pre * coef.csc_out_dc0;
337     coef.csc_out_dc1 = (hi_s32)dc_pre * coef.csc_out_dc1;
338     coef.csc_out_dc2 = (hi_s32)dc_pre * coef.csc_out_dc2;
339 
340     hal_layer_set_csc_coef(gfx_layer, &coef);
341 
342     gfx_layer_ctx = vou_graphics_get_layer_ctx(layer_index);
343 
344     (hi_void)memcpy_s(&gfx_layer_ctx->gfx_csc, sizeof(hi_vo_csc), gfx_csc, sizeof(hi_vo_csc));
345     (hi_void)memcpy_s(&gfx_layer_ctx->csc_param, sizeof(csc_coef_param), csc_param, sizeof(csc_coef_param));
346 
347     return HI_SUCCESS;
348 }
349 
graphic_drv_show_proc(osal_proc_entry_t * s)350 hi_s32 graphic_drv_show_proc(osal_proc_entry_t *s)
351 {
352     hi_unused(s);
353     return HI_SUCCESS;
354 }
355 
356