From cfe6710d5f6e8469936722d5399f9aead2f332fc Mon Sep 17 00:00:00 2001 From: MingLiang Dong Date: Mon, 29 Oct 2018 03:14:34 -0400 Subject: [PATCH] amvecm: pq: add amvecm support for tl1 [1/1] PD#172587 Problem: new feature, add amvecm support for tl1 Solution: 1. add cm hist for tl1 2. add 3dlut for tl1 3. add hdr support for tl1 4. add wb for tl1 5. add local contrast Verify: verify on tl1 ptm Change-Id: I1c7ebb83a1fb72a4529415fb9bf4acfd134e6b11 Signed-off-by: MingLiang Dong --- .../amlogic/media/enhancement/amvecm/Makefile | 13 +- .../amlogic/media/enhancement/amvecm/amve.c | 11 +- .../amlogic/media/enhancement/amvecm/amve.h | 2 +- .../amlogic/media/enhancement/amvecm/amvecm.c | 338 ++++++++++-- .../media/enhancement/amvecm/arch/vpp_regs.h | 197 +++++++ .../media/enhancement/amvecm/local_contrast.c | 514 ++++++++++++++++++ .../media/enhancement/amvecm/local_contrast.h | 45 ++ include/linux/amlogic/media/amvecm/amvecm.h | 6 + 8 files changed, 1085 insertions(+), 41 deletions(-) create mode 100644 drivers/amlogic/media/enhancement/amvecm/local_contrast.c create mode 100644 drivers/amlogic/media/enhancement/amvecm/local_contrast.h diff --git a/drivers/amlogic/media/enhancement/amvecm/Makefile b/drivers/amlogic/media/enhancement/amvecm/Makefile index 60740def0a09..42f1595c4770 100644 --- a/drivers/amlogic/media/enhancement/amvecm/Makefile +++ b/drivers/amlogic/media/enhancement/amvecm/Makefile @@ -3,6 +3,15 @@ # obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) += am_vecm.o -am_vecm-objs := amve.o amcm.o amcsc.o amvecm.o keystone_correction.o bitdepth.o set_hdr2_v0.o dnlp_cal.o cm2_adj.o vlock.o +am_vecm-objs := amve.o +am_vecm-objs += amcm.o +am_vecm-objs += amcsc.o +am_vecm-objs += amvecm.o +am_vecm-objs += keystone_correction.o +am_vecm-objs += bitdepth.o +am_vecm-objs += set_hdr2_v0.o +am_vecm-objs += dnlp_cal.o +am_vecm-objs += cm2_adj.o +am_vecm-objs += vlock.o am_vecm-objs += hdr/am_hdr10_plus.o - +am_vecm-objs += local_contrast.o diff --git a/drivers/amlogic/media/enhancement/amvecm/amve.c b/drivers/amlogic/media/enhancement/amvecm/amve.c index 6ae749317e04..52c0f6aa4b4a 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amve.c +++ b/drivers/amlogic/media/enhancement/amvecm/amve.c @@ -552,7 +552,7 @@ void vpp_set_rgb_ogo(struct tcon_rgb_ogo_s *p) m[i] = -1024; } - if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) { + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { WRITE_VPP_REG_BITS(VPP_POST_MATRIX_EN_CTRL, p->en, 0, 1); WRITE_VPP_REG(VPP_POST_MATRIX_PRE_OFFSET0_1, @@ -658,6 +658,7 @@ void vpp_set_rgb_ogo(struct tcon_rgb_ogo_s *p) WRITE_VPP_REG(VPP_GAINOFF_CTRL4, ((p->b_pre_offset << 0) & 0x00001fff)); } else { + /*txl and before txl, and tl1 10bit path offset is 11bit*/ WRITE_VPP_REG(VPP_GAINOFF_CTRL0, ((p->en << 31) & 0x80000000) | ((p->r_gain << 16) & 0x07ff0000) | @@ -1595,15 +1596,15 @@ static void ycbcr2rgbpc_nb(int *R, int *G, int *B, } /*table: use for yuv->rgb*/ -void vpp_lut3d_table_init(int *pLut3D) +void vpp_lut3d_table_init(int *pLut3D, int bitdepth) { int d0, d1, d2, ncmp; unsigned int i; int step[3]; /*steps of each input components lut-nodes*/ - int max_val = (1<<12) - 1; + int max_val = (1 << bitdepth) - 1; /*step*/ for (ncmp = 0; ncmp < 3; ncmp++) - step[ncmp] = (1<<(12-4)); + step[ncmp] = (1 << (bitdepth - 4)); /*initialize the lut3d ad same input and output;*/ for (d0 = 0; d0 < 17; d0++) { @@ -1625,7 +1626,7 @@ void vpp_lut3d_table_init(int *pLut3D) pLut3D[d0*17*17*3+d1*17*3+d2*3+0], pLut3D[d0*17*17*3+d1*17*3+d2*3+1], pLut3D[d0*17*17*3+d1*17*3+d2*3+2], - 12); + bitdepth); } } } diff --git a/drivers/amlogic/media/enhancement/amvecm/amve.h b/drivers/amlogic/media/enhancement/amvecm/amve.h index cbd8d093a7ca..f2d978553632 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amve.h +++ b/drivers/amlogic/media/enhancement/amvecm/amve.h @@ -158,7 +158,7 @@ extern void amvecm_fresh_overscan(struct vframe_s *vf); extern void amvecm_reset_overscan(void); extern int vpp_set_lut3d(int enable, int bLut3DLoad, int *pLut3D, int bLut3DCheck); -extern void vpp_lut3d_table_init(int *pLut3D); +extern void vpp_lut3d_table_init(int *pLut3D, int bitdepth); extern void dump_plut3d_table(void); extern void dump_plut3d_reg_table(void); #endif diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 38daf872d05d..e3b8d6375f2c 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -60,6 +60,7 @@ #include "dnlp_cal.h" #include "vlock.h" #include "hdr/am_hdr10_plus.h" +#include "local_contrast.h" #define pr_amvecm_dbg(fmt, args...)\ do {\ @@ -74,7 +75,7 @@ #define AMVECM_MODULE_NAME "amvecm" #define AMVECM_DEVICE_NAME "amvecm" #define AMVECM_CLASS_NAME "amvecm" -#define AMVECM_VER "Ref.2018/09/03" +#define AMVECM_VER "Ref.2018/09/28" struct amvecm_dev_s { @@ -1002,10 +1003,14 @@ int amvecm_on_vs( result = amvecm_matrix_process(toggle_vf, vf, flags); if (toggle_vf) ioctrl_get_hdr_metadata(toggle_vf); + + if (toggle_vf) + lc_process(toggle_vf, sps_h_en, sps_v_en); } else { amvecm_reset_overscan(); result = amvecm_matrix_process(NULL, NULL, flags); ve_hist_gamma_reset(); + lc_process(NULL, sps_h_en, sps_v_en); } if (!is_dolby_vision_on()) @@ -4402,6 +4407,108 @@ kfree_buf: return -EINVAL; } +static void cm_hist_config(unsigned int en, unsigned int mode, + unsigned int wd0, unsigned int wd1, + unsigned int wd2, unsigned int wd3) +{ + unsigned int value; + + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_CFG_REG); + value = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + value = (value & (~0xc0000000)) | (en << 30); + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_CFG_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, value); + + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG); + value = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + value = (value & (~(0x1fff0000))) | (mode << 16); + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, value); + + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_WIN_XYXY0_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, wd0 | (wd1 << 16)); + + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_WIN_XYXY1_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, wd2 | (wd3 << 16)); +} + +static void cm_sta_hist_range_thrd(int r, int ro_frame, + int thrd0, int thrd1) +{ + unsigned int value0, value1; + + if (r) { + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST0_REG); + value0 = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST1_REG); + value1 = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + pr_info("thrd0 = 0x%x, thrd0 = 0x%x\n", value0, value1); + } else { + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST0_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, thrd0 | (ro_frame << 24)); + + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST1_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, thrd1); + } +} + +static void cm_luma_bri_con(int r, int brightness, int contrast, + int blk_lel) +{ + int value; + + if (r) { + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG); + value = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + pr_info("contrast = 0x%x, blklel = 0x%x\n", + value & 0xfff, (value >> 12) & 0x3ff); + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG); + value = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + pr_info("bright = 0x%x, hist_mode = 0x%x\n", + value & 0x1fff, (value >> 16) & 0x1fff); + } else { + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, + (blk_lel << 12) | contrast); + + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG); + value = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG); + WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, + (value & (~(0x1fff))) | brightness); + } +} +static void get_cm_hist(enum cm_hist_e hist_sel) +{ + unsigned int *hist; + unsigned int i; + + hist = kmalloc(64 * sizeof(unsigned int), GFP_KERNEL); + memset(hist, 0, 64 * sizeof(unsigned int)); + + switch (hist_sel) { + case CM_HUE_HIST: + for (i = 0; i < 64; i++) { + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, + RO_CM_HUE_HIST_BIN0 + i); + hist[i] = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + pr_info("hist[%d] = 0x%8x\n", i, hist[i]); + } + break; + case CM_SAT_HIST: + for (i = 0; i < 64; i++) { + WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, + RO_CM_SAT_HIST_BIN0 + i); + hist[i] = READ_VPP_REG(VPP_CHROMA_DATA_PORT); + pr_info("hist[%d] = 0x%8x\n", i, hist[i]); + } + break; + default: + break; + } + kfree(hist); +} + static const char *amvecm_debug_usage_str = { "Usage:\n" "echo vpp_size > /sys/class/amvecm/debug; get vpp size config\n" @@ -4656,13 +4763,13 @@ static ssize_t amvecm_debug_store(struct class *cla, if (!parm[2]) { pr_info("misss param\n"); - return -EINVAL; + goto free_buf; } if (kstrtoul(parm[1], 10, &val) < 0) - return -EINVAL; + goto free_buf; vks_param = val; if (kstrtoul(parm[2], 10, &val) < 0) - return -EINVAL; + goto free_buf; vks_param_val = val; keystone_correction_config(vks_param, vks_param_val); } else if (!strcmp(parm[0], "bitdepth")) { @@ -4670,10 +4777,10 @@ static ssize_t amvecm_debug_store(struct class *cla, if (!parm[1]) { pr_info("misss param1\n"); - return -EINVAL; + goto free_buf; } if (kstrtoul(parm[1], 10, &val) < 0) - return -EINVAL; + goto free_buf; bitdepth = val; vpp_bitdepth_config(bitdepth); } else if (!strcmp(parm[0], "datapath_config")) { @@ -4681,18 +4788,18 @@ static ssize_t amvecm_debug_store(struct class *cla, if (!parm[1]) { pr_info("misss param1\n"); - return -EINVAL; + goto free_buf; } if (kstrtoul(parm[1], 10, &val) < 0) - return -EINVAL; + goto free_buf; node = val; if (!parm[2]) { pr_info("misss param2\n"); - return -EINVAL; + goto free_buf; } if (kstrtoul(parm[2], 10, &val) < 0) - return -EINVAL; + goto free_buf; param1 = val; if (!parm[3]) { @@ -4700,33 +4807,27 @@ static ssize_t amvecm_debug_store(struct class *cla, param2 = 0; } if (kstrtoul(parm[3], 10, &val) < 0) - return -EINVAL; + goto free_buf; param2 = val; vpp_datapath_config(node, param1, param2); } else if (!strcmp(parm[0], "datapath_status")) { vpp_datapath_status(); } else if (!strcmp(parm[0], "clip_config")) { if (parm[1]) { - if (kstrtoul(parm[1], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } + if (kstrtoul(parm[1], 16, &val) < 0) + goto free_buf; mode_sel = val; } else mode_sel = 0; if (parm[2]) { - if (kstrtoul(parm[2], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } + if (kstrtoul(parm[2], 16, &val) < 0) + goto free_buf; color = val; } else color = 0; if (parm[3]) { - if (kstrtoul(parm[3], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } + if (kstrtoul(parm[3], 16, &val) < 0) + goto free_buf; color_mode = val; } else color_mode = 0; @@ -4734,16 +4835,29 @@ static ssize_t amvecm_debug_store(struct class *cla, pr_info("vpp_clip_config done!\n"); } else if (!strcmp(parm[0], "3dlut_set")) { int *PLut3D; + unsigned int bitdepth; - PLut3D = kzalloc(14739 * sizeof(int), GFP_KERNEL); + PLut3D = kmalloc(14739 * sizeof(int), GFP_KERNEL); if (PLut3D == NULL) { - kfree(buf_orig); - return -EINVAL; + kfree(PLut3D); + goto free_buf; } - vpp_lut3d_table_init(PLut3D); - if (!strcmp(parm[1], "enable")) + if (parm[1]) { + if (kstrtoul(parm[1], 10, &val) < 0) { + kfree(PLut3D); + goto free_buf; + } + bitdepth = val; + } else { + pr_info("unsupport cmd\n"); + kfree(PLut3D); + goto free_buf; + } + + vpp_lut3d_table_init(PLut3D, bitdepth); + if (!strcmp(parm[2], "enable")) vpp_set_lut3d(1, 1, PLut3D, 1); - else if (!strcmp(parm[1], "disable")) + else if (!strcmp(parm[2], "disable")) vpp_set_lut3d(0, 0, PLut3D, 0); else pr_info("unsupprt cmd!\n"); @@ -4755,12 +4869,115 @@ static ssize_t amvecm_debug_store(struct class *cla, dump_plut3d_reg_table(); else pr_info("unsupprt cmd!\n"); + } else if (!strcmp(parm[0], "cm_hist")) { + if (!parm[1]) { + pr_info("miss param1\n"); + goto free_buf; + } + if (!strcmp(parm[1], "hue")) + get_cm_hist(CM_HUE_HIST); + else if (!strcmp(parm[1], "sat")) + get_cm_hist(CM_SAT_HIST); + else + pr_info("unsupport cmd\n"); + } else if (!strcmp(parm[0], "cm_hist_config")) { + unsigned int en, mode, wd0, wd1, wd2, wd3; + + if (!parm[6]) { + pr_info("miss param1\n"); + goto free_buf; + } + if (kstrtoul(parm[1], 10, &val) < 0) + goto free_buf; + en = val; + if (kstrtoul(parm[2], 10, &val) < 0) + goto free_buf; + mode = val; + if (kstrtoul(parm[3], 10, &val) < 0) + goto free_buf; + wd0 = val; + if (kstrtoul(parm[4], 10, &val) < 0) + goto free_buf; + wd1 = val; + if (kstrtoul(parm[5], 10, &val) < 0) + goto free_buf; + wd2 = val; + if (kstrtoul(parm[6], 10, &val) < 0) + goto free_buf; + wd3 = val; + cm_hist_config(en, mode, wd0, wd1, wd2, wd3); + pr_info("cm hist config success\n"); + } else if (!strcmp(parm[0], "cm_hist_thrd")) { + int rd, ro_frame, thrd0, thrd1; + + if (parm[1]) { + if (kstrtoul(parm[1], 16, &val) < 0) + goto free_buf; + rd = val; + } else { + pr_info("unsupport cmd\n"); + goto free_buf; + } + if (rd) + cm_sta_hist_range_thrd(rd, 0, 0, 0); + else { + if (!parm[3]) { + pr_info("miss param1\n"); + goto free_buf; + } + if (kstrtoul(parm[1], 16, &val) < 0) + goto free_buf; + ro_frame = val; + if (kstrtoul(parm[2], 16, &val) < 0) + goto free_buf; + thrd0 = val; + if (kstrtoul(parm[3], 16, &val) < 0) + goto free_buf; + thrd1 = val; + cm_sta_hist_range_thrd(rd, ro_frame, thrd0, thrd1); + pr_info("cm hist thrd set success\n"); + } + } else if (!strcmp(parm[0], "cm_bri_con")) { + int rd, bri, con, blk_lel; + + if (parm[1]) { + if (kstrtoul(parm[1], 16, &val) < 0) + goto free_buf; + rd = val; + } else { + pr_info("unsupport cmd\n"); + goto free_buf; + } + + if (rd) + cm_luma_bri_con(rd, 0, 0, 0); + else { + if (!parm[3]) { + pr_info("miss param1\n"); + goto free_buf; + } + if (kstrtoul(parm[1], 16, &val) < 0) + goto free_buf; + bri = val; + if (kstrtoul(parm[2], 16, &val) < 0) + goto free_buf; + con = val; + if (kstrtoul(parm[3], 16, &val) < 0) + goto free_buf; + blk_lel = val; + cm_luma_bri_con(rd, bri, con, blk_lel); + pr_info("cm hist bri_con set success\n"); + } } else { pr_info("unsupport cmd\n"); } kfree(buf_orig); return count; + +free_buf: + kfree(buf_orig); + return -EINVAL; } static const char *amvecm_reg_usage_str = { @@ -4769,8 +4986,8 @@ static const char *amvecm_reg_usage_str = { "echo rc addr(H) > /sys/class/amvecm/reg;\n" "echo rh addr(H) > /sys/class/amvecm/reg; read hiu reg\n" "echo wv addr(H) value(H) > /sys/class/amvecm/reg; write vpu reg\n" - "echo wc addr(H) value(H) > /sys/class/amvecm/re; write cbus reg\n" - "echo wh addr(H) value(H) > /sys/class/amvecm/re; write hiu reg\n" + "echo wc addr(H) value(H) > /sys/class/amvecm/reg; write cbus reg\n" + "echo wh addr(H) value(H) > /sys/class/amvecm/reg; write hiu reg\n" "echo dv|c|h addr(H) num > /sys/class/amvecm/reg; dump reg from addr\n" }; static ssize_t amvecm_reg_show(struct class *cla, @@ -4895,6 +5112,54 @@ static ssize_t amvecm_get_hdr_type_store(struct class *cls, return count; } +static ssize_t amvecm_lc_show(struct class *cla, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + + len += sprintf(buf+len, + "echo lc enable > /sys/class/amvecm/lc\n"); + len += sprintf(buf+len, + "echo lc disable > /sys/class/amvecm/lc\n"); + len += sprintf(buf+len, + "echo lc_dbg value > /sys/class/amvecm/lc\n"); + return len; +} + +static ssize_t amvecm_lc_store(struct class *cls, + struct class_attribute *attr, + const char *buf, size_t count) +{ + char *buf_orig, *parm[8] = {NULL}; + long val = 0; + + if (!buf) + return count; + + buf_orig = kstrdup(buf, GFP_KERNEL); + parse_param_amvecm(buf_orig, (char **)&parm); + + if (!strcmp(parm[0], "lc")) { + if (!strcmp(parm[1], "enable")) + lc_en = 1; + else if (!strcmp(parm[1], "disable")) + lc_en = 0; + else + pr_info("unsupprt cmd!\n"); + } else if (!strcmp(parm[0], "lc_dbg")) { + if (kstrtoul(parm[1], 16, &val) < 0) { + kfree(buf_orig); + return -EINVAL; + } + amlc_debug = val; + } else + pr_info("unsupprt cmd!\n"); + + kfree(buf_orig); + return count; +} + + /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */ void init_pq_setting(void) { @@ -4920,6 +5185,9 @@ void init_pq_setting(void) /*dnlp alg parameters init*/ dnlp_alg_param_init(); + + if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) + lc_init(); } /* #endif*/ @@ -5108,6 +5376,9 @@ static struct class_attribute amvecm_class_attrs[] = { amvecm_get_hdr_type_show, amvecm_get_hdr_type_store), __ATTR(dnlp_insmod, 0644, amvecm_dnlp_insmod_show, amvecm_dnlp_insmod_store), + __ATTR(lc, 0644, + amvecm_lc_show, + amvecm_lc_store), __ATTR_NULL }; @@ -5279,8 +5550,9 @@ static int aml_vecm_probe(struct platform_device *pdev) vout_register_client(&vlock_notifier_nb); /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */ - if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() - || is_meson_txlx_cpu() || is_meson_txhd_cpu()) + if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || + is_meson_txlx_cpu() || is_meson_txhd_cpu() || + is_meson_tl1_cpu()) init_pq_setting(); /* #endif */ vpp_get_hist_en(); diff --git a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h index 8787e9014d0d..993167842352 100644 --- a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h +++ b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h @@ -855,5 +855,202 @@ #define VPP_LUT3D_RAM_DATA 0x39d3 #define ENCL_VIDEO_EN 0x1ca0 + +/*TL1 add cm hist reg*/ +#define LUMA_ADJ0_REG 0x21f +#define LUMA_ADJ1_REG 0x220 +#define STA_WIN_XYXY0_REG 0x221 +#define STA_WIN_XYXY1_REG 0x222 +#define STA_CFG_REG 0x223 +#define STA_SAT_HIST0_REG 0x224 +#define STA_SAT_HIST1_REG 0x225 + +#define RO_CM_HUE_HIST_BIN0 0x226 +#define RO_CM_HUE_HIST_BIN1 0x227 +#define RO_CM_HUE_HIST_BIN2 0x228 +#define RO_CM_HUE_HIST_BIN3 0x229 +#define RO_CM_HUE_HIST_BIN4 0x22a +#define RO_CM_HUE_HIST_BIN5 0x22b +#define RO_CM_HUE_HIST_BIN6 0x22c +#define RO_CM_HUE_HIST_BIN7 0x22d +#define RO_CM_HUE_HIST_BIN8 0x22e +#define RO_CM_HUE_HIST_BIN9 0x22f +#define RO_CM_HUE_HIST_BIN10 0x230 +#define RO_CM_HUE_HIST_BIN11 0x231 +#define RO_CM_HUE_HIST_BIN12 0x232 +#define RO_CM_HUE_HIST_BIN13 0x233 +#define RO_CM_HUE_HIST_BIN14 0x234 +#define RO_CM_HUE_HIST_BIN15 0x235 +#define RO_CM_HUE_HIST_BIN16 0x236 +#define RO_CM_HUE_HIST_BIN17 0x237 +#define RO_CM_HUE_HIST_BIN18 0x238 +#define RO_CM_HUE_HIST_BIN19 0x239 +#define RO_CM_HUE_HIST_BIN20 0x23a +#define RO_CM_HUE_HIST_BIN21 0x23b +#define RO_CM_HUE_HIST_BIN22 0x23c +#define RO_CM_HUE_HIST_BIN23 0x23d +#define RO_CM_HUE_HIST_BIN24 0x23e +#define RO_CM_HUE_HIST_BIN25 0x23f +#define RO_CM_HUE_HIST_BIN26 0x240 +#define RO_CM_HUE_HIST_BIN27 0x241 +#define RO_CM_HUE_HIST_BIN28 0x242 +#define RO_CM_HUE_HIST_BIN29 0x243 +#define RO_CM_HUE_HIST_BIN30 0x244 +#define RO_CM_HUE_HIST_BIN31 0x245 + +#define RO_CM_SAT_HIST_BIN0 0x246 +#define RO_CM_SAT_HIST_BIN1 0x247 +#define RO_CM_SAT_HIST_BIN2 0x248 +#define RO_CM_SAT_HIST_BIN3 0x249 +#define RO_CM_SAT_HIST_BIN4 0x24a +#define RO_CM_SAT_HIST_BIN5 0x24b +#define RO_CM_SAT_HIST_BIN6 0x24c +#define RO_CM_SAT_HIST_BIN7 0x24d +#define RO_CM_SAT_HIST_BIN8 0x24e +#define RO_CM_SAT_HIST_BIN9 0x24f +#define RO_CM_SAT_HIST_BIN10 0x250 +#define RO_CM_SAT_HIST_BIN11 0x251 +#define RO_CM_SAT_HIST_BIN12 0x252 +#define RO_CM_SAT_HIST_BIN13 0x253 +#define RO_CM_SAT_HIST_BIN14 0x254 +#define RO_CM_SAT_HIST_BIN15 0x255 +#define RO_CM_SAT_HIST_BIN16 0x256 +#define RO_CM_SAT_HIST_BIN17 0x257 +#define RO_CM_SAT_HIST_BIN18 0x258 +#define RO_CM_SAT_HIST_BIN19 0x259 +#define RO_CM_SAT_HIST_BIN20 0x25a +#define RO_CM_SAT_HIST_BIN21 0x25b +#define RO_CM_SAT_HIST_BIN22 0x25c +#define RO_CM_SAT_HIST_BIN23 0x25d +#define RO_CM_SAT_HIST_BIN24 0x25e +#define RO_CM_SAT_HIST_BIN25 0x25f +#define RO_CM_SAT_HIST_BIN26 0x260 +#define RO_CM_SAT_HIST_BIN27 0x261 +#define RO_CM_SAT_HIST_BIN28 0x262 +#define RO_CM_SAT_HIST_BIN29 0x263 +#define RO_CM_SAT_HIST_BIN30 0x264 +#define RO_CM_SAT_HIST_BIN31 0x265 + +#define RO_CM_BLK_BIN 0x266 +#define RO_CM_BRT_BIN 0x267 +/*TL1 cm HIST reg end*/ + +/*LC register begin*/ +#define SRSHARP1_LC_INPUT_MUX 0x3fb1 +#define SRSHARP1_LC_TOP_CTRL 0x3fc0 +#define SRSHARP1_LC_HV_NUM 0x3fc1 +#define SRSHARP1_LC_SAT_LUT_0_1 0x3fc2 +#define SRSHARP1_LC_SAT_LUT_2_3 0x3fc3 +#define SRSHARP1_LC_SAT_LUT_4_5 0x3fc4 +#define SRSHARP1_LC_SAT_LUT_6_7 0x3fc5 +#define SRSHARP1_LC_SAT_LUT_8_9 0x3fc6 +#define SRSHARP1_LC_SAT_LUT_10_11 0x3fc7 +#define SRSHARP1_LC_SAT_LUT_12_13 0x3fc8 +#define SRSHARP1_LC_SAT_LUT_14_15 0x3fc9 +#define SRSHARP1_LC_SAT_LUT_16_17 0x3fca +#define SRSHARP1_LC_SAT_LUT_18_19 0x3fcb +#define SRSHARP1_LC_SAT_LUT_20_21 0x3fcc +#define SRSHARP1_LC_SAT_LUT_22_23 0x3fcd +#define SRSHARP1_LC_SAT_LUT_24_25 0x3fce +#define SRSHARP1_LC_SAT_LUT_26_27 0x3fcf +#define SRSHARP1_LC_SAT_LUT_28_29 0x3fd0 +#define SRSHARP1_LC_SAT_LUT_30_31 0x3fd1 +#define SRSHARP1_LC_SAT_LUT_32_33 0x3fd2 +#define SRSHARP1_LC_SAT_LUT_34_35 0x3fd3 +#define SRSHARP1_LC_SAT_LUT_36_37 0x3fd4 +#define SRSHARP1_LC_SAT_LUT_38_39 0x3fd5 +#define SRSHARP1_LC_SAT_LUT_40_41 0x3fd6 +#define SRSHARP1_LC_SAT_LUT_42_43 0x3fd7 +#define SRSHARP1_LC_SAT_LUT_44_45 0x3fd8 +#define SRSHARP1_LC_SAT_LUT_46_47 0x3fd9 +#define SRSHARP1_LC_SAT_LUT_48_49 0x3fda +#define SRSHARP1_LC_SAT_LUT_50_51 0x3fdb +#define SRSHARP1_LC_SAT_LUT_52_53 0x3fdc +#define SRSHARP1_LC_SAT_LUT_54_55 0x3fdd +#define SRSHARP1_LC_SAT_LUT_56_57 0x3fde +#define SRSHARP1_LC_SAT_LUT_58_59 0x3fdf +#define SRSHARP1_LC_SAT_LUT_60_61 0x3fe0 +#define SRSHARP1_LC_SAT_LUT_62 0x3fe1 +#define SRSHARP1_LC_CURVE_BLK_HIDX_0_1 0x3fe2 +#define SRSHARP1_LC_CURVE_BLK_HIDX_2_3 0x3fe3 +#define SRSHARP1_LC_CURVE_BLK_HIDX_4_5 0x3fe4 +#define SRSHARP1_LC_CURVE_BLK_HIDX_6_7 0x3fe5 +#define SRSHARP1_LC_CURVE_BLK_HIDX_8_9 0x3fe6 +#define SRSHARP1_LC_CURVE_BLK_HIDX_10_11 0x3fe7 +#define SRSHARP1_LC_CURVE_BLK_HIDX_12 0x3fe8 +#define SRSHARP1_LC_CURVE_BLK_VIDX_0_1 0x3fe9 +#define SRSHARP1_LC_CURVE_BLK_VIDX_2_3 0x3fea +#define SRSHARP1_LC_CURVE_BLK_VIDX_4_5 0x3feb +#define SRSHARP1_LC_CURVE_BLK_VIDX_6_7 0x3fec +#define SRSHARP1_LC_CURVE_BLK_VIDX_8 0x3fed +#define SRSHARP1_LC_YUV2RGB_MAT_0_1 0x3fee +#define SRSHARP1_LC_YUV2RGB_MAT_2_3 0x3fef +#define SRSHARP1_LC_YUV2RGB_MAT_4_5 0x3ff0 +#define SRSHARP1_LC_YUV2RGB_MAT_6_7 0x3ff1 +#define SRSHARP1_LC_YUV2RGB_MAT_8 0x3ff2 +#define SRSHARP1_LC_RGB2YUV_MAT_0_1 0x3ff3 +#define SRSHARP1_LC_RGB2YUV_MAT_2_3 0x3ff4 +#define SRSHARP1_LC_RGB2YUV_MAT_4_5 0x3ff5 +#define SRSHARP1_LC_RGB2YUV_MAT_6_7 0x3ff6 +#define SRSHARP1_LC_RGB2YUV_MAT_8 0x3ff7 +#define SRSHARP1_LC_YUV2RGB_OFST 0x3ff8 +#define SRSHARP1_LC_YUV2RGB_CLIP 0x3ff9 +#define SRSHARP1_LC_RGB2YUV_OFST 0x3ffa +#define SRSHARP1_LC_RGB2YUV_CLIP 0x3ffb +#define SRSHARP1_LC_MAP_RAM_CTRL 0x3ffc +#define SRSHARP1_LC_MAP_RAM_ADDR 0x3ffd +#define SRSHARP1_LC_MAP_RAM_DATA 0x3ffe + +#define LC_CURVE_CTRL 0x4000 +#define LC_CURVE_HV_NUM 0x4001 +#define LC_CURVE_LMT_RAT 0x4002 +#define LC_CURVE_CONTRAST_LH 0x4003 +#define LC_CURVE_CONTRAST__LMT_LH 0x4004 +#define LC_CURVE_CONTRAST_SCL_LH 0x4005 +#define LC_CURVE_CONTRAST_BVN_LH 0x4006 +#define LC_CURVE_MISC0 0x4007 +#define LC_CURVE_YPKBV_RAT 0x4008 +#define LC_CURVE_YPKBV_SLP_LMT 0x4009 +#define LC_CURVE_YMINVAL_LMT_0_1 0x400a +#define LC_CURVE_YMINVAL_LMT_2_3 0x400b +#define LC_CURVE_YMINVAL_LMT_4_5 0x400c +#define LC_CURVE_YMINVAL_LMT_6_7 0x400d +#define LC_CURVE_YMINVAL_LMT_8_9 0x400e +#define LC_CURVE_YMINVAL_LMT_10_11 0x400f +#define LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 0x4010 +#define LC_CURVE_YPKBV_YMAXVAL_LMT_2_3 0x4011 +#define LC_CURVE_YPKBV_YMAXVAL_LMT_4_5 0x4012 +#define LC_CURVE_YPKBV_YMAXVAL_LMT_6_7 0x4013 +#define LC_CURVE_YPKBV_YMAXVAL_LMT_8_9 0x4014 +#define LC_CURVE_YPKBV_YMAXVAL_LMT_10_11 0x4015 +#define LC_CURVE_HISTVLD_THRD 0x4016 +#define LC_CURVE_BB_MUTE_THRD 0x4017 +#define LC_CURVE_INT_STATUS 0x4018 +#define LC_CURVE_RAM_CTRL 0x4020 +#define LC_CURVE_RAM_ADDR 0x4021 +#define LC_CURVE_RAM_DATA 0x4022 + +#define LC_STTS_GCLK_CTRL0 0x4028 +#define LC_STTS_CTRL0 0x4029 +#define LC_STTS_WIDTHM1_HEIGHTM1 0x402a +#define LC_STTS_MATRIX_COEF00_01 0x402b +#define LC_STTS_MATRIX_COEF02_10 0x402c +#define LC_STTS_MATRIX_COEF11_12 0x402d +#define LC_STTS_MATRIX_COEF20_21 0x402e +#define LC_STTS_MATRIX_COEF22 0x402f +#define LC_STTS_MATRIX_OFFSET0_1 0x4030 +#define LC_STTS_MATRIX_OFFSET2 0x4031 +#define LC_STTS_MATRIX_PRE_OFFSET0_1 0x4032 +#define LC_STTS_MATRIX_PRE_OFFSET2 0x4033 +#define LC_STTS_MATRIX_HL_COLOR 0x4034 +#define LC_STTS_MATRIX_PROBE_POS 0x4035 +#define LC_STTS_MATRIX_PROBE_COLOR 0x4036 +#define LC_STTS_HIST_REGION_IDX 0x4037 +#define LC_STTS_HIST_SET_REGION 0x4038 +#define LC_STTS_HIST_READ_REGION 0x4039 +#define LC_STTS_HIST_START_RD_REGION 0x403a +#define LC_STTS_WHITE_INFO 0x403b +#define LC_STTS_BLACK_INFO 0x403c +/*LC register end*/ #endif diff --git a/drivers/amlogic/media/enhancement/amvecm/local_contrast.c b/drivers/amlogic/media/enhancement/amvecm/local_contrast.c new file mode 100644 index 000000000000..5f110182a041 --- /dev/null +++ b/drivers/amlogic/media/enhancement/amvecm/local_contrast.c @@ -0,0 +1,514 @@ + +/* #include */ +#include +#include +#include +#include +#include +#include +#include +#include "arch/vpp_regs.h" +#include "local_contrast.h" + +int amlc_debug; +#define pr_amlc_dbg(fmt, args...)\ + do {\ + if (amlc_debug&0x1)\ + pr_info("AMVE: " fmt, ## args);\ + } while (0) + +int lc_en; +static int lc_flag = 0xff; + +/*local contrast begin*/ +static void lc_mtx_set(enum lc_mtx_sel_e mtx_sel, + enum lc_mtx_csc_e mtx_csc, + int mtx_en) +{ + unsigned int matrix_coef00_01 = 0; + unsigned int matrix_coef02_10 = 0; + unsigned int matrix_coef11_12 = 0; + unsigned int matrix_coef20_21 = 0; + unsigned int matrix_coef22 = 0; + unsigned int matrix_clip = 0; + unsigned int matrix_offset0_1 = 0; + unsigned int matrix_offset2 = 0; + unsigned int matrix_pre_offset0_1 = 0; + unsigned int matrix_pre_offset2 = 0; + unsigned int matrix_en_ctrl = 0; + + switch (mtx_sel) { + case INP_MTX: + matrix_coef00_01 = SRSHARP1_LC_YUV2RGB_MAT_0_1; + matrix_coef02_10 = SRSHARP1_LC_YUV2RGB_MAT_2_3; + matrix_coef11_12 = SRSHARP1_LC_YUV2RGB_MAT_4_5; + matrix_coef20_21 = SRSHARP1_LC_YUV2RGB_MAT_6_7; + matrix_coef22 = SRSHARP1_LC_YUV2RGB_MAT_8; + matrix_pre_offset0_1 = SRSHARP1_LC_YUV2RGB_OFST; + matrix_clip = SRSHARP1_LC_YUV2RGB_CLIP; + break; + case OUTP_MTX: + matrix_coef00_01 = SRSHARP1_LC_RGB2YUV_MAT_0_1; + matrix_coef02_10 = SRSHARP1_LC_RGB2YUV_MAT_2_3; + matrix_coef11_12 = SRSHARP1_LC_RGB2YUV_MAT_4_5; + matrix_coef20_21 = SRSHARP1_LC_RGB2YUV_MAT_6_7; + matrix_coef22 = SRSHARP1_LC_RGB2YUV_MAT_8; + matrix_offset0_1 = SRSHARP1_LC_RGB2YUV_OFST; + matrix_clip = SRSHARP1_LC_RGB2YUV_CLIP; + break; + case STAT_MTX: + matrix_coef00_01 = LC_STTS_MATRIX_COEF00_01; + matrix_coef02_10 = LC_STTS_MATRIX_COEF02_10; + matrix_coef11_12 = LC_STTS_MATRIX_COEF11_12; + matrix_coef20_21 = LC_STTS_MATRIX_COEF20_21; + matrix_coef22 = LC_STTS_MATRIX_COEF22; + matrix_offset0_1 = LC_STTS_MATRIX_OFFSET0_1; + matrix_offset2 = LC_STTS_MATRIX_OFFSET2; + matrix_pre_offset0_1 = LC_STTS_MATRIX_PRE_OFFSET0_1; + matrix_pre_offset2 = LC_STTS_MATRIX_PRE_OFFSET2; + matrix_en_ctrl = LC_STTS_CTRL0; + break; + default: + break; + } + + if (mtx_sel & STAT_MTX) + WRITE_VPP_REG_BITS(matrix_en_ctrl, mtx_en, 2, 1); + + if (!mtx_en) + return; + + switch (mtx_csc) { + case LC_MTX_RGB_YUV709L: + if (mtx_sel & (INP_MTX | OUTP_MTX)) { + WRITE_VPP_REG(matrix_coef00_01, 0x00bb0275); + WRITE_VPP_REG(matrix_coef02_10, 0x003f1f99); + WRITE_VPP_REG(matrix_coef11_12, 0x1ea601c2); + WRITE_VPP_REG(matrix_coef20_21, 0x01c21e67); + WRITE_VPP_REG(matrix_coef22, 0x00001fd7); + WRITE_VPP_REG(matrix_offset0_1, 0x00400200); + } else if (mtx_sel & STAT_MTX) { + WRITE_VPP_REG(matrix_coef00_01, 0x00bb0275); + WRITE_VPP_REG(matrix_coef02_10, 0x003f1f99); + WRITE_VPP_REG(matrix_coef11_12, 0x1ea601c2); + WRITE_VPP_REG(matrix_coef20_21, 0x01c21e67); + WRITE_VPP_REG(matrix_coef22, 0x00001fd7); + WRITE_VPP_REG(matrix_offset0_1, 0x00400200); + WRITE_VPP_REG(matrix_offset2, 0x00000200); + WRITE_VPP_REG(matrix_pre_offset0_1, 0x0); + WRITE_VPP_REG(matrix_pre_offset2, 0x0); + } + break; + case LC_MTX_YUV709L_RGB: + if (mtx_sel & (INP_MTX | OUTP_MTX)) { + WRITE_VPP_REG(matrix_coef00_01, 0x04A80000); + WRITE_VPP_REG(matrix_coef02_10, 0x072C04A8); + WRITE_VPP_REG(matrix_coef11_12, 0x1F261DDD); + WRITE_VPP_REG(matrix_coef20_21, 0x04A80876); + WRITE_VPP_REG(matrix_coef22, 0x0); + WRITE_VPP_REG(matrix_pre_offset0_1, 0x00400200); + } else if (mtx_sel & STAT_MTX) { + WRITE_VPP_REG(matrix_coef00_01, 0x04A80000); + WRITE_VPP_REG(matrix_coef02_10, 0x072C04A8); + WRITE_VPP_REG(matrix_coef11_12, 0x1F261DDD); + WRITE_VPP_REG(matrix_coef20_21, 0x04A80876); + WRITE_VPP_REG(matrix_coef22, 0x0); + WRITE_VPP_REG(matrix_offset0_1, 0x0); + WRITE_VPP_REG(matrix_offset2, 0x0); + WRITE_VPP_REG(matrix_pre_offset0_1, 0x7c00600); + WRITE_VPP_REG(matrix_pre_offset2, 0x00000600); + } + break; + case LC_MTX_NULL: + if (mtx_sel & (INP_MTX | OUTP_MTX)) { + WRITE_VPP_REG(matrix_coef00_01, 0x04000000); + WRITE_VPP_REG(matrix_coef02_10, 0x0); + WRITE_VPP_REG(matrix_coef11_12, 0x04000000); + WRITE_VPP_REG(matrix_coef20_21, 0x0); + WRITE_VPP_REG(matrix_coef22, 0x400); + WRITE_VPP_REG(matrix_offset0_1, 0x0); + } else if (mtx_sel & STAT_MTX) { + + } + break; + default: + break; + } +} + +static void lc_stts_blk_config(int enable, + unsigned int height, unsigned int width) +{ + int h_num, v_num; + int blk_height, blk_width; + int row_start, col_start; + int data32; + int hend0, hend1, hend2, hend3, hend4, hend5, hend6; + int hend7, hend8, hend9, hend10, hend11; + int vend0, vend1, vend2, vend3, vend4, vend5, vend6, vend7; + + row_start = 0; + col_start = 0; + h_num = 12; + v_num = 8; + blk_height = height / h_num; + blk_width = width / v_num; + + hend0 = col_start + blk_width - 1; + hend1 = hend0 + blk_width; + hend2 = hend1 + blk_width; + hend3 = hend2 + blk_width; + hend4 = hend3 + blk_width; + hend5 = hend4 + blk_width; + hend6 = hend5 + blk_width; + hend7 = hend6 + blk_width; + hend8 = hend7 + blk_width; + hend9 = hend8 + blk_width; + hend10 = hend9 + blk_width; + hend11 = width - 1; + + vend0 = row_start + blk_height - 1; + vend1 = vend0 + blk_height; + vend2 = vend1 + blk_height; + vend3 = vend2 + blk_height; + vend4 = vend3 + blk_height; + vend5 = vend4 + blk_height; + vend6 = vend5 + blk_height; + vend7 = height - 1; + + data32 = READ_VPP_REG(LC_STTS_HIST_REGION_IDX); + WRITE_VPP_REG(LC_STTS_HIST_REGION_IDX, 0xffe0ffff & data32); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + ((((row_start & 0x1fff) << 16) & 0xffff0000) | + (col_start & 0x1fff))); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (hend1 & 0x1fff) | (hend0 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (vend1 & 0x1fff) | (vend0 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (hend3 & 0x1fff) | (hend2 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (vend3 & 0x1fff) | (vend2 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (hend5 & 0x1fff) | (hend4 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (vend5 & 0x1fff) | (vend4 & 0x1fff)); + + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (hend7 & 0x1fff) | (hend6 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (vend7 & 0x1fff) | (vend6 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (hend9 & 0x1fff) | (hend8 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, + (hend11 & 0x1fff) | (hend10 & 0x1fff)); + WRITE_VPP_REG(LC_STTS_HIST_SET_REGION, h_num); +} + +static void lc_stts_en(int enable, + unsigned int height, + unsigned int width, + int pix_drop_mode, + int eol_en, + int hist_mode, + int lpf_en, + int din_sel) +{ + int data32; + + WRITE_VPP_REG(LC_STTS_GCLK_CTRL0, 0x0); + WRITE_VPP_REG(LC_STTS_WIDTHM1_HEIGHTM1, + ((width - 1) << 16) | (height - 1)); + data32 = 0x80000000 | ((pix_drop_mode & 0x3) << 29); + data32 = data32 | ((eol_en & 0x1) << 28); + data32 = data32 | ((hist_mode & 0x3) << 22); + data32 = data32 | ((lpf_en & 0x1) << 21); + WRITE_VPP_REG(LC_STTS_HIST_REGION_IDX, data32); + + lc_mtx_set(STAT_MTX, LC_MTX_YUV709L_RGB, enable); + + WRITE_VPP_REG_BITS(LC_STTS_CTRL0, din_sel, 3, 3); + /*lc hist stts enable*/ + WRITE_VPP_REG_BITS(LC_STTS_HIST_REGION_IDX, enable, 31, 1); +} + +static void lc_curve_ctrl_config(int enable, + unsigned int height, unsigned int width) +{ + unsigned int lc_histvld_thrd; + unsigned int lc_blackbar_mute_thrd; + unsigned int lmtrat_minmax; + int h_num, v_num; + + h_num = 12; + v_num = 8; + + lmtrat_minmax = (READ_VPP_REG(LC_CURVE_LMT_RAT) >> 8) & 0xff; + lc_histvld_thrd = ((height * width) / + (h_num * v_num) * lmtrat_minmax) >> 10; + lc_blackbar_mute_thrd = ((height * width) / (h_num * v_num)) >> 3; + + if (!enable) + WRITE_VPP_REG_BITS(LC_CURVE_CTRL, enable, 0, 1); + else { + WRITE_VPP_REG(LC_CURVE_HV_NUM, (h_num << 8) | v_num); + WRITE_VPP_REG(LC_CURVE_HISTVLD_THRD, lc_histvld_thrd); + WRITE_VPP_REG(LC_CURVE_BB_MUTE_THRD, lc_blackbar_mute_thrd); + + WRITE_VPP_REG_BITS(LC_CURVE_CTRL, enable, 0, 1); + WRITE_VPP_REG_BITS(LC_CURVE_CTRL, enable, 31, 1); + } +} + +static void lc_blk_bdry_config(unsigned int height, unsigned int width) +{ + width /= 12; + height /= 8; + + /*lc curve mapping block IDX default 4k panel*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_0_1, + 0, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_0_1, + width, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_2_3, + width * 2, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_2_3, + width * 3, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_4_5, + width * 4, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_4_5, + width * 5, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_6_7, + width * 6, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_6_7, + width * 7, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_8_9, + width * 8, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_8_9, + width * 9, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_10_11, + width * 10, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_10_11, + width * 11, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_HIDX_12, + width, 0, 14); + + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_0_1, + 0, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_0_1, + height, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_2_3, + height * 2, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_2_3, + height * 3, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_4_5, + height * 4, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_4_5, + height * 5, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_6_7, + height * 6, 16, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_6_7, + height * 7, 0, 14); + WRITE_VPP_REG_BITS(SRSHARP1_LC_CURVE_BLK_VIDX_8, + height, 0, 14); +} + +static void lc_top_config(int enable, int h_num, int v_num, + unsigned int height, unsigned int width) +{ + /*lcinput_ysel*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_INPUT_MUX, 5, 4, 3); + /*lcinput_csel*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_INPUT_MUX, 5, 0, 3); + + /*lc ram write h num*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_HV_NUM, h_num, 8, 5); + /*lc ram write v num*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_HV_NUM, v_num, 0, 5); + + /*lc hblank*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_TOP_CTRL, 8, 8, 8); + /*lc blend mode*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_TOP_CTRL, 0, 0, 1); + /*lc curve mapping config*/ + lc_blk_bdry_config(height, width); + /*LC sync ctl*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_TOP_CTRL, 0, 16, 1); + /*lc enable need set at last*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_TOP_CTRL, enable, 4, 1); +} + +static void lc_disable(void) +{ + /*lc enable need set at last*/ + WRITE_VPP_REG_BITS(SRSHARP1_LC_TOP_CTRL, 0, 4, 1); + WRITE_VPP_REG_BITS(LC_CURVE_CTRL, 0, 0, 1); + /*lc hist stts enable*/ + WRITE_VPP_REG_BITS(LC_STTS_HIST_REGION_IDX, 0, 31, 1); +} + +static void lc_config(int enable, + struct vframe_s *vf, + unsigned int sps_h_en, + unsigned int sps_v_en) +{ + int h_num, v_num; + unsigned int height, width; + static unsigned int vf_height, vf_width; + const struct vinfo_s *vinfo = get_current_vinfo(); + + height = vinfo->height; + width = vinfo->width; + h_num = 12; + v_num = 8; + + if (vf == NULL) + return; + + if ((vf_height == vf->height) || + (vf_width == vf->width)) + return; + + vf_height = vf->height; + vf_width = vf->width; + + lc_top_config(enable, h_num, v_num, height, width); + + if (sps_h_en == 1) + width /= 2; + if (sps_v_en == 1) + height /= 2; + + lc_curve_ctrl_config(enable, height, width); + lc_stts_blk_config(enable, height, width); + lc_stts_en(enable, height, width, 0, 0, 1, 1, 4); +} + +static void read_lc_curve(int *szCurveInfo) +{ + int blk_hnum; + int blk_vnum; + int i; + unsigned int dwTemp; + + dwTemp = READ_VPP_REG(LC_CURVE_HV_NUM); + blk_hnum = (dwTemp >> 8) & 0x1f; + blk_vnum = (dwTemp) & 0x1f; + WRITE_VPP_REG(LC_CURVE_RAM_CTRL, 1); + WRITE_VPP_REG(LC_CURVE_RAM_ADDR, 0); + for (i = 0; i < blk_hnum * blk_vnum; i++) { + szCurveInfo[i*2+0] = READ_VPP_REG(LC_CURVE_RAM_DATA); + szCurveInfo[i*2+1] = READ_VPP_REG(LC_CURVE_RAM_DATA); + } +} + +static int set_lc_curve(int *szCurveInfo, int binit, int bcheck) +{ + int i, h_num, v_num; + unsigned int hvTemp; + int rflag; + int temp; + + rflag = 0; + hvTemp = READ_VPP_REG(SRSHARP1_LC_HV_NUM); + h_num = (hvTemp >> 8) & 0x1f; + v_num = hvTemp & 0x1f; + WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 1, 0, 1); + /*data sequence: ymin/minBv/pkBv/maxBv/ymaxv/ypkBv*/ + if (binit) { + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_ADDR, 0); + for (i = 0; i < h_num * v_num; i++) { + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, + (0|(0<<10)|(512<<20))); + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, + (1023|(1023<<10)|(512<<20))); + } + } else { + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_ADDR, 0); + for (i = 0; i < h_num * v_num; i++) { + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, + szCurveInfo[2 * i + 0]); + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, + szCurveInfo[2 * i + 1]); + } + } + WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 0, 0, 1); + + if (bcheck) { + WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 1, 0, 1); + WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_ADDR, 0 | (1 << 31)); + for (i = 0; i < h_num * v_num; i++) { + temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA); + if (temp != szCurveInfo[2 * i + 0]) + rflag = (2 * i + 0) | (1 << 31); + temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA); + if (temp != szCurveInfo[2 * i + 1]) + rflag = (2 * i + 1) | (1 << 31); + } + WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 0, 0, 1); + } + + return rflag; +} + +static void lc_fw_curve_iir(struct vframe_s *vf) +{ + if (!vf) + return; +} + +void lc_init(void) +{ + int h_num, v_num; + unsigned int height, width; + const struct vinfo_s *vinfo = get_current_vinfo(); + + height = vinfo->height; + width = vinfo->width; + h_num = 12; + v_num = 8; + + if (!lc_en) + return; + + lc_top_config(0, h_num, v_num, height, width); + lc_mtx_set(INP_MTX, LC_MTX_YUV709L_RGB, 1); + lc_mtx_set(OUTP_MTX, LC_MTX_RGB_YUV709L, 1); + + if (set_lc_curve(NULL, 1, 0)) + pr_amlc_dbg("%s: init fail", __func__); +} + +void lc_process(struct vframe_s *vf, + unsigned int sps_h_en, + unsigned int sps_v_en) +{ + int *szCurveInfo; + + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) + return; + + if (!lc_en) { + lc_disable(); + return; + } + + if ((vf == NULL) && (lc_flag == 0xff)) { + lc_disable(); + lc_flag = 0x0; + return; + } + + szCurveInfo = kmalloc(12 * 8 * 2 * sizeof(int), GFP_KERNEL); + + lc_config(lc_en, vf, sps_h_en, sps_v_en); + + read_lc_curve(szCurveInfo); + lc_fw_curve_iir(vf); + if (set_lc_curve(szCurveInfo, 0, 1)) + pr_amlc_dbg("%s: set lc curve fail", __func__); + + lc_flag = 0xff; + kfree(szCurveInfo); +} + diff --git a/drivers/amlogic/media/enhancement/amvecm/local_contrast.h b/drivers/amlogic/media/enhancement/amvecm/local_contrast.h new file mode 100644 index 000000000000..ad742c8a583d --- /dev/null +++ b/drivers/amlogic/media/enhancement/amvecm/local_contrast.h @@ -0,0 +1,45 @@ +/* + * drivers/amlogic/media/enhancement/amvecm/amcm.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __AM_LC_H +#define __AM_LC_H + + +#include + +enum lc_mtx_sel_e { + INP_MTX = 0x1, + OUTP_MTX = 0x2, + STAT_MTX = 0x4, + MAX_MTX +}; + +enum lc_mtx_csc_e { + LC_MTX_NULL = 0, + LC_MTX_YUV709L_RGB = 0x1, + LC_MTX_RGB_YUV709L = 0x2, + LC_MTX_MAX +}; + +extern int amlc_debug; +extern int lc_en; +extern void lc_init(void); +extern void lc_process(struct vframe_s *vf, + unsigned int sps_h_en, + unsigned int sps_v_en); +#endif + diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h index 89bc8997db37..ba81bd2697eb 100644 --- a/include/linux/amlogic/media/amvecm/amvecm.h +++ b/include/linux/amlogic/media/amvecm/amvecm.h @@ -99,6 +99,12 @@ #define HDR10_SOURCE (1 << 1) #define HLG_SOURCE (1 << 2) +enum cm_hist_e { + CM_HUE_HIST = 0, + CM_SAT_HIST, + CM_MAX_HIST +}; + enum pq_table_name_e { TABLE_NAME_SHARPNESS0 = 0x1,/*in vpp*/ TABLE_NAME_SHARPNESS1 = 0x2,/*in vpp*/