• 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 /* 4 devices default 0x00ffff, 0xFF00, 0xFF00, 0xFF00 default background */
25 static hi_u32 g_bg_color[4] = { 0x00ffff, 0xFF00, 0xFF00, 0xFF00 };
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 < 3) { /* 3 devices */
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     /* to get the width and height of the sync, not magic num */
127     switch (vo_out_mode) {
128         case VO_OUTPUT_PAL:
129         case VO_OUTPUT_576P50:
130             max_width = 720;
131             max_height = 576;
132             break;
133         case VO_OUTPUT_NTSC:
134         case VO_OUTPUT_480P60:
135             max_width = 720;
136             max_height = 480;
137             break;
138         case VO_OUTPUT_720P60:
139         case VO_OUTPUT_720P50:
140             max_width = 1280;
141             max_height = 720;
142             break;
143         case VO_OUTPUT_1080I50:
144         case VO_OUTPUT_1080I60:
145         case VO_OUTPUT_1080P24:
146         case VO_OUTPUT_1080P25:
147         case VO_OUTPUT_1080P30:
148         case VO_OUTPUT_1080P50:
149         case VO_OUTPUT_1080P60:
150             max_width = 1920;
151             max_height = 1080;
152             break;
153         case VO_OUTPUT_800x600_60:
154         case VO_OUTPUT_800x600_50:
155             max_width = 800;
156             max_height = 600;
157             break;
158         case VO_OUTPUT_1024x768_60:
159             max_width = 1024;
160             max_height = 768;
161             break;
162         case VO_OUTPUT_1280x1024_60:
163             max_width = 1280;
164             max_height = 1024;
165             break;
166         case VO_OUTPUT_1366x768_60:
167             max_width = 1366;
168             max_height = 768;
169             break;
170         case VO_OUTPUT_1440x900_60:
171             max_width = 1440;
172             max_height = 900;
173             break;
174         case VO_OUTPUT_1280x800_60:
175             max_width = 1280;
176             max_height = 800;
177             break;
178         case VO_OUTPUT_1600x1200_60:
179             max_width = 1600;
180             max_height = 1200;
181             break;
182         case VO_OUTPUT_1680x1050_60:
183             max_width = 1680;
184             max_height = 1050;
185             break;
186         case VO_OUTPUT_1920x1200_60:
187             max_width = 1920;
188             max_height = 1200;
189             break;
190         case VO_OUTPUT_640x480_60:
191             max_width = 640;
192             max_height = 480;
193             break;
194         case VO_OUTPUT_1920x2160_30:
195             max_width = 1920;
196             max_height = 2160;
197             break;
198         case VO_OUTPUT_2560x1440_30:
199         case VO_OUTPUT_2560x1440_60:
200             max_width = 2560;
201             max_height = 1440;
202             break;
203         case VO_OUTPUT_2560x1600_60:
204             max_width = 2560;
205             max_height = 1600;
206             break;
207         case VO_OUTPUT_3840x2160_24:
208         case VO_OUTPUT_3840x2160_25:
209         case VO_OUTPUT_3840x2160_30:
210         case VO_OUTPUT_3840x2160_50:
211         case VO_OUTPUT_3840x2160_60:
212             max_width = 3840;
213             max_height = 2160;
214             break;
215         case VO_OUTPUT_4096x2160_24:
216         case VO_OUTPUT_4096x2160_25:
217         case VO_OUTPUT_4096x2160_30:
218         case VO_OUTPUT_4096x2160_50:
219         case VO_OUTPUT_4096x2160_60:
220             max_width = 4096;
221             max_height = 2160;
222             break;
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         case VO_OUTPUT_240x320_50: /* just for hi3518ev200 hi3519 */
229         case VO_OUTPUT_240x320_60:
230             max_width = 240;
231             max_height = 320;
232             break;
233         case VO_OUTPUT_720x1280_60:
234             max_width = 720;
235             max_height = 1280;
236             break;
237         case VO_OUTPUT_1080x1920_60:
238             max_width = 1080;
239             max_height = 1920;
240             break;
241         case VO_OUTPUT_7680x4320_30:
242             max_width = 7680;
243             max_height = 4320;
244             break;
245         default:
246             max_width = 1920;
247             max_height = 1080;
248     }
249 
250     g_max_rect.width = max_width;
251     g_max_rect.height = max_height;
252 
253     printf("g_max_rect.width:%u, g_max_rect.height: %u.\n", g_max_rect.width, g_max_rect.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     hi_bool clk_en = HI_FALSE;
259     hi_u32 div_mod;
260 
261     if (g_inited == HI_FALSE) {
262         sys_hal_vo_vdp_low_power(HI_TRUE);
263         sys_hal_vo_bus_reset_sel(HI_FALSE);
264         sys_hal_vo_bus_clk_en(HI_TRUE);
265         sys_hal_vo_hd_clk_sel(0, 0x0);
266         /* open clk */
267         vo_drv_set_all_crg_clk(HI_TRUE);
268         vo_drv_board_init();
269         hal_sys_control();
270 
271         g_inited = HI_TRUE;
272     }
273 
274     if ((dev == VO_DEV_DHD0) || (dev == VO_DEV_DHD1)) {
275         sys_hal_vo_dev_clk_en(dev, HI_TRUE);
276     } else {
277     }
278 
279     vo_set_disp_max_size(dev, sync);
280     vo_drv_set_dev_intf_type(dev, type);
281     vo_drv_set_dev_out_sync(dev, sync);
282     vo_drv_set_dev_bk_grd(dev, g_bg_color[dev]);
283     if (vo_drv_special_work_flow(dev)) {
284         clk_en = HI_FALSE;
285         div_mod = 0;
286         sys_hal_vo_bt_bp_clk_en(clk_en);
287         sys_hal_vo_hd1_div_mode(dev, div_mod);
288 
289         vo_drv_open(dev);
290 
291         vo_drv_set_dev_clk(dev);
292 
293         clk_en = HI_TRUE;
294         sys_hal_vo_bt_bp_clk_en(clk_en);
295     } else {
296         vo_drv_set_dev_clk(dev);
297         vo_drv_open(dev);
298     }
299 
300     return 0;
301 }
302 
stop_vo(unsigned int dev)303 int stop_vo(unsigned int dev)
304 {
305     vo_drv_close(dev);
306     sys_hal_vo_dev_clk_en(dev, HI_FALSE);
307 
308     return 0;
309 }
310 
start_gx(unsigned int layer,unsigned long addr,unsigned int strd,hi_vo_rect gx_rect)311 int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect gx_rect)
312 {
313     hi_rect disp_rect = { gx_rect.x, gx_rect.y, gx_rect.w, gx_rect.h };
314     hi_vo_layer vo_layer;
315     hal_disp_layer hal_gfx_layer;
316     vo_intf_type intf_type;
317 
318     gf_g0_zme_cfg zme_cfg;
319 
320     vo_layer = gfx_convert_layer(layer);
321     hal_gfx_layer = gfx_convert_layer(layer);
322     intf_type = vo_drv_get_dev_intf_type(layer);
323 
324     vo_dcache_range(addr, strd * gx_rect.h);
325 
326     hal_graphic_set_gfx_ext(vo_layer, HAL_GFX_BITEXTEND_3RD);
327     hal_graphic_set_gfx_palpha(vo_layer, HI_TRUE, HI_TRUE, 0xff, 0xff);
328     hal_layer_set_layer_galpha(vo_layer, 0xff);
329     hal_graphic_set_gfx_pre_mult(vo_layer, HI_FALSE);
330     /* for mipi_tx, do not do this two line. */
331     if ((intf_type == VO_INTF_HDMI) ||
332         (intf_type == VO_INTF_BT1120)) {
333         /* do rgb to yuv. */
334         vo_drv_graphics_set_csc_coef(vo_layer);
335         hal_layer_set_csc_en(vo_layer, HI_TRUE);
336     } else if ((intf_type == VO_INTF_MIPI) ||
337         vo_drv_is_lcd_intf(intf_type)) {
338         /* do rgb to rgb or do nothing. */
339     }
340 
341     hal_graphic_set_gfx_addr(vo_layer, addr);
342     hal_graphic_set_gfx_stride(vo_layer, strd >> 4); /* 4 to set regitster */
343     hal_layer_set_layer_in_rect(vo_layer, &disp_rect);
344 
345     /* G0:full screen display */
346     if (vo_layer == VO_LAYER_G0) {
347         /* do zme: disprect to maxrect. */
348         zme_cfg.in_width = disp_rect.width;
349         zme_cfg.in_height = disp_rect.height;
350         zme_cfg.out_width = disp_rect.width;
351         zme_cfg.out_height = disp_rect.height;
352         graphic_drv_enable_zme(vo_layer, &zme_cfg, HI_TRUE);
353         hal_video_set_layer_disp_rect(vo_layer, &disp_rect);
354         hal_video_set_layer_video_rect(vo_layer, &disp_rect);
355     } else {
356         hal_video_set_layer_disp_rect(vo_layer, &disp_rect);
357         hal_video_set_layer_video_rect(vo_layer, &disp_rect);
358     }
359 
360     hal_gfx_set_src_resolution(vo_layer, &disp_rect);
361 
362     hal_layer_set_layer_data_fmt(vo_layer, HAL_INPUTFMT_ARGB_1555);
363 
364     hal_layer_enable_layer(vo_layer, HI_TRUE);
365     hal_layer_set_reg_up(hal_gfx_layer);
366 
367     return 0;
368 }
369 
stop_gx(unsigned int layer)370 int stop_gx(unsigned int layer)
371 {
372     hi_vo_layer vo_layer;
373     hal_disp_layer hal_gfx_layer;
374 
375     vo_layer = gfx_convert_layer(layer);
376     hal_gfx_layer = gfx_convert_to_hal_layer(layer);
377 
378     hal_layer_set_reg_up(vo_layer);
379     hal_layer_enable_layer(vo_layer, HI_FALSE);
380     hal_layer_set_reg_up(hal_gfx_layer);
381 
382     return 0;
383 }
384 
video_layer_set_zme_cfg(unsigned int layer,const hi_rect * disp_rect)385 hi_void video_layer_set_zme_cfg(unsigned int layer, const hi_rect *disp_rect)
386 {
387     vdp_vid_ip_cfg vid_cfg = {0};
388 
389     /* 0 1 is regitster config */
390     vid_cfg.csc_en = 0;
391     vid_cfg.hfir_en = 1;
392     vid_cfg.vid_iw = disp_rect->width;
393     vid_cfg.vid_ih = disp_rect->height;
394 
395     vid_cfg.vid_ow = disp_rect->width;
396     vid_cfg.vid_oh = disp_rect->height;
397     vid_cfg.zme_en = HI_FALSE;
398     vo_vid_set_zme_enable(layer, &vid_cfg);
399 }
400 
video_layer_set_csc_by_intf(unsigned int layer,vo_intf_type intf_type)401 hi_void video_layer_set_csc_by_intf(unsigned int layer, vo_intf_type intf_type)
402 {
403     hi_vo_layer vo_layer;
404 
405     vo_layer = video_layer_convert(layer);
406 
407     /* for mipi_tx, do not do this two line. */
408     if ((intf_type == VO_INTF_HDMI) ||
409         (intf_type == VO_INTF_BT1120)) {
410         /* do rgb to rgb or do nothing. */
411     } else if ((intf_type == VO_INTF_MIPI) ||
412         vo_drv_is_lcd_intf(intf_type)) {
413         /* do yuv to rgb. */
414         vo_drv_video_set_csc_coef(vo_layer);
415         hal_layer_set_csc_en(vo_layer, HI_TRUE);
416     }
417 }
418 
start_videolayer(unsigned int layer,unsigned long addr,unsigned int strd,hi_vo_rect layer_rect)419 int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect layer_rect)
420 {
421     int i;
422     hi_rect disp_rect = { layer_rect.x, layer_rect.y, layer_rect.w, layer_rect.h };
423     hi_vo_layer vo_layer;
424     hal_disp_layer hal_video_layer;
425     const hi_s32 as32_hfir_coef[2][8] = { /* 2 8 hifb coef array */
426         { 0x3f9, 0xc, 0x3ef, 0x19, 0x3da, 0x3a, 0x397, 0x148 },
427         { 0x3f5, 0xf, 0x3ec, 0x1c, 0x3d8, 0x3d, 0x395, 0x14a }
428     };
429     vo_intf_type intf_type;
430 
431     vo_dcache_range(addr, strd * layer_rect.h * 3 / 2); /* 3 / 2 times */
432 
433     vo_layer = video_layer_convert(layer);
434     hal_video_layer = video_layer_convert_to_hal(layer);
435     hal_layer_set_layer_data_fmt(layer, VO_LAYER_PIXERL_FORMAT_SP_Y_CB_CR_420);
436     intf_type = vo_drv_get_dev_intf_type(layer);
437 
438     video_layer_set_csc_by_intf(layer, intf_type);
439 
440     for (i = 0; i <= HAL_DISP_LAYER_VHD1; i++) {
441         hal_video_set_hfir_mode(i, HAL_HFIRMODE_COPY);
442         hal_video_set_hfir_coef(i, as32_hfir_coef[i]);
443     }
444 
445     hal_video_set_layer_disp_rect(layer, &disp_rect);
446     hal_video_set_layer_video_rect(layer, &disp_rect);
447     hal_layer_set_layer_out_rect(layer, &disp_rect);
448     hal_layer_set_layer_in_rect(layer, &disp_rect);
449     hal_layer_set_layer_galpha(layer, 255); /* 255 max alpha */
450     hal_layer_set_src_resolution(layer, &disp_rect);
451 
452     hal_layer_set_zme_enable(layer, HAL_DISP_ZMEMODE_ALL, HI_FALSE);
453     hal_layer_set_zme_msc_enable(layer, HAL_DISP_ZMEMODE_VERC, HI_TRUE);
454 
455     video_layer_set_zme_cfg(layer, &disp_rect);
456 
457     hal_layer_set_zme_info(layer, disp_rect.width, disp_rect.height, HAL_DISP_ZME_OUTFMT422);
458 
459     /* set area 0 */
460     hal_video_set_multi_area_rect(layer, 0, &disp_rect);
461     hal_video_set_multi_area_reso(layer, 0, disp_rect.width);
462     hal_video_set_multi_area_l_addr(layer, 0, addr, strd);
463     hal_video_set_multi_area_c_addr(layer, 0, addr + strd * vo_align(layer_rect.h, 16), strd); /* align 16 */
464     hal_video_set_multi_area_enable(layer, 0, HI_TRUE);
465     hal_layer_enable_layer(vo_layer, HI_TRUE);
466     hal_layer_set_reg_up(hal_video_layer);
467 
468     return 0;
469 }
470 
stop_videolayer(unsigned int layer)471 int stop_videolayer(unsigned int layer)
472 {
473     hi_vo_layer vo_layer;
474     hal_disp_layer hal_video_layer;
475 
476     vo_layer = video_layer_convert(layer);
477     hal_video_layer = video_layer_convert_to_hal(layer);
478 
479     hal_video_set_multi_area_enable(layer, 0, HI_FALSE); /* area 0 */
480     hal_layer_enable_layer(vo_layer, HI_FALSE);
481     hal_layer_set_reg_up(hal_video_layer);
482 
483     return 0;
484 }
485 
486