| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * drivers/amlogic/media/enhancement/amvecm/amvecm.c |
| * |
| * 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. |
| * |
| */ |
| |
| /* Standard Linux headers */ |
| #include <linux/types.h> |
| #include <linux/init.h> |
| #include <linux/module.h> |
| #include <linux/kernel.h> |
| #include <linux/fs.h> |
| #include <linux/device.h> |
| #include <linux/cdev.h> |
| #include <linux/platform_device.h> |
| #include <linux/of.h> |
| #include <linux/string.h> |
| #include <linux/mm.h> |
| #include <linux/slab.h> |
| #include <linux/stat.h> |
| #include <linux/errno.h> |
| #include <linux/uaccess.h> |
| #include <linux/compat.h> |
| #include <linux/of.h> |
| #include <linux/of_device.h> |
| /* #include <linux/amlogic/aml_common.h> */ |
| #include <linux/ctype.h>/* for parse_para_pq */ |
| #include <linux/vmalloc.h> |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include <linux/amlogic/media/amvecm/amvecm.h> |
| #include <linux/amlogic/media/vout/vout_notify.h> |
| #ifdef CONFIG_AMLOGIC_PIXEL_PROBE |
| #include <linux/amlogic/pixel_probe.h> |
| #endif |
| #include <linux/io.h> |
| #include <linux/poll.h> |
| #include <linux/workqueue.h> |
| #include <linux/sched/clock.h> |
| |
| #ifdef CONFIG_AMLOGIC_LCD |
| #include <linux/amlogic/media/vout/lcd/lcd_notify.h> |
| #endif |
| |
| #include "arch/vpp_regs.h" |
| #include "arch/ve_regs.h" |
| #include "arch/cm_regs.h" |
| #ifdef CONFIG_AMLOGIC_MEDIA_TVIN |
| #include "../../vin/tvin/tvin_global.h" |
| #endif |
| |
| #include "amve.h" |
| #include "amcm.h" |
| #include "amcsc.h" |
| #include "keystone_correction.h" |
| #include "bitdepth.h" |
| #include "cm2_adj.h" |
| #include "pattern_detection.h" |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| #include <linux/amlogic/media/amdolbyvision/dolby_vision.h> |
| #endif |
| #include "dnlp_cal.h" |
| #include "vlock.h" |
| #include "hdr/am_hdr10_plus.h" |
| #include "local_contrast.h" |
| #include "arch/vpp_hdr_regs.h" |
| #include "set_hdr2_v0.h" |
| #include "ai_pq/ai_pq.h" |
| #include "reg_helper.h" |
| #include "reg_default_setting.h" |
| #include "util/enc_dec.h" |
| #include "cabc_aadc/cabc_aadc_fw.h" |
| #include "hdr/am_hdr10_tmo_fw.h" |
| #include "hdr/gamut_convert.h" |
| #include "../../video_sink/vpp_pq.h" |
| |
| #define pr_amvecm_dbg(fmt, args...)\ |
| do {\ |
| if (debug_amvecm)\ |
| pr_info("AMVECM: " fmt, ## args);\ |
| } while (0) |
| #define pr_amvecm_error(fmt, args...)\ |
| pr_error("AMVECM: " fmt, ## args) |
| |
| #define AMVECM_NAME "amvecm" |
| #define AMVECM_DRIVER_NAME "amvecm" |
| #define AMVECM_MODULE_NAME "amvecm" |
| #define AMVECM_DEVICE_NAME "amvecm" |
| #define AMVECM_CLASS_NAME "amvecm" |
| #define AMVECM_VER "Ref.2018/11/20" |
| |
| struct amvecm_dev_s { |
| dev_t devt; |
| struct cdev cdev; |
| dev_t devno; |
| struct device *dev; |
| struct class *clsp; |
| wait_queue_head_t hdr_queue; |
| /*hdr*/ |
| struct hdr_data_t hdr_d; |
| |
| }; |
| |
| #ifdef CONFIG_AMLOGIC_LCD |
| struct work_struct aml_lcd_vlock_param_work; |
| #endif |
| |
| static struct amvecm_dev_s amvecm_dev; |
| static struct resource *res_viu2_vsync_irq; |
| static struct resource *res_lc_curve_irq; |
| static struct workqueue_struct *aml_cabc_queue; |
| static struct work_struct cabc_proc_work; |
| static struct work_struct cabc_bypass_work; |
| |
| /*gamma loading protect*/ |
| spinlock_t vpp_lcd_gamma_lock; |
| /*3dlut loading protect*/ |
| struct mutex vpp_lut3d_lock; |
| |
| signed int vd1_brightness = 0, vd1_contrast; |
| |
| static int hue_pre; /*-25~25*/ |
| static int saturation_pre; /*-128~127*/ |
| static int hue_post; /*-25~25*/ |
| static int saturation_post; /*-128~127*/ |
| |
| static s16 saturation_ma; |
| static s16 saturation_mb; |
| static s16 saturation_ma_shift; |
| static s16 saturation_mb_shift; |
| |
| enum ecm_color_type cm_cur_work_color_md = cm_14_color; |
| int cm2_debug; |
| |
| static int cm2_hue_array[cm_14_ecm2colormd_max][3]; |
| static int cm2_luma_array[cm_14_ecm2colormd_max][3]; |
| static int cm2_sat_array[cm_14_ecm2colormd_max][3]; |
| static int cm2_hue_by_hs_array[cm_14_ecm2colormd_max][3]; |
| |
| unsigned int sr1_reg_val[101]; |
| unsigned int sr1_ret_val[101]; |
| struct vpp_hist_param_s vpp_hist_param; |
| static unsigned int pre_hist_height, pre_hist_width; |
| static unsigned int pc_mode = 0xff; |
| static unsigned int pc_mode_last = 0xff; |
| static struct hdr_metadata_info_s vpp_hdr_metadata_s; |
| unsigned int atv_source_flg; |
| |
| #define VDJ_FLAG_BRIGHTNESS BIT(0) |
| #define VDJ_FLAG_BRIGHTNESS2 BIT(1) |
| #define VDJ_FLAG_SAT_HUE BIT(2) |
| #define VDJ_FLAG_SAT_HUE_POST BIT(3) |
| #define VDJ_FLAG_CONTRAST BIT(4) |
| #define VDJ_FLAG_CONTRAST2 BIT(5) |
| #define VDJ_FLAG_VADJ_EN BIT(6) |
| |
| static int vdj_mode_flg; |
| struct am_vdj_mode_s vdj_mode_s; |
| struct pq_ctrl_s pq_cfg; |
| struct pq_ctrl_s dv_cfg_bypass; |
| |
| struct pq_ctrl_s pq_cfg_init[PQ_CFG_MAX] = { |
| /*for tv enable pq module*/ |
| { |
| .sharpness0_en = 1, |
| .sharpness1_en = 1, |
| .dnlp_en = 1, |
| .cm_en = 1, |
| .vadj1_en = 1, |
| .vd1_ctrst_en = 0, |
| .vadj2_en = 0, |
| .post_ctrst_en = 0, |
| .wb_en = 1, |
| .gamma_en = 1, |
| .lc_en = 1, |
| .black_ext_en = 1, |
| .chroma_cor_en = 0, |
| .reserved = 0, |
| }, |
| /*for box disable all pq module*/ |
| { |
| .sharpness0_en = 0, |
| .sharpness1_en = 0, |
| .dnlp_en = 0, |
| .cm_en = 0, |
| .vadj1_en = 0, |
| .vd1_ctrst_en = 0, |
| .vadj2_en = 0, |
| .post_ctrst_en = 0, |
| .wb_en = 0, |
| .gamma_en = 0, |
| .lc_en = 0, |
| .black_ext_en = 0, |
| .chroma_cor_en = 0, |
| .reserved = 0, |
| }, |
| /*for tv dv bypass pq module*/ |
| { |
| .sharpness0_en = 0, |
| .sharpness1_en = 0, |
| .dnlp_en = 0, |
| .cm_en = 0, |
| .vadj1_en = 0, |
| .vd1_ctrst_en = 0, |
| .vadj2_en = 0, |
| .post_ctrst_en = 0, |
| .wb_en = 1, |
| .gamma_en = 1, |
| .lc_en = 0, |
| .black_ext_en = 0, |
| .chroma_cor_en = 0, |
| .reserved = 0, |
| }, |
| /*for ott dv bypass pq module*/ |
| { |
| .sharpness0_en = 0, |
| .sharpness1_en = 0, |
| .dnlp_en = 0, |
| .cm_en = 0, |
| .vadj1_en = 0, |
| .vd1_ctrst_en = 0, |
| .vadj2_en = 0, |
| .post_ctrst_en = 0, |
| .wb_en = 0, |
| .gamma_en = 0, |
| .lc_en = 0, |
| .black_ext_en = 0, |
| .chroma_cor_en = 0, |
| .reserved = 0, |
| } |
| }; |
| |
| /*void __iomem *amvecm_hiu_reg_base;*//* = *ioremap(0xc883c000, 0x2000); */ |
| |
| static int debug_amvecm; |
| module_param(debug_amvecm, int, 0664); |
| MODULE_PARM_DESC(debug_amvecm, "\n debug_amvecm\n"); |
| |
| unsigned int vecm_latch_flag; |
| module_param(vecm_latch_flag, uint, 0664); |
| MODULE_PARM_DESC(vecm_latch_flag, "\n vecm_latch_flag\n"); |
| |
| unsigned int vecm_latch_flag2; |
| module_param(vecm_latch_flag2, uint, 0664); |
| MODULE_PARM_DESC(vecm_latch_flag2, "\n vecm_latch_flag2\n"); |
| |
| unsigned int pq_load_en = 1;/* load pq table enable/disable */ |
| module_param(pq_load_en, uint, 0664); |
| MODULE_PARM_DESC(pq_load_en, "\n pq_load_en\n"); |
| |
| bool gamma_en; /* wb_gamma_en enable/disable */ |
| module_param(gamma_en, bool, 0664); |
| MODULE_PARM_DESC(gamma_en, "\n gamma_en\n"); |
| |
| bool wb_en; /* wb_en enable/disable */ |
| module_param(wb_en, bool, 0664); |
| MODULE_PARM_DESC(wb_en, "\n wb_en\n"); |
| |
| unsigned int lut3d_long_sec_en = 1; /* lut3d_long_sec_en enable/disable */ |
| unsigned int lut3d_compress = 1; /* lut3d_compress enable/disable */ |
| unsigned int lut3d_write_from_file = 1; /* lut3d_write from a file */ |
| unsigned int lut3d_data_source = 2;/* read fron bin */ |
| |
| unsigned int probe_ok;/* probe ok or not */ |
| module_param(probe_ok, uint, 0664); |
| MODULE_PARM_DESC(probe_ok, "\n probe_ok\n"); |
| |
| static unsigned int sr1_index;/* for sr1 read */ |
| module_param(sr1_index, uint, 0664); |
| MODULE_PARM_DESC(sr1_index, "\n sr1_index\n"); |
| |
| static int mtx_sel_dbg;/* for mtx debug */ |
| module_param(mtx_sel_dbg, uint, 0664); |
| MODULE_PARM_DESC(mtx_sel_dbg, "\n mtx_sel_dbg\n"); |
| |
| unsigned int pq_user_latch_flag; |
| module_param(pq_user_latch_flag, uint, 0664); |
| MODULE_PARM_DESC(pq_user_latch_flag, "\n pq_user_latch_flag\n"); |
| |
| unsigned int fmeter_debug = 255;/* for fmeter debug */ |
| module_param(fmeter_debug, uint, 0664); |
| MODULE_PARM_DESC(fmeter_debug, "\n fmeter_debug\n"); |
| |
| unsigned int fmeter_count = 2;/* for fmeter count */ |
| module_param(fmeter_count, uint, 0664); |
| MODULE_PARM_DESC(fmeter_count, "\n fmeter_count\n"); |
| |
| /*0: 709/601 1: bt2020*/ |
| int tx_op_color_primary; |
| module_param(tx_op_color_primary, int, 0664); |
| MODULE_PARM_DESC(tx_op_color_primary, |
| "tx output color_primary"); |
| |
| unsigned int debug_game_mode_1; |
| module_param(debug_game_mode_1, uint, 0664); |
| MODULE_PARM_DESC(debug_game_mode_1, "\n debug_game_mode_1\n"); |
| int freerun_en = GAME_MODE;/* 0:game mode;1:freerun mode */ |
| module_param(freerun_en, int, 0664); |
| MODULE_PARM_DESC(freerun_en, "\n enable or disable freerun\n"); |
| |
| unsigned int pq_user_value; |
| enum hdr_type_e hdr_source_type = HDRTYPE_NONE; |
| |
| unsigned int sr_demo_flag; |
| |
| unsigned int pd_detect_en; |
| int pd_weak_fix_lvl = PD_LOW_LVL; |
| int pd_fix_lvl = PD_HIG_LVL; |
| |
| unsigned int gmv_weak_th = 4; |
| unsigned int gmv_th = 17; |
| |
| int pre_fmeter_level = 0, cur_fmeter_level = 0, fmeter_flag = 0; |
| int cur_sr_level = 5; |
| int sat_hue_offset_val; |
| |
| static int wb_init_bypass_coef[24] = { |
| 0, 0, 0, /* pre offset */ |
| 1024, 0, 0, |
| 0, 1024, 0, |
| 0, 0, 1024, |
| 0, 0, 0, /* 10'/11'/12' */ |
| 0, 0, 0, /* 20'/21'/22' */ |
| 0, 0, 0, /* offset */ |
| 0, 0, 0 /* mode, right_shift, clip_en */ |
| }; |
| |
| static int sr0_gain_val[11] = { |
| 128, 128, 120, 112, 104, 96, 88, 80, 72, 64, 64 |
| }; |
| |
| static int sr0_shoot_val[11] = { |
| 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 |
| }; |
| |
| static int sr1_gain_val[11] = { |
| 128, 128, 120, 112, 104, 96, 88, 80, 72, 64, 64 |
| }; |
| |
| static int sr1_shoot_val[11] = { |
| 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20 |
| }; |
| |
| static int sr0_gain_lmt[11] = { |
| 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60 |
| }; |
| |
| static int sr1_gain_lmt[11] = { |
| 20, 25, 28, 30, 35, 38, 40, 45, 50, 55, 60 |
| }; |
| |
| static int nn_coring[11] = { |
| 10, 8, 6, 4, 3, 2, 1, 1, 1, 1, 1 |
| }; |
| |
| #define AIPQ_SCENE_MAX 25 |
| #define AIPQ_FUNC_MAX 10 |
| #define AIPQ_SINGL_DATA_LEN 3 |
| |
| static struct vpp_mtx_info_s mtx_info = { |
| MTX_NULL, |
| { |
| {0, 0, 0}, |
| { |
| {0x400, 0x0, 0x0}, |
| {0x0, 0x400, 0x0}, |
| {0x0, 0x0, 0x400}, |
| }, |
| {0, 0, 0}, |
| 0, |
| 0, |
| } |
| }; |
| |
| static struct pre_gamma_table_s pre_gamma; |
| struct eye_protect_s eye_protect; |
| static int hist_chl; |
| |
| static void str_sapr_to_d(char *s, int *d, int n) |
| { |
| int i, j, count; |
| long value; |
| char des[9] = {0}; |
| |
| count = (strlen(s) + n - 2) / (n - 1); |
| for (i = 0; i < count; i++) { |
| for (j = 0; j < n - 1; j++) |
| des[j] = s[j + i * (n - 1)]; |
| |
| des[n - 1] = '\0'; |
| if (kstrtol(des, 10, &value) < 0) |
| return; |
| d[i] = value; |
| } |
| } |
| |
| static void d_convert_str(int num, |
| int num_num, char cur_s[], |
| int char_bit, int bit_chose) |
| { |
| char buf[9] = {0}; |
| int i, count; |
| |
| if (bit_chose == 10) |
| snprintf(buf, sizeof(buf), "%d", num); |
| else if (bit_chose == 16) |
| snprintf(buf, sizeof(buf), "%x", num); |
| count = strlen(buf); |
| if (count > 4) |
| count = 4; |
| for (i = 0; i < count; i++) |
| buf[i + char_bit] = buf[i]; |
| for (i = 0; i < char_bit; i++) |
| buf[i] = '0'; |
| count = strlen(buf); |
| for (i = 0; i < char_bit; i++) |
| buf[i] = buf[count - char_bit + i]; |
| if (num_num > 0) { |
| for (i = 0; i < char_bit; i++) |
| cur_s[i + num_num * char_bit] = |
| buf[i]; |
| } else { |
| for (i = 0; i < char_bit; i++) |
| cur_s[i] = buf[i]; |
| } |
| } |
| |
| /* vpp brightness/contrast/saturation/hue */ |
| int __init amvecm_load_pq_val(char *str) |
| { |
| int i = 0, err = 0; |
| char *tk = NULL, *tmp[4]; |
| long val; |
| |
| if (!str) { |
| pr_err("[amvecm] pq val error !!!\n"); |
| return 0; |
| } |
| |
| for (tk = strsep(&str, ","); tk; tk = strsep(&str, ",")) { |
| tmp[i] = tk; |
| err = kstrtol(tmp[i], 10, &val); |
| if (err) { |
| pr_err("[amvecm] pq string error !!!\n"); |
| break; |
| } |
| /* pr_err("[amvecm] pq[%d]: %d\n", i, (int)val[i]); */ |
| |
| /* only need to get sat/hue value,*/ |
| /*brightness/contrast can be got from registers */ |
| if (i == 2) |
| saturation_post = (int)val; |
| else if (i == 3) |
| hue_post = (int)val; |
| i++; |
| if (i >= 4) |
| return 0; |
| } |
| |
| return 0; |
| } |
| __setup("pq=", amvecm_load_pq_val); |
| |
| void amvecm_vadj_latch_process(void) |
| { |
| /*vadj switch control according to vadj1_en/vadj2_en*/ |
| unsigned int cur_vadj1_en, cur_vadj2_en; |
| unsigned int vadj1_en = vdj_mode_s.vadj1_en; |
| unsigned int vadj2_en = vdj_mode_s.vadj2_en; |
| |
| if (vecm_latch_flag & FLAG_VADJ_EN) { |
| vecm_latch_flag &= ~FLAG_VADJ_EN; |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| cur_vadj1_en = READ_VPP_REG_BITS(VPP_VADJ1_MISC, 0, 1); |
| cur_vadj2_en = READ_VPP_REG_BITS(VPP_VADJ2_MISC, 0, 1); |
| if (cur_vadj1_en != vadj1_en) { |
| VSYNC_WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, |
| vadj1_en, 0, 1); |
| pr_amvecm_dbg("[amvecm.]vadj1 switch[%d->%d]success.\n", |
| cur_vadj1_en, vadj1_en); |
| } else { |
| pr_amvecm_dbg("[amvecm.] vadj1_en status unchanged.\n"); |
| } |
| |
| if (cur_vadj2_en != vadj2_en) { |
| VSYNC_WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, |
| vadj2_en, 0, 1); |
| pr_amvecm_dbg("[amvecm.] vadj2 switch [%d->%d] success.\n", |
| cur_vadj2_en, vadj2_en); |
| } else { |
| pr_amvecm_dbg("[amvecm.] vadj2_en status unchanged.\n"); |
| } |
| } else { |
| cur_vadj1_en = READ_VPP_REG_BITS(VPP_VADJ_CTRL, 0, 1); |
| cur_vadj2_en = READ_VPP_REG_BITS(VPP_VADJ_CTRL, 2, 1); |
| |
| if (cur_vadj1_en != vadj1_en) { |
| VSYNC_WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, |
| vadj1_en, 0, 1); |
| pr_amvecm_dbg("[amvecm] vadj1 switch [%d->%d] success.\n", |
| cur_vadj1_en, vadj1_en); |
| } else { |
| pr_amvecm_dbg("[amvecm] vadj1_en status unchanged.\n"); |
| } |
| |
| if (cur_vadj2_en != vadj2_en) { |
| VSYNC_WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, |
| vadj2_en, 2, 1); |
| pr_amvecm_dbg("[amvecm] vadj2 switch [%d->%d] success.\n", |
| cur_vadj2_en, vadj2_en); |
| } else { |
| pr_amvecm_dbg("[amvecm] vadj2_en status unchanged.\n"); |
| } |
| } |
| } |
| } |
| |
| static int amvecm_set_contrast2(int val) |
| { |
| val += 0x80; |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| WRITE_VPP_REG_BITS(VPP_VADJ2_Y_2, |
| val, 0, 8); |
| WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, 1, 0, 1); |
| |
| } else { |
| WRITE_VPP_REG_BITS(VPP_VADJ2_Y, |
| val, 0, 8); |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 2, 1); |
| } |
| return 0; |
| } |
| |
| static int amvecm_set_brightness2(int val) |
| { |
| if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| WRITE_VPP_REG_BITS(VPP_VADJ2_Y, |
| val, 8, 9); |
| #endif |
| } |
| else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ2_Y_2, |
| val, 8, 11); |
| else |
| WRITE_VPP_REG_BITS(VPP_VADJ2_Y, |
| val >> 1, 8, 10); |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, 1, 0, 1); |
| else |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 2, 1); |
| return 0; |
| } |
| |
| static void amvecm_size_patch(unsigned int cm_in_w, |
| unsigned int cm_in_h) |
| { |
| unsigned int hs, he, vs, ve; |
| |
| if (cm_in_w == 0 && cm_in_h == 0) { |
| hs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END, 16, 13); |
| he = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END, 0, 13); |
| |
| vs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END, 16, 13); |
| ve = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END, 0, 13); |
| cm2_frame_size_patch(he - hs + 1, ve - vs + 1); |
| } else { |
| cm2_frame_size_patch(cm_in_w, cm_in_h); |
| } |
| } |
| |
| /* video adj1 */ |
| static ssize_t video_adj1_brightness_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| s32 val = 0; |
| |
| if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| val = (READ_VPP_REG(VPP_VADJ1_Y) >> 8) & 0x1ff; |
| val = (val << 23) >> 23; |
| |
| return sprintf(buf, "%d\n", val); |
| #endif |
| } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| val = (READ_VPP_REG(VPP_VADJ1_Y_2) >> 8) & 0x7ff; |
| val = (val << 21) >> 21; |
| |
| return sprintf(buf, "%d\n", val); |
| } |
| val = (READ_VPP_REG(VPP_VADJ1_Y) >> 8) & 0x3ff; |
| val = (val << 22) >> 22; |
| |
| return sprintf(buf, "%d\n", val << 1); |
| } |
| |
| static ssize_t video_adj1_brightness_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%d\n", &val); |
| if (r != 1 || val < -1024 || val > 1023) |
| return -EINVAL; |
| |
| if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) |
| WRITE_VPP_REG_BITS(VPP_VADJ1_Y, val, 8, 9); |
| else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ1_Y_2, val, 8, 11); |
| else |
| WRITE_VPP_REG_BITS(VPP_VADJ1_Y, val >> 1, 8, 10); |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1); |
| else |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1); |
| |
| return count; |
| } |
| |
| static ssize_t video_adj1_contrast_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| return sprintf(buf, "%d\n", |
| (int)(READ_VPP_REG(VPP_VADJ1_Y_2) & 0xff) - 0x80); |
| else |
| return sprintf(buf, "%d\n", |
| (int)(READ_VPP_REG(VPP_VADJ1_Y) & 0xff) - 0x80); |
| } |
| |
| static ssize_t video_adj1_contrast_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%d\n", &val); |
| if (r != 1 || val < -127 || val > 127) |
| return -EINVAL; |
| |
| val += 0x80; |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| WRITE_VPP_REG_BITS(VPP_VADJ1_Y_2, val, 0, 8); |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1); |
| } else { |
| WRITE_VPP_REG_BITS(VPP_VADJ1_Y, val, 0, 8); |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1); |
| } |
| |
| return count; |
| } |
| |
| /* video adj2 */ |
| static ssize_t video_adj2_brightness_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| s32 val = 0; |
| |
| if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| val = (READ_VPP_REG(VPP_VADJ2_Y) >> 8) & 0x1ff; |
| val = (val << 23) >> 23; |
| |
| return sprintf(buf, "%d\n", val); |
| #endif |
| } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| val = (READ_VPP_REG(VPP_VADJ2_Y_2) >> 8) & 0x7ff; |
| val = (val << 21) >> 21; |
| |
| return sprintf(buf, "%d\n", val); |
| } |
| val = (READ_VPP_REG(VPP_VADJ2_Y) >> 8) & 0x3ff; |
| val = (val << 22) >> 22; |
| |
| return sprintf(buf, "%d\n", val << 1); |
| } |
| |
| static ssize_t video_adj2_brightness_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%d\n", &val); |
| if (r != 1 || val < -1024 || val > 1023) |
| return -EINVAL; |
| amvecm_set_brightness2(val); |
| return count; |
| } |
| |
| static ssize_t video_adj2_contrast_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| return sprintf(buf, "%d\n", |
| (int)(READ_VPP_REG(VPP_VADJ2_Y_2) & 0xff) - 0x80); |
| else |
| return sprintf(buf, "%d\n", |
| (int)(READ_VPP_REG(VPP_VADJ2_Y) & 0xff) - 0x80); |
| } |
| |
| static ssize_t video_adj2_contrast_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%d\n", &val); |
| if (r != 1 || val < -127 || val > 127) |
| return -EINVAL; |
| amvecm_set_contrast2(val); |
| return count; |
| } |
| |
| static ssize_t amvecm_usage_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("Usage:"); |
| pr_info("brightness_val range:-255~255\n"); |
| pr_info("contrast_val range:-127~127\n"); |
| pr_info("saturation_val range:-128~128\n"); |
| pr_info("hue_val range:-25~25\n"); |
| pr_info("************video brightness & contrast & saturation_hue adj as flow*************\n"); |
| pr_info("echo brightness_val > /sys/class/amvecm/brightness1\n"); |
| pr_info("echo contrast_val > /sys/class/amvecm/contrast1\n"); |
| pr_info("echo saturation_val hue_val > /sys/class/amvecm/saturation_hue_pre\n"); |
| pr_info("************after video+osd blender, brightness & contrast & saturation_hue adj as flow*************\n"); |
| pr_info("echo brightness_val > /sys/class/amvecm/brightness2\n"); |
| pr_info("echo contrast_val > /sys/class/amvecm/contrast2\n"); |
| pr_info("echo saturation_val hue_val > /sys/class/amvecm/saturation_hue_post\n"); |
| return 0; |
| } |
| |
| static void parse_param_amvecm(char *buf_orig, char **parm) |
| { |
| char *ps, *token; |
| unsigned int n = 0; |
| char delim1[3] = " "; |
| char delim2[2] = "\n"; |
| |
| ps = buf_orig; |
| strcat(delim1, delim2); |
| while (1) { |
| token = strsep(&ps, delim1); |
| if (!token) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| } |
| |
| static void amvecm_3d_sync_status(void) |
| { |
| unsigned int sync_h_start, sync_h_end, sync_v_start, |
| sync_v_end, sync_polarity, |
| sync_out_inv, sync_en; |
| if (!is_meson_gxtvbb_cpu()) { |
| pr_info("\n chip does not support 3D sync process!!!\n"); |
| return; |
| } |
| sync_h_start = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC2, 0, 13); |
| sync_h_end = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC2, 16, 13); |
| sync_v_start = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 0, 13); |
| sync_v_end = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 16, 13); |
| sync_polarity = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 29, 1); |
| sync_out_inv = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 15, 1); |
| sync_en = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 31, 1); |
| pr_info("\n current 3d sync state:\n"); |
| pr_info("sync_h_start:%d\n", sync_h_start); |
| pr_info("sync_h_end:%d\n", sync_h_end); |
| pr_info("sync_v_start:%d\n", sync_v_start); |
| pr_info("sync_v_end:%d\n", sync_v_end); |
| pr_info("sync_polarity:%d\n", sync_polarity); |
| pr_info("sync_out_inv:%d\n", sync_out_inv); |
| pr_info("sync_en:%d\n", sync_en); |
| pr_info("sync_3d_black_color:%d\n", sync_3d_black_color); |
| pr_info("sync_3d_sync_to_vbo:%d\n", sync_3d_sync_to_vbo); |
| } |
| |
| static ssize_t amvecm_3d_sync_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| ssize_t len = 0; |
| |
| len += sprintf(buf + len, |
| "echo hstart val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo hend val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo vstart val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo vend val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo pola val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo inv val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo black_color val(Hex) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo sync_to_vx1 val(D) > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo enable > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo disable > /sys/class/amvecm/sync_3d\n"); |
| len += sprintf(buf + len, |
| "echo status > /sys/class/amvecm/sync_3d\n"); |
| return len; |
| } |
| |
| static ssize_t amvecm_3d_sync_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val; |
| |
| if (!buf) |
| return count; |
| |
| if (!is_meson_gxtvbb_cpu()) { |
| pr_info("\n chip does not support 3D sync process!!!\n"); |
| return count; |
| } |
| |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strncmp(parm[0], "hstart", 6)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_h_start = val & 0x1fff; |
| WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC2, sync_3d_h_start, 0, 13); |
| } else if (!strncmp(parm[0], "hend", 4)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_h_end = val & 0x1fff; |
| WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC2, sync_3d_h_end, 16, 13); |
| } else if (!strncmp(parm[0], "vstart", 6)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_v_start = val & 0x1fff; |
| WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_v_start, 0, 13); |
| } else if (!strncmp(parm[0], "vend", 4)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_v_end = val & 0x1fff; |
| WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_v_end, 16, 13); |
| } else if (!strncmp(parm[0], "pola", 4)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_polarity = val & 0x1; |
| WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_polarity, 29, 1); |
| } else if (!strncmp(parm[0], "inv", 3)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_out_inv = val & 0x1; |
| WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_out_inv, 15, 1); |
| } else if (!strncmp(parm[0], "black_color", 11)) { |
| if (kstrtol(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_black_color = val & 0xffffff; |
| WRITE_VPP_REG_BITS(VPP_BLEND_ONECOLOR_CTRL, |
| sync_3d_black_color, 0, 24); |
| } else if (!strncmp(parm[0], "sync_to_vx1", 11)) { |
| if (kstrtol(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| sync_3d_sync_to_vbo = val & 0x1; |
| } else if (!strncmp(parm[0], "enable", 6)) { |
| vecm_latch_flag |= FLAG_3D_SYNC_EN; |
| } else if (!strncmp(parm[0], "disable", 7)) { |
| vecm_latch_flag |= FLAG_3D_SYNC_DIS; |
| } else if (!strncmp(parm[0], "status", 7)) { |
| amvecm_3d_sync_status(); |
| } |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_vlock_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| return vlock_debug_show(cla, attr, buf); |
| } |
| |
| static ssize_t amvecm_vlock_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| return vlock_debug_store(cla, attr, buf, count); |
| } |
| |
| /* #endif */ |
| |
| static void vpp_backup_histgram(struct vframe_s *vf) |
| { |
| unsigned int i = 0; |
| |
| vpp_hist_param.vpp_hist_pow = vf->prop.hist.hist_pow; |
| vpp_hist_param.vpp_luma_sum = vf->prop.hist.vpp_luma_sum; |
| vpp_hist_param.vpp_pixel_sum = vf->prop.hist.vpp_pixel_sum; |
| for (i = 0; i < 64; i++) |
| vpp_hist_param.vpp_histgram[i] = vf->prop.hist.vpp_gamma[i]; |
| for (i = 0; i < 128; i++) |
| vpp_hist_param.hdr_histgram[i] = hdr_hist[NUM_HDR_HIST - 1][i]; |
| for (i = 0; i < 32; i++) |
| vpp_hist_param.hue_histgram[i] = vf->prop.hist.vpp_hue_gamma[i]; |
| for (i = 0; i < 32; i++) |
| vpp_hist_param.sat_histgram[i] = vf->prop.hist.vpp_sat_gamma[i]; |
| } |
| |
| static void vpp_dump_histgram(void) |
| { |
| uint i; |
| |
| pr_info("%s:\n", __func__); |
| if (hdr_source_type == HDRTYPE_HDR10) { |
| pr_info("\t dump_hdr_hist begin\n"); |
| for (i = 0; i < 128; i++) { |
| pr_info("[%d]0x%-8x\t", i, |
| hdr_hist[NUM_HDR_HIST - 1][i]); |
| if ((i + 1) % 8 == 0) |
| pr_info("\n"); |
| } |
| pr_info("\t dump_hdr_hist done\n"); |
| } |
| |
| pr_info("\n\t dump_dnlp_hist begin\n"); |
| for (i = 0; i < 64; i++) { |
| pr_info("[%d]0x%-8x\t", i, vpp_hist_param.vpp_histgram[i]); |
| if ((i + 1) % 8 == 0) |
| pr_info("\n"); |
| } |
| pr_info("\n\t dump_dnlp_hist done\n"); |
| } |
| |
| void vpp_get_hist_en(void) |
| { |
| if (hist_chl) |
| WRITE_VPP_REG_BITS(VI_HIST_CTRL, 0x2, 11, 3); |
| else |
| WRITE_VPP_REG_BITS(VI_HIST_CTRL, 0x1, 11, 3); |
| WRITE_VPP_REG_BITS(VI_HIST_CTRL, 0x1, 0, 1); |
| WRITE_VPP_REG(VI_HIST_GCLK_CTRL, 0xffffffff); |
| WRITE_VPP_REG_BITS(VI_HIST_CTRL, 2, VI_HIST_POW_BIT, VI_HIST_POW_WID); |
| } |
| |
| static unsigned int vpp_luma_max; |
| void vpp_get_vframe_hist_info(struct vframe_s *vf) |
| { |
| unsigned int hist_height, hist_width, i; |
| u64 divid; |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| /*TL1 remove VPP_IN_H_V_SIZE register*/ |
| hist_width = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 0, 13); |
| hist_height = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 16, 13); |
| } else { |
| hist_height = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 0, 13); |
| hist_width = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 16, 13); |
| } |
| |
| if (hist_height != pre_hist_height || |
| hist_width != pre_hist_width) { |
| pre_hist_height = hist_height; |
| pre_hist_width = hist_width; |
| WRITE_VPP_REG_BITS(VI_HIST_PIC_SIZE, hist_height, 16, 13); |
| WRITE_VPP_REG_BITS(VI_HIST_PIC_SIZE, hist_width, 0, 13); |
| } |
| /* fetch hist info */ |
| /* vf->prop.hist.luma_sum = READ_CBUS_REG_BITS(VDIN_HIST_SPL_VAL,*/ |
| /* HIST_LUMA_SUM_BIT, HIST_LUMA_SUM_WID ); */ |
| vf->prop.hist.hist_pow = |
| READ_VPP_REG_BITS(VI_HIST_CTRL, |
| VI_HIST_POW_BIT, VI_HIST_POW_WID); |
| vf->prop.hist.vpp_luma_sum = |
| READ_VPP_REG(VI_HIST_SPL_VAL); |
| /* vf->prop.hist.chroma_sum = READ_CBUS_REG_BITS(VDIN_HIST_CHROMA_SUM,*/ |
| /* HIST_CHROMA_SUM_BIT, HIST_CHROMA_SUM_WID ); */ |
| vf->prop.hist.vpp_chroma_sum = |
| READ_VPP_REG(VI_HIST_CHROMA_SUM); |
| vf->prop.hist.vpp_pixel_sum = |
| READ_VPP_REG_BITS(VI_HIST_SPL_PIX_CNT, |
| VI_HIST_PIX_CNT_BIT, VI_HIST_PIX_CNT_WID); |
| vf->prop.hist.vpp_height = |
| READ_VPP_REG_BITS(VI_HIST_PIC_SIZE, |
| VI_HIST_PIC_HEIGHT_BIT, VI_HIST_PIC_HEIGHT_WID); |
| vf->prop.hist.vpp_width = |
| READ_VPP_REG_BITS(VI_HIST_PIC_SIZE, |
| VI_HIST_PIC_WIDTH_BIT, VI_HIST_PIC_WIDTH_WID); |
| vf->prop.hist.vpp_luma_max = |
| READ_VPP_REG_BITS(VI_HIST_MAX_MIN, |
| VI_HIST_MAX_BIT, VI_HIST_MAX_WID); |
| vf->prop.hist.vpp_luma_min = |
| READ_VPP_REG_BITS(VI_HIST_MAX_MIN, |
| VI_HIST_MIN_BIT, VI_HIST_MIN_WID); |
| vf->prop.hist.vpp_gamma[0] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST00, |
| VI_HIST_ON_BIN_00_BIT, VI_HIST_ON_BIN_00_WID); |
| vf->prop.hist.vpp_gamma[1] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST00, |
| VI_HIST_ON_BIN_01_BIT, VI_HIST_ON_BIN_01_WID); |
| vf->prop.hist.vpp_gamma[2] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST01, |
| VI_HIST_ON_BIN_02_BIT, VI_HIST_ON_BIN_02_WID); |
| vf->prop.hist.vpp_gamma[3] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST01, |
| VI_HIST_ON_BIN_03_BIT, VI_HIST_ON_BIN_03_WID); |
| vf->prop.hist.vpp_gamma[4] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST02, |
| VI_HIST_ON_BIN_04_BIT, VI_HIST_ON_BIN_04_WID); |
| vf->prop.hist.vpp_gamma[5] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST02, |
| VI_HIST_ON_BIN_05_BIT, VI_HIST_ON_BIN_05_WID); |
| vf->prop.hist.vpp_gamma[6] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST03, |
| VI_HIST_ON_BIN_06_BIT, VI_HIST_ON_BIN_06_WID); |
| vf->prop.hist.vpp_gamma[7] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST03, |
| VI_HIST_ON_BIN_07_BIT, VI_HIST_ON_BIN_07_WID); |
| vf->prop.hist.vpp_gamma[8] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST04, |
| VI_HIST_ON_BIN_08_BIT, VI_HIST_ON_BIN_08_WID); |
| vf->prop.hist.vpp_gamma[9] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST04, |
| VI_HIST_ON_BIN_09_BIT, VI_HIST_ON_BIN_09_WID); |
| vf->prop.hist.vpp_gamma[10] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST05, |
| VI_HIST_ON_BIN_10_BIT, VI_HIST_ON_BIN_10_WID); |
| vf->prop.hist.vpp_gamma[11] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST05, |
| VI_HIST_ON_BIN_11_BIT, VI_HIST_ON_BIN_11_WID); |
| vf->prop.hist.vpp_gamma[12] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST06, |
| VI_HIST_ON_BIN_12_BIT, VI_HIST_ON_BIN_12_WID); |
| vf->prop.hist.vpp_gamma[13] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST06, |
| VI_HIST_ON_BIN_13_BIT, VI_HIST_ON_BIN_13_WID); |
| vf->prop.hist.vpp_gamma[14] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST07, |
| VI_HIST_ON_BIN_14_BIT, VI_HIST_ON_BIN_14_WID); |
| vf->prop.hist.vpp_gamma[15] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST07, |
| VI_HIST_ON_BIN_15_BIT, VI_HIST_ON_BIN_15_WID); |
| vf->prop.hist.vpp_gamma[16] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST08, |
| VI_HIST_ON_BIN_16_BIT, VI_HIST_ON_BIN_16_WID); |
| vf->prop.hist.vpp_gamma[17] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST08, |
| VI_HIST_ON_BIN_17_BIT, VI_HIST_ON_BIN_17_WID); |
| vf->prop.hist.vpp_gamma[18] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST09, |
| VI_HIST_ON_BIN_18_BIT, VI_HIST_ON_BIN_18_WID); |
| vf->prop.hist.vpp_gamma[19] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST09, |
| VI_HIST_ON_BIN_19_BIT, VI_HIST_ON_BIN_19_WID); |
| vf->prop.hist.vpp_gamma[20] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST10, |
| VI_HIST_ON_BIN_20_BIT, VI_HIST_ON_BIN_20_WID); |
| vf->prop.hist.vpp_gamma[21] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST10, |
| VI_HIST_ON_BIN_21_BIT, VI_HIST_ON_BIN_21_WID); |
| vf->prop.hist.vpp_gamma[22] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST11, |
| VI_HIST_ON_BIN_22_BIT, VI_HIST_ON_BIN_22_WID); |
| vf->prop.hist.vpp_gamma[23] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST11, |
| VI_HIST_ON_BIN_23_BIT, VI_HIST_ON_BIN_23_WID); |
| vf->prop.hist.vpp_gamma[24] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST12, |
| VI_HIST_ON_BIN_24_BIT, VI_HIST_ON_BIN_24_WID); |
| vf->prop.hist.vpp_gamma[25] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST12, |
| VI_HIST_ON_BIN_25_BIT, VI_HIST_ON_BIN_25_WID); |
| vf->prop.hist.vpp_gamma[26] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST13, |
| VI_HIST_ON_BIN_26_BIT, VI_HIST_ON_BIN_26_WID); |
| vf->prop.hist.vpp_gamma[27] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST13, |
| VI_HIST_ON_BIN_27_BIT, VI_HIST_ON_BIN_27_WID); |
| vf->prop.hist.vpp_gamma[28] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST14, |
| VI_HIST_ON_BIN_28_BIT, VI_HIST_ON_BIN_28_WID); |
| vf->prop.hist.vpp_gamma[29] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST14, |
| VI_HIST_ON_BIN_29_BIT, VI_HIST_ON_BIN_29_WID); |
| vf->prop.hist.vpp_gamma[30] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST15, |
| VI_HIST_ON_BIN_30_BIT, VI_HIST_ON_BIN_30_WID); |
| vf->prop.hist.vpp_gamma[31] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST15, |
| VI_HIST_ON_BIN_31_BIT, VI_HIST_ON_BIN_31_WID); |
| vf->prop.hist.vpp_gamma[32] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST16, |
| VI_HIST_ON_BIN_32_BIT, VI_HIST_ON_BIN_32_WID); |
| vf->prop.hist.vpp_gamma[33] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST16, |
| VI_HIST_ON_BIN_33_BIT, VI_HIST_ON_BIN_33_WID); |
| vf->prop.hist.vpp_gamma[34] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST17, |
| VI_HIST_ON_BIN_34_BIT, VI_HIST_ON_BIN_34_WID); |
| vf->prop.hist.vpp_gamma[35] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST17, |
| VI_HIST_ON_BIN_35_BIT, VI_HIST_ON_BIN_35_WID); |
| vf->prop.hist.vpp_gamma[36] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST18, |
| VI_HIST_ON_BIN_36_BIT, VI_HIST_ON_BIN_36_WID); |
| vf->prop.hist.vpp_gamma[37] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST18, |
| VI_HIST_ON_BIN_37_BIT, VI_HIST_ON_BIN_37_WID); |
| vf->prop.hist.vpp_gamma[38] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST19, |
| VI_HIST_ON_BIN_38_BIT, VI_HIST_ON_BIN_38_WID); |
| vf->prop.hist.vpp_gamma[39] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST19, |
| VI_HIST_ON_BIN_39_BIT, VI_HIST_ON_BIN_39_WID); |
| vf->prop.hist.vpp_gamma[40] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST20, |
| VI_HIST_ON_BIN_40_BIT, VI_HIST_ON_BIN_40_WID); |
| vf->prop.hist.vpp_gamma[41] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST20, |
| VI_HIST_ON_BIN_41_BIT, VI_HIST_ON_BIN_41_WID); |
| vf->prop.hist.vpp_gamma[42] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST21, |
| VI_HIST_ON_BIN_42_BIT, VI_HIST_ON_BIN_42_WID); |
| vf->prop.hist.vpp_gamma[43] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST21, |
| VI_HIST_ON_BIN_43_BIT, VI_HIST_ON_BIN_43_WID); |
| vf->prop.hist.vpp_gamma[44] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST22, |
| VI_HIST_ON_BIN_44_BIT, VI_HIST_ON_BIN_44_WID); |
| vf->prop.hist.vpp_gamma[45] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST22, |
| VI_HIST_ON_BIN_45_BIT, VI_HIST_ON_BIN_45_WID); |
| vf->prop.hist.vpp_gamma[46] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST23, |
| VI_HIST_ON_BIN_46_BIT, VI_HIST_ON_BIN_46_WID); |
| vf->prop.hist.vpp_gamma[47] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST23, |
| VI_HIST_ON_BIN_47_BIT, VI_HIST_ON_BIN_47_WID); |
| vf->prop.hist.vpp_gamma[48] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST24, |
| VI_HIST_ON_BIN_48_BIT, VI_HIST_ON_BIN_48_WID); |
| vf->prop.hist.vpp_gamma[49] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST24, |
| VI_HIST_ON_BIN_49_BIT, VI_HIST_ON_BIN_49_WID); |
| vf->prop.hist.vpp_gamma[50] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST25, |
| VI_HIST_ON_BIN_50_BIT, VI_HIST_ON_BIN_50_WID); |
| vf->prop.hist.vpp_gamma[51] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST25, |
| VI_HIST_ON_BIN_51_BIT, VI_HIST_ON_BIN_51_WID); |
| vf->prop.hist.vpp_gamma[52] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST26, |
| VI_HIST_ON_BIN_52_BIT, VI_HIST_ON_BIN_52_WID); |
| vf->prop.hist.vpp_gamma[53] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST26, |
| VI_HIST_ON_BIN_53_BIT, VI_HIST_ON_BIN_53_WID); |
| vf->prop.hist.vpp_gamma[54] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST27, |
| VI_HIST_ON_BIN_54_BIT, VI_HIST_ON_BIN_54_WID); |
| vf->prop.hist.vpp_gamma[55] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST27, |
| VI_HIST_ON_BIN_55_BIT, VI_HIST_ON_BIN_55_WID); |
| vf->prop.hist.vpp_gamma[56] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST28, |
| VI_HIST_ON_BIN_56_BIT, VI_HIST_ON_BIN_56_WID); |
| vf->prop.hist.vpp_gamma[57] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST28, |
| VI_HIST_ON_BIN_57_BIT, VI_HIST_ON_BIN_57_WID); |
| vf->prop.hist.vpp_gamma[58] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST29, |
| VI_HIST_ON_BIN_58_BIT, VI_HIST_ON_BIN_58_WID); |
| vf->prop.hist.vpp_gamma[59] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST29, |
| VI_HIST_ON_BIN_59_BIT, VI_HIST_ON_BIN_59_WID); |
| vf->prop.hist.vpp_gamma[60] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST30, |
| VI_HIST_ON_BIN_60_BIT, VI_HIST_ON_BIN_60_WID); |
| vf->prop.hist.vpp_gamma[61] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST30, |
| VI_HIST_ON_BIN_61_BIT, VI_HIST_ON_BIN_61_WID); |
| vf->prop.hist.vpp_gamma[62] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST31, |
| VI_HIST_ON_BIN_62_BIT, VI_HIST_ON_BIN_62_WID); |
| vf->prop.hist.vpp_gamma[63] = |
| READ_VPP_REG_BITS(VI_DNLP_HIST31, |
| VI_HIST_ON_BIN_63_BIT, VI_HIST_ON_BIN_63_WID); |
| |
| if (get_cpu_type() == MESON_CPU_MAJOR_ID_T3 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5W) { |
| vf->fmeter0_hcnt[0] = |
| READ_VPP_REG(SRSHARP0_RO_FMETER_HCNT_TYPE0); |
| vf->fmeter0_hcnt[1] = |
| READ_VPP_REG(SRSHARP0_RO_FMETER_HCNT_TYPE1); |
| vf->fmeter0_hcnt[2] = |
| READ_VPP_REG(SRSHARP0_RO_FMETER_HCNT_TYPE2); |
| vf->fmeter0_hcnt[3] = |
| READ_VPP_REG(SRSHARP0_RO_FMETER_HCNT_TYPE3); |
| vf->fmeter1_hcnt[0] = |
| READ_VPP_REG(SRSHARP1_RO_FMETER_HCNT_TYPE0); |
| vf->fmeter1_hcnt[1] = |
| READ_VPP_REG(SRSHARP1_RO_FMETER_HCNT_TYPE1); |
| vf->fmeter1_hcnt[2] = |
| READ_VPP_REG(SRSHARP1_RO_FMETER_HCNT_TYPE2); |
| vf->fmeter1_hcnt[3] = |
| READ_VPP_REG(SRSHARP1_RO_FMETER_HCNT_TYPE3); |
| |
| vf->fmeter0_score = FMETER_SCORE(vf->fmeter0_hcnt[0], |
| vf->fmeter0_hcnt[1], vf->fmeter0_hcnt[2]); |
| |
| vf->fmeter1_score = FMETER_SCORE(vf->fmeter1_hcnt[0], |
| vf->fmeter1_hcnt[1], vf->fmeter1_hcnt[2]); |
| } |
| |
| if (enable_pattern_detect == 1) { |
| for (i = 0; i < 32; i++) { |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, |
| RO_CM_HUE_HIST_BIN0 + i); |
| vf->prop.hist.vpp_hue_gamma[i] = |
| READ_VPP_REG(VPP_CHROMA_DATA_PORT); |
| } |
| for (i = 0; i < 32; i++) { |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, |
| RO_CM_SAT_HIST_BIN0 + i); |
| vf->prop.hist.vpp_sat_gamma[i] = |
| READ_VPP_REG(VPP_CHROMA_DATA_PORT); |
| } |
| } |
| if (debug_game_mode_1 && |
| vpp_luma_max != vf->prop.hist.vpp_luma_max) { |
| divid = sched_clock(); |
| vf->ready_clock_hist[1] = sched_clock(); |
| do_div(divid, 1000); |
| pr_info("vpp output done %lld us. luma_max(0x%x-->0x%x)\n", |
| divid, vpp_luma_max, vf->prop.hist.vpp_luma_max); |
| vpp_luma_max = vf->prop.hist.vpp_luma_max; |
| } |
| } |
| |
| static void ioctrl_get_hdr_metadata(struct vframe_s *vf) |
| { |
| if (((vf->signal_type >> 16) & 0xff) == 9) { |
| if (vf->prop.master_display_colour.present_flag) { |
| memcpy(vpp_hdr_metadata_s.primaries, |
| vf->prop.master_display_colour.primaries, |
| sizeof(u32) * 6); |
| memcpy(vpp_hdr_metadata_s.white_point, |
| vf->prop.master_display_colour.white_point, |
| sizeof(u32) * 2); |
| vpp_hdr_metadata_s.luminance[0] = |
| vf->prop.master_display_colour.luminance[0]; |
| vpp_hdr_metadata_s.luminance[1] = |
| vf->prop.master_display_colour.luminance[1]; |
| } else { |
| memset(vpp_hdr_metadata_s.primaries, 0, |
| sizeof(vpp_hdr_metadata_s.primaries)); |
| } |
| } else { |
| memset(vpp_hdr_metadata_s.primaries, 0, |
| sizeof(vpp_hdr_metadata_s.primaries)); |
| } |
| } |
| |
| void vpp_demo_config(struct vframe_s *vf) |
| { |
| unsigned int reg_value; |
| /*dnlp demo config*/ |
| if (vecm_latch_flag2 & VPP_DEMO_DNLP_EN) { |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 1, 18, 1); |
| /*bit14-15 left: 2 right: 3*/ |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 2, 14, 2); |
| reg_value = READ_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 0, 1); |
| if ((vf->height > 1080 && vf->width > 1920) || |
| reg_value == 0) |
| WRITE_VPP_REG_BITS(VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH, |
| 1920, 0, 12); |
| else |
| WRITE_VPP_REG_BITS(VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH, |
| 960, 0, 12); |
| vecm_latch_flag2 &= ~VPP_DEMO_DNLP_EN; |
| } else if (vecm_latch_flag2 & VPP_DEMO_DNLP_DIS) { |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 18, 1); |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 14, 2); |
| WRITE_VPP_REG_BITS(VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH, |
| 0xfff, 0, 12); |
| vecm_latch_flag2 &= ~VPP_DEMO_DNLP_DIS; |
| } |
| /*cm demo config*/ |
| if (vecm_latch_flag2 & VPP_DEMO_CM_EN) { |
| /*left: 0x1 right: 0x4*/ |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, 0x20f); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x1); |
| vecm_latch_flag2 &= ~VPP_DEMO_CM_EN; |
| } else if (vecm_latch_flag2 & VPP_DEMO_CM_DIS) { |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, 0x20f); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x0); |
| vecm_latch_flag2 &= ~VPP_DEMO_CM_DIS; |
| } |
| } |
| |
| void amvecm_dejaggy_patch(struct vframe_s *vf) |
| { |
| int gmv; |
| |
| if (!vf) { |
| if (pd_detect_en) |
| pd_detect_en = 0; |
| return; |
| } |
| gmv = vf->di_gmv / 10000; |
| |
| if (vf->height == 1080 && |
| vf->width == 1920 && |
| (vf->di_pulldown & (1 << 3)) && |
| ((vf->di_pulldown & 0x7) || gmv >= gmv_th)) { |
| if (pd_detect_en == 1) |
| return; |
| pd_detect_en = 1; |
| pd_combing_fix_patch(pd_fix_lvl); |
| pr_amvecm_dbg("pd_detect_en1 = %d; level = %d, gmv %d\n", |
| pd_detect_en, pd_fix_lvl, gmv); |
| } else if ((vf->height == 1080) && |
| (vf->width == 1920) && |
| (vf->di_pulldown & (1 << 3)) && |
| (gmv >= gmv_weak_th)) { |
| if (pd_detect_en == 2) |
| return; |
| pd_detect_en = 2; |
| |
| pd_combing_fix_patch(pd_weak_fix_lvl); |
| pr_amvecm_dbg("pd_detect_en2 = %d; level = %d, gmv %d\n", |
| pd_detect_en, pd_weak_fix_lvl, gmv); |
| } else if (pd_detect_en) { |
| pd_detect_en = 0; |
| pd_combing_fix_patch(PD_DEF_LVL); |
| pr_amvecm_dbg("pd_detect_en = %d; pd_fix_lvl = %d\n", |
| pd_detect_en, pd_fix_lvl); |
| } |
| } |
| |
| /*sr fmeter interface*/ |
| void amvecm_fmeter_process(struct vframe_s *vf) |
| { |
| u8 fmeter_score_unit, fmeter_score_ten, fmeter_score_hundred; |
| uint val; |
| uint reg_val; |
| |
| if (!vf) |
| return; |
| |
| if (vf->height <= 1080 && vf->width <= 1920) { |
| fmeter_score_hundred = vf->fmeter0_score / 100; |
| fmeter_score_ten = |
| (vf->fmeter0_score - fmeter_score_hundred * 100) / 10; |
| fmeter_score_unit = |
| vf->fmeter0_score - fmeter_score_hundred * 100 |
| - fmeter_score_ten * 10; |
| if (fmeter_debug == 3) |
| pr_info("fmeter0_hcnt0 = %d,hcnt1 = %d,hcnt2 = %d,hcnt3 = %d\n", |
| vf->fmeter0_hcnt[0], vf->fmeter0_hcnt[1], |
| vf->fmeter0_hcnt[2], vf->fmeter0_hcnt[3]); |
| if (fmeter_debug == 2) |
| pr_info("fmeter0_score = %d\n", vf->fmeter0_score); |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_FRC |
| if (fmeter_debug == 1) |
| frc_set_seg_display(1, fmeter_score_hundred, |
| fmeter_score_ten, fmeter_score_unit); |
| if (fmeter_debug == 0) |
| frc_set_seg_display(0, 0, 0, 0); |
| #endif |
| |
| cur_fmeter_level = vf->fmeter0_score / 10; |
| if (cur_fmeter_level > 10) |
| cur_fmeter_level = 10; |
| if (cur_fmeter_level < 0) |
| cur_fmeter_level = 0; |
| |
| if (cur_fmeter_level == pre_fmeter_level) |
| fmeter_flag++; |
| else |
| fmeter_flag = 0; |
| } else { |
| fmeter_score_hundred = vf->fmeter1_score / 100; |
| fmeter_score_ten = |
| (vf->fmeter1_score - fmeter_score_hundred * 100) / 10; |
| fmeter_score_unit = |
| vf->fmeter1_score - fmeter_score_hundred * 100 |
| - fmeter_score_ten * 10; |
| if (fmeter_debug == 3) |
| pr_info("fmeter1_hcnt0 = %d,hcnt1 = %d,hcnt2 = %d,hcnt3 = %d\n", |
| vf->fmeter1_hcnt[0], vf->fmeter1_hcnt[1], |
| vf->fmeter1_hcnt[2], vf->fmeter1_hcnt[3]); |
| if (fmeter_debug == 2) |
| pr_info("fmeter1_score = %d\n", vf->fmeter1_score); |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_FRC |
| if (fmeter_debug == 1) |
| frc_set_seg_display(1, fmeter_score_hundred, |
| fmeter_score_ten, fmeter_score_unit); |
| if (fmeter_debug == 0) |
| frc_set_seg_display(0, 0, 0, 0); |
| #endif |
| |
| cur_fmeter_level = vf->fmeter1_score / 10; |
| if (cur_fmeter_level > 10) |
| cur_fmeter_level = 10; |
| if (cur_fmeter_level < 0) |
| cur_fmeter_level = 0; |
| |
| if (cur_fmeter_level == pre_fmeter_level) |
| fmeter_flag++; |
| else |
| fmeter_flag = 0; |
| } |
| |
| if (fmeter_flag == fmeter_count && fmeter_en) { |
| fmeter_flag = 0; |
| if (cur_sr_level < cur_fmeter_level) |
| cur_sr_level++; |
| else if (cur_sr_level > cur_fmeter_level) |
| cur_sr_level--; |
| else |
| return; |
| |
| val = sr1_gain_val[cur_sr_level] << 24 | |
| sr1_gain_val[cur_sr_level] << 16 | |
| sr1_gain_val[cur_sr_level] << 8 | |
| sr1_gain_val[cur_sr_level]; |
| VSYNC_WRITE_VPP_REG(SRSHARP1_SR7_PKLONG_PF_GAIN, val); |
| |
| reg_val = READ_VPP_REG(SRSHARP1_PK_OS_STATIC); |
| |
| reg_val &= ~(0x3ff | (0x3ff << 12)); |
| val = reg_val | |
| ((sr1_shoot_val[cur_sr_level] & 0x3ff) << 12) | |
| (sr1_shoot_val[cur_sr_level] & 0x3ff); |
| |
| VSYNC_WRITE_VPP_REG(SRSHARP1_PK_OS_STATIC, val); |
| |
| val = sr0_gain_val[cur_sr_level] << 24 | |
| sr0_gain_val[cur_sr_level] << 16 | |
| sr0_gain_val[cur_sr_level] << 8 | |
| sr0_gain_val[cur_sr_level]; |
| VSYNC_WRITE_VPP_REG(SRSHARP0_SR7_PKLONG_PF_GAIN, val); |
| |
| reg_val = READ_VPP_REG(SRSHARP0_PK_OS_STATIC); |
| reg_val &= ~(0x3ff | (0x3ff << 12)); |
| val = reg_val | |
| ((sr0_shoot_val[cur_sr_level] & 0x3ff) << 12) | |
| (sr0_shoot_val[cur_sr_level] & 0x3ff); |
| |
| VSYNC_WRITE_VPP_REG(SRSHARP0_PK_OS_STATIC, val); |
| |
| reg_val = READ_VPP_REG(SRSHARP1_PK_CON_2CIRHPGAIN_LIMIT); |
| reg_val &= ~(0xff << 24); |
| val = reg_val | |
| ((sr1_gain_lmt[cur_sr_level] & 0xff) << 24); |
| |
| VSYNC_WRITE_VPP_REG(SRSHARP1_PK_CON_2CIRHPGAIN_LIMIT, val); |
| |
| |
| reg_val = READ_VPP_REG(SRSHARP1_PK_CON_2CIRBPGAIN_LIMIT); |
| reg_val &= ~(0xff << 24); |
| val = reg_val | |
| ((sr1_gain_lmt[cur_sr_level] & 0xff) << 24); |
| |
| VSYNC_WRITE_VPP_REG(SRSHARP1_PK_CON_2CIRBPGAIN_LIMIT, val); |
| |
| reg_val = READ_VPP_REG(SRSHARP0_PK_CON_2CIRHPGAIN_LIMIT); |
| reg_val &= ~(0xff << 24); |
| val = reg_val | |
| ((sr0_gain_lmt[cur_sr_level] & 0xff) << 24); |
| |
| VSYNC_WRITE_VPP_REG(SRSHARP0_PK_CON_2CIRHPGAIN_LIMIT, val); |
| |
| reg_val = READ_VPP_REG(SRSHARP0_PK_CON_2CIRBPGAIN_LIMIT); |
| reg_val &= ~(0xff << 24); |
| val = reg_val | |
| ((sr0_gain_lmt[cur_sr_level] & 0xff) << 24); |
| |
| VSYNC_WRITE_VPP_REG(SRSHARP0_PK_CON_2CIRBPGAIN_LIMIT, val); |
| |
| if (get_cpu_type() == MESON_CPU_MAJOR_ID_T3) { |
| reg_val = READ_VPP_REG(NN_ADP_CORING); |
| reg_val &= ~(0xff << 8); |
| val = reg_val | |
| ((nn_coring[cur_sr_level] & 0xff) << 8); |
| |
| VSYNC_WRITE_VPP_REG(NN_ADP_CORING, val); |
| } |
| } |
| pre_fmeter_level = cur_fmeter_level; |
| } |
| |
| static int vpp_mtx_update(struct vpp_mtx_info_s *mtx_info) |
| { |
| 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; |
| |
| enum vpp_matrix_e mtx_sel; |
| unsigned int coef00_01 = 0; |
| unsigned int coef02_10 = 0; |
| unsigned int coef11_12 = 0; |
| unsigned int coef20_21 = 0; |
| unsigned int coef22 = 0; |
| unsigned int clip = 0; |
| unsigned int offset0_1 = 0; |
| unsigned int offset2 = 0; |
| unsigned int pre_offset0_1 = 0; |
| unsigned int pre_offset2 = 0; |
| unsigned int en = 0; |
| |
| if (!(vecm_latch_flag2 & (VPP_MARTIX_UPDATE | VPP_MARTIX_GET))) |
| return 0; |
| |
| mtx_sel = mtx_info->mtx_sel; |
| switch (mtx_sel) { |
| case VD1_MTX: |
| matrix_coef00_01 = VPP_VD1_MATRIX_COEF00_01; |
| matrix_coef02_10 = VPP_VD1_MATRIX_COEF02_10; |
| matrix_coef11_12 = VPP_VD1_MATRIX_COEF11_12; |
| matrix_coef20_21 = VPP_VD1_MATRIX_COEF20_21; |
| matrix_coef22 = VPP_VD1_MATRIX_COEF22; |
| matrix_clip = VPP_VD1_MATRIX_CLIP; |
| matrix_offset0_1 = VPP_VD1_MATRIX_OFFSET0_1; |
| matrix_offset2 = VPP_VD1_MATRIX_OFFSET2; |
| matrix_pre_offset0_1 = VPP_VD1_MATRIX_PRE_OFFSET0_1; |
| matrix_pre_offset2 = VPP_VD1_MATRIX_PRE_OFFSET2; |
| matrix_en_ctrl = VPP_VD1_MATRIX_EN_CTRL; |
| break; |
| case POST2_MTX: |
| matrix_coef00_01 = VPP_POST2_MATRIX_COEF00_01; |
| matrix_coef02_10 = VPP_POST2_MATRIX_COEF02_10; |
| matrix_coef11_12 = VPP_POST2_MATRIX_COEF11_12; |
| matrix_coef20_21 = VPP_POST2_MATRIX_COEF20_21; |
| matrix_coef22 = VPP_POST2_MATRIX_COEF22; |
| matrix_clip = VPP_POST2_MATRIX_CLIP; |
| matrix_offset0_1 = VPP_POST2_MATRIX_OFFSET0_1; |
| matrix_offset2 = VPP_POST2_MATRIX_OFFSET2; |
| matrix_pre_offset0_1 = VPP_POST2_MATRIX_PRE_OFFSET0_1; |
| matrix_pre_offset2 = VPP_POST2_MATRIX_PRE_OFFSET2; |
| matrix_en_ctrl = VPP_POST2_MATRIX_EN_CTRL; |
| break; |
| case POST_MTX: |
| matrix_coef00_01 = VPP_POST_MATRIX_COEF00_01; |
| matrix_coef02_10 = VPP_POST_MATRIX_COEF02_10; |
| matrix_coef11_12 = VPP_POST_MATRIX_COEF11_12; |
| matrix_coef20_21 = VPP_POST_MATRIX_COEF20_21; |
| matrix_coef22 = VPP_POST_MATRIX_COEF22; |
| matrix_clip = VPP_POST_MATRIX_CLIP; |
| matrix_offset0_1 = VPP_POST_MATRIX_OFFSET0_1; |
| matrix_offset2 = VPP_POST_MATRIX_OFFSET2; |
| matrix_pre_offset0_1 = VPP_POST_MATRIX_PRE_OFFSET0_1; |
| matrix_pre_offset2 = VPP_POST_MATRIX_PRE_OFFSET2; |
| matrix_en_ctrl = VPP_POST_MATRIX_EN_CTRL; |
| break; |
| case VPP1_POST2_MTX: |
| matrix_coef00_01 = VPP1_POST2_MATRIX_COEF00_01; |
| matrix_coef02_10 = VPP1_POST2_MATRIX_COEF02_10; |
| matrix_coef11_12 = VPP1_POST2_MATRIX_COEF11_12; |
| matrix_coef20_21 = VPP1_POST2_MATRIX_COEF20_21; |
| matrix_coef22 = VPP1_POST2_MATRIX_COEF22; |
| matrix_clip = VPP1_POST2_MATRIX_CLIP; |
| matrix_offset0_1 = VPP1_POST2_MATRIX_OFFSET0_1; |
| matrix_offset2 = VPP1_POST2_MATRIX_OFFSET2; |
| matrix_pre_offset0_1 = VPP1_POST2_MATRIX_PRE_OFFSET0_1; |
| matrix_pre_offset2 = VPP1_POST2_MATRIX_PRE_OFFSET2; |
| matrix_en_ctrl = VPP1_POST2_MATRIX_EN_CTRL; |
| break; |
| case VPP2_POST2_MTX: |
| matrix_coef00_01 = VPP2_POST2_MATRIX_COEF00_01; |
| matrix_coef02_10 = VPP2_POST2_MATRIX_COEF02_10; |
| matrix_coef11_12 = VPP2_POST2_MATRIX_COEF11_12; |
| matrix_coef20_21 = VPP2_POST2_MATRIX_COEF20_21; |
| matrix_coef22 = VPP2_POST2_MATRIX_COEF22; |
| matrix_clip = VPP2_POST2_MATRIX_CLIP; |
| matrix_offset0_1 = VPP2_POST2_MATRIX_OFFSET0_1; |
| matrix_offset2 = VPP2_POST2_MATRIX_OFFSET2; |
| matrix_pre_offset0_1 = VPP2_POST2_MATRIX_PRE_OFFSET0_1; |
| matrix_pre_offset2 = VPP2_POST2_MATRIX_PRE_OFFSET2; |
| matrix_en_ctrl = VPP2_POST2_MATRIX_EN_CTRL; |
| break; |
| |
| case MTX_NULL: |
| default: |
| break; |
| } |
| |
| if (!mtx_sel) { |
| vecm_latch_flag2 &= ~VPP_MARTIX_UPDATE; |
| vecm_latch_flag2 &= ~VPP_MARTIX_GET; |
| return 0; |
| } |
| |
| if (vecm_latch_flag2 & VPP_MARTIX_UPDATE) { |
| pre_offset0_1 = |
| (mtx_info->mtx_coef.pre_offset[0] << 16) | |
| mtx_info->mtx_coef.pre_offset[1]; |
| pre_offset2 = mtx_info->mtx_coef.pre_offset[2]; |
| |
| coef00_01 = |
| (mtx_info->mtx_coef.matrix_coef[0][0] << 16) | |
| mtx_info->mtx_coef.matrix_coef[0][1]; |
| coef02_10 = |
| (mtx_info->mtx_coef.matrix_coef[0][2] << 16) | |
| mtx_info->mtx_coef.matrix_coef[1][0]; |
| coef11_12 = |
| (mtx_info->mtx_coef.matrix_coef[1][1] << 16) | |
| mtx_info->mtx_coef.matrix_coef[1][2]; |
| coef20_21 = |
| (mtx_info->mtx_coef.matrix_coef[2][0] << 16) | |
| mtx_info->mtx_coef.matrix_coef[2][1]; |
| coef22 = mtx_info->mtx_coef.matrix_coef[2][2]; |
| |
| offset0_1 = |
| (mtx_info->mtx_coef.post_offset[0] << 16) | |
| mtx_info->mtx_coef.post_offset[1]; |
| offset2 = mtx_info->mtx_coef.post_offset[2]; |
| |
| en = mtx_info->mtx_coef.en; |
| clip = mtx_info->mtx_coef.right_shift; |
| |
| VSYNC_WRITE_VPP_REG(matrix_coef00_01, coef00_01); |
| VSYNC_WRITE_VPP_REG(matrix_coef02_10, coef02_10); |
| VSYNC_WRITE_VPP_REG(matrix_coef11_12, coef11_12); |
| VSYNC_WRITE_VPP_REG(matrix_coef20_21, coef20_21); |
| VSYNC_WRITE_VPP_REG(matrix_coef22, coef22); |
| VSYNC_WRITE_VPP_REG(matrix_offset0_1, offset0_1); |
| VSYNC_WRITE_VPP_REG(matrix_offset2, offset2); |
| VSYNC_WRITE_VPP_REG(matrix_pre_offset0_1, pre_offset0_1); |
| VSYNC_WRITE_VPP_REG(matrix_pre_offset2, pre_offset2); |
| VSYNC_WRITE_VPP_REG_BITS(matrix_en_ctrl, en, 0, 1); |
| VSYNC_WRITE_VPP_REG_BITS(matrix_clip, clip, 5, 3); |
| vecm_latch_flag2 &= ~VPP_MARTIX_UPDATE; |
| } |
| |
| if (vecm_latch_flag2 & VPP_MARTIX_GET) { |
| coef00_01 = READ_VPP_REG(matrix_coef00_01); |
| coef02_10 = READ_VPP_REG(matrix_coef02_10); |
| coef11_12 = READ_VPP_REG(matrix_coef11_12); |
| coef20_21 = READ_VPP_REG(matrix_coef20_21); |
| coef22 = READ_VPP_REG(matrix_coef22); |
| pre_offset0_1 = READ_VPP_REG(matrix_pre_offset0_1); |
| pre_offset2 = READ_VPP_REG(matrix_pre_offset2); |
| offset0_1 = READ_VPP_REG(matrix_offset0_1); |
| offset2 = READ_VPP_REG(matrix_offset2); |
| en = READ_VPP_REG_BITS(matrix_en_ctrl, 0, 1); |
| clip = READ_VPP_REG_BITS(matrix_clip, 5, 3); |
| mtx_info->mtx_coef.pre_offset[0] = |
| (u16)((pre_offset0_1 >> 16) & 0xffff); |
| mtx_info->mtx_coef.pre_offset[1] = |
| (u16)(pre_offset0_1 & 0xffff); |
| mtx_info->mtx_coef.pre_offset[2] = (u16)(pre_offset2 & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[0][0] = |
| (u16)((coef00_01 >> 16) & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[0][1] = |
| (u16)(coef00_01 & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[0][2] = |
| (u16)((coef02_10 >> 16) & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[1][0] = |
| (u16)(coef02_10 & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[1][1] = |
| (u16)((coef11_12 >> 16) & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[1][2] = |
| (u16)(coef11_12 & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[2][0] = |
| (u16)((coef20_21 >> 16) & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[2][1] = |
| (u16)(coef20_21 & 0xffff); |
| mtx_info->mtx_coef.matrix_coef[2][2] = |
| (u16)(coef22 & 0xffff); |
| mtx_info->mtx_coef.post_offset[0] = |
| (u16)((offset0_1 >> 16) & 0xffff); |
| mtx_info->mtx_coef.post_offset[1] = |
| (u16)(offset0_1 & 0xffff); |
| mtx_info->mtx_coef.post_offset[2] = |
| (u16)(offset2 & 0xffff); |
| mtx_info->mtx_coef.en = en; |
| mtx_info->mtx_coef.right_shift = clip; |
| vecm_latch_flag2 &= ~VPP_MARTIX_GET; |
| } |
| |
| return 0; |
| } |
| |
| void pre_gma_update(struct pre_gamma_table_s *pre_gma_lut) |
| { |
| if (vecm_latch_flag2 & VPP_PRE_GAMMA_UPDATE) { |
| set_pre_gamma_reg(pre_gma_lut); |
| vecm_latch_flag2 &= ~VPP_PRE_GAMMA_UPDATE; |
| } |
| } |
| |
| void eye_prot_update(struct eye_protect_s *eye_prot) |
| { |
| if (vecm_latch_flag2 & VPP_EYE_PROTECT_UPDATE) { |
| eye_proc(eye_prot->rgb, eye_prot->en); |
| vecm_latch_flag2 &= ~VPP_EYE_PROTECT_UPDATE; |
| } |
| } |
| |
| void amvecm_saturation_hue_update(int offset_val) |
| { |
| sat_hue_offset_val = offset_val; |
| pq_user_latch_flag |= PQ_USER_CMS_SAT_HUE; |
| if (debug_amvecm & 8) |
| pr_info("[amvecm..] %s: saturation_hue:%d offset=%d\n", |
| __func__, |
| vdj_mode_s.saturation_hue, |
| sat_hue_offset_val); |
| } |
| |
| void amvecm_video_latch(void) |
| { |
| unsigned int temp; |
| pc_mode_process(); |
| cm_latch_process(); |
| /*amvecm_size_patch();*/ |
| ve_dnlp_latch_process(); |
| /*venc*/ |
| if (cpu_after_eq_t7()) |
| temp = vpp_get_vout_viu_mux(); |
| else |
| temp = vpp_get_encl_viu_mux(); |
| if (temp) |
| ve_lcd_gamma_process(); |
| lvds_freq_process(); |
| /* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESONG9TV) */ |
| if (0) { |
| amvecm_3d_sync_process(); |
| amvecm_3d_black_process(); |
| } |
| /* #endif */ |
| pq_user_latch_process(); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) |
| ve_lc_latch_process(); |
| |
| /* ioc vadj1/2 switch */ |
| amvecm_vadj_latch_process(); |
| /*matrix wr & rd latch */ |
| vpp_mtx_update(&mtx_info); |
| pre_gma_update(&pre_gamma); |
| eye_prot_update(&eye_protect); |
| } |
| |
| static void amvecm_overscan_process(struct vframe_s *vf, |
| struct vframe_s *toggle_vf, |
| int flags, |
| enum vd_path_e vd_path) |
| { |
| if (vd_path != VD1_PATH) |
| return; |
| if (flags & CSC_FLAG_CHECK_OUTPUT) { |
| if (toggle_vf) |
| amvecm_fresh_overscan(toggle_vf); |
| else if (vf) |
| amvecm_fresh_overscan(vf); |
| return; |
| } |
| if (!toggle_vf && !vf) |
| amvecm_reset_overscan(); |
| |
| if (vf) |
| amvecm_fresh_overscan(vf); |
| else |
| amvecm_reset_overscan(); |
| } |
| |
| static int cabc_add_hist_proc(struct vframe_s *vf) |
| { |
| int *hist; |
| int i; |
| |
| hist = vf_hist_get(); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7)) { |
| vpp_pst_hist_sta_read(hist); |
| return 1; |
| } |
| |
| if (vf) { |
| for (i = 0; i < 64; i++) |
| hist[i] = vf->prop.hist.vpp_gamma[i]; |
| } else { |
| /*default 1080p linear hist*/ |
| for (i = 0; i < 64; i++) |
| hist[i] = 1012; |
| } |
| |
| return 1; |
| } |
| |
| static int cabc_aad_on_vs(int vf_state) |
| { |
| int cabc_en; |
| |
| cabc_en = fw_en_get(); |
| |
| if (!vf_state) |
| return 0; |
| |
| if (cabc_en) |
| queue_work(aml_cabc_queue, &cabc_proc_work); |
| else |
| queue_work(aml_cabc_queue, &cabc_bypass_work); |
| |
| return 0; |
| } |
| |
| #ifdef T7_BRINGUP_MULTI_VPP |
| int min_vpp_process(int vpp_top_index, enum vpp_index vpp_index) |
| { |
| int result = 0; |
| //write csc and gain/offset for vpp1/2 here |
| // update hdr matrix |
| result = amvecm_matrix_process(toggle_vf, vf, flags, vd_path, vpp_index); |
| // to do |
| |
| return result |
| } |
| #endif |
| |
| int amvecm_on_vs(struct vframe_s *vf, |
| struct vframe_s *toggle_vf, |
| int flags, |
| unsigned int sps_h_en, |
| unsigned int sps_v_en, |
| unsigned int sps_w_in, |
| unsigned int sps_h_in, |
| unsigned int cm_in_w, |
| unsigned int cm_in_h, |
| enum vd_path_e vd_path, |
| enum vpp_index vpp_index) |
| { |
| int result = 0; |
| int vf_state = 0; |
| #ifdef T7_BRINGUP_MULTI_VPP |
| // to do, t7 vecm bringup, |
| int vpp_top_index = 0; |
| // temp flag, should update it from video display module in future |
| // assuming here that post process only be used for vd1 input of vpp top0 |
| // and there is no post process for vpp top 1/2 |
| #endif |
| if (probe_ok == 0) |
| return 0; |
| |
| if (vd_path == VD1_PATH) |
| set_vpp_enh_clk(toggle_vf, vf); |
| |
| #ifdef T7_BRINGUP_MULTI_VPP |
| // todo, will not support in pxp bringup stage |
| if (get_cpu_type() == MESON_CPU_MAJOR_ID_T7 && |
| vpp_top_index != 0) { |
| // for t7 case, for min vpp 1 & 2 |
| // keep the legacy driver for vd1 not changed for back compatible |
| //and try to minimum the changes and add independent handler for min vpp newly added |
| result = min_vpp_process(vpp_top_index, vpp_index); |
| return result; |
| } |
| #endif |
| amvecm_overscan_process(vf, toggle_vf, flags, vd_path); |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (for_dolby_vision_certification() && vd_path == VD1_PATH) |
| return 0; |
| #endif |
| if (!dnlp_insmod_ok && vd_path == VD1_PATH) |
| dnlp_alg_param_init(); |
| |
| if (flags & CSC_FLAG_CHECK_OUTPUT) { |
| /* to test if output will change */ |
| return amvecm_matrix_process(toggle_vf, vf, flags, vd_path, vpp_index); |
| } else if (vd_path == VD1_PATH) { |
| send_hdr10_plus_pkt(vd_path, vpp_index); |
| } |
| if ((toggle_vf) || (vf)) { |
| /* matrix adjust */ |
| result = amvecm_matrix_process(toggle_vf, vf, flags, vd_path, vpp_index); |
| if (toggle_vf) { |
| ioctrl_get_hdr_metadata(toggle_vf); |
| vf_state = cabc_add_hist_proc(toggle_vf); |
| } |
| |
| if (toggle_vf && vd_path == VD1_PATH) { |
| lc_process(toggle_vf, sps_h_en, sps_v_en, |
| sps_w_in, sps_h_in); |
| amvecm_size_patch(cm_in_w, cm_in_h); |
| /*1080i pulldown combing workaround*/ |
| amvecm_dejaggy_patch(toggle_vf); |
| if ((get_cpu_type() == MESON_CPU_MAJOR_ID_T3) || |
| (get_cpu_type() == MESON_CPU_MAJOR_ID_T5W)) { |
| /*frequence meter size config*/ |
| amve_fmetersize_config(vf->width, vf->height, |
| sps_w_in, sps_h_in); |
| amvecm_fmeter_process(toggle_vf); |
| } |
| } |
| /*refresh vframe*/ |
| if (!toggle_vf && vf) { |
| if (vd_path == VD1_PATH) { |
| lc_process(vf, sps_h_en, sps_v_en, |
| sps_w_in, sps_h_in); |
| vf_state = cabc_add_hist_proc(vf); |
| } |
| } |
| |
| } else { |
| result = amvecm_matrix_process(NULL, NULL, flags, vd_path, vpp_index); |
| if (vd_path == VD1_PATH) { |
| lc_process(NULL, sps_h_en, sps_v_en, |
| sps_w_in, sps_h_in); |
| /*1080i pulldown combing workaround*/ |
| amvecm_dejaggy_patch(NULL); |
| } |
| vf_state = cabc_add_hist_proc(NULL); |
| } |
| |
| if (vd_path != VD1_PATH) |
| return result; |
| |
| /* add some flag to trigger */ |
| if (vf) { |
| /*gxlx sharpness adaptive setting*/ |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| if (is_meson_gxlx_cpu()) |
| amve_sharpness_adaptive_setting(vf, |
| sps_h_en, sps_v_en); |
| #endif |
| amvecm_bricon_process(vd1_brightness, |
| vd1_contrast + vd1_contrast_offset, vf); |
| |
| amvecm_color_process(saturation_pre + saturation_offset, |
| hue_pre, vf); |
| |
| vpp_demo_config(vf); |
| } |
| |
| /* pq latch process */ |
| amvecm_video_latch(); |
| /*wq for cacb and aad*/ |
| cabc_aad_on_vs(vf_state); |
| return result; |
| } |
| EXPORT_SYMBOL(amvecm_on_vs); |
| |
| void refresh_on_vs(struct vframe_s *vf, struct vframe_s *rpt_vf) |
| { |
| if (probe_ok == 0) |
| return; |
| |
| #ifdef T7_BRINGUP_MULTI_VPP |
| if (get_cpu_type() == MESON_CPU_MAJOR_ID_T7 && |
| vpp_top_index != 0) { |
| return 0; |
| } |
| #endif |
| |
| if (vf || rpt_vf) { |
| vpp_get_vframe_hist_info(vf ? vf : rpt_vf); |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (!for_dolby_vision_certification()) |
| #endif |
| ve_on_vs(vf ? vf : rpt_vf); |
| if (vf && is_video_layer_on(VD1_PATH)) { |
| ve_hist_gamma_tgt(vf); |
| vpp_backup_histgram(vf); |
| } |
| pattern_detect(vf ? vf : rpt_vf); |
| } else { |
| ve_hist_gamma_reset(); |
| } |
| } |
| EXPORT_SYMBOL(refresh_on_vs); |
| |
| static irqreturn_t amvecm_viu2_vsync_isr(int irq, void *dev_id) |
| { |
| if (vpp_get_encl_viu_mux() == 2) |
| ve_lcd_gamma_process(); |
| return IRQ_HANDLED; |
| } |
| |
| static irqreturn_t amvecm_lc_curve_isr(int irq, void *dev_id) |
| { |
| if (use_lc_curve_isr) |
| lc_read_region(8, 12); |
| return IRQ_HANDLED; |
| } |
| |
| static int amvecm_open(struct inode *inode, struct file *file) |
| { |
| struct amvecm_dev_s *devp; |
| /* Get the per-device structure that contains this cdev */ |
| devp = container_of(inode->i_cdev, struct amvecm_dev_s, cdev); |
| file->private_data = devp; |
| /*init queue*/ |
| init_waitqueue_head(&devp->hdr_queue); |
| return 0; |
| } |
| |
| static int amvecm_release(struct inode *inode, struct file *file) |
| { |
| file->private_data = NULL; |
| return 0; |
| } |
| |
| static struct am_regs_s amregs_ext; |
| struct ve_pq_overscan_s overscan_table[TIMING_MAX]; |
| |
| static int parse_para_pq(const char *para, int para_num, int *result) |
| { |
| char *token = NULL; |
| char *params, *params_base; |
| int *out = result; |
| int len = 0, count = 0; |
| int res = 0; |
| |
| if (!para) |
| return 0; |
| |
| params = kstrdup(para, GFP_KERNEL); |
| if (!params) |
| return -ENOMEM; |
| params_base = params; |
| token = params; |
| len = strlen(token); |
| do { |
| token = strsep(¶ms, " "); |
| while (token && (isspace(*token) || |
| !isgraph(*token)) && len) { |
| token++; |
| len--; |
| } |
| if (len == 0) |
| break; |
| if (!token || kstrtoint(token, 0, &res) < 0) |
| break; |
| len = strlen(token); |
| *out++ = res; |
| count++; |
| } while ((token) && (count < para_num) && (len > 0)); |
| |
| kfree(params_base); |
| return count; |
| } |
| |
| int amvecm_set_saturation_hue(int mab) |
| { |
| s16 mc = 0, md = 0; |
| s16 ma, mb; |
| |
| if (mab & 0xfc00fc00) |
| return -EINVAL; |
| ma = (s16)((mab << 6) >> 22); |
| mb = (s16)((mab << 22) >> 22); |
| |
| saturation_ma = ma - 0x100; |
| saturation_mb = mb; |
| |
| ma += saturation_ma_shift; |
| mb += saturation_mb_shift; |
| if (ma > 511) |
| ma = 511; |
| if (ma < -512) |
| ma = -512; |
| if (mb > 511) |
| mb = 511; |
| if (mb < -512) |
| mb = -512; |
| mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff); |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG(VPP_VADJ1_MA_MB_2, mab); |
| else |
| WRITE_VPP_REG(VPP_VADJ1_MA_MB, mab); |
| |
| mc = (s16)((mab << 22) >> 22); /* mc = -mb */ |
| mc = 0 - mc; |
| if (mc > 511) |
| mc = 511; |
| if (mc < -512) |
| mc = -512; |
| md = (s16)((mab << 6) >> 22); /* md = ma; */ |
| mab = ((mc & 0x3ff) << 16) | (md & 0x3ff); |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| WRITE_VPP_REG(VPP_VADJ1_MC_MD_2, mab); |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1); |
| } else { |
| WRITE_VPP_REG(VPP_VADJ1_MC_MD, mab); |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1); |
| } |
| pr_amvecm_dbg("%s set video_saturation_hue OK!!!\n", __func__); |
| return 0; |
| } |
| |
| static int amvecm_set_saturation_hue_post(int val1, |
| int val2) |
| { |
| int i, ma, mb, mab, mc, md; |
| int hue_cos_len, hue_sin_len; |
| int hue_cos[] = { |
| /*0~12*/ |
| 256, 256, 256, 255, 255, 254, 253, 252, 251, 250, |
| 248, 247, 245, 243, 241, 239, 237, 234, 231, 229, |
| 226, 223, 220, 216, 213, 209 /*13~25*/ |
| }; |
| int hue_sin[] = { |
| -147, -142, -137, -132, -126, -121, -115, -109, -104, |
| -98, -92, -86, -80, /*-25~-13*/-74, -68, -62, -56, |
| -50, -44, -38, -31, -25, -19, -13, -6, /*-12~-1*/ |
| 0, /*0*/ |
| 6, 13, 19, 25, 31, 38, 44, 50, 56, |
| 62, 68, 74, /*1~12*/ 80, 86, 92, 98, 104, |
| 109, 115, 121, 126, 132, 137, 142, 147 /*13~25*/ |
| }; |
| hue_cos_len = sizeof(hue_cos) / sizeof(int); |
| hue_sin_len = sizeof(hue_sin) / sizeof(int); |
| i = (val2 > 0) ? val2 : -val2; |
| if (val1 < -128 || val1 > 128 || |
| val2 < -25 || val2 > 25 || |
| i >= hue_cos_len || |
| (val2 >= (hue_sin_len - 25))) |
| return -EINVAL; |
| saturation_post = val1; |
| hue_post = val2; |
| ma = (hue_cos[i] * (saturation_post + 128)) >> 7; |
| mb = (hue_sin[25 + hue_post] * (saturation_post + 128)) >> 7; |
| if (ma > 511) |
| ma = 511; |
| if (ma < -512) |
| ma = -512; |
| if (mb > 511) |
| mb = 511; |
| if (mb < -512) |
| mb = -512; |
| mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff); |
| pr_info("\n[amvideo..] saturation_post:%d hue_post:%d mab:%x\n", |
| saturation_post, hue_post, mab); |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG(VPP_VADJ2_MA_MB_2, mab); |
| else |
| WRITE_VPP_REG(VPP_VADJ2_MA_MB, mab); |
| mc = (s16)((mab << 22) >> 22); /* mc = -mb */ |
| mc = 0 - mc; |
| if (mc > 511) |
| mc = 511; |
| if (mc < -512) |
| mc = -512; |
| md = (s16)((mab << 6) >> 22); /* md = ma; */ |
| mab = ((mc & 0x3ff) << 16) | (md & 0x3ff); |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| WRITE_VPP_REG(VPP_VADJ2_MC_MD_2, mab); |
| WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, 1, 0, 1); |
| } else { |
| WRITE_VPP_REG(VPP_VADJ2_MC_MD, mab); |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 2, 1); |
| } |
| return 0; |
| } |
| |
| static int gamma_table_compare(struct tcon_gamma_table_s *table1, |
| struct tcon_gamma_table_s *table2) |
| { |
| int i = 0, flag = 0; |
| |
| for (i = 0; i < 256; i++) |
| if (table1->data[i] != table2->data[i]) { |
| flag = 1; |
| break; |
| } |
| |
| return flag; |
| } |
| |
| static void parse_overscan_table(unsigned int length, |
| struct ve_pq_table_s *amvecm_pq_load_table) |
| { |
| unsigned int i; |
| unsigned int offset = TIMING_UHD + 1; |
| |
| memset(overscan_table, 0, sizeof(overscan_table)); |
| for (i = 0; i < length; i++) { |
| overscan_table[i].load_flag = |
| (amvecm_pq_load_table[i].src_timing >> 31) & 0x1; |
| overscan_table[i].afd_enable = |
| (amvecm_pq_load_table[i].src_timing >> 30) & 0x1; |
| overscan_table[i].screen_mode = |
| (amvecm_pq_load_table[i].src_timing >> 24) & 0x3f; |
| overscan_table[i].source = |
| (amvecm_pq_load_table[i].src_timing >> 16) & 0xff; |
| overscan_table[i].timing = |
| amvecm_pq_load_table[i].src_timing & 0xffff; |
| overscan_table[i].hs = |
| amvecm_pq_load_table[i].value1 & 0xffff; |
| overscan_table[i].he = |
| (amvecm_pq_load_table[i].value1 >> 16) & 0xffff; |
| overscan_table[i].vs = |
| amvecm_pq_load_table[i].value2 & 0xffff; |
| overscan_table[i].ve = |
| (amvecm_pq_load_table[i].value2 >> 16) & 0xffff; |
| } |
| if (!overscan_table[0].load_flag) |
| pq_user_latch_flag |= PQ_USER_OVERSCAN_RESET; |
| /*because SOURCE_TV is 0,so need to add a flg to check ATV*/ |
| if (overscan_table[offset].load_flag == 1 && |
| overscan_table[offset].source == SOURCE_TV) |
| atv_source_flg = 1; |
| else |
| atv_source_flg = 0; |
| } |
| |
| static void hdr_tone_mapping_get(enum lut_type_e lut_type, |
| unsigned int length, |
| unsigned int *hdr_tm) |
| { |
| int i; |
| |
| if (hdr_tm) { |
| if (lut_type & HLG_LUT) { |
| for (i = 0; i < length; i++) |
| oo_y_lut_hlg_sdr[i] = hdr_tm[i]; |
| |
| if (debug_amvecm & 4) { |
| for (i = 0; i < length; i++) { |
| pr_info("oo_y_lut_hlg_sdr[%d] = %d", |
| i, oo_y_lut_hlg_sdr[i]); |
| if (i % 8 == 0) |
| pr_info("\n"); |
| } |
| pr_info("\n"); |
| } |
| } else if (lut_type & HDR_LUT) { |
| for (i = 0; i < length; i++) |
| oo_y_lut_hdr_sdr_def[i] = hdr_tm[i]; |
| |
| vecm_latch_flag |= FLAG_HDR_OOTF_LATCH; |
| |
| if (debug_amvecm & 4) { |
| for (i = 0; i < length; i++) { |
| pr_info("oo_y_lut_hdr_sdr[%d] = %d", |
| i, oo_y_lut_hdr_sdr_def[i]); |
| if (i % 8 == 0) |
| pr_info("\n"); |
| } |
| pr_info("\n"); |
| } |
| } |
| } |
| } |
| |
| static int parse_aipq_ofst_table(int *table_ptr, |
| unsigned int height, unsigned int width) |
| { |
| unsigned int i; |
| unsigned int size = 0; |
| |
| size = width * sizeof(int); |
| for (i = 0; i < height; i++) |
| memcpy(vpp_pq_data[i], table_ptr + (i * width), size); |
| |
| return 0; |
| } |
| |
| static long amvecm_ioctl(struct file *file, |
| unsigned int cmd, unsigned long arg) |
| { |
| int ret = 0; |
| void __user *argp; |
| unsigned int mem_size; |
| struct ve_pq_load_s vpp_pq_load; |
| struct ve_pq_table_s *vpp_pq_load_table = NULL; |
| enum color_primary_e color_pri; |
| struct hdr_tone_mapping_s hdr_tone_mapping; |
| unsigned int *hdr_tm = NULL; |
| struct vpp_pq_ctrl_s pq_ctrl; |
| enum meson_cpu_ver_e cpu_ver; |
| struct aipq_load_s aipq_load_table; |
| char *aipq_char_data_ptr = NULL; |
| int *aipq_int_data_ptr = NULL; |
| int size, size1; |
| int aipq_data_length; |
| struct cm_color_md cm_color_mode; |
| struct table_3dlut_s *p3dlut; |
| int lut_order, lut_index; |
| struct vpp_mtx_info_s *mtx_p = &mtx_info; |
| struct pre_gamma_table_s *pre_gma_tb = NULL; |
| struct hdr_tmo_sw pre_tmo_reg; |
| struct db_cabc_param_s db_cabc_param; |
| struct db_aad_param_s db_aad_param; |
| struct eye_protect_s *eye_prot = NULL; |
| int tmp; |
| struct primary_s color_pr; |
| int cm_color = 0; |
| |
| if (debug_amvecm & 2) |
| pr_info("[amvecm..] %s: cmd_nr = 0x%x\n", |
| __func__, _IOC_NR(cmd)); |
| |
| if (probe_ok == 0) |
| return ret; |
| |
| if (pq_load_en == 0) { |
| pr_amvecm_dbg("[amvecm..] pq ioctl function disabled !!\n"); |
| return ret; |
| } |
| |
| switch (cmd) { |
| case AMVECM_IOC_LOAD_REG: |
| if ((vecm_latch_flag & FLAG_REG_MAP0) && |
| (vecm_latch_flag & FLAG_REG_MAP1) && |
| (vecm_latch_flag & FLAG_REG_MAP2) && |
| (vecm_latch_flag & FLAG_REG_MAP3) && |
| (vecm_latch_flag & FLAG_REG_MAP4) && |
| (vecm_latch_flag & FLAG_REG_MAP5)) { |
| ret = -EBUSY; |
| pr_amvecm_dbg("load regs error: loading regs, please wait\n"); |
| break; |
| } |
| if (copy_from_user(&amregs_ext, |
| (void __user *)arg, |
| sizeof(struct am_regs_s))) { |
| pr_amvecm_dbg("0x%lx load reg errors: can't get buffer length\n", |
| FLAG_REG_MAP0); |
| ret = -EFAULT; |
| } else { |
| ret = cm_load_reg(&amregs_ext); |
| } |
| break; |
| case AMVECM_IOC_VE_NEW_DNLP: |
| if (copy_from_user(&dnlp_curve_param_load, |
| (void __user *)arg, |
| sizeof(struct ve_dnlp_curve_param_s))) { |
| pr_amvecm_dbg("dnlp load fail\n"); |
| ret = -EFAULT; |
| } else { |
| ve_new_dnlp_param_update(); |
| pr_amvecm_dbg("dnlp load success\n"); |
| } |
| break; |
| case AMVECM_IOC_G_HIST_AVG: |
| argp = (void __user *)arg; |
| if (video_ve_hist.height == 0 || video_ve_hist.width == 0) |
| ret = -EFAULT; |
| else if (copy_to_user(argp, |
| &video_ve_hist, |
| sizeof(struct ve_hist_s))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_G_HIST_BIN: |
| argp = (void __user *)arg; |
| if (vpp_hist_param.vpp_pixel_sum == 0) |
| ret = -EFAULT; |
| else if (copy_to_user(argp, &vpp_hist_param, |
| sizeof(struct vpp_hist_param_s))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_G_HDR_METADATA: |
| argp = (void __user *)arg; |
| if (copy_to_user(argp, &vpp_hdr_metadata_s, |
| sizeof(struct hdr_metadata_info_s))) |
| ret = -EFAULT; |
| break; |
| /**********************************************************************/ |
| /*gamma ioctl*/ |
| /**********************************************************************/ |
| case AMVECM_IOC_GAMMA_TABLE_EN: |
| if (!gamma_en) |
| return -EINVAL; |
| |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_EN; |
| break; |
| case AMVECM_IOC_GAMMA_TABLE_DIS: |
| if (!gamma_en) |
| return -EINVAL; |
| |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS; |
| break; |
| case AMVECM_IOC_GAMMA_TABLE_R: |
| if (!gamma_en) |
| return -EINVAL; |
| |
| if (copy_from_user(&video_gamma_table_ioctl_set, |
| (void __user *)arg, |
| sizeof(struct tcon_gamma_table_s))) { |
| ret = -EFAULT; |
| } else if (gamma_table_compare(&video_gamma_table_ioctl_set, |
| &video_gamma_table_r)) { |
| memcpy(&video_gamma_table_r, |
| &video_gamma_table_ioctl_set, |
| sizeof(struct tcon_gamma_table_s)); |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_R; |
| } else { |
| pr_amvecm_dbg("load same gamma_r table,no need to change\n"); |
| } |
| break; |
| case AMVECM_IOC_GAMMA_TABLE_G: |
| if (!gamma_en) |
| return -EINVAL; |
| |
| if (copy_from_user(&video_gamma_table_ioctl_set, |
| (void __user *)arg, |
| sizeof(struct tcon_gamma_table_s))) { |
| ret = -EFAULT; |
| } else if (gamma_table_compare(&video_gamma_table_ioctl_set, |
| &video_gamma_table_g)) { |
| memcpy(&video_gamma_table_g, |
| &video_gamma_table_ioctl_set, |
| sizeof(struct tcon_gamma_table_s)); |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_G; |
| } else { |
| pr_amvecm_dbg("load same gamma_g table,no need to change\n"); |
| } |
| break; |
| case AMVECM_IOC_GAMMA_TABLE_B: |
| if (!gamma_en) |
| return -EINVAL; |
| |
| if (copy_from_user(&video_gamma_table_ioctl_set, |
| (void __user *)arg, |
| sizeof(struct tcon_gamma_table_s))) { |
| ret = -EFAULT; |
| } else if (gamma_table_compare(&video_gamma_table_ioctl_set, |
| &video_gamma_table_b)) { |
| memcpy(&video_gamma_table_b, |
| &video_gamma_table_ioctl_set, |
| sizeof(struct tcon_gamma_table_s)); |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_B; |
| } else { |
| pr_amvecm_dbg("load same gamma_b table,no need to change\n"); |
| } |
| break; |
| case AMVECM_IOC_S_RGB_OGO: |
| if (!wb_en) |
| return -EINVAL; |
| |
| if (copy_from_user(&video_rgb_ogo, |
| (void __user *)arg, |
| sizeof(struct tcon_rgb_ogo_s))) |
| ret = -EFAULT; |
| else |
| ve_ogo_param_update(); |
| break; |
| case AMVECM_IOC_G_RGB_OGO: |
| if (!wb_en) |
| return -EINVAL; |
| |
| if (copy_to_user((void __user *)arg, |
| &video_rgb_ogo, sizeof(struct tcon_rgb_ogo_s))) |
| ret = -EFAULT; |
| |
| break; |
| case AMVECM_IOC_SET_3D_LUT: |
| p3dlut = kmalloc(4913 * 3 * sizeof(unsigned int), |
| GFP_KERNEL); |
| if (!p3dlut) |
| return -ENOMEM; |
| |
| if (copy_from_user(p3dlut, |
| (void __user *)arg, |
| 4913 * 3 * sizeof(unsigned int))) { |
| ret = -EFAULT; |
| } else { |
| vpp_lut3d_table_init(0, 0, 0); |
| vpp_set_lut3d(0, 0, p3dlut->data, 0); |
| vpp_lut3d_table_release(); |
| } |
| |
| kfree(p3dlut); |
| break; |
| case AMVECM_IOC_LOAD_3D_LUT: |
| if (copy_from_user(&lut_index, |
| (void __user *)arg, |
| sizeof(int))) { |
| ret = -EFAULT; |
| break; |
| } |
| |
| vpp_lut3d_table_init(0, 0, 0); |
| vpp_set_lut3d(lut3d_data_source, lut_index, 0, 0); |
| vpp_lut3d_table_release(); |
| |
| break; |
| case AMVECM_IOC_SET_3D_LUT_ORDER: |
| if (copy_from_user(&lut_order, |
| (void __user *)arg, |
| sizeof(int))) { |
| ret = -EFAULT; |
| } else { |
| lut3d_order = lut_order; |
| } |
| |
| break; |
| case AMVECM_IOC_3D_LUT_EN: |
| if (copy_from_user(&tmp, |
| (void __user *)arg, |
| sizeof(int))) { |
| ret = -EFAULT; |
| } else { |
| lut3d_en = tmp; |
| lut3d_en &= 0x1; |
| vpp_enable_lut3d(lut3d_en); |
| } |
| break; |
| case AMVECM_IOC_COLOR_PRI_EN: |
| if (copy_from_user(&tmp, |
| (void __user *)arg, |
| sizeof(int))) { |
| ret = -EFAULT; |
| } else { |
| force_primary = tmp; |
| vecm_latch_flag |= FLAG_COLORPRI_LATCH; |
| force_toggle(); |
| } |
| break; |
| case AMVECM_IOC_COLOR_PRIMARY: |
| if (copy_from_user(&color_pr, |
| (void __user *)arg, |
| sizeof(struct primary_s))) { |
| ret = -EFAULT; |
| } else { |
| memcpy(force_src_primary, color_pr.src, |
| 8 * sizeof(u32)); |
| memcpy(force_dst_primary, color_pr.dest, |
| 8 * sizeof(u32)); |
| vecm_latch_flag |= FLAG_COLORPRI_LATCH; |
| force_toggle(); |
| } |
| break; |
| /*VLOCK*/ |
| case AMVECM_IOC_VLOCK_EN: |
| vecm_latch_flag |= FLAG_VLOCK_EN; |
| break; |
| case AMVECM_IOC_VLOCK_DIS: |
| vecm_latch_flag |= FLAG_VLOCK_DIS; |
| break; |
| /*3D-SYNC*/ |
| case AMVECM_IOC_3D_SYNC_EN: |
| vecm_latch_flag |= FLAG_3D_SYNC_EN; |
| break; |
| case AMVECM_IOC_3D_SYNC_DIS: |
| vecm_latch_flag |= FLAG_3D_SYNC_DIS; |
| break; |
| case AMVECM_IOC_SET_OVERSCAN: |
| if (copy_from_user(&vpp_pq_load, |
| (void __user *)arg, |
| sizeof(struct ve_pq_load_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("[amvecm..] pq ioctl copy fail!!\n"); |
| break; |
| } |
| if (!(vpp_pq_load.param_id & TABLE_NAME_OVERSCAN)) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("[amvecm..] overscan ioctl param_id fail!!\n"); |
| break; |
| } |
| /*check pq_table length copy_from_user*/ |
| if (vpp_pq_load.length > TIMING_MAX || |
| vpp_pq_load.length <= 0) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("[amvecm..] pq ioctl length check fail!!\n"); |
| break; |
| } |
| |
| mem_size = vpp_pq_load.length * sizeof(struct ve_pq_table_s); |
| vpp_pq_load_table = kmalloc(mem_size, GFP_KERNEL); |
| if (!vpp_pq_load_table) { |
| pr_info("vpp_pq_load_table kmalloc fail!!!\n"); |
| return -EFAULT; |
| } |
| argp = (void __user *)vpp_pq_load.param_ptr; |
| if (copy_from_user(vpp_pq_load_table, argp, mem_size)) { |
| pr_amvecm_dbg("[amvecm..] ovescan copy fail!!\n"); |
| break; |
| } |
| parse_overscan_table(vpp_pq_load.length, vpp_pq_load_table); |
| break; |
| case AMVECM_IOC_S_HDR_TM: |
| if (copy_from_user(&hdr_tone_mapping, |
| (void __user *)arg, |
| sizeof(struct hdr_tone_mapping_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("hdr ioc fail!!!\n"); |
| break; |
| } |
| |
| if (hdr_tone_mapping.lutlength > HDR2_OOTF_LUT_SIZE) { |
| pr_amvecm_dbg("hdr tm over size !!!\n"); |
| ret = -EFAULT; |
| break; |
| } |
| mem_size = hdr_tone_mapping.lutlength * sizeof(unsigned int); |
| hdr_tm = kmalloc(mem_size, GFP_KERNEL); |
| argp = (void __user *)hdr_tone_mapping.tm_lut; |
| if (!hdr_tm) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("hdr tm kmalloc fail!!!\n"); |
| break; |
| } |
| if (copy_from_user(hdr_tm, argp, mem_size)) { |
| pr_amvecm_dbg("[amvecm..] hdr_tm copy fail!!\n"); |
| ret = -EFAULT; |
| break; |
| } |
| hdr_tone_mapping_get(hdr_tone_mapping.lut_type, |
| hdr_tone_mapping.lutlength, |
| hdr_tm); |
| |
| break; |
| case AMVECM_IOC_G_DNLP_STATE: |
| if (copy_to_user((void __user *)arg, |
| &dnlp_en, sizeof(enum dnlp_state_e))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_S_DNLP_STATE: |
| if (copy_from_user(&dnlp_en, |
| (void __user *)arg, |
| sizeof(enum dnlp_state_e))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_G_PQMODE: |
| argp = (void __user *)arg; |
| if (copy_to_user(argp, |
| &pc_mode, sizeof(enum pc_mode_e))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_S_PQMODE: |
| if (copy_from_user(&pc_mode, |
| (void __user *)arg, |
| sizeof(enum pc_mode_e))) |
| ret = -EFAULT; |
| else |
| pc_mode_last = 0xff; |
| break; |
| case AMVECM_IOC_G_CSCTYPE: |
| argp = (void __user *)arg; |
| if (copy_to_user(argp, |
| &cur_csc_type[VD1_PATH], |
| sizeof(enum vpp_matrix_csc_e))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_G_COLOR_PRI: |
| argp = (void __user *)arg; |
| color_pri = get_color_primary(); |
| if (copy_to_user(argp, |
| &color_pri, |
| sizeof(enum color_primary_e))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_S_CSCTYPE: |
| if (copy_from_user(&cur_csc_type[VD1_PATH], |
| (void __user *)arg, |
| sizeof(enum vpp_matrix_csc_e))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("[amvecm..] cur_csc_type ioctl copy fail!!\n"); |
| } |
| break; |
| case AMVECM_IOC_G_PIC_MODE: |
| argp = (void __user *)arg; |
| if (copy_to_user(argp, |
| &vdj_mode_s, sizeof(struct am_vdj_mode_s))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_S_PIC_MODE: |
| if (copy_from_user(&vdj_mode_s, |
| (void __user *)arg, |
| sizeof(struct am_vdj_mode_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("[amvecm..] vdj_mode_s ioctl copy fail!!\n"); |
| break; |
| } |
| vdj_mode_flg = vdj_mode_s.flag; |
| /*vadj switch control according to vadj1_en/vadj2_en*/ |
| if (vdj_mode_flg & VDJ_FLAG_VADJ_EN) { |
| pr_amvecm_dbg("IOC--vadj1_en=%d,vadj2_en=%d.\n", |
| vdj_mode_s.vadj1_en, vdj_mode_s.vadj2_en); |
| vecm_latch_flag |= FLAG_VADJ_EN; |
| } |
| |
| if (vdj_mode_flg & VDJ_FLAG_BRIGHTNESS) { /*brightness*/ |
| vd1_brightness = vdj_mode_s.brightness; |
| vecm_latch_flag |= FLAG_VADJ1_BRI; |
| } |
| if (vdj_mode_flg & VDJ_FLAG_BRIGHTNESS2) { /*brightness2*/ |
| if (vdj_mode_s.brightness2 < -1024 || |
| vdj_mode_s.brightness2 > 1023) { |
| pr_amvecm_dbg("load brightness2 value invalid!!!\n"); |
| return -EINVAL; |
| } |
| ret = amvecm_set_brightness2(vdj_mode_s.brightness2); |
| } |
| if (vdj_mode_flg & VDJ_FLAG_SAT_HUE) { /*saturation_hue*/ |
| /*ai pq get saturation*/ |
| aipq_base_satur_param(vdj_mode_s.saturation_hue); |
| //ret = |
| //amvecm_set_saturation_hue(vdj_mode_s.saturation_hue); |
| pq_user_latch_flag |= PQ_USER_CMS_SAT_HUE; |
| pr_amvecm_dbg("vdj_mode_s.saturation_hue:%d\n", |
| vdj_mode_s.saturation_hue); |
| } |
| if (vdj_mode_flg & VDJ_FLAG_SAT_HUE_POST) { |
| /*saturation_hue_post*/ |
| int sat_post, hue_post, sat_hue_post; |
| |
| sat_hue_post = vdj_mode_s.saturation_hue_post; |
| sat_post = (((sat_hue_post >> 16) & 0xffff) / 2) - 128; |
| hue_post = sat_hue_post & 0xffff; |
| if (hue_post >= 0 && hue_post <= 150) |
| hue_post = hue_post / 6; |
| else |
| hue_post = (hue_post - 1024) / 6; |
| ret = |
| amvecm_set_saturation_hue_post(sat_post, hue_post); |
| if (ret < 0) |
| break; |
| } |
| if (vdj_mode_flg & 0x10) { /*contrast*/ |
| if (vdj_mode_s.contrast < -1024 || |
| vdj_mode_s.contrast > 1023) { |
| ret = -EINVAL; |
| pr_amvecm_dbg("[amvecm..] ioctrl contrast value invalid!!\n"); |
| break; |
| } |
| vd1_contrast = vdj_mode_s.contrast; |
| vecm_latch_flag |= FLAG_VADJ1_CON; |
| } |
| if (vdj_mode_flg & 0x20) { /*constract2*/ |
| if (vdj_mode_s.contrast2 < -127 || |
| vdj_mode_s.contrast2 > 127) { |
| ret = -EINVAL; |
| pr_amvecm_dbg("[amvecm..] ioctrl contrast2 value invalid!!\n"); |
| break; |
| } |
| ret = amvecm_set_contrast2(vdj_mode_s.contrast2); |
| } |
| break; |
| case AMVECM_IOC_S_LC_CURVE: |
| if (copy_from_user(&lc_curve_parm_load, |
| (void __user *)arg, |
| sizeof(struct ve_lc_curve_parm_s))) { |
| pr_amvecm_dbg("lc load curve parm fail\n"); |
| ret = -EFAULT; |
| } else { |
| ve_lc_curve_update(); |
| pr_amvecm_dbg("lc load curve parm success\n"); |
| } |
| break; |
| case AMVECM_IOC_G_HDR_TYPE: |
| argp = (void __user *)arg; |
| if (copy_to_user(argp, |
| &hdr_source_type, sizeof(enum hdr_type_e))) |
| ret = -EFAULT; |
| break; |
| case AMVECM_IOC_S_PQ_CTRL: |
| if (copy_from_user(&pq_ctrl, |
| (void __user *)arg, |
| sizeof(struct vpp_pq_ctrl_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("pq control cp vpp_pq_ctrl_s fail\n"); |
| } else { |
| argp = (void __user *)pq_ctrl.ptr; |
| pr_amvecm_dbg("argp = %p\n", argp); |
| mem_size = sizeof(struct pq_ctrl_s); |
| if (pq_ctrl.length > mem_size) { |
| pq_ctrl.length = mem_size; |
| pr_amvecm_dbg("system control length > kernel length\n"); |
| } |
| if (copy_from_user(&pq_cfg, |
| argp, |
| mem_size)) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("pq control cp pq_ctrl_s fail\n"); |
| } else { |
| vpp_pq_ctrl_config(pq_cfg); |
| pr_amvecm_dbg("pq control load success\n"); |
| } |
| } |
| break; |
| case AMVECM_IOC_G_PQ_CTRL: |
| argp = (void __user *)arg; |
| pq_ctrl.length = sizeof(struct pq_ctrl_s); |
| pq_ctrl.ptr = (void *)&pq_cfg; |
| if (copy_to_user(argp, &pq_ctrl, |
| sizeof(struct vpp_pq_ctrl_s))) { |
| ret = -EFAULT; |
| pr_info("pq control cp to user fail\n"); |
| } else { |
| pr_info("pq control cp to user success\n"); |
| } |
| break; |
| case AMVECM_IOC_S_MESON_CPU_VER: |
| if (!is_meson_tm2_cpu()) |
| break; |
| if (copy_from_user(&cpu_ver, |
| (void __user *)arg, |
| sizeof(enum meson_cpu_ver_e))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("copy cpu version fail\n"); |
| } else { |
| if ((is_meson_rev_a() && cpu_ver == VER_A) || |
| (is_meson_rev_b() && cpu_ver == VER_B)) |
| break; |
| ret = -EINVAL; |
| pr_amvecm_dbg("cpu version doesn't match\n"); |
| } |
| break; |
| case AMVECM_IOC_S_AIPQ_TABLE: |
| if (copy_from_user(&aipq_load_table, |
| (void __user *)arg, |
| sizeof(struct aipq_load_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("aipq load ioc fail\n"); |
| break; |
| } |
| if (aipq_load_table.height > AIPQ_SCENE_MAX) |
| aipq_load_table.height = AIPQ_SCENE_MAX; |
| if (aipq_load_table.width > AIPQ_FUNC_MAX) |
| aipq_load_table.width = AIPQ_FUNC_MAX; |
| aipq_data_length = AIPQ_SINGL_DATA_LEN * |
| aipq_load_table.height * |
| aipq_load_table.width; |
| |
| size = (aipq_data_length + 1) * sizeof(char); |
| aipq_char_data_ptr = kmalloc(size, GFP_KERNEL); |
| if (!aipq_char_data_ptr) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("aipq_char_data_ptr kmalloc fail!!!\n"); |
| break; |
| } |
| |
| size1 = aipq_load_table.height * |
| aipq_load_table.width * |
| sizeof(int); |
| aipq_int_data_ptr = kmalloc(size1, GFP_KERNEL); |
| if (!aipq_int_data_ptr) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("aipq_int_data_ptr kmalloc fail!!!\n"); |
| break; |
| } |
| |
| argp = (void __user *)aipq_load_table.table_ptr; |
| if (copy_from_user(aipq_char_data_ptr, argp, size)) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("aipq table copy from user fail\n"); |
| break; |
| } |
| |
| aipq_char_data_ptr[aipq_data_length] = '\0'; |
| if (strlen(aipq_char_data_ptr) != aipq_data_length) { |
| pr_amvecm_dbg("aipq data length not eq 3*height*width!!!\n"); |
| break; |
| } |
| |
| str_sapr_to_d(aipq_char_data_ptr, aipq_int_data_ptr, 4); |
| |
| parse_aipq_ofst_table(aipq_int_data_ptr, |
| aipq_load_table.height, |
| aipq_load_table.width); |
| break; |
| case AMVECM_IOC_S_CMS_LUMA: |
| if (copy_from_user(&cm_color_mode, (void __user *)arg, |
| sizeof(struct cm_color_md))) { |
| ret = -EFAULT; |
| } else { |
| if (cm_color_mode.color_type == cm_9_color) |
| cm_color = cm_color_mode.cm_9_color_md; |
| else |
| cm_color = cm_color_mode.cm_14_color_md; |
| |
| cm_cur_work_color_md = cm_color_mode.color_type; |
| cm2_luma_array[cm_color][0] = cm_color_mode.color_value; |
| cm2_luma_array[cm_color][1] = 0; |
| cm2_luma_array[cm_color][2] = 1; |
| cm2_luma(cm_color_mode, |
| cm2_luma_array[cm_color][0], |
| cm2_luma_array[cm_color][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_LUMA; |
| } |
| break; |
| case AMVECM_IOC_S_CMS_SAT: |
| if (copy_from_user(&cm_color_mode, (void __user *)arg, |
| sizeof(struct cm_color_md))) { |
| ret = -EFAULT; |
| } else { |
| if (cm_color_mode.color_type == cm_9_color) |
| cm_color = cm_color_mode.cm_9_color_md; |
| else |
| cm_color = cm_color_mode.cm_14_color_md; |
| |
| cm_cur_work_color_md = cm_color_mode.color_type; |
| cm2_sat_array[cm_color][0] = cm_color_mode.color_value; |
| cm2_sat_array[cm_color][1] = 0; |
| cm2_sat_array[cm_color][2] = 1; |
| cm2_sat(cm_color_mode, |
| cm2_sat_array[cm_color][0], |
| cm2_sat_array[cm_color][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_SAT; |
| } |
| break; |
| case AMVECM_IOC_S_CMS_HUE: |
| if (copy_from_user(&cm_color_mode, (void __user *)arg, |
| sizeof(struct cm_color_md))) { |
| ret = -EFAULT; |
| } else { |
| if (cm_color_mode.color_type == cm_9_color) |
| cm_color = cm_color_mode.cm_9_color_md; |
| else |
| cm_color = cm_color_mode.cm_14_color_md; |
| |
| cm_cur_work_color_md = cm_color_mode.color_type; |
| cm2_hue_array[cm_color][0] = cm_color_mode.color_value; |
| cm2_hue_array[cm_color][1] = 0; |
| cm2_hue_array[cm_color][2] = 1; |
| cm2_hue(cm_color_mode, |
| cm2_hue_array[cm_color][0], |
| cm2_hue_array[cm_color][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_HUE; |
| } |
| break; |
| case AMVECM_IOC_S_CMS_HUE_HS: |
| if (copy_from_user(&cm_color_mode, (void __user *)arg, |
| sizeof(struct cm_color_md))) { |
| ret = -EFAULT; |
| } else { |
| if (cm_color_mode.color_type == cm_9_color) |
| cm_color = cm_color_mode.cm_9_color_md; |
| else |
| cm_color = cm_color_mode.cm_14_color_md; |
| |
| cm_cur_work_color_md = cm_color_mode.color_type; |
| cm2_hue_by_hs_array[cm_color][0] = |
| cm_color_mode.color_value; |
| cm2_hue_by_hs_array[cm_color][1] = 0; |
| cm2_hue_by_hs_array[cm_color][2] = 1; |
| cm2_hue_by_hs(cm_color_mode, |
| cm2_hue_by_hs_array[cm_color][0], |
| cm2_hue_by_hs_array[cm_color][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_HUE_HS; |
| } |
| break; |
| case AMVECM_IOC_S_MTX_COEF: |
| if (copy_from_user(mtx_p, (void __user *)arg, |
| sizeof(struct vpp_mtx_info_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("mtx info cp from usr failed\n"); |
| } else { |
| vecm_latch_flag2 |= VPP_MARTIX_UPDATE; |
| } |
| break; |
| case AMVECM_IOC_G_MTX_COEF: |
| argp = (void __user *)arg; |
| vecm_latch_flag2 |= VPP_MARTIX_GET; |
| vpp_mtx_update(mtx_p); |
| if (copy_to_user(argp, mtx_p, |
| sizeof(struct vpp_mtx_info_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("mtx coef copy to user fail\n"); |
| } else { |
| pr_amvecm_dbg("mtx coef copy to user success\n"); |
| } |
| break; |
| case AMVECM_IOC_S_PRE_GAMMA: |
| mem_size = sizeof(struct pre_gamma_table_s); |
| pre_gma_tb = kmalloc(mem_size, GFP_KERNEL); |
| if (!pre_gma_tb) { |
| pr_amvecm_dbg("pre_gma_tb malloc fail\n"); |
| ret = -ENOMEM; |
| break; |
| } |
| if (copy_from_user(pre_gma_tb, (void __user *)arg, |
| sizeof(struct pre_gamma_table_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("pre gam struct cp from usr failed\n"); |
| } else { |
| pr_amvecm_dbg("pre gam struct cp from usr success\n"); |
| pre_gamma.en = pre_gma_tb->en; |
| memcpy(pre_gamma.lut_r, |
| pre_gma_tb->lut_r, 65 * sizeof(unsigned int)); |
| memcpy(pre_gamma.lut_g, |
| pre_gma_tb->lut_g, 65 * sizeof(unsigned int)); |
| memcpy(pre_gamma.lut_b, |
| pre_gma_tb->lut_b, 65 * sizeof(unsigned int)); |
| vecm_latch_flag2 |= VPP_PRE_GAMMA_UPDATE; |
| } |
| break; |
| case AMVECM_IOC_G_PRE_GAMMA: |
| argp = (void __user *)arg; |
| mem_size = sizeof(struct pre_gamma_table_s); |
| pre_gma_tb = kmalloc(mem_size, GFP_KERNEL); |
| if (!pre_gma_tb) { |
| pr_amvecm_dbg("pre_gma_tb malloc fail\n"); |
| ret = -EFAULT; |
| break; |
| } |
| pre_gma_tb->en = pre_gamma.en; |
| memcpy(pre_gma_tb->lut_r, |
| pre_gamma.lut_r, 65 * sizeof(unsigned int)); |
| memcpy(pre_gma_tb->lut_g, |
| pre_gamma.lut_g, 65 * sizeof(unsigned int)); |
| memcpy(pre_gma_tb->lut_b, |
| pre_gamma.lut_b, 65 * sizeof(unsigned int)); |
| if (copy_to_user(argp, pre_gma_tb, mem_size)) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("pre gam struct cp to usr failed\n"); |
| } else { |
| pr_amvecm_dbg("pre gam struct cp to usr success\n"); |
| } |
| break; |
| case AMVECM_IOC_S_HDR_TMO: |
| if (copy_from_user(&pre_tmo_reg, |
| (void __user *)arg, |
| sizeof(struct hdr_tmo_sw))) { |
| ret = -EFAULT; |
| pr_info("tmo_reg info cp from usr failed\n"); |
| } else { |
| hdr10_tmo_reg_set(&pre_tmo_reg); |
| pr_info("tmo_reg set success\n"); |
| } |
| break; |
| case AMVECM_IOC_G_HDR_TMO: |
| argp = (void __user *)arg; |
| hdr10_tmo_reg_get(&pre_tmo_reg); |
| if (copy_to_user(argp, &pre_tmo_reg, |
| sizeof(struct hdr_tmo_sw))) { |
| ret = -EFAULT; |
| pr_info("tmo_reg copy to user fail\n"); |
| } else { |
| pr_info("tmo_reg copy to user success\n"); |
| } |
| break; |
| case AMVECM_IOC_S_CABC_PARAM: |
| if (copy_from_user(&db_cabc_param, |
| (void __user *)arg, |
| sizeof(struct db_cabc_param_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("db_cabc_param copy from user fail\n"); |
| } else { |
| db_cabc_param_set(&db_cabc_param); |
| pr_amvecm_dbg("db_cabc_param set success\n"); |
| } |
| break; |
| case AMVECM_IOC_S_AAD_PARAM: |
| if (copy_from_user(&db_aad_param, |
| (void __user *)arg, |
| sizeof(struct db_aad_param_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("db_aad_param copy from user fail\n"); |
| } else { |
| db_aad_param_set(&db_aad_param); |
| pr_amvecm_dbg("db_aad_param set success\n"); |
| } |
| break; |
| case AMVECM_IOC_S_EYE_PROT: |
| mem_size = sizeof(struct eye_protect_s); |
| eye_prot = kmalloc(mem_size, GFP_KERNEL); |
| if (!eye_prot) { |
| pr_amvecm_dbg("eye_protect malloc fail\n"); |
| ret = -ENOMEM; |
| break; |
| } |
| if (copy_from_user(eye_prot, (void __user *)arg, |
| sizeof(struct eye_protect_s))) { |
| ret = -EFAULT; |
| pr_amvecm_dbg("eye_protect struct cp from usr failed\n"); |
| } else { |
| pr_amvecm_dbg("eye_protect struct cp from usr success\n"); |
| eye_protect.en = eye_prot->en; |
| memcpy(eye_protect.rgb, |
| eye_prot->rgb, 3 * sizeof(int)); |
| vecm_latch_flag2 |= VPP_EYE_PROTECT_UPDATE; |
| } |
| break; |
| case AMVECM_IOC_S_FREERUN_TYPE: |
| if (copy_from_user(&freerun_en, |
| (void __user *)arg, |
| sizeof(enum freerun_type_e))) |
| ret = -EFAULT; |
| break; |
| default: |
| ret = -EINVAL; |
| break; |
| } |
| |
| kfree(vpp_pq_load_table); |
| kfree(hdr_tm); |
| kfree(aipq_char_data_ptr); |
| kfree(aipq_int_data_ptr); |
| kfree(pre_gma_tb); |
| kfree(eye_prot); |
| // kfree(pre_tmo_reg); |
| return ret; |
| } |
| |
| #ifdef CONFIG_COMPAT |
| static long amvecm_compat_ioctl(struct file *file, unsigned int cmd, |
| unsigned long arg) |
| { |
| unsigned long ret; |
| |
| arg = (unsigned long)compat_ptr(arg); |
| ret = amvecm_ioctl(file, cmd, arg); |
| return ret; |
| } |
| #endif |
| |
| static unsigned int dnlp_dbg_flag; |
| static int dnlp_rd_param; |
| static char dnlp_rd_curve[400]; |
| static ssize_t amvecm_dnlp_debug_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| if (dnlp_dbg_flag & DNLP_PARAM_RD_UPDATE) { |
| dnlp_dbg_flag &= ~DNLP_PARAM_RD_UPDATE; |
| return sprintf(buf, "%d\n", dnlp_rd_param); |
| } |
| |
| if (dnlp_dbg_flag & DNLP_CV_RD_UPDATE) { |
| dnlp_dbg_flag &= ~DNLP_CV_RD_UPDATE; |
| return sprintf(buf, "%s\n", dnlp_rd_curve); |
| } |
| |
| return 0; |
| } |
| |
| static ssize_t amvecm_dnlp_debug_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int i, *p; |
| long val = 0; |
| unsigned int num; |
| char *buf_orig, *parm[8] = {NULL}; |
| int curve_val[65] = {0}; |
| char *stemp = NULL; |
| unsigned short *hist_tmp; |
| |
| if (!buf) |
| return count; |
| |
| stemp = kzalloc(400, GFP_KERNEL); |
| if (!stemp) |
| return 0; |
| memset(stemp, 0, 400); |
| memset(dnlp_rd_curve, 0, 400); |
| |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) { |
| kfree(stemp); |
| return -ENOMEM; |
| } |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (!dnlp_insmod_ok) { |
| pr_info("dnlp insmod fial\n"); |
| goto free_buf; |
| } |
| |
| if (!strcmp(parm[0], "r")) {/*read param*/ |
| if (!strcmp(parm[1], "param")) { |
| if (!strcmp(parm[2], "all")) { |
| for (i = 0; |
| dnlp_parse_cmd[i].value; i++) { |
| pr_info("%d ", |
| *dnlp_parse_cmd[i].value); |
| } |
| pr_info("\n"); |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else { |
| for (i = 0; |
| dnlp_parse_cmd[i].value; i++) { |
| if (!strcmp(parm[1], |
| dnlp_parse_cmd[i].parse_string)) { |
| dnlp_rd_param = *dnlp_parse_cmd[i].value; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| break; |
| } |
| } |
| dnlp_dbg_node_copy(); |
| } |
| } else if (!strcmp(parm[0], "w")) {/*write param*/ |
| for (i = 0; dnlp_parse_cmd[i].value; i++) { |
| if (!strcmp(parm[1], |
| dnlp_parse_cmd[i].parse_string)) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| *dnlp_parse_cmd[i].value = val; |
| pr_amvecm_dbg(" %s: %d\n", |
| dnlp_parse_cmd[i].parse_string, |
| *dnlp_parse_cmd[i].value); |
| break; |
| } |
| dnlp_dbg_node_copy(); |
| } |
| } else if (!strcmp(parm[0], "rc")) {/*read curve*/ |
| if (!strcmp(parm[1], "scurv_low")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(dnlp_scurv_low_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| dnlp_scurv_low_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "scurv_mid1")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(dnlp_scurv_mid1_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| dnlp_scurv_mid1_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "scurv_mid2")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(dnlp_scurv_mid2_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| dnlp_scurv_mid2_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "scurv_hgh1")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(dnlp_scurv_hgh1_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| dnlp_scurv_hgh1_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "scurv_hgh2")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(dnlp_scurv_hgh2_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| dnlp_scurv_hgh2_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "gain_var_lut49")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 49; i++) |
| d_convert_str(gain_var_lut49_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 49); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 48 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| gain_var_lut49_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "c_hist_gain")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(c_hist_gain_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, |
| sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| c_hist_gain_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "s_hist_gain")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(s_hist_gain_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, |
| sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 64 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| s_hist_gain_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "wext_gain")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 48; i++) |
| d_convert_str(wext_gain_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 48); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 47 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", wext_gain_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "adp_thrd")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 33; i++) |
| d_convert_str(adp_thrd_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 33); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 32 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", adp_thrd_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "reg_blk_boost_12")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 13; i++) |
| d_convert_str(reg_blk_boost_12_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 13); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 12 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| reg_blk_boost_12_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "reg_adp_ofset_20")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 20; i++) |
| d_convert_str(reg_adp_ofset_20_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 20); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 19 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| reg_adp_ofset_20_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "reg_mono_protect")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 6; i++) |
| d_convert_str(reg_mono_protect_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 6); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 5 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| reg_mono_protect_copy[val]); |
| } |
| } else if (!strcmp(parm[1], "reg_trend_wht_expand_lut8")) { |
| p = reg_trend_wht_expand_lut8_copy; |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 9; i++) |
| d_convert_str(p[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 9); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| if (val > 8 || val < 0) |
| pr_info("error cmd\n"); |
| else |
| pr_info("%d\n", |
| p[val]); |
| } |
| } else if (!strcmp(parm[1], "ve_dnlp_tgt")) { |
| /*read only curve*/ |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(ve_dnlp_tgt_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else if (!strcmp(parm[1], "ve_dnlp_tgt_10b")) { |
| /*read only curve*/ |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(ve_dnlp_tgt_10b_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else if (!strcmp(parm[1], "GmScurve")) { |
| /*read only curve*/ |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(gmscurve_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else if (!strcmp(parm[1], "clash_curve")) { |
| /*read only curve*/ |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(clash_curve_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else if (!strcmp(parm[1], "clsh_scvbld")) { |
| /*read only curve*/ |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(clsh_scvbld_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else if (!strcmp(parm[1], "blkwht_ebld")) { |
| /*read only curve*/ |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(blkwht_ebld_copy[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 65); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else if (!strcmp(parm[1], "vpp_histgram")) { |
| /*read only curve*/ |
| hist_tmp = vpp_hist_param.vpp_histgram; |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| for (i = 0; i < 64; i++) |
| d_convert_str(hist_tmp[i], |
| i, stemp, 4, 10); |
| memcpy(dnlp_rd_curve, stemp, sizeof(char) * 4 * 64); |
| dnlp_dbg_flag |= DNLP_CV_RD_UPDATE; |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } |
| } else if (!strcmp(parm[0], "wc")) {/*write curve*/ |
| if (!strcmp(parm[1], "scurv_low")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| dnlp_scurv_low_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| dnlp_scurv_low_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "scurv_mid1")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| dnlp_scurv_mid1_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| dnlp_scurv_mid1_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "scurv_mid2")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| dnlp_scurv_mid2_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| dnlp_scurv_mid2_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "scurv_hgh1")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| dnlp_scurv_hgh1_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| dnlp_scurv_hgh1_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "scurv_hgh2")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| dnlp_scurv_hgh2_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| dnlp_scurv_hgh2_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "gain_var_lut49")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 49; i++) |
| gain_var_lut49_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 48) |
| pr_info("error cmd\n"); |
| else |
| gain_var_lut49_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "c_hist_gain")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| c_hist_gain_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| c_hist_gain_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "s_hist_gain")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| s_hist_gain_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 64) |
| pr_info("error cmd\n"); |
| else |
| s_hist_gain_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "wext_gain")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 48; i++) |
| wext_gain_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 47) |
| pr_info("error cmd\n"); |
| else |
| wext_gain_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "adp_thrd")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 33; i++) |
| adp_thrd_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 32) |
| pr_info("error cmd\n"); |
| else |
| adp_thrd_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "reg_blk_boost_12")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 13; i++) |
| reg_blk_boost_12_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 12) |
| pr_info("error cmd\n"); |
| else |
| reg_blk_boost_12_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "reg_adp_ofset_20")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 20; i++) |
| reg_adp_ofset_20_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 19) |
| pr_info("error cmd\n"); |
| else |
| reg_adp_ofset_20_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "reg_mono_protect")) { |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 6; i++) |
| reg_mono_protect_copy[i] = curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 5) |
| pr_info("error cmd\n"); |
| else |
| reg_mono_protect_copy[num] = val; |
| } |
| } else if (!strcmp(parm[1], "reg_trend_wht_expand_lut8")) { |
| p = reg_trend_wht_expand_lut8_copy; |
| if (!parm[2]) { |
| pr_info("error cmd\n"); |
| goto free_buf; |
| } else if (!strcmp(parm[2], "all")) { |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 9; i++) |
| reg_trend_wht_expand_lut8_copy[i] = |
| curve_val[i]; |
| } else { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| |
| num = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| |
| if (num > 8) |
| pr_info("error cmd\n"); |
| else |
| reg_trend_wht_expand_lut8_copy[num] = |
| val; |
| } |
| } |
| } else if (!strcmp(parm[0], "ro")) { |
| if (!strcmp(parm[1], "luma_avg4")) { |
| dnlp_rd_param = *ro_luma_avg4_copy; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| } else if (!strcmp(parm[1], "var_d8")) { |
| dnlp_rd_param = *ro_var_d8_copy; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| } else if (!strcmp(parm[1], "scurv_gain")) { |
| dnlp_rd_param = *ro_scurv_gain_copy; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| } else if (!strcmp(parm[1], "blk_wht_ext0")) { |
| dnlp_rd_param = *ro_blk_wht_ext0_copy; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| } else if (!strcmp(parm[1], "blk_wht_ext1")) { |
| dnlp_rd_param = *ro_blk_wht_ext1_copy; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| } else if (!strcmp(parm[1], "dnlp_brightness")) { |
| dnlp_rd_param = *ro_dnlp_brightness_copy; |
| dnlp_dbg_flag |= DNLP_PARAM_RD_UPDATE; |
| } else |
| pr_info("error cmd\n"); |
| } else if (!strcmp(parm[0], "dnlp_print")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| |
| *dnlp_printk_copy = val; |
| pr_info("dnlp_print = %x\n", *dnlp_printk_copy); |
| } |
| |
| kfree(buf_orig); |
| kfree(stemp); |
| return count; |
| |
| free_buf: |
| kfree(buf_orig); |
| kfree(stemp); |
| return -EINVAL; |
| } |
| |
| static ssize_t amvecm_cabc_aad_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| ssize_t len = 0; |
| |
| len = cabc_aad_print(buf); |
| return len; |
| } |
| |
| static ssize_t amvecm_cabc_aad_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int ret; |
| char *buf_orig, *parm[8] = {NULL}; |
| |
| if (!buf) |
| return count; |
| |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| ret = cabc_aad_debug(parm); |
| |
| if (ret < 0) |
| pr_info("set parameters failed\n"); |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_brightness_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| return sprintf(buf, "%d\n", vd1_brightness); |
| } |
| |
| static ssize_t amvecm_brightness_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%d\n", &val); |
| if (r != 1 || val < -1024 || val > 1024) |
| return -EINVAL; |
| |
| vd1_brightness = val; |
| /*vecm_latch_flag |= FLAG_BRI_CON;*/ |
| vecm_latch_flag |= FLAG_VADJ1_BRI; |
| return count; |
| } |
| |
| static ssize_t amvecm_contrast_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| return sprintf(buf, "%d\n", vd1_contrast); |
| } |
| |
| static ssize_t amvecm_contrast_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%d\n", &val); |
| if (r != 1 || val < -1024 || val > 1023) |
| return -EINVAL; |
| |
| vd1_contrast = val; |
| /*vecm_latch_flag |= FLAG_BRI_CON;*/ |
| vecm_latch_flag |= FLAG_VADJ1_CON; |
| return count; |
| } |
| |
| static ssize_t amvecm_saturation_hue_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| return sprintf(buf, "0x%x\n", |
| READ_VPP_REG(VPP_VADJ1_MA_MB_2)); |
| else |
| return sprintf(buf, "0x%x\n", |
| READ_VPP_REG(VPP_VADJ1_MA_MB)); |
| } |
| |
| static ssize_t amvecm_saturation_hue_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| s32 mab = 0; |
| |
| r = sscanf(buf, "0x%x", &mab); |
| if (r != 1 || (mab & 0xfc00fc00)) |
| return -EINVAL; |
| amvecm_set_saturation_hue(mab); |
| return count; |
| } |
| |
| void vpp_vd_adj1_saturation_hue(signed int sat_val, |
| signed int hue_val, struct vframe_s *vf) |
| { |
| int i, ma, mb, mab, mc, md; |
| int hue_cos[] = { |
| /*0~12*/ |
| 256, 256, 256, 255, 255, 254, 253, 252, 251, 250, 248, 247, 245, |
| /*13~25*/ |
| 243, 241, 239, 237, 234, 231, 229, 226, 223, 220, 216, 213, 209 |
| }; |
| int hue_sin[] = { |
| /*-25~-13*/ |
| -147, -142, -137, -132, -126, -121, -115, -109, -104, |
| -98, -92, -86, -80, -74, -68, -62, -56, -50, |
| -44, -38, -31, -25, -19, -13, -6, /*-12~-1*/ |
| 0, /*0*/ |
| /*1~12*/ |
| 6, 13, 19, 25, 31, 38, 44, 50, 56, 62, |
| 68, 74, 80, 86, 92, 98, 104, 109, 115, 121, |
| 126, 132, 137, 142, 147 /*13~25*/ |
| }; |
| |
| i = (hue_val > 0) ? hue_val : -hue_val; |
| ma = (hue_cos[i] * (sat_val + 128)) >> 7; |
| mb = (hue_sin[25 + hue_val] * (sat_val + 128)) >> 7; |
| saturation_ma_shift = ma - 0x100; |
| saturation_mb_shift = mb; |
| |
| ma += saturation_ma; |
| mb += saturation_mb; |
| if (ma > 511) |
| ma = 511; |
| if (ma < -512) |
| ma = -512; |
| if (mb > 511) |
| mb = 511; |
| if (mb < -512) |
| mb = -512; |
| mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff); |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| VSYNC_WRITE_VPP_REG(VPP_VADJ1_MA_MB_2, mab); |
| else |
| VSYNC_WRITE_VPP_REG(VPP_VADJ1_MA_MB, mab); |
| mc = (s16)((mab << 22) >> 22); /* mc = -mb */ |
| mc = 0 - mc; |
| if (mc > 511) |
| mc = 511; |
| if (mc < -512) |
| mc = -512; |
| md = (s16)((mab << 6) >> 22); /* md = ma; */ |
| mab = ((mc & 0x3ff) << 16) | (md & 0x3ff); |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { |
| VSYNC_WRITE_VPP_REG(VPP_VADJ1_MC_MD_2, mab); |
| VSYNC_WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1); |
| } else { |
| VSYNC_WRITE_VPP_REG(VPP_VADJ1_MC_MD, mab); |
| VSYNC_WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1); |
| } |
| }; |
| |
| static ssize_t amvecm_saturation_hue_pre_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return snprintf(buf, 20, "%d %d\n", saturation_pre, hue_pre); |
| } |
| |
| static ssize_t amvecm_saturation_hue_pre_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int parsed[2]; |
| |
| if (likely(parse_para_pq(buf, 2, parsed) != 2)) |
| return -EINVAL; |
| |
| if (parsed[0] < -128 || parsed[0] > 128 || |
| parsed[1] < -25 || parsed[1] > 25) { |
| return -EINVAL; |
| } |
| saturation_pre = parsed[0]; |
| hue_pre = parsed[1]; |
| vecm_latch_flag |= FLAG_VADJ1_COLOR; |
| |
| return count; |
| } |
| |
| static ssize_t amvecm_saturation_hue_post_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return snprintf(buf, 20, "%d %d\n", saturation_post, hue_post); |
| } |
| |
| static ssize_t amvecm_saturation_hue_post_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int parsed[2], ret; |
| |
| if (likely(parse_para_pq(buf, 2, parsed) != 2)) |
| return -EINVAL; |
| ret = amvecm_set_saturation_hue_post(parsed[0], |
| parsed[1]); |
| if (ret < 0) |
| return ret; |
| return count; |
| } |
| |
| static ssize_t amvecm_cm2_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("Usage:"); |
| pr_info(" echo wm addr data0 data1 data2 data3 data4 "); |
| pr_info("> /sys/class/amvecm/cm2\n"); |
| pr_info(" echo rm addr > /sys/class/amvecm/cm2\n"); |
| return 0; |
| } |
| |
| static ssize_t amvecm_cm2_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| int n = 0; |
| char *buf_orig, *ps, *token; |
| char *parm[7]; |
| u32 addr; |
| int data[5] = {0}; |
| unsigned int addr_port = VPP_CHROMA_ADDR_PORT;/* 0x1d70; */ |
| unsigned int data_port = VPP_CHROMA_DATA_PORT;/* 0x1d71; */ |
| long val; |
| char delim1[3] = " "; |
| char delim2[2] = "\n"; |
| |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| ps = buf_orig; |
| strcat(delim1, delim2); |
| while (1) { |
| token = strsep(&ps, delim1); |
| if (!token) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| if (n == 0) { |
| pr_info("strsep fail,parm[] uninitialized !\n"); |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| if ((parm[0][0] == 'w') && parm[0][1] == 'm') { |
| if (n != 7) { |
| pr_info("read: invalid parameter\n"); |
| pr_info("please: cat /sys/class/amvecm/cm2\n"); |
| kfree(buf_orig); |
| return count; |
| } |
| if (kstrtol(parm[1], 16, &val) < 0) |
| return -EINVAL; |
| addr = val; |
| addr = addr - addr % 8; |
| if (kstrtol(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| data[0] = val; |
| if (kstrtol(parm[3], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| data[1] = val; |
| if (kstrtol(parm[4], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| data[2] = val; |
| if (kstrtol(parm[5], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| data[3] = val; |
| if (kstrtol(parm[6], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| data[4] = val; |
| WRITE_VPP_REG(addr_port, addr); |
| WRITE_VPP_REG(data_port, data[0]); |
| WRITE_VPP_REG(addr_port, addr + 1); |
| WRITE_VPP_REG(data_port, data[1]); |
| WRITE_VPP_REG(addr_port, addr + 2); |
| WRITE_VPP_REG(data_port, data[2]); |
| WRITE_VPP_REG(addr_port, addr + 3); |
| WRITE_VPP_REG(data_port, data[3]); |
| WRITE_VPP_REG(addr_port, addr + 4); |
| WRITE_VPP_REG(data_port, data[4]); |
| pr_info("wm: [0x%x] <-- 0x0\n", addr); |
| } else if ((parm[0][0] == 'r') && parm[0][1] == 'm') { |
| if (n != 2) { |
| pr_info("read: invalid parameter\n"); |
| pr_info("please: cat /sys/class/amvecm/cm2\n"); |
| kfree(buf_orig); |
| return count; |
| } |
| if (kstrtol(parm[1], 16, &val) < 0) |
| return -EINVAL; |
| addr = val; |
| addr = addr - addr % 8; |
| WRITE_VPP_REG(addr_port, addr); |
| data[0] = READ_VPP_REG(data_port); |
| data[0] = READ_VPP_REG(data_port); |
| data[0] = READ_VPP_REG(data_port); |
| WRITE_VPP_REG(addr_port, addr + 1); |
| data[1] = READ_VPP_REG(data_port); |
| data[1] = READ_VPP_REG(data_port); |
| data[1] = READ_VPP_REG(data_port); |
| WRITE_VPP_REG(addr_port, addr + 2); |
| data[2] = READ_VPP_REG(data_port); |
| data[2] = READ_VPP_REG(data_port); |
| data[2] = READ_VPP_REG(data_port); |
| WRITE_VPP_REG(addr_port, addr + 3); |
| data[3] = READ_VPP_REG(data_port); |
| data[3] = READ_VPP_REG(data_port); |
| data[3] = READ_VPP_REG(data_port); |
| WRITE_VPP_REG(addr_port, addr + 4); |
| data[4] = READ_VPP_REG(data_port); |
| data[4] = READ_VPP_REG(data_port); |
| data[4] = READ_VPP_REG(data_port); |
| pr_info("rm:[0x%x]-->[0x%x][0x%x][0x%x][0x%x][0x%x]\n", |
| addr, data[0], data[1], |
| data[2], data[3], data[4]); |
| } else { |
| pr_info("invalid command\n"); |
| pr_info("please: cat /sys/class/amvecm/bit"); |
| } |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_cm_reg_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("Usage: echo addr value > /sys/class/amvecm/cm_reg"); |
| return 0; |
| } |
| |
| static ssize_t amvecm_cm_reg_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| int data[5] = {0}; |
| unsigned int addr, value; |
| long val = 0; |
| int i, node, reg_node; |
| unsigned int addr_port = VPP_CHROMA_ADDR_PORT;/* 0x1d70; */ |
| unsigned int data_port = VPP_CHROMA_DATA_PORT;/* 0x1d71; */ |
| char *buf_orig, *parm[2] = {NULL}; |
| |
| if (!buffer) |
| return count; |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (kstrtoul(parm[0], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| addr = val; |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| value = val; |
| |
| node = (addr - 0x100) / 8; |
| reg_node = (addr - 0x100) % 8; |
| |
| for (i = 0; i < 5; i++) { |
| if (i == reg_node) { |
| data[i] = value; |
| continue; |
| } |
| addr = node * 8 + 0x100 + i; |
| WRITE_VPP_REG(addr_port, addr); |
| data[i] = READ_VPP_REG(data_port); |
| } |
| |
| for (i = 0; i < 5; i++) { |
| addr = node * 8 + 0x100 + i; |
| WRITE_VPP_REG(addr_port, addr); |
| WRITE_VPP_REG(data_port, data[i]); |
| } |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_write_reg_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("Usage: echo w addr value > /sys/class/amvecm/pq_reg_rw\n"); |
| pr_info("Usage: echo bw addr value start length > /...\n"); |
| pr_info("Usage: echo r addr > /sys/class/amvecm/pq_reg_rw\n"); |
| pr_info("addr and value must be hex\n"); |
| return 0; |
| } |
| |
| static ssize_t amvecm_write_reg_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| unsigned int addr, value, bitstart, bitlength; |
| long val = 0; |
| char *buf_orig, *parm[5] = {NULL}; |
| |
| if (!buffer) |
| return count; |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (!strncmp(parm[0], "r", 1)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| addr = val; |
| value = READ_VPP_REG(addr); |
| pr_info("0x%x=0x%x\n", addr, value); |
| } else if (!strncmp(parm[0], "w", 1)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| addr = val; |
| if (kstrtoul(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| value = val; |
| WRITE_VPP_REG(addr, value); |
| } else if (!strncmp(parm[0], "bw", 2)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| addr = val; |
| if (kstrtoul(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| value = val; |
| if (kstrtoul(parm[3], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| bitstart = val; |
| if (kstrtoul(parm[4], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| bitlength = val; |
| WRITE_VPP_REG_BITS(addr, value, bitstart, bitlength); |
| } |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_gamma_show(struct class *cls, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| pr_info("Usage:"); |
| pr_info(" echo sgr|sgg|sgb xxx...xx > /sys/class/amvecm/gamma\n"); |
| pr_info("Notes:\n"); |
| pr_info(" if the string xxx......xx is less than 256*3,"); |
| pr_info(" then the remaining will be set value 0\n"); |
| pr_info(" if the string xxx......xx is more than 256*3, "); |
| pr_info(" then the remaining will be ignored\n"); |
| pr_info("Usage:"); |
| pr_info(" echo ggr|ggg|ggb xxx > /sys/class/amvecm/gamma\n"); |
| pr_info("Notes:\n"); |
| pr_info(" read all as point......xxx is 'all'.\n"); |
| pr_info(" read all as strings......xxx is 'all_str'.\n"); |
| pr_info(" read one point......xxx is a value '0~255'.\n "); |
| return 0; |
| } |
| |
| static ssize_t amvecm_gamma_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| int n = 0; |
| char *buf_orig, *ps, *token; |
| char *parm[4]; |
| unsigned short *gamma_r, *gamma_g, *gamma_b; |
| unsigned int gamma_count; |
| char gamma[4]; |
| int i = 0; |
| long val; |
| char delim1[3] = " "; |
| char delim2[2] = "\n"; |
| char *stemp = NULL; |
| |
| stemp = kmalloc(600, GFP_KERNEL); |
| if (!stemp) |
| return -ENOMEM; |
| |
| gamma_r = kmalloc(256 * sizeof(unsigned short), GFP_KERNEL); |
| if (!gamma_r) { |
| kfree(stemp); |
| return -ENOMEM; |
| } |
| gamma_g = kmalloc(256 * sizeof(unsigned short), GFP_KERNEL); |
| if (!gamma_g) { |
| kfree(stemp); |
| kfree(gamma_r); |
| return -ENOMEM; |
| } |
| gamma_b = kmalloc(256 * sizeof(unsigned short), GFP_KERNEL); |
| if (!gamma_b) { |
| kfree(stemp); |
| kfree(gamma_r); |
| kfree(gamma_g); |
| return -ENOMEM; |
| } |
| |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) |
| goto free_buf; |
| ps = buf_orig; |
| strcat(delim1, delim2); |
| while (1) { |
| token = strsep(&ps, delim1); |
| if (!token) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| if (!gamma_r || !gamma_g || !gamma_b || !stemp || n == 0) |
| goto free_buf; |
| |
| if ((parm[0][0] == 's') && (parm[0][1] == 'g')) { |
| memset(gamma_r, 0, 256 * sizeof(unsigned short)); |
| gamma_count = (strlen(parm[1]) + 2) / 3; |
| if (gamma_count > 256) |
| gamma_count = 256; |
| |
| for (i = 0; i < gamma_count; ++i) { |
| gamma[0] = parm[1][3 * i + 0]; |
| gamma[1] = parm[1][3 * i + 1]; |
| gamma[2] = parm[1][3 * i + 2]; |
| gamma[3] = '\0'; |
| if (kstrtol(gamma, 16, &val) < 0) |
| goto free_buf; |
| gamma_r[i] = val; |
| } |
| |
| switch (parm[0][2]) { |
| case 'r': |
| amve_write_gamma_table(gamma_r, H_SEL_R); |
| break; |
| |
| case 'g': |
| amve_write_gamma_table(gamma_r, H_SEL_G); |
| break; |
| |
| case 'b': |
| amve_write_gamma_table(gamma_r, H_SEL_B); |
| break; |
| default: |
| break; |
| } |
| } else if (!strcmp(parm[0], "ggr")) { |
| vpp_get_lcd_gamma_table(H_SEL_R); |
| if (!strcmp(parm[1], "all")) { |
| for (i = 0; i < 256; i++) |
| pr_info("gamma_r[%d] = %x\n", |
| i, gamma_data_r[i]); |
| } else if (!strcmp(parm[1], "all_str")) { |
| for (i = 0; i < 256; i++) |
| d_convert_str(gamma_data_r[i], i, stemp, 3, 16); |
| pr_info("gamma_r str: %s\n", stemp); |
| } else { |
| if (kstrtoul(parm[1], 10, &val) < 0) { |
| pr_info("invalid command\n"); |
| goto free_buf; |
| } |
| i = val; |
| if (i >= 0 && i <= 255) |
| pr_info("gamma_r[%d] = %x\n", |
| i, gamma_data_r[i]); |
| } |
| } else if (!strcmp(parm[0], "ggg")) { |
| vpp_get_lcd_gamma_table(H_SEL_G); |
| if (!strcmp(parm[1], "all")) { |
| for (i = 0; i < 256; i++) |
| pr_info("gamma_g[%d] = %x\n", |
| i, gamma_data_g[i]); |
| } else if (!strcmp(parm[1], "all_str")) { |
| for (i = 0; i < 256; i++) |
| d_convert_str(gamma_data_g[i], i, stemp, 3, 16); |
| pr_info("gamma_g str: %s\n", stemp); |
| } else { |
| if (kstrtoul(parm[1], 10, &val) < 0) { |
| pr_info("invalid command\n"); |
| goto free_buf; |
| } |
| i = val; |
| if (i >= 0 && i <= 255) |
| pr_info("gamma_g[%d] = %x\n", |
| i, gamma_data_g[i]); |
| } |
| |
| } else if (!strcmp(parm[0], "ggb")) { |
| vpp_get_lcd_gamma_table(H_SEL_B); |
| if (!strcmp(parm[1], "all")) { |
| for (i = 0; i < 256; i++) |
| pr_info("gamma_b[%d] = %x\n", |
| i, gamma_data_b[i]); |
| } else if (!strcmp(parm[1], "all_str")) { |
| for (i = 0; i < 256; i++) |
| d_convert_str(gamma_data_b[i], i, stemp, 3, 16); |
| pr_info("gamma_b str: %s\n", stemp); |
| } else { |
| if (kstrtoul(parm[1], 10, &val) < 0) { |
| pr_info("invalid command\n"); |
| goto free_buf; |
| } |
| i = val; |
| if (i >= 0 && i <= 255) |
| pr_info("gamma_b[%d] = %x\n", |
| i, gamma_data_b[i]); |
| } |
| } else { |
| pr_info("invalid command\n"); |
| pr_info("please: cat /sys/class/amvecm/gamma"); |
| } |
| kfree(buf_orig); |
| kfree(stemp); |
| kfree(gamma_r); |
| kfree(gamma_g); |
| kfree(gamma_b); |
| return count; |
| free_buf: |
| kfree(buf_orig); |
| kfree(stemp); |
| kfree(gamma_r); |
| kfree(gamma_g); |
| kfree(gamma_b); |
| return -EINVAL; |
| } |
| |
| static ssize_t set_gamma_pattern_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("8bit: echo r g b > /sys/class/amvecm/gamma_pattern\n"); |
| pr_info("10bit: echo r g b 0xa > /sys/class/amvecm/gamma_pattern\n"); |
| pr_info(" r g b should be hex\n"); |
| pr_info("disable gamma pattern:\n"); |
| pr_info("echo disable > /sys/class/amvecm/gamma_pattern\n"); |
| return 0; |
| } |
| |
| static ssize_t set_gamma_pattern_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| static unsigned short r_val[256], g_val[256], b_val[256]; |
| int n = 0; |
| char *buf_orig, *ps, *token; |
| char *parm[4]; |
| unsigned int gamma[3]; |
| long val, i; |
| char deliml[3] = " "; |
| char delim2[2] = "\n"; |
| |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| ps = buf_orig; |
| strcat(deliml, delim2); |
| *(parm + 3) = NULL; |
| while (1) { |
| token = strsep(&ps, deliml); |
| if (!token) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| |
| if (!strcmp(parm[0], "disable")) { |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_R; |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_G; |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_B; |
| kfree(buf_orig); |
| return count; |
| } |
| |
| if (*(parm + 3) != NULL) { |
| if (kstrtol(parm[3], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| if (val == 10) { |
| if (kstrtol(parm[0], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| gamma[0] = val; |
| |
| if (kstrtol(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| gamma[1] = val; |
| |
| if (kstrtol(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| gamma[2] = val; |
| } else { |
| kfree(buf_orig); |
| return count; |
| } |
| } else { |
| if (kstrtol(parm[0], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| gamma[0] = val << 2; |
| |
| if (kstrtol(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| gamma[1] = val << 2; |
| |
| if (kstrtol(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| gamma[2] = val << 2; |
| } |
| |
| for (i = 0; i < 256; i++) { |
| r_val[i] = gamma[0]; |
| g_val[i] = gamma[1]; |
| b_val[i] = gamma[2]; |
| } |
| |
| if (cpu_after_eq_t7()) { |
| lcd_gamma_api(gamma_index, r_val, g_val, b_val, 0, 0); |
| } else { |
| amve_write_gamma_table(r_val, H_SEL_R); |
| amve_write_gamma_table(g_val, H_SEL_G); |
| amve_write_gamma_table(b_val, H_SEL_B); |
| } |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| void white_balance_adjust(int sel, int value) |
| { |
| switch (sel) { |
| /*0: en*/ |
| /*1: pre r 2: pre g 3: pre b*/ |
| /*4: gain r 5: gain g 6: gain b*/ |
| /*7: post r 8: post g 9: post b*/ |
| case 0: |
| video_rgb_ogo.en = value; |
| break; |
| case 1: |
| video_rgb_ogo.r_pre_offset = value; |
| break; |
| case 2: |
| video_rgb_ogo.g_pre_offset = value; |
| break; |
| case 3: |
| video_rgb_ogo.b_pre_offset = value; |
| break; |
| case 4: |
| video_rgb_ogo.r_gain = value; |
| break; |
| case 5: |
| video_rgb_ogo.g_gain = value; |
| break; |
| case 6: |
| video_rgb_ogo.b_gain = value; |
| break; |
| case 7: |
| video_rgb_ogo.r_post_offset = value; |
| break; |
| case 8: |
| video_rgb_ogo.g_post_offset = value; |
| break; |
| case 9: |
| video_rgb_ogo.b_post_offset = value; |
| break; |
| default: |
| break; |
| } |
| ve_ogo_param_update(); |
| } |
| |
| static int wb_dbg_flag; |
| static int wb_rd_val; |
| static ssize_t amvecm_wb_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| if (wb_dbg_flag & WB_PARAM_RD_UPDATE) { |
| wb_dbg_flag &= ~WB_PARAM_RD_UPDATE; |
| return sprintf(buf, "%d\n", wb_rd_val); |
| } |
| |
| pr_info("read: echo r gain_r > /sys/class/amvecm/wb;"); |
| pr_info("cat /sys/class/amvecm/wb\n"); |
| pr_info("read: echo r pre_r > /sys/class/amvecm/wb;"); |
| pr_info("cat /sys/class/amvecm/wb\n"); |
| pr_info("read: echo r post_r > /sys/class/amvecm/wb;"); |
| pr_info("cat /sys/class/amvecm/wb\n"); |
| pr_info("write: echo gain_r value > /sys/class/amvecm/wb\n"); |
| pr_info("write: echo preofst_r value > /sys/class/amvecm/wb\n"); |
| pr_info("write: echo postofst_r value > /sys/class/amvecm/wb\n"); |
| return 0; |
| } |
| |
| static ssize_t amvecm_wb_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long value; |
| |
| if (!buffer) |
| return count; |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (!strncmp(parm[0], "r", 1)) { |
| if (!strncmp(parm[1], "pre_r", 5)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.r_pre_offset; |
| } else if (!strncmp(parm[1], "pre_g", 5)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.g_pre_offset; |
| } else if (!strncmp(parm[1], "pre_b", 5)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.b_pre_offset; |
| } else if (!strncmp(parm[1], "gain_r", 6)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.r_gain; |
| } else if (!strncmp(parm[1], "gain_g", 6)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.g_gain; |
| } else if (!strncmp(parm[1], "gain_b", 6)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.b_gain; |
| } else if (!strncmp(parm[1], "post_r", 6)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.r_post_offset; |
| } else if (!strncmp(parm[1], "post_g", 6)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.g_post_offset; |
| } else if (!strncmp(parm[1], "post_b", 6)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.b_post_offset; |
| } else if (!strncmp(parm[1], "en", 2)) { |
| wb_dbg_flag |= WB_PARAM_RD_UPDATE; |
| wb_rd_val = video_rgb_ogo.en; |
| } |
| } else { |
| if (kstrtol(parm[1], 10, &value) < 0) |
| return -EINVAL; |
| if (!strncmp(parm[0], "wb_en", 5)) { |
| white_balance_adjust(0, value); |
| pr_info("\t set wb en\n"); |
| } else if (!strncmp(parm[0], "preofst_r", 9)) { |
| if (value > 1023 || value < -1024) { |
| pr_info("\t preofst r over range\n"); |
| } else { |
| white_balance_adjust(1, value); |
| pr_info("\t set wb preofst r\n"); |
| } |
| } else if (!strncmp(parm[0], "preofst_g", 9)) { |
| if (value > 1023 || value < -1024) { |
| pr_info("\t preofst g over range\n"); |
| } else { |
| white_balance_adjust(2, value); |
| pr_info("\t set wb preofst g\n"); |
| } |
| } else if (!strncmp(parm[0], "preofst_b", 9)) { |
| if (value > 1023 || value < -1024) { |
| pr_info("\t preofst b over range\n"); |
| } else { |
| white_balance_adjust(3, value); |
| pr_info("\t set wb preofst b\n"); |
| } |
| } else if (!strncmp(parm[0], "gain_r", 6)) { |
| if (value > 2047 || value < 0) { |
| pr_info("\t gain r over range\n"); |
| } else { |
| white_balance_adjust(4, value); |
| pr_info("\t set wb gain r\n"); |
| } |
| } else if (!strncmp(parm[0], "gain_g", 6)) { |
| if (value > 2047 || value < 0) { |
| pr_info("\t gain g over range\n"); |
| } else { |
| white_balance_adjust(5, value); |
| pr_info("\t set wb gain g\n"); |
| } |
| } else if (!strncmp(parm[0], "gain_b", 6)) { |
| if (value > 2047 || value < 0) { |
| pr_info("\t gain b over range\n"); |
| } else { |
| white_balance_adjust(6, value); |
| pr_info("\t set wb gain b\n"); |
| } |
| } else if (!strncmp(parm[0], "postofst_r", 10)) { |
| if (value > 1023 || value < -1024) { |
| pr_info("\t postofst r over range\n"); |
| } else { |
| white_balance_adjust(7, value); |
| pr_info("\t set wb postofst r\n"); |
| } |
| } else if (!strncmp(parm[0], "postofst_g", 10)) { |
| if (value > 1023 || value < -1024) { |
| pr_info("\t postofst g over range\n"); |
| } else { |
| white_balance_adjust(8, value); |
| pr_info("\t set wb postofst g\n"); |
| } |
| } else if (!strncmp(parm[0], "postofst_b", 10)) { |
| if (value > 1023 || value < -1024) { |
| pr_info("\t postofst b over range\n"); |
| } else { |
| white_balance_adjust(9, value); |
| pr_info("\t set wb postofst b\n"); |
| } |
| } |
| } |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t set_hdr_289lut_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| int i; |
| |
| for (i = 0; i < 289; i++) { |
| pr_info("0x%-8x\t", lut_289_mapping[i]); |
| if ((i + 1) % 8 == 0) |
| pr_info("\n"); |
| } |
| return 0; |
| } |
| |
| static ssize_t set_hdr_289lut_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| int n = 0; |
| char *buf_orig, *ps, *token; |
| char *parm[4]; |
| unsigned short *hdr289lut; |
| unsigned int gamma_count; |
| char gamma[4]; |
| int i = 0; |
| long val; |
| char deliml[3] = " "; |
| char delim2[2] = "\n"; |
| |
| hdr289lut = kmalloc(289 * sizeof(unsigned short), GFP_KERNEL); |
| |
| buf_orig = kstrdup(buffer, GFP_KERNEL); |
| if (!buf_orig) { |
| kfree(hdr289lut); |
| return -ENOMEM; |
| } |
| ps = buf_orig; |
| strcat(deliml, delim2); |
| while (1) { |
| token = strsep(&ps, deliml); |
| if (!token) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| if (n == 0 || !hdr289lut) { |
| kfree(buf_orig); |
| kfree(hdr289lut); |
| return -EINVAL; |
| } |
| memset(hdr289lut, 0, 289 * sizeof(unsigned short)); |
| gamma_count = (strlen(parm[0]) + 2) / 3; |
| if (gamma_count > 289) |
| gamma_count = 289; |
| |
| for (i = 0; i < gamma_count; ++i) { |
| gamma[0] = parm[0][3 * i + 0]; |
| gamma[1] = parm[0][3 * i + 1]; |
| gamma[2] = parm[0][3 * i + 2]; |
| gamma[3] = '\0'; |
| if (kstrtol(gamma, 16, &val) < 0) { |
| kfree(buf_orig); |
| kfree(hdr289lut); |
| return -EINVAL; |
| } |
| hdr289lut[i] = val; |
| } |
| |
| for (i = 0; i < gamma_count; i++) |
| lut_289_mapping[i] = hdr289lut[i]; |
| |
| kfree(buf_orig); |
| kfree(hdr289lut); |
| return count; |
| } |
| |
| static ssize_t amvecm_set_post_matrix_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int val; |
| |
| pr_info("Usage:\n"); |
| pr_info("echo port > /sys/class/amvecm/matrix_set\n"); |
| pr_info("1 : vadj1 input\n"); |
| pr_info("2 : vadj2 input\n"); |
| pr_info("4 : osd2 input\n"); |
| pr_info("8 : postblend input\n"); |
| pr_info("16 : osd1 input\n"); |
| pr_info("33 : vadj1 output\n"); |
| pr_info("34 : vadj2 output\n"); |
| pr_info("36 : osd2 output\n"); |
| pr_info("40 : postblend output\n"); |
| pr_info("48: osd1 output\n"); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7) && |
| !is_meson_s4d_cpu() && !is_meson_s4_cpu()) { |
| val = READ_VPP_REG(VPP_PROBE_CTRL); |
| pr_info("current setting: %d\n", val & 0x3f); |
| } else { |
| val = READ_VPP_REG(VPP_MATRIX_CTRL); |
| pr_info("current setting: %d\n", (val >> 10) & 0x3f); |
| } |
| |
| return 0; |
| } |
| |
| static ssize_t amvecm_set_post_matrix_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int val, reg_val; |
| |
| if (kstrtoint(buf, 10, &val) < 0) |
| return -EINVAL; |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7) && |
| !is_meson_s4d_cpu() && !is_meson_s4_cpu()) { |
| reg_val = READ_VPP_REG(VPP_PROBE_CTRL); |
| reg_val = reg_val & 0xffffffc0; |
| reg_val |= 0x10000; |
| /* enable probe hit */ |
| reg_val = reg_val | (val & 0x3f); |
| |
| WRITE_VPP_REG(VPP_PROBE_CTRL, reg_val); |
| WRITE_VPP_REG(VPP_HI_COLOR, 0x80000000); |
| |
| pr_info("VPP_PROBE_CTRL is set\n"); |
| |
| } else { |
| reg_val = READ_VPP_REG(VPP_MATRIX_CTRL); |
| reg_val = reg_val & 0xffff03ff; |
| reg_val = reg_val | ((val & 0x3f) << 10); |
| |
| WRITE_VPP_REG(VPP_MATRIX_CTRL, reg_val); |
| |
| pr_info("VPP_MATRIX_CTRL is set\n"); |
| } |
| return count; |
| } |
| |
| static ssize_t amvecm_post_matrix_pos_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int val; |
| |
| pr_info("Usage:\n"); |
| pr_info("echo x y > /sys/class/amvecm/matrix_pos\n"); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7) && |
| !is_meson_s4d_cpu() && !is_meson_s4_cpu()) |
| val = READ_VPP_REG(VPP_PROBE_POS); |
| else |
| val = READ_VPP_REG(VPP_MATRIX_PROBE_POS); |
| pr_info("current position: %d %d\n", |
| (val >> 16) & 0x1fff, |
| (val >> 0) & 0x1fff); |
| return 0; |
| } |
| |
| static ssize_t amvecm_post_matrix_pos_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int val_x, val_y, reg_val; |
| char *buf_orig, *parm[2] = {NULL}; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (kstrtoint(parm[0], 10, &val_x) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| if (kstrtoint(parm[1], 10, &val_y) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| |
| val_x = val_x & 0x1fff; |
| val_y = val_y & 0x1fff; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7) && |
| !is_meson_s4d_cpu() && !is_meson_s4_cpu()) |
| reg_val = READ_VPP_REG(VPP_PROBE_POS); |
| else |
| reg_val = READ_VPP_REG(VPP_MATRIX_PROBE_POS); |
| reg_val = reg_val & 0xe000e000; |
| reg_val = reg_val | (val_x << 16) | val_y; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7) && |
| !is_meson_s4d_cpu() && !is_meson_s4_cpu()) |
| WRITE_VPP_REG(VPP_PROBE_POS, reg_val); |
| else |
| WRITE_VPP_REG(VPP_MATRIX_PROBE_POS, reg_val); |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_post_matrix_data_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int len = 0, val1 = 0, val2 = 0; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7) && |
| !is_meson_s4d_cpu() && !is_meson_s4_cpu()) |
| val1 = READ_VPP_REG(VPP_PROBE_COLOR); |
| else |
| val1 = READ_VPP_REG(VPP_MATRIX_PROBE_COLOR); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { |
| len += sprintf(buf + len, |
| "VPP_MATRIX_PROBE_COLOR %d, %d, %d\n", |
| (val1 >> 20) & 0x3ff, |
| (val1 >> 10) & 0x3ff, |
| (val1 >> 0) & 0x3ff); |
| } else { |
| val2 = READ_VPP_REG(VPP_MATRIX_PROBE_COLOR1); |
| len += sprintf(buf + len, |
| "VPP_MATRIX_PROBE_COLOR %x, %x, %x\n", |
| ((val2 & 0xf) << 8) | ((val1 >> 24) & 0xff), |
| (val1 >> 12) & 0xfff, val1 & 0xfff); |
| } |
| return len; |
| } |
| |
| static ssize_t amvecm_post_matrix_data_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_sr1_reg_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| unsigned int addr; |
| |
| addr = ((sr1_index + 0x3280) << 2) | 0xd0100000; |
| return sprintf(buf, "0x%x = 0x%x\n", |
| addr, sr1_ret_val[sr1_index]); |
| } |
| |
| static ssize_t amvecm_sr1_reg_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| unsigned int addr, off_addr = 0; |
| |
| r = sscanf(buf, "0x%x", &addr); |
| addr = (addr & 0xffff) >> 2; |
| if (r != 1 || addr > 0x32e4 || addr < 0x3280) |
| return -EINVAL; |
| off_addr = addr - 0x3280; |
| sr1_index = off_addr; |
| sr1_ret_val[off_addr] = sr1_reg_val[off_addr]; |
| |
| return count; |
| } |
| |
| static ssize_t amvecm_write_sr1_reg_val_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_write_sr1_reg_val_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| unsigned int val; |
| |
| r = sscanf(buf, "0x%x", &val); |
| if (r != 1) |
| return -EINVAL; |
| sr1_reg_val[sr1_index] = val; |
| |
| return count; |
| } |
| |
| static ssize_t amvecm_dump_reg_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| unsigned int addr; |
| unsigned int value; |
| unsigned int base_reg; |
| |
| base_reg = codecio_reg_start[CODECIO_VCBUS_BASE]; |
| |
| pr_info("----dump sharpness0 reg----\n"); |
| for (addr = 0x3200; |
| addr <= 0x3264; addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| if (is_meson_txl_cpu() || is_meson_txlx_cpu()) { |
| for (addr = 0x3265; |
| addr <= 0x3272; addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| } |
| if (is_meson_txlx_cpu()) { |
| for (addr = 0x3273; |
| addr <= 0x327f; addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| } |
| #endif |
| pr_info("----dump sharpness1 reg----\n"); |
| for (addr = (0x3200 + 0x80); |
| addr <= (0x3264 + 0x80); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| if (is_meson_txl_cpu() || is_meson_txlx_cpu()) { |
| for (addr = (0x3265 + 0x80); |
| addr <= (0x3272 + 0x80); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| } |
| if (is_meson_txlx_cpu()) { |
| for (addr = (0x3273 + 0x80); |
| addr <= (0x327f + 0x80); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| } |
| #endif |
| pr_info("----dump cm reg----\n"); |
| for (addr = 0x200; addr <= 0x21e; addr++) { |
| WRITE_VPP_REG_EX(VPP_CHROMA_ADDR_PORT, addr, 0); |
| value = READ_VPP_REG_EX(VPP_CHROMA_DATA_PORT, 0); |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| addr, addr, |
| value); |
| } |
| for (addr = 0x100; addr <= 0x1fc; addr++) { |
| WRITE_VPP_REG_EX(VPP_CHROMA_ADDR_PORT, addr, 0); |
| value = READ_VPP_REG_EX(VPP_CHROMA_DATA_PORT, 0); |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| addr, addr, |
| value); |
| } |
| |
| pr_info("----dump vd1 IF0 reg----\n"); |
| for (addr = (0x1a50); |
| addr <= (0x1a69); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump vpp1 part1 reg----\n"); |
| for (addr = (0x1d00); |
| addr <= (0x1d6e); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| |
| pr_info("----dump vpp1 part2 reg----\n"); |
| for (addr = (0x1d72); |
| addr <= (0x1de4); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| |
| pr_info("----dump ndr reg----\n"); |
| for (addr = (0x2d00); |
| addr <= (0x2d78); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump nr3 reg----\n"); |
| for (addr = (0x2ff0); |
| addr <= (0x2ff6); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump vlock reg----\n"); |
| for (addr = (0x3000); |
| addr <= (0x3020); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump super scaler0 reg----\n"); |
| for (addr = (0x3100); |
| addr <= (0x3115); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump super scaler1 reg----\n"); |
| for (addr = (0x3118); |
| addr <= (0x312e); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump xvycc reg----\n"); |
| for (addr = (0x3158); |
| addr <= (0x3179); addr++) |
| pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", |
| (base_reg + (addr << 2)), addr, |
| READ_VPP_REG_EX(addr, 0)); |
| pr_info("----dump reg done----\n"); |
| return 0; |
| } |
| |
| static ssize_t amvecm_dump_reg_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_dump_vpp_hist_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| vpp_dump_histgram(); |
| return 0; |
| } |
| |
| static ssize_t amvecm_dump_vpp_hist_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_hdr_dbg_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int ret; |
| |
| ret = amvecm_hdr_dbg(0); |
| |
| return 0; |
| } |
| |
| static ssize_t amvecm_hdr_dbg_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| long val = 0; |
| char *buf_orig, *parm[5] = {NULL}; |
| int i; |
| int curve_val[65] = {0}; |
| char *stemp = NULL; |
| |
| if (!buf) |
| return count; |
| |
| stemp = kzalloc(400, GFP_KERNEL); |
| if (!stemp) |
| return 0; |
| |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) { |
| kfree(stemp); |
| return -ENOMEM; |
| } |
| |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (!strncmp(parm[0], "hdr_dbg", 7)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| debug_hdr = val; |
| pr_info("debug_hdr=0x%x\n", debug_hdr); |
| } else if (!strncmp(parm[0], "hdr10_pr", 8)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| hdr10_pr = val; |
| pr_info("hdr10_pr=0x%x\n", hdr10_pr); |
| } else if (!strncmp(parm[0], "clip_disable", 12)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| hdr10_clip_disable = val; |
| pr_info("hdr10_clip_disable=0x%x\n", |
| hdr10_clip_disable); |
| } else if (!strncmp(parm[0], "clip_luma", 9)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| hdr10_clip_luma = val; |
| pr_info("clip_luma=0x%x\n", hdr10_clip_luma); |
| } else if (!strncmp(parm[0], "clip_margin", 11)) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| hdr10_clip_margin = val; |
| pr_info("hdr10_clip_margin=0x%x\n", hdr10_clip_margin); |
| } else if (!strncmp(parm[0], "hdr_sdr_ootf", 12)) { |
| for (i = 0; i < HDR2_OOTF_LUT_SIZE; i++) { |
| pr_info("%d ", oo_y_lut_hdr_sdr_def[i]); |
| if ((i + 1) % 10 == 0) |
| pr_info("\n"); |
| } |
| pr_info("\n"); |
| } else if (!strncmp(parm[0], "cgain_lut", 9)) { |
| if (!strncmp(parm[1], "rv", 2)) { |
| for (i = 0; i < 65; i++) |
| d_convert_str(cgain_lut_bypass[i], |
| i, stemp, 4, 10); |
| pr_info("%s\n", stemp); |
| } else if (!strncmp(parm[1], "wv", 2)) { |
| str_sapr_to_d(parm[2], curve_val, 5); |
| for (i = 0; i < 65; i++) |
| cgain_lut_bypass[i] = curve_val[i]; |
| } |
| } |
| |
| hdr10_tmo_dbg(parm); |
| |
| free_buf: |
| kfree(stemp); |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_hdr_reg_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int ret; |
| |
| ret = amvecm_hdr_dbg(1); |
| |
| return 0; |
| } |
| |
| static ssize_t amvecm_hdr_reg_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_hdr_tmo_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| hdr10_tmo_parm_show(); |
| return 0; |
| } |
| |
| static ssize_t amvecm_hdr_tmo_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_pc_mode_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| pr_info("pc:echo 0x0 > /sys/class/amvecm/pc_mode\n"); |
| pr_info("other:echo 0x1 > /sys/class/amvecm/pc_mode\n"); |
| pr_info("pc_mode:%d,pc_mode_last:%d\n", pc_mode, pc_mode_last); |
| return 0; |
| } |
| |
| static ssize_t amvecm_pc_mode_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%x\n", &val); |
| if (r != 1) |
| return -EINVAL; |
| |
| if (!pq_load_en) |
| return count; |
| |
| if (val == 1) { |
| pc_mode = 1; |
| pc_mode_last = 0xff; |
| } else if (val == 0) { |
| pc_mode = 0; |
| pc_mode_last = 0xff; |
| } |
| |
| return count; |
| } |
| |
| void pc_mode_process(void) |
| { |
| unsigned int reg_val, drtlpf_config; |
| |
| if (pc_mode == 1 && pc_mode != pc_mode_last) { |
| /* open dnlp clock gate */ |
| lc_en = pq_cfg.lc_en; |
| dnlp_en = pq_cfg.dnlp_en; |
| if (dnlp_en) |
| ve_enable_dnlp(); |
| else |
| ve_disable_dnlp(); |
| cm_en = pq_cfg.cm_en; |
| |
| /* sharpness on */ |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| pq_cfg.sharpness0_en, 1, 1); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| pq_cfg.sharpness1_en, 1, 1); |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_HCTI_FLT_CLP_DC); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_HCTI_FLT_CLP_DC, |
| reg_val | (pq_cfg.sharpness0_en << 28)); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_HCTI_FLT_CLP_DC, |
| reg_val | (pq_cfg.sharpness1_en << 28)); |
| |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_HLTI_FLT_CLP_DC); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_HLTI_FLT_CLP_DC, |
| reg_val | (pq_cfg.sharpness0_en << 28)); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_HLTI_FLT_CLP_DC, |
| reg_val | (pq_cfg.sharpness1_en << 28)); |
| |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_VLTI_FLT_CON_CLP); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_VLTI_FLT_CON_CLP, |
| reg_val | (pq_cfg.sharpness0_en << 14)); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_VLTI_FLT_CON_CLP, |
| reg_val | (pq_cfg.sharpness1_en << 14)); |
| |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_VCTI_FLT_CON_CLP); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_VCTI_FLT_CON_CLP, |
| reg_val | (pq_cfg.sharpness0_en << 14)); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_VCTI_FLT_CON_CLP, |
| reg_val | (pq_cfg.sharpness1_en << 14)); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| pq_cfg.sharpness0_en, 0, 1); |
| drtlpf_config = pq_cfg.sharpness0_en ? 0x7 : 0x0; |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| drtlpf_config, 0, 3); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| pq_cfg.sharpness0_en, 28, 3); |
| |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| pq_cfg.sharpness1_en, 0, 1); |
| drtlpf_config = pq_cfg.sharpness1_en ? 0x7 : 0x0; |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| drtlpf_config, 0, 3); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| pq_cfg.sharpness1_en, 28, 3); |
| } |
| |
| pc_mode_last = pc_mode; |
| } else if ((pc_mode == 0) && (pc_mode != pc_mode_last)) { |
| dnlp_en = 0; |
| lc_en = 0; |
| ve_disable_dnlp(); |
| cm_en = 0; |
| |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 0, 1, 1); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 0, 1, 1); |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_HCTI_FLT_CLP_DC); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_HCTI_FLT_CLP_DC, |
| reg_val & 0xefffffff); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_HCTI_FLT_CLP_DC, |
| reg_val & 0xefffffff); |
| |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_HLTI_FLT_CLP_DC); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_HLTI_FLT_CLP_DC, |
| reg_val & 0xefffffff); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_HLTI_FLT_CLP_DC, |
| reg_val & 0xefffffff); |
| |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_VLTI_FLT_CON_CLP); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_VLTI_FLT_CON_CLP, |
| reg_val & 0xffffbfff); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_VLTI_FLT_CON_CLP, |
| reg_val & 0xffffbfff); |
| |
| reg_val = VSYNC_READ_VPP_REG(SRSHARP0_VCTI_FLT_CON_CLP); |
| VSYNC_WRITE_VPP_REG(SRSHARP0_VCTI_FLT_CON_CLP, |
| reg_val & 0xffffbfff); |
| VSYNC_WRITE_VPP_REG(SRSHARP1_VCTI_FLT_CON_CLP, |
| reg_val & 0xffffbfff); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 0, 0, 1); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 0, 0, 3); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| 0, 28, 3); |
| |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 0, 0, 1); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 0, 0, 3); |
| VSYNC_WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| 0, 28, 3); |
| } |
| |
| pc_mode_last = pc_mode; |
| } |
| } |
| |
| void amvecm_black_ext_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 1, 3, 1); |
| else |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 3, 1); |
| } |
| |
| void amvecm_black_ext_start_adj(unsigned int value) |
| { |
| if (value > 255) |
| return; |
| WRITE_VPP_REG_BITS(VPP_BLACKEXT_CTRL, value, 24, 8); |
| } |
| |
| void amvecm_black_ext_slope_adj(unsigned int value) |
| { |
| if (value > 255) |
| return; |
| WRITE_VPP_REG_BITS(VPP_BLACKEXT_CTRL, value, 16, 8); |
| } |
| |
| void amvecm_sr0_pk_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 1, 1, 1); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 0, 1, 1); |
| } |
| |
| void amvecm_sr1_pk_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 1, 1, 1); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 0, 1, 1); |
| } |
| |
| void amvecm_sr0_dering_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| 1, 28, 3); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| 0, 28, 3); |
| } |
| |
| void amvecm_sr1_dering_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| 1, 28, 3); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| 0, 28, 3); |
| } |
| |
| void amvecm_sr0_dejaggy_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 1, 0, 1); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 0, 0, 1); |
| } |
| |
| void amvecm_sr1_dejaggy_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 1, 0, 1); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 0, 0, 1); |
| } |
| |
| void amvecm_sr0_derection_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 7, 0, 3); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 0, 0, 3); |
| } |
| |
| void amvecm_sr1_derection_enable(unsigned int enable) |
| { |
| if (enable) |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 7, 0, 3); |
| else |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 0, 0, 3); |
| } |
| |
| void pq_user_latch_process(void) |
| { |
| int i = 0; |
| int sat_hue_val = 0; |
| int input_clr_md = 0; |
| int cm_color_md_max = cm_14_ecm2colormd_max; |
| struct cm_color_md cm_clr_md; |
| |
| if (pq_user_latch_flag & PQ_USER_BLK_EN) { |
| pq_user_latch_flag &= ~PQ_USER_BLK_EN; |
| amvecm_black_ext_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_BLK_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_BLK_DIS; |
| amvecm_black_ext_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_BLK_START) { |
| pq_user_latch_flag &= ~PQ_USER_BLK_START; |
| amvecm_black_ext_start_adj(pq_user_value); |
| } else if (pq_user_latch_flag & PQ_USER_BLK_SLOPE) { |
| pq_user_latch_flag &= ~PQ_USER_BLK_SLOPE; |
| amvecm_black_ext_slope_adj(pq_user_value); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_PK_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_PK_EN; |
| amvecm_sr0_pk_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_PK_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_PK_DIS; |
| amvecm_sr0_pk_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_PK_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_PK_EN; |
| amvecm_sr1_pk_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_PK_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_PK_DIS; |
| amvecm_sr1_pk_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_DERING_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_DERING_EN; |
| amvecm_sr0_dering_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_DERING_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_DERING_DIS; |
| amvecm_sr0_dering_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_DERING_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_DERING_EN; |
| amvecm_sr1_dering_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_DERING_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_DERING_DIS; |
| amvecm_sr1_dering_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_DEJAGGY_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_DEJAGGY_EN; |
| amvecm_sr0_dejaggy_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_DEJAGGY_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_DEJAGGY_DIS; |
| amvecm_sr0_dejaggy_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_DEJAGGY_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_DEJAGGY_EN; |
| amvecm_sr1_dejaggy_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_DEJAGGY_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_DEJAGGY_DIS; |
| amvecm_sr1_dejaggy_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_DERECTION_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_DERECTION_EN; |
| amvecm_sr0_derection_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR0_DERECTION_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR0_DERECTION_DIS; |
| amvecm_sr0_derection_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_DERECTION_EN) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_DERECTION_EN; |
| amvecm_sr1_derection_enable(true); |
| } else if (pq_user_latch_flag & PQ_USER_SR1_DERECTION_DIS) { |
| pq_user_latch_flag &= ~PQ_USER_SR1_DERECTION_DIS; |
| amvecm_sr1_derection_enable(false); |
| } else if (pq_user_latch_flag & PQ_USER_CMS_CURVE_SAT || |
| pq_user_latch_flag & PQ_USER_CMS_CURVE_LUMA || |
| pq_user_latch_flag & PQ_USER_CMS_CURVE_HUE_HS || |
| pq_user_latch_flag & PQ_USER_CMS_CURVE_HUE) { |
| if (cm_cur_work_color_md == cm_9_color) { |
| cm_color_md_max = ecm2colormd_max; |
| cm_clr_md.color_type = cm_9_color; |
| cm_clr_md.cm_9_color_md = ecm2colormd_purple; |
| cm_clr_md.cm_14_color_md = cm_14_ecm2colormd_max; |
| cm_clr_md.color_value = 0; |
| } else { |
| cm_color_md_max = cm_14_ecm2colormd_max; |
| cm_clr_md.color_type = cm_14_color; |
| cm_clr_md.cm_9_color_md = ecm2colormd_max; |
| cm_clr_md.cm_14_color_md = |
| cm_14_ecm2colormd_blue_purple; |
| cm_clr_md.color_value = 0; |
| } |
| |
| if (cm2_debug) { |
| pr_info("cm_color_md_max:%d\n", |
| cm_color_md_max); |
| pr_info("color_type:%d\n", |
| cm_clr_md.color_type); |
| pr_info("cm_9_color_md:%d\n", |
| cm_clr_md.cm_9_color_md); |
| pr_info("cm_14_color_md:%d\n", |
| cm_clr_md.cm_14_color_md); |
| pr_info("color_value:%d\n", |
| cm_clr_md.color_value); |
| } |
| if (pq_user_latch_flag & PQ_USER_CMS_CURVE_SAT) { |
| pq_user_latch_flag &= ~PQ_USER_CMS_CURVE_SAT; |
| input_clr_md = 0; |
| for (i = 0; i < cm_color_md_max; i++) { |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_clr_md.cm_9_color_md = input_clr_md; |
| else |
| cm_clr_md.cm_14_color_md = input_clr_md; |
| |
| input_clr_md++; |
| if (cm2_sat_array[i][2] == 1) { |
| cm2_curve_update_sat(cm_clr_md); |
| cm2_sat_array[i][2] = 0; |
| } |
| } |
| } |
| if (pq_user_latch_flag & PQ_USER_CMS_CURVE_LUMA) { |
| pq_user_latch_flag &= ~PQ_USER_CMS_CURVE_LUMA; |
| input_clr_md = 0; |
| for (i = 0; i < cm_color_md_max; i++) { |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_clr_md.cm_9_color_md = input_clr_md; |
| else |
| cm_clr_md.cm_14_color_md = input_clr_md; |
| |
| input_clr_md++; |
| if (cm2_luma_array[i][2] == 1) { |
| cm2_curve_update_luma(cm_clr_md); |
| cm2_luma_array[i][2] = 0; |
| } |
| } |
| } |
| if (pq_user_latch_flag & PQ_USER_CMS_CURVE_HUE_HS) { |
| pq_user_latch_flag &= ~PQ_USER_CMS_CURVE_HUE_HS; |
| input_clr_md = 0; |
| for (i = 0; i < cm_color_md_max; i++) { |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_clr_md.cm_9_color_md = input_clr_md; |
| else |
| cm_clr_md.cm_14_color_md = input_clr_md; |
| |
| input_clr_md++; |
| if (cm2_hue_by_hs_array[i][2] == 1) { |
| cm2_curve_update_hue_by_hs(cm_clr_md); |
| cm2_hue_by_hs_array[i][2] = 0; |
| } |
| } |
| } |
| if (pq_user_latch_flag & PQ_USER_CMS_CURVE_HUE) { |
| pq_user_latch_flag &= ~PQ_USER_CMS_CURVE_HUE; |
| input_clr_md = 0; |
| for (i = 0; i < cm_color_md_max; i++) { |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_clr_md.cm_9_color_md = input_clr_md; |
| else |
| cm_clr_md.cm_14_color_md = input_clr_md; |
| |
| input_clr_md++; |
| if (cm2_hue_array[i][2] == 1) { |
| cm2_curve_update_hue(cm_clr_md); |
| cm2_hue_array[i][2] = 0; |
| } |
| } |
| } |
| } else if (pq_user_latch_flag & PQ_USER_CMS_SAT_HUE) { |
| pq_user_latch_flag &= ~PQ_USER_CMS_SAT_HUE; |
| sat_hue_val = |
| aipq_saturation_hue_get_base_val() + sat_hue_offset_val; |
| /* ai_pq switch on, */ |
| /* if satuaration val(sat_hue_val >> 16) > max val(511), */ |
| /* saturation val can not add sat offset val. */ |
| if ((sat_hue_val >> 16) > 511) |
| sat_hue_val = aipq_saturation_hue_get_base_val(); |
| |
| amvecm_set_saturation_hue(sat_hue_val); |
| } |
| } |
| |
| static const char *amvecm_pq_user_usage_str = { |
| "Usage:\n" |
| "echo blk_ext_en > /sys/class/amvecm/pq_user_set: blk ext en\n" |
| "echo blk_ext_dis > /sys/class/amvecm/pq_user_set: blk ext dis\n" |
| "echo blk_start val > /sys/class/amvecm/pq_user_set: start adj\n" |
| "echo blk_slope val > /sys/class/amvecm/pq_user_set: slope adj\n" |
| "echo sr0_pk_en > /sys/class/amvecm/pq_user_set: sr0 pk en\n" |
| "echo sr0_pk_dis > /sys/class/amvecm/pq_user_set: sr0 pk dis\n" |
| "echo sr1_pk_en > /sys/class/amvecm/pq_user_set: sr0 pk en\n" |
| "echo sr1_pk_dis > /sys/class/amvecm/pq_user_set: sr0 pk dis\n" |
| "echo sr0_dering_en > /sys/class/amvecm/pq_user_set: sr0 dr en\n" |
| "echo sr0_dering_dis > /sys/class/amvecm/pq_user_set: sr0 dr dis\n" |
| "echo sr1_dering_en > /sys/class/amvecm/pq_user_set: sr1 dr en\n" |
| "echo sr1_dering_dis > /sys/class/amvecm/pq_user_set: sr1 dr dis\n" |
| "echo sr0_dejaggy_en > /sys/class/amvecm/pq_user_set: sr0 dj en\n" |
| "echo sr0_dejaggy_dis > /sys/class/amvecm/pq_user_set: sr0 dj dis\n" |
| "echo sr1_dejaggy_en > /sys/class/amvecm/pq_user_set: sr1 dj en\n" |
| "echo sr1_dejaggy_dis > /sys/class/amvecm/pq_user_set: sr1 dj dis\n" |
| "echo sr0_derec_en > /sys/class/amvecm/pq_user_set: sr0 drec en\n" |
| "echo sr0_derec_dis > /sys/class/amvecm/pq_user_set: sr0 drec dis\n" |
| "echo sr1_derec_en > /sys/class/amvecm/pq_user_set: sr1 drec en\n" |
| "echo sr1_derec_dis > /sys/class/amvecm/pq_user_set: sr1 drec dis\n" |
| |
| }; |
| |
| static ssize_t amvecm_pq_user_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| return sprintf(buf, "%s\n", amvecm_pq_user_usage_str); |
| } |
| |
| static ssize_t amvecm_pq_user_store(struct class *cla, |
| 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); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (!strncmp(parm[0], "blk_ext_en", 10)) { |
| pq_user_latch_flag |= PQ_USER_BLK_EN; |
| } else if (!strncmp(parm[0], "blk_ext_dis", 11)) { |
| pq_user_latch_flag |= PQ_USER_BLK_DIS; |
| } else if (!strncmp(parm[0], "blk_start", 9)) { |
| if (kstrtoul(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| pq_user_value = val; |
| pq_user_latch_flag |= PQ_USER_BLK_START; |
| } else if (!strncmp(parm[0], "blk_slope", 9)) { |
| if (kstrtoul(parm[1], 10, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| pq_user_value = val; |
| pq_user_latch_flag |= PQ_USER_BLK_SLOPE; |
| } else if (!strncmp(parm[0], "sr0_pk_en", 9)) { |
| pq_user_latch_flag |= PQ_USER_SR0_PK_EN; |
| } else if (!strncmp(parm[0], "sr0_pk_dis", 10)) { |
| pq_user_latch_flag |= PQ_USER_SR0_PK_DIS; |
| } else if (!strncmp(parm[0], "sr1_pk_en", 9)) { |
| pq_user_latch_flag |= PQ_USER_SR1_PK_EN; |
| } else if (!strncmp(parm[0], "sr1_pk_dis", 10)) { |
| pq_user_latch_flag |= PQ_USER_SR1_PK_DIS; |
| } else if (!strncmp(parm[0], "sr0_dering_en", 13)) { |
| pq_user_latch_flag |= PQ_USER_SR0_DERING_EN; |
| } else if (!strncmp(parm[0], "sr0_dering_dis", 14)) { |
| pq_user_latch_flag |= PQ_USER_SR0_DERING_DIS; |
| } else if (!strncmp(parm[0], "sr1_dering_en", 13)) { |
| pq_user_latch_flag |= PQ_USER_SR1_DERING_EN; |
| } else if (!strncmp(parm[0], "sr1_dering_dis", 14)) { |
| pq_user_latch_flag |= PQ_USER_SR1_DERING_DIS; |
| } else if (!strncmp(parm[0], "sr0_dejaggy_en", 14)) { |
| pq_user_latch_flag |= PQ_USER_SR0_DEJAGGY_EN; |
| } else if (!strncmp(parm[0], "sr0_dejaggy_dis", 15)) { |
| pq_user_latch_flag |= PQ_USER_SR0_DEJAGGY_DIS; |
| } else if (!strncmp(parm[0], "sr1_dejaggy_en", 14)) { |
| pq_user_latch_flag |= PQ_USER_SR1_DEJAGGY_EN; |
| } else if (!strncmp(parm[0], "sr1_dejaggy_dis", 15)) { |
| pq_user_latch_flag |= PQ_USER_SR1_DEJAGGY_DIS; |
| } else if (!strncmp(parm[0], "sr0_derec_en", 12)) { |
| pq_user_latch_flag |= PQ_USER_SR0_DERECTION_EN; |
| } else if (!strncmp(parm[0], "sr0_derec_dis", 13)) { |
| pq_user_latch_flag |= PQ_USER_SR0_DERECTION_DIS; |
| } else if (!strncmp(parm[0], "sr1_derec_en", 12)) { |
| pq_user_latch_flag |= PQ_USER_SR1_DERECTION_EN; |
| } else if (!strncmp(parm[0], "sr1_derec_dis", 13)) { |
| pq_user_latch_flag |= PQ_USER_SR1_DERECTION_DIS; |
| } |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static const char *dnlp_insmod_debug_usage_str = { |
| "usage: echo 1 > /sys/class/amvecm/dnlp_insmod\n" |
| }; |
| |
| static ssize_t amvecm_dnlp_insmod_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| return sprintf(buf, "%s\n", dnlp_insmod_debug_usage_str); |
| } |
| |
| static ssize_t amvecm_dnlp_insmod_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%x\n", &val); |
| if (r != 1) |
| return -EINVAL; |
| |
| if (val == 1) |
| dnlp_alg_param_init(); |
| |
| return count; |
| } |
| |
| static ssize_t amvecm_vpp_demo_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return 0; |
| } |
| |
| static ssize_t amvecm_vpp_demo_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| int val; |
| |
| r = sscanf(buf, "%x\n", &val); |
| if (r != 1) |
| return -EINVAL; |
| |
| if (val & VPP_DEMO_CM_EN) |
| vecm_latch_flag2 |= VPP_DEMO_CM_EN; |
| else if (val & VPP_DEMO_CM_DIS) |
| vecm_latch_flag2 |= VPP_DEMO_CM_DIS; |
| |
| if (val & VPP_DEMO_DNLP_EN) |
| vecm_latch_flag2 |= VPP_DEMO_DNLP_EN; |
| else if (val & VPP_DEMO_DNLP_DIS) |
| vecm_latch_flag2 |= VPP_DEMO_DNLP_DIS; |
| |
| return count; |
| } |
| |
| static void dump_vpp_size_info(void) |
| { |
| unsigned int vpp_input_h, vpp_input_v, |
| pps_input_length, pps_input_height, |
| pps_output_hs, pps_output_he, pps_output_vs, pps_output_ve, |
| vd1_preblend_hs, vd1_preblend_he, |
| vd1_preblend_vs, vd1_preblend_ve, |
| vd2_preblend_hs, vd2_preblend_he, |
| vd2_preblend_vs, vd2_preblend_ve, |
| prelend_input_hsize, |
| vd1_postblend_hs, vd1_postblend_he, |
| vd1_postblend_vs, vd1_postblend_ve, |
| postblend_hsize, |
| ve_hsize, ve_vsize, psr_hsize, psr_vsize, |
| cm_hsize, cm_vsize; |
| vpp_input_h = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 16, 13); |
| vpp_input_v = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 0, 13); |
| pps_input_length = READ_VPP_REG_BITS(VPP_LINE_IN_LENGTH, 0, 13); |
| pps_input_height = READ_VPP_REG_BITS(VPP_PIC_IN_HEIGHT, 0, 13); |
| pps_output_hs = READ_VPP_REG_BITS(VPP_HSC_REGION12_STARTP, 16, 13); |
| pps_output_he = READ_VPP_REG_BITS(VPP_HSC_REGION4_ENDP, 0, 13); |
| pps_output_vs = READ_VPP_REG_BITS(VPP_VSC_REGION12_STARTP, 16, 13); |
| pps_output_ve = READ_VPP_REG_BITS(VPP_VSC_REGION4_ENDP, 0, 13); |
| vd1_preblend_he = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_H_START_END, |
| 0, 13); |
| vd1_preblend_hs = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_H_START_END, |
| 16, 13); |
| vd1_preblend_ve = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_V_START_END, |
| 0, 13); |
| vd1_preblend_vs = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_V_START_END, |
| 16, 13); |
| vd2_preblend_he = READ_VPP_REG_BITS(VPP_BLEND_VD2_H_START_END, 0, 13); |
| vd2_preblend_hs = READ_VPP_REG_BITS(VPP_BLEND_VD2_H_START_END, 16, 13); |
| vd2_preblend_ve = READ_VPP_REG_BITS(VPP_BLEND_VD2_V_START_END, 0, 13); |
| vd2_preblend_vs = READ_VPP_REG_BITS(VPP_BLEND_VD2_V_START_END, 16, 13); |
| prelend_input_hsize = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 0, 13); |
| vd1_postblend_he = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END, |
| 0, 13); |
| vd1_postblend_hs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END, |
| 16, 13); |
| vd1_postblend_ve = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END, |
| 0, 13); |
| vd1_postblend_vs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END, |
| 16, 13); |
| postblend_hsize = READ_VPP_REG_BITS(VPP_POSTBLEND_H_SIZE, 0, 13); |
| ve_hsize = READ_VPP_REG_BITS(VPP_VE_H_V_SIZE, 16, 13); |
| ve_vsize = READ_VPP_REG_BITS(VPP_VE_H_V_SIZE, 0, 13); |
| psr_hsize = READ_VPP_REG_BITS(VPP_PSR_H_V_SIZE, 16, 13); |
| psr_vsize = READ_VPP_REG_BITS(VPP_PSR_H_V_SIZE, 0, 13); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, 0x205); |
| cm_hsize = READ_VPP_REG(VPP_CHROMA_DATA_PORT); |
| cm_vsize = (cm_hsize >> 16) & 0xffff; |
| cm_hsize = cm_hsize & 0xffff; |
| pr_info("\n vpp size info:\n"); |
| pr_info("vpp_input_h:%d, vpp_input_v:%d\n" |
| "pps_input_length:%d, pps_input_height:%d\n" |
| "pps_output_hs:%d, pps_output_he:%d\n" |
| "pps_output_vs:%d, pps_output_ve:%d\n" |
| "vd1_preblend_hs:%d, vd1_preblend_he:%d\n" |
| "vd1_preblend_vs:%d, vd1_preblend_ve:%d\n" |
| "vd2_preblend_hs:%d, vd2_preblend_he:%d\n" |
| "vd2_preblend_vs:%d, vd2_preblend_ve:%d\n" |
| "prelend_input_hsize:%d\n" |
| "vd1_postblend_hs:%d, vd1_postblend_he:%d\n" |
| "vd1_postblend_vs:%d, vd1_postblend_ve:%d\n" |
| "postblend_hsize:%d\n" |
| "ve_hsize:%d, ve_vsize:%d\n" |
| "psr_hsize:%d, psr_vsize:%d\n" |
| "cm_hsize:%d, cm_vsize:%d\n", |
| vpp_input_h, vpp_input_v, |
| pps_input_length, pps_input_height, |
| pps_output_hs, pps_output_he, |
| pps_output_vs, pps_output_ve, |
| vd1_preblend_hs, vd1_preblend_he, |
| vd1_preblend_vs, vd1_preblend_ve, |
| vd2_preblend_hs, vd2_preblend_he, |
| vd2_preblend_vs, vd2_preblend_ve, |
| prelend_input_hsize, |
| vd1_postblend_hs, vd1_postblend_he, |
| vd1_postblend_vs, vd1_postblend_ve, |
| postblend_hsize, |
| ve_hsize, ve_vsize, |
| psr_hsize, psr_vsize, |
| cm_hsize, cm_vsize); |
| } |
| |
| void amvecm_sharpness_enable(int sel) |
| { |
| /*0:peaking enable 1:peaking disable*/ |
| /*2:lti/cti enable 3:lti/cti disable*/ |
| switch (sel) { |
| case 0: |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 1, 1, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 1, 1, 1); |
| break; |
| case 1: |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 0, 1, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 0, 1, 1); |
| break; |
| case 2: |
| WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP, |
| 1, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP, |
| 1, 14, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP, |
| 1, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP, |
| 1, 14, 1); |
| break; |
| case 3: |
| WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP, |
| 0, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP, |
| 0, 14, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP, |
| 0, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP, |
| 0, 14, 1); |
| break; |
| /*sr4 drtlpf theta en*/ |
| case 4: |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 7, 4, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 7, 3, 3); |
| break; |
| case 5: |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 0, 4, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 0, 3, 3); |
| break; |
| /*sr4 debanding en*/ |
| case 6: |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 23, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 23, 1); |
| break; |
| case 7: |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 23, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 23, 1); |
| break; |
| /*sr3 dejaggy en*/ |
| case 8: |
| WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 1, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 1, 0, 1); |
| break; |
| case 9: |
| WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 0, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 0, 0, 1); |
| break; |
| /*sr3 dering en*/ |
| case 10: |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| 1, 28, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| 1, 28, 3); |
| break; |
| case 11: |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| 0, 28, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| 0, 28, 3); |
| break; |
| /*sr3 derection lpf en*/ |
| case 12: |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 7, 0, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 7, 0, 3); |
| break; |
| case 13: |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 0, 0, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 0, 0, 3); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| void amvecm_sr_demo(int enable) |
| { |
| if (enable) { |
| sr_demo_flag = 1; |
| WRITE_VPP_REG_BITS(SRSHARP0_DEMO_CRTL, 2, 17, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_DEMO_CRTL, 1, 16, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DEMO_CRTL, 0x438, 0, 13); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEMO_CRTL, 2, 17, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEMO_CRTL, 1, 16, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEMO_CRTL, 0x438, 0, 13); |
| |
| } else { |
| sr_demo_flag = 0; |
| WRITE_VPP_REG_BITS(SRSHARP0_DEMO_CRTL, 2, 17, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_DEMO_CRTL, 0, 16, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DEMO_CRTL, 0x438, 0, 13); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEMO_CRTL, 2, 17, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEMO_CRTL, 0, 16, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DEMO_CRTL, 0x438, 0, 13); |
| } |
| } |
| |
| void amvecm_clip_range_limit(bool limit_en) |
| { |
| /*fix mbox av out flicker black dot*/ |
| if (limit_en) { |
| /*cvbs output 16-235 16-240 16-240*/ |
| WRITE_VPP_REG(VPP_CLIP_MISC0, 0x3acf03c0); |
| WRITE_VPP_REG(VPP_CLIP_MISC1, 0x4010040); |
| } else { |
| /*retore for other mode*/ |
| WRITE_VPP_REG(VPP_CLIP_MISC0, 0x3fffffff); |
| WRITE_VPP_REG(VPP_CLIP_MISC1, 0x0); |
| } |
| } |
| EXPORT_SYMBOL(amvecm_clip_range_limit); |
| |
| static void amvecm_pq_enable(int enable) |
| { |
| if (enable) { |
| lc_en = 1; |
| /* black_ext_en */ |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 1, 3, 1); |
| /* chroma_coring */ |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 1, 4, 1); |
| ve_enable_dnlp(); |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (!is_dolby_vision_enable()) |
| #endif |
| amcm_enable(); |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 1, 1, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 1, 1, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP, |
| 1, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP, |
| 1, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC, |
| 1, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP, |
| 1, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP, |
| 1, 14, 1); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { |
| WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 1, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 7, 0, 3); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL, |
| 1, 28, 3); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 1, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN, |
| 7, 0, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL, |
| 1, 28, 3); |
| } |
| /*sr4 drtlpf theta/ debanding en*/ |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN, |
| 7, 4, 3); |
| |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 1, 23, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 1, 23, 1); |
| } |
| #endif |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_DRTLPF_EN, |
| 0x3f, 0, 6); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_DRTLPF_EN, |
| 0x7, 8, 3); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_PKDRT_BLD_EN, |
| 1, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_TIBLD_PRT, |
| 3, 2, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_TIBLD_PRT, |
| 3, 12, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_XTI_SDFDEN, |
| 3, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_TI_BPF_EN, |
| 0xf, 0, 4); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_PKLONG_PF_EN, |
| 3, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_CC_PK_ADJ, |
| 1, 24, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_GRAPHIC_CTRL, |
| 1, 10, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_DRTLPF_EN, |
| 0x3f, 0, 6); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_DRTLPF_EN, |
| 0x7, 8, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_PKDRT_BLD_EN, |
| 1, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_TIBLD_PRT, |
| 3, 2, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_TIBLD_PRT, |
| 3, 12, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_XTI_SDFDEN, |
| 3, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_TI_BPF_EN, |
| 0xf, 0, 4); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_PKLONG_PF_EN, |
| 3, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_CC_PK_ADJ, |
| 1, 24, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_GRAPHIC_CTRL, |
| 1, 10, 1); |
| } |
| |
| white_balance_adjust(0, 1); |
| |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_EN; |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1); |
| else |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1); |
| } else { |
| lc_en = 0; |
| /* black_ext_en */ |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 3, 1); |
| /* chroma_coring */ |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 4, 1); |
| ve_disable_dnlp(); |
| |
| amcm_disable(); |
| |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 0, 1, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 0, 1, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP, |
| 0, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP, |
| 0, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC, |
| 0, 28, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP, |
| 0, 14, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP, |
| 0, 14, 1); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { |
| WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL, |
| 0, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN |
| , 0, 0, 3); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL |
| , 0, 28, 3); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL, |
| 0, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN |
| , 0, 0, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL |
| , 0, 28, 3); |
| } |
| /*sr4 drtlpf theta/ debanding en*/ |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| if (is_meson_txlx_cpu()) { |
| WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN |
| , 0, 4, 3); |
| |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL, |
| 0, 23, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 4, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 5, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 22, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL, |
| 0, 23, 1); |
| } |
| #endif |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_DRTLPF_EN, |
| 0, 0, 6); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_DRTLPF_EN, |
| 0, 8, 3); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_PKDRT_BLD_EN, |
| 0, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_TIBLD_PRT, |
| 0, 2, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_TIBLD_PRT, |
| 0, 12, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_XTI_SDFDEN, |
| 0, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_TI_BPF_EN, |
| 0, 0, 4); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_PKLONG_PF_EN, |
| 0, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_CC_PK_ADJ, |
| 0, 24, 1); |
| WRITE_VPP_REG_BITS(SRSHARP0_SR7_GRAPHIC_CTRL, |
| 0, 10, 1); |
| |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_DRTLPF_EN, |
| 0, 0, 6); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_DRTLPF_EN, |
| 0, 8, 3); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_PKDRT_BLD_EN, |
| 0, 0, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_TIBLD_PRT, |
| 0, 2, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_TIBLD_PRT, |
| 0, 12, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_XTI_SDFDEN, |
| 0, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_TI_BPF_EN, |
| 0, 0, 4); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_PKLONG_PF_EN, |
| 0, 0, 2); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_CC_PK_ADJ, |
| 0, 24, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_SR7_GRAPHIC_CTRL, |
| 0, 10, 1); |
| } |
| |
| white_balance_adjust(0, 0); |
| |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS; |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 0, 0, 1); |
| else |
| WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 0, 0, 1); |
| } |
| } |
| |
| static void amvecm_dither_enable(int enable) |
| { |
| switch (enable) { |
| /*dither enable*/ |
| case 0:/*disable*/ |
| WRITE_VPP_REG_BITS(VPP_VE_DITHER_CTRL, 0, 0, 1); |
| break; |
| case 1:/*enable*/ |
| WRITE_VPP_REG_BITS(VPP_GAINOFF_CTRL0, 1, 0, 1); |
| break; |
| /*dither round enable*/ |
| case 2:/*disable*/ |
| WRITE_VPP_REG_BITS(VPP_VE_DITHER_CTRL, 0, 1, 1); |
| break; |
| case 3:/*enable*/ |
| WRITE_VPP_REG_BITS(VPP_VE_DITHER_CTRL, 1, 1, 1); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| static void amvecm_vpp_mtx_debug(int mtx_sel, int coef_sel) |
| { |
| if (mtx_sel & (1 << VPP_MATRIX_1)) { |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 5, 1); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 8, 3); |
| mtx_sel_dbg &= ~(1 << VPP_MATRIX_1); |
| } else if (mtx_sel & (1 << VPP_MATRIX_2)) { |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 0, 1); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 0, 8, 3); |
| mtx_sel_dbg &= ~(1 << VPP_MATRIX_2); |
| } else if (mtx_sel & (1 << VPP_MATRIX_3)) { |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 6, 1); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 3, 8, 3); |
| mtx_sel_dbg &= ~(1 << VPP_MATRIX_3); |
| } |
| /*coef_sel 1: 10bit yuvl2rgb 2:rgb2yuvl*/ |
| /*coef_sel 3: 12bit yuvl2rgb 4:rgb2yuvl*/ |
| if (coef_sel == 1) { |
| WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x04A80000); |
| WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x072C04A8); |
| WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1F261DDD); |
| WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x04A80876); |
| WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x0); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x0); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x0); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0xfc00e00); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0e00); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3); |
| } else if (coef_sel == 2) { |
| WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x00bb0275); |
| WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x003f1f99); |
| WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1ea601c2); |
| WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x01c21e67); |
| WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x00001fd7); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x00400200); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x00000200); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3); |
| } else if (coef_sel == 3) { |
| WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x04A80000); |
| WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x072C04A8); |
| WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1F261DDD); |
| WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x04A80876); |
| WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x0); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x8000800); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x800); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x7000000); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0000); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3); |
| } else if (coef_sel == 4) { |
| WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x00bb0275); |
| WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x003f1f99); |
| WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1ea601c2); |
| WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x01c21e67); |
| WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x00001fd7); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x01000000); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x00000000); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3); |
| } |
| } |
| |
| static void vpp_clip_config(unsigned int mode_sel, unsigned int color, |
| unsigned int color_mode) |
| { |
| unsigned int addr_cliptop, addr_clipbot, value_cliptop, value_clipbot; |
| |
| if (mode_sel == 0) {/*vd1*/ |
| addr_cliptop = VPP_VD1_CLIP_MISC0; |
| addr_clipbot = VPP_VD1_CLIP_MISC1; |
| } else if (mode_sel == 1) {/*vd2*/ |
| addr_cliptop = VPP_VD2_CLIP_MISC0; |
| addr_clipbot = VPP_VD2_CLIP_MISC1; |
| } else if (mode_sel == 2) {/*xvycc*/ |
| addr_cliptop = VPP_XVYCC_MISC0; |
| addr_clipbot = VPP_XVYCC_MISC1; |
| } else if (mode_sel == 3) {/*final clip*/ |
| addr_cliptop = VPP_CLIP_MISC0; |
| addr_clipbot = VPP_CLIP_MISC1; |
| } else { |
| addr_cliptop = mode_sel; |
| addr_clipbot = mode_sel + 1; |
| } |
| if (color == 0) {/*default*/ |
| value_cliptop = 0x3fffffff; |
| value_clipbot = 0x0; |
| } else if (color == 1) {/*Blue*/ |
| if (color_mode == 0) {/*yuv*/ |
| value_cliptop = (0x29 << 22) | (0xf0 << 12) | |
| (0x6e << 2); |
| value_clipbot = (0x29 << 22) | (0xf0 << 12) | |
| (0x6e << 2); |
| } else {/*RGB*/ |
| value_cliptop = 0xFF << 2; |
| value_clipbot = 0xFF << 2; |
| } |
| } else if (color == 2) {/*Black*/ |
| if (color_mode == 0) {/*yuv*/ |
| value_cliptop = (0x10 << 22) | (0x80 << 12) | |
| (0x80 << 2); |
| value_clipbot = (0x10 << 22) | (0x80 << 12) | |
| (0x80 << 2); |
| } else { |
| value_cliptop = 0; |
| value_clipbot = 0; |
| } |
| } else { |
| value_cliptop = color; |
| value_clipbot = color; |
| } |
| WRITE_VPP_REG(addr_cliptop, value_cliptop); |
| WRITE_VPP_REG(addr_clipbot, value_clipbot); |
| } |
| |
| #define MAX_CLIP_VAL ((1 << 30) - 1) |
| static ssize_t amvecm_clamp_color_top_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return sprintf(buf, "0x%08x\n", READ_VPP_REG(VPP_CLIP_MISC0)); |
| } |
| |
| static ssize_t amvecm_clamp_color_top_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| u32 val; |
| |
| r = sscanf(buf, "%x\n", &val); |
| if (r != 1 || val > MAX_CLIP_VAL) |
| return -EINVAL; |
| |
| WRITE_VPP_REG(VPP_CLIP_MISC0, val); |
| return count; |
| } |
| |
| static ssize_t amvecm_clamp_color_bottom_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return sprintf(buf, "0x%08x\n", READ_VPP_REG(VPP_CLIP_MISC1)); |
| } |
| |
| static ssize_t amvecm_clamp_color_bottom_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| size_t r; |
| u32 val; |
| |
| r = sscanf(buf, "%x\n", &val); |
| if (r != 1 || val > MAX_CLIP_VAL) |
| return -EINVAL; |
| |
| WRITE_VPP_REG(VPP_CLIP_MISC1, val); |
| return count; |
| } |
| |
| static ssize_t amvecm_cpu_ver_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("echo r cpu_ver > /sys/class/amvecm/cpu_ver"); |
| return 0; |
| } |
| |
| static ssize_t amvecm_cpu_ver_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| |
| if (!strncmp(parm[0], "r", 1)) { |
| if (!strncmp(parm[1], "cpu_ver", 7)) { |
| if (!is_meson_tm2_cpu()) { |
| pr_info("VER_NULL\n"); |
| kfree(buf_orig); |
| return count; |
| } |
| if (is_meson_rev_a()) |
| pr_info("VER_A\n"); |
| else if (is_meson_rev_b()) |
| pr_info("VER_B\n"); |
| else |
| pr_info("no ver\n"); |
| } else { |
| pr_info("error cmd\n"); |
| } |
| } else { |
| pr_info("error cmd\n"); |
| } |
| |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_cm2_hue_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| int i; |
| int pos = 0; |
| int cm_color_md_max = cm_14_ecm2colormd_max; |
| |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_color_md_max = ecm2colormd_max; |
| |
| for (i = 0; i < cm_color_md_max; i++) |
| pos += sprintf(buf + pos, "%d %d %d\n", i, |
| cm2_hue_array[i][0], cm2_hue_array[i][1]); |
| return pos; |
| } |
| |
| static ssize_t amvecm_cm2_hue_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val = 0; |
| unsigned int color_mode; |
| struct cm_color_md cm_color_md_dbg; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strncmp(parm[0], "cm2_hue", 7)) { |
| //parm[1]: 0: 9-color; 1: 14-color |
| { |
| if (!strncmp(parm[1], "0", 1)) |
| cm_color_md_dbg.color_type = cm_9_color; |
| else if (!strncmp(parm[1], "1", 1)) |
| cm_color_md_dbg.color_type = cm_14_color; |
| else |
| goto kfree_buf; |
| } |
| //parm[2]: color modes |
| { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto kfree_buf; |
| color_mode = val; |
| if (cm_color_md_dbg.color_type == cm_9_color) { |
| cm_color_md_dbg.cm_9_color_md = val; |
| cm_color_md_dbg.cm_14_color_md = |
| cm_14_ecm2colormd_max; |
| } else { |
| cm_color_md_dbg.cm_9_color_md = ecm2colormd_max; |
| cm_color_md_dbg.cm_14_color_md = val; |
| } |
| } |
| //parm[3]: color value |
| { |
| if (kstrtol(parm[3], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_hue_array[color_mode][0] = val; |
| cm_color_md_dbg.color_value = val; |
| } |
| //parm[4]: lpf flag |
| { |
| if (kstrtoul(parm[4], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_hue_array[color_mode][1] = val; |
| cm2_hue_array[color_mode][2] = 1; |
| } |
| |
| cm2_hue(cm_color_md_dbg, cm2_hue_array[color_mode][0], |
| cm2_hue_array[color_mode][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_HUE; |
| pr_info("cm2_hue ok\n"); |
| } |
| kfree(buf_orig); |
| return count; |
| |
| kfree_buf: |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| |
| static ssize_t amvecm_cm2_luma_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int i; |
| int pos = 0; |
| int cm_color_md_max = cm_14_ecm2colormd_max; |
| |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_color_md_max = ecm2colormd_max; |
| |
| for (i = 0; i < cm_color_md_max; i++) |
| pos += sprintf(buf + pos, "%d %d %d\n", i, |
| cm2_luma_array[i][0], cm2_luma_array[i][1]); |
| return pos; |
| } |
| |
| static ssize_t amvecm_cm2_luma_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val = 0; |
| unsigned int color_mode; |
| struct cm_color_md cm_color_md_dbg; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strncmp(parm[0], "cm2_luma", 7)) { |
| //parm[1]: 0: 9-color; 1: 14-color |
| { |
| if (!strncmp(parm[1], "0", 1)) |
| cm_color_md_dbg.color_type = cm_9_color; |
| else if (!strncmp(parm[1], "1", 1)) |
| cm_color_md_dbg.color_type = cm_14_color; |
| else |
| goto kfree_buf; |
| } |
| //parm[2]: color mode |
| { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto kfree_buf; |
| color_mode = val; |
| if (cm_color_md_dbg.color_type == cm_9_color) { |
| cm_color_md_dbg.cm_9_color_md = val; |
| cm_color_md_dbg.cm_14_color_md = |
| cm_14_ecm2colormd_max; |
| } else { |
| cm_color_md_dbg.cm_9_color_md = ecm2colormd_max; |
| cm_color_md_dbg.cm_14_color_md = val; |
| } |
| } |
| //parm[3]: color value |
| { |
| if (kstrtol(parm[3], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_luma_array[color_mode][0] = val; |
| cm_color_md_dbg.color_value = val; |
| } |
| //parm[4]: lpf flag |
| { |
| if (kstrtoul(parm[4], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_luma_array[color_mode][1] = val; |
| cm2_luma_array[color_mode][2] = 1; |
| } |
| |
| cm2_luma(cm_color_md_dbg, cm2_luma_array[color_mode][0], |
| cm2_luma_array[color_mode][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_LUMA; |
| pr_info("cm2_luma ok\n"); |
| } |
| kfree(buf_orig); |
| return count; |
| |
| kfree_buf: |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| |
| static ssize_t amvecm_cm2_sat_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int i; |
| int pos = 0; |
| int cm_color_md_max = cm_14_ecm2colormd_max; |
| |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_color_md_max = ecm2colormd_max; |
| |
| for (i = 0; i < cm_color_md_max; i++) |
| pos += sprintf(buf + pos, "%d %d %d\n", i, |
| cm2_sat_array[i][0], cm2_sat_array[i][1]); |
| return pos; |
| } |
| |
| static ssize_t amvecm_cm2_sat_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val = 0; |
| unsigned int color_mode; |
| struct cm_color_md cm_color_md_dbg; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strncmp(parm[0], "cm2_sat", 7)) { |
| //parm[1]: 0: 9-color; 1: 14-color |
| { |
| if (!strncmp(parm[1], "0", 1)) |
| cm_color_md_dbg.color_type = cm_9_color; |
| else if (!strncmp(parm[1], "1", 1)) |
| cm_color_md_dbg.color_type = cm_14_color; |
| else |
| goto kfree_buf; |
| } |
| //parm[2]: color mode |
| { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto kfree_buf; |
| color_mode = val; |
| if (cm_color_md_dbg.color_type == cm_9_color) { |
| cm_color_md_dbg.cm_9_color_md = val; |
| cm_color_md_dbg.cm_14_color_md = |
| cm_14_ecm2colormd_max; |
| } else { |
| cm_color_md_dbg.cm_9_color_md = ecm2colormd_max; |
| cm_color_md_dbg.cm_14_color_md = val; |
| } |
| } |
| //parm[3]: color value |
| { |
| if (kstrtol(parm[3], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_sat_array[color_mode][0] = val; |
| cm_color_md_dbg.color_value = val; |
| } |
| //parm[4]: lpf flag |
| { |
| if (kstrtoul(parm[4], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_sat_array[color_mode][1] = val; |
| cm2_sat_array[color_mode][2] = 1; |
| } |
| |
| cm2_sat(cm_color_md_dbg, cm2_sat_array[color_mode][0], |
| cm2_sat_array[color_mode][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_SAT; |
| pr_info("cm2_sat ok\n"); |
| } |
| kfree(buf_orig); |
| return count; |
| |
| kfree_buf: |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| |
| static ssize_t amvecm_cm2_hue_by_hs_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| int i; |
| int pos = 0; |
| int cm_color_md_max = cm_14_ecm2colormd_max; |
| |
| if (cm_cur_work_color_md == cm_9_color) |
| cm_color_md_max = ecm2colormd_max; |
| |
| for (i = 0; i < cm_color_md_max; i++) |
| pos += sprintf(buf + pos, "%d %d %d\n", i, |
| cm2_hue_by_hs_array[i][0], cm2_hue_by_hs_array[i][1]); |
| return pos; |
| } |
| |
| static ssize_t amvecm_cm2_hue_by_hs_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val = 0; |
| unsigned int color_mode; |
| struct cm_color_md cm_color_md_dbg; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strncmp(parm[0], "cm2_hue_by_hs", 7)) { |
| //parm[1]: 0: 9-color; 1: 14-color |
| { |
| if (!strncmp(parm[1], "0", 1)) |
| cm_color_md_dbg.color_type = cm_9_color; |
| else if (!strncmp(parm[1], "1", 1)) |
| cm_color_md_dbg.color_type = cm_14_color; |
| else |
| goto kfree_buf; |
| } |
| //parm[2]: color mode |
| { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto kfree_buf; |
| color_mode = val; |
| if (cm_color_md_dbg.color_type == cm_9_color) { |
| cm_color_md_dbg.cm_9_color_md = val; |
| cm_color_md_dbg.cm_14_color_md = |
| cm_14_ecm2colormd_max; |
| } else { |
| cm_color_md_dbg.cm_9_color_md = ecm2colormd_max; |
| cm_color_md_dbg.cm_14_color_md = val; |
| } |
| } |
| //parm[3]: color value |
| { |
| if (kstrtol(parm[3], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_hue_by_hs_array[color_mode][0] = val; |
| cm_color_md_dbg.color_value = val; |
| } |
| //parm[4]: lpf flag |
| { |
| if (kstrtoul(parm[4], 10, &val) < 0) |
| goto kfree_buf; |
| cm2_hue_by_hs_array[color_mode][1] = val; |
| cm2_hue_by_hs_array[color_mode][2] = 1; |
| } |
| |
| cm2_hue_by_hs(cm_color_md_dbg, |
| cm2_hue_by_hs_array[color_mode][0], |
| cm2_hue_by_hs_array[color_mode][1]); |
| pq_user_latch_flag |= PQ_USER_CMS_CURVE_HUE_HS; |
| pr_info("cm2_hue_by_hs ok\n"); |
| } |
| kfree(buf_orig); |
| return count; |
| |
| kfree_buf: |
| kfree(buf_orig); |
| 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("HIST0_REG = 0x%x, HIST1_REG = 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(32 * sizeof(unsigned int), GFP_KERNEL); |
| memset(hist, 0, 32 * sizeof(unsigned int)); |
| |
| switch (hist_sel) { |
| case CM_HUE_HIST: |
| for (i = 0; i < 32; 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 < 32; 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 void cm_init_config(int bitdepth) |
| { |
| int i, j, reg; |
| |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| am_set_regmap(&cm_default); |
| else |
| am_set_regmap(&cm_default_legacy); |
| |
| if (bitdepth == 10) { |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_YSCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_USCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_VSCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x40400); |
| } else if (bitdepth == 12) { |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_YSCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0xfff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_USCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0xfff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_VSCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0xfff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x100400); |
| } else { |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_YSCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_USCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_VSCP_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000); |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x40400); |
| } |
| |
| for (i = 0; i < 32; i++) { |
| for (j = 0; j < 5; j++) { |
| reg = CM2_ENH_COEF0_H00 + i * 8 + j; |
| WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, reg); |
| WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x0); |
| } |
| } |
| } |
| |
| static void dnlp_init_config(void) |
| { |
| memcpy(&dnlp_curve_param_load, &dnlp_default, |
| sizeof(struct ve_dnlp_curve_param_s)); |
| ve_new_dnlp_param_update(); |
| } |
| |
| static void sr_init_config(void) |
| { |
| am_set_regmap(&sr0_default); |
| am_set_regmap(&sr1_default); |
| } |
| |
| static const char *amvecm_debug_usage_str = { |
| "Usage:\n" |
| "echo vpp_size > /sys/class/amvecm/debug; get vpp size config\n" |
| "echo wb enable > /sys/class/amvecm/debug\n" |
| "echo wb disable > /sys/class/amvecm/debug\n" |
| "echo gamma enable > /sys/class/amvecm/debug\n" |
| "echo gamma disable > /sys/class/amvecm/debug\n" |
| "echo gamma load_protect_en > /sys/class/amvecm/debug\n" |
| "echo gamma load_protect_dis > /sys/class/amvecm/debug\n" |
| "echo sr peaking_en > /sys/class/amvecm/debug\n" |
| "echo sr peaking_dis > /sys/class/amvecm/debug\n" |
| "echo sr lcti_en > /sys/class/amvecm/debug\n" |
| "echo sr lcti_dis > /sys/class/amvecm/debug\n" |
| "echo sr dejaggy_en > /sys/class/amvecm/debug\n" |
| "echo sr dejaggy_dis > /sys/class/amvecm/debug\n" |
| "echo sr dering_en > /sys/class/amvecm/debug\n" |
| "echo sr dering_dis > /sys/class/amvecm/debug\n" |
| "echo sr derec_en > /sys/class/amvecm/debug\n" |
| "echo sr derec_dis > /sys/class/amvecm/debug\n" |
| "echo sr theta_en > /sys/class/amvecm/debug\n" |
| "echo sr theta_dis > /sys/class/amvecm/debug\n" |
| "echo sr deband_en > /sys/class/amvecm/debug\n" |
| "echo sr deband_dis > /sys/class/amvecm/debug\n" |
| "echo cm enable > /sys/class/amvecm/debug\n" |
| "echo cm disable > /sys/class/amvecm/debug\n" |
| "echo cm cm2_clr_dbg val > /sys/class/amvecm/debug\n" |
| "echo cm cur_color_md val(0:9clr 1:14clr) > /sys/class/amvecm/debug\n" |
| "echo dnlp enable > /sys/class/amvecm/debug\n" |
| "echo dnlp disable > /sys/class/amvecm/debug\n" |
| "echo vpp_pq enable > /sys/class/amvecm/debug\n" |
| "echo vpp_pq disable > /sys/class/amvecm/debug\n" |
| "echo keystone_process > /sys/class/amvecm/debug; keystone init config\n" |
| "echo keystone_status > /sys/class/amvecm/debug; keystone parameter status\n" |
| "echo keystone_regs > /sys/class/amvecm/debug; keystone regs value\n" |
| "echo keystone_config param1(D) param2(D) > /sys/class/amvecm/debug; keystone param config\n" |
| "echo vpp_mtx xvycc_10 rgb2yuv > /sys/class/amvecm/debug; 10bit xvycc mtx\n" |
| "echo vpp_mtx xvycc_10 yuv2rgb > /sys/class/amvecm/debug; 10bit xvycc mtx\n" |
| "echo vpp_mtx post_10 rgb2yuv > /sys/class/amvecm/debug; 10bit post mtx\n" |
| "echo vpp_mtx post_10 yuv2rgb > /sys/class/amvecm/debug; 10bit post mtx\n" |
| "echo vpp_mtx vd1_10 rgb2yuv > /sys/class/amvecm/debug; 10bit vd1 mtx\n" |
| "echo vpp_mtx vd1_10 yuv2rgb > /sys/class/amvecm/debug; 10bit vd1 mtx\n" |
| "echo vpp_mtx xvycc_12 rgb2yuv > /sys/class/amvecm/debug; 12bit xvycc mtx\n" |
| "echo vpp_mtx xvycc_12 yuv2rgb > /sys/class/amvecm/debug; 12bit xvycc mtx\n" |
| "echo vpp_mtx post_12 rgb2yuv > /sys/class/amvecm/debug; 12bit post mtx\n" |
| "echo vpp_mtx post_12 yuv2rgb > /sys/class/amvecm/debug; 12bit post mtx\n" |
| "echo vpp_mtx vd1_12 rgb2yuv > /sys/class/amvecm/debug; 12bit vd1 mtx\n" |
| "echo vpp_mtx vd1_12 yuv2rgb > /sys/class/amvecm/debug; 12bit vd1 mtx\n" |
| "echo bitdepth 10/12/other-num > /sys/class/amvecm/debug; config data path\n" |
| "echo datapath_config param1(D) param2(D) > /sys/class/amvecm/debug; config data path\n" |
| "echo datapath_status > /sys/class/amvecm/debug; data path status\n" |
| "echo clip_config 0/1/2/.. 0/1/... 0/1 > /sys/class/amvecm/debug; config clip\n" |
| }; |
| |
| static ssize_t amvecm_debug_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| pr_info("cm2_debug:%d\n", cm2_debug); |
| pr_info("cm_cur_work_color_md:%d\n", cm_cur_work_color_md); |
| return sprintf(buf, "%s\n", amvecm_debug_usage_str); |
| } |
| |
| static ssize_t amvecm_debug_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val = 0; |
| unsigned int mode_sel, color, color_mode, i; |
| struct vinfo_s *vinfo = get_current_vinfo(); |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strncmp(parm[0], "vpp_size", 8)) { |
| dump_vpp_size_info(); |
| } else if (!strncmp(parm[0], "vpp_state", 9)) { |
| pr_info("amvecm driver version : %s\n", AMVECM_VER); |
| } else if (!strncmp(parm[0], "checkpattern", 12)) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| pattern_detect_debug = 1; |
| enable_pattern_detect = 1; |
| pr_info("enable pattern detection\n"); |
| } else if (!strncmp(parm[1], "debug", 5)) { |
| pattern_detect_debug = 2; |
| pr_info("enable pattern detection debug info\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| pattern_detect_debug = 0; |
| enable_pattern_detect = 0; |
| pr_info("disable pattern detection\n"); |
| } else if (!strncmp(parm[1], "setmask", 7)) { |
| if (kstrtoul(parm[2], 16, &val) < 0) |
| goto free_buf; |
| pattern_mask = val; |
| pr_info("pattern_mask is 0x%x\n", pattern_mask); |
| } else if (!strncmp(parm[1], "getmask", 7)) { |
| pr_info("pattern_mask is 0x%x\n", pattern_mask); |
| } |
| } else if (!strncmp(parm[0], "wb", 2)) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| amvecm_wb_enable(1); |
| pr_info("enable wb\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| amvecm_wb_enable(0); |
| pr_info("disable wb\n"); |
| } |
| } else if (!strncmp(parm[0], "gamma", 5)) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_EN; /* gamma off */ |
| pr_info("enable gamma\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS;/* gamma off */ |
| pr_info("disable gamma\n"); |
| } else if (!strncmp(parm[1], "load_protect_en", 15)) { |
| gamma_loadprotect_en = 1; |
| pr_info("disable gamma before loading new gamma\n"); |
| } else if (!strncmp(parm[1], "load_protect_dis", 16)) { |
| gamma_loadprotect_en = 0; |
| pr_info("loading new gamma without pretect"); |
| } |
| } else if (!strncmp(parm[0], "sr", 2)) { |
| if (!strncmp(parm[1], "peaking_en", 10)) { |
| amvecm_sharpness_enable(0); |
| pr_info("enable peaking\n"); |
| } else if (!strncmp(parm[1], "peaking_dis", 11)) { |
| amvecm_sharpness_enable(1); |
| pr_info("disable peaking\n"); |
| } else if (!strncmp(parm[1], "lcti_en", 7)) { |
| amvecm_sharpness_enable(2); |
| pr_info("enable lti cti\n"); |
| } else if (!strncmp(parm[1], "lcti_dis", 8)) { |
| amvecm_sharpness_enable(3); |
| pr_info("disable lti cti\n"); |
| } else if (!strncmp(parm[1], "theta_en", 8)) { |
| amvecm_sharpness_enable(4); |
| pr_info("SR4 enable drtlpf theta\n"); |
| } else if (!strncmp(parm[1], "theta_dis", 9)) { |
| amvecm_sharpness_enable(5); |
| pr_info("SR4 disable drtlpf theta\n"); |
| } else if (!strncmp(parm[1], "deband_en", 9)) { |
| amvecm_sharpness_enable(6); |
| pr_info("SR4 enable debanding\n"); |
| } else if (!strncmp(parm[1], "deband_dis", 10)) { |
| amvecm_sharpness_enable(7); |
| pr_info("SR4 disable debanding\n"); |
| } else if (!strncmp(parm[1], "dejaggy_en", 10)) { |
| amvecm_sharpness_enable(8); |
| pr_info("SR3 enable dejaggy\n"); |
| } else if (!strncmp(parm[1], "dejaggy_dis", 11)) { |
| amvecm_sharpness_enable(9); |
| pr_info("SR3 disable dejaggy\n"); |
| } else if (!strncmp(parm[1], "dering_en", 9)) { |
| amvecm_sharpness_enable(10); |
| pr_info("SR3 enable dering\n"); |
| } else if (!strncmp(parm[1], "dering_dis", 10)) { |
| amvecm_sharpness_enable(11); |
| pr_info("SR3 disable dering\n"); |
| } else if (!strncmp(parm[1], "drlpf_en", 8)) { |
| amvecm_sharpness_enable(12); |
| pr_info("SR3 enable drlpf\n"); |
| } else if (!strncmp(parm[1], "drlpf_dis", 9)) { |
| amvecm_sharpness_enable(13); |
| pr_info("SR3 disable drlpf\n"); |
| } else if (!strncmp(parm[1], "enable", 6)) { |
| amvecm_sharpness_enable(0); |
| amvecm_sharpness_enable(2); |
| amvecm_sharpness_enable(4); |
| amvecm_sharpness_enable(6); |
| amvecm_sharpness_enable(8); |
| amvecm_sharpness_enable(10); |
| amvecm_sharpness_enable(12); |
| pr_info("SR enable\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| amvecm_sharpness_enable(1); |
| amvecm_sharpness_enable(3); |
| amvecm_sharpness_enable(5); |
| amvecm_sharpness_enable(7); |
| amvecm_sharpness_enable(9); |
| amvecm_sharpness_enable(11); |
| amvecm_sharpness_enable(13); |
| pr_info("SR disable\n"); |
| } else if (!strncmp(parm[1], "demo", 4)) { |
| if (!strncmp(parm[2], "enable", 6)) { |
| amvecm_sr_demo(1); |
| pr_info("sr demo enable\n"); |
| } else if (!strncmp(parm[2], "disable", 7)) { |
| amvecm_sr_demo(0); |
| pr_info("sr demo disable\n"); |
| } |
| } |
| } else if (!strcmp(parm[0], "cm")) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| amcm_enable(); |
| pr_info("enable cm\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| amcm_disable(); |
| pr_info("disable cm\n"); |
| } else if (!strcmp(parm[1], "cur_color_md")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| cm_cur_work_color_md = val; |
| } else { |
| pr_info("unsupport cm_cur_work_color_md cmd\n"); |
| goto free_buf; |
| } |
| } else if (!strcmp(parm[1], "cm2_clr_dbg")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| cm2_debug = val; |
| } else { |
| pr_info("unsupport cm2_clr_dbg cmd\n"); |
| goto free_buf; |
| } |
| } else { |
| pr_info("unsupport cm cmd\n"); |
| goto free_buf; |
| } |
| } else if (!strncmp(parm[0], "dnlp", 4)) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| ve_enable_dnlp(); |
| pr_info("enable dnlp\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| ve_disable_dnlp(); |
| pr_info("disable dnlp\n"); |
| } |
| } else if (!strncmp(parm[0], "vpp_pq", 6)) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| amvecm_pq_enable(1); |
| pr_info("enable vpp_pq\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| amvecm_pq_enable(0); |
| pr_info("disable vpp_pq\n"); |
| } |
| } else if (!strncmp(parm[0], "vpp_mtx", 7)) { |
| if (!strncmp(parm[1], "vd1_10", 6)) { |
| mtx_sel_dbg |= 1 << VPP_MATRIX_1; |
| if (!strncmp(parm[2], "yuv2rgb", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 1); |
| pr_info("10bit vd1 mtx yuv2rgb\n"); |
| } else if (!strncmp(parm[2], "rgb2yuv", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 2); |
| pr_info("10bit vd1 mtx rgb2yuv\n"); |
| } |
| } else if (!strncmp(parm[1], "post_10", 7)) { |
| mtx_sel_dbg |= 1 << VPP_MATRIX_2; |
| if (!strncmp(parm[2], "yuv2rgb", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 1); |
| pr_info("10bit post mtx yuv2rgb\n"); |
| } else if (!strncmp(parm[2], "rgb2yuv", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 2); |
| pr_info("10bit post mtx rgb2yuv\n"); |
| } |
| } else if (!strncmp(parm[1], "xvycc_10", 8)) { |
| mtx_sel_dbg |= 1 << VPP_MATRIX_3; |
| if (!strncmp(parm[2], "yuv2rgb", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 1); |
| pr_info("10bit xvycc mtx yuv2rgb\n"); |
| } else if (!strncmp(parm[2], "rgb2yuv", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 2); |
| pr_info("10bit xvycc mtx rgb2yuv\n"); |
| } |
| } else if (!strncmp(parm[1], "vd1_12", 6)) { |
| mtx_sel_dbg |= 1 << VPP_MATRIX_1; |
| if (!strncmp(parm[2], "yuv2rgb", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 3); |
| pr_info("1wbit vd1 mtx yuv2rgb\n"); |
| } else if (!strncmp(parm[2], "rgb2yuv", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 4); |
| pr_info("1wbit vd1 mtx rgb2yuv\n"); |
| } |
| } else if (!strncmp(parm[1], "post_12", 7)) { |
| mtx_sel_dbg |= 1 << VPP_MATRIX_2; |
| if (!strncmp(parm[2], "yuv2rgb", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 3); |
| pr_info("1wbit post mtx yuv2rgb\n"); |
| } else if (!strncmp(parm[2], "rgb2yuv", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 4); |
| pr_info("1wbit post mtx rgb2yuv\n"); |
| } |
| } else if (!strncmp(parm[1], "xvycc_12", 8)) { |
| mtx_sel_dbg |= 1 << VPP_MATRIX_3; |
| if (!strncmp(parm[2], "yuv2rgb", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 3); |
| pr_info("1wbit xvycc mtx yuv2rgb\n"); |
| } else if (!strncmp(parm[2], "rgb2yuv", 7)) { |
| amvecm_vpp_mtx_debug(mtx_sel_dbg, 4); |
| pr_info("1wbit xvycc mtx rgb2yuv\n"); |
| } |
| } |
| } else if (!strncmp(parm[0], "ve_dith", 7)) { |
| if (!strncmp(parm[1], "enable", 6)) { |
| amvecm_dither_enable(1); |
| pr_info("enable ve dither\n"); |
| } else if (!strncmp(parm[1], "disable", 7)) { |
| amvecm_dither_enable(0); |
| pr_info("disable ve dither\n"); |
| } else if (!strncmp(parm[1], "rd_en", 5)) { |
| amvecm_dither_enable(3); |
| pr_info("enable ve round dither\n"); |
| } else if (!strncmp(parm[1], "rd_dis", 6)) { |
| amvecm_dither_enable(2); |
| pr_info("disable ve round dither\n"); |
| } |
| } else if (!strcmp(parm[0], "keystone_process")) { |
| keystone_correction_process(); |
| pr_info("keystone_correction_process done!\n"); |
| } else if (!strcmp(parm[0], "keystone_status")) { |
| keystone_correction_status(); |
| } else if (!strcmp(parm[0], "keystone_regs")) { |
| keystone_correction_regs(); |
| } else if (!strcmp(parm[0], "keystone_config")) { |
| enum vks_param_e vks_param; |
| unsigned int vks_param_val; |
| |
| if (!parm[2]) { |
| pr_info("misss param\n"); |
| goto free_buf; |
| } |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| vks_param = val; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| vks_param_val = val; |
| keystone_correction_config(vks_param, vks_param_val); |
| } else if (!strcmp(parm[0], "bitdepth")) { |
| unsigned int bitdepth; |
| |
| if (!parm[1]) { |
| pr_info("misss param1\n"); |
| goto free_buf; |
| } |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| bitdepth = val; |
| vpp_bitdepth_config(bitdepth); |
| } else if (!strcmp(parm[0], "datapath_config")) { |
| unsigned int node, param1, param2; |
| |
| if (!parm[1]) { |
| pr_info("misss param1\n"); |
| goto free_buf; |
| } |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| node = val; |
| |
| if (!parm[2]) { |
| pr_info("misss param2\n"); |
| goto free_buf; |
| } |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| param1 = val; |
| |
| if (!parm[3]) { |
| pr_info("misss param3,default is 0\n"); |
| param2 = 0; |
| } |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| 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) |
| goto free_buf; |
| mode_sel = val; |
| } else { |
| mode_sel = 0; |
| } |
| if (parm[2]) { |
| 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) |
| goto free_buf; |
| color_mode = val; |
| } else { |
| color_mode = 0; |
| } |
| vpp_clip_config(mode_sel, color, color_mode); |
| pr_info("vpp_clip_config done!\n"); |
| } else if (!strcmp(parm[0], "3dlut_testpattern")) { |
| int r, g, b; |
| |
| if (parm[1]) { |
| if (kstrtol(parm[1], 10, &val) < 0) |
| goto free_buf; |
| r = val; |
| } else { |
| r = 0; |
| } |
| if (parm[2]) { |
| if (kstrtol(parm[2], 10, &val) < 0) |
| goto free_buf; |
| g = val; |
| } else { |
| g = 0; |
| } |
| if (parm[3]) { |
| if (kstrtol(parm[3], 10, &val) < 0) |
| goto free_buf; |
| b = val; |
| } else { |
| b = 0; |
| } |
| vpp_lut3d_table_init(r, g, b); |
| vpp_set_lut3d(0, 0, 0, 0); |
| vpp_lut3d_table_release(); |
| } else if (!strcmp(parm[0], "3dlut")) { |
| if (!parm[1]) |
| goto free_buf; |
| |
| if (!strcmp(parm[1], "enable")) { |
| lut3d_en = 1; |
| } else if (!strcmp(parm[1], "disable")) { |
| vpp_enable_lut3d(0); |
| lut3d_en = 0; |
| } else if (!strcmp(parm[1], "open")) { |
| vpp_enable_lut3d(1); |
| } else if (!strcmp(parm[1], "close")) { |
| vpp_enable_lut3d(0); |
| } else if (!strcmp(parm[1], "debug")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lut3d_debug = val; |
| } else { |
| lut3d_debug = 0; |
| } |
| } else if (!strcmp(parm[1], "long_section")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lut3d_long_sec_en = val; |
| } else { |
| lut3d_long_sec_en = 0; |
| } |
| } else if (!strcmp(parm[1], "compress")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lut3d_compress = val; |
| } else { |
| lut3d_compress = 0; |
| } |
| } else if (!strcmp(parm[1], "write_source")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lut3d_write_from_file = val; |
| } else { |
| lut3d_write_from_file = 0; |
| } |
| } else if (!strcmp(parm[1], "read_source")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lut3d_data_source = val; |
| } else { |
| lut3d_data_source = 0; |
| } |
| } else if (!strcmp(parm[1], "order")) { |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lut3d_order = val; |
| } else { |
| lut3d_order = 0; |
| } |
| } else if (!strcmp(parm[1], "load")) { |
| unsigned int index; |
| |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| index = val; |
| } else { |
| index = 0; |
| } |
| |
| if (index > 2) { |
| index = 2; |
| pr_info("support up to 3 different luts\n"); |
| } |
| |
| vpp_lut3d_table_init(0, 0, 0); |
| vpp_set_lut3d(lut3d_data_source, index, 0, 0); |
| vpp_lut3d_table_release(); |
| } else if (!strcmp(parm[1], "writesection")) { |
| unsigned int section_len, start, paracount; |
| unsigned int *section_in; |
| int readcount = 0; |
| unsigned int encode_table_size; |
| char data[4]; |
| char *buffer = NULL; |
| struct file *fp; |
| mm_segment_t fs; |
| loff_t pos; |
| |
| encode_table_size = |
| 257 * sizeof(unsigned long); |
| |
| section_len = 17; |
| if (lut3d_long_sec_en) |
| section_len = 17 * 17 * 17; |
| section_in = kmalloc(sizeof(unsigned int) * section_len * 3, |
| GFP_KERNEL); |
| if (!section_in) |
| goto free_buf; |
| |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) { |
| kfree(section_in); |
| goto free_buf; |
| } |
| start = val; |
| } else { |
| start = 0; |
| } |
| |
| if (start > ((17 * 17 * 17 / section_len) - 1)) { |
| start = (17 * 17 * 17 / section_len) - 1; |
| pr_info("section index should be in 0 ~ %d-1\n", |
| (17 * 17 * 17 / section_len)); |
| } |
| |
| memset(section_in, 0, |
| section_len * 3 * sizeof(unsigned int)); |
| |
| if (!parm[3]) { |
| kfree(section_in); |
| goto free_buf; |
| } |
| |
| buffer = parm[3]; |
| readcount = strlen(buffer); |
| if (lut3d_write_from_file) { |
| buffer = |
| kmalloc(section_len * 9 + encode_table_size, |
| GFP_KERNEL); |
| if (!buffer) { |
| kfree(section_in); |
| goto free_buf; |
| } |
| |
| fp = filp_open(parm[3], O_RDONLY, 0); |
| if (IS_ERR(fp)) { |
| kfree(section_in); |
| kfree(buffer); |
| goto free_buf; |
| } |
| fs = get_fs(); |
| set_fs(KERNEL_DS); |
| memset(buffer, 0, |
| section_len * 9 + encode_table_size); |
| pos = 0; |
| readcount = |
| vfs_read(fp, buffer, |
| section_len * 9 + encode_table_size, |
| &pos); |
| pr_info("read file lut data size %d\n", |
| readcount); |
| if (readcount <= 0) { |
| kfree(section_in); |
| kfree(buffer); |
| goto free_buf; |
| } |
| filp_close(fp, NULL); |
| set_fs(fs); |
| } |
| if (lut3d_compress) { |
| huff64_decode(buffer, (unsigned int)readcount, |
| section_in, section_len * 3); |
| } else { |
| paracount = (strlen(buffer) + 2) / 3; |
| if (paracount > (section_len * 3)) |
| paracount = section_len * 3; |
| |
| for (i = 0; i < paracount; ++i) { |
| data[0] = buffer[3 * i + 0]; |
| data[1] = buffer[3 * i + 1]; |
| data[2] = buffer[3 * i + 2]; |
| data[3] = '\0'; |
| if (kstrtoul(data, 16, &val) < 0) { |
| kfree(section_in); |
| goto free_buf; |
| } |
| section_in[i] = val; |
| } |
| } |
| |
| vpp_write_lut3d_section(start, |
| section_len, |
| section_in); |
| |
| kfree(section_in); |
| if (lut3d_write_from_file) |
| kfree(buffer); |
| } else if (!strcmp(parm[1], "readsection")) { |
| unsigned int section_len, start, len; |
| unsigned int *section_out; |
| unsigned int encode_table_size; |
| char *tmp, tmp1[10] = {0}; |
| struct file *fp; |
| mm_segment_t fs; |
| loff_t pos; |
| |
| encode_table_size = |
| 257 * sizeof(unsigned long); |
| section_len = 17; |
| if (lut3d_long_sec_en) |
| section_len = 17 * 17 * 17; |
| section_out = |
| kmalloc(sizeof(unsigned int) * section_len * 3, |
| GFP_KERNEL); |
| if (!section_out) |
| goto free_buf; |
| /* extra space is for encoding table */ |
| /* make sure there is enough buffer to use */ |
| tmp = |
| kmalloc(section_len * 9 + encode_table_size, |
| GFP_KERNEL); |
| if (!tmp) { |
| kfree(section_out); |
| goto free_buf; |
| } |
| memset(tmp, 0, |
| section_len * 9 + encode_table_size); |
| |
| if (parm[2]) { |
| if (kstrtoul(parm[2], 10, &val) < 0) { |
| kfree(section_out); |
| kfree(tmp); |
| goto free_buf; |
| } |
| start = val; |
| } else { |
| start = 0; |
| } |
| |
| if (start > ((17 * 17 * 17 / section_len) - 1)) { |
| start = (17 * 17 * 17 / section_len) - 1; |
| pr_info("section index should be in 0 ~ %d-1\n", |
| (17 * 17 * 17 / section_len)); |
| } |
| |
| vpp_read_lut3d_section(start, |
| section_len, |
| section_out); |
| |
| if (lut3d_compress) { |
| len = huff64_encode(section_out, |
| section_len * 3, |
| tmp); |
| tmp[len] = 0; |
| pr_info("compressed len %d vs %d\n", |
| len, section_len * 9); |
| |
| } else { |
| for (i = 0; i < section_len; ++i) { |
| sprintf(tmp1, "%03x%03x%03x", |
| section_out[i * 3 + 0], |
| section_out[i * 3 + 1], |
| section_out[i * 3 + 2]); |
| strcat(tmp, tmp1); |
| } |
| len = section_len * 9; |
| } |
| |
| if (parm[3]) { |
| fp = filp_open(parm[3], |
| O_RDWR | O_CREAT | O_APPEND, |
| 0644); |
| if (IS_ERR(fp)) { |
| kfree(section_out); |
| kfree(tmp); |
| goto free_buf; |
| } |
| fs = get_fs(); |
| set_fs(KERNEL_DS); |
| pos = fp->f_pos; |
| vfs_write(fp, tmp, |
| len, |
| &pos); |
| |
| filp_close(fp, NULL); |
| set_fs(fs); |
| } |
| |
| kfree(section_out); |
| kfree(tmp); |
| } else { |
| pr_info("unsupprt cmd!\n"); |
| } |
| } else if (!strcmp(parm[0], "3dlut_dump")) { |
| if (!strcmp(parm[1], "init_tab")) |
| dump_plut3d_table(); |
| else if (!strcmp(parm[1], "reg_tab")) |
| 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[4]) { |
| pr_info("miss param1\n"); |
| goto free_buf; |
| } |
| if (kstrtoul(parm[2], 16, &val) < 0) |
| goto free_buf; |
| ro_frame = val; |
| if (kstrtoul(parm[3], 16, &val) < 0) |
| goto free_buf; |
| thrd0 = val; |
| if (kstrtoul(parm[4], 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 if (!strcmp(parm[0], "dump_overscan_table")) { |
| for (i = 0; i < TIMING_MAX; i++) { |
| pr_info("*****dump overscan_tab[%d]*****\n", i); |
| pr_info("hs:%d, he:%d, vs:%d, ve:%d, screen_mode:%d, afd:%d, flag:%d.\n", |
| overscan_table[i].hs, overscan_table[i].he, |
| overscan_table[i].vs, overscan_table[i].ve, |
| overscan_table[i].screen_mode, |
| overscan_table[i].afd_enable, |
| overscan_table[i].load_flag); |
| } |
| } else if (!strcmp(parm[0], "set_gamma_lut_65")) { |
| if (!strcmp(parm[1], "default")) |
| set_gamma_regs(1, 0); |
| else if (!strcmp(parm[1], "straight")) |
| set_gamma_regs(1, 1); |
| else |
| pr_info("unsupport cmd\n"); |
| } else if (!strcmp(parm[0], "pd_fix_lvl")) { |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| if (val > PD_DEF_LVL) |
| pd_fix_lvl = PD_DEF_LVL; |
| else |
| pd_fix_lvl = val; |
| } else if (!strcmp(parm[0], "gmv_th")) { |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| gmv_th = val; |
| } else if (!strcmp(parm[0], "pd_weak_fix_lvl")) { |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| if (val > PD_DEF_LVL) |
| pd_weak_fix_lvl = PD_DEF_LVL; |
| else |
| pd_weak_fix_lvl = val; |
| } else if (!strcmp(parm[0], "gmv_weak_th")) { |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| if (val >= gmv_th) |
| gmv_weak_th = gmv_th - 1; |
| else |
| gmv_weak_th = val; |
| } else if (!strcmp(parm[0], "post2mtx")) { |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| mtx_setting(POST2_MTX, val, 1); |
| } |
| } else if (!strcmp(parm[0], "mltcast_ratio1")) { |
| pr_info("current value: %d\n", mltcast_ratio1); |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| mltcast_ratio1 = val; |
| pr_info("setting value: %d\n", mltcast_ratio1); |
| } else if (!strcmp(parm[0], "mltcast_ratio2")) { |
| pr_info("current value: %d\n", mltcast_ratio2); |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| mltcast_ratio2 = val; |
| pr_info("setting value: %d\n", mltcast_ratio2); |
| } else if (!strcmp(parm[0], "mltcast_skip_en")) { |
| pr_info("current value: %d\n", mltcast_skip_en); |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| } |
| mltcast_skip_en = val; |
| pr_info("setting value: %d\n", mltcast_skip_en); |
| } else if (!strcmp(parm[0], "pst_hist_sel")) { |
| if (parm[1]) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| if (val == 1) { |
| vpp_pst_hist_sta_config(1, HIST_MAXRGB, |
| AFTER_POST2_MTX, vinfo); |
| pr_info("hist sel: max rgb hist\n"); |
| } else { |
| vpp_pst_hist_sta_config(1, HIST_YR, |
| BEFORE_POST2_MTX, vinfo); |
| pr_info("hist sel: Y hist\n"); |
| } |
| } |
| } else { |
| pr_info("unsupport cmd\n"); |
| } |
| vpp_pst_hist_sta_config(1, HIST_MAXRGB, |
| AFTER_POST2_MTX, vinfo); |
| |
| kfree(buf_orig); |
| return count; |
| |
| free_buf: |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| |
| static const char *amvecm_reg_usage_str = { |
| "Usage:\n" |
| "echo rv addr(H) > /sys/class/amvecm/reg;\n" |
| "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/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, |
| struct class_attribute *attr, char *buf) |
| { |
| return sprintf(buf, "%s\n", amvecm_reg_usage_str); |
| } |
| |
| static ssize_t amvecm_reg_store(struct class *cla, |
| struct class_attribute *attr, |
| const char *buf, size_t count) |
| { |
| char *buf_orig, *parm[8] = {NULL}; |
| long val = 0; |
| unsigned int reg_addr, reg_val, i; |
| |
| if (!buf) |
| return count; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) |
| return -ENOMEM; |
| parse_param_amvecm(buf_orig, (char **)&parm); |
| if (!strcmp(parm[0], "rv")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| reg_val = READ_VPP_REG_EX(reg_addr, 0); |
| pr_info("VPU[0x%04x]=0x%08x\n", reg_addr, reg_val); |
| } else if (!strcmp(parm[0], "rc")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| reg_val = aml_read_cbus(reg_addr); |
| pr_info("CBUS[0x%04x]=0x%08x\n", reg_addr, reg_val); |
| } else if (!strcmp(parm[0], "rh")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| amvecm_hiu_reg_read(reg_addr, ®_val); |
| pr_info("HIU[0x%04x]=0x%08x\n", reg_addr, reg_val); |
| } else if (!strcmp(parm[0], "wv")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| if (kstrtoul(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_val = val; |
| WRITE_VPP_REG_EX(reg_addr, reg_val, 0); |
| } else if (!strcmp(parm[0], "wc")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| if (kstrtoul(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_val = val; |
| aml_write_cbus(reg_addr, reg_val); |
| } else if (!strcmp(parm[0], "wh")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| if (kstrtoul(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_val = val; |
| amvecm_hiu_reg_write(reg_addr, reg_val); |
| } else if (parm[0][0] == 'd') { |
| if (kstrtoul(parm[1], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| reg_addr = val; |
| if (kstrtoul(parm[2], 16, &val) < 0) { |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| for (i = 0; i < val; i++) { |
| if (parm[0][1] == 'v') { |
| reg_val = READ_VPP_REG_EX(reg_addr + i, 0); |
| } else if (parm[0][1] == 'c') { |
| reg_val = aml_read_cbus(reg_addr + i); |
| } else if (parm[0][1] == 'h') { |
| amvecm_hiu_reg_read((reg_addr + i), |
| ®_val); |
| } else { |
| pr_info("unsupprt cmd!\n"); |
| kfree(buf_orig); |
| return -EINVAL; |
| } |
| pr_info("REG[0x%04x]=0x%08x\n", |
| (reg_addr + i), reg_val); |
| } |
| } else { |
| pr_info("unsupprt cmd!\n"); |
| } |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static ssize_t amvecm_get_hdr_type_show(struct class *cla, |
| struct class_attribute *attr, |
| char *buf) |
| { |
| return sprintf(buf, "%x\n", hdr_source_type); |
| } |
| |
| static ssize_t amvecm_get_hdr_type_store(struct class *cls, |
| struct class_attribute *attr, |
| const char *buffer, size_t count) |
| { |
| return count; |
| } |
| |
| static void lc_rd_reg(enum lc_reg_lut_e reg_sel, int data_type, char *buf) |
| { |
| int i, j, tmp, tmp1, tmp2, len = 12; |
| int lut_data[63] = {0}; |
| char *stemp = NULL; |
| |
| if (data_type == 1) |
| goto dump_as_string; |
| |
| 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); |
| } |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (j = 0; j < 2 ; j++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YMINVAL_LMT_12_13 + j); |
| 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); |
| i++; |
| } |
| } |
| break; |
| case YPKBV_YMAXVAL_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| break; |
| |
| 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 YMAXVAL_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (i = 0; i < 6 ; i++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YMAXVAL_LMT_0_1 + i); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| pr_info("reg_lc_ymaxVal_lmt[%d] =%4d.\n", |
| 2 * i, tmp1); |
| pr_info("reg_lc_ymaxVal_lmt[%d] =%4d.\n", |
| 2 * i + 1, tmp2); |
| } |
| |
| for (j = 0; j < 2 ; j++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YMAXVAL_LMT_12_13 + j); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| pr_info("reg_lc_ymaxVal_lmt[%d] =%4d.\n", |
| 2 * i, tmp1); |
| pr_info("reg_lc_ymaxVal_lmt[%d] =%4d.\n", |
| 2 * i + 1, tmp2); |
| i++; |
| } |
| } |
| break; |
| case YPKBV_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (i = 0; i < 8 ; i++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YPKBV_LMT_0_1 + i); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| pr_info("reg_lc_ypkBV_lmt[%d] =%4d.\n", |
| 2 * i, tmp1); |
| pr_info("reg_lc_ypkBV_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; |
| } |
| return; |
| |
| dump_as_string: |
| stemp = kzalloc(300, GFP_KERNEL); |
| if (!stemp) |
| return; |
| memset(stemp, 0, 300); |
| 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; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| } |
| tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_62); |
| lut_data[62] = tmp & 0xfff; |
| for (i = 0; i < 63 ; i++) |
| d_convert_str(lut_data[i], |
| i, stemp, 4, 10); |
| memcpy(buf, stemp, 300); |
| 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; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| } |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| len = 16; |
| for (j = 0; j < 2 ; j++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YMINVAL_LMT_12_13 + j); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| i++; |
| } |
| } |
| for (i = 0; i < len ; i++) |
| d_convert_str(lut_data[i], |
| i, stemp, 4, 10); |
| memcpy(buf, stemp, 300); |
| break; |
| case YPKBV_YMAXVAL_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| break; |
| |
| 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; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| } |
| for (i = 0; i < 12 ; i++) |
| d_convert_str(lut_data[i], |
| i, stemp, 4, 10); |
| memcpy(buf, stemp, 300); |
| break; |
| case YMAXVAL_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (i = 0; i < 6 ; i++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YMAXVAL_LMT_0_1 + i); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| } |
| |
| len = 16; |
| for (j = 0; j < 2 ; j++) { |
| tmp = |
| READ_VPP_REG(LC_CURVE_YMAXVAL_LMT_12_13 + j); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| i++; |
| } |
| } |
| for (i = 0; i < len ; i++) |
| d_convert_str(lut_data[i], |
| i, stemp, 4, 10); |
| memcpy(buf, stemp, 300); |
| break; |
| case YPKBV_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (i = 0; i < 8 ; i++) { |
| tmp = READ_VPP_REG(LC_CURVE_YPKBV_LMT_0_1 + i); |
| tmp1 = (tmp >> 16) & 0x3ff; |
| tmp2 = tmp & 0x3ff; |
| lut_data[2 * i] = tmp1; |
| lut_data[2 * i + 1] = tmp2; |
| } |
| for (i = 0; i < 16 ; i++) |
| d_convert_str(lut_data[i], |
| i, stemp, 4, 10); |
| memcpy(buf, stemp, 300); |
| } |
| break; |
| case YPKBV_RAT: |
| tmp = READ_VPP_REG(LC_CURVE_YPKBV_RAT); |
| lut_data[0] = (tmp >> 24) & 0xff; |
| lut_data[1] = (tmp >> 16) & 0xff; |
| lut_data[2] = (tmp >> 8) & 0xff; |
| lut_data[3] = tmp & 0xff; |
| for (i = 0; i < 4 ; i++) |
| d_convert_str(lut_data[i], |
| i, stemp, 4, 10); |
| memcpy(buf, stemp, 300); |
| break; |
| default: |
| break; |
| } |
| kfree(stemp); |
| } |
| |
| static void lc_wr_reg(int *p, enum lc_reg_lut_e reg_sel) |
| { |
| int i, j, 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); |
| } |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (j = 0; j < 2 ; j++) { |
| tmp1 = *(p + 2 * i); |
| tmp2 = *(p + 2 * i + 1); |
| tmp = ((tmp1 & 0x3ff) << 16) | (tmp2 & 0x3ff); |
| WRITE_VPP_REG(LC_CURVE_YMINVAL_LMT_12_13 + j, |
| tmp); |
| i++; |
| } |
| } |
| break; |
| case YPKBV_YMAXVAL_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| break; |
| |
| 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 YMAXVAL_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| 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_YMAXVAL_LMT_0_1 + i, |
| tmp); |
| } |
| |
| for (j = 0; j < 2 ; j++) { |
| tmp1 = *(p + 2 * i); |
| tmp2 = *(p + 2 * i + 1); |
| tmp = ((tmp1 & 0x3ff) << 16) | (tmp2 & 0x3ff); |
| WRITE_VPP_REG(LC_CURVE_YMAXVAL_LMT_12_13 + j, |
| tmp); |
| i++; |
| } |
| } |
| break; |
| case YPKBV_LMT: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| for (i = 0; i < 8 ; i++) { |
| tmp1 = *(p + 2 * i); |
| tmp2 = *(p + 2 * i + 1); |
| tmp = ((tmp1 & 0x3ff) << 16) | (tmp2 & 0x3ff); |
| WRITE_VPP_REG(LC_CURVE_YPKBV_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; |
| } |
| } |
| |
| void lc_load_curve(struct ve_lc_curve_parm_s *p) |
| { |
| /*load lc parms*/ |
| lc_alg_parm.dbg_parm0 = p->param[lc_dbg_parm0]; |
| lc_alg_parm.dbg_parm1 = p->param[lc_dbg_parm1]; |
| lc_alg_parm.dbg_parm2 = p->param[lc_dbg_parm2]; |
| lc_alg_parm.dbg_parm3 = p->param[lc_dbg_parm3]; |
| lc_alg_parm.dbg_parm4 = p->param[lc_dbg_parm4]; |
| |
| /*load lc_staturation curve*/ |
| lc_wr_reg(p->ve_lc_saturation, 0x1); |
| /*load lc_yminval_lmt*/ |
| lc_wr_reg(p->ve_lc_yminval_lmt, 0x2); |
| /*load lc_ypkbv_ymaxval_lmt*/ |
| lc_wr_reg(p->ve_lc_ypkbv_ymaxval_lmt, 0x4); |
| /*load lc_ypkbV_ratio*/ |
| lc_wr_reg(p->ve_lc_ypkbv_ratio, 0x8); |
| /*load lc_ymaxval_ratio*/ |
| lc_wr_reg(p->ve_lc_ymaxval_lmt, 0x10); |
| /*load lc_ypkbV_ratio*/ |
| lc_wr_reg(p->ve_lc_ypkbv_lmt, 0x20); |
| } |
| |
| static int lc_dbg_flag; |
| static enum lc_reg_lut_e reg_sel; |
| static int lc_temp; |
| static char lc_dbg_curve[100]; |
| static ssize_t amvecm_lc_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| ssize_t len = 0; |
| char *temp_cur; |
| |
| if (lc_dbg_flag & LC_CUR_RD_UPDATE) { |
| temp_cur = kmalloc(300, GFP_KERNEL); |
| if (!temp_cur) |
| return len; |
| memset(temp_cur, 0, 300); |
| |
| switch (reg_sel) { |
| case SATUR_LUT: |
| lc_rd_reg(SATUR_LUT, 1, temp_cur); |
| break; |
| case YMINVAL_LMT: |
| lc_rd_reg(YMINVAL_LMT, 1, temp_cur); |
| break; |
| case YPKBV_YMAXVAL_LMT: |
| lc_rd_reg(YPKBV_YMAXVAL_LMT, 1, temp_cur); |
| break; |
| case YMAXVAL_LMT: |
| lc_rd_reg(YMAXVAL_LMT, 1, temp_cur); |
| break; |
| case YPKBV_LMT: |
| lc_rd_reg(YPKBV_LMT, 1, temp_cur); |
| break; |
| case YPKBV_RAT: |
| lc_rd_reg(YPKBV_RAT, 1, temp_cur); |
| break; |
| default: |
| pr_info("unsupprt cmd!\n"); |
| break; |
| } |
| lc_dbg_flag &= ~LC_CUR_RD_UPDATE; |
| reg_sel = MAX_REG_LUT; |
| len = sprintf(buf, "%s\n", temp_cur); |
| kfree(temp_cur); |
| return len; |
| } |
| |
| if (lc_dbg_flag & LC_PARAM_RD_UPDATE) { |
| lc_dbg_flag &= ~LC_PARAM_RD_UPDATE; |
| return sprintf(buf, "%d\n", lc_temp); |
| } |
| |
| if (lc_dbg_flag & LC_CUR2_RD_UPDATE) { |
| lc_dbg_flag &= ~LC_CUR2_RD_UPDATE; |
| return sprintf(buf, "%s\n", lc_dbg_curve); |
| } |
| |
| 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"); |
| 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"); |
| len += sprintf(buf + len, |
| "echo lc_osd_setting show > /sys/class/amvecm/lc\n"); |
| len += sprintf(buf + len, |
| "echo lc_osd_setting set xxx ... xxx > /sys/class/amvecm/lc\n"); |
| len += sprintf(buf + len, |
| "echo osd_iir_en val > /sys/class/amvecm/lc\n"); |
| len += sprintf(buf + len, |
| "echo iir_refresh show > /sys/class/amvecm/lc\n"); |
| len += sprintf(buf + len, |
| "echo iir_refresh set xxx ... xxx > /sys/class/amvecm/lc\n"); |
| len += sprintf(buf + len, |
| "echo scene_change_th val > /sys/class/amvecm/lc\n"); |
| len += sprintf(buf + len, |
| "echo irr_dbg_en val > /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}; |
| int reg_lut[63] = {0}; |
| int h, v, i, start_point; |
| long val = 0; |
| char *stemp = NULL; |
| int curve_val[6] = {0}; |
| |
| if (!buf) |
| return count; |
| stemp = kzalloc(100, GFP_KERNEL); |
| if (!stemp) |
| return 0; |
| |
| memset(stemp, 0, 100); |
| memset(lc_dbg_curve, 0, sizeof(char) * 100); |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (!buf_orig) { |
| kfree(stemp); |
| return -ENOMEM; |
| } |
| 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_version")) { |
| pr_info("lc driver version : %s\n", LC_VER); |
| } else if (!strcmp(parm[0], "lc_dbg")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| amlc_debug = val; |
| } else if (!strcmp(parm[0], "lc_curve_isr")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| use_lc_curve_isr = val; |
| } else if (!strcmp(parm[0], "lc_demo_mode")) { |
| if (!strcmp(parm[1], "enable")) |
| lc_demo_mode = 1; |
| else if (!strcmp(parm[1], "disable")) |
| lc_demo_mode = 0; |
| else |
| pr_info("unsupprt cmd!\n"); |
| } else if (!strcmp(parm[0], "dump_lut_data")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| reg_sel = val; |
| if (reg_sel == SATUR_LUT) |
| lc_rd_reg(SATUR_LUT, 0, NULL); |
| else if (reg_sel == YMINVAL_LMT) |
| lc_rd_reg(YMINVAL_LMT, 0, NULL); |
| else if (reg_sel == YPKBV_YMAXVAL_LMT) |
| lc_rd_reg(YPKBV_YMAXVAL_LMT, 0, NULL); |
| else if (reg_sel == YMAXVAL_LMT) |
| lc_rd_reg(YMAXVAL_LMT, 0, NULL); |
| else if (reg_sel == YPKBV_LMT) |
| lc_rd_reg(YPKBV_LMT, 0, NULL); |
| else if (reg_sel == YPKBV_RAT) |
| lc_rd_reg(YPKBV_RAT, 0, NULL); |
| else if (reg_sel == YPKBV_SLP_LMT) |
| lc_rd_reg(YPKBV_SLP_LMT, 0, NULL); |
| else if (reg_sel == CNTST_LMT) |
| lc_rd_reg(CNTST_LMT, 0, NULL); |
| else |
| pr_info("unsupprt cmd!\n"); |
| } else if (!strcmp(parm[0], "dump_lut_str")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| reg_sel = val; |
| lc_dbg_flag |= LC_CUR_RD_UPDATE; |
| } else if (!strcmp(parm[0], "lc_wr_lut")) { |
| if (kstrtoul(parm[1], 16, &val) < 0) |
| goto free_buf; |
| reg_sel = val; |
| if (!parm[2]) |
| 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 == YMAXVAL_LMT) |
| lc_wr_reg(reg_lut, YMAXVAL_LMT); |
| else if (reg_sel == YPKBV_LMT) |
| lc_wr_reg(reg_lut, YPKBV_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 of one frame*/ |
| lc_hist_prcnt = 1; |
| amlc_debug = 0x8; |
| } else if (!strcmp(parm[1], "chosen")) { |
| /*dump multiple frames in selected area*/ |
| if (!parm[6]) |
| 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 = 0x6; |
| } 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 if (!strcmp(parm[0], "lc_osd_setting")) { |
| if (!strcmp(parm[1], "show")) { |
| pr_info("VNUM_STRT_BELOW: %d, VNUM_END_BELOW: %d\n", |
| vnum_start_below, vnum_end_below); |
| pr_info("VNUM_STRT_ABOVE: %d, VNUM_END_ABOVE: %d\n", |
| vnum_start_above, vnum_end_above); |
| pr_info("INVALID_BLK: %d, MIN_BV_PERCENT_TH: %d\n", |
| invalid_blk, min_bv_percent_th); |
| } else if (!strcmp(parm[1], "set")) { |
| if (!parm[7]) |
| goto free_buf; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| vnum_start_below = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| vnum_end_below = val; |
| if (kstrtoul(parm[4], 10, &val) < 0) |
| goto free_buf; |
| vnum_start_above = val; |
| if (kstrtoul(parm[5], 10, &val) < 0) |
| goto free_buf; |
| vnum_end_above = val; |
| if (kstrtoul(parm[6], 10, &val) < 0) |
| goto free_buf; |
| invalid_blk = val; |
| if (kstrtoul(parm[7], 10, &val) < 0) |
| goto free_buf; |
| min_bv_percent_th = val; |
| } else { |
| pr_info("unsupprt cmd!\n"); |
| } |
| } else if (!strcmp(parm[0], "osd_iir_en")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| osd_iir_en = val; |
| } else if (!strcmp(parm[0], "iir_refresh")) { |
| if (!strcmp(parm[1], "show")) { |
| pr_info("current state: alpha1: %d, alpha2: %d, refresh_bit: %d, ts: %d\n", |
| alpha1, alpha2, refresh_bit, ts); |
| } else if (!strcmp(parm[1], "set")) { |
| if (!parm[5]) |
| goto free_buf; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| alpha1 = val; |
| if (kstrtoul(parm[3], 10, &val) < 0) |
| goto free_buf; |
| alpha2 = val; |
| if (kstrtoul(parm[4], 10, &val) < 0) |
| goto free_buf; |
| refresh_bit = val; |
| if (kstrtoul(parm[5], 10, &val) < 0) |
| goto free_buf; |
| ts = val; |
| pr_info("after setting: alpha1: %d, alpha2: %d, refresh_bit: %d, ts: %d\n", |
| alpha1, alpha2, refresh_bit, ts); |
| } else { |
| pr_info("unsupprt cmd!\n"); |
| } |
| } else if (!strcmp(parm[0], "scene_change_th")) { |
| pr_info("current value: %d\n", scene_change_th); |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| scene_change_th = val; |
| pr_info("setting value: %d\n", scene_change_th); |
| } else if (!strcmp(parm[0], "irr_dbg_en")) { |
| pr_info("current value: %d\n", amlc_iir_debug_en); |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| amlc_iir_debug_en = val; |
| pr_info("setting value: %d\n", amlc_iir_debug_en); |
| } else if (!strcmp(parm[0], "get_blk_region")) { |
| val = READ_VPP_REG(LC_CURVE_HV_NUM); |
| h = (val >> 8) & 0x1f; |
| v = (val) & 0x1f; |
| if (!strcmp(parm[1], "htotal")) { |
| lc_temp = h; |
| lc_dbg_flag |= LC_PARAM_RD_UPDATE; |
| } else if (!strcmp(parm[1], "vtotal")) { |
| lc_temp = v; |
| lc_dbg_flag |= LC_PARAM_RD_UPDATE; |
| } else |
| pr_info("unsupprt cmd!\n"); |
| } else if (!strcmp(parm[0], "get_hist")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| h = val; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| v = val; |
| if (h > 11 || v > 7) |
| goto free_buf; |
| start_point = (12 * v + h) * 17; |
| for (i = 0; i < 17; i++) |
| d_convert_str(lc_hist[start_point + i] >> 4, |
| i, stemp, 4, 10); |
| memcpy(lc_dbg_curve, stemp, 100); |
| lc_dbg_flag |= LC_CUR2_RD_UPDATE; |
| } else if (!strcmp(parm[0], "get_curve")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| h = val; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| v = val; |
| if (h > 11 || v > 7) |
| goto free_buf; |
| start_point = (12 * v + h) * 6; |
| for (i = 0; i < 6; i++) |
| d_convert_str(curve_nodes_cur[start_point + i], |
| i, stemp, 4, 10); |
| memcpy(lc_dbg_curve, stemp, 100); |
| lc_dbg_flag |= LC_CUR2_RD_UPDATE; |
| } else if (!strcmp(parm[0], "set_curve")) { |
| if (!parm[3]) |
| goto free_buf; |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| h = val; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| v = val; |
| if (h > 11 || v > 7) |
| goto free_buf; |
| start_point = (12 * v + h) * 6; |
| str_sapr_to_d(parm[3], curve_val, 5); |
| for (i = 0; i < 6; i++) |
| curve_nodes_cur[start_point + i] = |
| curve_val[i]; |
| } else if (!strcmp(parm[0], "stop_refresh")) { |
| lc_curve_fresh = false; |
| } else if (!strcmp(parm[0], "refresh_curve")) { |
| lc_curve_fresh = true; |
| } else if (!strcmp(parm[0], "reg_lmtrat_sigbin")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_tune_curve.lc_reg_lmtrat_sigbin = val; |
| pr_info("reg_lmtrat_sigbin = %d\n", |
| lc_tune_curve.lc_reg_lmtrat_sigbin); |
| } else if (!strcmp(parm[0], "reg_lmtrat_thd_max")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_tune_curve.lc_reg_lmtrat_thd_max = val; |
| pr_info("reg_lmtrat_thd_max = %d\n", |
| lc_tune_curve.lc_reg_lmtrat_thd_max); |
| } else if (!strcmp(parm[0], "reg_lmtrat_thd_black")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_tune_curve.lc_reg_lmtrat_thd_black = val; |
| pr_info("reg_lmtrat_thd_black = %d\n", |
| lc_tune_curve.lc_reg_lmtrat_thd_black); |
| } else if (!strcmp(parm[0], "reg_thd_black")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_tune_curve.lc_reg_thd_black = val; |
| WRITE_VPP_REG_BITS(LC_STTS_BLACK_INFO, |
| lc_tune_curve.lc_reg_thd_black, 0, 8); |
| pr_info("reg_thd_black = %d\n", |
| lc_tune_curve.lc_reg_thd_black); |
| } else if (!strcmp(parm[0], "ypkBV_black_thd")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_tune_curve.ypkbv_black_thd = val; |
| pr_info("ypkBV_black_thd = %d\n", |
| lc_tune_curve.ypkbv_black_thd); |
| } else if (!strcmp(parm[0], "yminV_black_thd")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_tune_curve.yminv_black_thd = val; |
| pr_info("yminV_black_thd = %d\n", |
| lc_tune_curve.yminv_black_thd); |
| } else if (!strcmp(parm[0], "tune_curve_debug")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| lc_node_pos_v = val; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| lc_node_pos_h = val; |
| pr_info("tune_curve_debug pos = v %d h %d\n", |
| lc_node_pos_v, lc_node_pos_h); |
| } else if (!strcmp(parm[0], "tune_curve_en")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| tune_curve_en = val; |
| amlc_debug = 0xc; |
| lc_node_prcnt = 10; |
| pr_info("tune_curve_en = %d\n", tune_curve_en); |
| } else if (!strcmp(parm[0], "detect_signal_range_en")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| amlc_debug = 0xe; |
| detect_signal_range_en = val; |
| pr_info("detect_signal_range_en = %d\n", |
| detect_signal_range_en); |
| } else if (!strcmp(parm[0], "detect_signal_range_threshold")) { |
| if (kstrtoul(parm[1], 10, &val) < 0) |
| goto free_buf; |
| detect_signal_range_threshold_black = val; |
| if (kstrtoul(parm[2], 10, &val) < 0) |
| goto free_buf; |
| detect_signal_range_threshold_white = val; |
| amlc_debug = 0xe; |
| pr_info("detect_signal_range_threshold = %d %d\n", |
| detect_signal_range_threshold_black, |
| detect_signal_range_threshold_white); |
| } else { |
| pr_info("unsupprt cmd!\n"); |
| } |
| |
| kfree(buf_orig); |
| kfree(stemp); |
| return count; |
| |
| free_buf: |
| pr_info("Missing parameters !\n"); |
| kfree(buf_orig); |
| kfree(stemp); |
| return -EINVAL; |
| } |
| |
| static void def_hdr_sdr_mode(void) |
| { |
| if (((READ_VPP_REG(VD1_HDR2_CTRL) >> 13) & 0x1) && |
| ((READ_VPP_REG(OSD1_HDR2_CTRL) >> 13) & 0x1)) |
| sdr_mode = 2; |
| } |
| |
| void hdr_hist_config_int(void) |
| { |
| VSYNC_WRITE_VPP_REG(VD1_HDR2_HIST_CTRL, 0x5510); |
| VSYNC_WRITE_VPP_REG(VD1_HDR2_HIST_H_START_END, 0x10000); |
| VSYNC_WRITE_VPP_REG(VD1_HDR2_HIST_V_START_END, 0x0); |
| |
| if (get_cpu_type() != MESON_CPU_MAJOR_ID_T5 && |
| get_cpu_type() != MESON_CPU_MAJOR_ID_T5D) { |
| VSYNC_WRITE_VPP_REG(VD2_HDR2_HIST_CTRL, 0x5510); |
| VSYNC_WRITE_VPP_REG(VD2_HDR2_HIST_H_START_END, 0x10000); |
| VSYNC_WRITE_VPP_REG(VD2_HDR2_HIST_V_START_END, 0x0); |
| |
| VSYNC_WRITE_VPP_REG(OSD1_HDR2_HIST_CTRL, 0x5510); |
| VSYNC_WRITE_VPP_REG(OSD1_HDR2_HIST_H_START_END, 0x10000); |
| VSYNC_WRITE_VPP_REG(OSD1_HDR2_HIST_V_START_END, 0x0); |
| } |
| } |
| |
| #define PQ_TV 1 |
| #define PQ_BOX 0 |
| void init_pq_control(unsigned int enable) |
| { |
| if (enable) { |
| memcpy(&pq_cfg, &pq_cfg_init[TV_CFG_DEF], |
| sizeof(struct pq_ctrl_s)); |
| memcpy(&dv_cfg_bypass, &pq_cfg_init[TV_DV_BYPASS], |
| sizeof(struct pq_ctrl_s)); |
| } else { |
| memcpy(&pq_cfg, &pq_cfg_init[OTT_CFG_DEF], |
| sizeof(struct pq_ctrl_s)); |
| memcpy(&dv_cfg_bypass, &pq_cfg_init[OTT_DV_BYPASS], |
| sizeof(struct pq_ctrl_s)); |
| } |
| } |
| |
| int vinfo_lcd_support(void) |
| { |
| struct vinfo_s *vinfo = get_current_vinfo(); |
| if (vinfo->mode == VMODE_LCD || |
| vinfo->mode == VMODE_DUMMY_ENCP) |
| return 1; |
| else |
| return 0; |
| } |
| |
| /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */ |
| void init_pq_setting(void) |
| { |
| struct vinfo_s *vinfo = get_current_vinfo(); |
| |
| int bitdepth; |
| |
| if (vinfo_lcd_support()) |
| init_pq_control(PQ_TV); |
| else |
| init_pq_control(PQ_BOX); |
| |
| if (get_cpu_type() == MESON_CPU_MAJOR_ID_SC2) |
| init_pq_control(PQ_BOX); |
| |
| /*ai pq interface*/ |
| ai_detect_scene_init(); |
| adaptive_param_init(); |
| |
| if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || |
| is_meson_txlx_cpu() || is_meson_txhd_cpu() || |
| is_meson_tl1_cpu() || is_meson_tm2_cpu() || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5D || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T7 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T3 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5W) |
| goto tvchip_pq_setting; |
| else if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || |
| is_meson_sm1_cpu() || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_SC2 || |
| is_meson_s4_cpu() || |
| is_meson_s4d_cpu()) { |
| if (is_meson_s4_cpu()) |
| bitdepth = 10; |
| else |
| bitdepth = 12; |
| /*confirm with vlsi-Lunhai.Chen, for G12A/G12B, |
| *VPP_GCLK_CTRL1 must enable |
| */ |
| WRITE_VPP_REG_BITS(VPP_GCLK_CTRL1, 0xf, 0, 4); |
| sr_init_config(); |
| dnlp_init_config(); |
| cm_init_config(bitdepth); |
| /*dnlp off*/ |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, |
| DNLP_EN_BIT, DNLP_EN_WID); |
| /*sr0 chroma filter bypass*/ |
| WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_HCOEF0, |
| 0x4000); |
| WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_VCOEF0, |
| 0x4000); |
| |
| /*kernel sdr2hdr match uboot setting*/ |
| def_hdr_sdr_mode(); |
| vpp_pq_ctrl_config(pq_cfg); |
| } |
| return; |
| |
| tvchip_pq_setting: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { |
| if (is_meson_tl1_cpu()) |
| bitdepth = 10; |
| else if (get_cpu_type() == MESON_CPU_MAJOR_ID_T5 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5D || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T3 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5W) |
| bitdepth = 10; |
| else if (is_meson_tm2_cpu()) |
| bitdepth = 12; |
| else |
| bitdepth = 12; |
| |
| sr_init_config(); |
| dnlp_init_config(); |
| cm_init_config(bitdepth); |
| /*lc init*/ |
| lc_init(bitdepth); |
| |
| /*frequence meter init*/ |
| if (get_cpu_type() == MESON_CPU_MAJOR_ID_T3 || |
| get_cpu_type() == MESON_CPU_MAJOR_ID_T5W) |
| amve_fmeter_init(fmeter_en); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| hdr_hist_config_int(); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_T7)) |
| vpp_pst_hist_sta_config(1, HIST_MAXRGB, |
| AFTER_POST2_MTX, vinfo); |
| } |
| |
| /* enable vadj1 by default */ |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1); |
| else |
| VSYNC_WRITE_VPP_REG(VPP_VADJ_CTRL, 0xd); |
| |
| /*probe close sr0 peaking for switch on video*/ |
| WRITE_VPP_REG_BITS(VPP_SRSHARP0_CTRL, 1, 0, 1); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { |
| WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 0, 0, 1); |
| /*VPP_VADJ1_MISC bit1: minus black level enable for vadj1*/ |
| WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 1, 1); |
| } else { |
| WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 1, 0, 1); |
| } |
| /*default dnlp off*/ |
| WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE, |
| 0, 1, 1); |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE, |
| 0, 1, 1); |
| WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, DNLP_EN_BIT, DNLP_EN_WID); |
| /*end*/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { |
| WRITE_VPP_REG_BITS(SRSHARP1_PK_FINALGAIN_HP_BP, |
| 2, 16, 2); |
| |
| /*sr0 sr1 chroma filter bypass*/ |
| WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_HCOEF0, |
| 0x4000); |
| WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_VCOEF0, |
| 0x4000); |
| WRITE_VPP_REG(SRSHARP1_SHARP_SR2_CBIC_HCOEF0, |
| 0x4000); |
| WRITE_VPP_REG(SRSHARP1_SHARP_SR2_CBIC_VCOEF0, |
| 0x4000); |
| } |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| if (is_meson_gxlx_cpu()) |
| amve_sharpness_init(); |
| #endif |
| |
| /*dnlp alg parameters init*/ |
| dnlp_alg_param_init(); |
| vpp_pq_ctrl_config(pq_cfg); |
| } |
| |
| /* #endif*/ |
| |
| void amvecm_gamma_init(bool en) |
| { |
| unsigned int i; |
| unsigned short data[256]; |
| |
| for (i = 0; i < 256; i++) { |
| data[i] = i << 2; |
| video_gamma_table_r.data[i] = data[i]; |
| video_gamma_table_g.data[i] = data[i]; |
| video_gamma_table_b.data[i] = data[i]; |
| } |
| |
| if (cpu_after_eq_t7()) { |
| if (is_meson_t7_cpu()) { |
| for (i = 0; i < 3; i++) |
| lcd_gamma_api(i, video_gamma_table_r.data, |
| video_gamma_table_g.data, |
| video_gamma_table_b.data, |
| 0, 0); |
| } else { |
| lcd_gamma_api(0, video_gamma_table_r.data, |
| video_gamma_table_g.data, |
| video_gamma_table_b.data, |
| 0, 0); |
| } |
| } else { |
| vpp_disable_lcd_gamma_table(0, 0); |
| WRITE_VPP_REG_BITS(L_GAMMA_CNTL_PORT, |
| 0, GAMMA_EN, 1); |
| amve_write_gamma_table(data, |
| H_SEL_R); |
| amve_write_gamma_table(data, |
| H_SEL_G); |
| amve_write_gamma_table(data, |
| H_SEL_B); |
| } |
| |
| if (en) |
| vpp_enable_lcd_gamma_table(0, 0); |
| else |
| vpp_disable_lcd_gamma_table(0, 0); |
| } |
| |
| static void amvecm_wb_init(bool en) |
| { |
| int *initcoef; |
| |
| initcoef = wb_init_bypass_coef; |
| |
| if (video_rgb_ogo_xvy_mtx) { |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 3, 8, 3); |
| |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, |
| ((initcoef[0] & 0xfff) << 16) |
| | (initcoef[1] & 0xfff)); |
| WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, |
| initcoef[2] & 0xfff); |
| WRITE_VPP_REG(VPP_MATRIX_COEF00_01, |
| ((initcoef[3] & 0x1fff) << 16) |
| | (initcoef[4] & 0x1fff)); |
| WRITE_VPP_REG(VPP_MATRIX_COEF02_10, |
| ((initcoef[5] & 0x1fff) << 16) |
| | (initcoef[6] & 0x1fff)); |
| WRITE_VPP_REG(VPP_MATRIX_COEF11_12, |
| ((initcoef[7] & 0x1fff) << 16) |
| | (initcoef[8] & 0x1fff)); |
| WRITE_VPP_REG(VPP_MATRIX_COEF20_21, |
| ((initcoef[9] & 0x1fff) << 16) |
| | (initcoef[10] & 0x1fff)); |
| WRITE_VPP_REG(VPP_MATRIX_COEF22, |
| initcoef[11] & 0x1fff); |
| if (initcoef[21]) { |
| WRITE_VPP_REG(VPP_MATRIX_COEF13_14, |
| ((initcoef[12] & 0x1fff) << 16) |
| | (initcoef[13] & 0x1fff)); |
| WRITE_VPP_REG(VPP_MATRIX_COEF15_25, |
| ((initcoef[14] & 0x1fff) << 16) |
| | (initcoef[17] & 0x1fff)); |
| WRITE_VPP_REG(VPP_MATRIX_COEF23_24, |
| ((initcoef[15] & 0x1fff) << 16) |
| | (initcoef[16] & 0x1fff)); |
| } |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, |
| ((initcoef[18] & 0xfff) << 16) |
| | (initcoef[19] & 0xfff)); |
| WRITE_VPP_REG(VPP_MATRIX_OFFSET2, |
| initcoef[20] & 0xfff); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, |
| initcoef[21], 3, 2); |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, |
| initcoef[22], 5, 3); |
| |
| WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, en, 6, 1); |
| } else { |
| WRITE_VPP_REG(VPP_GAINOFF_CTRL0, |
| (en << 31) | (1024 << 16) | 1024); |
| WRITE_VPP_REG(VPP_GAINOFF_CTRL1, |
| (1024 << 16)); |
| } |
| } |
| |
| void amvecm_3dlut_init(bool en) |
| { |
| vpp_lut3d_table_init(-1, -1, -1); |
| vpp_set_lut3d(0, 0, 0, 0); |
| vpp_lut3d_table_release(); |
| |
| vpp_enable_lut3d(en); |
| } |
| |
| static struct class_attribute amvecm_class_attrs[] = { |
| __ATTR(debug, 0644, |
| amvecm_debug_show, amvecm_debug_store), |
| __ATTR(dnlp_debug, 0644, |
| amvecm_dnlp_debug_show, |
| amvecm_dnlp_debug_store), |
| __ATTR(cm2_hue, 0644, |
| amvecm_cm2_hue_show, |
| amvecm_cm2_hue_store), |
| __ATTR(cm2_luma, 0644, |
| amvecm_cm2_luma_show, |
| amvecm_cm2_luma_store), |
| __ATTR(cm2_sat, 0644, |
| amvecm_cm2_sat_show, |
| amvecm_cm2_sat_store), |
| __ATTR(cm2_hue_by_hs, 0644, |
| amvecm_cm2_hue_by_hs_show, |
| amvecm_cm2_hue_by_hs_store), |
| __ATTR(brightness, 0644, |
| amvecm_brightness_show, amvecm_brightness_store), |
| __ATTR(contrast, 0644, |
| amvecm_contrast_show, amvecm_contrast_store), |
| __ATTR(saturation_hue, 0644, |
| amvecm_saturation_hue_show, |
| amvecm_saturation_hue_store), |
| __ATTR(saturation_hue_pre, 0644, |
| amvecm_saturation_hue_pre_show, |
| amvecm_saturation_hue_pre_store), |
| __ATTR(saturation_hue_post, 0644, |
| amvecm_saturation_hue_post_show, |
| amvecm_saturation_hue_post_store), |
| __ATTR(cm2, 0644, |
| amvecm_cm2_show, |
| amvecm_cm2_store), |
| __ATTR(cm_reg, 0644, |
| amvecm_cm_reg_show, |
| amvecm_cm_reg_store), |
| __ATTR(gamma, 0644, |
| amvecm_gamma_show, |
| amvecm_gamma_store), |
| __ATTR(wb, 0644, |
| amvecm_wb_show, |
| amvecm_wb_store), |
| __ATTR(brightness1, 0644, |
| video_adj1_brightness_show, |
| video_adj1_brightness_store), |
| __ATTR(contrast1, 0644, |
| video_adj1_contrast_show, video_adj1_contrast_store), |
| __ATTR(brightness2, 0644, |
| video_adj2_brightness_show, video_adj2_brightness_store), |
| __ATTR(contrast2, 0644, |
| video_adj2_contrast_show, video_adj2_contrast_store), |
| __ATTR(help, 0644, |
| amvecm_usage_show, NULL), |
| /* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESONG9TV) */ |
| __ATTR(sync_3d, 0644, |
| amvecm_3d_sync_show, |
| amvecm_3d_sync_store), |
| __ATTR(vlock, 0644, |
| amvecm_vlock_show, |
| amvecm_vlock_store), |
| __ATTR(matrix_set, 0644, |
| amvecm_set_post_matrix_show, amvecm_set_post_matrix_store), |
| __ATTR(matrix_pos, 0644, |
| amvecm_post_matrix_pos_show, amvecm_post_matrix_pos_store), |
| __ATTR(matrix_data, 0644, |
| amvecm_post_matrix_data_show, amvecm_post_matrix_data_store), |
| __ATTR(dump_reg, 0644, |
| amvecm_dump_reg_show, amvecm_dump_reg_store), |
| __ATTR(sr1_reg, 0644, |
| amvecm_sr1_reg_show, amvecm_sr1_reg_store), |
| __ATTR(write_sr1_reg_val, 0644, |
| amvecm_write_sr1_reg_val_show, amvecm_write_sr1_reg_val_store), |
| __ATTR(dump_vpp_hist, 0644, |
| amvecm_dump_vpp_hist_show, amvecm_dump_vpp_hist_store), |
| __ATTR(hdr_dbg, 0644, |
| amvecm_hdr_dbg_show, amvecm_hdr_dbg_store), |
| __ATTR(hdr_reg, 0644, |
| amvecm_hdr_reg_show, amvecm_hdr_reg_store), |
| __ATTR(hdr_tmo, 0644, |
| amvecm_hdr_tmo_show, amvecm_hdr_tmo_store), |
| __ATTR(gamma_pattern, 0644, |
| set_gamma_pattern_show, set_gamma_pattern_store), |
| __ATTR(pc_mode, 0644, |
| amvecm_pc_mode_show, amvecm_pc_mode_store), |
| __ATTR(set_hdr_289lut, 0644, |
| set_hdr_289lut_show, set_hdr_289lut_store), |
| __ATTR(vpp_demo, 0644, |
| amvecm_vpp_demo_show, amvecm_vpp_demo_store), |
| __ATTR(reg, 0644, |
| amvecm_reg_show, amvecm_reg_store), |
| __ATTR(pq_user_set, 0644, |
| amvecm_pq_user_show, amvecm_pq_user_store), |
| __ATTR(pq_reg_rw, 0644, |
| amvecm_write_reg_show, amvecm_write_reg_store), |
| __ATTR(get_hdr_type, 0644, |
| 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(color_top, 0644, |
| amvecm_clamp_color_top_show, amvecm_clamp_color_top_store), |
| __ATTR(color_bottom, 0644, |
| amvecm_clamp_color_bottom_show, |
| amvecm_clamp_color_bottom_store), |
| __ATTR(cpu_ver, 0644, |
| amvecm_cpu_ver_show, |
| amvecm_cpu_ver_store), |
| __ATTR(cabc_aad, 0644, |
| amvecm_cabc_aad_show, |
| amvecm_cabc_aad_store), |
| __ATTR_NULL |
| }; |
| |
| void amvecm_wakeup_queue(void) |
| { |
| struct amvecm_dev_s *devp = &amvecm_dev; |
| |
| wake_up(&devp->hdr_queue); |
| } |
| |
| static unsigned int amvecm_poll(struct file *file, poll_table *wait) |
| { |
| struct amvecm_dev_s *devp = file->private_data; |
| unsigned int mask = 0; |
| |
| poll_wait(file, &devp->hdr_queue, wait); |
| mask = (POLLIN | POLLRDNORM); |
| |
| return mask; |
| } |
| |
| static const struct file_operations amvecm_fops = { |
| .owner = THIS_MODULE, |
| .open = amvecm_open, |
| .release = amvecm_release, |
| .unlocked_ioctl = amvecm_ioctl, |
| #ifdef CONFIG_COMPAT |
| .compat_ioctl = amvecm_compat_ioctl, |
| #endif |
| .poll = amvecm_poll, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_xxx = { |
| .vlk_chip = vlock_chip_txlx, |
| .vlk_support = true, |
| .vlk_new_fsm = 0, |
| .vlk_hwver = vlock_hw_org, |
| .vlk_phlock_en = false, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| static const struct vecm_match_data_s vecm_dt_tl1 = { |
| .vlk_chip = vlock_chip_tl1, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_ver2, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| #endif |
| |
| static const struct vecm_match_data_s vecm_dt_sm1 = { |
| .vlk_chip = vlock_chip_sm1, |
| .vlk_support = false, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_ver2, |
| .vlk_phlock_en = false, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_tm2 = { |
| .vlk_chip = vlock_chip_tm2, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_ver2, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_tm2_verb = { |
| .vlk_chip = vlock_chip_tm2, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_tm2verb, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_t5 = { |
| .vlk_chip = vlock_chip_t5, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_tm2verb, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_t5d = { |
| .vlk_chip = vlock_chip_t5,/*same as t5d*/ |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_tm2verb, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_t7 = { |
| .vlk_chip = vlock_chip_t7, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_tm2verb, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct vecm_match_data_s vecm_dt_t3 = { |
| .vlk_chip = vlock_chip_t3, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_tm2verb, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| .vlk_ctl_for_frc = 1, |
| }; |
| |
| /*t5w vlock follow t5 */ |
| static const struct vecm_match_data_s vecm_dt_t5w = { |
| .vlk_chip = vlock_chip_t5, |
| .vlk_support = true, |
| .vlk_new_fsm = 1, |
| .vlk_hwver = vlock_hw_tm2verb, |
| .vlk_phlock_en = true, |
| .vlk_pll_sel = vlock_pll_sel_tcon, |
| }; |
| |
| static const struct of_device_id aml_vecm_dt_match[] = { |
| { |
| .compatible = "amlogic, vecm", |
| .data = &vecm_dt_xxx, |
| }, |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| { |
| .compatible = "amlogic, vecm-tl1", |
| .data = &vecm_dt_tl1, |
| }, |
| #endif |
| { |
| .compatible = "amlogic, vecm-sm1", |
| .data = &vecm_dt_sm1, |
| }, |
| { |
| .compatible = "amlogic, vecm-tm2", |
| .data = &vecm_dt_tm2, |
| }, |
| { |
| .compatible = "amlogic, vecm-tm2-verb", |
| .data = &vecm_dt_tm2_verb, |
| }, |
| { |
| .compatible = "amlogic, vecm-t5", |
| .data = &vecm_dt_t5, |
| }, |
| { |
| .compatible = "amlogic, vecm-t5d", |
| .data = &vecm_dt_t5d, |
| }, |
| { |
| .compatible = "amlogic, vecm-t7", |
| .data = &vecm_dt_t7, |
| }, |
| { |
| .compatible = "amlogic, vecm-t3", |
| .data = &vecm_dt_t3, |
| }, |
| { |
| .compatible = "amlogic, vecm-t5w", |
| .data = &vecm_dt_t5w, |
| }, |
| {}, |
| }; |
| |
| static void aml_vecm_dt_parse(struct platform_device *pdev) |
| { |
| struct device_node *node; |
| unsigned int val; |
| int ret; |
| const struct of_device_id *of_id; |
| struct vecm_match_data_s *matchdata; |
| |
| node = pdev->dev.of_node; |
| /* get integer value */ |
| if (node) { |
| ret = of_property_read_u32(node, "gamma_en", &val); |
| if (ret) |
| pr_amvecm_dbg("Can't find gamma_en.\n"); |
| else |
| gamma_en = val; |
| ret = of_property_read_u32(node, "wb_en", &val); |
| if (ret) |
| pr_amvecm_dbg("Can't find wb_en.\n"); |
| else |
| wb_en = val; |
| ret = of_property_read_u32(node, "lut3d_en", &val); |
| if (ret) |
| pr_info("Can't find lut3d_en.\n"); |
| else |
| lut3d_en = val; |
| ret = of_property_read_u32(node, "cm_en", &val); |
| if (ret) |
| pr_amvecm_dbg("Can't find cm_en.\n"); |
| else |
| cm_en = val; |
| ret = of_property_read_u32(node, "detect_colorbar", &val); |
| if (ret) { |
| pr_amvecm_dbg("Can't find detect_colorbar.\n"); |
| } else { |
| if (val == 0) |
| pattern_mask = |
| pattern_mask & |
| (~PATTERN_MASK(PATTERN_75COLORBAR)); |
| else |
| pattern_mask = |
| pattern_mask | |
| PATTERN_MASK(PATTERN_75COLORBAR); |
| } |
| ret = of_property_read_u32(node, "detect_face", &val); |
| if (ret) { |
| pr_amvecm_dbg("Can't find detect_face.\n"); |
| } else { |
| if (val == 0) |
| pattern_mask = |
| pattern_mask & |
| (~PATTERN_MASK(PATTERN_SKIN_TONE_FACE)); |
| else |
| pattern_mask = |
| pattern_mask | |
| PATTERN_MASK(PATTERN_SKIN_TONE_FACE); |
| } |
| ret = of_property_read_u32(node, "detect_corn", &val); |
| if (ret) { |
| pr_amvecm_dbg("Can't find detect_corn.\n"); |
| } else { |
| if (val == 0) |
| pattern_mask = |
| pattern_mask & |
| (~PATTERN_MASK(PATTERN_GREEN_CORN)); |
| else |
| pattern_mask = |
| pattern_mask | |
| PATTERN_MASK(PATTERN_GREEN_CORN); |
| } |
| ret = of_property_read_u32(node, "wb_sel", &val); |
| if (ret) |
| pr_amvecm_dbg("Can't find wb_sel.\n"); |
| else |
| video_rgb_ogo_xvy_mtx = val; |
| |
| ret = of_property_read_u32(node, "hist_sel", &val); |
| if (ret) |
| pr_amvecm_dbg("Can't find hist_sel.\n"); |
| else |
| hist_chl = val; |
| |
| /*hdr:cfg:osd_100*/ |
| ret = of_property_read_u32(node, "cfg_en_osd_100", &val); |
| if (ret) { |
| hdr_set_cfg_osd_100(0); |
| pr_amvecm_dbg("hdr:Can't find cfg_en_osd_100.\n"); |
| |
| } else { |
| hdr_set_cfg_osd_100((int)val); |
| } |
| ret = of_property_read_u32(node, "tx_op_color_primary", &val); |
| if (ret) |
| pr_amvecm_dbg("Can't find tx_op_color_primary.\n"); |
| else |
| tx_op_color_primary = val; |
| |
| /*get compatible matched device, to get chip related data*/ |
| of_id = of_match_device(aml_vecm_dt_match, &pdev->dev); |
| if (of_id) { |
| pr_amvecm_dbg("%s", of_id->compatible); |
| matchdata = (struct vecm_match_data_s *)of_id->data; |
| } else { |
| matchdata = (struct vecm_match_data_s *)&vecm_dt_xxx; |
| pr_amvecm_dbg("unable to get matched device\n"); |
| } |
| vlock_dt_match_init(matchdata); |
| |
| /*vlock param config*/ |
| vlock_param_config(node); |
| vlock_clk_config(&pdev->dev); |
| |
| vlock_status_init(); |
| } |
| /* init module status */ |
| #ifdef CONFIG_AMLOGIC_PIXEL_PROBE |
| vpp_probe_enable(); |
| #endif |
| amvecm_wb_init(wb_en); |
| amvecm_gamma_init(gamma_en); |
| amvecm_3dlut_init(lut3d_en); |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (!is_dolby_vision_enable()) |
| #endif |
| WRITE_VPP_REG_BITS(VPP_MISC, 1, 28, 1); |
| if (cm_en) { |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (!is_dolby_vision_enable()) |
| #endif |
| amcm_enable(); |
| } else { |
| amcm_disable(); |
| } |
| /* WRITE_VPP_REG_BITS(VPP_MISC, cm_en, 28, 1); */ |
| |
| res_viu2_vsync_irq = |
| platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync2"); |
| res_lc_curve_irq = |
| platform_get_resource_byname(pdev, IORESOURCE_IRQ, "lc_curve"); |
| } |
| |
| #ifdef CONFIG_AMLOGIC_LCD |
| static int aml_lcd_gamma_notifier(struct notifier_block *nb, |
| unsigned long event, void *data) |
| { |
| if ((event & LCD_EVENT_GAMMA_UPDATE) == 0) |
| return NOTIFY_DONE; |
| |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_R; |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_G; |
| vecm_latch_flag |= FLAG_GAMMA_TABLE_B; |
| |
| gamma_index = *(unsigned int *)data; |
| return NOTIFY_OK; |
| } |
| |
| static struct notifier_block aml_lcd_gamma_nb = { |
| .notifier_call = aml_lcd_gamma_notifier, |
| }; |
| #endif |
| |
| static struct notifier_block vlock_notifier_nb = { |
| .notifier_call = vlock_notify_callback, |
| }; |
| |
| static int aml_vecm_viu2_vsync_irq_init(void) |
| { |
| if (res_viu2_vsync_irq) { |
| if (request_irq(res_viu2_vsync_irq->start, |
| amvecm_viu2_vsync_isr, IRQF_SHARED, |
| "amvecm_vsync2", (void *)"amvecm_vsync2")) { |
| pr_err("can't request amvecm_vsync2_irq\n"); |
| } else { |
| pr_info("request amvecm_vsync2_irq successful\n"); |
| } |
| } |
| |
| return 0; |
| } |
| |
| static int aml_vecm_lc_curve_irq_init(void) |
| { |
| if (res_lc_curve_irq) { |
| if (request_irq(res_lc_curve_irq->start, |
| amvecm_lc_curve_isr, IRQF_SHARED, |
| "lc_curve_isr", (void *)"lc_curve_isr")) { |
| pr_err("can't request res_lc_curve_irq\n"); |
| } else { |
| lc_curve_isr_defined = 1; |
| pr_info("request res_lc_curve_irq successful\n"); |
| } |
| } |
| |
| return 0; |
| } |
| |
| static int aml_vecm_probe(struct platform_device *pdev) |
| { |
| int ret = 0; |
| int i = 0; |
| |
| struct amvecm_dev_s *devp = &amvecm_dev; |
| |
| memset(devp, 0, (sizeof(struct amvecm_dev_s))); |
| pr_info("\n VECM probe start\n"); |
| ret = alloc_chrdev_region(&devp->devno, 0, 1, AMVECM_NAME); |
| if (ret < 0) |
| goto fail_alloc_region; |
| |
| devp->clsp = class_create(THIS_MODULE, AMVECM_CLASS_NAME); |
| if (IS_ERR(devp->clsp)) { |
| ret = PTR_ERR(devp->clsp); |
| goto fail_create_class; |
| } |
| for (i = 0; amvecm_class_attrs[i].attr.name; i++) { |
| if (class_create_file(devp->clsp, &amvecm_class_attrs[i]) < 0) |
| goto fail_class_create_file; |
| } |
| cdev_init(&devp->cdev, &amvecm_fops); |
| devp->cdev.owner = THIS_MODULE; |
| ret = cdev_add(&devp->cdev, devp->devno, 1); |
| if (ret) |
| goto fail_add_cdev; |
| |
| devp->dev = device_create(devp->clsp, NULL, devp->devno, |
| NULL, AMVECM_NAME); |
| if (IS_ERR(devp->dev)) { |
| ret = PTR_ERR(devp->dev); |
| goto fail_create_device; |
| } |
| |
| spin_lock_init(&vpp_lcd_gamma_lock); |
| mutex_init(&vpp_lut3d_lock); |
| #ifdef CONFIG_AMLOGIC_LCD |
| ret = aml_lcd_notifier_register(&aml_lcd_gamma_nb); |
| if (ret) |
| pr_info("register aml_lcd_gamma_notifier failed\n"); |
| |
| INIT_WORK(&aml_lcd_vlock_param_work, vlock_lcd_param_work); |
| #endif |
| /* register vout client */ |
| vout_register_client(&vlock_notifier_nb); |
| |
| init_pattern_detect(); |
| /* #endif */ |
| vpp_get_hist_en(); |
| |
| if (is_meson_txlx_cpu()) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| vpp_set_12bit_datapath2(); |
| /*post matrix 12bit yuv2rgb*/ |
| /* mtx_sel_dbg |= 1 << VPP_MATRIX_2; */ |
| /* amvecm_vpp_mtx_debug(mtx_sel_dbg, 1);*/ |
| WRITE_VPP_REG(VPP_MATRIX_PROBE_POS, 0x1fff1fff); |
| #endif |
| } else if (is_meson_txhd_cpu()) { |
| vpp_set_10bit_datapath1(); |
| } else if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) { |
| vpp_set_12bit_datapath_g12a(); |
| } |
| memset(&vpp_hist_param.vpp_histgram[0], |
| 0, sizeof(unsigned short) * 64); |
| /* box sdr_mode:auto, tv sdr_mode:off */ |
| /* disable contrast and saturation adjustment for HDR on TV */ |
| /* disable SDR to HDR convert on TV */ |
| if (is_meson_gxl_cpu() || is_meson_gxm_cpu()) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| hdr_flag = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); |
| #endif |
| } else { |
| hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (1 << 4); |
| } |
| hdr_init(&amvecm_dev.hdr_d); |
| aml_vecm_dt_parse(pdev); |
| |
| init_pq_setting(); |
| aml_vecm_viu2_vsync_irq_init(); |
| lc_curve_isr_defined = 0; |
| aml_vecm_lc_curve_irq_init(); |
| |
| |
| aml_cabc_queue = create_workqueue("cabc workqueue"); |
| if (!aml_cabc_queue) { |
| pr_amvecm_dbg("cacb queue create failed"); |
| ret = -1; |
| goto fail_create_wq; |
| } |
| INIT_WORK(&cabc_proc_work, aml_cabc_alg_process); |
| INIT_WORK(&cabc_bypass_work, aml_cabc_alg_bypass); |
| |
| probe_ok = 1; |
| pr_info("%s: ok\n", __func__); |
| return 0; |
| |
| fail_create_device: |
| pr_info("[amvecm.] : amvecm device create error.\n"); |
| cdev_del(&devp->cdev); |
| return ret; |
| fail_add_cdev: |
| pr_info("[amvecm.] : amvecm add device error.\n"); |
| return ret; |
| fail_class_create_file: |
| pr_info("[amvecm.] : amvecm class create file error.\n"); |
| for (i = 0; amvecm_class_attrs[i].attr.name; i++) { |
| class_remove_file(devp->clsp, |
| &amvecm_class_attrs[i]); |
| } |
| class_destroy(devp->clsp); |
| return ret; |
| fail_create_class: |
| pr_info("[amvecm.] : amvecm class create error.\n"); |
| unregister_chrdev_region(devp->devno, 1); |
| return ret; |
| fail_alloc_region: |
| pr_info("[amvecm.] : amvecm alloc error.\n"); |
| pr_info("[amvecm.] : amvecm_init.\n"); |
| return ret; |
| fail_create_wq: |
| pr_info("[amvecm.] : amvecm create wq error\n"); |
| return ret; |
| } |
| |
| static int __exit aml_vecm_remove(struct platform_device *pdev) |
| { |
| struct amvecm_dev_s *devp = &amvecm_dev; |
| |
| if (res_viu2_vsync_irq) { |
| free_irq(res_viu2_vsync_irq->start, |
| (void *)"amvecm_vsync2"); |
| } |
| |
| hdr_exit(); |
| device_destroy(devp->clsp, devp->devno); |
| cdev_del(&devp->cdev); |
| class_destroy(devp->clsp); |
| unregister_chrdev_region(devp->devno, 1); |
| #ifdef CONFIG_AMLOGIC_LCD |
| aml_lcd_notifier_unregister(&aml_lcd_gamma_nb); |
| cancel_work_sync(&aml_lcd_vlock_param_work); |
| #endif |
| probe_ok = 0; |
| lc_free(); |
| pr_info("[amvecm.] : amvecm_exit.\n"); |
| return 0; |
| } |
| |
| #ifdef CONFIG_PM |
| static int amvecm_drv_suspend(struct platform_device *pdev, |
| pm_message_t state) |
| { |
| if (probe_ok == 1) |
| probe_ok = 0; |
| pr_info("amvecm: suspend module\n"); |
| return 0; |
| } |
| |
| static int amvecm_drv_resume(struct platform_device *pdev) |
| { |
| if (probe_ok == 0) |
| probe_ok = 1; |
| |
| pr_info("amvecm: resume module\n"); |
| return 0; |
| } |
| #endif |
| |
| static void amvecm_shutdown(struct platform_device *pdev) |
| { |
| struct amvecm_dev_s *devp = &amvecm_dev; |
| |
| hdr_exit(); |
| ve_disable_dnlp(); |
| amcm_disable(); |
| WRITE_VPP_REG(VPP_VADJ_CTRL, 0x0); |
| amvecm_wb_enable(0); |
| /*dnlp cm vadj1 wb gate*/ |
| WRITE_VPP_REG(VPP_GCLK_CTRL0, 0x11000400); |
| WRITE_VPP_REG(VPP_GCLK_CTRL1, 0x14); |
| pr_info("amvecm: shutdown module\n"); |
| |
| device_destroy(devp->clsp, devp->devno); |
| cdev_del(&devp->cdev); |
| class_destroy(devp->clsp); |
| unregister_chrdev_region(devp->devno, 1); |
| #ifdef CONFIG_AML_LCD |
| aml_lcd_notifier_unregister(&aml_lcd_gamma_nb); |
| #endif |
| lc_free(); |
| } |
| |
| static struct platform_driver aml_vecm_driver = { |
| .driver = { |
| .name = "aml_vecm", |
| .owner = THIS_MODULE, |
| .of_match_table = aml_vecm_dt_match, |
| }, |
| .probe = aml_vecm_probe, |
| .shutdown = amvecm_shutdown, |
| .remove = __exit_p(aml_vecm_remove), |
| #ifdef CONFIG_PM |
| .suspend = amvecm_drv_suspend, |
| .resume = amvecm_drv_resume, |
| #endif |
| |
| }; |
| |
| int __init aml_vecm_init(void) |
| { |
| /*unsigned int hiu_reg_base;*/ |
| |
| pr_info("%s:module init\n", __func__); |
| |
| if (platform_driver_register(&aml_vecm_driver)) { |
| pr_err("failed to register bl driver module\n"); |
| return -ENODEV; |
| } |
| |
| return 0; |
| } |
| |
| void __exit aml_vecm_exit(void) |
| { |
| pr_info("%s:module exit\n", __func__); |
| /*iounmap(amvecm_hiu_reg_base);*/ |
| platform_driver_unregister(&aml_vecm_driver); |
| } |
| |
| //MODULE_VERSION(AMVECM_VER); |
| //MODULE_DESCRIPTION("AMLOGIC amvecm driver"); |
| //MODULE_LICENSE("GPL"); |
| |