summaryrefslogtreecommitdiff
authorwenfeng.guo <wenfeng.guo@amlogic.com>2018-03-21 02:44:00 (GMT)
committer Xindong Xu <xindong.xu@amlogic.com>2018-05-02 02:10:04 (GMT)
commit3ab4eb317b58a8f1836929ed5677c6dcda1831fc (patch)
tree4c40f52cb5ab13d23e206f496b7a7319530525bd
parent81d4e869a840681a9caa3a6118d3de08f0e04740 (diff)
downloadcommon-3ab4eb317b58a8f1836929ed5677c6dcda1831fc.zip
common-3ab4eb317b58a8f1836929ed5677c6dcda1831fc.tar.gz
common-3ab4eb317b58a8f1836929ed5677c6dcda1831fc.tar.bz2
amvecm: add overscan iocontrol
PD#162552: amvecm: add overscan iocontrol Change-Id: I1aa4b2469e7360029a0c647a0a1e46c73c71e7cd Signed-off-by: wenfeng.guo <wenfeng.guo@amlogic.com>
Diffstat
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amve.c63
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amve.h2
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amvecm.c69
-rw-r--r--include/linux/amlogic/media/amvecm/amvecm.h82
4 files changed, 210 insertions, 6 deletions
diff --git a/drivers/amlogic/media/enhancement/amvecm/amve.c b/drivers/amlogic/media/enhancement/amvecm/amve.c
index 7ad9811..43c733b 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amve.c
+++ b/drivers/amlogic/media/enhancement/amvecm/amve.c
@@ -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;
+ }
+ }
+}
+
diff --git a/drivers/amlogic/media/enhancement/amvecm/amve.h b/drivers/amlogic/media/enhancement/amvecm/amve.h
index 060d74b..2719cdf 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amve.h
+++ b/drivers/amlogic/media/enhancement/amvecm/amve.h
@@ -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
diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c
index 7b4a802..1ac764b 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c
+++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c
@@ -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
diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h
index f7adfb6..d9ea64e 100644
--- a/include/linux/amlogic/media/amvecm/amvecm.h
+++ b/include/linux/amlogic/media/amvecm/amvecm.h
@@ -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 {