• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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