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 <mingliang.dong@amlogic.com>
This commit is contained in:
MingLiang Dong
2018-10-29 03:14:34 -04:00
committed by Dongjin Kim
parent d84cd4bf43
commit cfe6710d5f
8 changed files with 1085 additions and 41 deletions

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -0,0 +1,514 @@
/* #include <mach/am_regs.h> */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/amvecm/amvecm.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/uaccess.h>
#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);
}

View File

@@ -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 <linux/amlogic/media/vfm/vframe.h>
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

View File

@@ -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*/