gk7205v200-uboot/product/osd/vo/gk7205v200/vou.c
2025-08-07 17:13:54 +08:00

430 lines
12 KiB
C
Executable File

/*
* 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;
}