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