amvecm: add overscan iocontrol

PD#162552: amvecm: add overscan iocontrol

Change-Id: I1aa4b2469e7360029a0c647a0a1e46c73c71e7cd
Signed-off-by: wenfeng.guo <wenfeng.guo@amlogic.com>
This commit is contained in:
wenfeng.guo
2018-03-21 10:44:00 +08:00
committed by Bencheng Jing
parent 807e56fcb4
commit 7e32eee308
4 changed files with 210 additions and 6 deletions

View File

@@ -2013,3 +2013,66 @@ void amve_sharpness_init(void)
{
am_set_regmap(&sr1reg_sd_scale);
}
static int overscan_timing = TIMING_MAX;
module_param(overscan_timing, uint, 0664);
MODULE_PARM_DESC(overscan_timing, "\n overscan_control\n");
static int overscan_screen_mode = 0xff;
module_param(overscan_screen_mode, uint, 0664);
MODULE_PARM_DESC(overscan_screen_mode, "\n overscan_screen_mode\n");
static int overscan_disable;
module_param(overscan_disable, uint, 0664);
MODULE_PARM_DESC(overscan_disable, "\n overscan_disable\n");
void amvecm_fresh_overscan(struct vframe_s *vf)
{
unsigned int height = 0;
unsigned int cur_overscan_timing = 0;
if (overscan_disable)
return;
if (overscan_table[0].load_flag) {
height = (vf->type & VIDTYPE_COMPRESS) ?
vf->compHeight : vf->height;
if (height <= 576)
cur_overscan_timing = TIMING_SD;
else if (height <= 720)
cur_overscan_timing = TIMING_HD;
else if (height <= 1088)
cur_overscan_timing = TIMING_FHD;
else
cur_overscan_timing = TIMING_UHD;
overscan_timing = cur_overscan_timing;
overscan_screen_mode =
overscan_table[overscan_timing].screen_mode;
vf->pic_mode.AFD_enable =
overscan_table[overscan_timing].afd_enable;
vf->pic_mode.screen_mode =
overscan_table[overscan_timing].screen_mode;
vf->pic_mode.hs = overscan_table[overscan_timing].hs;
vf->pic_mode.he = overscan_table[overscan_timing].he;
vf->pic_mode.vs = overscan_table[overscan_timing].vs;
vf->pic_mode.ve = overscan_table[overscan_timing].ve;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
}
}
void amvecm_reset_overscan(void)
{
if (overscan_disable)
return;
if (overscan_timing != TIMING_MAX) {
overscan_timing = TIMING_MAX;
if ((overscan_table[0].source != SOURCE_DTV) &&
(overscan_table[0].source != SOURCE_MPEG)) {
overscan_table[0].load_flag = 0;
overscan_screen_mode = 0xff;
}
}
}

View File

@@ -190,5 +190,7 @@ extern struct am_regs_s sr1reg_sd_scale;
extern struct am_regs_s sr1reg_hd_scale;
extern struct am_regs_s sr1reg_cvbs;
extern struct am_regs_s sr1reg_hv_noscale;
extern void amvecm_fresh_overscan(struct vframe_s *vf);
extern void amvecm_reset_overscan(void);
#endif

View File

@@ -911,6 +911,10 @@ int amvecm_on_vs(
return 0;
#endif
if (flags & CSC_FLAG_CHECK_OUTPUT) {
if (toggle_vf)
amvecm_fresh_overscan(toggle_vf);
else if (vf)
amvecm_fresh_overscan(vf);
/* to test if output will change */
return amvecm_matrix_process(
toggle_vf, vf, flags);
@@ -920,8 +924,10 @@ int amvecm_on_vs(
result = amvecm_matrix_process(toggle_vf, vf, flags);
if (toggle_vf)
ioctrl_get_hdr_metadata(toggle_vf);
} else
} else {
amvecm_reset_overscan();
result = amvecm_matrix_process(NULL, NULL, flags);
}
/* add some flag to trigger */
if (vf) {
@@ -940,6 +946,10 @@ int amvecm_on_vs(
vpp_demo_config(vf);
}
if (vf)
amvecm_fresh_overscan(vf);
else
amvecm_reset_overscan();
/* todo:vlock processs only for tv chip */
if (is_meson_gxtvbb_cpu() ||
is_meson_txl_cpu() || is_meson_txlx_cpu()
@@ -989,12 +999,20 @@ static int amvecm_release(struct inode *inode, struct file *file)
return 0;
}
static struct am_regs_s amregs_ext;
struct ve_pq_overscan_s overscan_table[TIMING_MAX];
static long amvecm_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret = 0;
void __user *argp;
int mem_size;
struct ve_pq_load_s vpp_pq_load;
struct ve_pq_table_s *vpp_pq_load_table = NULL;
int i = 0;
i = sizeof(struct ve_pq_load_s);
pr_info("sizeof(struct ve_pq_load_s) = %d", i);
pr_amvecm_dbg("[amvecm..] %s: cmd_nr = 0x%x\n",
__func__, _IOC_NR(cmd));
@@ -1149,10 +1167,59 @@ static long amvecm_ioctl(struct file *file,
case AMVECM_IOC_3D_SYNC_DIS:
vecm_latch_flag |= FLAG_3D_SYNC_DIS;
break;
case AMVECM_IOC_GET_OVERSCAN:
if (copy_from_user(&vpp_pq_load,
(void __user *)arg,
sizeof(struct ve_pq_load_s))) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] pq ioctl copy fail!!\n");
break;
}
if (!(vpp_pq_load.param_id & TABLE_NAME_OVERSCAN)) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] overscan ioctl param_id fail!!\n");
break;
}
mem_size = vpp_pq_load.length * sizeof(struct ve_pq_table_s);
vpp_pq_load_table = kmalloc(mem_size, GFP_KERNEL);
if (vpp_pq_load_table == NULL) {
pr_info("vpp_pq_load_table kmalloc fail!!!\n");
return -EFAULT;
}
argp = (void __user *)vpp_pq_load.param_ptr;
if (copy_from_user(vpp_pq_load_table, argp, mem_size)) {
pr_amvecm_dbg("[amvecm..] ovescan copy fail!!\n");
break;
}
for (i = 0; i < vpp_pq_load.length; i++) {
if (i >= TIMING_MAX)
break;
overscan_table[i].load_flag =
(vpp_pq_load_table[i].src_timing >> 31) & 0x1;
overscan_table[i].afd_enable =
(vpp_pq_load_table[i].src_timing >> 30) & 0x1;
overscan_table[i].screen_mode =
(vpp_pq_load_table[i].src_timing >> 24) & 0x3f;
overscan_table[i].source =
(vpp_pq_load_table[i].src_timing >> 16) & 0xff;
overscan_table[i].timing =
vpp_pq_load_table[i].src_timing & 0xffff;
overscan_table[i].hs =
vpp_pq_load_table[i].value1 & 0xffff;
overscan_table[i].he =
(vpp_pq_load_table[i].value1 >> 16) & 0xffff;
overscan_table[i].vs =
vpp_pq_load_table[i].value2 & 0xffff;
overscan_table[i].ve =
(vpp_pq_load_table[i].value2 >> 16) & 0xffff;
}
break;
default:
ret = -EINVAL;
break;
}
if (vpp_pq_load_table != NULL)
kfree(vpp_pq_load_table);
return ret;
}
#ifdef CONFIG_COMPAT

View File

@@ -115,11 +115,11 @@ enum pq_table_name_e {
TABLE_NAME_XVYCC = 0x10000, /*in vpp*/
TABLE_NAME_HDR = 0x20000, /*in vpp*/
TABLE_NAME_DOLBY_VISION = 0x40000,/*in vpp*/
TABLE_NAME_RESERVED1 = 0x80000,
TABLE_NAME_RESERVED2 = 0x100000,
TABLE_NAME_RESERVED3 = 0x200000,
TABLE_NAME_RESERVED4 = 0x400000,
TABLE_NAME_RESERVED5 = 0x800000,
TABLE_NAME_OVERSCAN = 0x80000,
TABLE_NAME_RESERVED1 = 0x100000,
TABLE_NAME_RESERVED2 = 0x200000,
TABLE_NAME_RESERVED3 = 0x400000,
TABLE_NAME_RESERVED4 = 0x800000,
TABLE_NAME_MAX,
};
@@ -154,6 +154,78 @@ enum pq_table_name_e {
#define AMVECM_IOC_3D_SYNC_EN _IO(_VE_CM, 0x49)
#define AMVECM_IOC_3D_SYNC_DIS _IO(_VE_CM, 0x50)
struct ve_pq_load_s {
enum pq_table_name_e param_id;
unsigned int length;
void *param_ptr;
void *reserved;
};
struct ve_pq_table_s {
unsigned int src_timing;
unsigned int value1;
unsigned int value2;
unsigned int reserved1;
unsigned int reserved2;
};
#define AMVECM_IOC_GET_OVERSCAN _IOR(_VE_CM, 0x52, struct ve_pq_load_s)
enum ve_source_input_e {
SOURCE_INVALID = -1,
SOURCE_TV = 0,
SOURCE_AV1,
SOURCE_AV2,
SOURCE_YPBPR1,
SOURCE_YPBPR2,
SOURCE_HDMI1,
SOURCE_HDMI2,
SOURCE_HDMI3,
SOURCE_HDMI4,
SOURCE_VGA,
SOURCE_MPEG,
SOURCE_DTV,
SOURCE_SVIDEO,
SOURCE_IPTV,
SOURCE_DUMMY,
SOURCE_SPDIF,
SOURCE_ADTV,
SOURCE_MAX,
};
enum ve_pq_timing_e {
TIMING_SD = 0,
TIMING_HD,
TIMING_FHD,
TIMING_UHD,
TIMING_MAX,
};
/*overscan:
*length 0~31bit :number of crop;
*src_timing: bit31: on: load/save all crop
bit31: off: load one according to timing*
bit30: AFD_enable: 1 -> on; 0 -> off*
screen mode: bit24~bit29*
source: bit16~bit23 -> source*
timing: bit0~bit15 -> sd/hd/fhd/uhd*
*value1: 0~15bit hs 16~31bit he*
*value2: 0~15bit vs 16~31bit ve*
*/
struct ve_pq_overscan_s {
unsigned int load_flag;
unsigned int afd_enable;
unsigned int screen_mode;
enum ve_source_input_e source;
enum ve_pq_timing_e timing;
unsigned int hs;
unsigned int he;
unsigned int vs;
unsigned int ve;
};
extern struct ve_pq_overscan_s overscan_table[TIMING_MAX];
#define _DI_ 'D'
struct am_pq_parm_s {