/* * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. */ #include "vou.h" #include "vou_drv.h" #include "vou_hal.h" /* for debug,bootlogo.dat is a bin file(image) #include "bootlogo.dat" */ static gk_u32 g_bg_color = 0xFF; /* 0xFF default blue */ static gk_bool g_inited = GK_FALSE; static gk_rect g_max_rect = {0}; #define align_back(x, a) ((a) * (((x) / (a)))) static gk_void vo_dcache_range(gk_phys_addr_t start_addr, gk_u64 size) { if (dcache_status()) { flush_dcache_range(start_addr, start_addr + size); } } static unsigned int gfx_convert_layer(unsigned int layer) { unsigned int gfx_layer; /* hard cursor is not supported. */ switch (layer) { case 0: /* 0 layer */ gfx_layer = VO_LAYER_G0; break; default: gfx_layer = VO_LAYER_G0; break; } return gfx_layer; } static hal_disp_layer gfx_convert_to_hal_layer(unsigned int layer) { hal_disp_layer hal_gfx_layer; /* hard cursor is not supported. */ switch (layer) { case 0: /* 0 layer */ hal_gfx_layer = HAL_DISP_LAYER_GFX0; break; default: hal_gfx_layer = HAL_DISP_LAYER_GFX0; break; } return hal_gfx_layer; } static hal_disp_layer video_layer_convert_to_hal(unsigned int layer) { hal_disp_layer hal_video_layer; /* hard cursor is not supported. */ switch (layer) { case 0: /* 0 layer */ hal_video_layer = HAL_DISP_LAYER_VHD0; break; default: hal_video_layer = HAL_DISP_LAYER_VHD0; break; } return hal_video_layer; } int set_vobg(unsigned int dev, unsigned int rgb) { if (dev < 1) { g_bg_color = rgb; } return 0; } gk_void vo_set_disp_max_size(vo_hal_dev vo_dev, vo_intf_sync vo_out_mode) { /* default is 720x576 */ gk_u32 max_width = 720; gk_u32 max_height = 576; /* to get the width and height of the sync, not magic num */ switch (vo_out_mode) { case VO_OUTPUT_PAL: case VO_OUTPUT_576P50: max_width = 720; max_height = 576; break; case VO_OUTPUT_NTSC: case VO_OUTPUT_480P60: max_width = 720; max_height = 480; break; case VO_OUTPUT_720P60: case VO_OUTPUT_720P50: max_width = 1280; max_height = 720; break; case VO_OUTPUT_1080I50: case VO_OUTPUT_1080I60: case VO_OUTPUT_1080P24: case VO_OUTPUT_1080P25: case VO_OUTPUT_1080P30: case VO_OUTPUT_1080P50: case VO_OUTPUT_1080P60: max_width = 1920; max_height = 1080; break; case VO_OUTPUT_800x600_60: case VO_OUTPUT_800x600_50: max_width = 800; max_height = 600; break; case VO_OUTPUT_1024x768_60: max_width = 1024; max_height = 768; break; case VO_OUTPUT_1280x1024_60: max_width = 1280; max_height = 1024; break; case VO_OUTPUT_1366x768_60: max_width = 1366; max_height = 768; break; case VO_OUTPUT_1440x900_60: max_width = 1440; max_height = 900; break; case VO_OUTPUT_1280x800_60: max_width = 1280; max_height = 800; break; case VO_OUTPUT_1600x1200_60: max_width = 1600; max_height = 1200; break; case VO_OUTPUT_1680x1050_60: max_width = 1680; max_height = 1050; break; case VO_OUTPUT_1920x1200_60: max_width = 1920; max_height = 1200; break; case VO_OUTPUT_640x480_60: max_width = 640; max_height = 480; break; case VO_OUTPUT_1920x2160_30: max_width = 1920; max_height = 2160; break; case VO_OUTPUT_2560x1440_30: case VO_OUTPUT_2560x1440_60: max_width = 2560; max_height = 1440; break; case VO_OUTPUT_2560x1600_60: max_width = 2560; max_height = 1600; break; case VO_OUTPUT_3840x2160_24: case VO_OUTPUT_3840x2160_25: case VO_OUTPUT_3840x2160_30: case VO_OUTPUT_3840x2160_50: case VO_OUTPUT_3840x2160_60: max_width = 3840; max_height = 2160; break; case VO_OUTPUT_4096x2160_24: case VO_OUTPUT_4096x2160_25: case VO_OUTPUT_4096x2160_30: case VO_OUTPUT_4096x2160_50: case VO_OUTPUT_4096x2160_60: max_width = 4096; max_height = 2160; break; case VO_OUTPUT_320x240_50: case VO_OUTPUT_320x240_60: max_width = 320; max_height = 240; break; case VO_OUTPUT_240x320_50: case VO_OUTPUT_240x320_60: max_width = 240; max_height = 320; break; case VO_OUTPUT_720x1280_60: max_width = 720; max_height = 1280; break; case VO_OUTPUT_1080x1920_60: max_width = 1080; max_height = 1920; break; case VO_OUTPUT_7680x4320_30: max_width = 7680; max_height = 4320; break; default: max_width = 4096; max_height = 2160; } g_max_rect.width = max_width; g_max_rect.height = max_height; } int start_vo(unsigned int dev, unsigned int type, unsigned int sync) { if (g_inited == GK_FALSE) { sys_hal_vo_bus_reset_sel(GK_FALSE); /* open clk */ vo_drv_set_all_crg_clk(GK_TRUE); vo_drv_board_init(); hal_sys_control(); g_inited = GK_TRUE; } sys_hal_vo_dev_clk_en(dev, GK_TRUE); sys_hal_vo_core_clk_en(dev, GK_TRUE); vo_drv_def_layer_bind_dev(); vo_set_disp_max_size(dev, sync); vo_drv_set_dev_intf_type(dev, type); vo_drv_set_dev_out_sync(dev, sync); vo_drv_set_dev_bk_grd(dev, g_bg_color); vo_drv_set_dev_clk(dev); vo_drv_open(dev); return 0; } int stop_vo(unsigned int dev) { vo_drv_close(dev); sys_hal_vo_dev_clk_en(dev, GK_FALSE); return 0; } static void vo_get_videolayer_csc_matric(vo_intf_type intf_type, vo_csc_matrix *csc_matrix) { if (intf_type == VO_INTF_BT1120) { *csc_matrix = VO_CSC_MATRIX_IDENTITY; } else if ((intf_type == VO_INTF_LCD_6BIT) || (intf_type == VO_INTF_LCD_8BIT) || (intf_type == VO_INTF_LCD_16BIT)) { *csc_matrix = VO_CSC_MATRIX_BT709_TO_RGB_PC; } } int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, gk_vo_rect layer_rect) { int i; gk_rect disp_rect = { layer_rect.x, layer_rect.y, layer_rect.w, layer_rect.h }; hal_disp_layer vo_layer; const hfir_coef coef = { 42, -10, -20, 28, -40, 61, -107, 330 }; /* hfir coef */ vo_intf_type intf_type; vdp_vid_ip_cfg vid_cfg = {0}; vo_csc_matrix csc_matrix = VO_CSC_MATRIX_IDENTITY; vo_dcache_range(addr, strd * layer_rect.h * 3 / 2); /* 3 / 2 times */ vo_layer = video_layer_convert_to_hal(layer); hal_layer_set_layer_data_fmt(vo_layer, VO_LAYER_PIXERL_FORMAT_SP_Y_CB_CR_420); vdp_fdr_vid_set_chm_copy_en(vo_layer, GK_TRUE); intf_type = vo_drv_get_dev_intf_type(vo_layer); vo_get_videolayer_csc_matric(intf_type, &csc_matrix); vo_drv_video_set_csc_coef(vo_layer, csc_matrix); hal_layer_set_csc_en(vo_layer, GK_TRUE); for (i = 0; i < HAL_DISP_LAYER_VHD1; i++) { hal_video_set_layer_alpha(i, 255); /* 255 max alpha */ hal_video_set_hfir_mode(i, HAL_HFIRMODE_COPY); hal_video_hfir_set_coef(i, &coef); hal_video_hfir_set_mid_en(i, GK_TRUE); } hal_video_hfir_set_ck_gt_en(vo_layer, GK_TRUE); hal_video_set_layer_disp_rect(vo_layer, &disp_rect); hal_video_set_layer_video_rect(vo_layer, &disp_rect); hal_layer_set_layer_in_rect(vo_layer, &disp_rect); hal_layer_set_layer_galpha(vo_layer, 255); /* 255 max alpha */ hal_layer_set_src_resolution(vo_layer, &disp_rect); hal_layer_set_zme_enable(vo_layer, HAL_DISP_ZMEMODE_ALL, GK_FALSE); vid_cfg.csc_en = 0; vid_cfg.hfir_en = 1; vid_cfg.vid_iw = disp_rect.width; vid_cfg.vid_ih = disp_rect.height; vid_cfg.vid_ow = disp_rect.width; vid_cfg.vid_oh = disp_rect.height; vid_cfg.zme_en = GK_FALSE; vo_vid_set_zme_enable(vo_layer, &vid_cfg); hal_layer_set_zme_info(vo_layer, disp_rect.width, disp_rect.height, HAL_DISP_ZME_OUTFMT420); /* area 0 */ hal_video_set_multi_area_l_addr(vo_layer, 0, addr, strd); hal_video_set_multi_area_c_addr(vo_layer, 0, addr + layer_rect.h * align_back(layer_rect.w, 8), strd); /* align 8 */ hal_layer_enable_layer(vo_layer, GK_TRUE); hal_layer_set_reg_up(vo_layer); return 0; } int stop_videolayer(unsigned int layer) { hal_disp_layer hal_video_layer; hal_video_layer = video_layer_convert_to_hal(layer); hal_layer_enable_layer(hal_video_layer, GK_FALSE); hal_layer_set_reg_up(hal_video_layer); return 0; } int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, gk_vo_rect gx_rect) { osd_logo_t scroll_image_logo = {0}; gk_vo_layer vo_layer; vo_intf_type intf_type; vo_csc gfx_csc; csc_coef_param csc_coef; vo_layer = gfx_convert_layer(layer); intf_type = vo_drv_get_dev_intf_type(layer); load_bmp(addr, &scroll_image_logo); gk_rect disp_rect = { gx_rect.x, gx_rect.y, scroll_image_logo.width, scroll_image_logo.height }; vo_dcache_range(scroll_image_logo.rgb_buffer, strd * gx_rect.h); hal_graphic_set_gfx_ext(vo_layer, HAL_GFX_BITEXTEND_3RD); hal_graphic_set_gfx_palpha(vo_layer, GK_TRUE, GK_TRUE, 0xff, 0xff); hal_layer_set_layer_galpha(vo_layer, 0xff); hal_graphic_set_gfx_pre_mult(vo_layer, GK_FALSE); /* for mipi_tx, do not do this two line. */ if ((VO_INTF_BT1120 & intf_type) || (VO_INTF_BT656 & intf_type)) { gfx_csc.csc_matrix = VO_CSC_MATRIX_RGB_TO_BT709_PC; gfx_csc.luma = 50; /* 50 default value */ gfx_csc.contrast = 50; /* 50 default value */ gfx_csc.hue = 50; /* 50 default value */ gfx_csc.satuature = 50; /* 50 default value */ csc_coef.csc_scale2p = GFX_CSC_SCALE; csc_coef.csc_clip_min = GFX_CSC_CLIP_MIN; csc_coef.csc_clip_max = GFX_CSC_CLIP_MAX; /* do rgb to yuv. */ graphic_drv_set_csc_coef(vo_layer, &gfx_csc, &csc_coef); hal_layer_set_csc_en(vo_layer, GK_TRUE); } else if ((intf_type == VO_INTF_LCD_6BIT) || (intf_type == VO_INTF_LCD_8BIT) || (intf_type == VO_INTF_LCD_16BIT)) { /* do yuv to rgb or do nothing. */ hal_layer_set_csc_en(vo_layer, GK_FALSE); } hal_graphic_set_gfx_addr (vo_layer, (gk_u64)(gk_u32)scroll_image_logo.rgb_buffer); hal_graphic_set_gfx_stride(vo_layer, (scroll_image_logo.stride) >> 4); /* 4 to set register */ hal_layer_set_layer_in_rect(vo_layer, &disp_rect); hal_video_set_layer_disp_rect(vo_layer, &disp_rect); hal_video_set_layer_video_rect(vo_layer, &disp_rect); hal_gfx_set_src_resolution(vo_layer, &disp_rect); hal_layer_set_layer_data_fmt(vo_layer, HAL_INPUTFMT_ARGB_1555); hal_layer_enable_layer(vo_layer, GK_TRUE); hal_layer_set_reg_up(vo_layer); return 0; } int stop_gx(unsigned int layer) { gk_vo_layer vo_layer; hal_disp_layer hal_gfx_layer; vo_layer = gfx_convert_layer(layer); hal_gfx_layer = gfx_convert_to_hal_layer(layer); hal_layer_set_reg_up(vo_layer); hal_layer_enable_layer(vo_layer, GK_FALSE); hal_layer_set_reg_up(hal_gfx_layer); return 0; }