1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * 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, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include "vou.h"
20 #include "vou_drv.h"
21 #include "vou_hal.h"
22 #include <cpu_func.h>
23
24 /* for debug,bootlogo.dat is a bin file(image) #include "bootlogo.dat" */
25 static hi_u32 g_bg_color = 0xFF; /* 0xFF default blue */
26 static hi_bool g_inited = HI_FALSE;
27 static hi_rect g_max_rect = {0};
28
29 #define align_back(x, a) ((a) * (((x) / (a))))
30
vo_dcache_range(hi_phys_addr_t start_addr,hi_u64 size)31 static hi_void vo_dcache_range(hi_phys_addr_t start_addr, hi_u64 size)
32 {
33 if (dcache_status()) {
34 flush_dcache_range(start_addr, start_addr + size);
35 }
36 }
37
gfx_convert_layer(unsigned int layer)38 static unsigned int gfx_convert_layer(unsigned int layer)
39 {
40 unsigned int gfx_layer;
41
42 /* hard cursor is not supported. */
43 switch (layer) {
44 case 0: /* 0 layer */
45 gfx_layer = VO_LAYER_G0;
46 break;
47
48 default:
49 gfx_layer = VO_LAYER_G0;
50 break;
51 }
52
53 return gfx_layer;
54 }
55
gfx_convert_to_hal_layer(unsigned int layer)56 static hal_disp_layer gfx_convert_to_hal_layer(unsigned int layer)
57 {
58 hal_disp_layer hal_gfx_layer;
59
60 /* hard cursor is not supported. */
61 switch (layer) {
62 case 0: /* 0 layer */
63 hal_gfx_layer = HAL_DISP_LAYER_GFX0;
64 break;
65
66 default:
67 hal_gfx_layer = HAL_DISP_LAYER_GFX0;
68 break;
69 }
70
71 return hal_gfx_layer;
72 }
73
video_layer_convert_to_hal(unsigned int layer)74 static hal_disp_layer video_layer_convert_to_hal(unsigned int layer)
75 {
76 hal_disp_layer hal_video_layer;
77
78 /* hard cursor is not supported. */
79 switch (layer) {
80 case 0: /* 0 layer */
81 hal_video_layer = HAL_DISP_LAYER_VHD0;
82 break;
83
84 default:
85 hal_video_layer = HAL_DISP_LAYER_VHD0;
86 break;
87 }
88
89 return hal_video_layer;
90 }
91
set_vobg(unsigned int dev,unsigned int rgb)92 int set_vobg(unsigned int dev, unsigned int rgb)
93 {
94 if (dev < 1) {
95 g_bg_color = rgb;
96 }
97
98 return 0;
99 }
100
vo_set_disp_max_size(vo_hal_dev vo_dev,vo_intf_sync vo_out_mode)101 hi_void vo_set_disp_max_size(vo_hal_dev vo_dev, vo_intf_sync vo_out_mode)
102 {
103 /* default is 720x576 */
104 hi_u32 max_width = 720;
105 hi_u32 max_height = 576;
106
107 /* to get the width and height of the sync, not magic num */
108 switch (vo_out_mode) {
109 case VO_OUTPUT_PAL:
110 case VO_OUTPUT_576P50:
111 max_width = 720;
112 max_height = 576;
113 break;
114
115 case VO_OUTPUT_NTSC:
116 case VO_OUTPUT_480P60:
117 max_width = 720;
118 max_height = 480;
119 break;
120
121 case VO_OUTPUT_720P60:
122 case VO_OUTPUT_720P50:
123 max_width = 1280;
124 max_height = 720;
125 break;
126
127 case VO_OUTPUT_1080I50:
128 case VO_OUTPUT_1080I60:
129 case VO_OUTPUT_1080P24:
130 case VO_OUTPUT_1080P25:
131 case VO_OUTPUT_1080P30:
132 case VO_OUTPUT_1080P50:
133 case VO_OUTPUT_1080P60:
134 max_width = 1920;
135 max_height = 1080;
136 break;
137
138 case VO_OUTPUT_800x600_60:
139 case VO_OUTPUT_800x600_50:
140 max_width = 800;
141 max_height = 600;
142 break;
143
144 case VO_OUTPUT_1024x768_60:
145 max_width = 1024;
146 max_height = 768;
147 break;
148
149 case VO_OUTPUT_1280x1024_60:
150 max_width = 1280;
151 max_height = 1024;
152 break;
153
154 case VO_OUTPUT_1366x768_60:
155 max_width = 1366;
156 max_height = 768;
157 break;
158
159 case VO_OUTPUT_1440x900_60:
160 max_width = 1440;
161 max_height = 900;
162 break;
163
164 case VO_OUTPUT_1280x800_60:
165 max_width = 1280;
166 max_height = 800;
167 break;
168
169 case VO_OUTPUT_1600x1200_60:
170 max_width = 1600;
171 max_height = 1200;
172 break;
173
174 case VO_OUTPUT_1680x1050_60:
175 max_width = 1680;
176 max_height = 1050;
177 break;
178
179 case VO_OUTPUT_1920x1200_60:
180 max_width = 1920;
181 max_height = 1200;
182 break;
183
184 case VO_OUTPUT_640x480_60:
185 max_width = 640;
186 max_height = 480;
187 break;
188
189 case VO_OUTPUT_1920x2160_30:
190 max_width = 1920;
191 max_height = 2160;
192 break;
193
194 case VO_OUTPUT_2560x1440_30:
195 case VO_OUTPUT_2560x1440_60:
196 max_width = 2560;
197 max_height = 1440;
198 break;
199
200 case VO_OUTPUT_2560x1600_60:
201 max_width = 2560;
202 max_height = 1600;
203 break;
204
205 case VO_OUTPUT_3840x2160_24:
206 case VO_OUTPUT_3840x2160_25:
207 case VO_OUTPUT_3840x2160_30:
208 case VO_OUTPUT_3840x2160_50:
209 case VO_OUTPUT_3840x2160_60:
210 max_width = 3840;
211 max_height = 2160;
212 break;
213
214 case VO_OUTPUT_4096x2160_24:
215 case VO_OUTPUT_4096x2160_25:
216 case VO_OUTPUT_4096x2160_30:
217 case VO_OUTPUT_4096x2160_50:
218 case VO_OUTPUT_4096x2160_60:
219 max_width = 4096;
220 max_height = 2160;
221 break;
222
223 case VO_OUTPUT_320x240_50:
224 case VO_OUTPUT_320x240_60: /* just for hi3518ev200 hi3519 */
225 max_width = 320;
226 max_height = 240;
227 break;
228
229 case VO_OUTPUT_240x320_50: /* just for hi3518ev200 hi3519 */
230 case VO_OUTPUT_240x320_60:
231 max_width = 240;
232 max_height = 320;
233 break;
234
235 case VO_OUTPUT_720x1280_60:
236 max_width = 720;
237 max_height = 1280;
238 break;
239
240 case VO_OUTPUT_1080x1920_60:
241 max_width = 1080;
242 max_height = 1920;
243 break;
244
245 case VO_OUTPUT_7680x4320_30:
246 max_width = 7680;
247 max_height = 4320;
248 break;
249
250 default:
251 max_width = 4096;
252 max_height = 2160;
253 }
254
255 g_max_rect.width = max_width;
256 g_max_rect.height = max_height;
257 }
258
start_vo(unsigned int dev,unsigned int type,unsigned int sync)259 int start_vo(unsigned int dev, unsigned int type, unsigned int sync)
260 {
261 if (g_inited == HI_FALSE) {
262 sys_hal_vo_bus_reset_sel(HI_FALSE);
263 /* open clk */
264 vo_drv_set_all_crg_clk(HI_TRUE);
265 vo_drv_board_init();
266 hal_sys_control();
267
268 g_inited = HI_TRUE;
269 }
270
271 sys_hal_vo_dev_clk_en(dev, HI_TRUE);
272 sys_hal_vo_core_clk_en(dev, HI_TRUE);
273
274 vo_drv_def_layer_bind_dev();
275 vo_set_disp_max_size(dev, sync);
276 vo_drv_set_dev_intf_type(dev, type);
277 vo_drv_set_dev_out_sync(dev, sync);
278
279 vo_drv_set_dev_bk_grd(dev, g_bg_color);
280
281 vo_drv_set_dev_clk(dev);
282 vo_drv_open(dev);
283 return 0;
284 }
285
stop_vo(unsigned int dev)286 int stop_vo(unsigned int dev)
287 {
288 vo_drv_close(dev);
289 sys_hal_vo_dev_clk_en(dev, HI_FALSE);
290 return 0;
291 }
292
vo_get_videolayer_csc_matric(vo_intf_type intf_type,vo_csc_matrix * csc_matrix)293 static void vo_get_videolayer_csc_matric(vo_intf_type intf_type, vo_csc_matrix *csc_matrix)
294 {
295 if (intf_type == VO_INTF_BT1120) {
296 *csc_matrix = VO_CSC_MATRIX_IDENTITY;
297 } else if ((intf_type == VO_INTF_LCD_6BIT) ||
298 (intf_type == VO_INTF_LCD_8BIT) ||
299 (intf_type == VO_INTF_LCD_16BIT)) {
300 *csc_matrix = VO_CSC_MATRIX_BT709_TO_RGB_PC;
301 }
302 }
303
start_videolayer(unsigned int layer,unsigned long addr,unsigned int strd,hi_vo_rect layer_rect)304 int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect layer_rect)
305 {
306 int i;
307 hi_rect disp_rect = { layer_rect.x, layer_rect.y, layer_rect.w, layer_rect.h };
308 hal_disp_layer vo_layer;
309 const hfir_coef coef = { 42, -10, -20, 28, -40, 61, -107, 330 }; /* hfir coef */
310
311 vo_intf_type intf_type;
312
313 vdp_vid_ip_cfg vid_cfg = {0};
314 vo_csc_matrix csc_matrix = VO_CSC_MATRIX_IDENTITY;
315
316 vo_dcache_range(addr, strd * layer_rect.h * 3 / 2); /* 3 / 2 times */
317
318 vo_layer = video_layer_convert_to_hal(layer);
319 hal_layer_set_layer_data_fmt(vo_layer, VO_LAYER_PIXERL_FORMAT_SP_Y_CB_CR_420);
320 vdp_fdr_vid_set_chm_copy_en(vo_layer, HI_TRUE);
321 intf_type = vo_drv_get_dev_intf_type(vo_layer);
322 vo_get_videolayer_csc_matric(intf_type, &csc_matrix);
323
324 vo_drv_video_set_csc_coef(vo_layer, csc_matrix);
325 hal_layer_set_csc_en(vo_layer, HI_TRUE);
326
327 for (i = 0; i < HAL_DISP_LAYER_VHD1; i++) {
328 hal_video_set_layer_alpha(i, 255); /* 255 max alpha */
329 hal_video_set_hfir_mode(i, HAL_HFIRMODE_COPY);
330 hal_video_hfir_set_coef(i, &coef);
331 hal_video_hfir_set_mid_en(i, HI_TRUE);
332 }
333
334 hal_video_hfir_set_ck_gt_en(vo_layer, HI_TRUE);
335 hal_video_set_layer_disp_rect(vo_layer, &disp_rect);
336 hal_video_set_layer_video_rect(vo_layer, &disp_rect);
337 hal_layer_set_layer_in_rect(vo_layer, &disp_rect);
338 hal_layer_set_layer_galpha(vo_layer, 255); /* 255 max alpha */
339 hal_layer_set_src_resolution(vo_layer, &disp_rect);
340 hal_layer_set_zme_enable(vo_layer, HAL_DISP_ZMEMODE_ALL, HI_FALSE);
341
342 vid_cfg.csc_en = 0;
343 vid_cfg.hfir_en = 1;
344 vid_cfg.vid_iw = disp_rect.width;
345 vid_cfg.vid_ih = disp_rect.height;
346 vid_cfg.vid_ow = disp_rect.width;
347 vid_cfg.vid_oh = disp_rect.height;
348 vid_cfg.zme_en = HI_FALSE;
349 vo_vid_set_zme_enable(vo_layer, &vid_cfg);
350 hal_layer_set_zme_info(vo_layer, disp_rect.width, disp_rect.height, HAL_DISP_ZME_OUTFMT420);
351
352 /* area 0 */
353 hal_video_set_multi_area_l_addr(vo_layer, 0, addr, strd);
354 hal_video_set_multi_area_c_addr(vo_layer, 0, addr + layer_rect.h * align_back(layer_rect.w, 8), strd); /* align 8 */
355
356 hal_layer_enable_layer(vo_layer, HI_TRUE);
357 hal_layer_set_reg_up(vo_layer);
358
359 return 0;
360 }
361
stop_videolayer(unsigned int layer)362 int stop_videolayer(unsigned int layer)
363 {
364 hal_disp_layer hal_video_layer;
365
366 hal_video_layer = video_layer_convert_to_hal(layer);
367
368 hal_layer_enable_layer(hal_video_layer, HI_FALSE);
369 hal_layer_set_reg_up(hal_video_layer);
370
371 return 0;
372 }
373
start_gx(unsigned int layer,unsigned long addr,unsigned int strd,hi_vo_rect gx_rect)374 int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect gx_rect)
375 {
376 osd_logo_t scroll_image_logo = {0};
377 hi_vo_layer vo_layer;
378 vo_intf_type intf_type;
379 vo_csc gfx_csc;
380 csc_coef_param csc_coef;
381
382 vo_layer = gfx_convert_layer(layer);
383 intf_type = vo_drv_get_dev_intf_type(layer);
384 load_bmp(addr, &scroll_image_logo);
385 hi_rect disp_rect = { gx_rect.x, gx_rect.y, scroll_image_logo.width, scroll_image_logo.height };
386
387 vo_dcache_range(scroll_image_logo.rgb_buffer, strd * gx_rect.h);
388
389 hal_graphic_set_gfx_ext(vo_layer, HAL_GFX_BITEXTEND_3RD);
390 hal_graphic_set_gfx_palpha(vo_layer, HI_TRUE, HI_TRUE, 0xff, 0xff);
391 hal_layer_set_layer_galpha(vo_layer, 0xff);
392 hal_graphic_set_gfx_pre_mult(vo_layer, HI_FALSE);
393
394 /* for mipi_tx, do not do this two line. */
395 if ((VO_INTF_BT1120 & intf_type) || (VO_INTF_BT656 & intf_type)) {
396 gfx_csc.csc_matrix = VO_CSC_MATRIX_RGB_TO_BT709_PC;
397 gfx_csc.luma = 50; /* 50 default value */
398 gfx_csc.contrast = 50; /* 50 default value */
399 gfx_csc.hue = 50; /* 50 default value */
400 gfx_csc.satuature = 50; /* 50 default value */
401
402 csc_coef.csc_scale2p = GFX_CSC_SCALE;
403 csc_coef.csc_clip_min = GFX_CSC_CLIP_MIN;
404 csc_coef.csc_clip_max = GFX_CSC_CLIP_MAX;
405
406 /* do rgb to yuv. */
407 graphic_drv_set_csc_coef(vo_layer, &gfx_csc, &csc_coef);
408 hal_layer_set_csc_en(vo_layer, HI_TRUE);
409 } else if ((intf_type == VO_INTF_LCD_6BIT) ||
410 (intf_type == VO_INTF_LCD_8BIT) ||
411 (intf_type == VO_INTF_LCD_16BIT)) {
412 /* do yuv to rgb or do nothing. */
413 hal_layer_set_csc_en(vo_layer, HI_FALSE);
414 }
415
416 hal_graphic_set_gfx_addr (vo_layer, (hi_u64)(hi_u32)scroll_image_logo.rgb_buffer);
417 hal_graphic_set_gfx_stride(vo_layer, (scroll_image_logo.stride) >> 4); /* 4 to set register */
418
419 hal_layer_set_layer_in_rect(vo_layer, &disp_rect);
420 hal_video_set_layer_disp_rect(vo_layer, &disp_rect);
421 hal_video_set_layer_video_rect(vo_layer, &disp_rect);
422 hal_gfx_set_src_resolution(vo_layer, &disp_rect);
423 hal_layer_set_layer_data_fmt(vo_layer, HAL_INPUTFMT_ARGB_1555);
424 hal_layer_enable_layer(vo_layer, HI_TRUE);
425 hal_layer_set_reg_up(vo_layer);
426
427 return 0;
428 }
429
stop_gx(unsigned int layer)430 int stop_gx(unsigned int layer)
431 {
432 hi_vo_layer vo_layer;
433 hal_disp_layer hal_gfx_layer;
434
435 vo_layer = gfx_convert_layer(layer);
436 hal_gfx_layer = gfx_convert_to_hal_layer(layer);
437
438 hal_layer_set_reg_up(vo_layer);
439 hal_layer_enable_layer(vo_layer, HI_FALSE);
440 hal_layer_set_reg_up(hal_gfx_layer);
441
442 return 0;
443 }
444
445