GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "sys_drv.h"
|
||||
#include "hal_vo_clock.h"
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
xmedia_u64 g_vo_mipi_lcd_clk;
|
||||
|
||||
xmedia_void hal_vo_clock_init(vo_clock_config * vo_clock)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
memset(vo_clock, 0, sizeof(vo_clock_config));
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
vo_clock->dev_clock_info[i].clock_sel = VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
for(i = VO_CRG_CLOCK_TYPE_MIPI;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
vo_clock->intf_clock_info[i].intf_sel_dev = XMEDIA_VO_DEV_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clock_deinit(xmedia_void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//vo top 门控使能
|
||||
xmedia_void hal_vo_set_clock_gate(vo_clock_config * vo_clock, xmedia_bool enable)
|
||||
{
|
||||
hal_vout_set_cfg_ck_dyn_gt_en_dma(g_p_vout_reg, enable);
|
||||
hal_vout_set_cfg_ck_dyn_gt_en(g_p_vout_reg, enable);
|
||||
vo_clock->vo_top_clock_gate = enable;
|
||||
return;
|
||||
}
|
||||
|
||||
static vo_clock_src_sel vo_fix_clk_sel(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz)
|
||||
{
|
||||
if ((0 < clk_hz) && (clk_hz <= VO_CLOCK_SRC_13_5MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_13_5MHZ;
|
||||
return VO_CLOCK_SRC_SEL_13_5MHZ;
|
||||
} else if ((VO_CLOCK_SRC_13_5MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_27MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_27MHZ;
|
||||
return VO_CLOCK_SRC_SEL_27MHZ;
|
||||
} else if ((VO_CLOCK_SRC_27MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_37_125MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_37_125MHZ;
|
||||
return VO_CLOCK_SRC_SEL_37_125MHZ;
|
||||
} else if ((VO_CLOCK_SRC_37_125MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_74_25MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_74_25MHZ;
|
||||
return VO_CLOCK_SRC_SEL_74_25MHZ;
|
||||
} else if ((VO_CLOCK_SRC_74_25MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_148_5MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_148_5MHZ;
|
||||
return VO_CLOCK_SRC_SEL_148_5MHZ;
|
||||
} else if ((VO_CLOCK_SRC_148_5MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_297MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_297MHZ;
|
||||
return VO_CLOCK_SRC_SEL_297MHZ;
|
||||
} else if ((VO_CLOCK_SRC_297MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_343_75MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_343_75MHZ;
|
||||
return VO_CLOCK_SRC_SEL_297MHZ;
|
||||
} else {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "not match normal Hz! Use LCD or PLL Hz!\n");
|
||||
return VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static vo_clock_ppc_sel vo_get_ppc_clock(vo_clock_config *vo_clock, xmedia_u32 clk_hz)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
clk_hz = (clk_hz > vo_clock->dev_clock_info[i].clock_hz) ? clk_hz : vo_clock->dev_clock_info[i].clock_hz;
|
||||
}
|
||||
|
||||
if (clk_hz <= 74250000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_74_25MHZ;
|
||||
} else if (clk_hz <= 148500000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_148_5MHZ;
|
||||
} else if (clk_hz <= 297000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_297MHZ;
|
||||
} else if (clk_hz <= 343000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_343MHZ;
|
||||
} else {
|
||||
return VO_CLOCK_SRC_PPC_SEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static vo_clock_src_sel vo_div_clk_sel(vo_clock_config *vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_u32 clk_hz)
|
||||
{
|
||||
xmedia_bool lcd_use_flag = XMEDIA_TRUE;
|
||||
xmedia_u32 i;
|
||||
|
||||
//判断lcd分频能否使用
|
||||
if (clk_hz <= LCD_FREQUENCY_DIVIDER_MAX) {
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
//lcd分频已使能&&不是本dev使用&&分频频率不同 则无法使用lcd分频
|
||||
if ((vo_clock->dev_clock_info[i].clock_sel == VO_CLOCK_SRC_SEL_LCD) &&
|
||||
(i != dev) && (vo_clock->dev_clock_info[i].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_hz != clk_hz)) {
|
||||
lcd_use_flag = XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
//配置lcd分频
|
||||
if (lcd_use_flag == XMEDIA_TRUE) {
|
||||
return VO_CLOCK_SRC_SEL_LCD;
|
||||
}
|
||||
}
|
||||
return VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
|
||||
static vo_div_clock_type vo_clk_sel_to_div_type(vo_clock_src_sel clk_sel)
|
||||
{
|
||||
switch (clk_sel) {
|
||||
case VO_CLOCK_SRC_SEL_LCD:
|
||||
return VO_DIV_CLOCK_TYPE_LCD;
|
||||
default :
|
||||
return VO_DIV_CLOCK_TYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
//crg 分频时钟配置
|
||||
xmedia_s32 hal_vo_set_dev_div_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz,
|
||||
xmedia_bool *vo_special_timing_sel, xmedia_bool vo_lcd_divider_priority)
|
||||
{
|
||||
vo_clock_src_sel clk_sel;
|
||||
vo_clock_ppc_sel vo_ppc_sel;
|
||||
vo_div_clock_type div_type;
|
||||
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
//debug状态位检测,优先使用lcd分频器 or 优先使用固定频点
|
||||
if (vo_lcd_divider_priority == XMEDIA_TRUE) {
|
||||
clk_sel = vo_div_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
//分频器无法使用,尝试使用固定频点
|
||||
clk_sel = vo_fix_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
} else {
|
||||
div_type = vo_clk_sel_to_div_type(clk_sel);
|
||||
if (div_type == VO_DIV_CLOCK_TYPE_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//使用lcd分频器
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = 0;
|
||||
vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz = clk_hz;
|
||||
if (g_vo_mipi_lcd_clk != 0) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &g_vo_mipi_lcd_clk);
|
||||
} else {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &clk_hz);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clk_sel = vo_fix_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel != VO_CLOCK_SRC_SEL_MAX) {
|
||||
//使用固定频点
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
} else {
|
||||
clk_sel = vo_div_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
div_type = vo_clk_sel_to_div_type(clk_sel);
|
||||
if (div_type == VO_DIV_CLOCK_TYPE_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//使用lcd分频
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = 0;
|
||||
vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz = clk_hz;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &clk_hz);
|
||||
}
|
||||
}
|
||||
|
||||
//都使用校正后的特殊时序,不同的是依照 分频器时钟值/固定频点值 计算出不同的矫正时序
|
||||
*vo_special_timing_sel = XMEDIA_TRUE;
|
||||
|
||||
//时钟源选择配置
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_HD_CKSEL, &vo_clock->dev_clock_info[dev].clock_sel);
|
||||
|
||||
vo_clock->dev_clock_info[dev].clock_hz = clk_hz;
|
||||
|
||||
//ppc 时钟配置
|
||||
vo_ppc_sel = vo_get_ppc_clock(vo_clock, clk_hz);
|
||||
if (vo_ppc_sel != VO_CLOCK_SRC_PPC_SEL_MAX) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_PPC_CKSEL, &vo_ppc_sel);
|
||||
}else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
//crg时钟 分频器使能
|
||||
xmedia_void hal_vo_set_dev_div_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_en)
|
||||
{
|
||||
xmedia_bool lcd_div_freq_en = XMEDIA_FALSE;
|
||||
xmedia_u32 i;
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel == VO_CLOCK_SRC_SEL_LCD) {
|
||||
vo_clock->dev_clock_info[dev].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_en = clk_en;
|
||||
}
|
||||
//有可能两个dev用同一个分屏器的频点,判断是否是所有dev分频器的使能状态
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
lcd_div_freq_en |= vo_clock->dev_clock_info[i].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_en;
|
||||
}
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CKEN, &lcd_div_freq_en);
|
||||
return;
|
||||
}
|
||||
|
||||
//crg时钟 vou软复位请求
|
||||
xmedia_void hal_vo_set_clock_reset_enable(vo_clock_config * vo_clock, xmedia_bool reset_en)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_SRST_REQ, &reset_en);
|
||||
//软复位 暂定状态将会改变 其他配置呢 div配置及门控使能 intf门控使能等????
|
||||
vo_clock->dev_clock_info[XMEDIA_VO_DEV_0].dev_clock_gate = XMEDIA_FALSE;
|
||||
vo_clock->dev_clock_info[XMEDIA_VO_DEV_1].dev_clock_gate = XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_clock_reset_sta(xmedia_void)
|
||||
{
|
||||
xmedia_bool state;
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_SRST_GET, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
//crg时钟 vou dev0/dev1门控使能
|
||||
xmedia_void hal_vo_set_dev_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_en)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_HD_CKEN, &clk_en);
|
||||
vo_clock->dev_clock_info[dev].dev_clock_gate = clk_en;
|
||||
|
||||
return;
|
||||
}
|
||||
xmedia_bool vo_check_intf_sel_dev(vo_clock_config * vo_clock,
|
||||
vo_crg_intf_type crg_int_type, xmedia_vo_dev dev)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
for(i = VO_CRG_CLOCK_TYPE_MIPI;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
//dev是否已经被其他intf选定了
|
||||
if ((vo_clock->intf_clock_info[i].intf_sel_dev == dev) && (crg_int_type != i)) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static vo_crg_intf_type hal_vo_swap_intf_type(xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
return VO_CRG_CLOCK_TYPE_BT;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
return VO_CRG_CLOCK_TYPE_LCD;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
return VO_CRG_CLOCK_TYPE_MIPI;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
return VO_CRG_CLOCK_TYPE_LVDS;
|
||||
default:
|
||||
return VO_CRG_CLOCK_TYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_detach_dev(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
for(i = VO_CRG_CLOCK_TYPE_MIPI;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
if ((vo_clock->intf_clock_info[i].intf_sel_dev == dev) && (hal_vo_swap_intf_type(intf_type) == i)) {
|
||||
vo_clock->intf_clock_info[i].intf_sel_dev = XMEDIA_VO_DEV_MAX;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//crg intf 时钟 通道选择
|
||||
xmedia_s32 hal_vo_set_intf_clock(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_reverse_en, xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
xmedia_bool vo_lvds_por_srst = XMEDIA_TRUE;
|
||||
xmedia_bool vo_mipitx_pll_ref_cksel = VO_MIPI_PLL_FREF;
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
if (intf_type == XMEDIA_INTF_TYPE_LVDS) {
|
||||
//lvds 使用LVDS TXPHY PLL_CLKOUT 不需要配置分频
|
||||
vo_clock->dev_clock_info[dev].vo_lvds_sel = XMEDIA_TRUE;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_POR_SRST, &vo_lvds_por_srst);//lvds por 软复位
|
||||
vo_lvds_por_srst = XMEDIA_FALSE;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_POR_SRST, &vo_lvds_por_srst);
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_CKSEL, &vo_clock->dev_clock_info[dev].vo_lvds_sel);
|
||||
} else {
|
||||
vo_clock->dev_clock_info[dev].vo_lvds_sel = XMEDIA_FALSE;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_CKSEL, &vo_clock->dev_clock_info[dev].vo_lvds_sel);
|
||||
}
|
||||
//mipitx_pll_ref_cksel 配置为0 表示使用24Mh 时钟源
|
||||
if (intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_PLL_REF_CKSEL, &vo_mipitx_pll_ref_cksel);
|
||||
}
|
||||
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_BT, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_HD_CKSEL, &dev); //bt接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_PCTRL, &clk_reverse_en); //bt接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_BT].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_BT].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_LCD, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_HD_CKSEL, &dev); //lcd接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_PCTRL, &clk_reverse_en); //lcd接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LCD].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LCD].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_MIPI, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_HD_CKSEL, &dev); //mipi接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_PCTRL, &clk_reverse_en); //mipi接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_MIPI].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_MIPI].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_LVDS, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDSTX_HD_CKSEL, &dev); //lvds接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDSTX_PCTRL, &clk_reverse_en); //lvds接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LVDS].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LVDS].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR, "intf type error!\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
//crg intf 接口时钟门控使能
|
||||
xmedia_void hal_vo_set_intf_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_intf_type intf_type, xmedia_bool clock_enable)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_CKEN, &clock_enable); //bt时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_CKEN, &clock_enable); //lcd时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_CKEN, &clock_enable); //mipi时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDSTX_CKEN, &clock_enable); //lvds时钟使能
|
||||
break;
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR, "intf type error!\n");
|
||||
return;
|
||||
}
|
||||
vo_clock->intf_clock_info[hal_vo_swap_intf_type(intf_type)].intf_clock_gate = clock_enable;
|
||||
return;
|
||||
}
|
||||
|
||||
//获取接口实际配置时钟
|
||||
xmedia_s32 hal_vo_get_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 *clock_hz)
|
||||
{
|
||||
vo_div_clock_type div_type;
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "clock_sel error!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel != VO_CLOCK_SRC_SEL_LCD) {
|
||||
*clock_hz = vo_clock->dev_clock_info[dev].fixed_clock_hz;
|
||||
} else {
|
||||
div_type = vo_clk_sel_to_div_type(vo_clock->dev_clock_info[dev].clock_sel);
|
||||
*clock_hz = vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CLOCK_H__
|
||||
#define __HAL_VO_CLOCK_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef enum {
|
||||
VO_MIPITX_PLL_REF_CKSEL_24M = 0,
|
||||
VO_MIPITX_PLL_REF_CKSEL_36M,
|
||||
VO_MIPITX_PLL_REF_CKSEL_MAX
|
||||
} vo_mipitx_pll_ref_cksel;
|
||||
|
||||
#define LCD_FREQUENCY_DIVIDER_MAX (148.5 * 1000 * 1000)
|
||||
#define PLL_FREQUENCY_DIVIDER_MAX (297 * 1000 * 1000)
|
||||
|
||||
#define LCD_DIV_2_POWER_27 (1 << 27) //2的27次方
|
||||
#define LCD_DIV_2_POWER_24 (1 << 24) //2的24次方
|
||||
#define LCD_DIV_SORCE_FRE (1375*1000*1000) //lcd源频率
|
||||
|
||||
#define VO_CLOCK_SRC_13_5MHZ 13500000
|
||||
#define VO_CLOCK_SRC_27MHZ 27000000
|
||||
#define VO_CLOCK_SRC_37_125MHZ 37125000
|
||||
#define VO_CLOCK_SRC_74_25MHZ 74250000
|
||||
#define VO_CLOCK_SRC_148_5MHZ 148500000
|
||||
#define VO_CLOCK_SRC_297MHZ 297000000
|
||||
#define VO_CLOCK_SRC_343_75MHZ 343750000
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_SRC_SEL_297MHZ,
|
||||
VO_CLOCK_SRC_SEL_148_5MHZ,
|
||||
VO_CLOCK_SRC_SEL_74_25MHZ,
|
||||
VO_CLOCK_SRC_SEL_37_125MHZ,
|
||||
VO_CLOCK_SRC_SEL_27MHZ,
|
||||
VO_CLOCK_SRC_SEL_13_5MHZ,
|
||||
VO_CLOCK_SRC_SEL_LCD,
|
||||
VO_CLOCK_SRC_SEL_APLL_FOUT1,
|
||||
VO_CLOCK_SRC_SEL_343_75MHZ,
|
||||
VO_CLOCK_SRC_SEL_MAX,
|
||||
}vo_clock_src_sel;
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_SRC_PPC_SEL_343MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_297MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_148_5MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_74_25MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_MAX,
|
||||
}vo_clock_ppc_sel;
|
||||
|
||||
typedef enum {
|
||||
VO_DIV_CLOCK_TYPE_LCD,
|
||||
VO_DIV_CLOCK_TYPE_MAX,
|
||||
} vo_div_clock_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CRG_CLOCK_TYPE_MIPI,
|
||||
VO_CRG_CLOCK_TYPE_LVDS,
|
||||
VO_CRG_CLOCK_TYPE_BT,
|
||||
VO_CRG_CLOCK_TYPE_LCD,
|
||||
VO_CRG_CLOCK_TYPE_MAX,
|
||||
} vo_crg_intf_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_PRIORITY_SEL_NORMAL,
|
||||
VO_CLOCK_PRIORITY_SEL_LCD,
|
||||
VO_CLOCK_PRIORITY_SEL_FIX,
|
||||
VO_CLOCK_PRIORITY_SEL_MAX,
|
||||
} vo_clock_priority_sel;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool div_clock_en; //分频器使能状态 dev0 dev1 共用同一分频器时 需判断两个dev的使能状态来使能分频器
|
||||
xmedia_u32 div_clock_hz; //分频器频率
|
||||
} vo_div_clock_info;
|
||||
|
||||
typedef struct {
|
||||
vo_clock_src_sel clock_sel; //dev 时钟源选择
|
||||
xmedia_bool vo_lvds_sel; //lvds时需要配1 选择LVDS TXPHY PLL_CLKOUT,否则配0 选择SOC时钟
|
||||
xmedia_u32 clock_hz;
|
||||
xmedia_u32 fixed_clock_hz; //固定频点时钟
|
||||
vo_div_clock_info freq_clock[VO_DIV_CLOCK_TYPE_MAX];//dev 分频器信息
|
||||
xmedia_bool dev_clock_gate; //dev时钟门控
|
||||
} vo_dev_clock_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool intf_clock_gate; //intf时钟门控
|
||||
xmedia_vo_dev intf_sel_dev; //接口时钟通道选择
|
||||
xmedia_bool intf_reverse_en;
|
||||
} vo_intf_clock_info;
|
||||
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool vo_top_clock_gate; //vo top层动态时钟门控
|
||||
vo_dev_clock_info dev_clock_info[XMEDIA_VO_DEV_MAX]; //dev时钟信息
|
||||
vo_intf_clock_info intf_clock_info[VO_CRG_CLOCK_TYPE_MAX]; //intf时钟信息
|
||||
} vo_clock_config;
|
||||
|
||||
#define VO_MIPI_PLL_FREF VO_MIPITX_PLL_REF_CKSEL_24M //24MHz pll原始频率
|
||||
|
||||
xmedia_void hal_vo_clock_init(vo_clock_config * vo_clock);
|
||||
xmedia_void hal_vo_clock_deinit(xmedia_void);
|
||||
xmedia_void hal_vo_set_clock_gate(vo_clock_config * vo_clock, xmedia_bool enable);
|
||||
xmedia_s32 hal_vo_set_dev_div_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz,
|
||||
xmedia_bool *vo_special_timing_sel, xmedia_bool vo_lcd_divider_priority);
|
||||
|
||||
xmedia_void hal_vo_set_dev_div_clock_enable(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_bool clk_en);
|
||||
xmedia_void hal_vo_set_clock_reset_enable(vo_clock_config * vo_clock, xmedia_bool reset_en);
|
||||
xmedia_bool hal_vo_get_clock_reset_sta(xmedia_void);
|
||||
xmedia_void hal_vo_set_dev_clock_enable(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_bool clk_en);
|
||||
xmedia_s32 hal_vo_set_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_void hal_vo_set_intf_clock_enable(vo_clock_config * vo_clock, xmedia_intf_type intf_type,
|
||||
xmedia_bool clock_enable);
|
||||
xmedia_void hal_vo_set_intf_detach_dev(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_s32 hal_vo_get_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 *clock_hz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
|
||||
#define VO_CSC_TABLE_MAX 61
|
||||
|
||||
typedef struct{
|
||||
vo_csc_type type;
|
||||
const vo_csc_coef *matrix;
|
||||
} vo_csc_type_matrix;
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv601limit = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv601limit = {
|
||||
880, 0, 0, 0, 899, 0, 0, 0, 899,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv601limit = {
|
||||
1024, 102, 196, 0, 1014, -113, 0, -74, 1007,
|
||||
-16, -128, -128,
|
||||
-16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv601limit = {
|
||||
880, 90, 173, 0, 891, -99, 0, -65, 864,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv709limit = {
|
||||
1024, -118, -213, 0, 1043, 117, 0, 77, 1050,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv709limit = {
|
||||
880, -103, -187, 0, 916, 102, 0, 67, 922,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv709limit = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv709limit = {
|
||||
880, 0, 0, 0, 899, 0, 0, 0, 899,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv601full = {
|
||||
1192, 0, 0, 0, 1165, 0, 0, 0, 1165,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv601full = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv601full = {
|
||||
1192, 117, 222, 0, 1154, -128, 0, -84, 1146,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv601full = {
|
||||
1024, 102, 196, 0, 1014, -113, 0, -74, 1007,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv709full = {
|
||||
1192, -137, -248, 0, 1188, 133, 0, 87, 1194,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv709full = {
|
||||
1024, -118, -213, 0, 1043, 117, 0, 77, 1050,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv709full = {
|
||||
1192, 0, 0, 0, 1165, 0, 0, 0, 1165,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv709full = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_rgbfull = {
|
||||
1192, 0, 1634, 1192, -400, -833, 1192, 2066, 0,
|
||||
-16, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_rgbfull = {
|
||||
1024, 0, 1040, 1024, -344, -706, 1024, 1774, 0,
|
||||
0, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_rgbfull = {
|
||||
1192, 0, 1836, 1192, -218, -547, 1192, 2166, 0,
|
||||
-16, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_rgbfull = {
|
||||
1024, 0, 1577, 1024, -187, -470, 1024, 1860, 0,
|
||||
0, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_rgblimit = {
|
||||
1024, 0, 1404, 1024, -344, -716, 1024, 1775, 0,
|
||||
-16, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_rgblimit = {
|
||||
880, 0, 1233, 880, -302, -629, 880, 1559, 0,
|
||||
0, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_rgblimit = {
|
||||
1024, 0, 1578, 1024, -187, -470, 1024, 1861, 0,
|
||||
-16, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_rgblimit = {
|
||||
880, 0, 1385, 880, -164, -413, 880, 1634, 0,
|
||||
0, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const int g_sin_table[VO_CSC_TABLE_MAX] = {
|
||||
-500, -485, -469, -454, -438, -422, -407, -391, -374, -358,
|
||||
-342, -325, -309, -292, -276, -259, -242, -225, -208, -191,
|
||||
-174, -156, -139, -122, -104, -87, -70, -52, -35, -17,
|
||||
0, 17, 35, 52, 70, 87, 104, 122, 139, 156,
|
||||
174, 191, 208, 225, 242, 259, 276, 292, 309, 325,
|
||||
342, 358, 374, 391, 407, 422, 438, 454, 469, 485,
|
||||
500
|
||||
};
|
||||
|
||||
const int g_cos_table[VO_CSC_TABLE_MAX] = {
|
||||
866, 875, 883, 891, 899, 906, 914, 921, 927, 934,
|
||||
940, 946, 951, 956, 961, 966, 970, 974, 978, 982,
|
||||
985, 988, 990, 993, 995, 996, 998, 999, 999, 1000,
|
||||
1000, 1000, 999, 999, 998, 996, 995, 993, 990, 988,
|
||||
985, 982, 978, 974, 970, 966, 961, 956, 951, 946,
|
||||
940, 934, 927, 921, 914, 906, 899, 891, 883, 875,
|
||||
866
|
||||
};
|
||||
|
||||
//后面需要根据算法提供的参数进行更新
|
||||
static vo_csc_type_matrix g_type_to_matrix[VO_CSC_MAX] = {
|
||||
{ VO_CSC_YUV2RGB_601_LIMIT2FULL, &g_csc_yuv601limit_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_709_LIMIT2FULL, &g_csc_yuv709limit_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_601_FULL2LIMIT, &g_csc_yuv601full_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_709_FULL2LIMIT, &g_csc_yuv709full_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_601_FULL2FULL, &g_csc_yuv601full_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_709_FULL2FULL, &g_csc_yuv709full_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_601_LIMIT2LIMIT, &g_csc_yuv601limit_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_709_LIMIT2LIMIT, &g_csc_yuv709limit_to_rgblimit },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_LIMIT2LIMIT, &g_csc_yuv601limit_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_601_709_LIMIT2LIMIT, &g_csc_yuv601limit_to_yuv709limit },
|
||||
{ VO_CSC_YUV2YUV_709_601_LIMIT2LIMIT, &g_csc_yuv709limit_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_709_709_LIMIT2LIMIT, &g_csc_yuv709limit_to_yuv709limit },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_FULL2FULL, &g_csc_yuv601full_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_601_709_FULL2FULL, &g_csc_yuv601full_to_yuv709full },
|
||||
{ VO_CSC_YUV2YUV_709_601_FULL2FULL, &g_csc_yuv709full_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_709_709_FULL2FULL, &g_csc_yuv709full_to_yuv709full },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_LIMIT2FULL, &g_csc_yuv601limit_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_601_709_LIMIT2FULL, &g_csc_yuv601limit_to_yuv709full },
|
||||
{ VO_CSC_YUV2YUV_709_601_LIMIT2FULL, &g_csc_yuv709limit_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_709_709_LIMIT2FULL, &g_csc_yuv709limit_to_yuv709full },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_FULL2LIMIT, &g_csc_yuv601full_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_601_709_FULL2LIMIT, &g_csc_yuv601full_to_yuv709limit },
|
||||
{ VO_CSC_YUV2YUV_709_601_FULL2LIMIT, &g_csc_yuv709full_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_709_709_FULL2LIMIT, &g_csc_yuv709full_to_yuv709limit },
|
||||
};
|
||||
|
||||
static xmedia_s32 vo_get_base_matrix_by_type(vo_csc_type csc_type, const vo_csc_coef **csc_tmp)
|
||||
{
|
||||
xmedia_u32 loop;
|
||||
xmedia_u32 len;
|
||||
|
||||
len = sizeof(g_type_to_matrix) / sizeof(vo_csc_type_matrix);
|
||||
for (loop = 0; loop < len; loop++) {
|
||||
if (g_type_to_matrix[loop].type == csc_type) {
|
||||
if (g_type_to_matrix[loop].matrix != XMEDIA_NULL) {
|
||||
*csc_tmp = g_type_to_matrix[loop].matrix;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
}
|
||||
return XMEDIA_FAILURE;
|
||||
};
|
||||
|
||||
static xmedia_bool vo_check_csc_type(vo_csc_type type)
|
||||
{
|
||||
if ((type >= VO_CSC_YUV2RGB_601_LIMIT2FULL) && (type <= VO_CSC_YUV2RGB_709_LIMIT2LIMIT)) {
|
||||
return XMEDIA_TRUE;
|
||||
}
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_csc_coef_convert(vo_pic_info *src_pic_info, vo_csc_coef *pst_csc_matrix)
|
||||
{
|
||||
xmedia_s32 luma = 0;
|
||||
xmedia_s32 contrast = 0;
|
||||
xmedia_s32 hue = 0;
|
||||
xmedia_s32 satu = 0;
|
||||
const vo_csc_coef *base_csc_matrix = XMEDIA_NULL;
|
||||
|
||||
luma = (xmedia_s32)src_pic_info->luma * 64 / 100 - 32;
|
||||
contrast = ((xmedia_s32)src_pic_info->contrast - 50) * 2 + 100;
|
||||
hue = (xmedia_s32)src_pic_info->hue * 60 / 100;
|
||||
satu = ((xmedia_s32)src_pic_info->saturation - 50) * 2 + 100;
|
||||
if (hue >= VO_CSC_TABLE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hue %d error!\n", hue);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (vo_get_base_matrix_by_type(src_pic_info->csc_type, &base_csc_matrix) != XMEDIA_SUCCESS) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo_get_base_matrix_by_type error!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
pst_csc_matrix->csc_offset_in0 = base_csc_matrix->csc_offset_in0;
|
||||
pst_csc_matrix->csc_offset_in1 = base_csc_matrix->csc_offset_in1;
|
||||
pst_csc_matrix->csc_offset_in2 = base_csc_matrix->csc_offset_in2;
|
||||
pst_csc_matrix->csc_offset_out0 = base_csc_matrix->csc_offset_out0;
|
||||
pst_csc_matrix->csc_offset_out1 = base_csc_matrix->csc_offset_out1;
|
||||
pst_csc_matrix->csc_offset_out2 = base_csc_matrix->csc_offset_out2;
|
||||
|
||||
/* C_ratio的调节范围一般是0~1.99, C_ratio=s32Contrast/100
|
||||
* S的调节范围一般为0~1.99,S=s32Satu/100
|
||||
* 色调调节参数的范围一般为-30°~30°,通过查表法求得COS和SIN值并/1000
|
||||
*/
|
||||
if (vo_check_csc_type(src_pic_info->csc_type) == XMEDIA_TRUE) {
|
||||
/* 此公式仅用于YUV->RGB转换,RGB->YUV转换不可用此公式 */
|
||||
pst_csc_matrix->csc_coef0 = (contrast * base_csc_matrix->csc_coef0) / 100;
|
||||
pst_csc_matrix->csc_coef1 = (contrast * satu * ((base_csc_matrix->csc_coef1 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef2 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef2 = (contrast * satu * ((base_csc_matrix->csc_coef1 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef2 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef3 = (contrast * base_csc_matrix->csc_coef3) / 100;
|
||||
pst_csc_matrix->csc_coef4 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef5 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef5 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef5 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef6 = (contrast * base_csc_matrix->csc_coef6) / 100;
|
||||
pst_csc_matrix->csc_coef7 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef8 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef8 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef8 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_offset_in0 += (contrast != 0) ? (luma * 100 / contrast) : luma * 100;
|
||||
} else {
|
||||
/* 此公式仅用于RGB->YUV转换,YUV->RGB转换不可用此公式,
|
||||
* YUV->YUV仅调节图像效果可用此公式,因为常量矩阵为单位矩阵 */
|
||||
pst_csc_matrix->csc_coef0 = (contrast * base_csc_matrix->csc_coef0) / 100;
|
||||
pst_csc_matrix->csc_coef1 = (contrast * base_csc_matrix->csc_coef1) / 100;
|
||||
pst_csc_matrix->csc_coef2 = (contrast * base_csc_matrix->csc_coef2) / 100;
|
||||
pst_csc_matrix->csc_coef3 = (contrast * satu * ((base_csc_matrix->csc_coef3 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef3 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef4 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef4 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef5 = (contrast * satu * ((base_csc_matrix->csc_coef5 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef5 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef6 = (contrast * satu * ((base_csc_matrix->csc_coef6 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef6 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef7 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef7 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef8 = (contrast * satu * ((base_csc_matrix->csc_coef8 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef8 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_offset_out0 += luma;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CSC_H__
|
||||
#define __HAL_VO_CSC_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 csc_coef0;
|
||||
xmedia_s32 csc_coef1;
|
||||
xmedia_s32 csc_coef2;
|
||||
|
||||
xmedia_s32 csc_coef3;
|
||||
xmedia_s32 csc_coef4;
|
||||
xmedia_s32 csc_coef5;
|
||||
|
||||
xmedia_s32 csc_coef6;
|
||||
xmedia_s32 csc_coef7;
|
||||
xmedia_s32 csc_coef8;
|
||||
|
||||
xmedia_s32 csc_offset_in0;
|
||||
xmedia_s32 csc_offset_in1;
|
||||
xmedia_s32 csc_offset_in2;
|
||||
xmedia_s32 csc_offset_out0;
|
||||
xmedia_s32 csc_offset_out1;
|
||||
xmedia_s32 csc_offset_out2;
|
||||
} vo_csc_coef;
|
||||
|
||||
xmedia_s32 hal_vo_csc_coef_convert(vo_pic_info *src_pic_info, vo_csc_coef *pst_csc_matrix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_DISP_H__
|
||||
#define __HAL_VO_DISP_H__
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_MRG_MIX_PRIO_RDMA0 = 0,
|
||||
VO_MRG_MIX_PRIO_RDMA1,
|
||||
VO_MRG_MIX_PRIO_MAX,
|
||||
} vo_mrg_mix_prio;
|
||||
|
||||
typedef enum {
|
||||
VO_MIX_PRIO_VIDEO = 0,
|
||||
VO_MIX_PRIO_GFX,
|
||||
VO_MIX_PRIO_MAX,
|
||||
} vo_mix_prio;
|
||||
|
||||
typedef enum {
|
||||
VO_PIXEL_FMT_YUV_400 = 0,
|
||||
VO_PIXEL_FMT_YUV_420,
|
||||
VO_PIXEL_FMT_YUV_422,
|
||||
VO_PIXEL_FMT_YUV_MAX
|
||||
} vo_pixel_format;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool vcus_mode;
|
||||
xmedia_bool hcus_mode;
|
||||
xmedia_u8 hcus_coef0;
|
||||
xmedia_u8 hcus_coef1;
|
||||
xmedia_u8 hcus_coef2;
|
||||
xmedia_u8 hcus_coef3;
|
||||
xmedia_u8 vcus_coef0;
|
||||
xmedia_u8 vcus_coef1;
|
||||
xmedia_u8 vcus_coef2;
|
||||
xmedia_u8 vcus_coef3;
|
||||
} vo_video_cus;
|
||||
|
||||
xmedia_void hal_vo_set_top_regup(xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_top_regup(xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_video_regup(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_intf_regup(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_version0(xmedia_u32 *version);
|
||||
xmedia_void hal_vo_get_version1(xmedia_u32 *version);
|
||||
xmedia_void hal_vo_set_mem_ctrl(xmedia_u32 speed);
|
||||
xmedia_u32 hal_vo_get_mask_interrupt_state(xmedia_void);
|
||||
xmedia_void hal_vo_clear_mask_interrupt_state(vo_isr_interrupt_type int_mask);
|
||||
xmedia_void hal_vo_set_mask_interrupt_enable(vo_isr_interrupt_type int_mask,xmedia_bool enable);
|
||||
xmedia_u32 hal_vo_get_unmask_interrupt_state(xmedia_void);
|
||||
xmedia_void hal_vo_clear_lowband_state(xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_cbm_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_dma_standing(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_u8 hal_vo_get_dma_standing(xmedia_void);
|
||||
xmedia_void hal_vo_set_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
//两个及时寄存器
|
||||
xmedia_void hal_vo_set_regup_mode(xmedia_vo_layer layer, xmedia_bool filed_en);
|
||||
xmedia_void hal_vo_set_regup_field(xmedia_vo_layer layer, xmedia_bool bottom_en);
|
||||
xmedia_void hal_vo_set_alpha(xmedia_vo_layer layer, xmedia_u8 alpha);
|
||||
xmedia_void hal_vo_set_alpha_enable(xmedia_vo_layer layer, xmedia_bool alpha_en);
|
||||
xmedia_void hal_vo_set_alpha_blend_mode(xmedia_vo_layer layer, xmedia_bool alpha_blend_en);
|
||||
xmedia_void hal_vo_set_src_pixel_format(xmedia_vo_layer layer, vo_pixel_format format, xmedia_bool uv_order);
|
||||
xmedia_void hal_vo_set_multi_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_bgcolor(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_bgcolor(xmedia_vo_layer layer, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_mute_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_mute_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_video_regup_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_mute_pattern_mode(xmedia_vo_layer layer, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_mute_data_mode(xmedia_vo_layer layer, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_checkbar_size(xmedia_vo_layer layer, xmedia_u8 width, xmedia_u8 height);
|
||||
xmedia_void hal_vo_set_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_get_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_set_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_get_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_set_dst_rect (xmedia_vo_layer layer, xmedia_video_rect *dst_rect);
|
||||
xmedia_void hal_vo_set_addr (xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_mixer_prio(xmedia_vo_layer layer, vo_mrg_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_mrg_rdma1_link(xmedia_vo_layer layer, xmedia_u8 rgion_id);
|
||||
xmedia_void hal_vo_set_mrg_rdma1_en(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg_mute_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_mrg_sort(xmedia_vo_layer layer, xmedia_u16 sort);
|
||||
xmedia_void hal_vo_set_mrg_src_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_set_mrg_dst_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *dst_rect);
|
||||
xmedia_void hal_vo_set_mrg0_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg1_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg2_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg3_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_addr(xmedia_vo_layer layer, xmedia_u32 region_id,vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_cus(xmedia_vo_layer layer, vo_video_cus *cus);
|
||||
xmedia_void hal_vo_set_csc_en(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg0_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg1_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg2_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg3_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg_csc(xmedia_vo_layer layer, xmedia_u32 region_id, vo_csc_coef *csc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_gamma.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
|
||||
xmedia_void hal_vo_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_vout_set_cfg_gamma_en(g_p_vout_reg, enable);
|
||||
} else if (dev == XMEDIA_VO_DEV_1) {
|
||||
hal_vout_set_voutintf1_cfg_gamma_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_get_table_size(xmedia_void)
|
||||
{
|
||||
return VO_GAMMA_MAP_SIZE * sizeof(xmedia_u8);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_set_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
xmedia_s32 i;
|
||||
for (i = 0;i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
((xmedia_u8 *)gamma_virtual_addr)[i] = gamma_table->gamma_table[i];
|
||||
}
|
||||
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_vout_set_cfg_para_2_update(g_p_vout_reg, XMEDIA_TRUE);
|
||||
} else if (dev == XMEDIA_VO_DEV_1) {
|
||||
hal_vout_set_cfg_para_3_update(g_p_vout_reg, XMEDIA_TRUE);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_get_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
xmedia_s32 i;
|
||||
|
||||
for (i = 0;i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
gamma_table->gamma_table[i] = ((xmedia_u8 *)gamma_virtual_addr)[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_set_addr(xmedia_vo_dev dev, xmedia_u64 addr)
|
||||
{
|
||||
xmedia_u32 addr_l = addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_h = (addr & 0xFFFFFFFF00000000) >> 32;
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_vout_set_cfg_para_2_addr_h(g_p_vout_reg, addr_h);
|
||||
hal_vout_set_cfg_para_2_addr_l(g_p_vout_reg, addr_l);
|
||||
} else if (dev == XMEDIA_VO_DEV_1) {
|
||||
hal_vout_set_cfg_para_3_addr_h(g_p_vout_reg, addr_h);
|
||||
hal_vout_set_cfg_para_3_addr_l(g_p_vout_reg, addr_l);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_GAMMA_H__
|
||||
#define __HAL_VO_GAMMA_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
xmedia_void hal_vo_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_s32 hal_vo_gamma_get_table_size(xmedia_void);
|
||||
xmedia_void hal_vo_gamma_set_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_gamma_get_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_gamma_set_addr(xmedia_vo_dev dev, xmedia_u64 addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
|
||||
+954
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_intf.h"
|
||||
#include "hal_vo_clock.h"
|
||||
#include "hal_vo_gamma.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
static xmedia_s32 vo_mipi_htotal_adjust_value = 0;
|
||||
static xmedia_s32 vo_mipi_vsync_adjust_value = 0;
|
||||
|
||||
xmedia_void hal_vo_set_mipi_htotal_adjust_value(xmedia_s32 htotal_adjust_value)
|
||||
{
|
||||
vo_mipi_htotal_adjust_value = htotal_adjust_value;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mipi_vsync_adjust_value(xmedia_s32 vsync_adjust_value)
|
||||
{
|
||||
vo_mipi_vsync_adjust_value = vsync_adjust_value;
|
||||
}
|
||||
|
||||
vo_hal_context vo_hal_ctx;
|
||||
vo_hal_context *hal_vo_get_hal_context(xmedia_void)
|
||||
{
|
||||
return &vo_hal_ctx;
|
||||
}
|
||||
|
||||
#define vo_reg_addr_offset(REG) ((xmedia_ulong) & (((s_vout_regs_type *)0)->REG))
|
||||
#define OFFSET_ELE_NUM 2
|
||||
#ifdef VO_KERNEL
|
||||
static xmedia_ulong g_vo_reg_offset[][OFFSET_ELE_NUM] = {
|
||||
{ vo_reg_addr_offset(vout_top_ctrl), 0x320 },
|
||||
{ vo_reg_addr_offset(vout_lvds_phy_update), 0x50 },
|
||||
{ vo_reg_addr_offset(vout_v0_ctrl), 0x300 },
|
||||
{ vo_reg_addr_offset(vout_intf_ctrl), 0x230 },
|
||||
{ vo_reg_addr_offset(vout_intf_csc_offset_in), 0x70 },
|
||||
{ vo_reg_addr_offset(vout_v1_ctrl), 0x300 },
|
||||
{ vo_reg_addr_offset(vout_intf1_ctrl), 0x230 },
|
||||
{ vo_reg_addr_offset(vout_intf1_csc_offset_in), 0x70 },
|
||||
};
|
||||
#endif
|
||||
#ifdef VO_KERNEL
|
||||
static xmedia_u8 *g_vo_reg_record = XMEDIA_NULL;
|
||||
#endif
|
||||
typedef struct {
|
||||
xmedia_u64 gamma_phy_addr;
|
||||
xmedia_void *gamma_virtual_addr;
|
||||
xmedia_u32 gamma_mem_len;
|
||||
} vo_dev_gamma_buf;
|
||||
|
||||
#define VO_BASE_ADDR 0x11280000
|
||||
#define VO_MIPI_TX_CTRL_BASE 0x11960000
|
||||
#define VO_MIPI_TX_PHY_BASE 0x11970000
|
||||
|
||||
s_vout_regs_type *g_p_vout_reg = (s_vout_regs_type *)VO_BASE_ADDR;
|
||||
void *g_p_vout_mipi_tx_ctrl = (void *)VO_MIPI_TX_CTRL_BASE;
|
||||
void *g_p_vout_mipi_tx_phy = (void *)VO_MIPI_TX_PHY_BASE;
|
||||
|
||||
#define VO_MIPI_TX_PHY_SIZE 0x1000
|
||||
#define VO_FIFO_DEPTH 1919
|
||||
#define VO_MMZ_NAME_SIZE 128
|
||||
|
||||
#ifdef VO_KERNEL
|
||||
static vo_dev_gamma_buf g_vo_gamma_buf[XMEDIA_VO_DEV_MAX];
|
||||
#endif
|
||||
static xmedia_s32 vo_reg_map(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_p_vout_reg == XMEDIA_NULL) {
|
||||
g_p_vout_reg = (s_vout_regs_type *)osal_ioremap_nocache(VO_BASE_ADDR, sizeof(s_vout_regs_type));
|
||||
if (g_p_vout_reg == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy == XMEDIA_NULL) {
|
||||
g_p_vout_mipi_tx_phy = osal_ioremap_nocache(VO_MIPI_TX_PHY_BASE, VO_MIPI_TX_PHY_SIZE);
|
||||
if (g_p_vout_mipi_tx_phy == XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy_2 == XMEDIA_NULL) {
|
||||
g_p_vout_mipi_tx_phy_2 = osal_ioremap_nocache(VO_MIPI_TX_PHY_BASE_2, VO_MIPI_TX_PHY_SIZE);
|
||||
if (g_p_vout_mipi_tx_phy_2 == XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
osal_iounmap((xmedia_void *)g_p_vout_mipi_tx_phy);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
g_p_vout_mipi_tx_phy = XMEDIA_NULL;
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void vo_reg_unmap(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_p_vout_reg != XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy != XMEDIA_NULL) {
|
||||
osal_iounmap(g_p_vout_mipi_tx_phy);
|
||||
g_p_vout_mipi_tx_phy = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy_2 != XMEDIA_NULL) {
|
||||
osal_iounmap(g_p_vout_mipi_tx_phy_2);
|
||||
g_p_vout_mipi_tx_phy_2 = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_init(xmedia_vo_dev dev)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
xmedia_char mmz_user_name[VO_MMZ_NAME_SIZE];
|
||||
xmedia_vo_gamma_table gamma_table;
|
||||
|
||||
g_vo_gamma_buf[dev].gamma_mem_len = hal_vo_gamma_get_table_size();
|
||||
osal_snprintf(mmz_user_name, sizeof(mmz_user_name), "vo_gamma_dev%u", dev);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = drv_vo_mmz_alloc(mmz_user_name,
|
||||
g_vo_gamma_buf[dev].gamma_mem_len, XMEDIA_NULL);
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr == XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"drv_vo_mmz_alloc error!\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = drv_vo_mmz_map(g_vo_gamma_buf[dev].gamma_phy_addr,
|
||||
g_vo_gamma_buf[dev].gamma_mem_len);
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr == XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
VO_TRACE(MODULE_DBG_ERR,"drv_vo_mmz_map return NULL!\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
gamma_table.gamma_table[dev] = dev;
|
||||
hal_vo_set_gamma_table(dev, &gamma_table);
|
||||
return XMEDIA_SUCCESS;
|
||||
err_out:
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_unmap(g_vo_gamma_buf[dev].gamma_virtual_addr);
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_deinit(xmedia_vo_dev dev)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_unmap(g_vo_gamma_buf[dev].gamma_virtual_addr);
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 ret;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
memset(hal_ctx, 0, sizeof(vo_hal_context));
|
||||
|
||||
hal_vo_init_chip_capaciblity();
|
||||
ret = vo_reg_map();
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
hal_vo_clock_init(&hal_ctx->clock_config);
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_deinit(xmedia_void)
|
||||
{
|
||||
//关闭所有的时钟todo
|
||||
hal_vo_clock_deinit();
|
||||
vo_reg_unmap();
|
||||
return;
|
||||
}
|
||||
|
||||
vo_base_cap* hal_vo_get_capacity(xmedia_void)
|
||||
{
|
||||
return hal_vo_get_chip_capacity();
|
||||
}
|
||||
|
||||
vo_layer_cap* hal_get_layer_capacity(xmedia_u32 layer)
|
||||
{
|
||||
return hal_get_layer_chip_capacity(layer);
|
||||
}
|
||||
|
||||
vo_dev_cap* hal_get_dev_capacity(xmedia_vo_dev dev)
|
||||
{
|
||||
return hal_get_dev_chip_capacity(dev);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_clock_gate_enable(xmedia_bool clk_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_clock_gate(&hal_ctx->clock_config, clk_en);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_clock_reset(xmedia_bool reset_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_clock_reset_enable(&hal_ctx->clock_config, reset_en);
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_crg_clock_reset_state(xmedia_void)
|
||||
{
|
||||
return hal_vo_get_clock_reset_sta();
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_clock_sel_priority(xmedia_vo_dev dev, vo_clock_priority_sel vo_clock_priority_sel)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_ctx->special_timing[dev].vo_clock_priority_sel = vo_clock_priority_sel;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_crg_clock(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_bool vo_lcd_divider_priority = XMEDIA_FALSE;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
//根据时钟判断是否需要使用特殊时序配置
|
||||
if (hal_ctx->special_timing[dev].vo_clock_priority_sel == VO_CLOCK_PRIORITY_SEL_LCD) {
|
||||
vo_lcd_divider_priority = XMEDIA_TRUE;
|
||||
} else if (hal_ctx->special_timing[dev].vo_clock_priority_sel == VO_CLOCK_PRIORITY_SEL_FIX) {
|
||||
vo_lcd_divider_priority = XMEDIA_FALSE;
|
||||
} else {
|
||||
//debug没有设置lcd分频器时,对接口类型做二次判断,lcd/lvds优先使用LCD分频器
|
||||
if (intf_type == XMEDIA_INTF_TYPE_LCD || intf_type == XMEDIA_INTF_TYPE_LVDS) {
|
||||
vo_lcd_divider_priority = XMEDIA_TRUE;
|
||||
}
|
||||
}
|
||||
ret = hal_vo_set_dev_div_clock(&hal_ctx->clock_config, dev, clk_hz,
|
||||
&hal_ctx->special_timing[dev].vo_special_timing_sel, vo_lcd_divider_priority);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = hal_vo_set_intf_clock(&hal_ctx->clock_config, dev, clk_reverse_en, intf_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_clock_enable(xmedia_vo_dev dev, xmedia_intf_type intf_type, xmedia_bool clk_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_dev_div_clock_enable(&hal_ctx->clock_config, dev, clk_en);
|
||||
hal_vo_set_dev_clock_enable(&hal_ctx->clock_config, dev, clk_en);
|
||||
hal_vo_set_intf_clock_enable(&hal_ctx->clock_config, intf_type, clk_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_intf_detach_dev(xmedia_vo_dev dev, xmedia_intf_type intf_type)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_intf_detach_dev(&hal_ctx->clock_config, dev, intf_type);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_top_regup_enable(xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_top_regup(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_top_regup_enable(xmedia_void)
|
||||
{
|
||||
xmedia_bool enable = XMEDIA_FALSE;
|
||||
hal_vo_get_top_regup(&enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_regup_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_intf_regup(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_dev_intf_regup_state(xmedia_vo_dev dev)
|
||||
{
|
||||
xmedia_bool state = XMEDIA_FALSE;
|
||||
hal_vo_get_intf_regup(dev, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_regup_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_video_regup_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_layer_regup_enable(xmedia_vo_layer layer)
|
||||
{
|
||||
xmedia_bool enable = XMEDIA_FALSE;
|
||||
hal_vo_get_video_regup(layer, &enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_interrupt_state(vo_int_state_type type, xmedia_u32 *state)
|
||||
{
|
||||
if (type == VO_INT_STATE_TYPE_MASK) {
|
||||
*state = hal_vo_get_mask_interrupt_state();
|
||||
} else if (type == VO_INT_STATE_TYPE_UNMASK) {
|
||||
*state = hal_vo_get_unmask_interrupt_state();
|
||||
} else {
|
||||
*state = hal_vo_get_mask_interrupt_state();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clean_interrupt_state(vo_int_state_type type, vo_isr_interrupt_type state)
|
||||
{
|
||||
if (type == VO_INT_STATE_TYPE_UNMASK) {
|
||||
hal_vo_clear_lowband_state(XMEDIA_TRUE);
|
||||
} else {
|
||||
hal_vo_clear_mask_interrupt_state(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_interrupt_enable(vo_isr_interrupt_type int_type, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mask_interrupt_enable(int_type, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_int_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, vo_isr_field_flag int_mode)
|
||||
{
|
||||
xmedia_bool frame_mode;
|
||||
|
||||
if ((int_mode == VO_ISR_FIELD_FLAG_TOP) || (int_mode == VO_ISR_FIELD_FLAG_BOTTOM) ||
|
||||
(int_mode == VO_ISR_FIELD_FLAG_TOP_BOTTOM)) {
|
||||
frame_mode = XMEDIA_TRUE;
|
||||
} else {
|
||||
frame_mode = XMEDIA_FALSE;
|
||||
}
|
||||
hal_vo_set_intf_vtt_mode(dev, vtt_id, frame_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 thd)
|
||||
{
|
||||
//设置中断有效区计数
|
||||
hal_vo_set_intf_vtt_sel(dev, vtt_id, 1);
|
||||
hal_vo_set_intf_vtt_thd(dev, vtt_id, thd);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate)
|
||||
{
|
||||
hal_vo_get_intf_state(dev, btm, vcnt, vstate);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id)
|
||||
{
|
||||
hal_vo_set_cbm_mixer_prio(dev, prio_id);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_cbm_bgcolor(dev, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor)
|
||||
{
|
||||
xmedia_u32 color;
|
||||
hal_vo_get_cbm_bgcolor(dev, &color);
|
||||
*bgcolor = color;
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_csc_en(xmedia_vo_dev dev, xmedia_bool csc_en)
|
||||
{
|
||||
hal_vo_set_intf_csc_en(dev, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_csc_en(xmedia_vo_dev dev, xmedia_bool *csc_en)
|
||||
{
|
||||
hal_vo_get_intf_csc_en(dev, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_dev_csc_coef(xmedia_vo_dev dev, vo_pic_info* pic_info)
|
||||
{
|
||||
vo_csc_coef csc_matrix;
|
||||
|
||||
if (hal_vo_csc_coef_convert(pic_info, &csc_matrix) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
hal_vo_set_intf_csc(dev, &csc_matrix);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*以下关于特殊时序计算均参考 “VOUT_MIPI 时序配置说明.excel”,
|
||||
*以下计算得到的值都是非-1 计算,而excel中的寄存器值都是-1运算
|
||||
*/
|
||||
static xmedia_void hal_vo_calc_special_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing, mipi_phy_config *mipi_phy_cfg)
|
||||
{
|
||||
xmedia_s32 cycle_n = 0;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
vo_intf_special_timing * special_timing = &hal_ctx->special_timing[dev];
|
||||
xmedia_u32 fixed_clock_hz;
|
||||
xmedia_s32 htotal_adjust_value;
|
||||
xmedia_s32 vsync_adjust_value;
|
||||
|
||||
switch(intf_config->intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
//cycle_n表示单个像素时钟倍数,lcd串行配置为3,并行为1,bt656并行yuv为2
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_LCD) &&
|
||||
(intf_config->lcd_attr.data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL)) {
|
||||
cycle_n = 3;
|
||||
} else if (intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) {
|
||||
cycle_n = 2;
|
||||
} else {
|
||||
cycle_n = 1;
|
||||
}
|
||||
if (hal_vo_get_intf_clock(&hal_ctx->clock_config, dev, &fixed_clock_hz) != XMEDIA_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
/* =INT(1/I4/(I9+I10+I11+I12)/(1/(I26/I23)/10^6))
|
||||
* (1/(frame_rate * (vbb + vfb + vact))) / (1/((fixed_clock_Mz/cycle_n) * 10^6))
|
||||
* ((fixed_clock_Mz/cycle_n) * 10^6) / (frame_rate * (vbb + vfb + vact))
|
||||
* (fixed_clock_hz/cycle_n) / (frame_rate * (vbb + vfb + vact))
|
||||
*/
|
||||
special_timing->fixed_clk_htotal = (fixed_clock_hz / cycle_n) / (frame_rate * (sync_timing->vbb +
|
||||
sync_timing->vfb + sync_timing->vact));
|
||||
/* (I27-I31-1)/2-1
|
||||
* (special_timing->fixed_clk_htotal - sync_timing->hact) / 2
|
||||
* 表格运算会出现小数,和逻辑沟通,向下取整忽略小数部分
|
||||
*/
|
||||
special_timing->fixed_clk_hbb = (special_timing->fixed_clk_htotal - sync_timing->hact) / 2;
|
||||
/* I27-(I31+1)-(I29+1)-1
|
||||
* fixed_clk_hfb - hact - hbb
|
||||
*/
|
||||
special_timing->fixed_clk_hfb = special_timing->fixed_clk_htotal - sync_timing->hact -
|
||||
special_timing->fixed_clk_hbb;
|
||||
|
||||
special_timing->vs_st_v_filed = sync_timing->vfb;
|
||||
special_timing->vs_end_v_filed = special_timing->vs_st_v_filed + sync_timing->vpw;
|
||||
VO_TRACE(MODULE_DBG_DEBUG,
|
||||
"fixed_clk_htotal %d fixed_clock_hz %d fixed_clk_hbb %d fixed_clk_hfb %d\n",
|
||||
special_timing->fixed_clk_htotal, fixed_clock_hz,
|
||||
special_timing->fixed_clk_hbb, special_timing->fixed_clk_hfb);
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "vs_st_v_filed %d vs_end_v_filed %d\n",
|
||||
special_timing->vs_st_v_filed, special_timing->vs_end_v_filed);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
if (hal_vo_get_intf_clock(&hal_ctx->clock_config, dev, &fixed_clock_hz) != XMEDIA_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
htotal_adjust_value = (vo_mipi_htotal_adjust_value != 0) ? vo_mipi_htotal_adjust_value :
|
||||
mipi_phy_cfg->phy_htotal_adjust;
|
||||
vsync_adjust_value = (vo_mipi_vsync_adjust_value != 0) ? vo_mipi_vsync_adjust_value :
|
||||
mipi_phy_cfg->phy_vsync_adjust;
|
||||
/*
|
||||
* INT(D20/D15*D26) + FIXCLOCK_HTOTAL_AJUST_VALUE
|
||||
* hal_ctx->mipi_phy_cfg.phy_vid_hline_time * fixed_clock_Mhz / phy_lanebyte_clock_hzMhz + AJUST
|
||||
* hal_ctx->mipi_phy_cfg.phy_vid_hline_time * fixed_clock_hz / phy_lanebyte_clock_hzhz + AJUST
|
||||
* hal_ctx->mipi_phy_cfg.phy_vid_hline_time * (fixed_clock_hz/1000) / (phy_lanebyte_clock_hzhz/1000) + AJUST
|
||||
*/
|
||||
special_timing->fixed_clk_htotal = (hal_ctx->mipi_phy_cfg.phy_vid_hline_time * (fixed_clock_hz/1000)) /
|
||||
(hal_ctx->mipi_phy_cfg.phy_lanebyte_clock_hz/1000) + htotal_adjust_value;
|
||||
|
||||
// = D7 => hbp => hbb - hpw
|
||||
special_timing->fixed_clk_hbb = sync_timing->hbb - sync_timing->hpw;
|
||||
|
||||
// D29-(D33+1)-(D31+1) => fixed_clk_htotal - vact - fixed_clk_hbb
|
||||
special_timing->fixed_clk_hfb = special_timing->fixed_clk_htotal - sync_timing->hact -
|
||||
special_timing->fixed_clk_hbb;
|
||||
|
||||
// D34 + 1 + D28 => vfb + 1 + FIXCLOCK_VSYNC_AJUST_VALUE
|
||||
special_timing->vs_st_v_filed = sync_timing->vfb + 1 + vsync_adjust_value - 1;
|
||||
|
||||
// D39 + D21 => vs_st_v_filed + vpw
|
||||
special_timing->vs_end_v_filed = special_timing->vs_st_v_filed + sync_timing->vpw;
|
||||
|
||||
VO_TRACE(MODULE_DBG_DEBUG,
|
||||
"fixed_clk_htotal %d phy_vid_hline_time %d fixed_clock_hz %d phy_lanebyte_clock_hz %d! fixed_clk_hbb %d fixed_clk_hfb %d\n",
|
||||
special_timing->fixed_clk_htotal, hal_ctx->mipi_phy_cfg.phy_vid_hline_time, fixed_clock_hz,
|
||||
hal_ctx->mipi_phy_cfg.phy_lanebyte_clock_hz, special_timing->fixed_clk_hbb, special_timing->fixed_clk_hfb);
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "vs_st_v_filed %d vs_end_v_filed %d\n",
|
||||
special_timing->vs_st_v_filed, special_timing->vs_end_v_filed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing)
|
||||
{
|
||||
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
#ifdef VO_KERNEL
|
||||
ddr_ost_info ost_value;
|
||||
#endif
|
||||
hal_vo_set_intf_cnt_pos(dev);
|
||||
|
||||
if (hal_ctx->special_timing[dev].vo_special_timing_sel) {
|
||||
hal_vo_calc_special_timing(dev, frame_rate, intf_config, sync_timing, &hal_ctx->mipi_phy_cfg);
|
||||
}
|
||||
hal_vo_set_intf_timing(dev, frame_rate, intf_config, sync_timing, &hal_ctx->special_timing[dev]);
|
||||
hal_vo_set_intf_fifo(dev, VO_FIFO_DEPTH);
|
||||
#ifdef VO_KERNEL
|
||||
drv_ddr_get_ost(XMEDIA_MOD_ID_VO, &ost_value);
|
||||
#endif
|
||||
|
||||
hal_vo_set_dma_standing(dev, 8);
|
||||
|
||||
switch(intf_config->intf_type){
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
hal_vo_set_bt656_intf_cfg(dev, &(intf_config->bt656_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
hal_vo_set_bt1120_intf_cfg(dev, &(intf_config->bt1120_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
hal_vo_set_lcd_intf_cfg(dev, &(intf_config->lcd_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
hal_vo_set_mipi_intf_cfg(dev, &(intf_config->mipi_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
hal_vo_set_lvds_intf_cfg(dev, &(intf_config->lvds_attr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//intf 时钟相关绑定及门控 在前级set crg中做了
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
xmedia_bool intf_en[XMEDIA_VO_DEV_MAX];
|
||||
xmedia_vo_dev i;
|
||||
|
||||
hal_vo_set_intf_enable(dev, enable);
|
||||
|
||||
for (i = 0; i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
hal_vo_get_intf_enable(i, &intf_en[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_intf_enable(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_enable(layer,enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_bg_color(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_bgcolor(layer, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_mute_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mute_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_mute_enable(layer, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_csc_en(xmedia_vo_layer layer, xmedia_bool csc_en)
|
||||
{
|
||||
hal_vo_set_csc_en(layer, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_layer_csc_coef(xmedia_vo_layer layer, vo_pic_info* pic_info)
|
||||
{
|
||||
vo_csc_coef csc_matrix;
|
||||
xmedia_bool multi_en;
|
||||
|
||||
hal_vo_set_alpha(layer, 0xFF);
|
||||
|
||||
if (hal_vo_csc_coef_convert(pic_info, &csc_matrix) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
hal_vo_get_multi_enable(layer, &multi_en);
|
||||
if (multi_en == XMEDIA_TRUE) {
|
||||
hal_vo_set_mrg0_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg1_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg2_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg3_csc(layer, &csc_matrix);
|
||||
} else {
|
||||
//单区域的csc复用多区域0的csc
|
||||
hal_vo_set_csc(layer, &csc_matrix);
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
hal_vo_set_disp_rect(layer, disp_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
hal_vo_get_disp_rect(layer, disp_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
//单区域模式 设定真实内容相对于层的rect
|
||||
xmedia_void hal_vo_set_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect)
|
||||
{
|
||||
hal_vo_set_src_rect(layer, reso_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect)
|
||||
{
|
||||
hal_vo_get_src_rect(layer, reso_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_pixel_format(xmedia_vo_layer layer, xmedia_video_pixel_format pix_format)
|
||||
{
|
||||
vo_pixel_format format = VO_PIXEL_FMT_YUV_420;
|
||||
xmedia_bool uv_order = 0;
|
||||
|
||||
//注意下逻辑的排序与应用理解的UV是方向的
|
||||
if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 1;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 0;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) {
|
||||
format = VO_PIXEL_FMT_YUV_422;
|
||||
uv_order = 1;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) {
|
||||
format = VO_PIXEL_FMT_YUV_422;
|
||||
uv_order = 0;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
|
||||
format = VO_PIXEL_FMT_YUV_400;
|
||||
uv_order = 0;
|
||||
} else {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 1;
|
||||
}
|
||||
hal_vo_set_src_pixel_format(layer, format, uv_order);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//单区域和多区域控制
|
||||
xmedia_void hal_vo_set_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_multi_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_multi_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_mrg_mute_color(layer, region_id, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_single_region_cfg(xmedia_vo_layer layer, vo_layer_single_cfg *single_cfg)
|
||||
{
|
||||
//真实内容 相对于显示窗口的rect
|
||||
hal_vo_set_src_rect(layer, &(single_cfg->frame_rect));
|
||||
//层 相对于显示窗口的rect
|
||||
hal_vo_set_dst_rect(layer, &(single_cfg->video_rect));
|
||||
hal_vo_set_addr(layer, &(single_cfg->frame_addr));
|
||||
hal_vo_set_mute_enable(layer, single_cfg->mute_en);
|
||||
hal_vo_set_mrg_rdma1_en(layer, XMEDIA_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_multi_region_cfg(xmedia_vo_layer layer, vo_layer_multi_cfg *multi_cfg)
|
||||
{
|
||||
xmedia_u32 id;
|
||||
|
||||
id = multi_cfg->region_id;
|
||||
hal_vo_set_mrg_enable(layer, id, multi_cfg->region[id].enable);
|
||||
hal_vo_set_mrg_src_rect(layer,id, &(multi_cfg->region[id].src_rect));
|
||||
hal_vo_set_mrg_dst_rect(layer,id, &(multi_cfg->region[id].dst_rect));
|
||||
hal_vo_set_mrg_addr(layer,id, &(multi_cfg->region[id].region_addr));
|
||||
|
||||
if (multi_cfg->region_overlap) {
|
||||
hal_vo_set_mrg_rdma1_en(layer, XMEDIA_TRUE);
|
||||
//rdma0+rdma1 rdma1绑定优先级最高的
|
||||
hal_vo_set_mrg_mixer_prio(layer, VO_MRG_MIX_PRIO_RDMA0);
|
||||
hal_vo_set_mrg_rdma1_link(layer, multi_cfg->overlap_id);
|
||||
} else {
|
||||
hal_vo_set_mrg_rdma1_en(layer, XMEDIA_FALSE);
|
||||
hal_vo_set_mrg_mixer_prio(layer, VO_MRG_MIX_PRIO_RDMA0);
|
||||
}
|
||||
//sort的配置会影响画面的输出
|
||||
hal_vo_set_mrg_sort(layer, multi_cfg->region_sort);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_debug_pattern(xmedia_vo_dev dev, vo_pattern_info *pattern_info)
|
||||
{
|
||||
hal_vo_set_intf_mute_enable(dev, pattern_info->pattern_en);
|
||||
hal_vo_set_intf_mute_pattern_mode(dev, pattern_info->pattern_mode);
|
||||
hal_vo_set_intf_mute_data_mode(dev, pattern_info->data_mode);
|
||||
hal_vo_set_intf_mute_color(dev, pattern_info->color, pattern_info->color);
|
||||
hal_vo_set_intf_cbar_sel(dev, pattern_info->rgb);
|
||||
if (pattern_info->pattern_mode == VO_PATTERN_MODE_CHECKER) {
|
||||
hal_vo_set_intf_checkbar_size(dev, pattern_info->width, pattern_info->height);
|
||||
hal_vo_set_intf_mute_color(dev, pattern_info->color, !(pattern_info->color));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_debug_pattern(xmedia_vo_layer layer, vo_pattern_info *pattern_info)
|
||||
{
|
||||
vo_pattern_mode mode = VO_PATTERN_MODE_FULLCOLOR;
|
||||
|
||||
mode = pattern_info->pattern_mode;
|
||||
if ((mode != VO_PATTERN_MODE_FULLCOLOR) && (mode != VO_PATTERN_MODE_CHECKER)) {
|
||||
mode = VO_PATTERN_MODE_FULLCOLOR;
|
||||
}
|
||||
hal_vo_set_mute_enable(layer, pattern_info->pattern_en);
|
||||
hal_vo_set_mute_pattern_mode(layer, pattern_info->pattern_mode);
|
||||
hal_vo_set_mute_data_mode(layer, pattern_info->data_mode);
|
||||
hal_vo_set_mute_color(layer, pattern_info->color);
|
||||
if (mode == VO_PATTERN_MODE_CHECKER) {
|
||||
hal_vo_set_checkbar_size(layer, pattern_info->width, pattern_info->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_debug_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info)
|
||||
{
|
||||
hal_vo_set_intf_ink(dev, ink_info);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_debug_checksum(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v)
|
||||
{
|
||||
hal_vo_get_intf_checksum_value(dev, y, u,v);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_enable_dev_phy_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_u32 frame_rate,
|
||||
xmedia_vo_user_sync_timing *sync_timing,
|
||||
xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
vo_hal_context * hal_ctx = hal_vo_get_hal_context();
|
||||
|
||||
switch(intf_type){
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
ret = hal_vo_set_mipi_tx_phy_cfg(dev, frame_rate, sync_timing, &hal_ctx->mipi_phy_cfg,
|
||||
hal_ctx->special_timing[dev].vo_special_timing_sel);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
ret = hal_vo_enable_lvds_phy_cfg(clk_hz);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_disable_dev_phy_cfg(xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type){
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
hal_vo_set_mipi_tx_phy_reset();
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
hal_vo_disable_lvds_phy_cfg();
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 vo_calc_dev_phy_clk_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
|
||||
switch(intf_config->intf_type){
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
ret = vo_calculate_mipi_phy_cfg(dev, clk_hz, &intf_config->mipi_attr, &hal_ctx->mipi_phy_cfg);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef VO_KERNEL
|
||||
xmedia_void hal_vo_set_gamma_addr(xmedia_vo_dev dev)
|
||||
{
|
||||
hal_vo_gamma_set_addr(dev, g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_gamma_enable(dev, enable);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
hal_vo_gamma_set_table(dev, g_vo_gamma_buf[dev].gamma_virtual_addr, g_vo_gamma_buf[dev].gamma_mem_len, gamma_table);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
hal_vo_gamma_get_table(dev, g_vo_gamma_buf[dev].gamma_virtual_addr, g_vo_gamma_buf[dev].gamma_mem_len, gamma_table);
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_reg_record(xmedia_void)
|
||||
{
|
||||
|
||||
xmedia_u32 idx, section_num;
|
||||
xmedia_ulong offset = 0;
|
||||
xmedia_u32 malloc_size = 0;
|
||||
|
||||
section_num = sizeof(g_vo_reg_offset) / sizeof(xmedia_ulong) / OFFSET_ELE_NUM;
|
||||
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
malloc_size += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
|
||||
if (g_vo_reg_record != XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"g_vo_reg_record is not null,please check!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
} else {
|
||||
g_vo_reg_record = (xmedia_u8 *)osal_kmalloc(malloc_size, osal_gfp_kernel);
|
||||
}
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
osal_memcpy((xmedia_void *)((xmedia_uintptr_t)g_vo_reg_record + offset),
|
||||
(xmedia_void *)((xmedia_uintptr_t)g_p_vout_reg + g_vo_reg_offset[idx][0]), g_vo_reg_offset[idx][1]);
|
||||
offset += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_reg_restore(xmedia_void)
|
||||
{
|
||||
xmedia_u32 idx;
|
||||
xmedia_u32 section_num;
|
||||
xmedia_ulong offset = 0;
|
||||
|
||||
if (g_vo_reg_record == XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"g_vo_reg_record is null,please check!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
section_num = sizeof(g_vo_reg_offset) / sizeof(xmedia_ulong) / OFFSET_ELE_NUM;
|
||||
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
osal_memcpy((xmedia_void *)(xmedia_uintptr_t)((xmedia_ulong)(xmedia_uintptr_t)g_p_vout_reg + g_vo_reg_offset[idx][0]),
|
||||
(xmedia_void *)(xmedia_uintptr_t)((xmedia_ulong)(xmedia_uintptr_t)g_vo_reg_record + offset),
|
||||
g_vo_reg_offset[idx][1]);
|
||||
offset += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
osal_kfree(g_vo_reg_record);
|
||||
g_vo_reg_record = XMEDIA_NULL;
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#define VO_IRQ_NAME "intr_vo"
|
||||
#define VO_INTF_NOT_MIPI_MAX_WHIDTH 1920
|
||||
#define VO_INTF_NOT_MIPI_MAX_CLK 148500000
|
||||
#define VO_INTF_MIPI_MAX_CLK 297000000
|
||||
#define VO_IRQ_NUM_7606V1 47
|
||||
|
||||
xmedia_s32 g_vo_irq = VO_IRQ_NUM_7606V1;
|
||||
|
||||
static vo_base_cap g_vo_cap;
|
||||
static xmedia_bool g_vo_cap_is_inited = XMEDIA_FALSE;
|
||||
static vo_layer_cap g_layer_capability[XMEDIA_VO_LAYER_MAX];
|
||||
static vo_dev_cap g_dev_capability[XMEDIA_VO_DEV_MAX];
|
||||
|
||||
static xmedia_void vo_init_chip_capacity(xmedia_void)
|
||||
{
|
||||
g_vo_cap.irq_name = VO_IRQ_NAME;
|
||||
g_vo_cap.irq_num = g_vo_irq;
|
||||
g_vo_cap.irq_cpumask = 0;
|
||||
g_vo_cap.vo_phy_addr = 0x11420000;
|
||||
g_vo_cap.chip_name = "xm7606v1";
|
||||
g_vo_cap.chip_revision = 0;
|
||||
g_vo_cap.chip_type = 0;
|
||||
g_vo_cap.board_id =0;
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_init_chip_dev_capacity(xmedia_void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
g_dev_capability[i].support_video_layer_num = 1;
|
||||
g_dev_capability[i].support_gfx_layer_num = 1;
|
||||
g_dev_capability[i].support_max_layer_num = 2;
|
||||
g_dev_capability[i].support_intf_num = 1;
|
||||
g_dev_capability[i].support_csc_num = 3;
|
||||
if(i == XMEDIA_VO_DEV_1) {
|
||||
g_dev_capability[i].max_size.width = 1920;
|
||||
g_dev_capability[i].max_size.height = 1080;
|
||||
} else {
|
||||
g_dev_capability[i].max_size.width = 3840;
|
||||
g_dev_capability[i].max_size.height = 2160;
|
||||
}
|
||||
g_dev_capability[i].max_frame_rate = 60;
|
||||
g_dev_capability[i].support_ink = XMEDIA_TRUE;
|
||||
g_dev_capability[i].support_attach_layer = XMEDIA_FALSE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_init_chip_layer_capacity(xmedia_void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < XMEDIA_VO_LAYER_MAX; i++) {
|
||||
g_layer_capability[i].support_hdr = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_flip = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_mirror = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_zme = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_dcmp = XMEDIA_FALSE;
|
||||
|
||||
g_layer_capability[i].support_region = XMEDIA_TRUE;
|
||||
g_layer_capability[i].region_num = 4;
|
||||
if(i == XMEDIA_VO_DEV_1) {
|
||||
g_layer_capability[i].max_read_size.width = 1920;
|
||||
g_layer_capability[i].max_read_size.height = 1080;
|
||||
} else {
|
||||
g_layer_capability[i].max_read_size.width = 3840;
|
||||
g_layer_capability[i].max_read_size.height = 2160;
|
||||
}
|
||||
g_layer_capability[i].min_out_size.width = 32;
|
||||
g_layer_capability[i].min_out_size.height = 32;
|
||||
|
||||
g_layer_capability[i].support_max_bit_width = 8;
|
||||
g_layer_capability[i].support_pixformat_num = 5;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_bt656_attr(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if (bt656_attr->data_type != XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf not support data_type(%d) !\n", dev, bt656_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_UYVY) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_VYUY) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_YUYV) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_YVYU)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf not support data_seq(%d) !\n", dev, bt656_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_PAL) && (intf_sync != XMEDIA_VO_INTF_SYNC_NTSC) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_960H_PAL) && (intf_sync != XMEDIA_VO_INTF_SYNC_960H_NTSC)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_bt1120_attr(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if (bt1120_attr->data_type != XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf not support data_type(%d) !\n", dev, bt1120_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((bt1120_attr->data_seq != XMEDIA_INTF_BT1120_DATA_SEQ_UVUV) &&
|
||||
(bt1120_attr->data_seq != XMEDIA_INTF_BT1120_DATA_SEQ_VUVU)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf not support data_seq(%d) !\n", dev, bt1120_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080P24) && (intf_sync != XMEDIA_VO_INTF_SYNC_1080P25) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080P30) && (intf_sync != XMEDIA_VO_INTF_SYNC_1080I50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080I60) && (intf_sync != XMEDIA_VO_INTF_SYNC_1080P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_720P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_720P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_576P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_480P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_960H_PAL) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_960H_NTSC)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lcd_sync(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_intf_lcd_data_type data_type = lcd_attr->data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode = lcd_attr->data_mode;
|
||||
//XMEDIA_VO_INTF_SYNC_USER lcd 用户自定义时序 是否会有问题????
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_320x240_50) && (intf_sync != XMEDIA_VO_INTF_SYNC_240x320_50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 6bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_320x240_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 8bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 16bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 18bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_800x480_50) && (intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 24bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lcd_attr(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_intf_lcd_data_type data_type = lcd_attr->data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode = lcd_attr->data_mode;
|
||||
|
||||
if ((data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT) && (data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) &&
|
||||
(data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_type(%d) !\n", dev, data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((data_mode != XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_mode != XMEDIA_VO_LCD_DATA_MODE_PARA)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_mode(%d) !\n", dev, data_mode);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_RGB) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_RBG) &&
|
||||
(lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_GRB) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_GBR) &&
|
||||
(lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_BRG) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_BGR)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_seq(%d) !\n", dev, lcd_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) {
|
||||
if ((data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) && (data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf support 18&24 bit in serial mode(%d) !\n", dev, data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
return vo_check_lcd_sync(dev, lcd_attr, intf_sync);
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_mipi_attr(xmedia_vo_dev dev, xmedia_vo_mipi_attr *mipi_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (!(CHIP_ONLY_SUPPORT_MIPITX() || CHIP_BOTH_SUPPORT_MIPITX_LVDSTX())) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf not support, CHIP_TYPE err!\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
#endif
|
||||
xmedia_s32 i, j;
|
||||
for (i = XMEDIA_VO_MIPI_LANE_DATA0; i < XMEDIA_VO_MIPI_LANE_MAX - 1; i++) {
|
||||
for (j = i + 1; j < XMEDIA_VO_MIPI_LANE_MAX; j++) {
|
||||
if (mipi_attr->lane_sel[i] == mipi_attr->lane_sel[j]) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf not support duplicate (lane sel[%d] and lane_sel[%d])!\n",
|
||||
dev, mipi_attr->lane_sel[i], mipi_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (mipi_attr->lane_sel[i] >= XMEDIA_VO_MIPI_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, mipi lane sel is out of support(%d) !\n",
|
||||
dev, mipi_attr->lane_sel[i]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (mipi_attr->lane_sel[j] >= XMEDIA_VO_MIPI_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, mipi lane sel is out of support(%d) !\n",
|
||||
dev, mipi_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = XMEDIA_VO_MIPI_LANE_DATA0; i < XMEDIA_VO_MIPI_LANE_MAX; i++) {
|
||||
if ((mipi_attr->lane_pn_swap[i] != XMEDIA_TRUE) && (mipi_attr->lane_pn_swap[i] != XMEDIA_FALSE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, mipi lane swap is out of support(%d) !\n",
|
||||
dev, mipi_attr->lane_pn_swap[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
if ((mipi_attr->data_type != XMEDIA_INTF_MIPI_DSI_DATA_TYPE_YUV422_16BIT) &&
|
||||
(mipi_attr->data_type != XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB666_18BIT) &&
|
||||
(mipi_attr->data_type != XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB888_24BIT)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_type(%d) !\n", dev, mipi_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
//需要测试是否支持所有的这些分辨率
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(((intf_sync >= XMEDIA_VO_INTF_SYNC_3840x2160_50) && (intf_sync <= XMEDIA_VO_INTF_SYNC_4096x2160_60)) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_7680x4320_30) || (intf_sync == XMEDIA_VO_INTF_SYNC_PAL) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_NTSC) || (intf_sync == XMEDIA_VO_INTF_SYNC_960H_PAL) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_960H_NTSC) || (intf_sync == XMEDIA_VO_INTF_SYNC_1080I50) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_1080I60))) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (mipi_attr->mipi_lane_num < XMEDIA_VO_MIPI_LANE_DEFAULT || mipi_attr->mipi_lane_num >= XMEDIA_VO_MIPI_LANE_NUM_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev %d not support mipi_lane_num %d", dev, mipi_attr->mipi_lane_num);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (mipi_attr->mipi_lane_num == XMEDIA_VO_MIPI_LANE_DEFAULT) {
|
||||
mipi_attr->mipi_lane_num = XMEDIA_VO_MIPI_LANE_NUM4;
|
||||
VO_TRACE(MODULE_DBG_INFO, "mipi_lane_num %d\n", mipi_attr->mipi_lane_num);
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lvds_attr(xmedia_vo_dev dev, xmedia_vo_lvds_attr *lvds_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_s32 i, j;
|
||||
#ifdef VO_KERNEL
|
||||
if (!(CHIP_ONLY_SUPPORT_LVDSTX() || CHIP_BOTH_SUPPORT_MIPITX_LVDSTX())) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support, CHIP_TYPE err!\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
#endif
|
||||
if ((lvds_attr->data_type != XMEDIA_INTF_LVDS_DATA_TYPE_RGB666_18BIT) &&
|
||||
(lvds_attr->data_type != XMEDIA_INTF_LVDS_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support data_type(%d) !\n", dev, lvds_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((lvds_attr->format != XMEDIA_INTF_LVDS_FORMAT_VESA) && (lvds_attr->format != XMEDIA_INTF_LVDS_FORMAT_JEIDA)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support format(%d) !\n", dev, lvds_attr->format);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
for (i = XMEDIA_VO_LVDS_LANE_DATA0; i < XMEDIA_VO_LVDS_LANE_MAX - 1; i++) {
|
||||
for (j = i + 1; j < XMEDIA_VO_LVDS_LANE_MAX; j++) {
|
||||
if (lvds_attr->lane_sel[i] == lvds_attr->lane_sel[j]) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support duplicate (lane sel[%d] and lane_sel[%d])!\n",
|
||||
dev, lvds_attr->lane_sel[i], lvds_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (lvds_attr->lane_sel[i] >= XMEDIA_VO_LVDS_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf, lvds lane sel is out of support(%d) !\n",
|
||||
dev, lvds_attr->lane_sel[i]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (lvds_attr->lane_sel[j] >= XMEDIA_VO_LVDS_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf, lvds lane sel is out of support(%d) !\n",
|
||||
dev, lvds_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//需要测试是否支持所有的这些分辨率
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(((intf_sync >= XMEDIA_VO_INTF_SYNC_1920x2160_30) && (intf_sync <= XMEDIA_VO_INTF_SYNC_4096x2160_60)) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_7680x4320_30) || (intf_sync == XMEDIA_VO_INTF_SYNC_1920x1200_60) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_PAL) || (intf_sync == XMEDIA_VO_INTF_SYNC_NTSC) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_960H_PAL) || (intf_sync == XMEDIA_VO_INTF_SYNC_960H_NTSC) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_1080I50) || (intf_sync == XMEDIA_VO_INTF_SYNC_1080I60))) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_dev_size(xmedia_vo_dev dev, xmedia_intf_type intf_type,
|
||||
xmedia_video_size *dev_size) {
|
||||
if (VO_CHECK_VIRT_DEV(dev) == XMEDIA_TRUE) {
|
||||
if (dev_size->width > g_dev_capability[dev].max_size.width ||
|
||||
dev_size->height > g_dev_capability[dev].max_size.height) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev%d not support dev_size_width %d\n", dev, dev_size->width);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (dev_size->width > g_dev_capability[dev].max_size.width) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev%d not support dev_size_width %d\n", dev, dev_size->width);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//只有mipi支持 width>1920以上时序
|
||||
if ((dev_size->width > VO_INTF_NOT_MIPI_MAX_WHIDTH) && (intf_type != XMEDIA_INTF_TYPE_MIPI_DSI)) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "only mipi width support 1920+\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_intf(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_video_size *dev_size)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
if (vo_check_dev_size(dev, config->intf_config.intf_type, dev_size) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
//虚拟设备不需要后续的check
|
||||
if (VO_CHECK_VIRT_DEV(dev) == XMEDIA_TRUE) {
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
switch (config->intf_config.intf_type){
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
ret = vo_check_bt656_attr(dev, &(config->intf_config.bt656_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
ret = vo_check_bt1120_attr(dev, &(config->intf_config.bt1120_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
ret = vo_check_lcd_attr(dev, &(config->intf_config.lcd_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
ret = vo_check_mipi_attr(dev, &(config->intf_config.mipi_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
ret = vo_check_lvds_attr(dev, &(config->intf_config.lvds_attr), config->intf_sync);
|
||||
break;
|
||||
default:
|
||||
ret = XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_clk(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_u32 clk)
|
||||
{
|
||||
//dev=0 且 mipi 端子才支持297M时钟,否则只支持148.5M
|
||||
if ((dev == XMEDIA_VO_DEV_0) && (config->intf_config.intf_type == XMEDIA_INTF_TYPE_MIPI_DSI)) {
|
||||
if (clk > VO_INTF_MIPI_MAX_CLK) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hal_vo_check_clk err, clk %d\n", clk);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (clk > VO_INTF_NOT_MIPI_MAX_CLK) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hal_vo_check_clk err, clk %d\n", clk);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_csc_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config,
|
||||
xmedia_vo_dev_csc *dev_csc)
|
||||
{
|
||||
xmedia_bool mipi_rgb_en;
|
||||
|
||||
if (dev_csc->color_info.color_gamut == XMEDIA_VIDEO_COLOR_GAMUT_BT2020) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) color gamut should be bt601 or 709\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (((intf_config->intf_type == XMEDIA_INTF_TYPE_LCD) || (intf_config->intf_type == XMEDIA_INTF_TYPE_LVDS)) &&
|
||||
(dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_YUV)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) lcd/lvds should be output rgb\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (((intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) || (intf_config->intf_type == XMEDIA_INTF_TYPE_BT1120)) &&
|
||||
(dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_RGB)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) bt656/bt1120 should be output yuv\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (intf_config->intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) {
|
||||
if ((intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB666_18BIT) ||
|
||||
(intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB888_24BIT)){
|
||||
mipi_rgb_en = XMEDIA_TRUE;
|
||||
} else {
|
||||
mipi_rgb_en = XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
if ((mipi_rgb_en == XMEDIA_TRUE) && (dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_YUV)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d color space should be same as mipi output(%d,%d)\n",
|
||||
dev, mipi_rgb_en, dev_csc->color_info.color_space);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((mipi_rgb_en == XMEDIA_FALSE) && (dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_RGB)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d color space should be same as mipi output(%d,%d)\n",
|
||||
dev, mipi_rgb_en, dev_csc->color_info.color_space);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_gamma_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) || (intf_config->intf_type == XMEDIA_INTF_TYPE_BT1120)) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG,"Vo dev(%d) yuv output not support gamma set\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) &&
|
||||
(intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_YUV422_16BIT)) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG,"Vo dev(%d) yuv output not support gamma set\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_check_chip_type(vo_chip_type board_id)
|
||||
{
|
||||
if (board_id == VO_CHIP_TYPE_XM7606V1) {
|
||||
return XMEDIA_TRUE;
|
||||
} else {
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_layer_cap(xmedia_vo_layer layer, xmedia_u32 max_width, xmedia_u32 max_height,
|
||||
xmedia_vo_layer_config *layer_config)
|
||||
{
|
||||
if ((layer_config->img_size.width < g_layer_capability[layer].min_out_size.width) ||
|
||||
(layer_config->img_size.height < g_layer_capability[layer].min_out_size.height)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d image size(%d, %d) is illegaled, should biger than (%d,%d)!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height,
|
||||
g_layer_capability[layer].min_out_size.width, g_layer_capability[layer].min_out_size.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (layer_config->img_size.width > max_width || layer_config->img_size.height > max_height) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d image size width(%d %d) is illegaled, should less than(%d %d)!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height, max_width, max_height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((IS_ALIGN(layer_config->img_size.width, 2) != XMEDIA_TRUE) ||
|
||||
(IS_ALIGN(layer_config->img_size.height, 2) != XMEDIA_TRUE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d img size(%d, %d) dosen't aligned by 2 pixel!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_400)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d pix_format %d doesn't support!\n", layer, layer_config->pix_format);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
if (layer_config->bit_width != XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d bit_width %d doesn't support!\n", layer, layer_config->bit_width);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
if (layer_config->part_mode >= XMEDIA_VO_PARTITION_MODE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d part mode %d is illegal!\n", layer, layer_config->part_mode);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_layer_frame(xmedia_vo_layer layer, xmedia_video_frame_info *frame_info)
|
||||
{
|
||||
xmedia_u32 valid_width;
|
||||
xmedia_u32 valid_height;
|
||||
|
||||
valid_width = g_layer_capability[layer].min_out_size.width;
|
||||
valid_height = g_layer_capability[layer].min_out_size.height;
|
||||
if ((frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input pixel format %d!\n", frame_info->frame.pixel_fmt);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.width < valid_width) || (frame_info->frame.height < valid_height) ||
|
||||
(IS_ALIGN(frame_info->frame.width, 2) != XMEDIA_TRUE) ||
|
||||
(IS_ALIGN(frame_info->frame.width, 2) != XMEDIA_TRUE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"pic width(%d) is smaller than min width 32 or pic height(%d) is smaller than"
|
||||
"min height 32 or not align2!!\n", frame_info->frame.width, frame_info->frame.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.dynamic_range != XMEDIA_VIDEO_DYNAMIC_RANGE_SDR) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input dynamic range%d!\n", frame_info->frame.dynamic_range);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input compress mode%d!\n", frame_info->frame.compress_mode);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input video format%d!\n", frame_info->frame.video_fmt);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.bit_width != XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input bit width%d!\n", frame_info->frame.bit_width);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.color_info.color_space != XMEDIA_VIDEO_COLOR_SPACE_YUV) ||
|
||||
(frame_info->frame.color_info.color_gamut == XMEDIA_VIDEO_COLOR_GAMUT_BT2020) ||
|
||||
(frame_info->frame.color_info.color_gamut >= XMEDIA_VIDEO_COLOR_GAMUT_MAX) ||
|
||||
(frame_info->frame.color_info.quantify_range >= XMEDIA_VIDEO_COLOR_RANGE_MAX)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input color info:space-gamut-range(%d-%d-%d)!\n",
|
||||
frame_info->frame.color_info.color_space,
|
||||
frame_info->frame.color_info.color_gamut,frame_info->frame.color_info.quantify_range);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_init_chip_capaciblity(xmedia_void)
|
||||
{
|
||||
if (g_vo_cap_is_inited == XMEDIA_TRUE) {
|
||||
return;
|
||||
}
|
||||
g_vo_cap_is_inited = XMEDIA_TRUE;
|
||||
|
||||
vo_init_chip_capacity();
|
||||
vo_init_chip_dev_capacity();
|
||||
vo_init_chip_layer_capacity();
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vo_get_chip_revision(xmedia_void)
|
||||
{
|
||||
return g_vo_cap.chip_revision;
|
||||
}
|
||||
|
||||
vo_base_cap *hal_vo_get_chip_capacity(xmedia_void)
|
||||
{
|
||||
return &g_vo_cap;
|
||||
}
|
||||
|
||||
vo_layer_cap *hal_get_layer_chip_capacity(xmedia_vo_layer layer)
|
||||
{
|
||||
return &g_layer_capability[layer];
|
||||
}
|
||||
|
||||
vo_dev_cap *hal_get_dev_chip_capacity(xmedia_vo_dev dev)
|
||||
{
|
||||
return &g_dev_capability[dev];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CHIP_CFG_H__
|
||||
#define __HAL_VO_CHIP_CFG_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_CHIP_INTF_TYPE_BT656 = 1 << 0,
|
||||
VO_CHIP_INTF_TYPE_BT1120 = 1 << 1,
|
||||
VO_CHIP_INTF_TYPE_LCD = 1 << 2,
|
||||
VO_CHIP_INTF_TYPE_LVDS = 1 << 3,
|
||||
VO_CHIP_INTF_TYPE_MIPI_DSI = 1 << 4,
|
||||
VO_CHIP_INTF_TYPE_MAX
|
||||
} vo_chip_intf_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CHIP_TYPE_XM7606V1,
|
||||
VO_CHIP_TYPE_MAX
|
||||
} vo_chip_type;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool support_hdr;
|
||||
xmedia_bool support_flip;
|
||||
xmedia_bool support_mirror;
|
||||
xmedia_bool support_zme;
|
||||
xmedia_bool support_dcmp;
|
||||
xmedia_bool support_region;
|
||||
xmedia_u32 region_num;
|
||||
xmedia_video_size max_read_size;
|
||||
xmedia_video_size min_out_size;
|
||||
xmedia_u32 support_max_bit_width;
|
||||
xmedia_u32 support_pixformat_num;
|
||||
} vo_layer_cap;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 support_video_layer_num;
|
||||
xmedia_u32 support_gfx_layer_num;
|
||||
xmedia_u32 support_max_layer_num;
|
||||
xmedia_u32 support_intf_num;
|
||||
xmedia_u32 support_csc_num;
|
||||
xmedia_video_size max_size;
|
||||
xmedia_bool support_ink;
|
||||
xmedia_bool support_attach_layer;
|
||||
xmedia_u32 max_frame_rate;
|
||||
} vo_dev_cap;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 vo_phy_addr;
|
||||
xmedia_u32 board_id;
|
||||
xmedia_u32 irq_num;
|
||||
xmedia_u32 irq_cpumask;
|
||||
xmedia_u32 chip_revision;
|
||||
xmedia_u32 chip_type;
|
||||
xmedia_char *chip_name;
|
||||
xmedia_char *irq_name;
|
||||
} vo_base_cap;
|
||||
|
||||
xmedia_bool hal_vo_check_chip_type(vo_chip_type board_id);
|
||||
xmedia_void hal_vo_init_chip_capaciblity(xmedia_void);
|
||||
xmedia_u32 hal_vo_get_chip_revision(xmedia_void);
|
||||
xmedia_s32 hal_vo_check_layer_cap(xmedia_vo_layer layer, xmedia_u32 max_width, xmedia_u32 max_height,
|
||||
xmedia_vo_layer_config *layer_config);
|
||||
xmedia_s32 hal_vo_check_dev_intf(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_video_size *dev_size);
|
||||
xmedia_s32 hal_vo_check_clk(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_u32 clk);
|
||||
xmedia_s32 hal_vo_check_dev_size(xmedia_vo_dev dev, xmedia_u32 width, xmedia_u32 height);
|
||||
xmedia_s32 hal_vo_check_dev_csc_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config,
|
||||
xmedia_vo_dev_csc *dev_csc);
|
||||
xmedia_s32 hal_vo_check_dev_gamma_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config);
|
||||
xmedia_s32 hal_vo_check_layer_frame(xmedia_vo_layer layer, xmedia_video_frame_info *frame_info);
|
||||
vo_base_cap *hal_vo_get_chip_capacity(xmedia_void);
|
||||
vo_layer_cap* hal_get_layer_chip_capacity(xmedia_vo_layer layer);
|
||||
vo_dev_cap* hal_get_dev_chip_capacity(xmedia_vo_dev dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO__CHIP_CFG_H__ */
|
||||
+17373
File diff suppressed because it is too large
Load Diff
+7889
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_INTF_H__
|
||||
#define __HAL_VO_INTF_H__
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
#include "hal_vo_clock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum{
|
||||
VO_INTF_HS_MODE_RF = 0, //vsyn对应的上升沿和下降沿都有效
|
||||
VO_INTF_HS_MODE_RF_NONE, //vsyn对应的上升沿和下降沿都无效
|
||||
VO_INTF_HS_MODE_FALLING,
|
||||
VO_INTF_HS_MODE_RISING,
|
||||
VO_INTF_HS_MODE_MAX,
|
||||
}vo_intf_hs_mode;
|
||||
|
||||
typedef struct{
|
||||
xmedia_bool hcds_en;
|
||||
xmedia_bool hcds_mode;
|
||||
xmedia_u8 hcds_coef_0;
|
||||
xmedia_u8 hcds_coef_1;
|
||||
xmedia_u8 hcds_coef_2;
|
||||
xmedia_u8 hcds_coef_3;
|
||||
}vo_intf_hcds;
|
||||
|
||||
typedef struct{
|
||||
xmedia_bool clip_en;
|
||||
xmedia_u32 clip_l;
|
||||
xmedia_u32 clip_h;
|
||||
}vo_intf_clip;
|
||||
|
||||
typedef struct{
|
||||
xmedia_u16 top_start;
|
||||
xmedia_u16 top_end;
|
||||
xmedia_u16 bottom_start;
|
||||
xmedia_u16 bottom_end;
|
||||
}vo_intf_bt_sync;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool ink_en;
|
||||
xmedia_bool cross_en;
|
||||
xmedia_bool color_reverse;
|
||||
xmedia_u32 color;
|
||||
xmedia_u32 x;
|
||||
xmedia_u32 y;
|
||||
} vo_csc_ink_info;
|
||||
|
||||
typedef struct {
|
||||
vo_clock_priority_sel vo_clock_priority_sel; //debug 接口 1:lcd分频器优先,0:固定频点优先
|
||||
xmedia_bool vo_special_timing_sel; //true表示使用固定分频,需要配置特殊时序,否则使用默认时序
|
||||
xmedia_u32 fixed_clk_htotal;
|
||||
xmedia_u32 fixed_clk_hbb;
|
||||
xmedia_u32 fixed_clk_hfb;
|
||||
xmedia_u32 vs_st_v_filed;
|
||||
xmedia_u32 vs_end_v_filed;
|
||||
} vo_intf_special_timing;
|
||||
|
||||
typedef struct{
|
||||
xmedia_u32 phy_clk_cfg; //mipi phy clock 需要配置给mipi ctrl,根据dev clk_hz 和 mipi ctrl计算公式得到
|
||||
xmedia_u32 phy_vid_hline_time; //mipi phy hline time
|
||||
xmedia_u32 phy_lanebyte_clock_hz;
|
||||
xmedia_u32 phy_master_swap; //mipi lane序配置
|
||||
xmedia_s32 phy_htotal_adjust;
|
||||
xmedia_s32 phy_vsync_adjust;
|
||||
xmedia_vo_mipi_lane_num phy_lane_num; //mipi lane数量
|
||||
} mipi_phy_config;
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 size;
|
||||
xmedia_u8 *array;
|
||||
} vo_mipi_lcd_config;
|
||||
|
||||
xmedia_void hal_vo_set_intf_fifo(xmedia_vo_dev dev, xmedia_u32 fifo);
|
||||
xmedia_void hal_vo_set_intf_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_chk_sum_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_hs_mode(xmedia_vo_dev dev, vo_intf_hs_mode hs_mode);
|
||||
xmedia_void hal_vo_set_intf_mux(xmedia_vo_dev dev, xmedia_intf_type intf);
|
||||
xmedia_void hal_vo_set_intf_regup(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_cnt_pos(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing, vo_intf_special_timing *special_timing);
|
||||
xmedia_void hal_vo_set_intf_sync_inverse(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_intf_vtt_sel(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool cnt_mode);
|
||||
xmedia_void hal_vo_set_intf_vtt_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool frame_mode);
|
||||
xmedia_void hal_vo_set_intf_vtt_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 vtt_thd);
|
||||
xmedia_void hal_vo_get_intf_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate);
|
||||
xmedia_void hal_vo_get_intf_checksum_value(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v);
|
||||
xmedia_void hal_vo_set_intf_bt_mode(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_yc_order(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_uv_order(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_vbit_mode(xmedia_vo_dev dev, xmedia_bool sync_mode);
|
||||
xmedia_void hal_vo_set_intf_bt_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_bt_user_sync(xmedia_vo_dev dev, vo_intf_bt_sync *sync);
|
||||
xmedia_void hal_vo_set_intf_lcd_mode(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_lcd_rgb_order(xmedia_vo_dev dev, xmedia_u8 order0, xmedia_u8 order1);
|
||||
xmedia_void hal_vo_set_intf_lcd_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_mute_pattern_mode(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_mute_data_mode(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_checkbar_size(xmedia_vo_dev dev, xmedia_u8 width, xmedia_u8 height);
|
||||
xmedia_void hal_vo_set_intf_cbar_sel(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_mute_color(xmedia_vo_dev dev, xmedia_u32 white_color, xmedia_u32 black_color);
|
||||
xmedia_void hal_vo_set_intf_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info);
|
||||
xmedia_void hal_vo_set_intf_clip(xmedia_vo_dev dev, vo_intf_clip *intf_clip);
|
||||
xmedia_void hal_vo_set_intf_csc_en(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_csc_en(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_csc(xmedia_vo_dev dev, vo_csc_coef *intf_csc);
|
||||
xmedia_void hal_vo_set_intf_hcds(xmedia_vo_dev dev, vo_intf_hcds *intf_hcds);
|
||||
xmedia_void hal_vo_set_intf_dither_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_dither_thd(xmedia_vo_dev dev, xmedia_u8 thd_h, xmedia_u8 thd_l);
|
||||
xmedia_void hal_vo_set_bt656_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr);
|
||||
xmedia_void hal_vo_set_bt1120_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr);
|
||||
xmedia_void hal_vo_set_lcd_intf_cfg(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr);
|
||||
xmedia_void hal_vo_set_mipi_intf_cfg(xmedia_vo_dev dev, xmedia_vo_mipi_attr *mipi_attr);
|
||||
xmedia_void hal_vo_set_lvds_intf_cfg(xmedia_vo_dev dev, xmedia_vo_lvds_attr *lvds_attr);
|
||||
xmedia_s32 hal_vo_set_mipi_tx_phy_cfg(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_user_sync_timing *sync_timing, mipi_phy_config *mipi_phy_cfg, xmedia_bool special_timing_sel);
|
||||
xmedia_void hal_vo_set_mipi_tx_phy_reset(xmedia_void);
|
||||
xmedia_s32 hal_vo_enable_lvds_phy_cfg(xmedia_u32 clk_hz);
|
||||
xmedia_s32 hal_vo_disable_lvds_phy_cfg(xmedia_void);
|
||||
xmedia_s32 vo_calculate_mipi_phy_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_vo_mipi_attr *mipi_attr,
|
||||
mipi_phy_config* mipi_phy_cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user