• 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 static hi_u32 g_bg_color[2] = { 0xFF, 0xFF }; /* 2 devices 0xFF default blue */
25 
26 static hi_bool g_inited = HI_FALSE;
27 static hi_rect g_max_rect = {0};
28 
29 #define vo_align(val, align) (((val) + (align) - 1) & (~((align) - 1)))
30 
vo_dcache_range(unsigned long start_addr,hi_u64 size)31 static hi_void vo_dcache_range(unsigned long 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         case 1: /* 1 layer */
48             gfx_layer = VO_LAYER_G1;
49             break;
50         default:
51             gfx_layer = VO_LAYER_G0;
52             break;
53     }
54     return gfx_layer;
55 }
56 
gfx_convert_to_hal_layer(unsigned int layer)57 static hal_disp_layer gfx_convert_to_hal_layer(unsigned int layer)
58 {
59     hal_disp_layer hal_gfx_layer;
60 
61     /* hard cursor is not supported. */
62     switch (layer) {
63         case 0: /* 0 layer */
64             hal_gfx_layer = HAL_DISP_LAYER_GFX0;
65             break;
66         case 1: /* 1 layer */
67             hal_gfx_layer = HAL_DISP_LAYER_GFX1;
68             break;
69         default:
70             hal_gfx_layer = HAL_DISP_LAYER_GFX0;
71             break;
72     }
73     return hal_gfx_layer;
74 }
video_layer_convert(unsigned int layer)75 static hi_vo_layer video_layer_convert(unsigned int layer)
76 {
77     hi_vo_layer video_layer;
78 
79     /* hard cursor is not supported. */
80     switch (layer) {
81         case 0: /* 0 layer */
82             video_layer = VO_LAYER_VHD0;
83             break;
84         case 1: /* 1 layer */
85             video_layer = VO_LAYER_VHD1;
86             break;
87         default:
88             video_layer = VO_LAYER_VHD0;
89             break;
90     }
91     return video_layer;
92 }
93 
video_layer_convert_to_hal(unsigned int layer)94 static hal_disp_layer video_layer_convert_to_hal(unsigned int layer)
95 {
96     hal_disp_layer hal_video_layer;
97 
98     /* hard cursor is not supported. */
99     switch (layer) {
100         case 0: /* 0 layer */
101             hal_video_layer = HAL_DISP_LAYER_VHD0;
102             break;
103         case 1: /* 1 layer */
104             hal_video_layer = HAL_DISP_LAYER_VHD1;
105             break;
106         default:
107             hal_video_layer = HAL_DISP_LAYER_VHD0;
108             break;
109     }
110     return hal_video_layer;
111 }
112 
set_vobg(unsigned int dev,unsigned int rgb)113 int set_vobg(unsigned int dev, unsigned int rgb)
114 {
115     if (dev < 2) { /* 2 device */
116         g_bg_color[dev] = rgb;
117     }
118     return 0;
119 }
120 
vo_set_disp_max_size(vo_hal_dev vo_dev,vo_intf_sync vo_out_mode)121 hi_void vo_set_disp_max_size(vo_hal_dev vo_dev, vo_intf_sync vo_out_mode)
122 {
123     /* default is 720x576 */
124     hi_u32 max_width = 720;
125     hi_u32 max_height = 576;
126 
127     /* to get the width and height of the sync, not magic num */
128     switch (vo_out_mode) {
129         case VO_OUTPUT_PAL:
130         case VO_OUTPUT_576P50:
131             max_width = 720;
132             max_height = 576;
133             break;
134         case VO_OUTPUT_NTSC:
135         case VO_OUTPUT_480P60:
136             max_width = 720;
137             max_height = 480;
138             break;
139         case VO_OUTPUT_720P60:
140         case VO_OUTPUT_720P50:
141             max_width = 1280;
142             max_height = 720;
143             break;
144         case VO_OUTPUT_1080I50:
145         case VO_OUTPUT_1080I60:
146         case VO_OUTPUT_1080P24:
147         case VO_OUTPUT_1080P25:
148         case VO_OUTPUT_1080P30:
149         case VO_OUTPUT_1080P50:
150         case VO_OUTPUT_1080P60:
151             max_width = 1920;
152             max_height = 1080;
153             break;
154         case VO_OUTPUT_800x600_60:
155         case VO_OUTPUT_800x600_50:
156             max_width = 800;
157             max_height = 600;
158             break;
159         case VO_OUTPUT_1024x768_60:
160             max_width = 1024;
161             max_height = 768;
162             break;
163         case VO_OUTPUT_1280x1024_60:
164             max_width = 1280;
165             max_height = 1024;
166             break;
167         case VO_OUTPUT_1366x768_60:
168             max_width = 1366;
169             max_height = 768;
170             break;
171         case VO_OUTPUT_1440x900_60:
172             max_width = 1440;
173             max_height = 900;
174             break;
175         case VO_OUTPUT_1280x800_60:
176             max_width = 1280;
177             max_height = 800;
178             break;
179         case VO_OUTPUT_1600x1200_60:
180             max_width = 1600;
181             max_height = 1200;
182             break;
183         case VO_OUTPUT_1680x1050_60:
184             max_width = 1680;
185             max_height = 1050;
186             break;
187         case VO_OUTPUT_1920x1200_60:
188             max_width = 1920;
189             max_height = 1200;
190             break;
191         case VO_OUTPUT_640x480_60:
192             max_width = 640;
193             max_height = 480;
194             break;
195         case VO_OUTPUT_1920x2160_30:
196             max_width = 1920;
197             max_height = 2160;
198             break;
199         case VO_OUTPUT_2560x1440_30:
200         case VO_OUTPUT_2560x1440_60:
201             max_width = 2560;
202             max_height = 1440;
203             break;
204         case VO_OUTPUT_2560x1600_60:
205             max_width = 2560;
206             max_height = 1600;
207             break;
208         case VO_OUTPUT_3840x2160_24:
209         case VO_OUTPUT_3840x2160_25:
210         case VO_OUTPUT_3840x2160_30:
211         case VO_OUTPUT_3840x2160_50:
212         case VO_OUTPUT_3840x2160_60:
213             max_width = 3840;
214             max_height = 2160;
215             break;
216         case VO_OUTPUT_4096x2160_24:
217         case VO_OUTPUT_4096x2160_25:
218         case VO_OUTPUT_4096x2160_30:
219         case VO_OUTPUT_4096x2160_50:
220         case VO_OUTPUT_4096x2160_60:
221             max_width = 4096;
222             max_height = 2160;
223             break;
224         case VO_OUTPUT_320x240_50:
225         case VO_OUTPUT_320x240_60: /* just for hi3518ev200 hi3519 */
226             max_width = 320;
227             max_height = 240;
228             break;
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         case VO_OUTPUT_720x1280_60:
235             max_width = 720;
236             max_height = 1280;
237             break;
238         case VO_OUTPUT_1080x1920_60:
239             max_width = 1080;
240             max_height = 1920;
241             break;
242         case VO_OUTPUT_7680x4320_30:
243             max_width = 7680;
244             max_height = 4320;
245             break;
246 
247         default:
248             max_width = 1920;
249             max_height = 1080;
250     }
251 
252     g_max_rect.width = max_width;
253     g_max_rect.height = max_height;
254 }
255 
start_vo(unsigned int dev,unsigned int type,unsigned int sync)256 int start_vo(unsigned int dev, unsigned int type, unsigned int sync)
257 {
258     if (g_inited == HI_FALSE) {
259         sys_hal_set_vo_low_power_ctrl(HI_TRUE);
260         sys_hal_vo_bus_reset_sel(HI_FALSE);
261 
262         /* open clk */
263         vo_drv_set_all_crg_clk(HI_TRUE);
264         vo_drv_board_init();
265         hal_sys_control();
266 
267         g_inited = HI_TRUE;
268     }
269 
270     if ((dev == VO_DEV_DHD0) || (dev == VO_DEV_DHD1)) {
271         sys_hal_vo_dev_clk_en(dev, HI_TRUE);
272     }
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     vo_drv_set_dev_bk_grd(dev, g_bg_color[dev]);
279     vo_drv_set_dev_clk(dev);
280     vo_drv_open(dev);
281 
282     return 0;
283 }
284 
stop_vo(unsigned int dev)285 int stop_vo(unsigned int dev)
286 {
287     vo_drv_close(dev);
288     sys_hal_vo_dev_clk_en(dev, HI_FALSE);
289 
290     return 0;
291 }
292 
video_layer_set_zme_cfg(unsigned int layer,const hi_rect * disp_rect)293 static hi_void video_layer_set_zme_cfg(unsigned int layer, const hi_rect *disp_rect)
294 {
295     vdp_vid_ip_cfg vid_cfg = {0};
296 
297     vid_cfg.csc_en = 0;
298     vid_cfg.hfir_en = 1;
299     vid_cfg.vid_iw = disp_rect->width;
300     vid_cfg.vid_ih = disp_rect->height;
301 
302     vid_cfg.vid_ow = disp_rect->width;
303     vid_cfg.vid_oh = disp_rect->height;
304     vid_cfg.zme_en = HI_FALSE;
305     vo_vid_set_zme_enable(layer, &vid_cfg);
306 }
307 
video_layer_set_csc_by_intf(unsigned int layer,vo_intf_type intf_type)308 static hi_void video_layer_set_csc_by_intf(unsigned int layer, vo_intf_type intf_type)
309 {
310     hi_vo_layer vo_layer;
311     hal_disp_layer hal_video_layer;
312     vo_csc csc;
313     csc_coef_param csc_coef;
314 
315     vo_layer = video_layer_convert(layer);
316     hal_video_layer = video_layer_convert_to_hal(layer);
317 
318     if ((intf_type & VO_INTF_MIPI) ||
319         (intf_type & VO_INTF_MIPI_SLAVE)) {
320         /* do yuv to rgb. */
321         csc.csc_matrix = VO_CSC_MATRIX_BT709_TO_RGB_PC;
322         csc.luma = 50; /* 50 default value */
323         csc.contrast = 50; /* 50 default value */
324         csc.hue = 50; /* 50 default value */
325         csc.satuature = 50; /* 50 default value */
326         csc_coef.csc_scale2p = GFX_CSC_SCALE;
327         csc_coef.csc_clip_min = GFX_CSC_CLIP_MIN;
328         csc_coef.csc_clip_max = GFX_CSC_CLIP_MAX;
329         /* do rgb to yuv. */
330         vo_drv_set_csc_coef(hal_video_layer, &csc, &csc_coef);
331 
332         hal_layer_set_csc_en(vo_layer, HI_TRUE);
333     } else {
334         /* do rgb to rgb or do nothing. */
335         hal_layer_set_csc_en(vo_layer, HI_FALSE);
336     }
337 }
338 
start_videolayer(unsigned int layer,unsigned long addr,unsigned int strd,hi_vo_rect layer_rect)339 int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect layer_rect)
340 {
341     int i;
342     hi_rect disp_rect = { layer_rect.x, layer_rect.y, layer_rect.w, layer_rect.h };
343     hi_vo_layer vo_layer;
344     hal_disp_layer hal_video_layer;
345     const hi_s32 as32_hfir_coef[2][8] = { /* 2 8 hifb coef array */
346         { 0x3f9, 0xc, 0x3ef, 0x19, 0x3da, 0x3a, 0x397, 0x148 },
347         { 0x3f5, 0xf, 0x3ec, 0x1c, 0x3d8, 0x3d, 0x395, 0x14a }
348     };
349     vo_intf_type intf_type;
350 
351     vo_dcache_range(addr, strd * layer_rect.h * 3 / 2); /* 3 / 2 times */
352 
353     vo_layer = video_layer_convert(layer);
354     hal_video_layer = video_layer_convert_to_hal(layer);
355     hal_layer_set_layer_data_fmt(layer, VO_LAYER_PIXERL_FORMAT_SP_Y_CB_CR_420);
356 
357     intf_type = vo_drv_get_dev_intf_type(layer);
358 
359     video_layer_set_csc_by_intf(layer, intf_type);
360 
361     for (i = 0; i <= HAL_DISP_LAYER_VHD1; i++) {
362         hal_video_set_hfir_mode(i, HAL_HFIRMODE_COPY);
363         hal_video_set_hfir_coef(i, as32_hfir_coef[i]);
364     }
365 
366     hal_video_hfir_set_ck_gt_en(layer, HI_TRUE);
367 
368     hal_video_set_layer_disp_rect(layer, &disp_rect);
369     hal_video_set_layer_video_rect(layer, &disp_rect);
370     hal_layer_set_layer_in_rect(layer, &disp_rect);
371     hal_layer_set_layer_galpha(layer, 255); /* 255 max alpha */
372     hal_layer_set_src_resolution(layer, &disp_rect);
373 
374     hal_layer_set_zme_enable(layer, HAL_DISP_ZMEMODE_ALL, HI_FALSE);
375 
376     video_layer_set_zme_cfg(layer, &disp_rect);
377 
378     hal_layer_set_zme_info(layer, disp_rect.width, disp_rect.height, HAL_DISP_ZME_OUTFMT422);
379 
380     /* area 0 */
381     hal_video_set_multi_area_l_addr(layer, 0, addr, strd);
382     hal_video_set_multi_area_c_addr(layer, 0, addr + strd * vo_align(layer_rect.h, 16), strd); /* align 16 */
383 
384     hal_layer_enable_layer(vo_layer, HI_TRUE);
385     hal_layer_set_reg_up(hal_video_layer);
386 
387     return 0;
388 }
389 
stop_videolayer(unsigned int layer)390 int stop_videolayer(unsigned int layer)
391 {
392     hi_vo_layer vo_layer;
393     hal_disp_layer hal_video_layer;
394 
395     vo_layer = video_layer_convert(layer);
396     hal_video_layer = video_layer_convert_to_hal(layer);
397 
398     hal_layer_enable_layer(vo_layer, HI_FALSE);
399     hal_layer_set_reg_up(hal_video_layer);
400 
401     return 0;
402 }
403 
start_gx(unsigned int layer,unsigned long addr,unsigned int strd,hi_vo_rect gx_rect)404 int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect gx_rect)
405 {
406     hi_rect disp_rect = { gx_rect.x, gx_rect.y, gx_rect.w, gx_rect.h };
407     hi_vo_layer vo_layer;
408     hal_disp_layer hal_gfx_layer;
409     vo_intf_type intf_type;
410     vo_csc gfx_csc;
411     csc_coef_param csc_coef;
412 
413     vo_layer = gfx_convert_layer(layer);
414     hal_gfx_layer = gfx_convert_layer(layer);
415     intf_type = vo_drv_get_dev_intf_type(layer);
416 
417     vo_dcache_range(addr, strd * gx_rect.h);
418 
419     hal_graphic_set_gfx_ext(vo_layer, HAL_GFX_BITEXTEND_3RD);
420     hal_graphic_set_gfx_palpha(vo_layer, HI_TRUE, HI_TRUE, 0xff, 0xff); /* 0xff max alpha */
421     hal_layer_set_layer_galpha(vo_layer, 0xff); /* 0xff max alpha */
422     hal_graphic_set_gfx_pre_mult(vo_layer, HI_FALSE);
423 
424     /* for mipi_tx, close csc */
425     if ((intf_type & VO_INTF_MIPI) ||
426         (intf_type & VO_INTF_MIPI_SLAVE)) {
427         hal_layer_set_csc_en(vo_layer, HI_FALSE);
428     } else {
429         gfx_csc.csc_matrix = VO_CSC_MATRIX_RGB_TO_BT601_TV;
430         gfx_csc.luma = 50; /* 50 default value */
431         gfx_csc.contrast = 50; /* 50 default value */
432         gfx_csc.hue = 50; /* 50 default value */
433         gfx_csc.satuature = 50; /* 50 default value */
434         csc_coef.csc_scale2p = GFX_CSC_SCALE;
435         csc_coef.csc_clip_min = GFX_CSC_CLIP_MIN;
436         csc_coef.csc_clip_max = GFX_CSC_CLIP_MAX;
437         /* do rgb to yuv. */
438         vo_drv_set_csc_coef(hal_gfx_layer, &gfx_csc, &csc_coef);
439         hal_layer_set_csc_en(vo_layer, HI_TRUE);
440     }
441 
442     hal_graphic_set_gfx_addr(vo_layer, addr);
443     hal_graphic_set_gfx_stride(vo_layer, strd >> 4); /* 4 to set register */
444     hal_layer_set_layer_in_rect(vo_layer, &disp_rect);
445 
446     hal_video_set_layer_disp_rect(vo_layer, &disp_rect);
447     hal_video_set_layer_video_rect(vo_layer, &disp_rect);
448 
449     hal_gfx_set_src_resolution(vo_layer, &disp_rect);
450 
451     hal_layer_set_layer_data_fmt(vo_layer, HAL_INPUTFMT_ARGB_1555);
452 
453     hal_layer_enable_layer(vo_layer, HI_TRUE);
454     hal_layer_set_reg_up(hal_gfx_layer);
455 
456     return 0;
457 }
458 
stop_gx(unsigned int layer)459 int stop_gx(unsigned int layer)
460 {
461     hi_vo_layer vo_layer;
462     hal_disp_layer hal_gfx_layer;
463 
464     vo_layer = gfx_convert_layer(layer);
465     hal_gfx_layer = gfx_convert_to_hal_layer(layer);
466 
467     hal_layer_set_reg_up(vo_layer);
468     hal_layer_enable_layer(vo_layer, HI_FALSE);
469     hal_layer_set_reg_up(hal_gfx_layer);
470 
471     return 0;
472 }
473 
474