return count;
}
+static void lc_rd_reg(enum lc_reg_lut_e reg_sel)
+{
+ int i, tmp, tmp1, tmp2;
+
+ switch (reg_sel) {
+ case SATUR_LUT:
+ for (i = 0; i < 31 ; i++) {
+ tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i);
+ tmp1 = (tmp >> 16) & 0xfff;
+ tmp2 = tmp & 0xfff;
+ pr_info("reg_lc_satur_lut[%d] =%4d.\n",
+ 2*i, tmp1);
+ pr_info("reg_lc_satur_lut[%d] =%4d.\n",
+ 2*i + 1, tmp2);
+ }
+ tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_62);
+ pr_info("reg_lc_satur_lut[62] =%4d.\n",
+ tmp & 0xfff);
+ break;
+ case YMINVAL_LMT:
+ for (i = 0; i < 6 ; i++) {
+ tmp = READ_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i);
+ tmp1 = (tmp >> 16) & 0x3ff;
+ tmp2 = tmp & 0x3ff;
+ pr_info("reg_yminVal_lmt[%d] =%4d.\n",
+ 2*i, tmp1);
+ pr_info("reg_yminVal_lmt[%d] =%4d.\n",
+ 2*i + 1, tmp2);
+ }
+ break;
+ case YPKBV_YMAXVAL_LMT:
+ for (i = 0; i < 6 ; i++) {
+ tmp = READ_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i);
+ tmp1 = (tmp >> 16) & 0x3ff;
+ tmp2 = tmp & 0x3ff;
+ pr_info("reg_lc_ypkBV_ymaxVal_lmt[%d] =%4d.\n",
+ 2*i, tmp1);
+ pr_info("reg_lc_ypkBV_ymaxVal_lmt[%d] =%4d.\n",
+ 2*i + 1, tmp2);
+ }
+ break;
+ case YPKBV_RAT:
+ tmp = READ_VPP_REG(LC_CURVE_YPKBV_RAT);
+ pr_info("reg_lc_ypkBV_ratio[0] =%4d.\n",
+ (tmp>>24) & 0xff);
+ pr_info("reg_lc_ypkBV_ratio[1] =%4d.\n",
+ (tmp>>16) & 0xff);
+ pr_info("reg_lc_ypkBV_ratio[2] =%4d.\n",
+ (tmp>>8) & 0xff);
+ pr_info("reg_lc_ypkBV_ratio[3] =%4d.\n",
+ tmp & 0xff);
+ break;
+ case YPKBV_SLP_LMT:
+ tmp = READ_VPP_REG(LC_CURVE_YPKBV_SLP_LMT);
+ pr_info("reg_lc_ypkBV_slope_lmt[0] =%4d.\n",
+ (tmp>>8) & 0xff);
+ pr_info("reg_lc_ypkBV_slope_lmt[1] =%4d.\n",
+ tmp & 0xff);
+ break;
+ case CNTST_LMT:
+ tmp = READ_VPP_REG(LC_CURVE_CONTRAST__LMT_LH);
+ pr_info("reg_lc_cntstlmt_low[0] =%4d.\n",
+ (tmp>>24) & 0xff);
+ pr_info("reg_lc_cntstlmt_high[0] =%4d.\n",
+ (tmp>>16) & 0xff);
+ pr_info("reg_lc_cntstlmt_low[1] =%4d.\n",
+ (tmp>>8) & 0xff);
+ pr_info("reg_lc_cntstlmt_high[1] =%4d.\n",
+ tmp & 0xff);
+ break;
+ default:
+ break;
+ }
+}
+
+static void lc_wr_reg(int *p, enum lc_reg_lut_e reg_sel)
+{
+ int i, tmp, tmp1, tmp2;
+
+ switch (reg_sel) {
+ case SATUR_LUT:
+ for (i = 0; i < 31 ; i++) {
+ tmp1 = *(p + 2*i);
+ tmp2 = *(p + 2*i + 1);
+ tmp = ((tmp1 & 0xfff)<<16) | (tmp2 & 0xfff);
+ WRITE_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i, tmp);
+ }
+ tmp = (*(p+62)) & 0xfff;
+ WRITE_VPP_REG(SRSHARP1_LC_SAT_LUT_62, tmp);
+ break;
+ case YMINVAL_LMT:
+ for (i = 0; i < 6 ; i++) {
+ tmp1 = *(p + 2*i);
+ tmp2 = *(p + 2*i + 1);
+ tmp = ((tmp1&0x3ff) << 16) | (tmp2 & 0x3ff);
+ WRITE_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i, tmp);
+ }
+ break;
+ case YPKBV_YMAXVAL_LMT:
+ for (i = 0; i < 6 ; i++) {
+ tmp1 = *(p + 2*i);
+ tmp2 = *(p + 2*i + 1);
+ tmp = ((tmp1&0x3ff) << 16) | (tmp2 & 0x3ff);
+ WRITE_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i, tmp);
+ }
+ break;
+ case YPKBV_RAT:
+ tmp = (*p & 0xff) << 24 | (*(p+1) & 0xff) << 16 |
+ (*(p+2) & 0xff) << 8 | (*(p+3) & 0xff);
+ WRITE_VPP_REG(LC_CURVE_YPKBV_RAT, tmp);
+ break;
+ case YPKBV_SLP_LMT:
+ tmp = (*p & 0xff) << 8 | (*(p+1) & 0xff);
+ WRITE_VPP_REG(LC_CURVE_YPKBV_SLP_LMT, tmp);
+ break;
+ case CNTST_LMT:
+ tmp = (*p & 0xff) << 24 | (*(p+1) & 0xff) << 16 |
+ (*(p+2) & 0xff) << 8 | (*(p+3) & 0xff);
+ WRITE_VPP_REG(LC_CURVE_CONTRAST__LMT_LH, tmp);
+ break;
+ default:
+ break;
+ }
+}
+
static ssize_t amvecm_lc_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
"echo lc disable > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_dbg value > /sys/class/amvecm/lc\n");
+ len += sprintf(buf+len,
+ "echo lc_demo_mode enable/disable > /sys/class/amvecm/lc\n");
+ len += sprintf(buf+len,
+ "echo lc_dump_reg parm1 > /sys/class/amvecm/lc\n");
+ len += sprintf(buf+len,
+ "echo lc_rd_reg parm1 parm2 > /sys/class/amvecm/lc\n");
+ len += sprintf(buf+len,
+ "parm1: 0x1,0x2,0x4,0x8,0x10,0x20...\n");
+ len += sprintf(buf+len,
+ "parm2: decimal strings, each data width is 4.\n");
+ len += sprintf(buf+len,
+ "echo dump_hist all > /sys/class/amvecm/lc\n");
+ len += sprintf(buf+len,
+ "echo dump_hist chosen hs he vs ve cnt > /sys/class/amvecm/lc\n");
+ len += sprintf(buf+len,
+ "echo dump_curve cnt > /sys/class/amvecm/lc\n");
return len;
}
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
+ int reg_lut[63] = {0};
+ enum lc_reg_lut_e reg_sel;
long val = 0;
if (!buf)
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;
- }
+ if (kstrtoul(parm[1], 16, &val) < 0)
+ goto free_buf;
amlc_debug = val;
} else if (!strcmp(parm[0], "lc_demo_mode")) {
if (!strcmp(parm[1], "enable"))
lc_demo_mode = 0;
else
pr_info("unsupprt cmd!\n");
+ } else if (!strcmp(parm[0], "lc_dump_reg")) {
+ if (kstrtoul(parm[1], 16, &val) < 0)
+ goto free_buf;
+ reg_sel = val;
+ if (reg_sel == SATUR_LUT)
+ lc_rd_reg(SATUR_LUT);
+ else if (reg_sel == YMINVAL_LMT)
+ lc_rd_reg(YMINVAL_LMT);
+ else if (reg_sel == YPKBV_YMAXVAL_LMT)
+ lc_rd_reg(YPKBV_YMAXVAL_LMT);
+ else if (reg_sel == YPKBV_RAT)
+ lc_rd_reg(YPKBV_RAT);
+ else if (reg_sel == YPKBV_SLP_LMT)
+ lc_rd_reg(YPKBV_SLP_LMT);
+ else if (reg_sel == CNTST_LMT)
+ lc_rd_reg(CNTST_LMT);
+ else
+ pr_info("unsupprt cmd!\n");
+ } else if (!strcmp(parm[0], "lc_wr_reg")) {
+ if (kstrtoul(parm[1], 16, &val) < 0)
+ goto free_buf;
+ reg_sel = val;
+ if (parm[2] == NULL)
+ goto free_buf;
+ str_sapr_to_d(parm[2], reg_lut, 5);
+ if (reg_sel == SATUR_LUT)
+ lc_wr_reg(reg_lut, SATUR_LUT);
+ else if (reg_sel == YMINVAL_LMT)
+ lc_wr_reg(reg_lut, YMINVAL_LMT);
+ else if (reg_sel == YPKBV_YMAXVAL_LMT)
+ lc_wr_reg(reg_lut, YPKBV_YMAXVAL_LMT);
+ else if (reg_sel == YPKBV_RAT)
+ lc_wr_reg(reg_lut, YPKBV_RAT);
+ else if (reg_sel == YPKBV_SLP_LMT)
+ lc_wr_reg(reg_lut, YPKBV_SLP_LMT);
+ else if (reg_sel == CNTST_LMT)
+ lc_wr_reg(reg_lut, CNTST_LMT);
+ else
+ pr_info("unsupprt cmd!\n");
+ } else if (!strcmp(parm[0], "dump_hist")) {
+ if (!strcmp(parm[1], "all")) {
+ /*dump all hist in one frame*/
+ lc_hist_prcnt = 1;
+ amlc_debug = 0x2;
+ } else if (!strcmp(parm[1], "chosen")) {
+ /*dump multiple frames in selected area*/
+ if (parm[6] == NULL)
+ goto free_buf;
+ if (kstrtoul(parm[2], 10, &val) < 0)
+ goto free_buf;
+ lc_hist_hs = val;
+ if (kstrtoul(parm[3], 10, &val) < 0)
+ goto free_buf;
+ lc_hist_he = val;
+ if (kstrtoul(parm[4], 10, &val) < 0)
+ goto free_buf;
+ lc_hist_vs = val;
+ if (kstrtoul(parm[5], 10, &val) < 0)
+ goto free_buf;
+ lc_hist_ve = val;
+ if (kstrtoul(parm[6], 10, &val) < 0)
+ goto free_buf;
+ lc_hist_prcnt = val;
+ amlc_debug = 0x4;
+ } else
+ pr_info("unsupprt cmd!\n");
+ } else if (!strcmp(parm[0], "dump_curve")) {
+ if (kstrtoul(parm[1], 10, &val) < 0)
+ goto free_buf;
+ lc_curve_prcnt = val;
} else
pr_info("unsupprt cmd!\n");
kfree(buf_orig);
return count;
+
+free_buf:
+ kfree(buf_orig);
+ return -EINVAL;
}
cancel_work_sync(&aml_lcd_vlock_param_work);
#endif
probe_ok = 0;
+ lc_free();
pr_info("[amvecm.] : amvecm_exit.\n");
return 0;
}
#ifdef CONFIG_AML_LCD
aml_lcd_notifier_unregister(&aml_lcd_gamma_nb);
#endif
+ lc_free();
}
static const struct of_device_id aml_vecm_dt_match[] = {
int lc_demo_mode;
int lc_en_chflg = 0xff;
static int lc_flag = 0xff;
-static int lc_szcurve[192];
+static int *lc_szcurve;
/*local contrast begin*/
static void lc_mtx_set(enum lc_mtx_sel_e mtx_sel,
{
int blk_hnum;
int blk_vnum;
- int i;
+ int i, j;
unsigned int dwTemp;
+ unsigned int temp1, temp2;
+ if (!lc_szcurve) {
+ pr_amlc_dbg("%s: lc_szcurve not init!", __func__);
+ return;
+ }
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++) {
- lc_szcurve[i*2+0] = READ_VPP_REG(LC_CURVE_RAM_DATA);
- lc_szcurve[i*2+1] = READ_VPP_REG(LC_CURVE_RAM_DATA);
+ for (i = 0; i < blk_vnum; i++) {
+ for (j = 0; j < blk_hnum; j++) {
+ temp1 = READ_VPP_REG(LC_CURVE_RAM_DATA);
+ temp2 = READ_VPP_REG(LC_CURVE_RAM_DATA);
+ lc_szcurve[(i*blk_hnum + j)*6+0] =
+ temp1 & 0x3ff;/*bit0:9*/
+ lc_szcurve[(i*blk_hnum + j)*6+1] =
+ (temp1>>10) & 0x3ff;/*bit10:19*/
+ lc_szcurve[(i*blk_hnum + j)*6+2] =
+ (temp1>>20) & 0x3ff;/*bit20:29*/
+ lc_szcurve[(i*blk_hnum + j)*6+3] =
+ temp2 & 0x3ff;/*bit0:9*/
+ lc_szcurve[(i*blk_hnum + j)*6+4] =
+ (temp2>>10) & 0x3ff;/*bit10:19*/
+ lc_szcurve[(i*blk_hnum + j)*6+5] =
+ (temp2>>20) & 0x3ff;/*bit20:29*/
+ }
}
WRITE_VPP_REG(LC_CURVE_RAM_CTRL, 0);
}
static void lc_demo_wr_curve(int h_num, int v_num)
{
- int i, j;
+ int i, j, temp1, temp2;
for (i = 0; i < v_num; i++) {
for (j = 0; j < h_num / 2; j++) {
- WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
- lc_szcurve[2 * (i * h_num + j) + 0]);
- WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
- lc_szcurve[2 * (i * h_num + j) + 1]);
+ temp1 = lc_szcurve[6 * (i * h_num + j) + 0] |
+ (lc_szcurve[6 * (i * h_num + j) + 1] << 10) |
+ (lc_szcurve[6 * (i * h_num + j) + 2] << 20);
+ temp2 = lc_szcurve[6 * (i * h_num + j) + 3] |
+ (lc_szcurve[6 * (i * h_num + j) + 4] << 10) |
+ (lc_szcurve[6 * (i * h_num + j) + 5] << 20);
+ WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, temp1);
+ WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, temp2);
}
for (j = h_num / 2; j < h_num; j++) {
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
static int lc_demo_check_curve(int h_num, int v_num)
{
- int i, j, temp, flag;
+ int i, j, temp, temp1, flag;
flag = 0;
for (i = 0; i < v_num; i++) {
for (j = 0; j < h_num / 2; j++) {
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
- if (temp != lc_szcurve[2 * (i * h_num + j) + 0])
+ temp1 = lc_szcurve[6 * (i * h_num + j) + 0] |
+ (lc_szcurve[6 * (i * h_num + j) + 1] << 10) |
+ (lc_szcurve[6 * (i * h_num + j) + 2] << 20);
+ if (temp != temp1)
flag = (2 * (i * h_num + j) + 0) | (1 << 31);
+
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
- if (temp != lc_szcurve[2 * (i * h_num + j) + 1])
+ temp1 = lc_szcurve[6 * (i * h_num + j) + 3] |
+ (lc_szcurve[6 * (i * h_num + j) + 4] << 10) |
+ (lc_szcurve[6 * (i * h_num + j) + 5] << 20);
+ if (temp != temp1)
flag = (2 * (i * h_num + j) + 1) | (1 << 31);
}
for (j = h_num / 2; j < h_num; j++) {
int i, h_num, v_num;
unsigned int hvTemp;
int rflag;
- int temp;
+ int temp, temp1;
+ if (!lc_szcurve) {
+ pr_amlc_dbg("%s: lc_szcurve not init!", __func__);
+ return -EINVAL;
+ }
rflag = 0;
hvTemp = READ_VPP_REG(SRSHARP1_LC_HV_NUM);
h_num = (hvTemp >> 8) & 0x1f;
else
for (i = 0; i < h_num * v_num; i++) {
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
- lc_szcurve[2 * i + 0]);
+ lc_szcurve[6 * i + 0]|
+ (lc_szcurve[6 * i + 1]<<10)|
+ (lc_szcurve[6 * i + 2]<<20));
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
- lc_szcurve[2 * i + 1]);
+ lc_szcurve[6 * i + 3]|
+ (lc_szcurve[6 * i + 4]<<10)|
+ (lc_szcurve[6 * i + 5]<<20));
}
}
WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 0, 0, 1);
else
for (i = 0; i < h_num * v_num; i++) {
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
- if (temp != lc_szcurve[2 * i + 0])
+ temp1 = lc_szcurve[6 * i + 0]|
+ (lc_szcurve[6 * i + 1]<<10)|
+ (lc_szcurve[6 * i + 2]<<20);
+ if (temp != temp1)
rflag = (2 * i + 0) | (1 << 31);
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
- if (temp != lc_szcurve[2 * i + 1])
+ temp1 = lc_szcurve[6 * i + 3]|
+ (lc_szcurve[6 * i + 4]<<10)|
+ (lc_szcurve[6 * i + 5]<<20);
+ if (temp != temp1)
rflag = (2 * i + 1) | (1 << 31);
}
WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 0, 0, 1);
return;
}
+/*print statistics hist and curve, vlsi suggest add*/
+unsigned int lc_hist_vs = 4;
+unsigned int lc_hist_ve = 6;
+unsigned int lc_hist_hs;
+unsigned int lc_hist_he = 11;
+unsigned int lc_hist_prcnt;
+unsigned int lc_curve_prcnt;
+static int *lc_hist;
+
+static void lc_read_region(void)
+{
+ int i, j, k;
+ int data32;
+ int rgb_min, rgb_max;
+ int dwTemp, blk_hnum, blk_vnum;
+
+ if (!lc_hist) {
+ pr_amlc_dbg("%s: lc_hist not init!", __func__);
+ return;
+ }
+ WRITE_VPP_REG_BITS(0x4037, 1, 14, 1);
+ dwTemp = READ_VPP_REG(LC_CURVE_HV_NUM);
+ blk_hnum = (dwTemp >> 8) & 0x1f;
+ blk_vnum = (dwTemp) & 0x1f;
+ data32 = READ_VPP_REG(LC_STTS_HIST_START_RD_REGION);
+
+ for (i = 0; i < blk_vnum; i++)
+ for (j = 0; j < blk_hnum; j++) {
+ data32 = READ_VPP_REG(LC_STTS_HIST_START_RD_REGION);
+ if ((i >= lc_hist_vs) && (i <= lc_hist_ve) &&
+ (j >= lc_hist_hs) && (j <= lc_hist_he) &&
+ (amlc_debug == 0x4))
+ pr_info("========[r,c](%2d,%2d)======\n", i, j);
+
+ for (k = 0; k < 17; k++) {
+ data32 = READ_VPP_REG(LC_STTS_HIST_READ_REGION);
+ lc_hist[(i*blk_hnum+j)*17 + k] = data32;
+ if ((i >= lc_hist_vs) && (i <= lc_hist_ve) &&
+ (j >= lc_hist_hs) && (j <= lc_hist_he)
+ && (amlc_debug == 0x4)) {
+ /*print chosen hist*/
+ if (k == 16) {/*last bin*/
+ rgb_min =
+ (data32 >> 10) & 0x3ff;
+ rgb_max = (data32) & 0x3ff;
+ pr_info("[%2d]:%d,%d\n",
+ k, rgb_min, rgb_max);
+ } else
+ pr_info("[%2d]:%d\n",
+ k, data32);
+ }
+ }
+ }
+
+ if (amlc_debug == 0x2)/*print all hist data*/
+ for (i = 0; i < 8*12*17; i++)
+ pr_info("%x\n", lc_hist[i]);
+}
+
+static void lc_prt_curve(void)
+{/*print curve node*/
+ int i, j;
+ int dwTemp, blk_hnum, blk_vnum;
+
+ dwTemp = READ_VPP_REG(LC_CURVE_HV_NUM);
+ blk_hnum = (dwTemp >> 8) & 0x1f;
+ blk_vnum = (dwTemp) & 0x1f;
+ pr_amlc_dbg("======lc_prt curve node=======\n");
+ for (i = 0; i < blk_hnum*blk_vnum; i++) {
+ for (j = 0; j < 6 ; j++)
+ pr_amlc_dbg("%d\n", lc_szcurve[i*6 + j]);
+ pr_amlc_dbg("\n");
+ }
+}
+
void lc_init(void)
{
int h_num, v_num;
if (!lc_en)
return;
+ lc_szcurve = kzalloc(580 * sizeof(int), GFP_KERNEL);
+ if (!lc_szcurve)
+ return;
+ lc_hist = kzalloc(1632 * sizeof(int), GFP_KERNEL);
+ if (!lc_hist) {
+ kfree(lc_szcurve);
+ return;
+ }
lc_top_config(0, h_num, v_num, height, width);
lc_mtx_set(INP_MTX, LC_MTX_YUV709L_RGB, 1);
lc_config(lc_en, vf, sps_h_en, sps_v_en);
read_lc_curve();
-
lc_fw_curve_iir(vf);
+
+ if (lc_curve_prcnt > 0) { /*debug lc curve node*/
+ lc_prt_curve();
+ lc_curve_prcnt--;
+ }
+ if (lc_hist_prcnt > 0) { /*debug hist*/
+ lc_read_region();
+ lc_hist_prcnt--;
+ }
if (set_lc_curve(0, 1))
pr_amlc_dbg("%s: set lc curve fail", __func__);
lc_flag = 0xff;
}
+void lc_free(void)
+{
+ kfree(lc_szcurve);
+ kfree(lc_hist);
+}
LC_MTX_MAX
};
+enum lc_reg_lut_e {
+ SATUR_LUT = 0x1,
+ YMINVAL_LMT = 0x2,
+ YPKBV_YMAXVAL_LMT = 0x4,
+ YPKBV_RAT = 0x8,
+ YPKBV_SLP_LMT = 0x10,
+ CNTST_LMT = 0x20,
+ MAX_REG_LUT
+};
+
extern int amlc_debug;
extern int lc_en;
extern int lc_demo_mode;
+extern unsigned int lc_hist_vs;
+extern unsigned int lc_hist_ve;
+extern unsigned int lc_hist_hs;
+extern unsigned int lc_hist_he;
+extern unsigned int lc_hist_prcnt;
+extern unsigned int lc_curve_prcnt;
+
+
extern void lc_init(void);
extern void lc_process(struct vframe_s *vf,
unsigned int sps_h_en,
unsigned int sps_v_en);
+extern void lc_free(void);
#endif