[PATCH 4/5] media: platform: visconti: Add Toshiba VIIF image signal processor driver

From: Yuji Ishikawa
Date: Wed Apr 13 2022 - 05:44:52 EST


Add support to Video Input Interface on Toshiba Visconti ARM SoCs.
Functions in this commit are drivers for the integrated Image Signal Processor.

Signed-off-by: Yuji Ishikawa <yuji2.ishikawa@xxxxxxxxxxxxx>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@xxxxxxxxxxxxx>
---
drivers/media/platform/visconti/Makefile | 2 +-
drivers/media/platform/visconti/hwd_viif.h | 942 ++++
.../media/platform/visconti/hwd_viif_l1isp.c | 3769 +++++++++++++++++
drivers/media/platform/visconti/viif.c | 554 +++
include/uapi/linux/visconti_viif.h | 1327 ++++++
5 files changed, 6593 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/visconti/hwd_viif_l1isp.c

diff --git a/drivers/media/platform/visconti/Makefile b/drivers/media/platform/visconti/Makefile
index 6463f33f0..3a9e04d0b 100644
--- a/drivers/media/platform/visconti/Makefile
+++ b/drivers/media/platform/visconti/Makefile
@@ -4,6 +4,6 @@
#

visconti-viif-objs = viif.o
-visconti-viif-objs += hwd_viif_csi2rx.o hwd_viif.o
+visconti-viif-objs += hwd_viif_csi2rx.o hwd_viif.o hwd_viif_l1isp.o

obj-$(CONFIG_VIDEO_VISCONTI_VIIF) += visconti-viif.o
diff --git a/drivers/media/platform/visconti/hwd_viif.h b/drivers/media/platform/visconti/hwd_viif.h
index 86d2be9f7..c0cc83473 100644
--- a/drivers/media/platform/visconti/hwd_viif.h
+++ b/drivers/media/platform/visconti/hwd_viif.h
@@ -546,6 +546,883 @@ struct hwd_viif_isp_regbuf_status {
bool write_err;
};

+/**
+ * struct hwd_viif_l1_raw_input_order - HWD L1ISP RAW input mode parameters
+ * @input_order_high; high sensitivity image position [0..input_num] For input_num, refer to #drv_VIIF_open
+ * @input_order_middle; middle sensitivity image or LED image position [0..input_num] For input_num, refer to #drv_VIIF_open
+ * @input_order_low; low sensitivity image position [0..input_num] For input_num, refer to #drv_VIIF_open
+ *
+ * When input_num is set, the corresponding image is not input.
+ */
+struct hwd_viif_l1_raw_input_order {
+ uint32_t input_order_high;
+ uint32_t input_order_middle;
+ uint32_t input_order_low;
+};
+
+/**
+ * struct hwd_viif_l1_ag_mode - HWD L1ISP AG mode parameters
+ * @sysm_ag_grad[4]: analog gain slope [0..255] (element is id)
+ * @sysm_ag_ofst[4]: analog gain offset [0..65535] (element is id)
+ * @sysm_ag_cont_hobc_en_high: enable/disable to control analog gain for high sensitivity image of OBCC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_hobc_high: analog gain id for high sensitivity image of OBCC [0..3]
+ * @sysm_ag_cont_hobc_en_middle_led: enable/disable to control analog gain for middle sensitivity or led image of OBCC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_hobc_middle_led: analog gain id for middle sensitivity or led image of OBCC [0..3]
+ * @sysm_ag_cont_hobc_en_low: enable/disable to control analog gain for low sensitivity image of OBCC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_hobc_low: analog gain id for low sensitivity image of OBCC [0..3]
+ * @sysm_ag_cont_abpc_en_high: enable/disable to control analog gain for high sensitivity image of ABPC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_abpc_high: analog gain id for high sensitivity image of ABPC [0..3]
+ * @sysm_ag_cont_abpc_en_middle_led: enable/disable to control analog gain for middle sensitivity or led image of ABPC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_abpc_middle_led: analog gain id for middle sensitivity or led image of ABPC [0..3]
+ * @sysm_ag_cont_abpc_en_low: enable/disable to control analog gain for low sensitivity image of ABPC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_abpc_low: analog gain id for low sensitivity image of ABPC [0..3]
+ * @sysm_ag_cont_rcnr_en_high: enable/disable to control analog gain for high sensitivity image of RCNR @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_rcnr_high: analog gain id for high sensitivity image of RCNR [0..3]
+ * @sysm_ag_cont_rcnr_en_middle_led: enable/disable to control analog gain for middle sensitivity or led image of RCNR @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_rcnr_middle_led: analog gain id for middle sensitivity or led image of RCNR [0..3]
+ * @sysm_ag_cont_rcnr_en_low: enable/disable to control analog gain for low sensitivity image of RCNR @ref hwd_VIIF_enable_flag
+ * @sysm_ag_psel_rcnr_low: analog gain id for low sensitivity image of RCNR [0..3]
+ * @sysm_ag_cont_lssc_en: enable/disable to control analog gain for LSSC @ref hwd_VIIF_enable_flag
+ * @sysm_ag_ssel_lssc: sensitive image used for LSSC @ref hwd_VIIF_l1_img_sens
+ * @sysm_ag_psel_lssc: analog gain id for LSSC [0..3]
+ * @sysm_ag_cont_mpro_en: enable/disable to control analog gain for color matrix @ref hwd_VIIF_enable_flag
+ * @sysm_ag_ssel_mpro: sensitive image used for color matrix @ref hwd_VIIF_l1_img_sens
+ * @sysm_ag_psel_mpro: analog gain id for color matrix [0..3]
+ * @sysm_ag_cont_vpro_en: enable/disable to control analog gain for image adjustment @ref hwd_VIIF_enable_flag
+ * @sysm_ag_ssel_vpro: sensitive image used for image adjustment @ref hwd_VIIF_l1_img_sens
+ * @sysm_ag_psel_vpro: analog gain id for image adjustment [0..3]
+ * @sysm_ag_cont_hobc_test_high: manual analog gain for high sensitivity image of OBCC [0..255]
+ * @sysm_ag_cont_hobc_test_middle_led: manual analog gain for middle sensitivity or led image of OBCC [0..255]
+ * @sysm_ag_cont_hobc_test_low: manual analog gain for low sensitivity image of OBCC [0..255]
+ * @sysm_ag_cont_abpc_test_high: manual analog gain for high sensitivity image of ABPC [0..255]
+ * @sysm_ag_cont_abpc_test_middle_led: manual analog gain for middle sensitivity or led image of ABPC [0..255]
+ * @sysm_ag_cont_abpc_test_low: manual analog gain for low sensitivity image of ABPC [0..255]
+ * @sysm_ag_cont_rcnr_test_high: manual analog gain for high sensitivity image of RCNR [0..255]
+ * @sysm_ag_cont_rcnr_test_middle_led: manual analog gain for middle sensitivity or led image of RCNR [0..255]
+ * @sysm_ag_cont_rcnr_test_low: manual analog gain for low sensitivity image of RCNR [0..255]
+ * @sysm_ag_cont_lssc_test: manual analog gain for LSSC [0..255]
+ * @sysm_ag_cont_mpro_test: manual analog gain for color matrix [0..255]
+ * @sysm_ag_cont_vpro_test: manual analog gain for image adjustment [0..255]
+ */
+struct hwd_viif_l1_ag_mode {
+ uint8_t sysm_ag_grad[4];
+ uint16_t sysm_ag_ofst[4];
+ uint32_t sysm_ag_cont_hobc_en_high;
+ uint32_t sysm_ag_psel_hobc_high;
+ uint32_t sysm_ag_cont_hobc_en_middle_led;
+ uint32_t sysm_ag_psel_hobc_middle_led;
+ uint32_t sysm_ag_cont_hobc_en_low;
+ uint32_t sysm_ag_psel_hobc_low;
+ uint32_t sysm_ag_cont_abpc_en_high;
+ uint32_t sysm_ag_psel_abpc_high;
+ uint32_t sysm_ag_cont_abpc_en_middle_led;
+ uint32_t sysm_ag_psel_abpc_middle_led;
+ uint32_t sysm_ag_cont_abpc_en_low;
+ uint32_t sysm_ag_psel_abpc_low;
+ uint32_t sysm_ag_cont_rcnr_en_high;
+ uint32_t sysm_ag_psel_rcnr_high;
+ uint32_t sysm_ag_cont_rcnr_en_middle_led;
+ uint32_t sysm_ag_psel_rcnr_middle_led;
+ uint32_t sysm_ag_cont_rcnr_en_low;
+ uint32_t sysm_ag_psel_rcnr_low;
+ uint32_t sysm_ag_cont_lssc_en;
+ uint32_t sysm_ag_ssel_lssc;
+ uint32_t sysm_ag_psel_lssc;
+ uint32_t sysm_ag_cont_mpro_en;
+ uint32_t sysm_ag_ssel_mpro;
+ uint32_t sysm_ag_psel_mpro;
+ uint32_t sysm_ag_cont_vpro_en;
+ uint32_t sysm_ag_ssel_vpro;
+ uint32_t sysm_ag_psel_vpro;
+ uint8_t sysm_ag_cont_hobc_test_high;
+ uint8_t sysm_ag_cont_hobc_test_middle_led;
+ uint8_t sysm_ag_cont_hobc_test_low;
+ uint8_t sysm_ag_cont_abpc_test_high;
+ uint8_t sysm_ag_cont_abpc_test_middle_led;
+ uint8_t sysm_ag_cont_abpc_test_low;
+ uint8_t sysm_ag_cont_rcnr_test_high;
+ uint8_t sysm_ag_cont_rcnr_test_middle_led;
+ uint8_t sysm_ag_cont_rcnr_test_low;
+ uint8_t sysm_ag_cont_lssc_test;
+ uint8_t sysm_ag_cont_mpro_test;
+ uint8_t sysm_ag_cont_vpro_test;
+};
+
+/**
+ * struct hwd_viif_l1_hdre - HWD L1ISP HDR extension parameters
+ * @hdre_src_point: the number of knee points, N of PWL compression signal [0x0..0x3fff]
+ * @hdre_dst_base: the offset value of HDR signal of the knee area, M [0x0..0xffffff]
+ * @hdre_ratio: output pixel ratio at the area M [0x0..0x3FFFFF] accuracy: 1/64
+ * @hdre_dst_max_val: the maximum value of output pixel [0x0..0xffffff]
+ */
+struct hwd_viif_l1_hdre {
+ uint32_t hdre_src_point[16];
+ uint32_t hdre_dst_base[17];
+ uint32_t hdre_ratio[17];
+ uint32_t hdre_dst_max_val;
+};
+
+/**
+ * struct hwd_viif_l1_dpc - HWD L1ISP defect pixel correction parameters
+ *
+ * @abpc_sta_en: enable/disable static defect pixel correction @ref hwd_VIIF_enable_flag
+ * @abpc_dyn_en: enable/disable dynamic defect pixel correction @ref hwd_VIIF_enable_flag
+ * @abpc_dyn_mode: enable/disable dynamic defect pixel correction @ref hwd_VIIF_l1_dpc
+ * @abpc_ratio_limit: ratio limit for defect pixel correction [0..1023]
+ * @abpc_dark_limit: ratio limit for white defect pixel correction in dark area [0..1023]
+ * @abpc_sn_coef_w_ag_min: luminance difference adjustment value for white defect pixel correction(under lower threshold) [1..31]
+ * @abpc_sn_coef_w_ag_mid: luminance difference adjustment value for white defect pixel correction(between lower and upper threshold) [1..31]
+ * @abpc_sn_coef_w_ag_max: luminance difference adjustment value for white defect pixel correction(over upper threshold) [1..31]
+ * @abpc_sn_coef_b_ag_min: luminance difference adjustment value for black defect pixel correction(under lower threshold) [1..31]
+ * @abpc_sn_coef_b_ag_mid: luminance difference adjustment value for black defect pixel correction(between lower and upper threshold) [1..31]
+ * @abpc_sn_coef_b_ag_max: luminance difference adjustment value for black defect pixel correction(over upper threshold) [1..31]
+ * @abpc_sn_coef_w_th_min: analog gain lower threshold for luminance difference adjustment for white defect pixel correction [0..255]
+ * @abpc_sn_coef_w_th_max: analog gain upper threshold for luminance difference adjustment for white defect pixel correction [0..255]
+ * @abpc_sn_coef_b_th_min: analog gain lower threshold for luminance difference adjustment for black defect pixel correction [0..255]
+ * @abpc_sn_coef_b_th_max: analog gain upper threshold for luminance difference adjustment for black defect pixel correction [0..255]
+ *
+ * it is necessary to keep the following relation for each parameters
+ * - *_th_min < *_th_max
+ */
+struct hwd_viif_l1_dpc {
+ uint32_t abpc_sta_en;
+ uint32_t abpc_dyn_en;
+ uint32_t abpc_dyn_mode;
+ uint32_t abpc_ratio_limit;
+ uint32_t abpc_dark_limit;
+ uint32_t abpc_sn_coef_w_ag_min;
+ uint32_t abpc_sn_coef_w_ag_mid;
+ uint32_t abpc_sn_coef_w_ag_max;
+ uint32_t abpc_sn_coef_b_ag_min;
+ uint32_t abpc_sn_coef_b_ag_mid;
+ uint32_t abpc_sn_coef_b_ag_max;
+ uint8_t abpc_sn_coef_w_th_min;
+ uint8_t abpc_sn_coef_w_th_max;
+ uint8_t abpc_sn_coef_b_th_min;
+ uint8_t abpc_sn_coef_b_th_max;
+};
+
+/**
+ * struct hwd_viif_l1_preset_white_balance - HWD L1ISP preset white balance parameters
+ * @gain_gr; Gr gain value [0..0x7FFFF]
+ * @gain_r; R gain value [0..0x7FFFF]
+ * @gain_b; B gain value [0..0x7FFFF]
+ * @gain_gb; Gb gain value [0..0x7FFFF]
+ *
+ * accuracy of each parameter is 1/16384
+ */
+struct hwd_viif_l1_preset_white_balance {
+ uint32_t gain_gr;
+ uint32_t gain_r;
+ uint32_t gain_b;
+ uint32_t gain_gb;
+};
+
+/**
+ * struct hwd_viif_l1_raw_color_noise_reduction - HWD L1ISP raw color noise reduction parameters
+ * @rcnr_sw: enable/disable raw color noise reduction @ref hwd_VIIF_enable_flag
+ * @rcnr_cnf_dark_ag0: maximum value for LSF noise reduction in dark [0..63]
+ * @rcnr_cnf_dark_ag1: middle value for LSF noise reduction in dark [0..63]
+ * @rcnr_cnf_dark_ag2: minimum value for LSF noise reduction in dark [0..63]
+ * @rcnr_cnf_ratio_ag0: maximum value for LSF luminance linkage noise reduction [0..31]
+ * @rcnr_cnf_ratio_ag1: middle value for LSF luminance linkage noise reduction [0..31]
+ * @rcnr_cnf_ratio_ag2: minimum value for LSF luminance linkage noise reduction [0..31]
+ * @rcnr_cnf_clip_gain_r: R gain value to adjust correction width of LSF [0..3]
+ * @rcnr_cnf_clip_gain_g: G gain value to adjust correction width of LSF [0..3]
+ * @rcnr_cnf_clip_gain_b: B gain value to adjust correction width of LSF [0..3]
+ * @rcnr_a1l_dark_ag0: maximum value for MSF noise reduction in dark [0..63]
+ * @rcnr_a1l_dark_ag1: middle value for MSF noise reduction in dark [0..63]
+ * @rcnr_a1l_dark_ag2: minimum value for MSF noise reduction in dark [0..63]
+ * @rcnr_a1l_ratio_ag0: maximum value for MSF luminance linkage noise reduction [0..31]
+ * @rcnr_a1l_ratio_ag1: middle value for MSF luminance linkage noise reduction [0..31]
+ * @rcnr_a1l_ratio_ag2: minimum value for MSF luminance linkage noise reduction [0..31]
+ * @rcnr_inf_zero_clip: clip value [0..256]
+ * @rcnr_merge_d2blend_ag0: maximum blend ratio for input data and filtered input data [0..16]
+ * @rcnr_merge_d2blend_ag1: middle blend ratio for input data and filtered input data [0..16]
+ * @rcnr_merge_d2blend_ag2: minimum blend ratio for input data and filtered input data [0..16]
+ * @rcnr_merge_black: minimum black level value [0..64]
+ * @rcnr_merge_mindiv: 0div guard value for inverse operator [4..16]
+ * @rcnr_hry_type: HSF filter type @ref hwd_VIIF_l1_rcnr_hry_type
+ * @rcnr_anf_blend_ag0: maximum blend ratio for MSF result for write back data to line memory @ref hwd_VIIF_l1_rcnr_msf_blend_ratio
+ * @rcnr_anf_blend_ag1: middle blend ratio for MSF result for write back data to line memory @ref hwd_VIIF_l1_rcnr_msf_blend_ratio
+ * @rcnr_anf_blend_ag2: minimum blend ratio for MSF result for write back data to line memory @ref hwd_VIIF_l1_rcnr_msf_blend_ratio
+ * @rcnr_lpf_threshold: multiplication value at calculating MSF noise [0x0..0x1F] accuracy: 1/8
+ * @rcnr_merge_hlblend_ag0: maximum value of generating luminance signal blend [0..2]
+ * @rcnr_merge_hlblend_ag1: middle value of generating luminance signal blend [0..2]
+ * @rcnr_merge_hlblend_ag2: minimum value of generating luminance signal blend [0..2]
+ * @rcnr_gnr_sw: enable/disable Gr/Gb sensitivity ratio correction
+ * @rcnr_gnr_ratio: upper limit ratio of Gr/Gb sensitivity ratio
+ * @rcnr_gnr_wide_en: enable/disable that upper limit ratio of Gr/Gb is double @ref hwd_VIIF_enable_flag
+ */
+struct hwd_viif_l1_raw_color_noise_reduction {
+ uint32_t rcnr_sw;
+ uint32_t rcnr_cnf_dark_ag0;
+ uint32_t rcnr_cnf_dark_ag1;
+ uint32_t rcnr_cnf_dark_ag2;
+ uint32_t rcnr_cnf_ratio_ag0;
+ uint32_t rcnr_cnf_ratio_ag1;
+ uint32_t rcnr_cnf_ratio_ag2;
+ uint32_t rcnr_cnf_clip_gain_r;
+ uint32_t rcnr_cnf_clip_gain_g;
+ uint32_t rcnr_cnf_clip_gain_b;
+ uint32_t rcnr_a1l_dark_ag0;
+ uint32_t rcnr_a1l_dark_ag1;
+ uint32_t rcnr_a1l_dark_ag2;
+ uint32_t rcnr_a1l_ratio_ag0;
+ uint32_t rcnr_a1l_ratio_ag1;
+ uint32_t rcnr_a1l_ratio_ag2;
+ uint32_t rcnr_inf_zero_clip;
+ uint32_t rcnr_merge_d2blend_ag0;
+ uint32_t rcnr_merge_d2blend_ag1;
+ uint32_t rcnr_merge_d2blend_ag2;
+ uint32_t rcnr_merge_black;
+ uint32_t rcnr_merge_mindiv;
+ uint32_t rcnr_hry_type;
+ uint32_t rcnr_anf_blend_ag0;
+ uint32_t rcnr_anf_blend_ag1;
+ uint32_t rcnr_anf_blend_ag2;
+ uint32_t rcnr_lpf_threshold;
+ uint32_t rcnr_merge_hlblend_ag0;
+ uint32_t rcnr_merge_hlblend_ag1;
+ uint32_t rcnr_merge_hlblend_ag2;
+ uint32_t rcnr_gnr_sw;
+ uint32_t rcnr_gnr_ratio;
+ uint32_t rcnr_gnr_wide_en;
+};
+
+/**
+ * struct hwd_viif_l1_hdrs - HWD L1ISP HDR synthesis parameters
+ * @hdrs_hdr_mode: use or not use middle sensitivity image @ref hwd_VIIF_l1_hdrs
+ * @hdrs_hdr_ratio_m: ratio of mid sensitivity image to high sensitivity image [0x400..0x400000] accuracy: 1/1024
+ * @hdrs_hdr_ratio_l: ratio of low sensitivity image to high sensitivity image [0x400..0x400000] accuracy: 1/1024
+ * @hdrs_hdr_ratio_e: ratio of led image to high sensitivity image [0x400..0x400000] accuracy: 1/1024
+ * @hdrs_dg_h: digital gain of high sensitivity image [0x0..0x3FFFFF] accuracy: 1/1024
+ * @hdrs_dg_m: digital gain of middle sensitivity image [0x0..0x3FFFFF] accuracy: 1/1024
+ * @hdrs_dg_l: digital gain of low sensitivity image [0x0..0x3FFFFF] accuracy: 1/1024
+ * @hdrs_dg_e: digital gain of led image [0x0..0x3FFFFF] accuracy: 1/1024
+ * @hdrs_blendend_h: maximum luminance used for blend of high sensitivity image [0..4095]
+ * @hdrs_blendend_m: maximum luminance used for blend of middle sensitivity image [0..4095]
+ * @hdrs_blendend_e: maximum luminance used for blend of led image [0..4095]
+ * @hdrs_blendbeg_h: minimum luminance used for blend of high sensitivity image [0..4095]
+ * @hdrs_blendbeg_m: minimum luminance used for blend of middle sensitivity image [0..4095]
+ * @hdrs_blendbeg_e: minimum luminance used for blend of led image [0..4095]
+ * @hdrs_led_mode_on: enable/disable LED mode @ref hwd_VIIF_enable_flag
+ * @hdrs_dst_max_val: the maximum value of output pixel [0x0..0xffffff]
+ *
+ * -EINVAL needs to be returned in the below condition.
+ * - (hdrs_hdr_mode == DRV_VIIF_ENABLE) && (hdrs_led_mode_on == DRV_VIIF_ENABLE)
+ */
+struct hwd_viif_l1_hdrs {
+ uint32_t hdrs_hdr_mode;
+ uint32_t hdrs_hdr_ratio_m;
+ uint32_t hdrs_hdr_ratio_l;
+ uint32_t hdrs_hdr_ratio_e;
+ uint32_t hdrs_dg_h;
+ uint32_t hdrs_dg_m;
+ uint32_t hdrs_dg_l;
+ uint32_t hdrs_dg_e;
+ uint32_t hdrs_blendend_h;
+ uint32_t hdrs_blendend_m;
+ uint32_t hdrs_blendend_e;
+ uint32_t hdrs_blendbeg_h;
+ uint32_t hdrs_blendbeg_m;
+ uint32_t hdrs_blendbeg_e;
+ uint32_t hdrs_led_mode_on;
+ uint32_t hdrs_dst_max_val;
+};
+
+/**
+ * struct hwd_viif_l1_black_level_correction - HWD L1ISP black level correction parameters
+ * @srcblacklevel_gr: black level of Gr input [0x0..0xffffff] [pixel]
+ * @srcblacklevel_r: black level of R input [0x0..0xffffff] [pixel]
+ * @srcblacklevel_b: black level of B input [0x0..0xffffff] [pixel]
+ * @srcblacklevel_gb: black level of Gb input [0x0..0xffffff] [pixel]
+ * @mulval_gr: Gr gain [0x0..0xfffff] accuracy: 1/256
+ * @mulval_r: R gain [0x0..0xfffff] accuracy: 1/256
+ * @mulval_b: B gain [0x0..0xfffff] accuracy: 1/256
+ * @mulval_gb: Gb gain [0x0..0xfffff] accuracy: 1/256
+ * @dstmaxval: the maximum value of output pixel [0x0..0xffffff]
+ */
+struct hwd_viif_l1_black_level_correction {
+ uint32_t srcblacklevel_gr;
+ uint32_t srcblacklevel_r;
+ uint32_t srcblacklevel_b;
+ uint32_t srcblacklevel_gb;
+ uint32_t mulval_gr;
+ uint32_t mulval_r;
+ uint32_t mulval_b;
+ uint32_t mulval_gb;
+ uint32_t dstmaxval;
+};
+
+/**
+ * struct hwd_viif_l1_lsc_parabola_ag_param - HWD L1ISP parabola shading analog gain parameters
+ * @lssc_paracoef_h_l_max: maximum gain for the left side of parabola coefficient
+ * @lssc_paracoef_h_l_min: minimum gain for the left side of parabola coefficient
+ * @lssc_paracoef_h_r_max: maximum gain for the right side of parabola coefficient
+ * @lssc_paracoef_h_r_min: minimum gain for the right side of parabola coefficient
+ * @lssc_paracoef_v_u_max: maximum gain for the upper side of parabola coefficient
+ * @lssc_paracoef_v_u_min: minimum gain for the upper side of parabola coefficient
+ * @lssc_paracoef_v_d_max: maximum gain for the lower side of parabola coefficient
+ * @lssc_paracoef_v_d_min: minimum gain for the lower side of parabola coefficient
+ * @lssc_paracoef_hv_lu_max: maximum gain for the upper left side of parabola coefficient
+ * @lssc_paracoef_hv_lu_min: minimum gain for the upper left side of parabola coefficient
+ * @lssc_paracoef_hv_ru_max: maximum gain for the upper right side of parabola coefficient
+ * @lssc_paracoef_hv_ru_min: minimum gain for the upper right side of parabola coefficient
+ * @lssc_paracoef_hv_ld_max: maximum gain for the lower left side of parabola coefficient
+ * @lssc_paracoef_hv_ld_min: minimum gain for the lower left side of parabola coefficient
+ * @lssc_paracoef_hv_rd_max: maximum gain for the lower right side of parabola coefficient
+ * @lssc_paracoef_hv_rd_min: minimum gain for the lower right side of parabola coefficient
+ *
+ * range and accuracy of each parameter is as below.
+ * * range: -4096 <= lssc_paracoef_* < 4096
+ * * accuracy: 1/256
+ */
+struct hwd_viif_l1_lsc_parabola_ag_param {
+ int16_t lssc_paracoef_h_l_max;
+ int16_t lssc_paracoef_h_l_min;
+ int16_t lssc_paracoef_h_r_max;
+ int16_t lssc_paracoef_h_r_min;
+ int16_t lssc_paracoef_v_u_max;
+ int16_t lssc_paracoef_v_u_min;
+ int16_t lssc_paracoef_v_d_max;
+ int16_t lssc_paracoef_v_d_min;
+ int16_t lssc_paracoef_hv_lu_max;
+ int16_t lssc_paracoef_hv_lu_min;
+ int16_t lssc_paracoef_hv_ru_max;
+ int16_t lssc_paracoef_hv_ru_min;
+ int16_t lssc_paracoef_hv_ld_max;
+ int16_t lssc_paracoef_hv_ld_min;
+ int16_t lssc_paracoef_hv_rd_max;
+ int16_t lssc_paracoef_hv_rd_min;
+};
+
+/**
+ * struct hwd_viif_l1_lsc_parabola_param - HWD L1ISP parabola shading parameters
+ * @lssc_para_h_center: horizontal position of optical axis center (0 <= lssc_para_h_center < "width of input image") [pixel]
+ * @lssc_para_v_center: vertical position of optical axis center (0 <= lssc_para_v_center < "height of input image") [line]
+ * @lssc_para_h_gain: gain for horizontal distance from optical axis (0 <= lssc_para_h_gain < 4096) accuracy: 1/256
+ * @lssc_para_v_gain: gain for vertical distance from optical axis (0 <= lssc_para_h_gain < 4096) accuracy: 1/256
+ * @lssc_para_mgsel2: gain ratio of coefficient of the 2nd degree parabola correction @ref hwd_VIIF_l1_lsc_grid_mag
+ * @lssc_para_mgsel4: gain ratio of coefficient of the 4th degree parabola correction @ref hwd_VIIF_l1_lsc_grid_mag
+ * @*r_2d: coefficient of the 2nd degree parabola correction for R
+ * @*r_4d: coefficient of the 4th degree parabola correction for R
+ * @*gr_2d: coefficient of the 2nd degree parabola correction for Gr
+ * @*gr_4d: coefficient of the 4th degree parabola correction for Gr
+ * @*gb_2d: coefficient of the 2nd degree parabola correction for Gb
+ * @*gb_4d: coefficient of the 4th degree parabola correction for Gb
+ * @*b_2d: coefficient of the 2nd degree parabola correction for B
+ * @*b_4d: coefficient of the 4th degree parabola correction for B
+ *
+ * EINVAL needs to be returned in below condition.
+ * * NULL is set to {r/gr/gb/b}_{2/4}d
+ */
+struct hwd_viif_l1_lsc_parabola_param {
+ uint32_t lssc_para_h_center;
+ uint32_t lssc_para_v_center;
+ uint32_t lssc_para_h_gain;
+ uint32_t lssc_para_v_gain;
+ uint32_t lssc_para_mgsel2;
+ uint32_t lssc_para_mgsel4;
+ struct hwd_viif_l1_lsc_parabola_ag_param *r_2d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *r_4d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *gr_2d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *gr_4d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *gb_2d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *gb_4d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *b_2d;
+ struct hwd_viif_l1_lsc_parabola_ag_param *b_4d;
+};
+
+/**
+ * @brief HWD L1ISP grid shading parameters
+ * @lssc_grid_h_size: horizontal grid size (32, 64, 128, 256 or 512) [pixel]
+ * @lssc_grid_v_size: vertical grid size (32, 64, 128, 256 or 512) [pixel]
+ * @lssc_grid_h_center: horizontal position of grid(1,1) [1..lssc_grid_h_size] [pixel]
+ * * "width of input image" <= lssc_grid_h_center + lssc_grid_h_size * 31 [pixel]
+ * @lssc_grid_v_center: vertical position of grid(1,1) [1..lssc_grid_v_size] [line]
+ * * "height of input image" <= lssc_grid_v_center + lssc_grid_v_size * 23 [line]
+ * @lssc_grid_mgsel: gain ratio of coefficient of grid correction @ref hwd_VIIF_l1_lsc_grid_mag
+ */
+struct hwd_viif_l1_lsc_grid_param {
+ uint32_t lssc_grid_h_size;
+ uint32_t lssc_grid_v_size;
+ uint32_t lssc_grid_h_center;
+ uint32_t lssc_grid_v_center;
+ uint32_t lssc_grid_mgsel;
+};
+
+/**
+ * struct hwd_viif_l1_lsc - HWD L1ISP lens shading correction parameters
+ * @lssc_parabola_param: parabola shading correction parameter
+ * * NULL: disable parabola shading correction
+ * * not NULL: enable parabola shading correction
+ * @lssc_grid_param: grid shading correction parameter
+ * * NULL: disable grid shading correction
+ * * not NULL: enable grid shading correction
+ * @lssc_pwhb_r_gain_max: maximum R gain of preset white balance correction
+ * @lssc_pwhb_r_gain_min: minimum R gain of preset white balance correction
+ * @lssc_pwhb_gr_gain_max: maximum Gr gain of preset white balance correction
+ * @lssc_pwhb_gr_gain_min: minimum Gr gain of preset white balance correction
+ * @lssc_pwhb_gb_gain_max: maximum Gb gain of preset white balance correction
+ * @lssc_pwhb_gb_gain_min: minimum Gb gain of preset white balance correction
+ * @lssc_pwhb_b_gain_max: maximum B gain of preset white balance correction
+ * @lssc_pwhb_b_gain_min: minimum B gain of preset white balance correction
+ *
+ * Range and accuracy of lssc_pwhb_xxx_gain_xxx are as below.
+ * - range: [0x0..0x7FF]
+ * - accuracy : 1/256
+ */
+struct hwd_viif_l1_lsc {
+ struct hwd_viif_l1_lsc_parabola_param *lssc_parabola_param;
+ struct hwd_viif_l1_lsc_grid_param *lssc_grid_param;
+ uint32_t lssc_pwhb_r_gain_max;
+ uint32_t lssc_pwhb_r_gain_min;
+ uint32_t lssc_pwhb_gr_gain_max;
+ uint32_t lssc_pwhb_gr_gain_min;
+ uint32_t lssc_pwhb_gb_gain_max;
+ uint32_t lssc_pwhb_gb_gain_min;
+ uint32_t lssc_pwhb_b_gain_max;
+ uint32_t lssc_pwhb_b_gain_min;
+};
+
+/**
+ * struct hwd_viif_l1_color_matrix_correction - HWD L1ISP color matrix correction parameters
+ * @coef_rmg_min: minimum gain of (R-G) [-32768..32767] accuracy: 1/4096
+ * @coef_rmg_max: maximum gain of (R-G) [-32768..32767] accuracy: 1/4096
+ * @coef_rmb_min: minimum gain of (R-B) [-32768..32767] accuracy: 1/4096
+ * @coef_rmb_max: maximum gain of (R-B) [-32768..32767] accuracy: 1/4096
+ * @coef_gmr_min: minimum gain of (G-R) [-32768..32767] accuracy: 1/4096
+ * @coef_gmr_max: maximum gain of (G-R) [-32768..32767] accuracy: 1/4096
+ * @coef_gmb_min: minimum gain of (G-B) [-32768..32767] accuracy: 1/4096
+ * @coef_gmb_max: maximum gain of (G-B) [-32768..32767] accuracy: 1/4096
+ * @coef_bmr_min: minimum gain of (B-R) [-32768..32767] accuracy: 1/4096
+ * @coef_bmr_max: maximum gain of (B-R) [-32768..32767] accuracy: 1/4096
+ * @coef_bmg_min: minimum gain of (B-G) [-32768..32767] accuracy: 1/4096
+ * @coef_bmg_max: maximum gain of (B-G) [-32768..32767] accuracy: 1/4096
+ * @dst_minval: the minimum output pixel [0x0..0xffff] [pixel]
+ */
+struct hwd_viif_l1_color_matrix_correction {
+ int16_t coef_rmg_min;
+ int16_t coef_rmg_max;
+ int16_t coef_rmb_min;
+ int16_t coef_rmb_max;
+ int16_t coef_gmr_min;
+ int16_t coef_gmr_max;
+ int16_t coef_gmb_min;
+ int16_t coef_gmb_max;
+ int16_t coef_bmr_min;
+ int16_t coef_bmr_max;
+ int16_t coef_bmg_min;
+ int16_t coef_bmg_max;
+ uint16_t dst_minval;
+};
+
+/**
+ * struct hwd_viif_l1_awb - HWD L1ISP auto white balance parameters
+ * @awhb_ygate_sel: enable/disable to use fixed Y value at RGB to YUV conversion @ref hwd_VIIF_enable_flag
+ * @awhb_ygate_data: Y value in case of awhb_ygate_sel = HWD_VIIF_ENABLE [64, 128, 256 or 512]
+ * @awhb_cgrange: magnification of output signal before auto white balance adjustment @ref hwd_VIIF_l1_awb_mag
+ * @awhb_ygatesw: enable/disable Y-gate @ref hwd_VIIF_enable_flag
+ * @awhb_hexsw: enable/disable Hexa-gate @ref hwd_VIIF_enable_flag
+ * @awhb_areamode: area mode for auto white balance @ref hwd_VIIF_l1_awb_area_mode
+ * @awhb_area_hsize: horizontal size of one block of central area [1..(width of input image - 8)/8] [pixel]
+ * @awhb_area_vsize: vertical size of one block of central area [1..(height of input image - 4)/8] [line]
+ * @awhb_area_hofs: horizontal offset of block[0] of central area [0..(width of input image - 9)] [pixel]
+ * @awhb_area_vofs: vertical offset of block[0] of central area [0..(height of input image - 5)] [line]
+ * @awhb_area_maskh: selection of target block(upper side). Corresponding bit means including(1) or not including(0).
+ * * The relation between each bit and block is as below.
+ * * [31 :0] = {
+ * * (7, 3),(6, 3),(5, 3),(4, 3),(3, 3),(2, 3),(1, 3),(0, 3),
+ * * (7, 2),(6, 2),(5, 2),(4, 2),(3, 2),(2, 2),(1, 2),(0, 2),
+ * * (7, 1),(6, 1),(5, 1),(4, 1),(3, 1),(2, 1),(1, 1),(0, 1),
+ * * (7, 0),(6, 0),(5, 0),(4, 0),(3, 0),(2, 0),(1, 0),(0, 0)}
+ * @awhb_area_maskl: selection of target block(lower side). Corresponding bit means including(1) or not including(0).
+ * * The relation between each bit and block is as below.
+ * * [31:0] = {
+ * * (7, 7),(6, 7),(5, 7),(4, 7),(3, 7),(2, 7),(1, 7),(0, 7),
+ * * (7, 6),(6, 6),(5, 6),(4, 6),(3, 6),(2, 6),(1, 6),(0, 6),
+ * * (7, 5),(6, 5),(5, 5),(4, 5),(3, 5),(2, 5),(1, 5),(0, 5),
+ * * (7, 4),(6, 4),(5, 4),(4, 4),(3, 4),(2, 4),(1, 4),(0, 4)}
+ * @awhb_sq_sw[3]: enable/disable each square gate @ref hwd_VIIF_enable_flag
+ * @awhb_sq_pol[3]: enable/disable to add accumulated gate for each square gate @ref hwd_VIIF_enable_flag
+ * @awhb_bycut0p: upper U value of hexa-gate [0..127] [pixel]
+ * @awhb_bycut0n: lower U value of hexa-gate [0..127] [pixel]
+ * @awhb_rycut0p: upper V value of hexa-gate [0..127] [pixel]
+ * @awhb_rycut0n: lower V value of hexa-gate [0..127] [pixel]
+ * @awhb_rbcut0h: upper intercept on V axis of hexa-gate [-127..127] [pixel]
+ * @awhb_rbcut0l: lower intercept on V axis of hexa-gate [-127..127] [pixel]
+ * @awhb_bycut_h[3]: center value of each square gate in the U direction [-127..127]
+ * @awhb_bycut_l[3]: width of each square gate in the U direction [0..127]
+ * @awhb_rycut_h[3]: center value of each square gate in the V direction [-127..127]
+ * @awhb_rycut_l[3]: width of each square gate in the V direction [0..127]
+ * @awhb_awbsftu: offset of U gain [-127..127]
+ * @awhb_awbsftv: offset of V gain [-127..127]
+ * @awhb_awbhuecor: enable/disable to hold color correlation @ref hwd_VIIF_enable_flag
+ * @awhb_awbspd: UV convergence speed [0..15] [times] (0 means "stop")
+ * @awhb_awbulv: convergence level of U [0..31]
+ * @awhb_awbvlv: convergence level of V [0..31]
+ * @awhb_awbondot: threshold to stop accumulation [0..1023] [pixel]
+ * @awhb_awbfztim: condition to restart auto white balance @ref hwd_VIIF_l1_awb_restart_cond
+ * @awhb_wbgrmax: adjustment range of R gain(upper side) [0..255] accuracy: 1/64
+ * @awhb_wbgbmax: adjustment range of B gain(upper side) [0..255] accuracy: 1/64
+ * @awhb_wbgrmin: adjustment range of R gain(lower side) [0..255] accuracy: 1/64
+ * @awhb_wbgbmin: adjustment range of B gain(lower side) [0..255] accuracy: 1/64
+ * @awhb_ygateh: the maximum value of Y-gate [0..255] [pixel]
+ * @awhb_ygatel: the minimum value of Y-gate [0..255] [pixel]
+ * @awhb_awbwait: the number of frame to restart auto white balance after completion of UV convergence [0..255]
+ */
+struct hwd_viif_l1_awb {
+ uint32_t awhb_ygate_sel;
+ uint32_t awhb_ygate_data;
+ uint32_t awhb_cgrange;
+ uint32_t awhb_ygatesw;
+ uint32_t awhb_hexsw;
+ uint32_t awhb_areamode;
+ uint32_t awhb_area_hsize;
+ uint32_t awhb_area_vsize;
+ uint32_t awhb_area_hofs;
+ uint32_t awhb_area_vofs;
+ uint32_t awhb_area_maskh;
+ uint32_t awhb_area_maskl;
+ uint32_t awhb_sq_sw[3];
+ uint32_t awhb_sq_pol[3];
+ uint32_t awhb_bycut0p;
+ uint32_t awhb_bycut0n;
+ uint32_t awhb_rycut0p;
+ uint32_t awhb_rycut0n;
+ int32_t awhb_rbcut0h;
+ int32_t awhb_rbcut0l;
+ int32_t awhb_bycut_h[3];
+ uint32_t awhb_bycut_l[3];
+ int32_t awhb_rycut_h[3];
+ uint32_t awhb_rycut_l[3];
+ int32_t awhb_awbsftu;
+ int32_t awhb_awbsftv;
+ uint32_t awhb_awbhuecor;
+ uint32_t awhb_awbspd;
+ uint32_t awhb_awbulv;
+ uint32_t awhb_awbvlv;
+ uint32_t awhb_awbondot;
+ uint32_t awhb_awbfztim;
+ uint8_t awhb_wbgrmax;
+ uint8_t awhb_wbgbmax;
+ uint8_t awhb_wbgrmin;
+ uint8_t awhb_wbgbmin;
+ uint8_t awhb_ygateh;
+ uint8_t awhb_ygatel;
+ uint8_t awhb_awbwait;
+};
+
+/**
+ * struct hwd_viif_l1_hdrc - HWD L1ISP HDR compression parameters
+ * @hdrc_ratio: input image data width [10..24]
+ * @hdrc_pt_ratio: slope of Preset Tone curve [0..13]
+ * @hdrc_pt_blend: blend ratio of Preset Tone0 curve [0..256] accuracy: 1/256
+ * @hdrc_pt_blend2: blend ratio of Preset Tone2 curve [0..256] accuracy: 1/256
+ * @hdrc_tn_type: tone curve type @ref hwd_VIIF_l1_hdrc_tone_type
+ * @hdrc_utn_tbl[20]: User Tone curve value after HDRC [0x0..0xffff]
+ * @hdrc_flr_val: constant flare value [0x0..0xffffff]
+ * @hdrc_flr_adp: enable/disable adaptive constant flare @ref hwd_VIIF_enable_flag
+ * @hdrc_ybr_off: enable/disable bilateral luminance filter off @ref hwd_VIIF_enable_flag
+ * * HWD_VIIF_ENABLE: filter off
+ * * HWD_VIIF_DISABLE: filter on
+ * @hdrc_orgy_blend: blend setting for corrected luminance data after HDRC and original luminance data [0..16]
+ * * 0: corrected luminance data 100%
+ * * 8: corrected luminance data 50%
+ * * 16: corrected luminance data 0%
+ * @hdrc_pt_sat: saturation value for Preset Tone [0x0..0xffff]
+ *
+ * -EINVAL needs to be returned in the below condition.
+ * - hdrc_pt_blend + hdrc_pt_blend2 > 256
+ */
+struct hwd_viif_l1_hdrc {
+ uint32_t hdrc_ratio;
+ uint32_t hdrc_pt_ratio;
+ uint32_t hdrc_pt_blend;
+ uint32_t hdrc_pt_blend2;
+ uint32_t hdrc_tn_type;
+ uint16_t hdrc_utn_tbl[20];
+ uint32_t hdrc_flr_val;
+ uint32_t hdrc_flr_adp;
+ uint32_t hdrc_ybr_off;
+ uint32_t hdrc_orgy_blend;
+ uint16_t hdrc_pt_sat;
+};
+
+/**
+ * struct hwd_viif_l1_hdrc_ltm - HWD L1ISP HDR compression local tone mapping parameters
+ * @tnp_max: the maximum tone blend ratio of LTM [0x0..0x3FFFFF] accuracy: 1/64
+ * * 0 means LTM off.
+ * @tnp_mag: strength adjustment of LTM [0x0..0x3FFF] accuracy: 1/64
+ * @tnp_fil[5]: coefficient of smoothing filter
+ *
+ * -EINVAL needs to be returned in the below condition.
+ * * (coef1 + coef2 + coef3 + coef4) * 2 + coef0 != 1024
+ * * Here, [0]: coef0, [1]: coef1, [2]: coef2, [3]: coef3, [4]: coef4
+ */
+struct hwd_viif_l1_hdrc_ltm {
+ uint32_t tnp_max;
+ uint32_t tnp_mag;
+ uint8_t tnp_fil[5];
+};
+
+/**
+ * struct hwd_viif_l1_gamma - HWD L1ISP gamma correction parameters
+ * @gam_p[44]: luminance value after gamma correction [0..8191]
+ * @blkadj: adjustment black level after gamma correction [0..65535]
+ */
+struct hwd_viif_l1_gamma {
+ uint16_t gam_p[44];
+ uint16_t blkadj;
+};
+
+/**
+ * struct hwd_viif_l1_nonlinear_contrast - HWD L1ISP nonlinear contrast parameters
+ * @blk_knee: top luminance value in black area after nonlinear contrast adjustment [0x0..0xffff]
+ * @wht_knee: top luminance value in white area after nonlinear contrast adjustment [0x0..0xffff]
+ * @blk_cont[3]: slope in black area after nonlinear contrast adjustment [0..255] accuracy: 1/256
+ * * [0]: the value at AG minimum
+ * * [1]: the value at AG less than 128
+ * * [2]: the value at AG equal to or more than 128
+ * @wht_cont[3]: slope in white area after nonlinear contrast adjustment [0..255] accuracy: 1/256
+ * * [0]: the value at AG minimum
+ * * [1]: the value at AG less than 128
+ * * [2]: the value at AG equal to or more than 128
+ */
+struct hwd_viif_l1_nonlinear_contrast {
+ uint16_t blk_knee; /**< top luminance value in black area after nonlinear contrast adjustment [0x0..0xffff] */
+ uint16_t wht_knee; /**< top luminance value in white area after nonlinear contrast adjustment [0x0..0xffff] */
+ uint8_t blk_cont[3];
+ uint8_t wht_cont[3];
+};
+
+/**
+ * struct hwd_viif_l1_lum_noise_reduction - HWD L1ISP luminance noise reduction parameters
+ * @gain_min: the minimum gain for extracted noise [0x0..0xffff] accuracy: 1/256
+ * @gain_max: the maximum gain for extracted noise [0x0..0xffff] accuracy: 1/256
+ * @lim_min: the minimum limit value for extracted noise [0x0..0xffff]
+ * @lim_max: the maximum limit value for extracted noise [0x0..0xffff]
+ *
+ * -EINVAL needs to be returned in the below conditions.
+ * * gain_min > gain_max
+ * * lim_min > lim_max
+ */
+struct hwd_viif_l1_lum_noise_reduction {
+ uint16_t gain_min;
+ uint16_t gain_max;
+ uint16_t lim_min;
+ uint16_t lim_max;
+};
+
+/**
+ * struct hwd_viif_l1_edge_enhancement - HWD L1ISP edge enhancement parameters
+ * @gain_min: the minimum gain for extracted edge [0x0..0xffff] accuracy: 1/256
+ * @gain_max: the maximum gain for extracted edge [0x0..0xffff] accuracy: 1/256
+ * @lim_min: the minimum limit value for extracted edge [0x0..0xffff]
+ * @lim_max: the maximum limit value for extracted edge [0x0..0xffff]
+ * @coring_min: the minimum coring threshold for extracted edge [0x0..0xffff]
+ * @coring_max: the maximum coring threshold for extracted edge [0x0..0xffff]
+ *
+ * -EINVAL needs to be returned in the below conditions.
+ * * gain_min > gain_max
+ * * lim_min > lim_max
+ * * coring_min > coring_max
+ */
+struct hwd_viif_l1_edge_enhancement {
+ uint16_t gain_min;
+ uint16_t gain_max;
+ uint16_t lim_min;
+ uint16_t lim_max;
+ uint16_t coring_min;
+ uint16_t coring_max;
+};
+
+/**
+ * struct hwd_viif_l1_uv_suppression - HWD L1ISP UV suppression parameters
+ * @bk_mp: slope of black [0x0..0x3fff] accuracy: 1/16384
+ * @black: the minimum black gain [0x0..0x3fff] accuracy: 1/16384
+ * @wh_mp: slope of white [0x0..0x3fff] accuracy: 1/16384
+ * @white: the minimum white gain [0x0..0x3fff] accuracy: 1/16384
+ * @bk_slv: intercept of black [0x0..0xffff]
+ * @wh_slv: intercept of white [0x0..0xffff]
+ *
+ * -EINVAL needs to be returned in the below condition.
+ * * bk_slv >= wh_slv
+ */
+struct hwd_viif_l1_uv_suppression {
+ uint32_t bk_mp;
+ uint32_t black;
+ uint32_t wh_mp;
+ uint32_t white;
+ uint16_t bk_slv;
+ uint16_t wh_slv;
+};
+
+/**
+ * struct hwd_viif_l1_coring_suppression - HWD L1ISP coring suppression parameters
+ * @lv_min: the minimum coring threshold [0x0..0xffff]
+ * @lv_max: the maximum coring threshold [0x0..0xffff]
+ * @gain_min: the minimum gain [0x0..0xffff] accuracy: 1/65536
+ * @gain_max: the maximum gain [0x0..0xffff] accuracy: 1/65536
+ *
+ * -EINVAL needs to be returned in the below condition.
+ * * lv_min > lv_max
+ * * gain_min > gain_max
+ */
+struct hwd_viif_l1_coring_suppression {
+ uint16_t lv_min;
+ uint16_t lv_max;
+ uint16_t gain_min;
+ uint16_t gain_max;
+};
+
+/**
+ * struct hwd_viif_l1_edge_suppression - HWD L1ISP edge suppression parameters
+ * @gain: gain [0x0..0xffff] accuracy: 1/256
+ * @lim: limit threshold [0..15]
+ */
+struct hwd_viif_l1_edge_suppression {
+ uint16_t gain;
+ uint32_t lim;
+};
+
+/**
+ * struct hwd_viif_l1_color_level - HWD L1ISP color level parameters
+ * @cb_gain: U gain
+ * @cr_gain: V gain
+ * @cbr_mgain_min: UV common gain
+ * @cbp_gain_max: U plus gain
+ * @cbm_gain_max: U minus gain
+ * @crp_gain_max: V plus gain
+ * @crm_gain_max: V minus gain
+ *
+ * Range and accuracy of each parameter are as below.
+ * * range: [0x0..0xfff]
+ * * accuracy: 1/2048
+ */
+struct hwd_viif_l1_color_level {
+ uint32_t cb_gain;
+ uint32_t cr_gain;
+ uint32_t cbr_mgain_min;
+ uint32_t cbp_gain_max;
+ uint32_t cbm_gain_max;
+ uint32_t crp_gain_max;
+ uint32_t crm_gain_max;
+};
+
+/**
+ * struct hwd_viif_l1_img_quality_adjustment - HWD L1ISP image quality adjustment parameters
+ * @coef_cb: Cb coefficient [0x0..0xffff] accuracy: 1/65536
+ * @coef_cr: Cr coefficient [0x0..0xffff] accuracy: 1/65536
+ * @brightness: brightness value [-32768..32767] (0 means off.)
+ * @linear_contrast: linear contrast value [0x0..0xff] accuracy: 1/128 (128 means off.)
+ * @*nonlinear_contrast: pointer to nonlinear contrast parameter
+ * @*lum_noise_reduction: pointer to luminance noise reduction parameter
+ * @*edge_enhancement: pointer to edge enhancement parameter
+ * @*uv_suppression: pointer to UV suppression parameter
+ * @*coring_suppression: pointer to coring suppression parameter
+ * @*edge_suppression: pointer to edge enhancement parameter
+ * @*color_level: pointer to color level adjustment parameter
+ * @color_noise_reduction_enable: enable/disable color noise reduction @ref hwd_VIIF_enable_flag
+ */
+struct hwd_viif_l1_img_quality_adjustment {
+ uint16_t coef_cb;
+ uint16_t coef_cr;
+ int16_t brightness;
+ uint8_t linear_contrast;
+ struct hwd_viif_l1_nonlinear_contrast *nonlinear_contrast;
+ struct hwd_viif_l1_lum_noise_reduction *lum_noise_reduction;
+ struct hwd_viif_l1_edge_enhancement *edge_enhancement;
+ struct hwd_viif_l1_uv_suppression *uv_suppression;
+ struct hwd_viif_l1_coring_suppression *coring_suppression;
+ struct hwd_viif_l1_edge_suppression *edge_suppression;
+ struct hwd_viif_l1_color_level *color_level;
+ uint32_t color_noise_reduction_enable;
+};
+
+/**
+ * struct hwd_viif_l1_avg_lum_generation - HWD L1ISP average luminance generation parameters
+ * @aexp_start_x: horizontal position of block[0] [0.."width of input image - 1"] [pixel]
+ * @aexp_start_y: vertical position of block[0] [0.."height of input image - 1"] [line]
+ * @aexp_block_width: width of one block(needs to be multiple of 64) [64.."width of input image"] [pixel]
+ * @aexp_block_height: height of one block(needs to be multiple of 64) [64.."height of input image"] [line]
+ * @aexp_weight[8][8]: weight of each block [0..3] [y][x]: y means vertical position and x means horizontal position.
+ * @aexp_satur_ratio: threshold to judge whether saturated block or not [0..256]
+ * @aexp_black_ratio: threshold to judge whether black block or not [0..256]
+ * @aexp_satur_level: threshold to judge whether saturated pixel or not [0x0..0xffffff]
+ * @aexp_ave4linesy[4]: vertical position of the initial line for 4-lines average luminance [0.."height of input image - 4"] [line]
+ */
+struct hwd_viif_l1_avg_lum_generation {
+ uint32_t aexp_start_x;
+ uint32_t aexp_start_y;
+ uint32_t aexp_block_width;
+ uint32_t aexp_block_height;
+ uint32_t aexp_weight[8][8];
+ uint32_t aexp_satur_ratio;
+ uint32_t aexp_black_ratio;
+ uint32_t aexp_satur_level;
+ uint32_t aexp_ave4linesy[4];
+};
+
+/**
+ * struct hwd_viif_l1_histogram - HWD L1ISP histogram parameters
+ * @hist_bin_mode: bin mode @ref hwd_VIIF_l1_bin_mode
+ * @hist_block_v_ofst: vertical position of block[0] [0.."height of input image - 1"] [line]
+ * @hist_block_h_ofst: horizontal position of block[0] [0.."width of input image - 1"] [pixel]
+ * @hist_block_height: height of one block [1.."height of input image"] [line]
+ * @hist_block_width: width of one block [1.."width of input image"] [pixel]
+ * @hist_block_v_num: the number of block in the vertical direction [1..8]
+ * @hist_block_h_num: the number of block in the horizontal direction [1..8]
+ * @hist_block_v_step: vertical line spacing [0..15] [line]
+ * @hist_block_h_step: horizontal pixel spacing [0..15] [pixel]
+ * @hist_linear_sft: bin shift value in case of linear mode [0..31]
+ * @hist_mult_a_r: bin multiplier coefficient(MULT_A) for R [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_a_r: bin additional value(ADD_A) for R [-16777216..16777215] accuracy: 1/256
+ * @hist_mult_b_r: bin multiplier coefficient(MULT_B) for R [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_b_r: bin additional value(ADD_B) for R [-65536..65535] accuracy: 1/256
+ * @hist_mult_a_g: bin multiplier coefficient(MULT_A) for G [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_a_g: bin additional value(ADD_A) for G [-16777216..16777215] accuracy: 1/256
+ * @hist_mult_b_g: bin multiplier coefficient(MULT_B) for G [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_b_g: bin additional value(ADD_B) for G [-65536..65535] accuracy: 1/256
+ * @hist_mult_a_b: bin multiplier coefficient(MULT_A) for B [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_a_b: bin additional value(ADD_A) for B [-16777216..16777215] accuracy: 1/256
+ * @hist_mult_b_b: bin multiplier coefficient(MULT_B) for B [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_b_b: bin additional value(ADD_B) for B [-65536..65535] accuracy: 1/256
+ * @hist_mult_a_y: bin multiplier coefficient(MULT_A) for Y [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_a_y: bin additional value(ADD_A) for Y [-16777216..16777215] accuracy: 1/256
+ * @hist_mult_b_y: bin multiplier coefficient(MULT_B) for Y [0x0..0xFFFF] accuracy: 1/256
+ * @hist_add_b_y: bin additional value(ADD_B) for Y [-65536..65535] accuracy: 1/256
+ */
+struct hwd_viif_l1_histogram {
+ uint32_t hist_bin_mode;
+ uint32_t hist_block_v_ofst;
+ uint32_t hist_block_h_ofst;
+ uint32_t hist_block_height;
+ uint32_t hist_block_width;
+ uint32_t hist_block_v_num;
+ uint32_t hist_block_h_num;
+ uint32_t hist_block_v_step;
+ uint32_t hist_block_h_step;
+ uint32_t hist_linear_sft;
+ uint16_t hist_mult_a_r;
+ int32_t hist_add_a_r;
+ uint16_t hist_mult_b_r;
+ int32_t hist_add_b_r;
+ uint16_t hist_mult_a_g;
+ int32_t hist_add_a_g;
+ uint16_t hist_mult_b_g;
+ int32_t hist_add_b_g;
+ uint16_t hist_mult_a_b;
+ int32_t hist_add_a_b;
+ uint16_t hist_mult_b_b;
+ int32_t hist_add_b_b;
+ uint16_t hist_mult_a_y;
+ int32_t hist_add_a_y;
+ uint16_t hist_mult_b_y;
+ int32_t hist_add_b_y;
+};
+
/**
* struct hwd_viif_l1_info - HWD L1ISP processing information
* @context_id: context id
@@ -806,6 +1683,71 @@ void hwd_VIIF_isp_set_regbuf_irq_mask(uint32_t module_id, const uint32_t *mask_l
const uint32_t *mask_l2);
void hwd_VIIF_isp_disable_isst(uint32_t module_id);

+int32_t hwd_VIIF_l1_set_input_mode(uint32_t module_id, uint32_t mode, uint32_t depth,
+ uint32_t raw_color_filter,
+ const struct hwd_viif_l1_raw_input_order *interpolation_order);
+int32_t hwd_VIIF_l1_set_rgb_to_y_coef(uint32_t module_id, uint32_t regbuf_id, uint16_t coef_r,
+ uint16_t coef_g, uint16_t coef_b);
+int32_t hwd_VIIF_l1_set_ag_mode(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_ag_mode *param);
+int32_t hwd_VIIF_l1_set_ag(uint32_t module_id, uint32_t regbuf_id, uint16_t gain_h, uint16_t gain_m,
+ uint16_t gain_l);
+int32_t hwd_VIIF_l1_set_hdre(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdre *param);
+int32_t hwd_VIIF_l1_set_img_extraction(uint32_t module_id, uint32_t regbuf_id,
+ uint32_t input_black_gr, uint32_t input_black_r,
+ uint32_t input_black_b, uint32_t input_black_gb);
+int32_t hwd_VIIF_l1_set_dpc(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_dpc *param_h,
+ const struct hwd_viif_l1_dpc *param_m,
+ const struct hwd_viif_l1_dpc *param_l);
+int32_t hwd_VIIF_l1_set_dpc_table_transmission(uint32_t module_id, uintptr_t table_h,
+ uintptr_t table_m, uintptr_t table_l);
+int32_t
+hwd_VIIF_l1_set_preset_white_balance(uint32_t module_id, uint32_t regbuf_id, uint32_t dstmaxval,
+ const struct hwd_viif_l1_preset_white_balance *param_h,
+ const struct hwd_viif_l1_preset_white_balance *param_m,
+ const struct hwd_viif_l1_preset_white_balance *param_l);
+int32_t hwd_VIIF_l1_set_raw_color_noise_reduction(
+ uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_raw_color_noise_reduction *param_h,
+ const struct hwd_viif_l1_raw_color_noise_reduction *param_m,
+ const struct hwd_viif_l1_raw_color_noise_reduction *param_l);
+int32_t hwd_VIIF_l1_set_hdrs(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdrs *param);
+int32_t
+hwd_VIIF_l1_set_black_level_correction(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_black_level_correction *param);
+int32_t hwd_VIIF_l1_set_lsc(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_lsc *param);
+int32_t hwd_VIIF_l1_set_lsc_table_transmission(uint32_t module_id, uintptr_t table_gr,
+ uintptr_t table_r, uintptr_t table_b,
+ uintptr_t table_gb);
+int32_t hwd_VIIF_l1_set_main_process(uint32_t module_id, uint32_t regbuf_id, uint32_t demosaic_mode,
+ uint32_t damp_lsbsel,
+ const struct hwd_viif_l1_color_matrix_correction *color_matrix,
+ uint32_t dst_maxval);
+int32_t hwd_VIIF_l1_set_awb(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_awb *param, uint32_t awhb_wbmrg,
+ uint32_t awhb_wbmgg, uint32_t awhb_wbmbg);
+int32_t hwd_VIIF_l1_lock_awb_gain(uint32_t module_id, uint32_t regbuf_id, uint32_t enable);
+int32_t hwd_VIIF_l1_set_hdrc(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdrc *param, uint32_t hdrc_thr_sft_amt);
+int32_t hwd_VIIF_l1_set_hdrc_ltm(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdrc_ltm *param);
+int32_t hwd_VIIF_l1_set_gamma(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_gamma *param);
+int32_t
+hwd_VIIF_l1_set_img_quality_adjustment(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_img_quality_adjustment *param);
+int32_t hwd_VIIF_l1_set_avg_lum_generation(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_avg_lum_generation *param);
+int32_t hwd_VIIF_l1_set_histogram(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_histogram *param);
+int32_t hwd_VIIF_l1_set_histogram_transmission(uint32_t module_id, uintptr_t buf,
+ uint32_t block_v_num);
+void hwd_VIIF_l1_set_irq_mask(uint32_t module_id, const uint32_t *mask);
+
/* control L2 Image Signal Processor */
int32_t hwd_VIIF_l2_set_input_path(uint32_t module_id, bool is_other_ch);
int32_t hwd_VIIF_l2_set_input_csc(uint32_t module_id, const struct hwd_viif_csc_param *param,
diff --git a/drivers/media/platform/visconti/hwd_viif_l1isp.c b/drivers/media/platform/visconti/hwd_viif_l1isp.c
new file mode 100644
index 000000000..495133720
--- /dev/null
+++ b/drivers/media/platform/visconti/hwd_viif_l1isp.c
@@ -0,0 +1,3769 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/* Toshiba Visconti Video Capture Support
+ *
+ * (C) Copyright 2022 TOSHIBA CORPORATION
+ * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation
+ */
+
+#include <linux/io.h>
+#include "hwd_viif.h"
+#include "hwd_viif_internal.h"
+
+/**
+ * hwd_VIIF_l1_set_input_mode() - Configure L1ISP input mode.
+ *
+ * @mode: L1ISP preprocessing mode @ref hwd_VIIF_l1_input_mode
+ * @depth: input color depth (even only)
+ * - [8..24] in case of mode = #HWD_VIIF_L1_INPUT_HDR or #HWD_VIIF_L1_INPUT_HDR_IMG_CORRECT
+ * - [8..14] in case of mode = #HWD_VIIF_L1_INPUT_PWL or #HWD_VIIF_L1_INPUT_PWL_IMG_CORRECT
+ * - [8..12] in case of mode = #HWD_VIIF_L1_INPUT_SDR
+ * @raw_color_filter: RAW color filter array @ref hwd_VIIF_l1_raw_color_filter_mode
+ * @interpolation_order: interpolation order for input image
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "mode" is out of range
+ * - "depth" is out of range
+ * - "raw_color_filter" is out of range
+ * - "interpolation_order" is NULL in case of "mode" == #HWD_VIIF_L1_INPUT_SDR
+ * - "interpolation_order" is not NULL in case of "mode" != #HWD_VIIF_L1_INPUT_SDR
+ *
+ * Note that if 'mode' is not HWD_VIIF_L1_INPUT_SDR, NULL shall be set to 'interpolation_order'.
+ */
+int32_t hwd_VIIF_l1_set_input_mode(uint32_t module_id, uint32_t mode, uint32_t depth,
+ uint32_t raw_color_filter,
+ const struct hwd_viif_l1_raw_input_order *interpolation_order)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val, input_num, depth_max;
+
+ if (mode >= HWD_VIIF_L1_INPUT_MODE_NUM)
+ return -EINVAL;
+
+ if (mode == HWD_VIIF_L1_INPUT_SDR) {
+ depth_max = HWD_VIIF_L1_INPUT_DEPTH_SDR_MAX;
+ } else if ((mode == HWD_VIIF_L1_INPUT_PWL) || (mode == HWD_VIIF_L1_INPUT_PWL_IMG_CORRECT)) {
+ depth_max = HWD_VIIF_L1_INPUT_DEPTH_PWL_MAX;
+ } else {
+ depth_max = HWD_VIIF_L1_INPUT_DEPTH_MAX;
+ }
+
+ if ((depth < HWD_VIIF_L1_INPUT_DEPTH_MIN) || (depth > depth_max))
+ return -EINVAL;
+
+ if ((depth % 2U) != 0U)
+ return -EINVAL;
+
+ if (raw_color_filter >= HWD_VIIF_L1_RAW_MODE_NUM)
+ return -EINVAL;
+
+ if ((mode != HWD_VIIF_L1_INPUT_SDR) && (interpolation_order != NULL))
+ return -EINVAL;
+
+ if (mode == HWD_VIIF_L1_INPUT_SDR) {
+ if (interpolation_order == NULL)
+ return -EINVAL;
+
+ /* check the range of high sensitivity and order of other images (middle, low) */
+ input_num = readl(&res->capture_reg->l1isp.L1_IBUF_INPUT_ORDER) & 0x3U;
+ if (interpolation_order->input_order_high > input_num) {
+ return -EINVAL;
+ } else if (interpolation_order->input_order_high ==
+ interpolation_order->input_order_middle) {
+ return -EINVAL;
+ } else if (interpolation_order->input_order_high ==
+ interpolation_order->input_order_low) {
+ return -EINVAL;
+ }
+
+ /* check the range of middle sensitivity and order of other image (low) */
+ if (interpolation_order->input_order_middle > input_num) {
+ return -EINVAL;
+ } else if (interpolation_order->input_order_middle ==
+ interpolation_order->input_order_low) {
+ return -EINVAL;
+ }
+
+ /* check the range of low sensitivity */
+ if (interpolation_order->input_order_low > input_num)
+ return -EINVAL;
+ }
+
+ writel(mode, &(res->capture_reg->l1isp.L1_SYSM_INPUT_MODE));
+ writel(depth, &(res->capture_reg->l1isp.L1_IBUF_DEPTH));
+ writel(raw_color_filter, &(res->capture_reg->l1isp.L1_SYSM_START_COLOR));
+ if (mode == HWD_VIIF_L1_INPUT_SDR) {
+ val = readl(&res->capture_reg->l1isp.L1_IBUF_INPUT_ORDER) & 0xffff81ffU;
+ val |= (interpolation_order->input_order_high << 13U) |
+ (interpolation_order->input_order_middle << 11U) |
+ (interpolation_order->input_order_low << 9U);
+ writel(val, &(res->capture_reg->l1isp.L1_IBUF_INPUT_ORDER));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_rgb_to_y_coef() - Configure L1ISP RGB coefficients to calculate Y.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @coef_r: R coefficient to calculate Y [256..65024] accuracy: 1/65536
+ * @coef_g: G coefficient to calculate Y [256..65024] accuracy: 1/65536
+ * @coef_b: B coefficient to calculate Y [256..65024] accuracy: 1/65536
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "coef_r" is out of range
+ * - "coef_g" is out of range
+ * - "coef_b" is out of range
+ *
+ * Note that it is possible that coef_r/g/b has rounding error when the value is set to HW register
+ */
+int32_t hwd_VIIF_l1_set_rgb_to_y_coef(uint32_t module_id, uint32_t regbuf_id, uint16_t coef_r,
+ uint16_t coef_g, uint16_t coef_b)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+
+ if ((coef_r < HWD_VIIF_L1_COEF_MIN) || (coef_r > HWD_VIIF_L1_COEF_MAX)) {
+ return -EINVAL;
+ }
+ if ((coef_g < HWD_VIIF_L1_COEF_MIN) || (coef_g > HWD_VIIF_L1_COEF_MAX)) {
+ return -EINVAL;
+ }
+ if ((coef_b < HWD_VIIF_L1_COEF_MIN) || (coef_b > HWD_VIIF_L1_COEF_MAX)) {
+ return -EINVAL;
+ }
+
+ writel((uint32_t)coef_r, &(res->capture_reg->l1isp.L1_SYSM_YCOEF_R));
+ writel((uint32_t)coef_g, &(res->capture_reg->l1isp.L1_SYSM_YCOEF_G));
+ writel((uint32_t)coef_b, &(res->capture_reg->l1isp.L1_SYSM_YCOEF_B));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_ag_mode() - Configure L1ISP AG mode.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to struct hwd_viif_l1_ag_mode
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "param" is NULL
+ * - each member of "param" is invalid
+ */
+int32_t hwd_VIIF_l1_set_ag_mode(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_ag_mode *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+
+ uint32_t val;
+
+ if (param == NULL)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_hobc_high >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_hobc_middle_led >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_hobc_low >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_abpc_high >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_abpc_middle_led >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_abpc_low >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_rcnr_high >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_rcnr_middle_led >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_rcnr_low >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_ssel_lssc >= HWD_VIIF_L1_SENSITIVITY_IMAGE_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_lssc >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_ssel_mpro >= HWD_VIIF_L1_SENSITIVITY_IMAGE_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_mpro >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_ssel_vpro >= HWD_VIIF_L1_SENSITIVITY_IMAGE_NUM)
+ return -EINVAL;
+
+ if (param->sysm_ag_psel_vpro >= HWD_VIIF_L1_AG_ID_NUM)
+ return -EINVAL;
+
+ if ((param->sysm_ag_cont_hobc_en_high != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_hobc_en_high != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->sysm_ag_cont_hobc_en_middle_led != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_hobc_en_middle_led != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->sysm_ag_cont_hobc_en_low != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_hobc_en_low != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_rcnr_en_high != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_rcnr_en_high != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->sysm_ag_cont_rcnr_en_middle_led != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_rcnr_en_middle_led != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->sysm_ag_cont_rcnr_en_low != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_rcnr_en_low != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_lssc_en != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_lssc_en != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_mpro_en != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_mpro_en != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_vpro_en != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_vpro_en != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_abpc_en_middle_led != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_abpc_en_middle_led != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_abpc_en_high != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_abpc_en_high != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->sysm_ag_cont_abpc_en_low != HWD_VIIF_ENABLE) &&
+ (param->sysm_ag_cont_abpc_en_low != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ /* SYSM_AG_PARAM */
+ val = ((uint32_t)param->sysm_ag_grad[0] << 16U) | ((uint32_t)param->sysm_ag_ofst[0]);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_PARAM_A));
+ val = ((uint32_t)param->sysm_ag_grad[1] << 16U) | ((uint32_t)param->sysm_ag_ofst[1]);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_PARAM_B));
+ val = ((uint32_t)param->sysm_ag_grad[2] << 16U) | ((uint32_t)param->sysm_ag_ofst[2]);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_PARAM_C));
+ val = ((uint32_t)param->sysm_ag_grad[3] << 16U) | ((uint32_t)param->sysm_ag_ofst[3]);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_PARAM_D));
+
+ /* SYSM_AG_SEL */
+ val = ((uint32_t)param->sysm_ag_psel_hobc_high << 6U) |
+ ((uint32_t)param->sysm_ag_psel_hobc_middle_led << 4U) |
+ ((uint32_t)param->sysm_ag_psel_hobc_low << 2U);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_SEL_HOBC));
+
+ val = ((uint32_t)param->sysm_ag_psel_abpc_high << 6U) |
+ ((uint32_t)param->sysm_ag_psel_abpc_middle_led << 4U) |
+ ((uint32_t)param->sysm_ag_psel_abpc_low << 2U);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_SEL_ABPC));
+
+ val = ((uint32_t)param->sysm_ag_psel_rcnr_high << 6U) |
+ ((uint32_t)param->sysm_ag_psel_rcnr_middle_led << 4U) |
+ ((uint32_t)param->sysm_ag_psel_rcnr_low << 2U);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_SEL_RCNR));
+
+ val = ((uint32_t)param->sysm_ag_ssel_lssc << 2U) | ((uint32_t)param->sysm_ag_psel_lssc);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_SEL_LSSC));
+
+ val = ((uint32_t)param->sysm_ag_ssel_mpro << 2U) | ((uint32_t)param->sysm_ag_psel_mpro);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_SEL_MPRO));
+
+ val = ((uint32_t)param->sysm_ag_ssel_vpro << 2U) | ((uint32_t)param->sysm_ag_psel_vpro);
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_SEL_VPRO));
+
+ /* SYSM_AG_CONT */
+ val = (param->sysm_ag_cont_hobc_en_middle_led << 24U) |
+ ((uint32_t)(param->sysm_ag_cont_hobc_test_middle_led) << 16U) |
+ (param->sysm_ag_cont_hobc_en_high << 8U) |
+ (uint32_t)param->sysm_ag_cont_hobc_test_high;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_HOBC01_EN));
+ val = (param->sysm_ag_cont_hobc_en_low << 8U) | (uint32_t)param->sysm_ag_cont_hobc_test_low;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_HOBC2_EN));
+
+ val = (param->sysm_ag_cont_abpc_en_middle_led << 24U) |
+ ((uint32_t)(param->sysm_ag_cont_abpc_test_middle_led) << 16U) |
+ (param->sysm_ag_cont_abpc_en_high << 8U) |
+ (uint32_t)param->sysm_ag_cont_abpc_test_high;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_ABPC01_EN));
+ val = (param->sysm_ag_cont_abpc_en_low << 8U) | (uint32_t)param->sysm_ag_cont_abpc_test_low;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_ABPC2_EN));
+
+ val = (param->sysm_ag_cont_rcnr_en_middle_led << 24U) |
+ ((uint32_t)(param->sysm_ag_cont_rcnr_test_middle_led) << 16U) |
+ (param->sysm_ag_cont_rcnr_en_high << 8U) |
+ (uint32_t)param->sysm_ag_cont_rcnr_test_high;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_RCNR01_EN));
+ val = (param->sysm_ag_cont_rcnr_en_low << 8U) | (uint32_t)param->sysm_ag_cont_rcnr_test_low;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_RCNR2_EN));
+
+ val = (param->sysm_ag_cont_lssc_en << 8U) | (uint32_t)param->sysm_ag_cont_lssc_test;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_LSSC_EN));
+
+ val = (param->sysm_ag_cont_mpro_en << 8U) | (uint32_t)param->sysm_ag_cont_mpro_test;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_MPRO_EN));
+
+ val = (param->sysm_ag_cont_vpro_en << 8U) | (uint32_t)param->sysm_ag_cont_vpro_test;
+ writel(val, &(res->capture_reg->l1isp.L1_SYSM_AG_CONT_VPRO_EN));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_ag() - Configure L1ISP analog gain.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @gain_h: analog gain value for high sensitivity image [0..65535]
+ * @gain_m: analog gain value for middle sensitivity or led image [0..65535]
+ * @gain_l: analog gain value for low sensitivity image [0..65535]
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ */
+int32_t hwd_VIIF_l1_set_ag(uint32_t module_id, uint32_t regbuf_id, uint16_t gain_h, uint16_t gain_m,
+ uint16_t gain_l)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+
+ writel((uint32_t)gain_h, &(res->capture_reg->l1isp.L1_SYSM_AG_H));
+ writel((uint32_t)gain_m, &(res->capture_reg->l1isp.L1_SYSM_AG_M));
+ writel((uint32_t)gain_l, &(res->capture_reg->l1isp.L1_SYSM_AG_L));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_hdre() - Configure L1ISP HDR extension parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to struct hwd_viif_l1_hdre
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "param" is NULL
+ * - each member of "param" is invalid
+ */
+int32_t hwd_VIIF_l1_set_hdre(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdre *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t idx;
+
+ if (param == NULL)
+ return -EINVAL;
+
+ for (idx = 0; idx < 16U; idx++) {
+ if (param->hdre_src_point[idx] > HWD_VIIF_L1_HDRE_MAX_KNEEPOINT_VAL) {
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < 17U; idx++) {
+ if (param->hdre_dst_base[idx] > HWD_VIIF_L1_HDRE_MAX_HDRE_SIG_VAL) {
+ return -EINVAL;
+ }
+ if (param->hdre_ratio[idx] >= HWD_VIIF_L1_HDRE_MAX_OUT_PIXEL_RATIO) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->hdre_dst_max_val > HWD_VIIF_L1_HDRE_MAX_OUT_PIXEL_VAL)
+ return -EINVAL;
+
+ writel(param->hdre_src_point[0], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint00));
+ writel(param->hdre_src_point[1], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint01));
+ writel(param->hdre_src_point[2], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint02));
+ writel(param->hdre_src_point[3], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint03));
+ writel(param->hdre_src_point[4], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint04));
+ writel(param->hdre_src_point[5], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint05));
+ writel(param->hdre_src_point[6], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint06));
+ writel(param->hdre_src_point[7], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint07));
+ writel(param->hdre_src_point[8], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint08));
+ writel(param->hdre_src_point[9], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint09));
+ writel(param->hdre_src_point[10], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint10));
+ writel(param->hdre_src_point[11], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint11));
+ writel(param->hdre_src_point[12], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint12));
+ writel(param->hdre_src_point[13], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint13));
+ writel(param->hdre_src_point[14], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint14));
+ writel(param->hdre_src_point[15], &(res->capture_reg->l1isp.L1_HDRE_SrcPoint15));
+
+ writel(0, &(res->capture_reg->l1isp.L1_HDRE_SrcBase00));
+ writel(param->hdre_src_point[0], &(res->capture_reg->l1isp.L1_HDRE_SrcBase01));
+ writel(param->hdre_src_point[1], &(res->capture_reg->l1isp.L1_HDRE_SrcBase02));
+ writel(param->hdre_src_point[2], &(res->capture_reg->l1isp.L1_HDRE_SrcBase03));
+ writel(param->hdre_src_point[3], &(res->capture_reg->l1isp.L1_HDRE_SrcBase04));
+ writel(param->hdre_src_point[4], &(res->capture_reg->l1isp.L1_HDRE_SrcBase05));
+ writel(param->hdre_src_point[5], &(res->capture_reg->l1isp.L1_HDRE_SrcBase06));
+ writel(param->hdre_src_point[6], &(res->capture_reg->l1isp.L1_HDRE_SrcBase07));
+ writel(param->hdre_src_point[7], &(res->capture_reg->l1isp.L1_HDRE_SrcBase08));
+ writel(param->hdre_src_point[8], &(res->capture_reg->l1isp.L1_HDRE_SrcBase09));
+ writel(param->hdre_src_point[9], &(res->capture_reg->l1isp.L1_HDRE_SrcBase10));
+ writel(param->hdre_src_point[10], &(res->capture_reg->l1isp.L1_HDRE_SrcBase11));
+ writel(param->hdre_src_point[11], &(res->capture_reg->l1isp.L1_HDRE_SrcBase12));
+ writel(param->hdre_src_point[12], &(res->capture_reg->l1isp.L1_HDRE_SrcBase13));
+ writel(param->hdre_src_point[13], &(res->capture_reg->l1isp.L1_HDRE_SrcBase14));
+ writel(param->hdre_src_point[14], &(res->capture_reg->l1isp.L1_HDRE_SrcBase15));
+ writel(param->hdre_src_point[15], &(res->capture_reg->l1isp.L1_HDRE_SrcBase16));
+
+ writel(param->hdre_dst_base[0], &(res->capture_reg->l1isp.L1_HDRE_DstBase00));
+ writel(param->hdre_dst_base[1], &(res->capture_reg->l1isp.L1_HDRE_DstBase01));
+ writel(param->hdre_dst_base[2], &(res->capture_reg->l1isp.L1_HDRE_DstBase02));
+ writel(param->hdre_dst_base[3], &(res->capture_reg->l1isp.L1_HDRE_DstBase03));
+ writel(param->hdre_dst_base[4], &(res->capture_reg->l1isp.L1_HDRE_DstBase04));
+ writel(param->hdre_dst_base[5], &(res->capture_reg->l1isp.L1_HDRE_DstBase05));
+ writel(param->hdre_dst_base[6], &(res->capture_reg->l1isp.L1_HDRE_DstBase06));
+ writel(param->hdre_dst_base[7], &(res->capture_reg->l1isp.L1_HDRE_DstBase07));
+ writel(param->hdre_dst_base[8], &(res->capture_reg->l1isp.L1_HDRE_DstBase08));
+ writel(param->hdre_dst_base[9], &(res->capture_reg->l1isp.L1_HDRE_DstBase09));
+ writel(param->hdre_dst_base[10], &(res->capture_reg->l1isp.L1_HDRE_DstBase10));
+ writel(param->hdre_dst_base[11], &(res->capture_reg->l1isp.L1_HDRE_DstBase11));
+ writel(param->hdre_dst_base[12], &(res->capture_reg->l1isp.L1_HDRE_DstBase12));
+ writel(param->hdre_dst_base[13], &(res->capture_reg->l1isp.L1_HDRE_DstBase13));
+ writel(param->hdre_dst_base[14], &(res->capture_reg->l1isp.L1_HDRE_DstBase14));
+ writel(param->hdre_dst_base[15], &(res->capture_reg->l1isp.L1_HDRE_DstBase15));
+ writel(param->hdre_dst_base[16], &(res->capture_reg->l1isp.L1_HDRE_DstBase16));
+
+ writel(param->hdre_ratio[0], &(res->capture_reg->l1isp.L1_HDRE_Ratio00));
+ writel(param->hdre_ratio[1], &(res->capture_reg->l1isp.L1_HDRE_Ratio01));
+ writel(param->hdre_ratio[2], &(res->capture_reg->l1isp.L1_HDRE_Ratio02));
+ writel(param->hdre_ratio[3], &(res->capture_reg->l1isp.L1_HDRE_Ratio03));
+ writel(param->hdre_ratio[4], &(res->capture_reg->l1isp.L1_HDRE_Ratio04));
+ writel(param->hdre_ratio[5], &(res->capture_reg->l1isp.L1_HDRE_Ratio05));
+ writel(param->hdre_ratio[6], &(res->capture_reg->l1isp.L1_HDRE_Ratio06));
+ writel(param->hdre_ratio[7], &(res->capture_reg->l1isp.L1_HDRE_Ratio07));
+ writel(param->hdre_ratio[8], &(res->capture_reg->l1isp.L1_HDRE_Ratio08));
+ writel(param->hdre_ratio[9], &(res->capture_reg->l1isp.L1_HDRE_Ratio09));
+ writel(param->hdre_ratio[10], &(res->capture_reg->l1isp.L1_HDRE_Ratio10));
+ writel(param->hdre_ratio[11], &(res->capture_reg->l1isp.L1_HDRE_Ratio11));
+ writel(param->hdre_ratio[12], &(res->capture_reg->l1isp.L1_HDRE_Ratio12));
+ writel(param->hdre_ratio[13], &(res->capture_reg->l1isp.L1_HDRE_Ratio13));
+ writel(param->hdre_ratio[14], &(res->capture_reg->l1isp.L1_HDRE_Ratio14));
+ writel(param->hdre_ratio[15], &(res->capture_reg->l1isp.L1_HDRE_Ratio15));
+ writel(param->hdre_ratio[16], &(res->capture_reg->l1isp.L1_HDRE_Ratio16));
+
+ writel(param->hdre_dst_max_val, &(res->capture_reg->l1isp.L1_HDRE_DstMaxval));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_img_extraction() - Configure L1ISP image extraction parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @input_black_gr: black level of Gr input pixel [0x0..0xffffff]
+ * @input_black_r: black level of R input pixel [0x0..0xffffff]
+ * @input_black_b: black level of B input pixel [0x0..0xffffff]
+ * @input_black_gb: black level of Gb input pixel [0x0..0xffffff]
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "input_black_gr" is out of range
+ * - "input_black_r" is out of range
+ * - "input_black_b" is out of range
+ * - "input_black_gb" is out of range
+ */
+int32_t hwd_VIIF_l1_set_img_extraction(uint32_t module_id, uint32_t regbuf_id,
+ uint32_t input_black_gr, uint32_t input_black_r,
+ uint32_t input_black_b, uint32_t input_black_gb)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+
+ if (input_black_gr > HWD_VIIF_L1_IMG_EXTRACT_MAX_BLACK_LEVEL_VAL)
+ return -EINVAL;
+
+ if (input_black_r > HWD_VIIF_L1_IMG_EXTRACT_MAX_BLACK_LEVEL_VAL)
+ return -EINVAL;
+
+ if (input_black_b > HWD_VIIF_L1_IMG_EXTRACT_MAX_BLACK_LEVEL_VAL)
+ return -EINVAL;
+
+ if (input_black_gb > HWD_VIIF_L1_IMG_EXTRACT_MAX_BLACK_LEVEL_VAL)
+ return -EINVAL;
+
+ writel(input_black_gr, &(res->capture_reg->l1isp.L1_SLIC_SrcBlackLevelGr));
+ writel(input_black_r, &(res->capture_reg->l1isp.L1_SLIC_SrcBlackLevelR));
+ writel(input_black_b, &(res->capture_reg->l1isp.L1_SLIC_SrcBlackLevelB));
+ writel(input_black_gb, &(res->capture_reg->l1isp.L1_SLIC_SrcBlackLevelGb));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_dpc() - Configure L1ISP defect pixel correction parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param_h: pointer to defect pixel correction parameters for high sensitivity image
+ * @param_m: pointer to defect pixel correction parameters for middle sensitivity or led image
+ * @param_l: pointer to defect pixel correction parameters for low sensitivity image
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "param_h", "param_m" and "param_l" are NULL
+ * - each member of "param_h" is invalid
+ * - each member of "param_m" is invalid
+ * - each member of "param_l" is invalid
+ */
+int32_t hwd_VIIF_l1_set_dpc(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_dpc *param_h,
+ const struct hwd_viif_l1_dpc *param_m,
+ const struct hwd_viif_l1_dpc *param_l)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ const struct hwd_viif_l1_dpc *param;
+ uint32_t idx;
+ uint32_t val;
+
+ if ((param_h == NULL) && (param_m == NULL) && (param_l == NULL))
+ return -EINVAL;
+
+ for (idx = 0U; idx < 3U; idx++) {
+ if (idx == 0U)
+ param = param_h;
+ else if (idx == 1U)
+ param = param_m;
+ else
+ param = param_l;
+
+ if (param != NULL) {
+ if ((param->abpc_sta_en != HWD_VIIF_ENABLE) &&
+ (param->abpc_sta_en != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->abpc_dyn_en != HWD_VIIF_ENABLE) &&
+ (param->abpc_dyn_en != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->abpc_dyn_en == HWD_VIIF_ENABLE) {
+ if ((param->abpc_dyn_mode != HWD_VIIF_L1_DPC_1PIXEL) &&
+ (param->abpc_dyn_mode != HWD_VIIF_L1_DPC_2PIXEL)) {
+ return -EINVAL;
+ }
+ if (param->abpc_ratio_limit > HWD_VIIF_L1_DPC_MAX_RATIO_LIMIT_VAL) {
+ return -EINVAL;
+ }
+ if (param->abpc_dark_limit > HWD_VIIF_L1_DPC_MAX_RATIO_LIMIT_VAL) {
+ return -EINVAL;
+ }
+ if ((param->abpc_sn_coef_w_ag_min <
+ HWD_VIIF_L1_DPC_MIN_LUMA_ADJ_VAL) ||
+ (param->abpc_sn_coef_w_ag_min >
+ HWD_VIIF_L1_DPC_MAX_LUMA_ADJ_VAL)) {
+ return -EINVAL;
+ }
+ if ((param->abpc_sn_coef_w_ag_mid <
+ HWD_VIIF_L1_DPC_MIN_LUMA_ADJ_VAL) ||
+ (param->abpc_sn_coef_w_ag_mid >
+ HWD_VIIF_L1_DPC_MAX_LUMA_ADJ_VAL)) {
+ return -EINVAL;
+ }
+ if ((param->abpc_sn_coef_w_ag_max <
+ HWD_VIIF_L1_DPC_MIN_LUMA_ADJ_VAL) ||
+ (param->abpc_sn_coef_w_ag_max >
+ HWD_VIIF_L1_DPC_MAX_LUMA_ADJ_VAL)) {
+ return -EINVAL;
+ }
+ if ((param->abpc_sn_coef_b_ag_min <
+ HWD_VIIF_L1_DPC_MIN_LUMA_ADJ_VAL) ||
+ (param->abpc_sn_coef_b_ag_min >
+ HWD_VIIF_L1_DPC_MAX_LUMA_ADJ_VAL)) {
+ return -EINVAL;
+ }
+ if ((param->abpc_sn_coef_b_ag_mid <
+ HWD_VIIF_L1_DPC_MIN_LUMA_ADJ_VAL) ||
+ (param->abpc_sn_coef_b_ag_mid >
+ HWD_VIIF_L1_DPC_MAX_LUMA_ADJ_VAL)) {
+ return -EINVAL;
+ }
+ if ((param->abpc_sn_coef_b_ag_max <
+ HWD_VIIF_L1_DPC_MIN_LUMA_ADJ_VAL) ||
+ (param->abpc_sn_coef_b_ag_max >
+ HWD_VIIF_L1_DPC_MAX_LUMA_ADJ_VAL)) {
+ return -EINVAL;
+ }
+ if (param->abpc_sn_coef_w_th_min >= param->abpc_sn_coef_w_th_max) {
+ return -EINVAL;
+ }
+ if (param->abpc_sn_coef_b_th_min >= param->abpc_sn_coef_b_th_max) {
+ return -EINVAL;
+ }
+ }
+ }
+ }
+
+ val = 0;
+ if (param_h != NULL)
+ val |= param_h->abpc_sta_en << 24U;
+
+ if (param_m != NULL)
+ val |= param_m->abpc_sta_en << 16U;
+
+ if (param_l != NULL)
+ val |= param_l->abpc_sta_en << 8U;
+
+ writel(val, &(res->capture_reg->l1isp.L1_ABPC012_STA_EN));
+
+ val = 0;
+ if (param_h != NULL)
+ val |= param_h->abpc_dyn_en << 24U;
+
+ if (param_m != NULL)
+ val |= param_m->abpc_dyn_en << 16U;
+
+ if (param_l != NULL)
+ val |= param_l->abpc_dyn_en << 8U;
+
+ writel(val, &(res->capture_reg->l1isp.L1_ABPC012_DYN_EN));
+
+ val = 0;
+ if (param_h != NULL)
+ val |= param_h->abpc_dyn_mode << 24U;
+
+ if (param_m != NULL)
+ val |= param_m->abpc_dyn_mode << 16U;
+
+ if (param_l != NULL)
+ val |= param_l->abpc_dyn_mode << 8U;
+
+ writel(val, &(res->capture_reg->l1isp.L1_ABPC012_DYN_MODE));
+
+ if (param_h != NULL) {
+ writel(param_h->abpc_ratio_limit, &(res->capture_reg->l1isp.L1_ABPC0_RATIO_LIMIT));
+ writel(param_h->abpc_dark_limit, &(res->capture_reg->l1isp.L1_ABPC0_DARK_LIMIT));
+ writel(param_h->abpc_sn_coef_w_ag_min,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_W_AG_MIN));
+ writel(param_h->abpc_sn_coef_w_ag_mid,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_W_AG_MID));
+ writel(param_h->abpc_sn_coef_w_ag_max,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_W_AG_MAX));
+ writel(param_h->abpc_sn_coef_b_ag_min,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_B_AG_MIN));
+ writel(param_h->abpc_sn_coef_b_ag_mid,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_B_AG_MID));
+ writel(param_h->abpc_sn_coef_b_ag_max,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_B_AG_MAX));
+ writel((uint32_t)param_h->abpc_sn_coef_w_th_min,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_W_TH_MIN));
+ writel((uint32_t)param_h->abpc_sn_coef_w_th_max,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_W_TH_MAX));
+ writel((uint32_t)param_h->abpc_sn_coef_b_th_min,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_B_TH_MIN));
+ writel((uint32_t)param_h->abpc_sn_coef_b_th_max,
+ &(res->capture_reg->l1isp.L1_ABPC0_SN_COEF_B_TH_MAX));
+ }
+
+ if (param_m != NULL) {
+ writel(param_m->abpc_ratio_limit, &(res->capture_reg->l1isp.L1_ABPC1_RATIO_LIMIT));
+ writel(param_m->abpc_dark_limit, &(res->capture_reg->l1isp.L1_ABPC1_DARK_LIMIT));
+ writel(param_m->abpc_sn_coef_w_ag_min,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_W_AG_MIN));
+ writel(param_m->abpc_sn_coef_w_ag_mid,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_W_AG_MID));
+ writel(param_m->abpc_sn_coef_w_ag_max,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_W_AG_MAX));
+ writel(param_m->abpc_sn_coef_b_ag_min,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_B_AG_MIN));
+ writel(param_m->abpc_sn_coef_b_ag_mid,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_B_AG_MID));
+ writel(param_m->abpc_sn_coef_b_ag_max,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_B_AG_MAX));
+ writel((uint32_t)param_m->abpc_sn_coef_w_th_min,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_W_TH_MIN));
+ writel((uint32_t)param_m->abpc_sn_coef_w_th_max,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_W_TH_MAX));
+ writel((uint32_t)param_m->abpc_sn_coef_b_th_min,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_B_TH_MIN));
+ writel((uint32_t)param_m->abpc_sn_coef_b_th_max,
+ &(res->capture_reg->l1isp.L1_ABPC1_SN_COEF_B_TH_MAX));
+ }
+
+ if (param_l != NULL) {
+ writel(param_l->abpc_ratio_limit, &(res->capture_reg->l1isp.L1_ABPC2_RATIO_LIMIT));
+ writel(param_l->abpc_dark_limit, &(res->capture_reg->l1isp.L1_ABPC2_DARK_LIMIT));
+ writel(param_l->abpc_sn_coef_w_ag_min,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_W_AG_MIN));
+ writel(param_l->abpc_sn_coef_w_ag_mid,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_W_AG_MID));
+ writel(param_l->abpc_sn_coef_w_ag_max,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_W_AG_MAX));
+ writel(param_l->abpc_sn_coef_b_ag_min,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_B_AG_MIN));
+ writel(param_l->abpc_sn_coef_b_ag_mid,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_B_AG_MID));
+ writel(param_l->abpc_sn_coef_b_ag_max,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_B_AG_MAX));
+ writel((uint32_t)param_l->abpc_sn_coef_w_th_min,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_W_TH_MIN));
+ writel((uint32_t)param_l->abpc_sn_coef_w_th_max,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_W_TH_MAX));
+ writel((uint32_t)param_l->abpc_sn_coef_b_th_min,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_B_TH_MIN));
+ writel((uint32_t)param_l->abpc_sn_coef_b_th_max,
+ &(res->capture_reg->l1isp.L1_ABPC2_SN_COEF_B_TH_MAX));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_dpc_table_transmission() - Configure L1ISP transferring defect pixel correction table.
+ *
+ * @table_h: defect pixel correction table for high sensitivity image(physical address)
+ * @table_m: defect pixel correction table for middle sensitivity or led image(physical address)
+ * @table_l: defect pixel correction table for low sensitivity image(physical address)
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "table_h", "table_m" or "table_l" is not 8byte alignment
+ *
+ * Note that when 0 is set to table address, table transfer of the table is disabled.
+ */
+int32_t hwd_VIIF_l1_set_dpc_table_transmission(uint32_t module_id, uintptr_t table_h,
+ uintptr_t table_m, uintptr_t table_l)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val = 0x0U;
+
+ if (((table_h % HWD_VIIF_L1_VDM_ALIGN) != 0U) ||
+ ((table_m % HWD_VIIF_L1_VDM_ALIGN) != 0U) ||
+ ((table_l % HWD_VIIF_L1_VDM_ALIGN) != 0U)) {
+ return -EINVAL;
+ }
+
+ /* VDM common settings */
+
+ writel(HWD_VIIF_L1_VDM_CFG_PARAM, &(res->capture_reg->vdm.t_group[0].VDM_T_CFG));
+ writel(HWD_VIIF_L1_VDM_SRAM_BASE, &(res->capture_reg->vdm.t_group[0].VDM_T_SRAM_BASE));
+ writel(HWD_VIIF_L1_VDM_SRAM_SIZE, &(res->capture_reg->vdm.t_group[0].VDM_T_SRAM_SIZE));
+
+ if (table_h != 0U) {
+ writel((uint32_t)table_h, &(res->capture_reg->vdm.t_port[0].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_DPC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[0].VDM_T_SIZE));
+ val |= 0x1U;
+ }
+
+ if (table_m != 0U) {
+ writel((uint32_t)table_m, &(res->capture_reg->vdm.t_port[1].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_DPC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[1].VDM_T_SIZE));
+ val |= 0x2U;
+ }
+
+ if (table_l != 0U) {
+ writel((uint32_t)table_l, &(res->capture_reg->vdm.t_port[2].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_DPC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[2].VDM_T_SIZE));
+ val |= 0x4U;
+ }
+
+ val |= (readl(&res->capture_reg->vdm.VDM_T_ENABLE) & 0xfffffff8U);
+ writel(val, &(res->capture_reg->vdm.VDM_T_ENABLE));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_preset_white_balance() - Configure L1ISP preset white balance parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @dstmaxval: maximum output pixel value [0..4095]
+ * @param_h: pointer to preset white balance parameters for high sensitivity image
+ * @param_m: pointer to preset white balance parameters for middle sensitivity or led image
+ * @param_l: pointer to preset white balance parameters for low sensitivity image
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "dstmaxval" is out of range
+ * - "param_h", "param_m", and "param_l" are NULL
+ * - each parameter of "param_h" is out of range
+ * - each parameter of "param_m" is out of range
+ * - each parameter of "param_l" is out of range
+ * Note that when NULL is set to "param_{h/m/l}", the corresponding parameters are not set to HW.
+ */
+int32_t hwd_VIIF_l1_set_preset_white_balance(uint32_t module_id, uint32_t regbuf_id,
+ uint32_t dstmaxval,
+ const struct hwd_viif_l1_preset_white_balance *param_h,
+ const struct hwd_viif_l1_preset_white_balance *param_m,
+ const struct hwd_viif_l1_preset_white_balance *param_l)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+
+ if (dstmaxval > HWD_VIIF_L1_PWHB_MAX_OUT_PIXEL_VAL)
+ return -EINVAL;
+
+ if ((param_h == NULL) && (param_m == NULL) && (param_l == NULL))
+ return -EINVAL;
+
+ if (param_h != NULL) {
+ if (param_h->gain_gr >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_h->gain_r >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_h->gain_b >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_h->gain_gb >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+ }
+
+ if (param_m != NULL) {
+ if (param_m->gain_gr >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_m->gain_r >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_m->gain_b >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_m->gain_gb >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+ }
+
+ if (param_l != NULL) {
+ if (param_l->gain_gr >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_l->gain_r >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_l->gain_b >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param_l->gain_gb >= HWD_VIIF_L1_PWHB_MAX_GAIN_VAL)
+ return -EINVAL;
+ }
+
+ writel(dstmaxval, &(res->capture_reg->l1isp.L1_PWHB_DstMaxval));
+
+ if (param_h != NULL) {
+ writel(param_h->gain_gr, &(res->capture_reg->l1isp.L1_PWHB_HGr));
+ writel(param_h->gain_r, &(res->capture_reg->l1isp.L1_PWHB_HR));
+ writel(param_h->gain_b, &(res->capture_reg->l1isp.L1_PWHB_HB));
+ writel(param_h->gain_gb, &(res->capture_reg->l1isp.L1_PWHB_HGb));
+ }
+
+ if (param_m != NULL) {
+ writel(param_m->gain_gr, &(res->capture_reg->l1isp.L1_PWHB_MGr));
+ writel(param_m->gain_r, &(res->capture_reg->l1isp.L1_PWHB_MR));
+ writel(param_m->gain_b, &(res->capture_reg->l1isp.L1_PWHB_MB));
+ writel(param_m->gain_gb, &(res->capture_reg->l1isp.L1_PWHB_MGb));
+ }
+
+ if (param_l != NULL) {
+ writel(param_l->gain_gr, &(res->capture_reg->l1isp.L1_PWHB_LGr));
+ writel(param_l->gain_r, &(res->capture_reg->l1isp.L1_PWHB_LR));
+ writel(param_l->gain_b, &(res->capture_reg->l1isp.L1_PWHB_LB));
+ writel(param_l->gain_gb, &(res->capture_reg->l1isp.L1_PWHB_LGb));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_raw_color_noise_reduction() - Configure L1ISP raw color noise reduction parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param_h: pointer to raw color noise reduction parameters for high sensitivity image
+ * @param_m: pointer to raw color noise reduction parameters for middle sensitivity or led image
+ * @param_l: pointer to raw color noise reduction parameters for low sensitivity image
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "param_h", "param_m", and "param_l" are NULL
+ * - each parameter of "param_h" is out of range
+ * - each parameter of "param_m" is out of range
+ * - each parameter of "param_l" is out of range
+ * Note that when NULL is set to "param_{h/m/l}", the corresponding parameters are not set to HW.
+ */
+int32_t hwd_VIIF_l1_set_raw_color_noise_reduction(
+ uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_raw_color_noise_reduction *param_h,
+ const struct hwd_viif_l1_raw_color_noise_reduction *param_m,
+ const struct hwd_viif_l1_raw_color_noise_reduction *param_l)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ int32_t ret = 0;
+ const struct hwd_viif_l1_raw_color_noise_reduction *param;
+ uint32_t idx;
+
+ if ((param_h == NULL) && (param_m == NULL) && (param_l == NULL))
+ return -EINVAL;
+
+ for (idx = 0; idx < 3U; idx++) {
+ if (idx == 0U)
+ param = param_h;
+ else if (idx == 1U)
+ param = param_m;
+ else
+ param = param_l;
+
+ if (param != NULL) {
+ if ((param->rcnr_sw != HWD_VIIF_ENABLE) &&
+ (param->rcnr_sw != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_cnf_dark_ag0 > HWD_VIIF_L1_RCNR_MAX_DARK_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_cnf_dark_ag1 > HWD_VIIF_L1_RCNR_MAX_DARK_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_cnf_dark_ag2 > HWD_VIIF_L1_RCNR_MAX_DARK_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_cnf_ratio_ag0 >
+ HWD_VIIF_L1_RCNR_MAX_LUMA_LINKAGE_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_cnf_ratio_ag1 >
+ HWD_VIIF_L1_RCNR_MAX_LUMA_LINKAGE_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_cnf_ratio_ag2 >
+ HWD_VIIF_L1_RCNR_MAX_LUMA_LINKAGE_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_cnf_clip_gain_r >
+ HWD_VIIF_L1_RCNR_MAX_ADJUSTMENT_GAIN_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_cnf_clip_gain_g >
+ HWD_VIIF_L1_RCNR_MAX_ADJUSTMENT_GAIN_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_cnf_clip_gain_b >
+ HWD_VIIF_L1_RCNR_MAX_ADJUSTMENT_GAIN_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_a1l_dark_ag0 > HWD_VIIF_L1_RCNR_MAX_DARK_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_a1l_dark_ag1 > HWD_VIIF_L1_RCNR_MAX_DARK_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_a1l_dark_ag2 > HWD_VIIF_L1_RCNR_MAX_DARK_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_a1l_ratio_ag0 >
+ HWD_VIIF_L1_RCNR_MAX_LUMA_LINKAGE_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_a1l_ratio_ag1 >
+ HWD_VIIF_L1_RCNR_MAX_LUMA_LINKAGE_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_a1l_ratio_ag2 >
+ HWD_VIIF_L1_RCNR_MAX_LUMA_LINKAGE_ADJUSTMENT_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_inf_zero_clip > HWD_VIIF_L1_RCNR_MAX_ZERO_CLIP_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_merge_d2blend_ag0 > HWD_VIIF_L1_RCNR_MAX_BLEND_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_merge_d2blend_ag1 > HWD_VIIF_L1_RCNR_MAX_BLEND_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_merge_d2blend_ag2 > HWD_VIIF_L1_RCNR_MAX_BLEND_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_merge_black > HWD_VIIF_L1_RCNR_MAX_BLACK_LEVEL_VAL) {
+ return -EINVAL;
+ }
+
+ if ((param->rcnr_merge_mindiv < HWD_VIIF_L1_RCNR_MIN_0DIV_GUARD_VAL) ||
+ (param->rcnr_merge_mindiv > HWD_VIIF_L1_RCNR_MAX_0DIV_GUARD_VAL)) {
+ return -EINVAL;
+ }
+
+ switch (param->rcnr_hry_type) {
+ case HWD_VIIF_L1_RCNR_LOW_RESOLUTION:
+ case HWD_VIIF_L1_RCNR_MIDDLE_RESOLUTION:
+ case HWD_VIIF_L1_RCNR_HIGH_RESOLUTION:
+ case HWD_VIIF_L1_RCNR_ULTRA_HIGH_RESOLUTION:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ if ((param->rcnr_anf_blend_ag0 != HWD_VIIF_L1_MSF_BLEND_RATIO_0_DIV_64) &&
+ (param->rcnr_anf_blend_ag0 != HWD_VIIF_L1_MSF_BLEND_RATIO_1_DIV_64) &&
+ (param->rcnr_anf_blend_ag0 != HWD_VIIF_L1_MSF_BLEND_RATIO_2_DIV_64)) {
+ return -EINVAL;
+ }
+ if ((param->rcnr_anf_blend_ag1 != HWD_VIIF_L1_MSF_BLEND_RATIO_0_DIV_64) &&
+ (param->rcnr_anf_blend_ag1 != HWD_VIIF_L1_MSF_BLEND_RATIO_1_DIV_64) &&
+ (param->rcnr_anf_blend_ag1 != HWD_VIIF_L1_MSF_BLEND_RATIO_2_DIV_64)) {
+ return -EINVAL;
+ }
+ if ((param->rcnr_anf_blend_ag2 != HWD_VIIF_L1_MSF_BLEND_RATIO_0_DIV_64) &&
+ (param->rcnr_anf_blend_ag2 != HWD_VIIF_L1_MSF_BLEND_RATIO_1_DIV_64) &&
+ (param->rcnr_anf_blend_ag2 != HWD_VIIF_L1_MSF_BLEND_RATIO_2_DIV_64)) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_lpf_threshold >=
+ HWD_VIIF_L1_RCNR_MAX_CALC_MSF_NOISE_MULTI_VAL) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_merge_hlblend_ag0 >
+ HWD_VIIF_L1_RCNR_MAX_GEN_LUMA_SIG_BLEND_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_merge_hlblend_ag1 >
+ HWD_VIIF_L1_RCNR_MAX_GEN_LUMA_SIG_BLEND_VAL) {
+ return -EINVAL;
+ }
+ if (param->rcnr_merge_hlblend_ag2 >
+ HWD_VIIF_L1_RCNR_MAX_GEN_LUMA_SIG_BLEND_VAL) {
+ return -EINVAL;
+ }
+
+ if ((param->rcnr_gnr_sw != HWD_VIIF_DISABLE) &&
+ (param->rcnr_gnr_sw != HWD_VIIF_ENABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->rcnr_gnr_sw == HWD_VIIF_ENABLE) {
+ if (param->rcnr_gnr_ratio >
+ HWD_VIIF_L1_RCNR_MAX_UP_LIMIT_GRGB_SENS_RATIO) {
+ return -EINVAL;
+ }
+ if ((param->rcnr_gnr_wide_en != HWD_VIIF_DISABLE) &&
+ (param->rcnr_gnr_wide_en != HWD_VIIF_ENABLE)) {
+ return -EINVAL;
+ }
+ }
+ }
+ }
+
+ if (param_h != NULL) {
+ writel(param_h->rcnr_sw, &(res->capture_reg->l1isp.L1_RCNR0_SW));
+
+ writel(param_h->rcnr_cnf_dark_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_DARK_AG0));
+ writel(param_h->rcnr_cnf_dark_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_DARK_AG1));
+ writel(param_h->rcnr_cnf_dark_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_DARK_AG2));
+
+ writel(param_h->rcnr_cnf_ratio_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_RATIO_AG0));
+ writel(param_h->rcnr_cnf_ratio_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_RATIO_AG1));
+ writel(param_h->rcnr_cnf_ratio_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_RATIO_AG2));
+
+ writel(param_h->rcnr_cnf_clip_gain_r,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_CLIP_GAIN_R));
+ writel(param_h->rcnr_cnf_clip_gain_g,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_CLIP_GAIN_G));
+ writel(param_h->rcnr_cnf_clip_gain_b,
+ &(res->capture_reg->l1isp.L1_RCNR0_CNF_CLIP_GAIN_B));
+
+ writel(param_h->rcnr_a1l_dark_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_A1L_DARK_AG0));
+ writel(param_h->rcnr_a1l_dark_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_A1L_DARK_AG1));
+ writel(param_h->rcnr_a1l_dark_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_A1L_DARK_AG2));
+
+ writel(param_h->rcnr_a1l_ratio_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_A1L_RATIO_AG0));
+ writel(param_h->rcnr_a1l_ratio_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_A1L_RATIO_AG1));
+ writel(param_h->rcnr_a1l_ratio_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_A1L_RATIO_AG2));
+
+ writel(param_h->rcnr_inf_zero_clip,
+ &(res->capture_reg->l1isp.L1_RCNR0_INF_ZERO_CLIP));
+
+ writel(param_h->rcnr_merge_d2blend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_D2BLEND_AG0));
+ writel(param_h->rcnr_merge_d2blend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_D2BLEND_AG1));
+ writel(param_h->rcnr_merge_d2blend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_D2BLEND_AG2));
+ writel(param_h->rcnr_merge_black, &(res->capture_reg->l1isp.L1_RCNR0_MERGE_BLACK));
+ writel(param_h->rcnr_merge_mindiv,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_MINDIV));
+
+ writel(param_h->rcnr_hry_type, &(res->capture_reg->l1isp.L1_RCNR0_HRY_TYPE));
+
+ writel(param_h->rcnr_anf_blend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_ANF_BLEND_AG0));
+ writel(param_h->rcnr_anf_blend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_ANF_BLEND_AG1));
+ writel(param_h->rcnr_anf_blend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_ANF_BLEND_AG2));
+
+ writel(param_h->rcnr_lpf_threshold,
+ &(res->capture_reg->l1isp.L1_RCNR0_LPF_THRESHOLD));
+
+ writel(param_h->rcnr_merge_hlblend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_HLBLEND_AG0));
+ writel(param_h->rcnr_merge_hlblend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_HLBLEND_AG1));
+ writel(param_h->rcnr_merge_hlblend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR0_MERGE_HLBLEND_AG2));
+
+ writel(param_h->rcnr_gnr_sw, &(res->capture_reg->l1isp.L1_RCNR0_GNR_SW));
+
+ if (param_h->rcnr_gnr_sw == HWD_VIIF_ENABLE) {
+ writel(param_h->rcnr_gnr_ratio,
+ &(res->capture_reg->l1isp.L1_RCNR0_GNR_RATIO));
+ writel(param_h->rcnr_gnr_wide_en,
+ &(res->capture_reg->l1isp.L1_RCNR0_GNR_WIDE_EN));
+ }
+ }
+
+ if (param_m != NULL) {
+ writel(param_m->rcnr_sw, &(res->capture_reg->l1isp.L1_RCNR1_SW));
+
+ writel(param_m->rcnr_cnf_dark_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_DARK_AG0));
+ writel(param_m->rcnr_cnf_dark_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_DARK_AG1));
+ writel(param_m->rcnr_cnf_dark_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_DARK_AG2));
+
+ writel(param_m->rcnr_cnf_ratio_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_RATIO_AG0));
+ writel(param_m->rcnr_cnf_ratio_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_RATIO_AG1));
+ writel(param_m->rcnr_cnf_ratio_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_RATIO_AG2));
+
+ writel(param_m->rcnr_cnf_clip_gain_r,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_CLIP_GAIN_R));
+ writel(param_m->rcnr_cnf_clip_gain_g,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_CLIP_GAIN_G));
+ writel(param_m->rcnr_cnf_clip_gain_b,
+ &(res->capture_reg->l1isp.L1_RCNR1_CNF_CLIP_GAIN_B));
+
+ writel(param_m->rcnr_a1l_dark_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_A1L_DARK_AG0));
+ writel(param_m->rcnr_a1l_dark_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_A1L_DARK_AG1));
+ writel(param_m->rcnr_a1l_dark_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_A1L_DARK_AG2));
+
+ writel(param_m->rcnr_a1l_ratio_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_A1L_RATIO_AG0));
+ writel(param_m->rcnr_a1l_ratio_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_A1L_RATIO_AG1));
+ writel(param_m->rcnr_a1l_ratio_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_A1L_RATIO_AG2));
+
+ writel(param_m->rcnr_inf_zero_clip,
+ &(res->capture_reg->l1isp.L1_RCNR1_INF_ZERO_CLIP));
+
+ writel(param_m->rcnr_merge_d2blend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_D2BLEND_AG0));
+ writel(param_m->rcnr_merge_d2blend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_D2BLEND_AG1));
+ writel(param_m->rcnr_merge_d2blend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_D2BLEND_AG2));
+ writel(param_m->rcnr_merge_black, &(res->capture_reg->l1isp.L1_RCNR1_MERGE_BLACK));
+ writel(param_m->rcnr_merge_mindiv,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_MINDIV));
+
+ writel(param_m->rcnr_hry_type, &(res->capture_reg->l1isp.L1_RCNR1_HRY_TYPE));
+
+ writel(param_m->rcnr_anf_blend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_ANF_BLEND_AG0));
+ writel(param_m->rcnr_anf_blend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_ANF_BLEND_AG1));
+ writel(param_m->rcnr_anf_blend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_ANF_BLEND_AG2));
+
+ writel(param_m->rcnr_lpf_threshold,
+ &(res->capture_reg->l1isp.L1_RCNR1_LPF_THRESHOLD));
+
+ writel(param_m->rcnr_merge_hlblend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_HLBLEND_AG0));
+ writel(param_m->rcnr_merge_hlblend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_HLBLEND_AG1));
+ writel(param_m->rcnr_merge_hlblend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR1_MERGE_HLBLEND_AG2));
+
+ writel(param_m->rcnr_gnr_sw, &(res->capture_reg->l1isp.L1_RCNR1_GNR_SW));
+
+ if (param_m->rcnr_gnr_sw == HWD_VIIF_ENABLE) {
+ writel(param_m->rcnr_gnr_ratio,
+ &(res->capture_reg->l1isp.L1_RCNR1_GNR_RATIO));
+ writel(param_m->rcnr_gnr_wide_en,
+ &(res->capture_reg->l1isp.L1_RCNR1_GNR_WIDE_EN));
+ }
+ }
+
+ if (param_l != NULL) {
+ writel(param_l->rcnr_sw, &(res->capture_reg->l1isp.L1_RCNR2_SW));
+
+ writel(param_l->rcnr_cnf_dark_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_DARK_AG0));
+ writel(param_l->rcnr_cnf_dark_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_DARK_AG1));
+ writel(param_l->rcnr_cnf_dark_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_DARK_AG2));
+
+ writel(param_l->rcnr_cnf_ratio_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_RATIO_AG0));
+ writel(param_l->rcnr_cnf_ratio_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_RATIO_AG1));
+ writel(param_l->rcnr_cnf_ratio_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_RATIO_AG2));
+
+ writel(param_l->rcnr_cnf_clip_gain_r,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_CLIP_GAIN_R));
+ writel(param_l->rcnr_cnf_clip_gain_g,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_CLIP_GAIN_G));
+ writel(param_l->rcnr_cnf_clip_gain_b,
+ &(res->capture_reg->l1isp.L1_RCNR2_CNF_CLIP_GAIN_B));
+
+ writel(param_l->rcnr_a1l_dark_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_A1L_DARK_AG0));
+ writel(param_l->rcnr_a1l_dark_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_A1L_DARK_AG1));
+ writel(param_l->rcnr_a1l_dark_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_A1L_DARK_AG2));
+
+ writel(param_l->rcnr_a1l_ratio_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_A1L_RATIO_AG0));
+ writel(param_l->rcnr_a1l_ratio_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_A1L_RATIO_AG1));
+ writel(param_l->rcnr_a1l_ratio_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_A1L_RATIO_AG2));
+
+ writel(param_l->rcnr_inf_zero_clip,
+ &(res->capture_reg->l1isp.L1_RCNR2_INF_ZERO_CLIP));
+
+ writel(param_l->rcnr_merge_d2blend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_D2BLEND_AG0));
+ writel(param_l->rcnr_merge_d2blend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_D2BLEND_AG1));
+ writel(param_l->rcnr_merge_d2blend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_D2BLEND_AG2));
+ writel(param_l->rcnr_merge_black, &(res->capture_reg->l1isp.L1_RCNR2_MERGE_BLACK));
+ writel(param_l->rcnr_merge_mindiv,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_MINDIV));
+
+ writel(param_l->rcnr_hry_type, &(res->capture_reg->l1isp.L1_RCNR2_HRY_TYPE));
+
+ writel(param_l->rcnr_anf_blend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_ANF_BLEND_AG0));
+ writel(param_l->rcnr_anf_blend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_ANF_BLEND_AG1));
+ writel(param_l->rcnr_anf_blend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_ANF_BLEND_AG2));
+
+ writel(param_l->rcnr_lpf_threshold,
+ &(res->capture_reg->l1isp.L1_RCNR2_LPF_THRESHOLD));
+
+ writel(param_l->rcnr_merge_hlblend_ag0,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_HLBLEND_AG0));
+ writel(param_l->rcnr_merge_hlblend_ag1,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_HLBLEND_AG1));
+ writel(param_l->rcnr_merge_hlblend_ag2,
+ &(res->capture_reg->l1isp.L1_RCNR2_MERGE_HLBLEND_AG2));
+
+ writel(param_l->rcnr_gnr_sw, &(res->capture_reg->l1isp.L1_RCNR2_GNR_SW));
+
+ if (param_l->rcnr_gnr_sw == HWD_VIIF_ENABLE) {
+ writel(param_l->rcnr_gnr_ratio,
+ &(res->capture_reg->l1isp.L1_RCNR2_GNR_RATIO));
+ writel(param_l->rcnr_gnr_wide_en,
+ &(res->capture_reg->l1isp.L1_RCNR2_GNR_WIDE_EN));
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_hdrs() - Configure L1ISP HDR synthesis parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to HDR synthesis parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "param" is NULL
+ * - each parameter of "param" is out of range
+ */
+int32_t hwd_VIIF_l1_set_hdrs(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdrs *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+
+ if (param == NULL)
+ return -EINVAL;
+
+ if ((param->hdrs_hdr_mode != HWD_VIIF_L1_HDRS_NOT_USE_MIDDLE_SENS_IMAGE) &&
+ (param->hdrs_hdr_mode != HWD_VIIF_L1_HDRS_USE_MIDDLE_SENS_IMAGE)) {
+ return -EINVAL;
+ }
+
+ if ((param->hdrs_hdr_ratio_m < HWD_VIIF_L1_HDRS_MIN_BLEND_RATIO) ||
+ (param->hdrs_hdr_ratio_m > HWD_VIIF_L1_HDRS_MAX_BLEND_RATIO)) {
+ return -EINVAL;
+ }
+ if ((param->hdrs_hdr_ratio_l < HWD_VIIF_L1_HDRS_MIN_BLEND_RATIO) ||
+ (param->hdrs_hdr_ratio_l > HWD_VIIF_L1_HDRS_MAX_BLEND_RATIO)) {
+ return -EINVAL;
+ }
+ if ((param->hdrs_hdr_ratio_e < HWD_VIIF_L1_HDRS_MIN_BLEND_RATIO) ||
+ (param->hdrs_hdr_ratio_e > HWD_VIIF_L1_HDRS_MAX_BLEND_RATIO)) {
+ return -EINVAL;
+ }
+
+ if (param->hdrs_dg_h >= HWD_VIIF_L1_HDRS_MAX_DIGITAL_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_dg_m >= HWD_VIIF_L1_HDRS_MAX_DIGITAL_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_dg_l >= HWD_VIIF_L1_HDRS_MAX_DIGITAL_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_dg_e >= HWD_VIIF_L1_HDRS_MAX_DIGITAL_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_blendend_h > HWD_VIIF_L1_HDRS_MAX_BLEND_PIX_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_blendend_m > HWD_VIIF_L1_HDRS_MAX_BLEND_PIX_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_blendend_e > HWD_VIIF_L1_HDRS_MAX_BLEND_PIX_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_blendbeg_h > HWD_VIIF_L1_HDRS_MAX_BLEND_PIX_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_blendbeg_m > HWD_VIIF_L1_HDRS_MAX_BLEND_PIX_VAL)
+ return -EINVAL;
+
+ if (param->hdrs_blendbeg_e > HWD_VIIF_L1_HDRS_MAX_BLEND_PIX_VAL)
+ return -EINVAL;
+
+ if ((param->hdrs_led_mode_on != HWD_VIIF_ENABLE) &&
+ (param->hdrs_led_mode_on != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->hdrs_dst_max_val > HWD_VIIF_L1_HDRS_MAX_DST_MAX_VAL)
+ return -EINVAL;
+
+ writel(param->hdrs_hdr_mode, &(res->capture_reg->l1isp.L1_HDRS_HdrMode));
+
+ writel(param->hdrs_hdr_ratio_m, &(res->capture_reg->l1isp.L1_HDRS_HdrRatioM));
+ writel(param->hdrs_hdr_ratio_l, &(res->capture_reg->l1isp.L1_HDRS_HdrRatioL));
+ writel(param->hdrs_hdr_ratio_e, &(res->capture_reg->l1isp.L1_HDRS_HdrRatioE));
+
+ writel(param->hdrs_dg_h, &(res->capture_reg->l1isp.L1_HDRS_DgH));
+ writel(param->hdrs_dg_m, &(res->capture_reg->l1isp.L1_HDRS_DgM));
+ writel(param->hdrs_dg_l, &(res->capture_reg->l1isp.L1_HDRS_DgL));
+ writel(param->hdrs_dg_e, &(res->capture_reg->l1isp.L1_HDRS_DgE));
+
+ writel(param->hdrs_blendend_h, &(res->capture_reg->l1isp.L1_HDRS_BlendEndH));
+ writel(param->hdrs_blendend_m, &(res->capture_reg->l1isp.L1_HDRS_BlendEndM));
+ writel(param->hdrs_blendend_e, &(res->capture_reg->l1isp.L1_HDRS_BlendEndE));
+
+ writel(param->hdrs_blendbeg_h, &(res->capture_reg->l1isp.L1_HDRS_BlendBegH));
+ writel(param->hdrs_blendbeg_m, &(res->capture_reg->l1isp.L1_HDRS_BlendBegM));
+ writel(param->hdrs_blendbeg_e, &(res->capture_reg->l1isp.L1_HDRS_BlendBegE));
+
+ writel(param->hdrs_led_mode_on, &(res->capture_reg->l1isp.L1_HDRS_LedModeOn));
+ writel(param->hdrs_dst_max_val, &(res->capture_reg->l1isp.L1_HDRS_DstMaxval));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_black_level_correction() - Configure L1ISP black level correction parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to black level correction parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "param" is NULL
+ * - each parameter of "param" is out of range
+ */
+int32_t
+hwd_VIIF_l1_set_black_level_correction(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_black_level_correction *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ if (param == NULL)
+ return -EINVAL;
+
+ if (param->srcblacklevel_gr > HWD_VIIF_L1_BLACK_LEVEL_MAX_VAL)
+ return -EINVAL;
+
+ if (param->srcblacklevel_r > HWD_VIIF_L1_BLACK_LEVEL_MAX_VAL)
+ return -EINVAL;
+
+ if (param->srcblacklevel_b > HWD_VIIF_L1_BLACK_LEVEL_MAX_VAL)
+ return -EINVAL;
+
+ if (param->srcblacklevel_gb > HWD_VIIF_L1_BLACK_LEVEL_MAX_VAL)
+ return -EINVAL;
+
+ if (param->mulval_gr >= HWD_VIIF_L1_BLACK_LEVEL_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->mulval_r >= HWD_VIIF_L1_BLACK_LEVEL_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->mulval_b >= HWD_VIIF_L1_BLACK_LEVEL_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->mulval_gb >= HWD_VIIF_L1_BLACK_LEVEL_MAX_GAIN_VAL)
+ return -EINVAL;
+
+ if (param->dstmaxval > HWD_VIIF_L1_BLACK_LEVEL_MAX_DST_VAL)
+ return -EINVAL;
+
+ writel(param->srcblacklevel_gr, &(res->capture_reg->l1isp.L1_BLVC_SrcBlackLevelGr));
+ writel(param->srcblacklevel_r, &(res->capture_reg->l1isp.L1_BLVC_SrcBlackLevelR));
+ writel(param->srcblacklevel_b, &(res->capture_reg->l1isp.L1_BLVC_SrcBlackLevelB));
+ writel(param->srcblacklevel_gb, &(res->capture_reg->l1isp.L1_BLVC_SrcBlackLevelGb));
+
+ writel(param->mulval_gr, &(res->capture_reg->l1isp.L1_BLVC_MultValGr));
+ writel(param->mulval_r, &(res->capture_reg->l1isp.L1_BLVC_MultValR));
+ writel(param->mulval_b, &(res->capture_reg->l1isp.L1_BLVC_MultValB));
+ writel(param->mulval_gb, &(res->capture_reg->l1isp.L1_BLVC_MultValGb));
+
+ writel(param->dstmaxval, &(res->capture_reg->l1isp.L1_BLVC_DstMaxval));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_lsc() - Configure L1ISP lens shading correction parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to lens shading correction parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - each parameter of "param" is out of range
+ * @note when NULL is set to "param"
+ */
+int32_t hwd_VIIF_l1_set_lsc(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_lsc *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ int32_t ret = 0;
+ uint32_t idx;
+ const struct hwd_viif_l1_lsc_parabola_ag_param *ag_param;
+ uint32_t val;
+ uint32_t tmp;
+ uint32_t sysm_width, sysm_height;
+ uint32_t grid_h_size = 0U;
+ uint32_t grid_v_size = 0U;
+
+ if (param != NULL) {
+ sysm_width = readl(&res->capture_reg->l1isp.L1_SYSM_WIDTH);
+ sysm_height = readl(&res->capture_reg->l1isp.L1_SYSM_HEIGHT);
+
+ if (param->lssc_parabola_param != NULL) {
+ if (param->lssc_parabola_param->lssc_para_h_center >= sysm_width) {
+ return -EINVAL;
+ }
+
+ if (param->lssc_parabola_param->lssc_para_v_center >= sysm_height) {
+ return -EINVAL;
+ }
+
+ if (param->lssc_parabola_param->lssc_para_h_gain >= HWD_VIIF_LSC_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->lssc_parabola_param->lssc_para_v_gain >= HWD_VIIF_LSC_MAX_GAIN) {
+ return -EINVAL;
+ }
+
+ switch (param->lssc_parabola_param->lssc_para_mgsel2) {
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_EIGHTH:
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_FOURTH:
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_SECOND:
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_FIRST:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ switch (param->lssc_parabola_param->lssc_para_mgsel4) {
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_EIGHTH:
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_FOURTH:
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_SECOND:
+ case HWD_VIIF_L1_PARA_COEF_GAIN_ONE_FIRST:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ for (idx = 0U; idx < 8U; idx++) {
+ switch (idx) {
+ case 0U:
+ ag_param = param->lssc_parabola_param->r_2d;
+ break;
+ case 1U:
+ ag_param = param->lssc_parabola_param->r_4d;
+ break;
+ case 2U:
+ ag_param = param->lssc_parabola_param->gr_2d;
+ break;
+ case 3U:
+ ag_param = param->lssc_parabola_param->gr_4d;
+ break;
+ case 4U:
+ ag_param = param->lssc_parabola_param->gb_2d;
+ break;
+ case 5U:
+ ag_param = param->lssc_parabola_param->gb_4d;
+ break;
+ case 6U:
+ ag_param = param->lssc_parabola_param->b_2d;
+ break;
+ default:
+ ag_param = param->lssc_parabola_param->b_4d;
+ break;
+ }
+
+ if (ag_param == NULL)
+ return -EINVAL;
+
+ if ((ag_param->lssc_paracoef_h_l_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_h_l_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_h_l_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_h_l_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_h_l_min >
+ ag_param->lssc_paracoef_h_l_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_h_r_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_h_r_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_h_r_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_h_r_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_h_r_min >
+ ag_param->lssc_paracoef_h_r_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_v_u_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_v_u_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_v_u_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_v_u_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_v_u_min >
+ ag_param->lssc_paracoef_v_u_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_v_d_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_v_d_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_v_d_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_v_d_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_v_d_min >
+ ag_param->lssc_paracoef_v_d_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_hv_lu_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_lu_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_hv_lu_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_lu_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_hv_lu_min >
+ ag_param->lssc_paracoef_hv_lu_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_hv_ru_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_ru_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_hv_ru_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_ru_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_hv_ru_min >
+ ag_param->lssc_paracoef_hv_ru_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_hv_ld_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_ld_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_hv_ld_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_ld_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_hv_ld_min >
+ ag_param->lssc_paracoef_hv_ld_max) {
+ return -EINVAL;
+ }
+
+ if ((ag_param->lssc_paracoef_hv_rd_max < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_rd_max >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((ag_param->lssc_paracoef_hv_rd_min < HWD_VIIF_LSC_MIN_GAIN) ||
+ (ag_param->lssc_paracoef_hv_rd_min >= HWD_VIIF_LSC_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if (ag_param->lssc_paracoef_hv_rd_min >
+ ag_param->lssc_paracoef_hv_rd_max) {
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (param->lssc_grid_param != NULL) {
+ switch (param->lssc_grid_param->lssc_grid_h_size) {
+ case 32U:
+ grid_h_size = 5U;
+ break;
+ case 64U:
+ grid_h_size = 6U;
+ break;
+ case 128U:
+ grid_h_size = 7U;
+ break;
+ case 256U:
+ grid_h_size = 8U;
+ break;
+ case 512U:
+ grid_h_size = 9U;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ switch (param->lssc_grid_param->lssc_grid_v_size) {
+ case 32U:
+ grid_v_size = 5U;
+ break;
+ case 64U:
+ grid_v_size = 6U;
+ break;
+ case 128U:
+ grid_v_size = 7U;
+ break;
+ case 256U:
+ grid_v_size = 8U;
+ break;
+ case 512U:
+ grid_v_size = 9U;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ if ((param->lssc_grid_param->lssc_grid_h_center <
+ HWD_VIIF_LSC_GRID_MIN_COORDINATE) ||
+ (param->lssc_grid_param->lssc_grid_h_center >
+ param->lssc_grid_param->lssc_grid_h_size)) {
+ return -EINVAL;
+ }
+
+ if (sysm_width > (param->lssc_grid_param->lssc_grid_h_center +
+ (param->lssc_grid_param->lssc_grid_h_size * 31U))) {
+ return -EINVAL;
+ }
+
+ if ((param->lssc_grid_param->lssc_grid_v_center <
+ HWD_VIIF_LSC_GRID_MIN_COORDINATE) ||
+ (param->lssc_grid_param->lssc_grid_v_center >
+ param->lssc_grid_param->lssc_grid_v_size)) {
+ return -EINVAL;
+ }
+
+ if (sysm_height > (param->lssc_grid_param->lssc_grid_v_center +
+ (param->lssc_grid_param->lssc_grid_v_size * 23U))) {
+ return -EINVAL;
+ }
+
+ if ((param->lssc_grid_param->lssc_grid_mgsel !=
+ HWD_VIIF_L1_GRID_COEF_GAIN_X1) &&
+ (param->lssc_grid_param->lssc_grid_mgsel !=
+ HWD_VIIF_L1_GRID_COEF_GAIN_X2)) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->lssc_pwhb_r_gain_max >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_r_gain_min >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_r_gain_min > param->lssc_pwhb_r_gain_max)
+ return -EINVAL;
+
+ if (param->lssc_pwhb_gr_gain_max >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_gr_gain_min >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_gr_gain_min > param->lssc_pwhb_gr_gain_max) {
+ return -EINVAL;
+ }
+
+ if (param->lssc_pwhb_gb_gain_max >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_gb_gain_min >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_gb_gain_min > param->lssc_pwhb_gb_gain_max) {
+ return -EINVAL;
+ }
+
+ if (param->lssc_pwhb_b_gain_max >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_b_gain_min >= HWD_VIIF_LSC_PWB_MAX_COEF_VAL) {
+ return -EINVAL;
+ }
+ if (param->lssc_pwhb_b_gain_min > param->lssc_pwhb_b_gain_max)
+ return -EINVAL;
+ }
+
+ if (param != NULL) {
+ /* parabola shading */
+ if (param->lssc_parabola_param != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_LSSC_PARA_EN));
+
+ writel(param->lssc_parabola_param->lssc_para_h_center,
+ &(res->capture_reg->l1isp.L1_LSSC_PARA_H_CENTER));
+ writel(param->lssc_parabola_param->lssc_para_v_center,
+ &(res->capture_reg->l1isp.L1_LSSC_PARA_V_CENTER));
+
+ writel(param->lssc_parabola_param->lssc_para_h_gain,
+ &(res->capture_reg->l1isp.L1_LSSC_PARA_H_GAIN));
+ writel(param->lssc_parabola_param->lssc_para_v_gain,
+ &(res->capture_reg->l1isp.L1_LSSC_PARA_V_GAIN));
+
+ writel(param->lssc_parabola_param->lssc_para_mgsel2,
+ &(res->capture_reg->l1isp.L1_LSSC_PARA_MGSEL2));
+ writel(param->lssc_parabola_param->lssc_para_mgsel4,
+ &(res->capture_reg->l1isp.L1_LSSC_PARA_MGSEL4));
+
+ /* R 2D */
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_2d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_2d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_2D_HV_RD));
+
+ /* R 4D */
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->r_4d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->r_4d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_R_COEF_4D_HV_RD));
+
+ /* GR 2D */
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_2d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_2d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_2d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_2d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_2d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_2D_HV_RD));
+
+ /* GR 4D */
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_4d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_4d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_4d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gr_4d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gr_4d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GR_COEF_4D_HV_RD));
+
+ /* GB 2D */
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_2d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_2d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_2d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_2d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_2d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_2D_HV_RD));
+
+ /* GB 4D */
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_4d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_4d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_4d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->gb_4d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(
+ param->lssc_parabola_param->gb_4d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_GB_COEF_4D_HV_RD));
+
+ /* B 2D */
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_2d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_2d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_2D_HV_RD));
+
+ /* B 4D */
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_h_l_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_h_l_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_H_L));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_h_r_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_h_r_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_H_R));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_v_u_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_v_u_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_V_U));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_v_d_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_v_d_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_V_D));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_hv_lu_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_hv_lu_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_HV_LU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_hv_ru_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_hv_ru_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_HV_RU));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_hv_ld_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_hv_ld_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_HV_LD));
+
+ tmp = (uint32_t)param->lssc_parabola_param->b_4d->lssc_paracoef_hv_rd_max &
+ 0x1fffU;
+ val = (tmp << 16U) |
+ (uint32_t)(param->lssc_parabola_param->b_4d->lssc_paracoef_hv_rd_min &
+ 0x1fffU);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PARA_B_COEF_4D_HV_RD));
+
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_LSSC_PARA_EN));
+ }
+
+ /* grid shading */
+ if (param->lssc_grid_param != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_LSSC_GRID_EN));
+ writel(grid_h_size, &(res->capture_reg->l1isp.L1_LSSC_GRID_H_SIZE));
+ writel(grid_v_size, &(res->capture_reg->l1isp.L1_LSSC_GRID_V_SIZE));
+ writel(param->lssc_grid_param->lssc_grid_h_center,
+ &(res->capture_reg->l1isp.L1_LSSC_GRID_H_CENTER));
+ writel(param->lssc_grid_param->lssc_grid_v_center,
+ &(res->capture_reg->l1isp.L1_LSSC_GRID_V_CENTER));
+ writel(param->lssc_grid_param->lssc_grid_mgsel,
+ &(res->capture_reg->l1isp.L1_LSSC_GRID_MGSEL));
+
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_LSSC_GRID_EN));
+ }
+
+ /* preset white balance */
+ val = (param->lssc_pwhb_r_gain_max << 16U) | (param->lssc_pwhb_r_gain_min);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PWHB_R_GAIN));
+
+ val = (param->lssc_pwhb_gr_gain_max << 16U) | (param->lssc_pwhb_gr_gain_min);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PWHB_GR_GAIN));
+
+ val = (param->lssc_pwhb_gb_gain_max << 16U) | (param->lssc_pwhb_gb_gain_min);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PWHB_GB_GAIN));
+
+ val = (param->lssc_pwhb_b_gain_max << 16U) | (param->lssc_pwhb_b_gain_min);
+ writel(val, &(res->capture_reg->l1isp.L1_LSSC_PWHB_B_GAIN));
+
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_LSSC_EN));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_LSSC_EN));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_lsc_table_transmission() - Configure L1ISP transferring lens shading grid table.
+ *
+ * @table_gr: grid shading table for Gr(physical address)
+ * @table_r: grid shading table for R(physical address)
+ * @table_b: grid shading table for B(physical address)
+ * @table_gb: grid shading table for Gb(physical address)
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "table_h", "table_m" or "table_l" is not 8byte alignment
+ *
+ * Note that when 0 is set to table address, table transfer of the table is disabled.
+ */
+int32_t hwd_VIIF_l1_set_lsc_table_transmission(uint32_t module_id, uintptr_t table_gr,
+ uintptr_t table_r, uintptr_t table_b,
+ uintptr_t table_gb)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val = 0x0U;
+
+ if (((table_gr % HWD_VIIF_L1_VDM_ALIGN) != 0U) ||
+ ((table_r % HWD_VIIF_L1_VDM_ALIGN) != 0U) ||
+ ((table_b % HWD_VIIF_L1_VDM_ALIGN) != 0U) ||
+ ((table_gb % HWD_VIIF_L1_VDM_ALIGN) != 0U)) {
+ return -EINVAL;
+ }
+ /* VDM common settings */
+ writel(HWD_VIIF_L1_VDM_CFG_PARAM, &(res->capture_reg->vdm.t_group[0].VDM_T_CFG));
+ writel(HWD_VIIF_L1_VDM_SRAM_BASE, &(res->capture_reg->vdm.t_group[0].VDM_T_SRAM_BASE));
+ writel(HWD_VIIF_L1_VDM_SRAM_SIZE, &(res->capture_reg->vdm.t_group[0].VDM_T_SRAM_SIZE));
+
+ if (table_gr != 0U) {
+ writel((uint32_t)table_gr, &(res->capture_reg->vdm.t_port[4].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_LSC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[4].VDM_T_SIZE));
+ val |= 0x10U;
+ }
+
+ if (table_r != 0U) {
+ writel((uint32_t)table_r, &(res->capture_reg->vdm.t_port[5].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_LSC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[5].VDM_T_SIZE));
+ val |= 0x20U;
+ }
+
+ if (table_b != 0U) {
+ writel((uint32_t)table_b, &(res->capture_reg->vdm.t_port[6].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_LSC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[6].VDM_T_SIZE));
+ val |= 0x40U;
+ }
+
+ if (table_gb != 0U) {
+ writel((uint32_t)table_gb, &(res->capture_reg->vdm.t_port[7].VDM_T_STADR));
+ writel(HWD_VIIF_L1_VDM_LSC_TABLE_SIZE,
+ &(res->capture_reg->vdm.t_port[7].VDM_T_SIZE));
+ val |= 0x80U;
+ }
+
+ val |= (readl(&res->capture_reg->vdm.VDM_T_ENABLE) & 0xffffff0fU);
+ writel(val, &(res->capture_reg->vdm.VDM_T_ENABLE));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_main_process() - Configure L1ISP main process.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @demosaic_mode: demosaic mode @ref hwd_VIIF_l1_demosaic
+ * @damp_lsbsel: output pixel clip range for auto white balance [0..15]
+ * @color_matrix: pointer to color matrix correction parameters
+ * @dst_maxval: output pixel maximum value [0x0..0xffffff]
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * main process means digital amp, demosaic, and color matrix correction
+ * NULL means disabling color matrix correction
+ * - "demosaic_mode" is neither HWD_VIIF_L1_DEMOSAIC_ACPI nor HWD_VIIF_L1_DEMOSAIC_DMG
+ * - "damp_lsbsel" is out of range
+ * - each parameter of "color_matrix" is out of range
+ * - "dst_maxval" is out of range
+ */
+int32_t hwd_VIIF_l1_set_main_process(uint32_t module_id, uint32_t regbuf_id, uint32_t demosaic_mode,
+ uint32_t damp_lsbsel,
+ const struct hwd_viif_l1_color_matrix_correction *color_matrix,
+ uint32_t dst_maxval)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val;
+
+ if ((demosaic_mode != HWD_VIIF_L1_DEMOSAIC_ACPI) &&
+ (demosaic_mode != HWD_VIIF_L1_DEMOSAIC_DMG)) {
+ return -EINVAL;
+ }
+
+ if (damp_lsbsel > HWD_VIIF_DAMP_MAX_LSBSEL)
+ return -EINVAL;
+
+ if (color_matrix != NULL) {
+ if (color_matrix->coef_rmg_min > color_matrix->coef_rmg_max)
+ return -EINVAL;
+
+ if (color_matrix->coef_rmb_min > color_matrix->coef_rmb_max)
+ return -EINVAL;
+
+ if (color_matrix->coef_gmr_min > color_matrix->coef_gmr_max)
+ return -EINVAL;
+
+ if (color_matrix->coef_gmb_min > color_matrix->coef_gmb_max)
+ return -EINVAL;
+
+ if (color_matrix->coef_bmr_min > color_matrix->coef_bmr_max)
+ return -EINVAL;
+
+ if (color_matrix->coef_bmg_min > color_matrix->coef_bmg_max)
+ return -EINVAL;
+
+ if ((uint32_t)color_matrix->dst_minval > dst_maxval)
+ return -EINVAL;
+ }
+
+ if (dst_maxval > HWD_VIIF_MAIN_PROCESS_MAX_OUT_PIXEL_VAL)
+ return -EINVAL;
+
+ val = damp_lsbsel << 4U;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_CONF));
+
+ writel(demosaic_mode, &(res->capture_reg->l1isp.L1_MPRO_LCS_MODE));
+
+ if (color_matrix != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_MPRO_SW));
+
+ val = (uint32_t)color_matrix->coef_rmg_min & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_RMG_MIN));
+
+ val = (uint32_t)color_matrix->coef_rmg_max & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_RMG_MAX));
+
+ val = (uint32_t)color_matrix->coef_rmb_min & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_RMB_MIN));
+
+ val = (uint32_t)color_matrix->coef_rmb_max & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_RMB_MAX));
+
+ val = (uint32_t)color_matrix->coef_gmr_min & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_GMR_MIN));
+
+ val = (uint32_t)color_matrix->coef_gmr_max & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_GMR_MAX));
+
+ val = (uint32_t)color_matrix->coef_gmb_min & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_GMB_MIN));
+
+ val = (uint32_t)color_matrix->coef_gmb_max & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_GMB_MAX));
+
+ val = (uint32_t)color_matrix->coef_bmr_min & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_BMR_MIN));
+
+ val = (uint32_t)color_matrix->coef_bmr_max & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_BMR_MAX));
+
+ val = (uint32_t)color_matrix->coef_bmg_min & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_BMG_MIN));
+
+ val = (uint32_t)color_matrix->coef_bmg_max & 0xffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_MPRO_LM0_BMG_MAX));
+
+ writel((uint32_t)color_matrix->dst_minval,
+ &(res->capture_reg->l1isp.L1_MPRO_DST_MINVAL));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_MPRO_SW));
+ }
+
+ writel(dst_maxval, &(res->capture_reg->l1isp.L1_MPRO_DST_MAXVAL));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_awb() - Configure L1ISP auto white balance parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to auto white balance parameters; NULL means disabling auto white balance
+ * @awhb_wbmrg: R gain of white balance adjustment [0x40..0x3FF] accuracy: 1/256
+ * @awhb_wbmgg: G gain of white balance adjustment [0x40..0x3FF] accuracy: 1/256
+ * @awhb_wbmbg: B gain of white balance adjustment [0x40..0x3FF] accuracy: 1/256
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL
+ * - each parameter of "param" is out of range
+ * - awhb_wbm*g is out of range
+ */
+int32_t hwd_VIIF_l1_set_awb(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_awb *param, uint32_t awhb_wbmrg,
+ uint32_t awhb_wbmgg, uint32_t awhb_wbmbg)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ int32_t ret = 0;
+ uint32_t val, ygate_data;
+
+ if ((awhb_wbmrg < HWD_VIIF_AWB_MIN_GAIN) || (awhb_wbmrg >= HWD_VIIF_AWB_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((awhb_wbmgg < HWD_VIIF_AWB_MIN_GAIN) || (awhb_wbmgg >= HWD_VIIF_AWB_MAX_GAIN)) {
+ return -EINVAL;
+ }
+ if ((awhb_wbmbg < HWD_VIIF_AWB_MIN_GAIN) || (awhb_wbmbg >= HWD_VIIF_AWB_MAX_GAIN)) {
+ return -EINVAL;
+ }
+
+ if (param != NULL) {
+ if ((param->awhb_ygate_sel != HWD_VIIF_ENABLE) &&
+ (param->awhb_ygate_sel != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_ygate_data != 64U) && (param->awhb_ygate_data != 128U) &&
+ (param->awhb_ygate_data != 256U) && (param->awhb_ygate_data != 512U)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_cgrange != HWD_VIIF_L1_AWB_ONE_SECOND) &&
+ (param->awhb_cgrange != HWD_VIIF_L1_AWB_X1) &&
+ (param->awhb_cgrange != HWD_VIIF_L1_AWB_X2) &&
+ (param->awhb_cgrange != HWD_VIIF_L1_AWB_X4)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_ygatesw != HWD_VIIF_ENABLE) &&
+ (param->awhb_ygatesw != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_hexsw != HWD_VIIF_ENABLE) &&
+ (param->awhb_hexsw != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_areamode != HWD_VIIF_L1_AWB_AREA_MODE0) &&
+ (param->awhb_areamode != HWD_VIIF_L1_AWB_AREA_MODE1) &&
+ (param->awhb_areamode != HWD_VIIF_L1_AWB_AREA_MODE2) &&
+ (param->awhb_areamode != HWD_VIIF_L1_AWB_AREA_MODE3)) {
+ return -EINVAL;
+ }
+
+ val = readl(&res->capture_reg->l1isp.L1_SYSM_WIDTH);
+ if ((param->awhb_area_hsize < 1U) || (param->awhb_area_hsize > ((val - 8U) / 8U))) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_area_hofs > (val - 9U))
+ return -EINVAL;
+
+ val = readl(&res->capture_reg->l1isp.L1_SYSM_HEIGHT);
+ if ((param->awhb_area_vsize < 1U) || (param->awhb_area_vsize > ((val - 4U) / 8U))) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_area_vofs > (val - 5U))
+ return -EINVAL;
+
+ if ((param->awhb_sq_sw[0] != HWD_VIIF_ENABLE) &&
+ (param->awhb_sq_sw[0] != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_sq_sw[1] != HWD_VIIF_ENABLE) &&
+ (param->awhb_sq_sw[1] != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_sq_sw[2] != HWD_VIIF_ENABLE) &&
+ (param->awhb_sq_sw[2] != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_sq_pol[0] != HWD_VIIF_ENABLE) &&
+ (param->awhb_sq_pol[0] != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_sq_pol[1] != HWD_VIIF_ENABLE) &&
+ (param->awhb_sq_pol[1] != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_sq_pol[2] != HWD_VIIF_ENABLE) &&
+ (param->awhb_sq_pol[2] != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_bycut0p > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_bycut0n > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_rycut0p > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_rycut0n > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if ((param->awhb_rbcut0h < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_rbcut0h > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_rbcut0l < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_rbcut0l > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_bycut_h[0] < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_bycut_h[0] > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_bycut_h[1] < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_bycut_h[1] > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_bycut_h[2] < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_bycut_h[2] > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_bycut_l[0] > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_bycut_l[1] > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_bycut_l[2] > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if ((param->awhb_rycut_h[0] < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_rycut_h[0] > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_rycut_h[1] < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_rycut_h[1] > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_rycut_h[2] < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_rycut_h[2] > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_rycut_l[0] > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_rycut_l[1] > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if (param->awhb_rycut_l[2] > HWD_VIIF_AWB_UNSIGNED_GATE_UPPER)
+ return -EINVAL;
+
+ if ((param->awhb_awbsftu < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_awbsftu > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+ if ((param->awhb_awbsftv < HWD_VIIF_AWB_GATE_LOWER) ||
+ (param->awhb_awbsftv > HWD_VIIF_AWB_GATE_UPPER)) {
+ return -EINVAL;
+ }
+
+ if ((param->awhb_awbhuecor != HWD_VIIF_ENABLE) &&
+ (param->awhb_awbhuecor != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_awbspd > HWD_VIIF_AWB_MAX_UV_CONVERGENCE_SPEED) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_awbulv > HWD_VIIF_AWB_MAX_UV_CONVERGENCE_LEVEL) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_awbvlv > HWD_VIIF_AWB_MAX_UV_CONVERGENCE_LEVEL) {
+ return -EINVAL;
+ }
+
+ if (param->awhb_awbondot > HWD_VIIF_AWB_INTEGRATION_STOP_TH)
+ return -EINVAL;
+
+ switch (param->awhb_awbfztim) {
+ case HWD_VIIF_L1_AWB_RESTART_NO:
+ case HWD_VIIF_L1_AWB_RESTART_128FRAME:
+ case HWD_VIIF_L1_AWB_RESTART_64FRAME:
+ case HWD_VIIF_L1_AWB_RESTART_32FRAME:
+ case HWD_VIIF_L1_AWB_RESTART_16FRAME:
+ case HWD_VIIF_L1_AWB_RESTART_8FRAME:
+ case HWD_VIIF_L1_AWB_RESTART_4FRAME:
+ case HWD_VIIF_L1_AWB_RESTART_2FRAME:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0)
+ return ret;
+ }
+
+ writel(awhb_wbmrg, &(res->capture_reg->l1isp.L1_AWHB_WBMRG));
+ writel(awhb_wbmgg, &(res->capture_reg->l1isp.L1_AWHB_WBMGG));
+ writel(awhb_wbmbg, &(res->capture_reg->l1isp.L1_AWHB_WBMBG));
+
+ val = readl(&res->capture_reg->l1isp.L1_AWHB_SW) & 0xffffff7fU;
+
+ if (param != NULL) {
+ val |= (HWD_VIIF_ENABLE << 7U);
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_SW));
+
+ if (param->awhb_ygate_data == 64U)
+ ygate_data = 0U;
+ else if (param->awhb_ygate_data == 128U)
+ ygate_data = 1U;
+ else if (param->awhb_ygate_data == 256U)
+ ygate_data = 2U;
+ else
+ ygate_data = 3U;
+
+ val = (param->awhb_ygate_sel << 7U) | (ygate_data << 5U) | (param->awhb_cgrange);
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_GATE_CONF0));
+
+ val = (param->awhb_ygatesw << 5U) | (param->awhb_hexsw << 4U) |
+ (param->awhb_areamode);
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_GATE_CONF1));
+
+ writel(param->awhb_area_hsize, &(res->capture_reg->l1isp.L1_AWHB_AREA_HSIZE));
+ writel(param->awhb_area_vsize, &(res->capture_reg->l1isp.L1_AWHB_AREA_VSIZE));
+ writel(param->awhb_area_hofs, &(res->capture_reg->l1isp.L1_AWHB_AREA_HOFS));
+ writel(param->awhb_area_vofs, &(res->capture_reg->l1isp.L1_AWHB_AREA_VOFS));
+
+ writel(param->awhb_area_maskh, &(res->capture_reg->l1isp.L1_AWHB_AREA_MASKH));
+ writel(param->awhb_area_maskl, &(res->capture_reg->l1isp.L1_AWHB_AREA_MASKL));
+
+ val = (param->awhb_sq_sw[0] << 7U) | (param->awhb_sq_pol[0] << 6U) |
+ (param->awhb_sq_sw[1] << 5U) | (param->awhb_sq_pol[1] << 4U) |
+ (param->awhb_sq_sw[2] << 3U) | (param->awhb_sq_pol[2] << 2U);
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_SQ_CONF));
+
+ writel((uint32_t)param->awhb_ygateh, &(res->capture_reg->l1isp.L1_AWHB_YGATEH));
+ writel((uint32_t)param->awhb_ygatel, &(res->capture_reg->l1isp.L1_AWHB_YGATEL));
+
+ writel(param->awhb_bycut0p, &(res->capture_reg->l1isp.L1_AWHB_BYCUT0P));
+ writel(param->awhb_bycut0n, &(res->capture_reg->l1isp.L1_AWHB_BYCUT0N));
+ writel(param->awhb_rycut0p, &(res->capture_reg->l1isp.L1_AWHB_RYCUT0P));
+ writel(param->awhb_rycut0n, &(res->capture_reg->l1isp.L1_AWHB_RYCUT0N));
+
+ val = (uint32_t)param->awhb_rbcut0h & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_RBCUT0H));
+ val = (uint32_t)param->awhb_rbcut0l & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_RBCUT0L));
+
+ val = (uint32_t)param->awhb_bycut_h[0] & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_BYCUT1H));
+ writel(param->awhb_bycut_l[0], &(res->capture_reg->l1isp.L1_AWHB_BYCUT1L));
+ val = (uint32_t)param->awhb_bycut_h[1] & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_BYCUT2H));
+ writel(param->awhb_bycut_l[1], &(res->capture_reg->l1isp.L1_AWHB_BYCUT2L));
+ val = (uint32_t)param->awhb_bycut_h[2] & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_BYCUT3H));
+ writel(param->awhb_bycut_l[2], &(res->capture_reg->l1isp.L1_AWHB_BYCUT3L));
+
+ val = (uint32_t)param->awhb_rycut_h[0] & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_RYCUT1H));
+ writel(param->awhb_rycut_l[0], &(res->capture_reg->l1isp.L1_AWHB_RYCUT1L));
+ val = (uint32_t)param->awhb_rycut_h[1] & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_RYCUT2H));
+ writel(param->awhb_rycut_l[1], &(res->capture_reg->l1isp.L1_AWHB_RYCUT2L));
+ val = (uint32_t)param->awhb_rycut_h[2] & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_RYCUT3H));
+ writel(param->awhb_rycut_l[2], &(res->capture_reg->l1isp.L1_AWHB_RYCUT3L));
+
+ val = (uint32_t)param->awhb_awbsftu & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_AWBSFTU));
+ val = (uint32_t)param->awhb_awbsftv & 0xffU;
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_AWBSFTV));
+
+ val = (param->awhb_awbhuecor << 4U) | (param->awhb_awbspd);
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_AWBSPD));
+
+ writel(param->awhb_awbulv, &(res->capture_reg->l1isp.L1_AWHB_AWBULV));
+ writel(param->awhb_awbvlv, &(res->capture_reg->l1isp.L1_AWHB_AWBVLV));
+ writel((uint32_t)param->awhb_awbwait, &(res->capture_reg->l1isp.L1_AWHB_AWBWAIT));
+
+ writel(param->awhb_awbondot, &(res->capture_reg->l1isp.L1_AWHB_AWBONDOT));
+ writel(param->awhb_awbfztim, &(res->capture_reg->l1isp.L1_AWHB_AWBFZTIM));
+
+ writel((uint32_t)param->awhb_wbgrmax, &(res->capture_reg->l1isp.L1_AWHB_WBGRMAX));
+ writel((uint32_t)param->awhb_wbgbmax, &(res->capture_reg->l1isp.L1_AWHB_WBGBMAX));
+ writel((uint32_t)param->awhb_wbgrmin, &(res->capture_reg->l1isp.L1_AWHB_WBGRMIN));
+ writel((uint32_t)param->awhb_wbgbmin, &(res->capture_reg->l1isp.L1_AWHB_WBGBMIN));
+
+ } else {
+ /* disable awb */
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_SW));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_lock_awb_gain() - Configure L1ISP lock auto white balance gain.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @enable: enable/disable lock AWB gain
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "enable" is neither HWD_VIIF_ENABLE nor HWD_VIIF_DISABLE
+ */
+int32_t hwd_VIIF_l1_lock_awb_gain(uint32_t module_id, uint32_t regbuf_id, uint32_t enable)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val;
+
+ if ((enable != HWD_VIIF_ENABLE) && (enable != HWD_VIIF_DISABLE))
+ return -EINVAL;
+
+ val = readl(&res->capture_reg->l1isp.L1_AWHB_SW) & 0xffffffdfU;
+ val |= (enable << 5U);
+ writel(val, &(res->capture_reg->l1isp.L1_AWHB_SW));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_hdrc() - Configure L1ISP HDR compression parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to HDR compression parameters
+ * @hdrc_thr_sft_amt: shift value in case of through mode [0..8]
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - each parameter of "param" is out of range
+ * - hdrc_thr_sft_amt is out of range when param is NULL
+ * - hdrc_thr_sft_amt is not 0 when param is not NULL
+ */
+int32_t hwd_VIIF_l1_set_hdrc(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdrc *param, uint32_t hdrc_thr_sft_amt)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val, sw_delay1;
+
+ if (param != NULL) {
+ if (hdrc_thr_sft_amt != 0U)
+ return -EINVAL;
+
+ if ((param->hdrc_ratio < HWD_VIIF_L1_HDRC_MIN_INPUT_DATA_WIDTH) ||
+ (param->hdrc_ratio > HWD_VIIF_L1_HDRC_MAX_INPUT_DATA_WIDTH)) {
+ return -EINVAL;
+ }
+
+ if (param->hdrc_pt_ratio > HWD_VIIF_L1_HDRC_MAX_PT_SLOPE)
+ return -EINVAL;
+
+ if (param->hdrc_pt_blend > HWD_VIIF_L1_HDRC_MAX_BLEND_RATIO)
+ return -EINVAL;
+
+ if (param->hdrc_pt_blend2 > HWD_VIIF_L1_HDRC_MAX_BLEND_RATIO)
+ return -EINVAL;
+
+ if ((param->hdrc_pt_blend + param->hdrc_pt_blend2) >
+ HWD_VIIF_L1_HDRC_MAX_BLEND_RATIO) {
+ return -EINVAL;
+ }
+
+ if ((param->hdrc_tn_type != HWD_VIIF_L1_HDRC_TONE_USER) &&
+ (param->hdrc_tn_type != HWD_VIIF_L1_HDRC_TONE_PRESET)) {
+ return -EINVAL;
+ }
+
+ if (param->hdrc_flr_val > HWD_VIIF_L1_HDRC_MAX_FLARE_VAL)
+ return -EINVAL;
+
+ if ((param->hdrc_flr_adp != HWD_VIIF_ENABLE) &&
+ (param->hdrc_flr_adp != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if ((param->hdrc_ybr_off != HWD_VIIF_ENABLE) &&
+ (param->hdrc_ybr_off != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ if (param->hdrc_orgy_blend > HWD_VIIF_L1_HDRC_MAX_BLEND_LUMA)
+ return -EINVAL;
+
+ } else {
+ if (hdrc_thr_sft_amt > HWD_VIIF_L1_HDRC_MAX_THROUGH_SHIFT_VAL)
+ return -EINVAL;
+ }
+
+ if (param != NULL) {
+ writel((param->hdrc_ratio - HWD_VIIF_L1_HDRC_RATIO_OFFSET),
+ &(res->capture_reg->l1isp.L1_HDRC_RATIO));
+ writel(param->hdrc_pt_ratio, &(res->capture_reg->l1isp.L1_HDRC_PT_RATIO));
+
+ writel(param->hdrc_pt_blend, &(res->capture_reg->l1isp.L1_HDRC_PT_BLEND));
+ writel(param->hdrc_pt_blend2, &(res->capture_reg->l1isp.L1_HDRC_PT_BLEND2));
+
+ writel(param->hdrc_pt_sat, &(res->capture_reg->l1isp.L1_HDRC_PT_SAT));
+ writel(param->hdrc_tn_type, &(res->capture_reg->l1isp.L1_HDRC_TN_TYPE));
+
+ writel(param->hdrc_utn_tbl[0], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL0));
+ writel(param->hdrc_utn_tbl[1], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL1));
+ writel(param->hdrc_utn_tbl[2], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL2));
+ writel(param->hdrc_utn_tbl[3], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL3));
+ writel(param->hdrc_utn_tbl[4], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL4));
+ writel(param->hdrc_utn_tbl[5], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL5));
+ writel(param->hdrc_utn_tbl[6], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL6));
+ writel(param->hdrc_utn_tbl[7], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL7));
+ writel(param->hdrc_utn_tbl[8], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL8));
+ writel(param->hdrc_utn_tbl[9], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL9));
+ writel(param->hdrc_utn_tbl[10], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL10));
+ writel(param->hdrc_utn_tbl[11], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL11));
+ writel(param->hdrc_utn_tbl[12], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL12));
+ writel(param->hdrc_utn_tbl[13], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL13));
+ writel(param->hdrc_utn_tbl[14], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL14));
+ writel(param->hdrc_utn_tbl[15], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL15));
+ writel(param->hdrc_utn_tbl[16], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL16));
+ writel(param->hdrc_utn_tbl[17], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL17));
+ writel(param->hdrc_utn_tbl[18], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL18));
+ writel(param->hdrc_utn_tbl[19], &(res->capture_reg->l1isp.L1_HDRC_UTN_TBL19));
+
+ writel(param->hdrc_flr_val, &(res->capture_reg->l1isp.L1_HDRC_FLR_VAL));
+ writel(param->hdrc_flr_adp, &(res->capture_reg->l1isp.L1_HDRC_FLR_ADP));
+
+ writel(param->hdrc_ybr_off, &(res->capture_reg->l1isp.L1_HDRC_YBR_OFF));
+ writel(param->hdrc_orgy_blend, &(res->capture_reg->l1isp.L1_HDRC_ORGY_BLEND));
+
+ val = ((readl(&res->capture_reg->l1isp.L1_SYSM_HEIGHT)) % 64U) / 2U;
+ writel(val, &(res->capture_reg->l1isp.L1_HDRC_MAR_TOP));
+ val = ((readl(&res->capture_reg->l1isp.L1_SYSM_WIDTH)) % 64U) / 2U;
+ writel(val, &(res->capture_reg->l1isp.L1_HDRC_MAR_LEFT));
+
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_HDRC_EN));
+
+ /* update of sw_delay1 must be done when MAIN unit is NOT running. */
+ if (res->run_flag_main == false) {
+ sw_delay1 = (uint32_t)((HWD_VIIF_REGBUF_ACCESS_TIME *
+ (uint64_t)res->pixel_clock) /
+ ((uint64_t)res->htotal_size * HWD_VIIF_SYS_CLK)) +
+ HWD_VIIF_L1_DELAY_W_HDRC + 1U;
+ val = readl(&res->capture_reg->sys.INT_M1_LINE) & 0xffffU;
+ val |= (sw_delay1 << 16U);
+ writel(val, &(res->capture_reg->sys.INT_M1_LINE));
+ /* M2_LINE is the same condition as M1_LINE */
+ writel(val, &(res->capture_reg->sys.INT_M2_LINE));
+ }
+ } else {
+ writel(hdrc_thr_sft_amt, &(res->capture_reg->l1isp.L1_HDRC_THR_SFT_AMT));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_HDRC_EN));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_hdrc_ltm() - Configure L1ISP HDR compression local tone mapping parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to HDR compression local tone mapping parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL
+ * - "param" is NULL
+ * - each parameter of "param" is out of range
+ */
+int32_t hwd_VIIF_l1_set_hdrc_ltm(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_hdrc_ltm *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val;
+ uint32_t idx;
+
+ if (param == NULL)
+ return -EINVAL;
+
+ if (param->tnp_max >= HWD_VIIF_L1_HDRC_MAX_LTM_TONE_BLEND_RATIO)
+ return -EINVAL;
+
+ if (param->tnp_mag >= HWD_VIIF_L1_HDRC_MAX_LTM_MAGNIFICATION)
+ return -EINVAL;
+
+ val = (uint32_t)param->tnp_fil[0];
+ for (idx = 1; idx < 5U; idx++)
+ val += (uint32_t)param->tnp_fil[idx] * 2U;
+
+ if (val != 1024U)
+ return -EINVAL;
+
+ writel(param->tnp_max, &(res->capture_reg->l1isp.L1_HDRC_TNP_MAX));
+
+ writel(param->tnp_mag, &(res->capture_reg->l1isp.L1_HDRC_TNP_MAG));
+
+ writel((uint32_t)param->tnp_fil[0], &(res->capture_reg->l1isp.L1_HDRC_TNP_FIL0));
+ writel((uint32_t)param->tnp_fil[1], &(res->capture_reg->l1isp.L1_HDRC_TNP_FIL1));
+ writel((uint32_t)param->tnp_fil[2], &(res->capture_reg->l1isp.L1_HDRC_TNP_FIL2));
+ writel((uint32_t)param->tnp_fil[3], &(res->capture_reg->l1isp.L1_HDRC_TNP_FIL3));
+ writel((uint32_t)param->tnp_fil[4], &(res->capture_reg->l1isp.L1_HDRC_TNP_FIL4));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_gamma() - Configure L1ISP gamma correction parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to gamma correction parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - each parameter of "param" is out of range
+ */
+int32_t hwd_VIIF_l1_set_gamma(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_gamma *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t idx;
+
+ if (param != NULL) {
+ for (idx = 0; idx < 44U; idx++) {
+ if (param->gam_p[idx] > HWD_VIIF_L1_GAMMA_MAX_VAL)
+ return -EINVAL;
+ }
+ }
+
+ if (param != NULL) {
+ writel(param->gam_p[0], &(res->capture_reg->l1isp.L1_VPRO_GAM01P));
+ writel(param->gam_p[1], &(res->capture_reg->l1isp.L1_VPRO_GAM02P));
+ writel(param->gam_p[2], &(res->capture_reg->l1isp.L1_VPRO_GAM03P));
+ writel(param->gam_p[3], &(res->capture_reg->l1isp.L1_VPRO_GAM04P));
+ writel(param->gam_p[4], &(res->capture_reg->l1isp.L1_VPRO_GAM05P));
+ writel(param->gam_p[5], &(res->capture_reg->l1isp.L1_VPRO_GAM06P));
+ writel(param->gam_p[6], &(res->capture_reg->l1isp.L1_VPRO_GAM07P));
+ writel(param->gam_p[7], &(res->capture_reg->l1isp.L1_VPRO_GAM08P));
+ writel(param->gam_p[8], &(res->capture_reg->l1isp.L1_VPRO_GAM09P));
+ writel(param->gam_p[9], &(res->capture_reg->l1isp.L1_VPRO_GAM10P));
+ writel(param->gam_p[10], &(res->capture_reg->l1isp.L1_VPRO_GAM11P));
+ writel(param->gam_p[11], &(res->capture_reg->l1isp.L1_VPRO_GAM12P));
+ writel(param->gam_p[12], &(res->capture_reg->l1isp.L1_VPRO_GAM13P));
+ writel(param->gam_p[13], &(res->capture_reg->l1isp.L1_VPRO_GAM14P));
+ writel(param->gam_p[14], &(res->capture_reg->l1isp.L1_VPRO_GAM15P));
+ writel(param->gam_p[15], &(res->capture_reg->l1isp.L1_VPRO_GAM16P));
+ writel(param->gam_p[16], &(res->capture_reg->l1isp.L1_VPRO_GAM17P));
+ writel(param->gam_p[17], &(res->capture_reg->l1isp.L1_VPRO_GAM18P));
+ writel(param->gam_p[18], &(res->capture_reg->l1isp.L1_VPRO_GAM19P));
+ writel(param->gam_p[19], &(res->capture_reg->l1isp.L1_VPRO_GAM20P));
+ writel(param->gam_p[20], &(res->capture_reg->l1isp.L1_VPRO_GAM21P));
+ writel(param->gam_p[21], &(res->capture_reg->l1isp.L1_VPRO_GAM22P));
+ writel(param->gam_p[22], &(res->capture_reg->l1isp.L1_VPRO_GAM23P));
+ writel(param->gam_p[23], &(res->capture_reg->l1isp.L1_VPRO_GAM24P));
+ writel(param->gam_p[24], &(res->capture_reg->l1isp.L1_VPRO_GAM25P));
+ writel(param->gam_p[25], &(res->capture_reg->l1isp.L1_VPRO_GAM26P));
+ writel(param->gam_p[26], &(res->capture_reg->l1isp.L1_VPRO_GAM27P));
+ writel(param->gam_p[27], &(res->capture_reg->l1isp.L1_VPRO_GAM28P));
+ writel(param->gam_p[28], &(res->capture_reg->l1isp.L1_VPRO_GAM29P));
+ writel(param->gam_p[29], &(res->capture_reg->l1isp.L1_VPRO_GAM30P));
+ writel(param->gam_p[30], &(res->capture_reg->l1isp.L1_VPRO_GAM31P));
+ writel(param->gam_p[31], &(res->capture_reg->l1isp.L1_VPRO_GAM32P));
+ writel(param->gam_p[32], &(res->capture_reg->l1isp.L1_VPRO_GAM33P));
+ writel(param->gam_p[33], &(res->capture_reg->l1isp.L1_VPRO_GAM34P));
+ writel(param->gam_p[34], &(res->capture_reg->l1isp.L1_VPRO_GAM35P));
+ writel(param->gam_p[35], &(res->capture_reg->l1isp.L1_VPRO_GAM36P));
+ writel(param->gam_p[36], &(res->capture_reg->l1isp.L1_VPRO_GAM37P));
+ writel(param->gam_p[37], &(res->capture_reg->l1isp.L1_VPRO_GAM38P));
+ writel(param->gam_p[38], &(res->capture_reg->l1isp.L1_VPRO_GAM39P));
+ writel(param->gam_p[39], &(res->capture_reg->l1isp.L1_VPRO_GAM40P));
+ writel(param->gam_p[40], &(res->capture_reg->l1isp.L1_VPRO_GAM41P));
+ writel(param->gam_p[41], &(res->capture_reg->l1isp.L1_VPRO_GAM42P));
+ writel(param->gam_p[42], &(res->capture_reg->l1isp.L1_VPRO_GAM43P));
+ writel(param->gam_p[43], &(res->capture_reg->l1isp.L1_VPRO_GAM44P));
+ writel(param->blkadj, &(res->capture_reg->l1isp.L1_VPRO_BLKADJ));
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_PGC_SW));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_PGC_SW));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_img_quality_adjustment() - Configure L1ISP image quality adjustment.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to image quality adjustment parameters; NULL means disabling
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - each parameter of "param" is out of range
+ */
+int32_t
+hwd_VIIF_l1_set_img_quality_adjustment(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_img_quality_adjustment *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val;
+
+ if (param != NULL) {
+ if (param->lum_noise_reduction != NULL) {
+ if (param->lum_noise_reduction->gain_min >
+ param->lum_noise_reduction->gain_max) {
+ return -EINVAL;
+ }
+ if (param->lum_noise_reduction->lim_min >
+ param->lum_noise_reduction->lim_max) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->edge_enhancement != NULL) {
+ if (param->edge_enhancement->gain_min > param->edge_enhancement->gain_max) {
+ return -EINVAL;
+ }
+ if (param->edge_enhancement->lim_min > param->edge_enhancement->lim_max) {
+ return -EINVAL;
+ }
+ if (param->edge_enhancement->coring_min >
+ param->edge_enhancement->coring_max) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->uv_suppression != NULL) {
+ if (param->uv_suppression->bk_mp >= HWD_VIIF_L1_SUPPRESSION_MAX_VAL) {
+ return -EINVAL;
+ }
+ if (param->uv_suppression->black >= HWD_VIIF_L1_SUPPRESSION_MAX_VAL) {
+ return -EINVAL;
+ }
+ if (param->uv_suppression->wh_mp >= HWD_VIIF_L1_SUPPRESSION_MAX_VAL) {
+ return -EINVAL;
+ }
+ if (param->uv_suppression->white >= HWD_VIIF_L1_SUPPRESSION_MAX_VAL) {
+ return -EINVAL;
+ }
+ if (param->uv_suppression->bk_slv >= param->uv_suppression->wh_slv) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->coring_suppression != NULL) {
+ if (param->coring_suppression->gain_min >
+ param->coring_suppression->gain_max) {
+ return -EINVAL;
+ }
+ if (param->coring_suppression->lv_min > param->coring_suppression->lv_max) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->edge_suppression != NULL) {
+ if (param->edge_suppression->lim > HWD_VIIF_L1_EDGE_SUPPRESSION_MAX_LIMIT) {
+ return -EINVAL;
+ }
+ }
+
+ if (param->color_level != NULL) {
+ if (param->color_level->cb_gain >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->color_level->cr_gain >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->color_level->cbr_mgain_min >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->color_level->cbp_gain_max >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->color_level->cbm_gain_max >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->color_level->crp_gain_max >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ if (param->color_level->crm_gain_max >= HWD_VIIF_L1_COLOR_LEVEL_MAX_GAIN) {
+ return -EINVAL;
+ }
+ }
+
+ if ((param->color_noise_reduction_enable != HWD_VIIF_ENABLE) &&
+ (param->color_noise_reduction_enable != HWD_VIIF_DISABLE)) {
+ return -EINVAL;
+ }
+
+ /* RGB to YUV */
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_YUVC_SW));
+ writel((uint32_t)param->coef_cb, &(res->capture_reg->l1isp.L1_VPRO_Cb_MAT));
+ writel((uint32_t)param->coef_cr, &(res->capture_reg->l1isp.L1_VPRO_Cr_MAT));
+
+ /* brightness */
+ val = (uint32_t)param->brightness & 0xffffU;
+ if (val != 0U) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_BRIGHT_SW));
+ writel(val, &(res->capture_reg->l1isp.L1_VPRO_BRIGHT));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_BRIGHT_SW));
+ }
+
+ /* linear contrast */
+ if ((uint32_t)param->linear_contrast != 128U) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_LCNT_SW));
+ writel((uint32_t)param->linear_contrast,
+ &(res->capture_reg->l1isp.L1_VPRO_LCONT_LEV));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_LCNT_SW));
+ }
+
+ /* nonlinear contrast */
+ if (param->nonlinear_contrast != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_NLCNT_SW));
+ writel((uint32_t)param->nonlinear_contrast->blk_knee,
+ &(res->capture_reg->l1isp.L1_VPRO_BLK_KNEE));
+ writel((uint32_t)param->nonlinear_contrast->wht_knee,
+ &(res->capture_reg->l1isp.L1_VPRO_WHT_KNEE));
+
+ writel((uint32_t)param->nonlinear_contrast->blk_cont[0],
+ &(res->capture_reg->l1isp.L1_VPRO_BLK_CONT0));
+ writel((uint32_t)param->nonlinear_contrast->blk_cont[1],
+ &(res->capture_reg->l1isp.L1_VPRO_BLK_CONT1));
+ writel((uint32_t)param->nonlinear_contrast->blk_cont[2],
+ &(res->capture_reg->l1isp.L1_VPRO_BLK_CONT2));
+
+ writel((uint32_t)param->nonlinear_contrast->wht_cont[0],
+ &(res->capture_reg->l1isp.L1_VPRO_WHT_CONT0));
+ writel((uint32_t)param->nonlinear_contrast->wht_cont[1],
+ &(res->capture_reg->l1isp.L1_VPRO_WHT_CONT1));
+ writel((uint32_t)param->nonlinear_contrast->wht_cont[2],
+ &(res->capture_reg->l1isp.L1_VPRO_WHT_CONT2));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_NLCNT_SW));
+ }
+
+ /* luminance noise reduction */
+ if (param->lum_noise_reduction != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_YNR_SW));
+ writel((uint32_t)param->lum_noise_reduction->gain_min,
+ &(res->capture_reg->l1isp.L1_VPRO_YNR_GAIN_MIN));
+ writel((uint32_t)param->lum_noise_reduction->gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_YNR_GAIN_MAX));
+ writel((uint32_t)param->lum_noise_reduction->lim_min,
+ &(res->capture_reg->l1isp.L1_VPRO_YNR_LIM_MIN));
+ writel((uint32_t)param->lum_noise_reduction->lim_max,
+ &(res->capture_reg->l1isp.L1_VPRO_YNR_LIM_MAX));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_YNR_SW));
+ }
+
+ /* edge enhancement */
+ if (param->edge_enhancement != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_ETE_SW));
+ writel((uint32_t)param->edge_enhancement->gain_min,
+ &(res->capture_reg->l1isp.L1_VPRO_ETE_GAIN_MIN));
+ writel((uint32_t)param->edge_enhancement->gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_ETE_GAIN_MAX));
+ writel((uint32_t)param->edge_enhancement->lim_min,
+ &(res->capture_reg->l1isp.L1_VPRO_ETE_LIM_MIN));
+ writel((uint32_t)param->edge_enhancement->lim_max,
+ &(res->capture_reg->l1isp.L1_VPRO_ETE_LIM_MAX));
+ writel((uint32_t)param->edge_enhancement->coring_min,
+ &(res->capture_reg->l1isp.L1_VPRO_ETE_CORING_MIN));
+ writel((uint32_t)param->edge_enhancement->coring_max,
+ &(res->capture_reg->l1isp.L1_VPRO_ETE_CORING_MAX));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_ETE_SW));
+ }
+
+ /* UV suppression */
+ if (param->uv_suppression != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_CSUP_UVSUP_SW));
+ writel((uint32_t)param->uv_suppression->bk_slv,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_BK_SLV));
+ writel(param->uv_suppression->bk_mp,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_BK_MP));
+ writel(param->uv_suppression->black,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_BLACK));
+
+ writel((uint32_t)param->uv_suppression->wh_slv,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_WH_SLV));
+ writel(param->uv_suppression->wh_mp,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_WH_MP));
+ writel(param->uv_suppression->white,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_WHITE));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_CSUP_UVSUP_SW));
+ }
+
+ /* coring suppression */
+ if (param->coring_suppression != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_SW));
+ writel((uint32_t)param->coring_suppression->lv_min,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_LV_MIN));
+ writel((uint32_t)param->coring_suppression->lv_max,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_LV_MAX));
+ writel((uint32_t)param->coring_suppression->gain_min,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_GAIN_MIN));
+ writel((uint32_t)param->coring_suppression->gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_GAIN_MAX));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_SW));
+ }
+
+ /* edge suppression */
+ if (param->edge_suppression != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_VPRO_EDGE_SUP_SW));
+ writel((uint32_t)param->edge_suppression->gain,
+ &(res->capture_reg->l1isp.L1_VPRO_EDGE_SUP_GAIN));
+ writel((uint32_t)param->edge_suppression->lim,
+ &(res->capture_reg->l1isp.L1_VPRO_EDGE_SUP_LIM));
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_EDGE_SUP_SW));
+ }
+
+ /* color level */
+ if (param->color_level != NULL) {
+ writel(param->color_level->cb_gain,
+ &(res->capture_reg->l1isp.L1_VPRO_Cb_GAIN));
+ writel(param->color_level->cr_gain,
+ &(res->capture_reg->l1isp.L1_VPRO_Cr_GAIN));
+ writel(param->color_level->cbr_mgain_min,
+ &(res->capture_reg->l1isp.L1_VPRO_Cbr_MGAIN_MIN));
+ writel(param->color_level->cbp_gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_CbP_GAIN_MAX));
+ writel(param->color_level->cbm_gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_CbM_GAIN_MAX));
+ writel(param->color_level->crp_gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_CrP_GAIN_MAX));
+ writel(param->color_level->crm_gain_max,
+ &(res->capture_reg->l1isp.L1_VPRO_CrM_GAIN_MAX));
+ } else {
+ /* disable */
+ writel(1024U, &(res->capture_reg->l1isp.L1_VPRO_Cb_GAIN));
+ writel(1024U, &(res->capture_reg->l1isp.L1_VPRO_Cr_GAIN));
+ writel(1024U, &(res->capture_reg->l1isp.L1_VPRO_Cbr_MGAIN_MIN));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CbP_GAIN_MAX));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CbM_GAIN_MAX));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CrP_GAIN_MAX));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CrM_GAIN_MAX));
+ }
+
+ /* color noise reduction */
+ writel(param->color_noise_reduction_enable,
+ &(res->capture_reg->l1isp.L1_VPRO_CNR_SW));
+
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_YUVC_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_BRIGHT_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_LCNT_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_NLCNT_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_YNR_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_ETE_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_CSUP_UVSUP_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_CSUP_CORING_SW));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_EDGE_SUP_SW));
+ writel(1024U, &(res->capture_reg->l1isp.L1_VPRO_Cb_GAIN));
+ writel(1024U, &(res->capture_reg->l1isp.L1_VPRO_Cr_GAIN));
+ writel(1024U, &(res->capture_reg->l1isp.L1_VPRO_Cbr_MGAIN_MIN));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CbP_GAIN_MAX));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CbM_GAIN_MAX));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CrP_GAIN_MAX));
+ writel(0U, &(res->capture_reg->l1isp.L1_VPRO_CrM_GAIN_MAX));
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_VPRO_CNR_SW));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_avg_lum_generation() - Configure L1ISP average luminance generation parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to auto exposure parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - each parameter of "param" is out of range
+ */
+int32_t hwd_VIIF_l1_set_avg_lum_generation(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_avg_lum_generation *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val;
+ uint32_t idx, j;
+
+ if (param != NULL) {
+ val = readl(&res->capture_reg->l1isp.L1_SYSM_WIDTH);
+ if (param->aexp_start_x > (val - 1U))
+ return -EINVAL;
+
+ if ((param->aexp_block_width < HWD_VIIF_L1_AEXP_MIN_BLOCK_WIDTH) ||
+ (param->aexp_block_width > val)) {
+ return -EINVAL;
+ }
+ if ((param->aexp_block_width % 64U) != 0U)
+ return -EINVAL;
+
+ val = readl(&res->capture_reg->l1isp.L1_SYSM_HEIGHT);
+ if (param->aexp_start_y > (val - 1U))
+ return -EINVAL;
+
+ if ((param->aexp_block_height < HWD_VIIF_L1_AEXP_MIN_BLOCK_HEIGHT) ||
+ (param->aexp_block_height > val)) {
+ return -EINVAL;
+ }
+ if ((param->aexp_block_height % 64U) != 0U)
+ return -EINVAL;
+
+ for (idx = 0; idx < 8U; idx++) {
+ for (j = 0; j < 8U; j++) {
+ if (param->aexp_weight[idx][j] > HWD_VIIF_L1_AEXP_MAX_WEIGHT) {
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (param->aexp_satur_ratio > HWD_VIIF_L1_AEXP_MAX_BLOCK_TH)
+ return -EINVAL;
+
+ if (param->aexp_black_ratio > HWD_VIIF_L1_AEXP_MAX_BLOCK_TH)
+ return -EINVAL;
+
+ if (param->aexp_satur_level > HWD_VIIF_L1_AEXP_MAX_SATURATION_PIXEL_TH) {
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < 4U; idx++) {
+ if (param->aexp_ave4linesy[idx] > (val - 4U))
+ return -EINVAL;
+ }
+ }
+
+ if (param != NULL) {
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_AEXP_ON));
+ writel(param->aexp_start_x, &(res->capture_reg->l1isp.L1_AEXP_START_X));
+ writel(param->aexp_start_y, &(res->capture_reg->l1isp.L1_AEXP_START_Y));
+ writel(param->aexp_block_width, &(res->capture_reg->l1isp.L1_AEXP_BLOCK_WIDTH));
+ writel(param->aexp_block_height, &(res->capture_reg->l1isp.L1_AEXP_BLOCK_HEIGHT));
+
+ val = (param->aexp_weight[0][0] << 14U) | (param->aexp_weight[0][1] << 12U) |
+ (param->aexp_weight[0][2] << 10U) | (param->aexp_weight[0][3] << 8U) |
+ (param->aexp_weight[0][4] << 6U) | (param->aexp_weight[0][5] << 4U) |
+ (param->aexp_weight[0][6] << 2U) | (param->aexp_weight[0][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_0));
+
+ val = (param->aexp_weight[1][0] << 14U) | (param->aexp_weight[1][1] << 12U) |
+ (param->aexp_weight[1][2] << 10U) | (param->aexp_weight[1][3] << 8U) |
+ (param->aexp_weight[1][4] << 6U) | (param->aexp_weight[1][5] << 4U) |
+ (param->aexp_weight[1][6] << 2U) | (param->aexp_weight[1][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_1));
+
+ val = (param->aexp_weight[2][0] << 14U) | (param->aexp_weight[2][1] << 12U) |
+ (param->aexp_weight[2][2] << 10U) | (param->aexp_weight[2][3] << 8U) |
+ (param->aexp_weight[2][4] << 6U) | (param->aexp_weight[2][5] << 4U) |
+ (param->aexp_weight[2][6] << 2U) | (param->aexp_weight[2][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_2));
+
+ val = (param->aexp_weight[3][0] << 14U) | (param->aexp_weight[3][1] << 12U) |
+ (param->aexp_weight[3][2] << 10U) | (param->aexp_weight[3][3] << 8U) |
+ (param->aexp_weight[3][4] << 6U) | (param->aexp_weight[3][5] << 4U) |
+ (param->aexp_weight[3][6] << 2U) | (param->aexp_weight[3][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_3));
+
+ val = (param->aexp_weight[4][0] << 14U) | (param->aexp_weight[4][1] << 12U) |
+ (param->aexp_weight[4][2] << 10U) | (param->aexp_weight[4][3] << 8U) |
+ (param->aexp_weight[4][4] << 6U) | (param->aexp_weight[4][5] << 4U) |
+ (param->aexp_weight[4][6] << 2U) | (param->aexp_weight[4][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_4));
+
+ val = (param->aexp_weight[5][0] << 14U) | (param->aexp_weight[5][1] << 12U) |
+ (param->aexp_weight[5][2] << 10U) | (param->aexp_weight[5][3] << 8U) |
+ (param->aexp_weight[5][4] << 6U) | (param->aexp_weight[5][5] << 4U) |
+ (param->aexp_weight[5][6] << 2U) | (param->aexp_weight[5][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_5));
+
+ val = (param->aexp_weight[6][0] << 14U) | (param->aexp_weight[6][1] << 12U) |
+ (param->aexp_weight[6][2] << 10U) | (param->aexp_weight[6][3] << 8U) |
+ (param->aexp_weight[6][4] << 6U) | (param->aexp_weight[6][5] << 4U) |
+ (param->aexp_weight[6][6] << 2U) | (param->aexp_weight[6][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_6));
+
+ val = (param->aexp_weight[7][0] << 14U) | (param->aexp_weight[7][1] << 12U) |
+ (param->aexp_weight[7][2] << 10U) | (param->aexp_weight[7][3] << 8U) |
+ (param->aexp_weight[7][4] << 6U) | (param->aexp_weight[7][5] << 4U) |
+ (param->aexp_weight[7][6] << 2U) | (param->aexp_weight[7][7]);
+ writel(val, &(res->capture_reg->l1isp.L1_AEXP_WEIGHT_7));
+
+ writel(param->aexp_satur_ratio, &(res->capture_reg->l1isp.L1_AEXP_SATUR_RATIO));
+ writel(param->aexp_black_ratio, &(res->capture_reg->l1isp.L1_AEXP_BLACK_RATIO));
+ writel(param->aexp_satur_level, &(res->capture_reg->l1isp.L1_AEXP_SATUR_LEVEL));
+
+ writel(param->aexp_ave4linesy[0], &(res->capture_reg->l1isp.L1_AEXP_AVE4LINESY0));
+ writel(param->aexp_ave4linesy[1], &(res->capture_reg->l1isp.L1_AEXP_AVE4LINESY1));
+ writel(param->aexp_ave4linesy[2], &(res->capture_reg->l1isp.L1_AEXP_AVE4LINESY2));
+ writel(param->aexp_ave4linesy[3], &(res->capture_reg->l1isp.L1_AEXP_AVE4LINESY3));
+
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_AEXP_ON));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_histogram() - Configure L1ISP histogram parameters.
+ *
+ * @regbuf_id: ISP register buffer ID [0..3]
+ * @param: pointer to gamma correction parameters
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - each parameter of "param" is out of range
+ */
+int32_t hwd_VIIF_l1_set_histogram(uint32_t module_id, uint32_t regbuf_id,
+ const struct hwd_viif_l1_histogram *param)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val;
+
+ if (param != NULL) {
+ if ((param->hist_bin_mode != HWD_VIIF_L1_HIST_BIN_MODE_LINEAR) &&
+ (param->hist_bin_mode != HWD_VIIF_L1_HIST_BIN_MODE_LOG)) {
+ return -EINVAL;
+ }
+
+ val = readl(&res->capture_reg->l1isp.L1_SYSM_HEIGHT);
+ if (param->hist_block_v_ofst > (val - 1U))
+ return -EINVAL;
+
+ if ((param->hist_block_height == 0U) || (param->hist_block_height > val)) {
+ return -EINVAL;
+ }
+
+ val = readl(&res->capture_reg->l1isp.L1_SYSM_WIDTH);
+ if (param->hist_block_h_ofst > (val - 1U))
+ return -EINVAL;
+
+ if ((param->hist_block_width == 0U) || (param->hist_block_width > val)) {
+ return -EINVAL;
+ }
+
+ if ((param->hist_block_v_num == 0U) ||
+ (param->hist_block_v_num > HWD_VIIF_L1_HIST_MAX_BLOCK_NUM)) {
+ return -EINVAL;
+ }
+ if ((param->hist_block_h_num == 0U) ||
+ (param->hist_block_h_num > HWD_VIIF_L1_HIST_MAX_BLOCK_NUM)) {
+ return -EINVAL;
+ }
+
+ if (param->hist_block_v_step > HWD_VIIF_L1_HIST_MAX_STEP)
+ return -EINVAL;
+
+ if (param->hist_block_h_step > HWD_VIIF_L1_HIST_MAX_STEP)
+ return -EINVAL;
+
+ if (param->hist_linear_sft > HWD_VIIF_L1_HIST_MAX_BIN_SHIFT)
+ return -EINVAL;
+
+ if ((param->hist_add_a_r < HWD_VIIF_L1_HIST_MIN_ADD_A_COEF) ||
+ (param->hist_add_a_r >= HWD_VIIF_L1_HIST_MAX_ADD_A_COEF)) {
+ return -EINVAL;
+ }
+ if ((param->hist_add_b_r < HWD_VIIF_L1_HIST_MIN_ADD_B_COEF) ||
+ (param->hist_add_b_r >= HWD_VIIF_L1_HIST_MAX_COEF)) {
+ return -EINVAL;
+ }
+
+ if ((param->hist_add_a_g < HWD_VIIF_L1_HIST_MIN_ADD_A_COEF) ||
+ (param->hist_add_a_g >= HWD_VIIF_L1_HIST_MAX_ADD_A_COEF)) {
+ return -EINVAL;
+ }
+ if ((param->hist_add_b_g < HWD_VIIF_L1_HIST_MIN_ADD_B_COEF) ||
+ (param->hist_add_b_g >= HWD_VIIF_L1_HIST_MAX_COEF)) {
+ return -EINVAL;
+ }
+
+ if ((param->hist_add_a_b < HWD_VIIF_L1_HIST_MIN_ADD_A_COEF) ||
+ (param->hist_add_a_b >= HWD_VIIF_L1_HIST_MAX_ADD_A_COEF)) {
+ return -EINVAL;
+ }
+ if ((param->hist_add_b_b < HWD_VIIF_L1_HIST_MIN_ADD_B_COEF) ||
+ (param->hist_add_b_b >= HWD_VIIF_L1_HIST_MAX_COEF)) {
+ return -EINVAL;
+ }
+
+ if ((param->hist_add_a_y < HWD_VIIF_L1_HIST_MIN_ADD_A_COEF) ||
+ (param->hist_add_a_y >= HWD_VIIF_L1_HIST_MAX_ADD_A_COEF)) {
+ return -EINVAL;
+ }
+ if ((param->hist_add_b_y < HWD_VIIF_L1_HIST_MIN_ADD_B_COEF) ||
+ (param->hist_add_b_y >= HWD_VIIF_L1_HIST_MAX_COEF)) {
+ return -EINVAL;
+ }
+ }
+
+ if (param != NULL) {
+ val = ((uint32_t)HWD_VIIF_L1_HIST_COLOR_RGBY << 8U) | (param->hist_bin_mode);
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_MODE));
+
+ val = (param->hist_block_v_ofst << 16U) | (param->hist_block_h_ofst);
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_BLOCK_OFST));
+
+ val = (param->hist_block_height << 16U) | (param->hist_block_width);
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_BLOCK_SIZE));
+
+ val = (param->hist_block_v_num << 16U) | (param->hist_block_h_num);
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_BLOCK_NUM));
+
+ val = (param->hist_block_v_step << 16U) | (param->hist_block_h_step);
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_BLOCK_STEP));
+
+ writel(param->hist_linear_sft, &(res->capture_reg->l1isp.L1_HIST_LINEAR_SFT));
+
+ /* R */
+ writel((uint32_t)param->hist_mult_a_r, &(res->capture_reg->l1isp.L1_HIST_MULT_A_R));
+ val = (uint32_t)param->hist_add_a_r & 0x1ffffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_A_R));
+ writel((uint32_t)param->hist_mult_b_r, &(res->capture_reg->l1isp.L1_HIST_MULT_B_R));
+ val = (uint32_t)param->hist_add_b_r & 0x1ffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_B_R));
+
+ /* G */
+ writel((uint32_t)param->hist_mult_a_g, &(res->capture_reg->l1isp.L1_HIST_MULT_A_G));
+ val = (uint32_t)param->hist_add_a_g & 0x1ffffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_A_G));
+ writel((uint32_t)param->hist_mult_b_g, &(res->capture_reg->l1isp.L1_HIST_MULT_B_G));
+ val = (uint32_t)param->hist_add_b_g & 0x1ffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_B_G));
+
+ /* B */
+ writel((uint32_t)param->hist_mult_a_b, &(res->capture_reg->l1isp.L1_HIST_MULT_A_B));
+ val = (uint32_t)param->hist_add_a_b & 0x1ffffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_A_B));
+ writel((uint32_t)param->hist_mult_b_b, &(res->capture_reg->l1isp.L1_HIST_MULT_B_B));
+ val = (uint32_t)param->hist_add_b_b & 0x1ffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_B_B));
+
+ /* Y */
+ writel((uint32_t)param->hist_mult_a_y, &(res->capture_reg->l1isp.L1_HIST_MULT_A_Y));
+ val = (uint32_t)param->hist_add_a_y & 0x1ffffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_A_Y));
+ writel((uint32_t)param->hist_mult_b_y, &(res->capture_reg->l1isp.L1_HIST_MULT_B_Y));
+ val = (uint32_t)param->hist_add_b_y & 0x1ffffU;
+ writel(val, &(res->capture_reg->l1isp.L1_HIST_ADD_B_Y));
+
+ writel(HWD_VIIF_ENABLE, &(res->capture_reg->l1isp.L1_HIST_EN));
+
+ } else {
+ writel(HWD_VIIF_DISABLE, &(res->capture_reg->l1isp.L1_HIST_EN));
+ }
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_histogram_transmission() - Configure L1ISP transferring histogram data.
+ *
+ * @buf: buffer address to store histogram data
+ * @block_v_num: the number of vertical block[1..8]
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: 0 operation completed successfully
+ * Return: -EINVAL Parameter error
+ * - "buf" is not 8byte alignment
+ * - "block_v_num" is out of range
+ */
+int32_t hwd_VIIF_l1_set_histogram_transmission(uint32_t module_id, uintptr_t buf,
+ uint32_t block_v_num)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ uint32_t val = 0x0U;
+ uint32_t end_addr;
+
+ if ((block_v_num == 0U) || (block_v_num > HWD_VIIF_L1_HIST_MAX_BLOCK_NUM)) {
+ return -EINVAL;
+ }
+
+ if (buf != 0U) {
+ if ((buf % HWD_VIIF_L1_VDM_ALIGN) != 0U)
+ return -EINVAL;
+
+ /* VDM common settings */
+ writel(HWD_VIIF_L1_VDM_CFG_PARAM, &(res->capture_reg->vdm.w_port[2].VDM_W_CFG0));
+ writel(HWD_VIIF_L1_HIST_VDM_SRAM_BASE,
+ &(res->capture_reg->vdm.w_port[2].VDM_W_SRAM_BASE));
+ writel(HWD_VIIF_L1_HIST_VDM_SRAM_SIZE,
+ &(res->capture_reg->vdm.w_port[2].VDM_W_SRAM_SIZE));
+
+ writel((uint32_t)buf, &(res->capture_reg->vdm.w_port[2].VDM_W_STADR));
+ end_addr = (uint32_t)buf + HWD_VIIF_L1_HIST_VDM_SIZE - 1U;
+ writel(end_addr, &(res->capture_reg->vdm.w_port[2].VDM_W_ENDADR));
+
+ writel((block_v_num * 4U), &(res->capture_reg->vdm.w_port[2].VDM_W_HEIGHT));
+ writel(HWD_VIIF_L1_HIST_VDM_SIZE, &(res->capture_reg->vdm.w_port[2].VDM_W_PITCH));
+
+ val = 0x4U;
+ }
+
+ val |= (readl(&res->capture_reg->vdm.VDM_W_ENABLE) & 0xfffffffbU);
+ writel(val, &(res->capture_reg->vdm.VDM_W_ENABLE));
+
+ return 0;
+}
+
+/**
+ * hwd_VIIF_l1_set_irq_mask() - Set L1ISP interruption mask.
+ *
+ * @mask: pointer to mask setting
+ * @module_id: ID of each VIIF module; must be 0 or 1
+ * Return: None
+ */
+void hwd_VIIF_l1_set_irq_mask(uint32_t module_id, const uint32_t *mask)
+{
+ struct hwd_viif_res *res = viif_id2res(module_id);
+ writel(*mask, &(res->capture_reg->l1isp.L1_CRGBF_ISP_INT_MASK));
+}
diff --git a/drivers/media/platform/visconti/viif.c b/drivers/media/platform/visconti/viif.c
index 1869f0267..2012d406a 100644
--- a/drivers/media/platform/visconti/viif.c
+++ b/drivers/media/platform/visconti/viif.c
@@ -505,6 +505,503 @@ static int viif_main_set_rawpack_mode(struct viif_device *viif_dev, uint32_t *ra
return 0;
}

+static int viif_l1_set_input_mode(struct viif_device *viif_dev,
+ struct viif_l1_input_mode_config *input_mode)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ /* SDR input is not supported */
+ ret = hwd_VIIF_l1_set_input_mode(viif_dev->ch, input_mode->mode, input_mode->depth,
+ input_mode->raw_color_filter, NULL);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_rgb_to_y_coef(struct viif_device *viif_dev,
+ struct viif_l1_rgb_to_y_coef_config *l1_rgb_to_y_coef)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_rgb_to_y_coef(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ l1_rgb_to_y_coef->coef_r, l1_rgb_to_y_coef->coef_g,
+ l1_rgb_to_y_coef->coef_b);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_ag_mode(struct viif_device *viif_dev,
+ struct viif_l1_ag_mode_config *l1_ag_mode)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_ag_mode(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_ag_mode *)l1_ag_mode);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_ag(struct viif_device *viif_dev, struct viif_l1_ag_config *l1_ag)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_ag(viif_dev->ch, VIIF_ISP_REGBUF_0, l1_ag->gain_h, l1_ag->gain_m,
+ l1_ag->gain_l);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_hdre(struct viif_device *viif_dev, struct viif_l1_hdre_config *l1_hdre)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_hdre(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_hdre *)l1_hdre);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_img_extraction(struct viif_device *viif_dev,
+ struct viif_l1_img_extraction_config *img_extract)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_img_extraction(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ img_extract->input_black_gr,
+ img_extract->input_black_r, img_extract->input_black_b,
+ img_extract->input_black_gb);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+#define VISCONTI_VIIF_DPC_TABLE_SIZE 8192
+static int viif_l1_set_dpc(struct viif_device *viif_dev, struct viif_l1_dpc_config *l1_dpc)
+{
+ int ret;
+ unsigned long irqflags;
+ uintptr_t table_h_paddr = 0;
+ uintptr_t table_m_paddr = 0;
+ uintptr_t table_l_paddr = 0;
+
+ if (l1_dpc->table_h) {
+ if (copy_from_user(viif_dev->table_vaddr->dpc_table_h,
+ (void __user *)l1_dpc->table_h, VISCONTI_VIIF_DPC_TABLE_SIZE))
+ return -EFAULT;
+ table_h_paddr = (uintptr_t)viif_dev->table_paddr->dpc_table_h;
+ }
+ if (l1_dpc->table_m) {
+ if (copy_from_user(viif_dev->table_vaddr->dpc_table_m,
+ (void __user *)l1_dpc->table_m, VISCONTI_VIIF_DPC_TABLE_SIZE))
+ return -EFAULT;
+ table_m_paddr = (uintptr_t)viif_dev->table_paddr->dpc_table_m;
+ }
+ if (l1_dpc->table_l) {
+ if (copy_from_user(viif_dev->table_vaddr->dpc_table_l,
+ (void __user *)l1_dpc->table_l, VISCONTI_VIIF_DPC_TABLE_SIZE))
+ return -EFAULT;
+ table_l_paddr = (uintptr_t)viif_dev->table_paddr->dpc_table_l;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_dpc_table_transmission(viif_dev->ch, table_h_paddr, table_m_paddr,
+ table_l_paddr);
+ if (ret)
+ goto err;
+
+ ret = hwd_VIIF_l1_set_dpc(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_dpc *)&l1_dpc->param_h,
+ (struct hwd_viif_l1_dpc *)&l1_dpc->param_m,
+ (struct hwd_viif_l1_dpc *)&l1_dpc->param_l);
+err:
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+ return ret;
+}
+
+static int
+viif_l1_set_preset_white_balance(struct viif_device *viif_dev,
+ struct viif_l1_preset_white_balance_config *l1_preset_wb)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_preset_white_balance(
+ viif_dev->ch, VIIF_ISP_REGBUF_0, l1_preset_wb->dstmaxval,
+ (struct hwd_viif_l1_preset_white_balance *)&l1_preset_wb->param_h,
+ (struct hwd_viif_l1_preset_white_balance *)&l1_preset_wb->param_m,
+ (struct hwd_viif_l1_preset_white_balance *)&l1_preset_wb->param_l);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int
+viif_l1_set_raw_color_noise_reduction(struct viif_device *viif_dev,
+ struct viif_l1_raw_color_noise_reduction_config *raw_color)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_raw_color_noise_reduction(
+ viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_raw_color_noise_reduction *)&raw_color->param_h,
+ (struct hwd_viif_l1_raw_color_noise_reduction *)&raw_color->param_m,
+ (struct hwd_viif_l1_raw_color_noise_reduction *)&raw_color->param_l);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_hdrs(struct viif_device *viif_dev, struct viif_l1_hdrs_config *hdrs)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_hdrs(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_hdrs *)hdrs);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_black_level_correction(struct viif_device *viif_dev,
+ struct viif_l1_black_level_correction_config *blc)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_black_level_correction(
+ viif_dev->ch, VIIF_ISP_REGBUF_0, (struct hwd_viif_l1_black_level_correction *)blc);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_lsc(struct viif_device *viif_dev, struct viif_l1_lsc_config *l1_lsc)
+{
+ int ret;
+ unsigned long irqflags;
+ struct viif_l1_lsc_parabola_param lsc_para;
+ struct hwd_viif_l1_lsc hwd_lsc;
+ struct hwd_viif_l1_lsc_parabola_param hwd_lsc_para;
+ struct hwd_viif_l1_lsc_grid_param hwd_lsc_grid;
+ uintptr_t table_gr_paddr = 0;
+ uintptr_t table_r_paddr = 0;
+ uintptr_t table_b_paddr = 0;
+ uintptr_t table_gb_paddr = 0;
+
+ if (!l1_lsc->param) {
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_lsc(viif_dev->ch, VIIF_ISP_REGBUF_0, NULL);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+ return ret;
+ }
+
+ if (l1_lsc->table_gr) {
+ if (copy_from_user(viif_dev->table_vaddr->lsc_table_gr,
+ (void __user *)l1_lsc->table_gr, 1536))
+ return -EFAULT;
+ table_gr_paddr = (uintptr_t)viif_dev->table_paddr->lsc_table_gr;
+ }
+ if (l1_lsc->table_r) {
+ if (copy_from_user(viif_dev->table_vaddr->lsc_table_r,
+ (void __user *)l1_lsc->table_r, 1536))
+ return -EFAULT;
+ table_r_paddr = (uintptr_t)viif_dev->table_paddr->lsc_table_r;
+ }
+ if (l1_lsc->table_b) {
+ if (copy_from_user(viif_dev->table_vaddr->lsc_table_b,
+ (void __user *)l1_lsc->table_b, 1536))
+ return -EFAULT;
+ table_b_paddr = (uintptr_t)viif_dev->table_paddr->lsc_table_b;
+ }
+ if (l1_lsc->table_gb) {
+ if (copy_from_user(viif_dev->table_vaddr->lsc_table_gb,
+ (void __user *)l1_lsc->table_gb, 1536))
+ return -EFAULT;
+ table_gb_paddr = (uintptr_t)viif_dev->table_paddr->lsc_table_gb;
+ }
+
+ if (copy_from_user(&hwd_lsc, (void __user *)l1_lsc->param, sizeof(struct hwd_viif_l1_lsc)))
+ return -EFAULT;
+
+ if (hwd_lsc.lssc_parabola_param) {
+ if (copy_from_user(&lsc_para, (void __user *)hwd_lsc.lssc_parabola_param,
+ sizeof(struct viif_l1_lsc_parabola_param)))
+ return -EFAULT;
+
+ hwd_lsc_para.lssc_para_h_center = lsc_para.lssc_para_h_center;
+ hwd_lsc_para.lssc_para_v_center = lsc_para.lssc_para_v_center;
+ hwd_lsc_para.lssc_para_h_gain = lsc_para.lssc_para_h_gain;
+ hwd_lsc_para.lssc_para_v_gain = lsc_para.lssc_para_v_gain;
+ hwd_lsc_para.lssc_para_mgsel2 = lsc_para.lssc_para_mgsel2;
+ hwd_lsc_para.lssc_para_mgsel4 = lsc_para.lssc_para_mgsel4;
+ hwd_lsc_para.r_2d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.r_2d;
+ hwd_lsc_para.r_4d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.r_4d;
+ hwd_lsc_para.gr_2d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.gr_2d;
+ hwd_lsc_para.gr_4d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.gr_4d;
+ hwd_lsc_para.gb_2d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.gb_2d;
+ hwd_lsc_para.gb_4d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.gb_4d;
+ hwd_lsc_para.b_2d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.b_2d;
+ hwd_lsc_para.b_4d = (struct hwd_viif_l1_lsc_parabola_ag_param *)&lsc_para.b_4d;
+
+ hwd_lsc.lssc_parabola_param = &hwd_lsc_para;
+ }
+
+ if (hwd_lsc.lssc_grid_param) {
+ if (copy_from_user(&hwd_lsc_grid, (void __user *)hwd_lsc.lssc_grid_param,
+ sizeof(struct hwd_viif_l1_lsc_grid_param)))
+ return -EFAULT;
+
+ hwd_lsc.lssc_grid_param = &hwd_lsc_grid;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_lsc_table_transmission(viif_dev->ch, table_gr_paddr, table_r_paddr,
+ table_b_paddr, table_gb_paddr);
+ if (ret)
+ goto err;
+
+ ret = hwd_VIIF_l1_set_lsc(viif_dev->ch, VIIF_ISP_REGBUF_0, &hwd_lsc);
+err:
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+ return ret;
+}
+
+static int viif_l1_set_main_process(struct viif_device *viif_dev,
+ struct viif_l1_main_process_config *mpro)
+{
+ struct hwd_viif_l1_color_matrix_correction color_matrix;
+ int ret;
+ unsigned long irqflags;
+
+ if (mpro->param) {
+ if (copy_from_user(&color_matrix, (void __user *)mpro->param,
+ sizeof(struct hwd_viif_l1_color_matrix_correction)))
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_main_process(viif_dev->ch, VIIF_ISP_REGBUF_0, mpro->demosaic_mode,
+ mpro->damp_lsbsel, mpro->param ? &color_matrix : NULL,
+ mpro->dst_maxval);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_awb(struct viif_device *viif_dev, struct viif_l1_awb_config *l1_awb)
+{
+ struct hwd_viif_l1_awb param;
+ int ret;
+ unsigned long irqflags;
+
+ if (l1_awb->param) {
+ if (copy_from_user(&param, (void __user *)l1_awb->param,
+ sizeof(struct hwd_viif_l1_awb)))
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_awb(viif_dev->ch, VIIF_ISP_REGBUF_0, l1_awb->param ? &param : NULL,
+ l1_awb->awhb_wbmrg, l1_awb->awhb_wbmgg, l1_awb->awhb_wbmbg);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_lock_awb_gain(struct viif_device *viif_dev, uint32_t *enable)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_lock_awb_gain(viif_dev->ch, VIIF_ISP_REGBUF_0, *enable);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_hdrc(struct viif_device *viif_dev, struct viif_l1_hdrc_config *hdrc)
+{
+ struct hwd_viif_l1_hdrc param;
+ int ret;
+ unsigned long irqflags;
+
+ if (hdrc->param) {
+ if (copy_from_user(&param, (void __user *)hdrc->param,
+ sizeof(struct hwd_viif_l1_hdrc)))
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_hdrc(viif_dev->ch, VIIF_ISP_REGBUF_0, hdrc->param ? &param : NULL,
+ hdrc->hdrc_thr_sft_amt);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_hdrc_ltm(struct viif_device *viif_dev,
+ struct viif_l1_hdrc_ltm_config *l1_hdrc_ltm)
+{
+ int ret;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_hdrc_ltm(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_hdrc_ltm *)l1_hdrc_ltm);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int viif_l1_set_gamma(struct viif_device *viif_dev, struct viif_l1_gamma_config *l1_gamma)
+{
+ struct hwd_viif_l1_gamma param;
+ int ret;
+ unsigned long irqflags;
+
+ if (l1_gamma->param) {
+ if (copy_from_user(&param, (void __user *)l1_gamma->param,
+ sizeof(struct hwd_viif_l1_gamma)))
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_gamma(viif_dev->ch, VIIF_ISP_REGBUF_0,
+ l1_gamma->param ? &param : NULL);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
+static int
+viif_l1_set_img_quality_adjustment(struct viif_device *viif_dev,
+ struct viif_l1_img_quality_adjustment_config *img_quality)
+{
+ struct viif_l1_nonlinear_contrast nonlinear;
+ struct viif_l1_lum_noise_reduction lum_noise;
+ struct viif_l1_edge_enhancement edge_enh;
+ struct viif_l1_uv_suppression uv;
+ struct viif_l1_coring_suppression coring;
+ struct viif_l1_edge_suppression edge_sup;
+ struct viif_l1_color_level color;
+ int ret;
+ unsigned long irqflags;
+
+ if (img_quality->nonlinear_contrast) {
+ if (copy_from_user(&nonlinear, (void __user *)img_quality->nonlinear_contrast,
+ sizeof(struct viif_l1_nonlinear_contrast)))
+ return -EFAULT;
+ img_quality->nonlinear_contrast = &nonlinear;
+ }
+ if (img_quality->lum_noise_reduction) {
+ if (copy_from_user(&lum_noise, (void __user *)img_quality->lum_noise_reduction,
+ sizeof(struct viif_l1_lum_noise_reduction)))
+ return -EFAULT;
+ img_quality->lum_noise_reduction = &lum_noise;
+ }
+ if (img_quality->edge_enhancement) {
+ if (copy_from_user(&edge_enh, (void __user *)img_quality->edge_enhancement,
+ sizeof(struct viif_l1_edge_enhancement)))
+ return -EFAULT;
+ img_quality->edge_enhancement = &edge_enh;
+ }
+ if (img_quality->uv_suppression) {
+ if (copy_from_user(&uv, (void __user *)img_quality->uv_suppression,
+ sizeof(struct viif_l1_uv_suppression)))
+ return -EFAULT;
+ img_quality->uv_suppression = &uv;
+ }
+ if (img_quality->coring_suppression) {
+ if (copy_from_user(&coring, (void __user *)img_quality->coring_suppression,
+ sizeof(struct viif_l1_coring_suppression)))
+ return -EFAULT;
+ img_quality->coring_suppression = &coring;
+ }
+ if (img_quality->edge_suppression) {
+ if (copy_from_user(&edge_sup, (void __user *)img_quality->edge_suppression,
+ sizeof(struct viif_l1_edge_suppression)))
+ return -EFAULT;
+ img_quality->edge_suppression = &edge_sup;
+ }
+ if (img_quality->color_level) {
+ if (copy_from_user(&color, (void __user *)img_quality->color_level,
+ sizeof(struct viif_l1_color_level)))
+ return -EFAULT;
+ img_quality->color_level = &color;
+ }
+
+ spin_lock_irqsave(&viif_dev->lock, irqflags);
+ VIIF_ISP_GUARD_START(viif_dev);
+ ret = hwd_VIIF_l1_set_img_quality_adjustment(
+ viif_dev->ch, VIIF_ISP_REGBUF_0,
+ (struct hwd_viif_l1_img_quality_adjustment *)img_quality);
+ VIIF_ISP_GUARD_END(viif_dev);
+ spin_unlock_irqrestore(&viif_dev->lock, irqflags);
+
+ return ret;
+}
+
#define VISCONTI_VIIF_DPC_TABLE_SIZE_MIN 1024
#define VISCONTI_VIIF_DPC_TABLE_SIZE_MAX 8192
static int viif_l2_set_undist(struct viif_device *viif_dev, struct viif_l2_undist_config *undist)
@@ -736,6 +1233,63 @@ static long viif_ioctl_default(struct file *file, void *fh, bool valid_prio, uns
case VIDIOC_VIIF_MAIN_SET_RAWPACK_MODE:
ret = viif_main_set_rawpack_mode(viif_dev, arg);
break;
+ case VIDIOC_VIIF_L1_SET_INPUT_MODE:
+ ret = viif_l1_set_input_mode(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_RGB_TO_Y_COEF:
+ ret = viif_l1_set_rgb_to_y_coef(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_AG_MODE:
+ ret = viif_l1_set_ag_mode(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_AG:
+ ret = viif_l1_set_ag(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_HDRE:
+ ret = viif_l1_set_hdre(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_IMG_EXTRACTION:
+ ret = viif_l1_set_img_extraction(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_DPC:
+ ret = viif_l1_set_dpc(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_PRESET_WHITE_BALANCE:
+ ret = viif_l1_set_preset_white_balance(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_RAW_COLOR_NOISE_REDUCTION:
+ ret = viif_l1_set_raw_color_noise_reduction(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_HDRS:
+ ret = viif_l1_set_hdrs(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_BLACK_LEVEL_CORRECTION:
+ ret = viif_l1_set_black_level_correction(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_LSC:
+ ret = viif_l1_set_lsc(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_MAIN_PROCESS:
+ ret = viif_l1_set_main_process(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_AWB:
+ ret = viif_l1_set_awb(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_LOCK_AWB_GAIN:
+ ret = viif_l1_lock_awb_gain(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_HDRC:
+ ret = viif_l1_set_hdrc(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_HDRC_LTM:
+ ret = viif_l1_set_hdrc_ltm(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_GAMMA:
+ ret = viif_l1_set_gamma(viif_dev, arg);
+ break;
+ case VIDIOC_VIIF_L1_SET_IMG_QUALITY_ADJUSTMENT:
+ ret = viif_l1_set_img_quality_adjustment(viif_dev, arg);
+ break;
case VIDIOC_VIIF_L2_SET_UNDIST:
ret = viif_l2_set_undist(viif_dev, arg);
break;
diff --git a/include/uapi/linux/visconti_viif.h b/include/uapi/linux/visconti_viif.h
index a235b4d7c..14e6b176c 100644
--- a/include/uapi/linux/visconti_viif.h
+++ b/include/uapi/linux/visconti_viif.h
@@ -14,6 +14,48 @@
/* Private IPCTLs */
#define VIDIOC_VIIF_MAIN_SET_RAWPACK_MODE \
_IOW('V', BASE_VIDIOC_PRIVATE + 1, uint32_t)
+#define VIDIOC_VIIF_L1_SET_INPUT_MODE \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 2, struct viif_l1_input_mode_config)
+#define VIDIOC_VIIF_L1_SET_RGB_TO_Y_COEF \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 3, struct viif_l1_rgb_to_y_coef_config)
+#define VIDIOC_VIIF_L1_SET_AG_MODE \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 4, struct viif_l1_ag_mode_config)
+#define VIDIOC_VIIF_L1_SET_AG \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 5, struct viif_l1_ag_config)
+#define VIDIOC_VIIF_L1_SET_HDRE \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 6, struct viif_l1_hdre_config)
+#define VIDIOC_VIIF_L1_SET_IMG_EXTRACTION \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 7, struct viif_l1_img_extraction_config)
+#define VIDIOC_VIIF_L1_SET_DPC \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 8, struct viif_l1_dpc_config)
+#define VIDIOC_VIIF_L1_SET_PRESET_WHITE_BALANCE \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 9, \
+ struct viif_l1_preset_white_balance_config)
+#define VIDIOC_VIIF_L1_SET_RAW_COLOR_NOISE_REDUCTION \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 10, \
+ struct viif_l1_raw_color_noise_reduction_config)
+#define VIDIOC_VIIF_L1_SET_HDRS \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 11, struct viif_l1_hdrs_config)
+#define VIDIOC_VIIF_L1_SET_BLACK_LEVEL_CORRECTION \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 12, \
+ struct viif_l1_black_level_correction_config)
+#define VIDIOC_VIIF_L1_SET_LSC \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 13, struct viif_l1_lsc_config)
+#define VIDIOC_VIIF_L1_SET_MAIN_PROCESS \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 14, struct viif_l1_main_process_config)
+#define VIDIOC_VIIF_L1_SET_AWB \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 15, struct viif_l1_awb_config)
+#define VIDIOC_VIIF_L1_LOCK_AWB_GAIN \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 16, uint32_t)
+#define VIDIOC_VIIF_L1_SET_HDRC \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 17, struct viif_l1_hdrc_config)
+#define VIDIOC_VIIF_L1_SET_HDRC_LTM \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 18, struct viif_l1_hdrc_ltm_config)
+#define VIDIOC_VIIF_L1_SET_GAMMA \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 19, struct viif_l1_gamma_config)
+#define VIDIOC_VIIF_L1_SET_IMG_QUALITY_ADJUSTMENT \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 20, \
+ struct viif_l1_img_quality_adjustment_config)
#define VIDIOC_VIIF_L2_SET_UNDIST \
_IOW('V', BASE_VIDIOC_PRIVATE + 21, struct viif_l2_undist_config)
#define VIDIOC_VIIF_L2_SET_ROI \
@@ -49,6 +91,1291 @@ enum viif_rawpack_mode {
VIIF_RAWPACK_LSBFIRST = 3,
};

+/**
+ * enum viif_l1_input - L1ISP preprocessing mode
+ *
+ * @VIIF_L1_INPUT_HDR: bypass(HDR input)
+ * @VIIF_L1_INPUT_PWL: HDRE(PWL input)
+ * @VIIF_L1_INPUT_HDR_IMG_CORRECT: SLIC-ABPC-PWHB-RCNR-HDRS
+ * @VIIF_L1_INPUT_PWL_IMG_CORRECT: HDRE-SLIC-ABPC-PWHB-RCNR-HDRS
+ */
+enum viif_l1_input {
+ VIIF_L1_INPUT_HDR = 0,
+ VIIF_L1_INPUT_PWL = 1,
+ VIIF_L1_INPUT_HDR_IMG_CORRECT = 3,
+ VIIF_L1_INPUT_PWL_IMG_CORRECT = 4,
+};
+
+/**
+ * enum viif_l1_raw - L1ISP RAW color filter mode
+ *
+ * @VIIF_L1_RAW_GR_R_B_GB: Gr-R-B-Gb
+ * @VIIF_L1_RAW_R_GR_GB_B: R-Gr-Gb-B
+ * @VIIF_L1_RAW_B_GB_GR_R: B-Gb-Gr-R
+ * @VIIF_L1_RAW_GB_B_R_GR: Gb-B-R-Gr
+ */
+enum viif_l1_raw {
+ VIIF_L1_RAW_GR_R_B_GB = 0,
+ VIIF_L1_RAW_R_GR_GB_B = 1,
+ VIIF_L1_RAW_B_GB_GR_R = 2,
+ VIIF_L1_RAW_GB_B_R_GR = 3,
+};
+
+/**
+ * struct viif_l1_input_mode_config - L1ISP INPUT MODE parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_INPUT_MODE`
+ * @mode: :ref:`L1ISP pre-processing mode <L1ISP_preprocessing_mode>`
+ * @depth: Color depth (even only). Range for each L1ISP pre-processing mode is as below:
+ * - VIIF_L1_INPUT_HDR/HDR_IMG_CORRECT: Range: [8..24].
+ * - VIIF_L1_INPUT_PWL/PWL_IMG_CORRECT: Range: [8..14].
+ * @raw_color_filter: :ref:`RAW color filter mode <L1ISP_RAW_color_filter_mode>`
+ */
+struct viif_l1_input_mode_config {
+ uint32_t mode;
+ uint32_t depth;
+ uint32_t raw_color_filter;
+};
+
+/**
+ * struct viif_l1_rgb_to_y_coef_config - L1ISP coefficient for calculating
+ * Y from RGB parameters for :ref:`VIDIOC_VIIF_L1_SET_RGB_TO_Y_COEF`
+ * @coef_r: R co-efficient [256..65024] accuracy: 1/65536
+ * @coef_g: R co-efficient [256..65024] accuracy: 1/65536
+ * @coef_b: R co-efficient [256..65024] accuracy: 1/65536
+ */
+struct viif_l1_rgb_to_y_coef_config {
+ uint16_t coef_r;
+ uint16_t coef_g;
+ uint16_t coef_b;
+};
+
+/** enum viif_l1_img_sensitivity_mode - L1ISP image sensitivity
+ *
+ * @VIIF_L1_IMG_SENSITIVITY_HIGH: high sensitivity
+ * @VIIF_L1_IMG_SENSITIVITY_MIDDLE_LED: middle sensitivity or led
+ * @VIIF_L1_IMG_SENSITIVITY_LOW: low sensitivity
+ */
+enum viif_l1_img_sensitivity_mode {
+ VIIF_L1_IMG_SENSITIVITY_HIGH = 0,
+ VIIF_L1_IMG_SENSITIVITY_MIDDLE_LED = 1,
+ VIIF_L1_IMG_SENSITIVITY_LOW = 2,
+};
+
+/**
+ * struct viif_l1_ag_mode_config - L1ISP AG mode parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_AG_MODE`
+ * @sysm_ag_grad: Analog gain slope [0..255] (element is id)
+ * @sysm_ag_ofst: Analog gain offset [0..65535] (element is id)
+ * @sysm_ag_cont_hobc_en_high: 1:enable/0:disable to control analog gain
+ * for high sensitivity image of OBCC
+ * @sysm_ag_psel_hobc_high: Analog gain id for high sensitivity image of OBCC [0..3]
+ * @sysm_ag_cont_hobc_en_middle_led: 1:enable/0:disable to control analog gain
+ * for middle sensitivity or LED image of OBCC
+ * @sysm_ag_psel_hobc_middle_led: Analog gain id for middle sensitivity
+ * or LED image of OBCC [0..3]
+ * @sysm_ag_cont_hobc_en_low: 1:enable/0:disable to control analog gain
+ * for low sensitivity image of OBCC
+ * @sysm_ag_psel_hobc_low: Analog gain id for low sensitivity image of OBCC [0..3]
+ * @sysm_ag_cont_abpc_en_high: 1:enable/0:disable to control analog gain
+ * for high sensitivity image of ABPC
+ * @sysm_ag_psel_abpc_high: Analog gain id for high sensitivity image of ABPC [0..3]
+ * @sysm_ag_cont_abpc_en_middle_led: 1:enable/0:disable to control analog gain
+ * for middle sensitivity or LED image of ABPC
+ * @sysm_ag_psel_abpc_middle_led: Analog gain id for middle sensitivity
+ * or LED image of ABPC [0..3]
+ * @sysm_ag_cont_abpc_en_low: 1:enable/0:disable to control analog gain
+ * for low sensitivity image of ABPC
+ * @sysm_ag_psel_abpc_low: Analog gain id for low sensitivity image of ABPC [0..3]
+ * @sysm_ag_cont_rcnr_en_high: 1:enable/0:disable to control analog gain
+ * for high sensitivity image of RCNR
+ * @sysm_ag_psel_rcnr_high: Analog gain id for high sensitivity image of RCNR [0..3]
+ * @sysm_ag_cont_rcnr_en_middle_led: 1:enable/0:disable to control analog gain
+ * for middle sensitivity or LED image of RCNR
+ * @sysm_ag_psel_rcnr_middle_led: Analog gain id for middle sensitivity
+ * or LED image of RCNR [0..3]
+ * @sysm_ag_cont_rcnr_en_low: 1:enable/0:disable to control analog gain
+ * for low sensitivity image of RCNR
+ * @sysm_ag_psel_rcnr_low: Analog gain id for low sensitivity image of RCNR [0..3]
+ * @sysm_ag_cont_lssc_en: 1:enable/0:disable to control analog gain for LSC
+ * @sysm_ag_ssel_lssc: Sensitive image used for LSC.
+ * Refer to :ref:`L1ISP_image_sensitivity`
+ * @sysm_ag_psel_lssc: Analog gain id for LSC [0..3]
+ * @sysm_ag_cont_mpro_en: 1:enable/0:disable to control analog gain for color matrix
+ * @sysm_ag_ssel_mpro: Sensitive image used for color matrix.
+ * Refer to :ref:`L1ISP_image_sensitivity`
+ * @sysm_ag_psel_mpro:Aanalog gain id for color matrix [0..3]
+ * @sysm_ag_cont_vpro_en: 1:enable/0:disable to control analog gain for image adjustment
+ * @sysm_ag_ssel_vpro: Sensitive image used for image adjustment.
+ * Refer to :ref:`L1ISP_image_sensitivity`
+ * @sysm_ag_psel_vpro: Analog gain id for image adjustment [0..3]
+ * @sysm_ag_cont_hobc_test_high: Manual analog gain for high sensitivity image
+ * of OBCC [0..255]
+ * @sysm_ag_cont_hobc_test_middle_led: Manual analog gain for middle sensitivity
+ * or led image of OBCC [0..255]
+ * @sysm_ag_cont_hobc_test_low: Manual analog gain for low sensitivity image
+ * of OBCC [0..255]
+ * @sysm_ag_cont_abpc_test_high: Manual analog gain for high sensitivity image
+ * of ABPC [0..255]
+ * @sysm_ag_cont_abpc_test_middle_led: Manual analog gain for middle sensitivity
+ * or led image of ABPC [0..255]
+ * @sysm_ag_cont_abpc_test_low: Manual analog gain for low sensitivity image
+ * of ABPC [0..255]
+ * @sysm_ag_cont_rcnr_test_high: Manual analog gain for high sensitivity image
+ * of RCNR [0..255]
+ * @sysm_ag_cont_rcnr_test_middle_led: Manual analog gain for middle sensitivity
+ * or led image of RCNR [0..255]
+ * @sysm_ag_cont_rcnr_test_low: Manual analog gain for low sensitivity image
+ * of RCNR [0..255]
+ * @sysm_ag_cont_lssc_test: Manual analog gain for LSSC [0..255]
+ * @sysm_ag_cont_mpro_test: Manual analog gain for color matrix [0..255]
+ * @sysm_ag_cont_vpro_test: Manual analog gain for image adjustment [0..255]
+ *
+ * Operation setting of L1ISP analog gain function.
+ * Analog gain control is disabled if following settings are done.
+ * "sysm_ag_cont_*_en = DRV_VIIF_DISABLE" and "sysm_ag_cont_*_test = 0"
+ * In case "VIIF_L1_INPUT_HDR" or "VIIF_L1_INPUT_PWL" is set to "mode" which is
+ * an &struct viif_l1_input_mode_config, analog gain control needs to be disabled.
+ * Even if this condition is not satisfied, this driver doesn't return error.
+ *
+ * The value set in sysm_ag_psel_xxx indicates analog gain system to be used and
+ * corresponds to the element number of sysm_ag_grad and sysm_ag_ofst.
+ * For example, if sysm_ag_psel_hobc_high is set to 2, then values set in
+ * sysm_ag_grad[2] and sysm_ag_ofst[2] are used for high sensitivity images
+ * in OBCC processing.
+ */
+struct viif_l1_ag_mode_config {
+ uint8_t sysm_ag_grad[4];
+ uint16_t sysm_ag_ofst[4];
+ uint32_t sysm_ag_cont_hobc_en_high;
+ uint32_t sysm_ag_psel_hobc_high;
+ uint32_t sysm_ag_cont_hobc_en_middle_led;
+ uint32_t sysm_ag_psel_hobc_middle_led;
+ uint32_t sysm_ag_cont_hobc_en_low;
+ uint32_t sysm_ag_psel_hobc_low;
+ uint32_t sysm_ag_cont_abpc_en_high;
+ uint32_t sysm_ag_psel_abpc_high;
+ uint32_t sysm_ag_cont_abpc_en_middle_led;
+ uint32_t sysm_ag_psel_abpc_middle_led;
+ uint32_t sysm_ag_cont_abpc_en_low;
+ uint32_t sysm_ag_psel_abpc_low;
+ uint32_t sysm_ag_cont_rcnr_en_high;
+ uint32_t sysm_ag_psel_rcnr_high;
+ uint32_t sysm_ag_cont_rcnr_en_middle_led;
+ uint32_t sysm_ag_psel_rcnr_middle_led;
+ uint32_t sysm_ag_cont_rcnr_en_low;
+ uint32_t sysm_ag_psel_rcnr_low;
+ uint32_t sysm_ag_cont_lssc_en;
+ uint32_t sysm_ag_ssel_lssc;
+ uint32_t sysm_ag_psel_lssc;
+ uint32_t sysm_ag_cont_mpro_en;
+ uint32_t sysm_ag_ssel_mpro;
+ uint32_t sysm_ag_psel_mpro;
+ uint32_t sysm_ag_cont_vpro_en;
+ uint32_t sysm_ag_ssel_vpro;
+ uint32_t sysm_ag_psel_vpro;
+ uint8_t sysm_ag_cont_hobc_test_high;
+ uint8_t sysm_ag_cont_hobc_test_middle_led;
+ uint8_t sysm_ag_cont_hobc_test_low;
+ uint8_t sysm_ag_cont_abpc_test_high;
+ uint8_t sysm_ag_cont_abpc_test_middle_led;
+ uint8_t sysm_ag_cont_abpc_test_low;
+ uint8_t sysm_ag_cont_rcnr_test_high;
+ uint8_t sysm_ag_cont_rcnr_test_middle_led;
+ uint8_t sysm_ag_cont_rcnr_test_low;
+ uint8_t sysm_ag_cont_lssc_test;
+ uint8_t sysm_ag_cont_mpro_test;
+ uint8_t sysm_ag_cont_vpro_test;
+};
+
+/**
+ * struct viif_l1_ag_config - L1ISP AG parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_AG`
+ * @gain_h: Analog gain for high sensitive image [0..65535]
+ * @gain_m: Analog gain for middle sensitive image or LED image [0..65535]
+ * @gain_l: Analog gain for low sensitive image [0..65535]
+ */
+struct viif_l1_ag_config {
+ uint16_t gain_h;
+ uint16_t gain_m;
+ uint16_t gain_l;
+};
+
+/**
+ * struct viif_l1_hdre_config - L1ISP HDRE parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_HDRE`
+ * @hdre_src_point: Knee point N value of PWL compressed signal [0..0x3FFF]
+ * @hdre_dst_base: Offset value of HDR signal in Knee area M [0..0xFFFFFF]
+ * @hdre_ratio: Slope of output pixel value in Knee area M
+ * [0..0x3FFFFF], accuracy: 1/64
+ * @hdre_dst_max_val: Maximum value of output pixel [0..0xFFFFFF]
+ */
+struct viif_l1_hdre_config {
+ uint32_t hdre_src_point[16];
+ uint32_t hdre_dst_base[17];
+ uint32_t hdre_ratio[17];
+ uint32_t hdre_dst_max_val;
+};
+
+/**
+ * struct viif_l1_img_extraction_config - L1ISP image extraction parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_IMG_EXTRACTION`
+ * @input_black_gr: Black level of input pixel (Gr) [0..0xFFFFFF]
+ * @input_black_r: Black level of input pixel (R) [0..0xFFFFFF]
+ * @input_black_b: Black level of input pixel (B) [0..0xFFFFFF]
+ * @input_black_gb: Black level of input pixel (Gb) [0..0xFFFFFF]
+ */
+struct viif_l1_img_extraction_config {
+ uint32_t input_black_gr;
+ uint32_t input_black_r;
+ uint32_t input_black_b;
+ uint32_t input_black_gb;
+};
+
+/**
+ * enum viif_l1_dpc_mode - L1ISP defect pixel correction mode
+ * @VIIF_L1_DPC_1PIXEL: 1 pixel correction mode
+ * @VIIF_L1_DPC_2PIXEL: 2 pixel correction mode
+ */
+enum viif_l1_dpc_mode {
+ VIIF_L1_DPC_1PIXEL = 0,
+ VIIF_L1_DPC_2PIXEL = 1,
+};
+
+/**
+ * struct viif_l1_dpc - L1ISP defect pixel correction parameters
+ * for &struct viif_l1_dpc_config
+ * @abpc_sta_en: 1:enable/0:disable setting of Static DPC
+ * @abpc_dyn_en: 1:enable/0:disable setting of Dynamic DPC
+ * @abpc_dyn_mode: :ref:`Dynamic DPC mode <L1ISP_dynamic_defect_pixel_correction_mode>`
+ * @abpc_ratio_limit: Variation adjustment of dynamic DPC [0..1023]
+ * @abpc_dark_limit: White defect judgment limit of dark area [0..1023]
+ * @abpc_sn_coef_w_ag_min: Luminance difference adjustment of white DPC
+ * (undere lower threshold) [1..31]
+ * @abpc_sn_coef_w_ag_mid: Luminance difference adjustment of white DPC
+ * (between lower and upper threshold) [1..31]
+ * @abpc_sn_coef_w_ag_max: Luminance difference adjustment of white DPC
+ * (over upper threshold) [1..31]
+ * @abpc_sn_coef_b_ag_min: Luminance difference adjustment of black DPC
+ * (undere lower threshold) [1..31]
+ * @abpc_sn_coef_b_ag_mid: Luminance difference adjustment of black DPC
+ * (between lower and upper threshold) [1..31]
+ * @abpc_sn_coef_b_ag_max: Luminance difference adjustment of black DPC
+ * (over upper threshold) [1..31]
+ * @abpc_sn_coef_w_th_min: Luminance difference adjustment of white DPC
+ * analog gain lower threshold [0..255]
+ * @abpc_sn_coef_w_th_max: Luminance difference adjustment of white DPC
+ * analog gain upper threshold [0..255]
+ * @abpc_sn_coef_b_th_min: Luminance difference adjustment of black DPC
+ * analog gain lower threshold [0..255]
+ * @abpc_sn_coef_b_th_max: Luminance difference adjustment of black DPC
+ * analog gain upper threshold [0..255]
+ *
+ * Parameters should meet the following conditions.
+ * "abpc_sn_coef_w_th_min < abpc_sn_coef_w_th_max" and
+ * "abpc_sn_coef_b_th_min < abpc_sn_coef_b_th_max"
+ */
+struct viif_l1_dpc {
+ uint32_t abpc_sta_en;
+ uint32_t abpc_dyn_en;
+ uint32_t abpc_dyn_mode;
+ uint32_t abpc_ratio_limit;
+ uint32_t abpc_dark_limit;
+ uint32_t abpc_sn_coef_w_ag_min;
+ uint32_t abpc_sn_coef_w_ag_mid;
+ uint32_t abpc_sn_coef_w_ag_max;
+ uint32_t abpc_sn_coef_b_ag_min;
+ uint32_t abpc_sn_coef_b_ag_mid;
+ uint32_t abpc_sn_coef_b_ag_max;
+ uint8_t abpc_sn_coef_w_th_min;
+ uint8_t abpc_sn_coef_w_th_max;
+ uint8_t abpc_sn_coef_b_th_min;
+ uint8_t abpc_sn_coef_b_th_max;
+};
+/**
+ * struct viif_l1_dpc - L1ISP defect pixel correction parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_DPC`
+ * @param_h: DPC parameter for high sensitive image. Refer to &struct viif_l1_dpc
+ * @param_m: DPC parameter for middle sensitive image. Refer to &struct viif_l1_dpc
+ * @param_l: DPC parameter for low sensitive image. Refer to &struct viif_l1_dpc
+ * @table_h: DPC table address for high sensitive image.
+ * Table is not transferred if a NULL pointer is set
+ * @table_m: DPC table address for middle sensitive image or LED image
+ * Table is not transferred if a NULL pointer is set
+ * @table_l: DPC table address for low sensitive image
+ * Table is not transferred if a NULL pointer is set
+ *
+ * The size of each table is fixed at 8192 Byte.
+ * Application should make sure that the table data is based on HW specification
+ * since this driver does not check the DPC table.
+ */
+struct viif_l1_dpc_config {
+ struct viif_l1_dpc param_h;
+ struct viif_l1_dpc param_m;
+ struct viif_l1_dpc param_l;
+ uint32_t *table_h;
+ uint32_t *table_m;
+ uint32_t *table_l;
+};
+
+/**
+ * struct viif_l1_preset_wb - L1ISP preset white balance parameters
+ * for &struct viif_l1_preset_white_balance_config
+ * @gain_gr: Gr gain [0..524287], accuracy 1/16384
+ * @gain_r: R gain [0..524287], accuracy 1/16384
+ * @gain_b: B gain [0..524287], accuracy 1/16384
+ * @gain_gb: Gb gain [0..524287], accuracy 1/16384
+ */
+struct viif_l1_preset_wb {
+ uint32_t gain_gr;
+ uint32_t gain_r;
+ uint32_t gain_b;
+ uint32_t gain_gb;
+};
+/**
+ * struct viif_l1_preset_white_balance_config - L1ISP preset white balance
+ * parameters for :ref:`VIDIOC_VIIF_L1_SET_PRESET_WHITE_BALANCE`
+ * @dstmaxval: Maximum value of output pixel [pixel] [0..4095]
+ * @param_h: Preset white balance parameter for high sensitive image.
+ * Refer to &struct viif_l1_preset_wb
+ * @param_m: Preset white balance parameters for middle sensitive image or LED image.
+ * Refer to &struct viif_l1_preset_wb
+ * @param_l: Preset white balance parameters for low sensitive image.
+ * Refer to &struct viif_l1_preset_wb
+ */
+struct viif_l1_preset_white_balance_config {
+ uint32_t dstmaxval;
+ struct viif_l1_preset_wb param_h;
+ struct viif_l1_preset_wb param_m;
+ struct viif_l1_preset_wb param_l;
+};
+
+/**
+ * enum viif_l1_rcnr_type - L1ISP high resolution luminance filter type
+ *
+ * @VIIF_L1_RCNR_LOW_RESOLUTION: low resolution
+ * @VIIF_L1_RCNR_MIDDLE_RESOLUTION: middle resolution
+ * @VIIF_L1_RCNR_HIGH_RESOLUTION: high resolution
+ * @VIIF_L1_RCNR_ULTRA_HIGH_RESOLUTION: ultra high resolution
+ */
+enum viif_l1_rcnr_type {
+ VIIF_L1_RCNR_LOW_RESOLUTION = 0,
+ VIIF_L1_RCNR_MIDDLE_RESOLUTION = 1,
+ VIIF_L1_RCNR_HIGH_RESOLUTION = 2,
+ VIIF_L1_RCNR_ULTRA_HIGH_RESOLUTION = 3,
+};
+
+/**
+ * enum viif_l1_msf_blend_ratio - L1ISP MSF blend ratio
+ *
+ * @VIIF_L1_MSF_BLEND_RATIO_0_DIV_64: 0/64
+ * @VIIF_L1_MSF_BLEND_RATIO_1_DIV_64: 1/64
+ * @VIIF_L1_MSF_BLEND_RATIO_2_DIV_64: 2/64
+ */
+enum viif_l1_msf_blend_ratio {
+ VIIF_L1_MSF_BLEND_RATIO_0_DIV_64 = 0,
+ VIIF_L1_MSF_BLEND_RATIO_1_DIV_64 = 1,
+ VIIF_L1_MSF_BLEND_RATIO_2_DIV_64 = 2,
+};
+
+/**
+ * struct viif_l1_raw_color_noise_reduction - L1ISP RCNR parameters
+ * for &struct viif_l1_raw_color_noise_reduction_config
+ * @rcnr_sw: 1:Enable/0:Disable setting of RAW color noise reduction
+ * @rcnr_cnf_dark_ag0: Maximum value of LSF dark noise adjustment[0..63]
+ * @rcnr_cnf_dark_ag1: Middle value of LSF dark noise adjustment [0..63]
+ * @rcnr_cnf_dark_ag2: Minimum value of LSF dark noise adjustment [0..63]
+ * @rcnr_cnf_ratio_ag0: Maximum value of LSF luminance interlocking noise adjustment [0..31]
+ * @rcnr_cnf_ratio_ag1: Middle value of LSF luminance interlocking noise adjustment [0..31]
+ * @rcnr_cnf_ratio_ag2: Minimum value of LSF luminance interlocking noise adjustment [0..31]
+ * @rcnr_cnf_clip_gain_r: LSF color correction limit adjustment gain R [0..3]
+ * @rcnr_cnf_clip_gain_g: LSF color correction limit adjustment gain G [0..3]
+ * @rcnr_cnf_clip_gain_b: LSF color correction limit adjustment gain B [0..3]
+ * @rcnr_a1l_dark_ag0: Maximum value of MSF dark noise adjustment [0..63]
+ * @rcnr_a1l_dark_ag1: Middle value of MSF dark noise adjustment [0..63]
+ * @rcnr_a1l_dark_ag2: Minimum value of MSF dark noise adjustment [0..63]
+ * @rcnr_a1l_ratio_ag0: Maximum value of MSF luminance interlocking noise adjustment [0..31]
+ * @rcnr_a1l_ratio_ag1: Middle value of MSF luminance interlocking noise adjustment [0..31]
+ * @rcnr_a1l_ratio_ag2: Minimum value of MSF luminance interlocking noise adjustment [0..31]
+ * @rcnr_inf_zero_clip: Input stage zero clip setting [0..256]
+ * @rcnr_merge_d2blend_ag0: Maximum value of filter results and input blend ratio [0..16]
+ * @rcnr_merge_d2blend_ag1: Middle value of filter results and input blend ratio [0..16]
+ * @rcnr_merge_d2blend_ag2: Minimum value of filter results and input blend ratio [0..16]
+ * @rcnr_merge_black: Black level minimum value [0..64]
+ * @rcnr_merge_mindiv: 0 div guard value of inverse arithmetic unit [4..16]
+ * @rcnr_hry_type: Filter type for HSF filter process.
+ * Refer to :ref:`L1ISP_high_resolution_luminance_filter_type`
+ * @rcnr_anf_blend_ag0: Maximum value of MSF result blend ratio in write back data to line memory.
+ * Refer to :ref:`L1ISP_MSF_blend_ratio`
+ * @rcnr_anf_blend_ag1: Middle value of MSF result blend ratio in write back data to line memory.
+ * Refer to :ref:`L1ISP_MSF_blend_ratio`
+ * @rcnr_anf_blend_ag2: Minimum value of MSF result blend ratio in write back data to line memory.
+ * Refer to :ref:`L1ISP_MSF_blend_ratio`
+ * @rcnr_lpf_threshold: Multiplier value for calculating dark noise / luminance
+ * interlock noise of MSF [0..31], accuracy: 1/8
+ * @rcnr_merge_hlblend_ag0: Maximum value of luminance signal generation blend [0..2]
+ * @rcnr_merge_hlblend_ag1: Middle value of luminance signal generation blend [0..2]
+ * @rcnr_merge_hlblend_ag2: Minimum value of luminance signal generation blend [0..2]
+ * @rcnr_gnr_sw: 1:Enable/0:Disable setting of Gr/Gb sensitivity ratio
+ * correction function switching
+ * @rcnr_gnr_ratio: Upper limit of Gr/Gb sensitivity ratio correction factor [0..15]
+ * @rcnr_gnr_wide_en: 1:Enable/0:Disable setting of the function to double
+ * correction upper limit ratio of rcnr_gnr_ratio
+ */
+struct viif_l1_raw_color_noise_reduction {
+ uint32_t rcnr_sw;
+ uint32_t rcnr_cnf_dark_ag0;
+ uint32_t rcnr_cnf_dark_ag1;
+ uint32_t rcnr_cnf_dark_ag2;
+ uint32_t rcnr_cnf_ratio_ag0;
+ uint32_t rcnr_cnf_ratio_ag1;
+ uint32_t rcnr_cnf_ratio_ag2;
+ uint32_t rcnr_cnf_clip_gain_r;
+ uint32_t rcnr_cnf_clip_gain_g;
+ uint32_t rcnr_cnf_clip_gain_b;
+ uint32_t rcnr_a1l_dark_ag0;
+ uint32_t rcnr_a1l_dark_ag1;
+ uint32_t rcnr_a1l_dark_ag2;
+ uint32_t rcnr_a1l_ratio_ag0;
+ uint32_t rcnr_a1l_ratio_ag1;
+ uint32_t rcnr_a1l_ratio_ag2;
+ uint32_t rcnr_inf_zero_clip;
+ uint32_t rcnr_merge_d2blend_ag0;
+ uint32_t rcnr_merge_d2blend_ag1;
+ uint32_t rcnr_merge_d2blend_ag2;
+ uint32_t rcnr_merge_black;
+ uint32_t rcnr_merge_mindiv;
+ uint32_t rcnr_hry_type;
+ uint32_t rcnr_anf_blend_ag0;
+ uint32_t rcnr_anf_blend_ag1;
+ uint32_t rcnr_anf_blend_ag2;
+ uint32_t rcnr_lpf_threshold;
+ uint32_t rcnr_merge_hlblend_ag0;
+ uint32_t rcnr_merge_hlblend_ag1;
+ uint32_t rcnr_merge_hlblend_ag2;
+ uint32_t rcnr_gnr_sw;
+ uint32_t rcnr_gnr_ratio;
+ uint32_t rcnr_gnr_wide_en;
+};
+/**
+ * struct viif_l1_raw_color_noise_reduction_config - L1ISP RCNR parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_RAW_COLOR_NOISE_REDUCTION`
+ * @param_h: RAW color noise reduction parameter for high sensitive image.
+ * Refer to &struct viif_l1_raw_color_noise_reduction
+ * @param_m: RAW color noise reduction parameter for middle sensitive image or LED image.
+ * Refer to &struct viif_l1_raw_color_noise_reduction
+ * @param_l: RAW color noise reduction parameter for low sensitive image.
+ * Refer to &struct viif_l1_raw_color_noise_reduction
+ */
+struct viif_l1_raw_color_noise_reduction_config {
+ struct viif_l1_raw_color_noise_reduction param_h;
+ struct viif_l1_raw_color_noise_reduction param_m;
+ struct viif_l1_raw_color_noise_reduction param_l;
+};
+
+/**
+ * enum viif_l1_hdrs_middle_img_mode - L1ISP HDR setting
+ *
+ * @VIIF_L1_HDRS_NOT_USE_MIDDLE_SENS_IMAGE: not use middle image
+ * @VIIF_L1_HDRS_USE_MIDDLE_SENS_IMAGE: use middle image
+ */
+enum viif_l1_hdrs_middle_img_mode {
+ VIIF_L1_HDRS_NOT_USE_MIDDLE_SENS_IMAGE = 0,
+ VIIF_L1_HDRS_USE_MIDDLE_SENS_IMAGE = 1,
+};
+
+/**
+ * struct viif_l1_hdrs_config - L1ISP HDRS parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_HDRS`
+ * @hdrs_hdr_mode: Use/No use settings of middle sensitivity image in HDRS.
+ * :ref:`L1ISP HDR setting <L1ISP_HDR_setting>`
+ * @hdrs_hdr_ratio_m: Magnification ratio of middle sensitivity image for high
+ * sensitivity image [0x400..0x400000] accuracy: 1/1024
+ * @hdrs_hdr_ratio_l: Magnification ratio of low sensitivity image for high
+ * sensitivity image [0x400..0x400000], accuracy: 1/1024
+ * @hdrs_hdr_ratio_e: Magnification ratio of LED image for high sensitivity image
+ * [0x400..0x400000], accuracy: 1/1024
+ * @hdrs_dg_h: High sensitivity image digital gain [0..0x3FFFFF], accuracy: 1/1024
+ * @hdrs_dg_m: Middle sensitivity image digital gain [0..0x3FFFFF], accuracy: 1/1024
+ * @hdrs_dg_l: Low sensitivity image digital gain [0..0x3FFFFF], accuracy: 1/1024
+ * @hdrs_dg_e: LED image digital gain [0..0x3FFFFF], accuracy: 1/1024
+ * @hdrs_blendend_h: Maximum luminance used for blend high sensitivity image [0..4095]
+ * @hdrs_blendend_m: Maximum luminance used for blend middle sensitivity image [0..4095]
+ * @hdrs_blendend_e: Maximum luminance used for blend LED image [0..4095]
+ * @hdrs_blendbeg_h: Minimum luminance used for blend high sensitivity image [0..4095]
+ * @hdrs_blendbeg_m: Minimum luminance used for blend middle sensitivity image [0..4095]
+ * @hdrs_blendbeg_e: Minimum luminance used for blend LED image [0..4095]
+ * @hdrs_led_mode_on: 1:Enable/0:Disable settings of LED mode
+ * @hdrs_dst_max_val: Maximum value of output pixel [0..0xFFFFFF]
+ *
+ * parameter error needs to be returned in the below condition.
+ * (hdrs_hdr_mode == VIIF_L1_HDRS_USE_MIDDLE_SENS_IMAGE) && (hdrs_led_mode_on == 1)
+ */
+struct viif_l1_hdrs_config {
+ uint32_t hdrs_hdr_mode;
+ uint32_t hdrs_hdr_ratio_m;
+ uint32_t hdrs_hdr_ratio_l;
+ uint32_t hdrs_hdr_ratio_e;
+ uint32_t hdrs_dg_h;
+ uint32_t hdrs_dg_m;
+ uint32_t hdrs_dg_l;
+ uint32_t hdrs_dg_e;
+ uint32_t hdrs_blendend_h;
+ uint32_t hdrs_blendend_m;
+ uint32_t hdrs_blendend_e;
+ uint32_t hdrs_blendbeg_h;
+ uint32_t hdrs_blendbeg_m;
+ uint32_t hdrs_blendbeg_e;
+ uint32_t hdrs_led_mode_on;
+ uint32_t hdrs_dst_max_val;
+};
+
+/**
+ * struct viif_l1_black_level_correction_config - L1ISP image level conversion
+ * parameters for :ref:`VIDIOC_VIIF_L1_SET_BLACK_LEVEL_CORRECTION`
+ * @srcblacklevel_gr: Black level of Gr input pixel [pixel] [0..0xFFFFFF]
+ * @srcblacklevel_r: Black level of R input pixel [pixel] [0..0xFFFFFF]
+ * @srcblacklevel_b: Black level of B input pixel [pixel] [0..0xFFFFFF]
+ * @srcblacklevel_gb: Black level of Gb input pixel [pixel] [0..0xFFFFFF]
+ * @mulval_gr: Gr gain [0..0xFFFFF], accuracy: 1/256
+ * @mulval_r: R gain [0..0xFFFFF], accuracy: 1/256
+ * @mulval_b: B gain [0..0xFFFFF], accuracy: 1/256
+ * @mulval_gb: Gb gain [0..0xFFFFF], accuracy: 1/256
+ * @dstmaxval: Maximum value of output pixel [pixel] [0..0xFFFFFF]
+ */
+struct viif_l1_black_level_correction_config {
+ uint32_t srcblacklevel_gr;
+ uint32_t srcblacklevel_r;
+ uint32_t srcblacklevel_b;
+ uint32_t srcblacklevel_gb;
+ uint32_t mulval_gr;
+ uint32_t mulval_r;
+ uint32_t mulval_b;
+ uint32_t mulval_gb;
+ uint32_t dstmaxval;
+};
+
+/**
+ * enum viif_l1_para_coef_gain - L1ISP parabola shading correction coefficient ratio
+ *
+ * @VIIF_L1_PARA_COEF_GAIN_ONE_EIGHTH: 1/8
+ * @VIIF_L1_PARA_COEF_GAIN_ONE_FOURTH: 1/4
+ * @VIIF_L1_PARA_COEF_GAIN_ONE_SECOND: 1/2
+ * @VIIF_L1_PARA_COEF_GAIN_ONE_FIRST: 1/1
+ */
+enum viif_l1_para_coef_gain {
+ VIIF_L1_PARA_COEF_GAIN_ONE_EIGHTH = 0, /* 1/8 */
+ VIIF_L1_PARA_COEF_GAIN_ONE_FOURTH = 1, /* 1/4 */
+ VIIF_L1_PARA_COEF_GAIN_ONE_SECOND = 2, /* 1/2 */
+ VIIF_L1_PARA_COEF_GAIN_ONE_FIRST = 3, /* 1/1 */
+};
+
+/**
+ * enum viif_l1_grid_coef_gain - L1ISP grid shading correction coefficient ratio
+ *
+ * @VIIF_L1_GRID_COEF_GAIN_X1: x1
+ * @VIIF_L1_GRID_COEF_GAIN_X2: x2
+ */
+enum viif_l1_grid_coef_gain {
+ VIIF_L1_GRID_COEF_GAIN_X1 = 0,
+ VIIF_L1_GRID_COEF_GAIN_X2 = 1,
+};
+
+/**
+ * struct viif_l1_lsc_parabola_ag_param - L2ISP parabola shading parameters
+ * for &struct viif_l1_lsc_parabola_param
+ * @lssc_paracoef_h_l_max: Parabola coefficient left maximum gain value
+ * @lssc_paracoef_h_l_min: Parabola coefficient left minimum gain value
+ * @lssc_paracoef_h_r_max: Parabola coefficient right maximum gain value
+ * @lssc_paracoef_h_r_min: Parabola coefficient right minimum gain value
+ * @lssc_paracoef_v_u_max: Parabola coefficient upper maximum gain value
+ * @lssc_paracoef_v_u_min: Parabola coefficient upper minimum gain value
+ * @lssc_paracoef_v_d_max: Parabola coefficient lower maximum gain value
+ * @lssc_paracoef_v_d_min: Parabola coefficient lower minimum gain value
+ * @lssc_paracoef_hv_lu_max: Parabola coefficient upper left gain maximum value
+ * @lssc_paracoef_hv_lu_min: Parabola coefficient upper left gain minimum value
+ * @lssc_paracoef_hv_ru_max: Parabola coefficient upper right gain maximum value
+ * @lssc_paracoef_hv_ru_min: Parabola coefficient upper right minimum gain value
+ * @lssc_paracoef_hv_ld_max: Parabola coefficient lower left gain maximum value
+ * @lssc_paracoef_hv_ld_min: Parabola coefficient lower left gain minimum value
+ * @lssc_paracoef_hv_rd_max: Parabola coefficient lower right gain maximum value
+ * @lssc_paracoef_hv_rd_min: Parabola coefficient lower right minimum gain value
+ *
+ * The range and accuracy of each coefficient are as
+ * "range: [-4096..4095], accuracy: 1/256 "
+ *
+ * Each coefficient should meet the following conditions.
+ * "lssc_paracoef_xx_xx_min <= lssc_paracoef_xx_xx_max"
+ */
+struct viif_l1_lsc_parabola_ag_param {
+ int16_t lssc_paracoef_h_l_max;
+ int16_t lssc_paracoef_h_l_min;
+ int16_t lssc_paracoef_h_r_max;
+ int16_t lssc_paracoef_h_r_min;
+ int16_t lssc_paracoef_v_u_max;
+ int16_t lssc_paracoef_v_u_min;
+ int16_t lssc_paracoef_v_d_max;
+ int16_t lssc_paracoef_v_d_min;
+ int16_t lssc_paracoef_hv_lu_max;
+ int16_t lssc_paracoef_hv_lu_min;
+ int16_t lssc_paracoef_hv_ru_max;
+ int16_t lssc_paracoef_hv_ru_min;
+ int16_t lssc_paracoef_hv_ld_max;
+ int16_t lssc_paracoef_hv_ld_min;
+ int16_t lssc_paracoef_hv_rd_max;
+ int16_t lssc_paracoef_hv_rd_min;
+};
+/**
+ * struct viif_l1_lsc_parabola_param - L2ISP parabola shading parameters
+ * for &struct viif_l1_lsc
+ * @lssc_para_h_center: Horizontal coordinate of central optical axis [pixel]
+ * [0..(Input image width - 1)]
+ * @lssc_para_v_center: Vertical coordinate of central optical axis [line]
+ * [0..(Input image height - 1)]
+ * @lssc_para_h_gain: Horizontal distance gain with the optical axis
+ * [0..4095], accuracy: 1/256
+ * @lssc_para_v_gain: Vertical distance gain with the optical axis
+ * [0..4095], accuracy: 1/256
+ * @lssc_para_mgsel2: Parabola 2D correction coefficient gain magnification ratio.
+ * Refer to :ref:`L1ISP_parabola_shading_correction_ratio`
+ * @lssc_para_mgsel4: Parabola 4D correction coefficient gain magnification ratio.
+ * Refer to :ref:`L1ISP_parabola_shading_correction_ratio`
+ * @r_2d: 2D parabola coefficient for R.
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @r_4d: 4D parabola coefficient for R.
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @gr_2d: 2D parabola coefficient for Gr
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @gr_4d: 4D parabola coefficient for Gr
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @gb_2d: 2D parabola coefficient for Gb
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @gb_4d: 4D parabola coefficient for Gb
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @b_2d: 2D parabola coefficient for B
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ * @b_4d: 4D parabola coefficient for B
+ * Refer to &struct viif_l1_lsc_parabola_ag_param
+ */
+struct viif_l1_lsc_parabola_param {
+ uint32_t lssc_para_h_center;
+ uint32_t lssc_para_v_center;
+ uint32_t lssc_para_h_gain;
+ uint32_t lssc_para_v_gain;
+ uint32_t lssc_para_mgsel2;
+ uint32_t lssc_para_mgsel4;
+ struct viif_l1_lsc_parabola_ag_param r_2d;
+ struct viif_l1_lsc_parabola_ag_param r_4d;
+ struct viif_l1_lsc_parabola_ag_param gr_2d;
+ struct viif_l1_lsc_parabola_ag_param gr_4d;
+ struct viif_l1_lsc_parabola_ag_param gb_2d;
+ struct viif_l1_lsc_parabola_ag_param gb_4d;
+ struct viif_l1_lsc_parabola_ag_param b_2d;
+ struct viif_l1_lsc_parabola_ag_param b_4d;
+};
+/**
+ * struct viif_l1_lsc_grid_param - L2ISP grid shading parameters
+ * for &struct viif_l1_lsc
+ * @lssc_grid_h_size: Grid horizontal direction pixel count [32, 64, 128, 256, 512]
+ * @lssc_grid_v_size: Grid vertical direction pixel count [32, 64, 128, 256, 512]
+ * @lssc_grid_h_center: Horizontal coordinates of grid (1, 1) [pixel] [1..lssc_grid_h_size]
+ * Should meet the following condition.
+ * "Input image width <= lssc_grid_h_center + lssc_grid_h_size * 31"
+ * @lssc_grid_v_center: Vertical coordinates of grid (1, 1) [line] [1..lssc_grid_v_size]
+ * Should meet the following condition.
+ * "Input image height <= lssc_grid_v_center + lssc_grid_v_size * 23"
+ * @lssc_grid_mgsel: Grid correction coefficient gain value magnification ratio.
+ * Refer to :ref:`L1ISP_grid_shading_correction_coefficient_ratio`
+ */
+struct viif_l1_lsc_grid_param {
+ uint32_t lssc_grid_h_size;
+ uint32_t lssc_grid_v_size;
+ uint32_t lssc_grid_h_center;
+ uint32_t lssc_grid_v_center;
+ uint32_t lssc_grid_mgsel;
+};
+/**
+ * struct viif_l1_lsc - L2ISP LSC parameters for &struct viif_l1_lsc_config
+ * @lssc_parabola_param: Pointer to parabola shading correction parameter.
+ * Refer to &struct viif_l1_lsc_parabola_param.
+ * "NULL: Disable parabola shading correction",
+ * "Other: Enable parabola shading correction"
+ * @lssc_grid_param: Pointer to grid shading correction parameter
+ * Refer to &struct viif_l1_lsc_grid_param.
+ * "NULL: Disable grid shading correction",
+ * "Other: Enable grid shading correction"
+ * @lssc_pwhb_r_gain_max: PWB R correction processing coefficient maximum value
+ * @lssc_pwhb_r_gain_min: PWB R correction processing coefficient minimum value
+ * @lssc_pwhb_gr_gain_max: PWB Gr correction processing coefficient maximum value
+ * @lssc_pwhb_gr_gain_min: PWB Gr correction processing coefficient minimum value
+ * @lssc_pwhb_gb_gain_max: PWB Gb correction processing coefficient maximum value
+ * @lssc_pwhb_gb_gain_min: PWB Gb correction processing coefficient minimum value
+ * @lssc_pwhb_b_gain_max: PWB B correction processing coefficient maximum value
+ * @lssc_pwhb_b_gain_min: PWB B correction processing coefficient minimum value
+ *
+ * The range and accuracy of preset white balance (PWB) correction process
+ * coefficient (lssc_pwhb_{r/gr/gb/b}_gain_{max/min}) are as below.
+ * "range: [0..2047], accuracy: 1/256"
+ *
+ * PWB correction process coefficient
+ * (lssc_pwhb_{r/gr/gb/b}_gain_{max/min}) should meet the following conditions.
+ * "lssc_pwhb_{r/gr/gb/b}_gain_min <= lssc_pwhb_{r/gr/gb/b}_gain_max"
+ */
+struct viif_l1_lsc {
+ struct viif_l1_lsc_parabola_param *lssc_parabola_param;
+ struct viif_l1_lsc_grid_param *lssc_grid_param;
+ uint32_t lssc_pwhb_r_gain_max;
+ uint32_t lssc_pwhb_r_gain_min;
+ uint32_t lssc_pwhb_gr_gain_max;
+ uint32_t lssc_pwhb_gr_gain_min;
+ uint32_t lssc_pwhb_gb_gain_max;
+ uint32_t lssc_pwhb_gb_gain_min;
+ uint32_t lssc_pwhb_b_gain_max;
+ uint32_t lssc_pwhb_b_gain_min;
+};
+/**
+ * struct viif_l1_lsc_config - L2ISP LSC parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_LSC`
+ * @param: Pointer to LSC parameter. Refer to &struct viif_l1_lsc
+ * "NULL: Disable LSC", "Other: Enable LSC"
+ * @table_gr: Grid table address for LSC of Gr.
+ * Table is not transferred if a NULL pointer is set
+ * @table_r: Grid table address for LSC of R.
+ * Table is not transferred if a NULL pointer is set
+ * @table_b: Grid table address for LSC of B.
+ * Table is not transferred if a NULL pointer is set
+ * @table_gb: Grid table address for LSC of Gb.
+ * Table is not transferred if a NULL pointer is set
+ *
+ * The size of each table is fixed to 1,536 Bytes.
+ * Application should make sure that the table data is based on HW specification
+ * since this driver does not check the grid table.
+ */
+struct viif_l1_lsc_config {
+ struct viif_l1_lsc *param;
+ uint16_t *table_gr;
+ uint16_t *table_r;
+ uint16_t *table_b;
+ uint16_t *table_gb;
+};
+
+/**
+ * enum viif_l1_demosaic_mode - L1ISP demosaic modeenum viif_l1_demosaic_mode
+ *
+ * @VIIF_L1_DEMOSAIC_ACPI: Toshiba ACPI algorithm
+ * @VIIF_L1_DEMOSAIC_DMG: DMG algorithm
+ */
+enum viif_l1_demosaic_mode {
+ VIIF_L1_DEMOSAIC_ACPI = 0,
+ VIIF_L1_DEMOSAIC_DMG = 1,
+};
+
+/**
+ * struct viif_l1_color_matrix_correction - L1ISP color matrix correction
+ * parameters for &struct viif_l1_main_process_config
+ * @coef_rmg_min: (R-G) Minimum coefficient
+ * @coef_rmg_max: (R-G) Maximum coefficient
+ * @coef_rmb_min: (R-B) Minimum coefficient
+ * @coef_rmb_max: (R-B) Maximum coefficient
+ * @coef_gmr_min: (G-R) Minimum coefficient
+ * @coef_gmr_max: (G-R) Maximum coefficient
+ * @coef_gmb_min: (G-B) Minimum coefficient
+ * @coef_gmb_max: (G-B) Maximum coefficient
+ * @coef_bmr_min: (B-R) Minimum coefficient
+ * @coef_bmr_max: (B-R) Maximum coefficient
+ * @coef_bmg_min: (B-G) Minimum coefficient
+ * @coef_bmg_max: (B-G) Maximum coefficient
+ * @dst_minval: Minimum value of output pixel [0..0xFFFF] [pixel]
+ *
+ * The range and accuracy of each coefficient are as
+ * "range: [-32768..32767], accuracy: 1/ 4096"
+ *
+ * Also, each coefficient should meet "coef_xxx_min <= coef_xxx_max" condition
+ */
+struct viif_l1_color_matrix_correction {
+ int16_t coef_rmg_min;
+ int16_t coef_rmg_max;
+ int16_t coef_rmb_min;
+ int16_t coef_rmb_max;
+ int16_t coef_gmr_min;
+ int16_t coef_gmr_max;
+ int16_t coef_gmb_min;
+ int16_t coef_gmb_max;
+ int16_t coef_bmr_min;
+ int16_t coef_bmr_max;
+ int16_t coef_bmg_min;
+ int16_t coef_bmg_max;
+ uint16_t dst_minval;
+};
+/**
+ * struct viif_l1_main_process_config - L1ISP Main process operating parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_MAIN_PROCESS`
+ * @demosaic_mode: :ref:`Demosaic mode <L1ISP_demosaic_mode>`
+ * @damp_lsbsel: Clipping range of output pixel value to AWB adjustment function [0..15]
+ * @param: Pointer to color matrix correction parameter.
+ * Refer to &struct viif_l1_color_matrix_correction.
+ * "NULL: Disable color matrix correction",
+ * "Other: Enable color matrix correction"
+ * @dst_maxval: Maximum value of output pixel [0..0xFFFFFF].
+ * Applicable to output of each process (digital amplifier,
+ * demosaicing and color matrix correction) in L1ISP Main process.
+ */
+struct viif_l1_main_process_config {
+ uint32_t demosaic_mode;
+ uint32_t damp_lsbsel;
+ struct viif_l1_color_matrix_correction *param;
+ uint32_t dst_maxval;
+};
+
+/**
+ * enum viif_l1_awb_mag - L1ISP signal magnification before AWB adjustment
+ *
+ * @VIIF_L1_AWB_ONE_SECOND: x 1/2
+ * @VIIF_L1_AWB_X1: 1 times
+ * @VIIF_L1_AWB_X2: 2 times
+ * @VIIF_L1_AWB_X4: 4 times
+ */
+enum viif_l1_awb_mag {
+ VIIF_L1_AWB_ONE_SECOND = 0,
+ VIIF_L1_AWB_X1 = 1,
+ VIIF_L1_AWB_X2 = 2,
+ VIIF_L1_AWB_X4 = 3,
+};
+
+/**
+ * enum viif_l1_awb_area_mode - L1ISP AWB detection target area
+ *
+ * @VIIF_L1_AWB_AREA_MODE0: only center area
+ * @VIIF_L1_AWB_AREA_MODE1: center area when uv is in square gate
+ * @VIIF_L1_AWB_AREA_MODE2: all area except center area
+ * @VIIF_L1_AWB_AREA_MODE3: all area
+ */
+enum viif_l1_awb_area_mode {
+ VIIF_L1_AWB_AREA_MODE0 = 0,
+ VIIF_L1_AWB_AREA_MODE1 = 1,
+ VIIF_L1_AWB_AREA_MODE2 = 2,
+ VIIF_L1_AWB_AREA_MODE3 = 3,
+};
+
+/**
+ * enum viif_l1_awb_restart_cond - L1ISP AWB adjustment restart conditions
+ *
+ * @VIIF_L1_AWB_RESTART_128FRAME: restart after 128 frame
+ * @VIIF_L1_AWB_RESTART_64FRAME: restart after 64 frame
+ * @VIIF_L1_AWB_RESTART_32FRAME: restart after 32 frame
+ * @VIIF_L1_AWB_RESTART_16FRAME: restart after 16 frame
+ * @VIIF_L1_AWB_RESTART_8FRAME: restart after 8 frame
+ * @VIIF_L1_AWB_RESTART_4FRAME: restart after 4 frame
+ * @VIIF_L1_AWB_RESTART_2FRAME: restart after 2 frame
+ */
+enum viif_l1_awb_restart_cond {
+ VIIF_L1_AWB_RESTART_NO = 0, /* not restart */
+ VIIF_L1_AWB_RESTART_128FRAME = 1, /* restart after 128 frame */
+ VIIF_L1_AWB_RESTART_64FRAME = 2, /* restart after 64 frame */
+ VIIF_L1_AWB_RESTART_32FRAME = 3, /* restart after 32 frame */
+ VIIF_L1_AWB_RESTART_16FRAME = 4, /* restart after 16 frame */
+ VIIF_L1_AWB_RESTART_8FRAME = 5, /* restart after 8 frame */
+ VIIF_L1_AWB_RESTART_4FRAME = 6, /* restart after 4 frame */
+ VIIF_L1_AWB_RESTART_2FRAME = 7, /* restart after 2 frame */
+};
+
+/**
+ * struct viif_l1_awb - L1ISP AWB adjustment parameters
+ * for &struct viif_l1_awb_config
+ * @awhb_ygate_sel: 1:Enable/0:Disable to fix Y value at YUV conversion
+ * @awhb_ygate_data: Y value in case Y value is fixed [64, 128, 256, 512]
+ * @awhb_cgrange: Signal output magnification ratio before AWB adjustment.
+ * Refer to :ref:`L1ISP_signal_magnification_before_AWB_adjustment`
+ * @awhb_ygatesw: 1:Enable/0:Disable settings of luminance gate
+ * @awhb_hexsw: 1:Enable/0:Disable settings of hexa-gate
+ * @awhb_areamode: Final selection of accumulation area for detection target area.
+ * Refer to :ref:`L1ISP_AWB_detection_target_area`
+ * @awhb_area_hsize: Horizontal size per block in central area [pixel]
+ * [1..(Input image width -8)/8]
+ * @awhb_area_vsize: Vertical size per block in central area [line]
+ * [1..(Input image height -4)/8]
+ * @awhb_area_hofs: Horizontal offset of block [0] in central area [pixel]
+ * [0..(Input image width -9)]
+ * @awhb_area_vofs: Vertical offset of block [0] in central area [line]
+ * [0..(Input image height -5)]
+ * @awhb_area_maskh: Setting 1:Enable/0:Disable( of accumulated selection.
+ * Each bit implies the following.
+ * [31:0] = {
+ * (7, 3),(6, 3),(5, 3),(4, 3),(3, 3),(2, 3),(1, 3),(0, 3),
+ * (7, 2),(6, 2),(5, 2),(4, 2),(3, 2),(2, 2),(1, 2),(0, 2),
+ * (7, 1),(6, 1),(5, 1),(4, 1),(3, 1),(2, 1),(1, 1),(0, 1),
+ * (7, 0),(6, 0),(5, 0),(4, 0),(3, 0),(2, 0),(1, 0),(0, 0)}
+ * @awhb_area_maskl: Setting 1:Enable/0:Disable of accumulated selection.
+ * Each bit implies the following.
+ * [31:0] = {
+ * (7, 7),(6, 7),(5, 7),(4, 7),(3, 7),(2, 7),(1, 7),(0, 7),
+ * (7, 6),(6, 6),(5, 6),(4, 6),(3, 6),(2, 6),(1, 6),(0, 6),
+ * (7, 5),(6, 5),(5, 5),(4, 5),(3, 5),(2, 5),(1, 5),(0, 5),
+ * (7, 4),(6, 4),(5, 4),(4, 4),(3, 4),(2, 4),(1, 4),(0, 4)}
+ * @awhb_sq_sw: 1:Enable/0:Disable each square gate
+ * @awhb_sq_pol: 1:Enable/0:Disable to add accumulated gate for each square gate
+ * @awhb_bycut0p: U upper end value [pixel] [0..127]
+ * @awhb_bycut0n: U lower end value [pixel] [0..127]
+ * @awhb_rycut0p: V upper end value [pixel] [0..127]
+ * @awhb_rycut0n: V lower end value [pixel] [0..127]
+ * @awhb_rbcut0h: V-axis intercept upper end [pixel] [-127..127]
+ * @awhb_rbcut0l: V-axis intercept lower end [pixel] [-127..127]
+ * @awhb_bycut_h: U direction center value of each square gate [-127..127]
+ * @awhb_bycut_l: U direction width of each square gate [0..127]
+ * @awhb_rycut_h: V direction center value of each square gate [-127..127]
+ * @awhb_rycut_l: V direction width of each square gate [0..127]
+ * @awhb_awbsftu: U gain offset [-127..127]
+ * @awhb_awbsftv: V gain offset [-127..127]
+ * @awhb_awbhuecor: 1:Enable/0:Disable setting of color correlation retention function
+ * @awhb_awbspd: UV convergence speed [0..15] [times] (0 means "stop")
+ * @awhb_awbulv: U convergence point level [0..31]
+ * @awhb_awbvlv: V convergence point level [0..31]
+ * @awhb_awbondot: Accumulation operation stop pixel count threshold [pixel] [0..1023]
+ * @awhb_awbfztim: Condition to restart AWB process.
+ * Refer to :ref:`L1ISP_AWB_adjustment_restart_conditions`
+ * @awhb_wbgrmax: B gain adjustment range (Width from center to upper limit)
+ * [0..255], accuracy: 1/64
+ * @awhb_wbgbmax: R gain adjustment range (Width from center to upper limit)
+ * [0..255], accuracy: 1/64
+ * @awhb_wbgrmin: B gain adjustment range (Width from center to lower limit)
+ * [0..255], accuracy: 1/64
+ * @awhb_wbgbmin: R gain adjustment range (Width from center to lower limit)
+ * [0..255], accuracy: 1/64
+ * @awhb_ygateh: Luminance gate maximum value [pixel] [0..255]
+ * @awhb_ygatel: Luminance gate minimum value [pixel] [0..255]
+ * @awhb_awbwait: Number of restart frames after UV convergence freeze [0..255]
+ */
+struct viif_l1_awb {
+ uint32_t awhb_ygate_sel;
+ uint32_t awhb_ygate_data;
+ uint32_t awhb_cgrange;
+ uint32_t awhb_ygatesw;
+ uint32_t awhb_hexsw;
+ uint32_t awhb_areamode;
+ uint32_t awhb_area_hsize;
+ uint32_t awhb_area_vsize;
+ uint32_t awhb_area_hofs;
+ uint32_t awhb_area_vofs;
+ uint32_t awhb_area_maskh;
+ uint32_t awhb_area_maskl;
+ uint32_t awhb_sq_sw[3];
+ uint32_t awhb_sq_pol[3];
+ uint32_t awhb_bycut0p;
+ uint32_t awhb_bycut0n;
+ uint32_t awhb_rycut0p;
+ uint32_t awhb_rycut0n;
+ int32_t awhb_rbcut0h;
+ int32_t awhb_rbcut0l;
+ int32_t awhb_bycut_h[3];
+ uint32_t awhb_bycut_l[3];
+ int32_t awhb_rycut_h[3];
+ uint32_t awhb_rycut_l[3];
+ int32_t awhb_awbsftu;
+ int32_t awhb_awbsftv;
+ uint32_t awhb_awbhuecor;
+ uint32_t awhb_awbspd;
+ uint32_t awhb_awbulv;
+ uint32_t awhb_awbvlv;
+ uint32_t awhb_awbondot;
+ uint32_t awhb_awbfztim;
+ uint8_t awhb_wbgrmax;
+ uint8_t awhb_wbgbmax;
+ uint8_t awhb_wbgrmin;
+ uint8_t awhb_wbgbmin;
+ uint8_t awhb_ygateh;
+ uint8_t awhb_ygatel;
+ uint8_t awhb_awbwait;
+};
+/**
+ * struct viif_l1_awb_config - L1ISP AWB parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_AWB`
+ * @param: Pointer to AWB adjustment parameter. Refer to &struct viif_l1_awb
+ * "NULL: Disable AWB adjustment", "Other: Enable AWB adjustment"
+ * @awhb_wbmrg: White balance adjustment R gain [64..1023], accuracy: 1/256
+ * @awhb_wbmgg: White balance adjustment G gain [64..1023], accuracy: 1/256
+ * @awhb_wbmbg: White balance adjustment B gain [64..1023], accuracy: 1/256
+ */
+struct viif_l1_awb_config {
+ struct viif_l1_awb *param;
+ uint32_t awhb_wbmrg;
+ uint32_t awhb_wbmgg;
+ uint32_t awhb_wbmbg;
+};
+
+/**
+ * enum viif_l1_hdrc_tone_type - L1ISP HDRC tone type
+ *
+ * @VIIF_L1_HDRC_TONE_USER: User Tone
+ * @VIIF_L1_HDRC_TONE_PRESET: Preset Tone
+ */
+enum viif_l1_hdrc_tone_type {
+ VIIF_L1_HDRC_TONE_USER = 0,
+ VIIF_L1_HDRC_TONE_PRESET = 1,
+};
+
+/**
+ * struct viif_l1_hdrc - L1ISP HDRC parameters for &struct viif_l1_hdrc_config
+ * @hdrc_ratio: Data width of input image [bit] [10..24]
+ * @hdrc_pt_ratio: Preset Tone curve slope [0..13]
+ * @hdrc_pt_blend: Preset Tone0 curve blend ratio [0..256], accuracy: 1/256
+ * @hdrc_pt_blend2: Preset Tone2 curve blend ratio [0..256], accuracy: 1/256
+ * @hdrc_tn_type: :ref:`L1ISP HDRC tone type <L1ISP_HDRC_tone_type>`
+ * @hdrc_utn_tbl: HDRC value of User Tone curve [0..0xFFFF]
+ * @hdrc_flr_val: Constant flare value [0..0xFFFFFF]
+ * @hdrc_flr_adp: 1:Enable/0:Disable setting of dynamic flare measurement
+ * @hdrc_ybr_off: 1:Enable(function OFF) / 0:Disable(function ON) settings
+ * of bilateral luminance filter function OFF
+ * @hdrc_orgy_blend: Blend settings of luminance correction data after HDRC
+ * and data before luminance correction [0..16].
+ * (0:Luminance correction 100%, 8:Luminance correction 50%,
+ * 16:Luminance correction 0%)
+ * @hdrc_pt_sat: Preset Tone saturation value [0..0xFFFF]
+ *
+ * Parameter error needs to be returned in
+ * "hdrc_pt_blend + hdrc_pt_blend2 > 256" condition.
+ *
+ * In case application enables dynamic flare control, input image height should
+ * satisfy the following condition. Even if this condition is not satisfied,
+ * this driver doesn't return error in case other conditions for each parameter
+ * are satisfied. "Input image height % 64 != 18, 20, 22, 24, 26"
+ *
+ * hdrc_utn_tbl should satisfy the following condition. Even if this condition
+ * is not satisfied, this driver doesn't return error in case other conditions
+ * for each parameter are satisfied. "hdrc_utn_tbl[N] <= hdrc_utn_tbl[N+1]"
+ */
+struct viif_l1_hdrc {
+ uint32_t hdrc_ratio;
+ uint32_t hdrc_pt_ratio;
+ uint32_t hdrc_pt_blend;
+ uint32_t hdrc_pt_blend2;
+ uint32_t hdrc_tn_type;
+ uint16_t hdrc_utn_tbl[20];
+ uint32_t hdrc_flr_val;
+ uint32_t hdrc_flr_adp;
+ uint32_t hdrc_ybr_off;
+ uint32_t hdrc_orgy_blend;
+ uint16_t hdrc_pt_sat;
+};
+/**
+ * struct viif_l1_hdrc_config - L1ISP HDRC parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_HDRC`
+ * @param: Pointer to HDRC parameter. Refer to &struct viif_l1_hdrc.
+ * "NULL: Disable HDRC", "Other: Enable HDRC"
+ * @hdrc_thr_sft_amt: Amount of right shift in through mode (HDRC disabled) [0..8].
+ * Should set 0 in case to enable HDRC
+ */
+struct viif_l1_hdrc_config {
+ struct viif_l1_hdrc *param;
+ uint32_t hdrc_thr_sft_amt;
+};
+
+/**
+ * struct viif_l1_hdrc_ltm_config - L1ISP HDRC LTM parameters
+ * for :ref:`VIDIOC_VIIF_L1_SET_HDRC_LTM`
+ * @tnp_max: Tone blend rate maximum value of LTM function
+ * [0..4194303], accuracy: 1/64. In case of 0, LTM function is OFF
+ * @tnp_mag: Intensity adjustment of LTM function [0..16383], accuracy: 1/64
+ * @tnp_fil: Smoothing filter coefficient [0..255].
+ * [0]: coef0, [1]: coef1, [2]: coef2, [3]: coef3, [4]: coef4
+ * EINVAL needs to be returned in the below condition.
+ * "(coef1 + coef2 + coef3 + coef4) * 2 + coef0 != 1024"
+ */
+struct viif_l1_hdrc_ltm_config {
+ uint32_t tnp_max;
+ uint32_t tnp_mag;
+ uint8_t tnp_fil[5];
+};
+
+/**
+ * struct viif_l1_gamma - L1ISP gamma correction parameters
+ * for &struct viif_l1_gamma_config
+ * @gam_p: Luminance value after gamma correction [0..8191]
+ * @blkadj: Black level adjustment value after gamma correction [0..65535]
+ */
+struct viif_l1_gamma {
+ uint16_t gam_p[44];
+ uint16_t blkadj;
+};
+/**
+ * struct viif_l1_gamma_config - L1ISP gamma correction parameters
+ * @param: Pointer to gamma correction parameter. Refer to &struct viif_l1_gamma
+ * "NULL: Disable gamma correction", "Other: Enable gamma correction"
+ */
+struct viif_l1_gamma_config {
+ struct viif_l1_gamma *param;
+};
+
+/**
+ * struct viif_l1_nonlinear_contrast - L1ISP non-linear contrast parameters
+ * for &struct viif_l1_img_quality_adjustment_config
+ * @blk_knee: Black side peak luminance value [0..0xFFFF]
+ * @wht_knee: White side peak luminance value[0..0xFFFF]
+ * @blk_cont: Black side slope [0..255], accuracy: 1/256
+ * [0]:the value at AG minimum, [1]:the value at AG less than 128,
+ * [2]:the value at AG equal to or more than 128
+ * @wht_cont: White side slope [0..255], accuracy: 1/256
+ * [0]:the value at AG minimum, [1]:the value at AG less than 128,
+ * [2]:the value at AG equal to or more than 128
+ */
+struct viif_l1_nonlinear_contrast {
+ uint16_t blk_knee;
+ uint16_t wht_knee;
+ uint8_t blk_cont[3];
+ uint8_t wht_cont[3];
+};
+/**
+ * struct viif_l1_lum_noise_reduction - L1ISP luminance noise reduction
+ * parameters for &struct viif_l1_img_quality_adjustment_config
+ * @gain_min: Minimum value of extracted noise gain [0..0xFFFF], accuracy: 1/256
+ * @gain_max: Maximum value of extracted noise gain [0..0xFFFF], accuracy: 1/256
+ * @lim_min: Minimum value of extracted noise limit [0..0xFFFF]
+ * @lim_max: Maximum value of extracted noise limit [0..0xFFFF]
+ *
+ * Parameter error needs to be returned in the below conditions.
+ * "gain_min > gain_max" or "lim_min > lim_max"
+ */
+struct viif_l1_lum_noise_reduction {
+ uint16_t gain_min;
+ uint16_t gain_max;
+ uint16_t lim_min;
+ uint16_t lim_max;
+};
+/**
+ * struct viif_l1_edge_enhancement - L1ISP edge enhancement parameters
+ * for &struct viif_l1_img_quality_adjustment_config
+ * @gain_min: Extracted edge gain minimum value [0..0xFFFF], accuracy: 1/256
+ * @gain_max: Extracted edge gain maximum value [0..0xFFFF], accuracy: 1/256
+ * @lim_min: Extracted edge limit minimum value [0..0xFFFF]
+ * @lim_max: Extracted edge limit maximum value [0..0xFFFF]
+ * @coring_min: Extracted edge coring threshold minimum value [0..0xFFFF]
+ * @coring_max: Extracted edge coring threshold maximum value [0..0xFFFF]
+ *
+ * Parameter error needs to be returned in the below conditions.
+ * "gain_min > gain_max" or "lim_min > lim_max" or "coring_min > coring_max"
+ */
+struct viif_l1_edge_enhancement {
+ uint16_t gain_min;
+ uint16_t gain_max;
+ uint16_t lim_min;
+ uint16_t lim_max;
+ uint16_t coring_min;
+ uint16_t coring_max;
+};
+/**
+ * struct viif_l1_uv_suppression - L1ISP UV suppression parameters
+ * for &struct viif_l1_img_quality_adjustment_config
+ * @bk_mp: Black side slope [0..0x3FFF], accuracy: 1/16384
+ * @black: Minimum black side gain [0..0x3FFF], accuracy: 1/16384
+ * @wh_mp: White side slope [0..0x3FFF], accuracy: 1/16384
+ * @white: Minimum white side gain [0..0x3FFF], accuracy: 1/16384
+ * @bk_slv: Black side intercept [0..0xFFFF]
+ * @wh_slv: White side intercept [0..0xFFFF]
+ *
+ * parameter error needs to be returned in "bk_slv >= wh_slv" condition.
+ */
+struct viif_l1_uv_suppression {
+ uint32_t bk_mp;
+ uint32_t black;
+ uint32_t wh_mp;
+ uint32_t white;
+ uint16_t bk_slv;
+ uint16_t wh_slv;
+};
+/**
+ * struct viif_l1_coring_suppression - L1ISP coring suppression parameters
+ * for &struct viif_l1_img_quality_adjustment_config
+ * @lv_min: Minimum coring threshold [0..0xFFFF]
+ * @lv_max: Maximum coring threshold [0..0xFFFF]
+ * @gain_min: Minimum gain [0..0xFFFF], accuracy: 1/65536
+ * @gain_max: Maximum gain [0..0xFFFF], accuracy: 1/65536
+ *
+ * Parameter error needs to be returned in the below condition.
+ * "lv_min > lv_max" or "gain_min > gain_max"
+ */
+struct viif_l1_coring_suppression {
+ uint16_t lv_min;
+ uint16_t lv_max;
+ uint16_t gain_min;
+ uint16_t gain_max;
+};
+/**
+ * struct viif_l1_edge_suppression - L1ISP edge suppression parameters
+ * for &struct viif_l1_img_quality_adjustment_config
+ * @gain: Gain of edge color suppression [0..0xFFFF], accuracy: 1/256
+ * @lim: Limiter threshold of edge color suppression [0..15]
+ */
+struct viif_l1_edge_suppression {
+ uint16_t gain;
+ uint32_t lim;
+};
+/**
+ * struct viif_l1_color_level - L1ISP color level parameters
+ * for &struct viif_l1_img_quality_adjustment_config
+ * @cb_gain: U component gain [0..0xFFF], accuracy: 1/2048
+ * @cr_gain: V component gain [0..0xFFF], accuracy: 1/2048
+ * @cbr_mgain_min: UV component gain [0..0xFFF], accuracy: 1/2048
+ * @cbp_gain_max: Positive U component gain [0..0xFFF], accuracy: 1/2048
+ * @cbm_gain_max: Negative V component gain [0..0xFFF], accuracy: 1/2048
+ * @crp_gain_max: Positive U component gain [0..0xFFF], accuracy: 1/2048
+ * @crm_gain_max: Negative V component gain [0..0xFFF], accuracy: 1/2048
+ */
+struct viif_l1_color_level {
+ uint32_t cb_gain;
+ uint32_t cr_gain;
+ uint32_t cbr_mgain_min;
+ uint32_t cbp_gain_max;
+ uint32_t cbm_gain_max;
+ uint32_t crp_gain_max;
+ uint32_t crm_gain_max;
+};
+/**
+ * struct viif_l1_img_quality_adjustment_config - L1ISP image quality
+ * adjustment parameters for :ref:`VIDIOC_VIIF_L1_SET_IMG_QUALITY_ADJUSTMENT`
+ * @coef_cb: Cb coefficient used in RGB to YUV conversion
+ * [0..0xFFFF], accuracy: 1/65536
+ * @coef_cr: Cr coefficient used in RGB to YUV conversion
+ * [0..0xFFFF], accuracy: 1/65536
+ * @brightness: Brightness value [-32768..32767] (0 means off)
+ * @linear_contrast: Linear contrast adjustment value
+ * [0..0xFF], accuracy: 1/128 (128 means off)
+ * @nonlinear_contrast: Pointer to nonlinear contrast adjustment parameter.
+ * Refer to &struct viif_l1_nonlinear_contrast.
+ * "NULL: Disable function", "Other: Enable function"
+ * @lum_noise_reduction: Pointer to luminance noise reduction parameter.
+ * Refer to &struct viif_l1_lum_noise_reduction.
+ * "NULL: Disable function", "Other: Enable function"
+ * @edge_enhancement: Pointer to edge enhancement processing parameter.
+ * Refer to &struct viif_l1_edge_enhancement.
+ * "NULL: Disable function", "Other: Enable function"
+ * @uv_suppression: Pointer to low / high luminance color suppression processing parameter.
+ * Refer to &struct viif_l1_uv_suppression.
+ * "NULL: Disable function", "Other: Enable function"
+ * @coring_suppression: Pointer to low chroma coring suppression processing parameter.
+ * Refer to &struct viif_l1_coring_suppression.
+ * "NULL: Disable function", "Other: Enable function"
+ * @edge_suppression: Pointer to edge color suppression processing parameter.
+ * Refer to &struct viif_l1_edge_suppression.
+ * "NULL: Disable function", "Other: Enable function"
+ * @color_level: Pointer to color level adjustment parameter.
+ * Refer to &struct viif_l1_color_level.
+ * "NULL: Disable function", "Other: Enable function"
+ * @color_noise_reduction_enable: 1:Enable/0:disable setting of
+ * color component noise reduction processing
+ */
+struct viif_l1_img_quality_adjustment_config {
+ uint16_t coef_cb;
+ uint16_t coef_cr;
+ int16_t brightness;
+ uint8_t linear_contrast;
+ struct viif_l1_nonlinear_contrast *nonlinear_contrast;
+ struct viif_l1_lum_noise_reduction *lum_noise_reduction;
+ struct viif_l1_edge_enhancement *edge_enhancement;
+ struct viif_l1_uv_suppression *uv_suppression;
+ struct viif_l1_coring_suppression *coring_suppression;
+ struct viif_l1_edge_suppression *edge_suppression;
+ struct viif_l1_color_level *color_level;
+ uint32_t color_noise_reduction_enable;
+};
+
/* L2ISP undistortion mode */
enum viif_l2_undist_mode {
VIIF_L2_UNDIST_POLY = 0, /* polynomial mode */
--
2.17.1