/* * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "vo.h" #include "mkp_vo_dev.h" #include "mkp_vo_video.h" #include "mkp_vo_comm.h" #include "mkp_vo_gfx.h" #include "mkp_vo_init.h" #include "mkp_vo_user.h" #include "hi_math.h" #include #include #include #include #include #include #include #include "drv_vo.h" #include "drv_vo_gfx.h" hi_void vo_dcache_range(hi_phys_addr_t start_addr, hi_u64 size) { if (dcache_status()) { flush_dcache_range(start_addr, start_addr + size); } } int set_vobg(unsigned int dev, unsigned int rgb) { vo_check_dev_id_return(dev); vo_dev_set_bg_color(dev, rgb); return HI_SUCCESS; } static hi_void vo_construct_pub_attr(unsigned int dev, unsigned int type, unsigned int sync, hi_vo_pub_attr *pub_attr) { hi_vo_sync_info *sync_info = HI_NULL; pub_attr->bg_color = vo_dev_get_bg_color(dev); pub_attr->intf_sync = sync; pub_attr->intf_type = type; if (vo_is_user_intf_sync(sync) == HI_TRUE) { sync_info = vo_get_dev_user_sync_timing(dev); if (sync_info != NULL) { memcpy(&(pub_attr->sync_info), sync_info, sizeof(hi_vo_sync_info)); } } } static hi_s32 vo_set_user_sync_clk(unsigned int dev, unsigned int sync) { hi_s32 ret; hi_vo_user_sync_info *user_sync = HI_NULL; if (vo_is_user_intf_sync(sync) == HI_TRUE) { /* set the user sync info: clk source, clk value */ user_sync = vo_get_dev_user_sync_info(dev); if (user_sync == HI_NULL) { return HI_FAILURE; } ret = vo_set_user_sync_info(dev, user_sync); if (ret != HI_SUCCESS) { return ret; } } return HI_SUCCESS; } int start_vo(unsigned int dev, unsigned int type, unsigned int sync) { hi_s32 ret; hi_vo_pub_attr pub_attr = {0}; vo_init(); vo_construct_pub_attr(dev, type, sync, &pub_attr); ret = vo_set_pub_attr(dev, &pub_attr); if (ret != HI_SUCCESS) { return ret; } ret = vo_set_user_sync_clk(dev, sync); if (ret != HI_SUCCESS) { return ret; } ret = vo_enable(dev); return ret; } int stop_vo(unsigned int dev) { vo_check_dev_id_return(dev); return vo_disable(dev); } static hi_s32 vo_construct_gfx_attr(unsigned long addr, unsigned int strd, hi_rect gfx_rect, unsigned int type, hi_vo_gfx_attr *gfx_attr) { hi_vo_gfx_attr gfx_attr_tmp = {0}; gfx_attr_tmp.stride = strd; gfx_attr_tmp.address = addr; gfx_attr_tmp.type = type; memcpy(&gfx_attr_tmp.display_rect, &gfx_rect, sizeof(hi_rect)); return vo_drv_gfx_convert_gfx_attr(&gfx_attr_tmp, gfx_attr); } int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, hi_rect gx_rect, unsigned int type) { hi_s32 ret; hi_vo_gfx_attr gfx_attr = {0}; ret = vo_construct_gfx_attr(addr, strd, gx_rect, type, &gfx_attr); if (ret != HI_SUCCESS) { vo_err_trace("convert gfx attr failed.\n"); return ret; } ret = vo_set_gfx_attr(layer, &gfx_attr); if (ret != HI_SUCCESS) { printf("invalid parameter!\n"); return ret; } ret = vo_enable_gfx_layer(layer, &gfx_attr); return ret; } int stop_gx(unsigned int layer) { hi_s32 ret; ret = vo_disable_gfx_layer(layer); if (ret != HI_SUCCESS) { printf("invalid parameter!\n"); return ret; } return HI_SUCCESS; } static hi_void vo_contruct_video_layer_attr(unsigned long addr, unsigned int strd, hi_rect layer_rect, hi_vo_video_layer_attr *video_attr) { video_attr->stride = strd; video_attr->address = addr; memcpy(&video_attr->display_rect, &layer_rect, sizeof(hi_rect)); } int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, hi_rect layer_rect) { hi_s32 ret; hi_vo_video_layer_attr video_attr = {0}; vo_contruct_video_layer_attr(addr, strd, layer_rect, &video_attr); ret = vo_set_video_layer_attr(layer, &video_attr); if (ret != HI_SUCCESS) { printf("invalid parameter!\n"); return ret; } vo_dcache_range(addr, strd * layer_rect.height * 3 / 2); /* 3 / 2 times */ ret = vo_enable_video_layer(layer, &video_attr); return ret; } int stop_videolayer(unsigned int layer) { hi_s32 ret; ret = vo_disable_video_layer(layer); if (ret != HI_SUCCESS) { printf("invalid parameter!\n"); return ret; } return 0; }