1e6938cc1SHelen Koike // SPDX-License-Identifier: (GPL-2.0+ OR MIT) 2e6938cc1SHelen Koike /* 3e6938cc1SHelen Koike * Rockchip ISP1 Driver - Params subdevice 4e6938cc1SHelen Koike * 5e6938cc1SHelen Koike * Copyright (C) 2017 Rockchip Electronics Co., Ltd. 6e6938cc1SHelen Koike */ 7e6938cc1SHelen Koike 8*ac79beb9SPaul Elder #include <linux/math.h> 9092e276dSJacopo Mondi #include <linux/string.h> 10092e276dSJacopo Mondi 11e6938cc1SHelen Koike #include <media/v4l2-common.h> 12e6938cc1SHelen Koike #include <media/v4l2-event.h> 13e6938cc1SHelen Koike #include <media/v4l2-ioctl.h> 14e6938cc1SHelen Koike #include <media/videobuf2-core.h> 15e6938cc1SHelen Koike #include <media/videobuf2-vmalloc.h> /* for ISP params */ 16e6938cc1SHelen Koike 17e6938cc1SHelen Koike #include "rkisp1-common.h" 18e6938cc1SHelen Koike 19e6938cc1SHelen Koike #define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params" 20e6938cc1SHelen Koike 21e6938cc1SHelen Koike #define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2 22e6938cc1SHelen Koike #define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8 23e6938cc1SHelen Koike 24596fa6e7SLaurent Pinchart #define RKISP1_ISP_DPCC_METHODS_SET(n) \ 25596fa6e7SLaurent Pinchart (RKISP1_CIF_ISP_DPCC_METHODS_SET_1 + 0x4 * (n)) 26e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_LINE_THRESH(n) \ 27e6938cc1SHelen Koike (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n)) 28e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \ 29e6938cc1SHelen Koike (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n)) 30e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_PG_FAC(n) \ 31e6938cc1SHelen Koike (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n)) 32e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_RND_THRESH(n) \ 33e6938cc1SHelen Koike (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n)) 34e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_RG_FAC(n) \ 35e6938cc1SHelen Koike (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n)) 36e6938cc1SHelen Koike #define RKISP1_ISP_CC_COEFF(n) \ 37e6938cc1SHelen Koike (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4) 38e6938cc1SHelen Koike 396c53a7b6SJacopo Mondi #define RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS BIT(0) 406c53a7b6SJacopo Mondi #define RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC BIT(1) 416c53a7b6SJacopo Mondi 426c53a7b6SJacopo Mondi union rkisp1_ext_params_config { 436c53a7b6SJacopo Mondi struct rkisp1_ext_params_block_header header; 446c53a7b6SJacopo Mondi struct rkisp1_ext_params_bls_config bls; 456c53a7b6SJacopo Mondi struct rkisp1_ext_params_dpcc_config dpcc; 466c53a7b6SJacopo Mondi struct rkisp1_ext_params_sdg_config sdg; 476c53a7b6SJacopo Mondi struct rkisp1_ext_params_lsc_config lsc; 486c53a7b6SJacopo Mondi struct rkisp1_ext_params_awb_gain_config awbg; 496c53a7b6SJacopo Mondi struct rkisp1_ext_params_flt_config flt; 506c53a7b6SJacopo Mondi struct rkisp1_ext_params_bdm_config bdm; 516c53a7b6SJacopo Mondi struct rkisp1_ext_params_ctk_config ctk; 526c53a7b6SJacopo Mondi struct rkisp1_ext_params_goc_config goc; 536c53a7b6SJacopo Mondi struct rkisp1_ext_params_dpf_config dpf; 546c53a7b6SJacopo Mondi struct rkisp1_ext_params_dpf_strength_config dpfs; 556c53a7b6SJacopo Mondi struct rkisp1_ext_params_cproc_config cproc; 566c53a7b6SJacopo Mondi struct rkisp1_ext_params_ie_config ie; 576c53a7b6SJacopo Mondi struct rkisp1_ext_params_awb_meas_config awbm; 586c53a7b6SJacopo Mondi struct rkisp1_ext_params_hst_config hst; 596c53a7b6SJacopo Mondi struct rkisp1_ext_params_aec_config aec; 606c53a7b6SJacopo Mondi struct rkisp1_ext_params_afc_config afc; 61*ac79beb9SPaul Elder struct rkisp1_ext_params_compand_bls_config compand_bls; 62*ac79beb9SPaul Elder struct rkisp1_ext_params_compand_curve_config compand_curve; 636c53a7b6SJacopo Mondi }; 646c53a7b6SJacopo Mondi 6516398399SJacopo Mondi enum rkisp1_params_formats { 6616398399SJacopo Mondi RKISP1_PARAMS_FIXED, 6716398399SJacopo Mondi RKISP1_PARAMS_EXTENSIBLE, 6816398399SJacopo Mondi }; 6916398399SJacopo Mondi 7016398399SJacopo Mondi static const struct v4l2_meta_format rkisp1_params_formats[] = { 7116398399SJacopo Mondi [RKISP1_PARAMS_FIXED] = { 7216398399SJacopo Mondi .dataformat = V4L2_META_FMT_RK_ISP1_PARAMS, 7316398399SJacopo Mondi .buffersize = sizeof(struct rkisp1_params_cfg), 7416398399SJacopo Mondi }, 7516398399SJacopo Mondi [RKISP1_PARAMS_EXTENSIBLE] = { 7616398399SJacopo Mondi .dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS, 7716398399SJacopo Mondi .buffersize = sizeof(struct rkisp1_ext_params_cfg), 7816398399SJacopo Mondi }, 7916398399SJacopo Mondi }; 8016398399SJacopo Mondi 81f848c031SJacopo Mondi static const struct v4l2_meta_format * 82f848c031SJacopo Mondi rkisp1_params_get_format_info(u32 dataformat) 83f848c031SJacopo Mondi { 84f848c031SJacopo Mondi for (unsigned int i = 0; i < ARRAY_SIZE(rkisp1_params_formats); i++) { 85f848c031SJacopo Mondi if (rkisp1_params_formats[i].dataformat == dataformat) 86f848c031SJacopo Mondi return &rkisp1_params_formats[i]; 87f848c031SJacopo Mondi } 88f848c031SJacopo Mondi 89f848c031SJacopo Mondi return &rkisp1_params_formats[RKISP1_PARAMS_FIXED]; 90f848c031SJacopo Mondi } 91f848c031SJacopo Mondi 92e6938cc1SHelen Koike static inline void 93e6938cc1SHelen Koike rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask) 94e6938cc1SHelen Koike { 95e6938cc1SHelen Koike u32 val; 96e6938cc1SHelen Koike 97e6938cc1SHelen Koike val = rkisp1_read(params->rkisp1, reg); 980ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, reg, val | bit_mask); 99e6938cc1SHelen Koike } 100e6938cc1SHelen Koike 101e6938cc1SHelen Koike static inline void 102e6938cc1SHelen Koike rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask) 103e6938cc1SHelen Koike { 104e6938cc1SHelen Koike u32 val; 105e6938cc1SHelen Koike 106e6938cc1SHelen Koike val = rkisp1_read(params->rkisp1, reg); 1070ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, reg, val & ~bit_mask); 108e6938cc1SHelen Koike } 109e6938cc1SHelen Koike 110e6938cc1SHelen Koike /* ISP BP interface function */ 111e6938cc1SHelen Koike static void rkisp1_dpcc_config(struct rkisp1_params *params, 112e6938cc1SHelen Koike const struct rkisp1_cif_isp_dpcc_config *arg) 113e6938cc1SHelen Koike { 114e6938cc1SHelen Koike unsigned int i; 115e6938cc1SHelen Koike u32 mode; 116e6938cc1SHelen Koike 1179daa2b84SLaurent Pinchart /* 1189daa2b84SLaurent Pinchart * The enable bit is controlled in rkisp1_isp_isr_other_config() and 1199daa2b84SLaurent Pinchart * must be preserved. The grayscale mode should be configured 1209daa2b84SLaurent Pinchart * automatically based on the media bus code on the ISP sink pad, so 1219daa2b84SLaurent Pinchart * only the STAGE1_ENABLE bit can be set by userspace. 1229daa2b84SLaurent Pinchart */ 123e6938cc1SHelen Koike mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE); 1249daa2b84SLaurent Pinchart mode &= RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE; 1259daa2b84SLaurent Pinchart mode |= arg->mode & RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE; 1260ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE, mode); 1279daa2b84SLaurent Pinchart 1280ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_OUTPUT_MODE, 1299daa2b84SLaurent Pinchart arg->output_mode & RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_MASK); 1300ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_SET_USE, 1319daa2b84SLaurent Pinchart arg->set_use & RKISP1_CIF_ISP_DPCC_SET_USE_MASK); 132e6938cc1SHelen Koike 133e6938cc1SHelen Koike for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) { 134596fa6e7SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_METHODS_SET(i), 1359daa2b84SLaurent Pinchart arg->methods[i].method & 1369daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_METHODS_SET_MASK); 1370ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_THRESH(i), 1389daa2b84SLaurent Pinchart arg->methods[i].line_thresh & 1399daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_LINE_THRESH_MASK); 1400ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_MAD_FAC(i), 1419daa2b84SLaurent Pinchart arg->methods[i].line_mad_fac & 1429daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_MASK); 1430ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_PG_FAC(i), 1449daa2b84SLaurent Pinchart arg->methods[i].pg_fac & 1459daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_PG_FAC_MASK); 1460ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RND_THRESH(i), 1479daa2b84SLaurent Pinchart arg->methods[i].rnd_thresh & 1489daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_RND_THRESH_MASK); 1490ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RG_FAC(i), 1509daa2b84SLaurent Pinchart arg->methods[i].rg_fac & 1519daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_RG_FAC_MASK); 152e6938cc1SHelen Koike } 153e6938cc1SHelen Koike 1540ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RND_OFFS, 1559daa2b84SLaurent Pinchart arg->rnd_offs & RKISP1_CIF_ISP_DPCC_RND_OFFS_MASK); 1560ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RO_LIMITS, 1579daa2b84SLaurent Pinchart arg->ro_limits & RKISP1_CIF_ISP_DPCC_RO_LIMIT_MASK); 158e6938cc1SHelen Koike } 159e6938cc1SHelen Koike 160e6938cc1SHelen Koike /* ISP black level subtraction interface function */ 161e6938cc1SHelen Koike static void rkisp1_bls_config(struct rkisp1_params *params, 162e6938cc1SHelen Koike const struct rkisp1_cif_isp_bls_config *arg) 163e6938cc1SHelen Koike { 164e6938cc1SHelen Koike /* avoid to override the old enable value */ 165e6938cc1SHelen Koike u32 new_control; 166e6938cc1SHelen Koike 167e6938cc1SHelen Koike new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL); 168e6938cc1SHelen Koike new_control &= RKISP1_CIF_ISP_BLS_ENA; 169e6938cc1SHelen Koike /* fixed subtraction values */ 170e6938cc1SHelen Koike if (!arg->enable_auto) { 171d2db5694SLaurent Pinchart static const u32 regs[] = { 172d2db5694SLaurent Pinchart RKISP1_CIF_ISP_BLS_A_FIXED, 173d2db5694SLaurent Pinchart RKISP1_CIF_ISP_BLS_B_FIXED, 174d2db5694SLaurent Pinchart RKISP1_CIF_ISP_BLS_C_FIXED, 175d2db5694SLaurent Pinchart RKISP1_CIF_ISP_BLS_D_FIXED, 176d2db5694SLaurent Pinchart }; 177d2db5694SLaurent Pinchart u32 swapped[4]; 178e6938cc1SHelen Koike 179d2db5694SLaurent Pinchart rkisp1_bls_swap_regs(params->raw_type, regs, swapped); 180e6938cc1SHelen Koike 181d2db5694SLaurent Pinchart rkisp1_write(params->rkisp1, swapped[0], arg->fixed_val.r); 182d2db5694SLaurent Pinchart rkisp1_write(params->rkisp1, swapped[1], arg->fixed_val.gr); 183d2db5694SLaurent Pinchart rkisp1_write(params->rkisp1, swapped[2], arg->fixed_val.gb); 184d2db5694SLaurent Pinchart rkisp1_write(params->rkisp1, swapped[3], arg->fixed_val.b); 185e6938cc1SHelen Koike } else { 186e6938cc1SHelen Koike if (arg->en_windows & BIT(1)) { 1870ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_START, 1880ef7dc30SLaurent Pinchart arg->bls_window2.h_offs); 1890ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_STOP, 1900ef7dc30SLaurent Pinchart arg->bls_window2.h_size); 1910ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V2_START, 1920ef7dc30SLaurent Pinchart arg->bls_window2.v_offs); 1930ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V2_STOP, 1940ef7dc30SLaurent Pinchart arg->bls_window2.v_size); 195e6938cc1SHelen Koike new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2; 196e6938cc1SHelen Koike } 197e6938cc1SHelen Koike 198e6938cc1SHelen Koike if (arg->en_windows & BIT(0)) { 1990ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H1_START, 2000ef7dc30SLaurent Pinchart arg->bls_window1.h_offs); 2010ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H1_STOP, 2020ef7dc30SLaurent Pinchart arg->bls_window1.h_size); 2030ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V1_START, 2040ef7dc30SLaurent Pinchart arg->bls_window1.v_offs); 2050ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V1_STOP, 2060ef7dc30SLaurent Pinchart arg->bls_window1.v_size); 207e6938cc1SHelen Koike new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1; 208e6938cc1SHelen Koike } 209e6938cc1SHelen Koike 2100ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_SAMPLES, 2110ef7dc30SLaurent Pinchart arg->bls_samples); 212e6938cc1SHelen Koike 213e6938cc1SHelen Koike new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED; 214e6938cc1SHelen Koike } 2150ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL, new_control); 216e6938cc1SHelen Koike } 217e6938cc1SHelen Koike 218e6938cc1SHelen Koike /* ISP LS correction interface function */ 219e6938cc1SHelen Koike static void 220dce8ccb2SHeiko Stuebner rkisp1_lsc_matrix_config_v10(struct rkisp1_params *params, 221e6938cc1SHelen Koike const struct rkisp1_cif_isp_lsc_config *pconfig) 222e6938cc1SHelen Koike { 223cf655fafSLaurent Pinchart struct rkisp1_device *rkisp1 = params->rkisp1; 224da57dffaSLaurent Pinchart u32 lsc_status, sram_addr, lsc_table_sel; 225da57dffaSLaurent Pinchart unsigned int i, j; 226e6938cc1SHelen Koike 227cf655fafSLaurent Pinchart lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS); 228e6938cc1SHelen Koike 229e6938cc1SHelen Koike /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */ 230cf655fafSLaurent Pinchart sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 231e6938cc1SHelen Koike RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 : 232e6938cc1SHelen Koike RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153; 233cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr); 234cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr); 235cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr); 236cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr); 237e6938cc1SHelen Koike 238e6938cc1SHelen Koike /* program data tables (table size is 9 * 17 = 153) */ 239e6938cc1SHelen Koike for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) { 240cf655fafSLaurent Pinchart const __u16 *r_tbl = pconfig->r_data_tbl[i]; 241cf655fafSLaurent Pinchart const __u16 *gr_tbl = pconfig->gr_data_tbl[i]; 242cf655fafSLaurent Pinchart const __u16 *gb_tbl = pconfig->gb_data_tbl[i]; 243cf655fafSLaurent Pinchart const __u16 *b_tbl = pconfig->b_data_tbl[i]; 244cf655fafSLaurent Pinchart 245e6938cc1SHelen Koike /* 246e6938cc1SHelen Koike * 17 sectors with 2 values in one DWORD = 9 247e6938cc1SHelen Koike * DWORDs (2nd value of last DWORD unused) 248e6938cc1SHelen Koike */ 249e6938cc1SHelen Koike for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) { 250cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 251cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 252cf655fafSLaurent Pinchart r_tbl[j], r_tbl[j + 1])); 253cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 254cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 255cf655fafSLaurent Pinchart gr_tbl[j], gr_tbl[j + 1])); 256cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 257cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 258cf655fafSLaurent Pinchart gb_tbl[j], gb_tbl[j + 1])); 259cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 260cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 261cf655fafSLaurent Pinchart b_tbl[j], b_tbl[j + 1])); 262e6938cc1SHelen Koike } 263e6938cc1SHelen Koike 264cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 265cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(r_tbl[j], 0)); 266cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 267cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gr_tbl[j], 0)); 268cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 269cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gb_tbl[j], 0)); 270cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 271cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(b_tbl[j], 0)); 272e6938cc1SHelen Koike } 273cf655fafSLaurent Pinchart 274cf655fafSLaurent Pinchart lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 275cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1; 276cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel); 277e6938cc1SHelen Koike } 278e6938cc1SHelen Koike 279cd42f802SHeiko Stuebner static void 280cd42f802SHeiko Stuebner rkisp1_lsc_matrix_config_v12(struct rkisp1_params *params, 281cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_lsc_config *pconfig) 282cd42f802SHeiko Stuebner { 283cf655fafSLaurent Pinchart struct rkisp1_device *rkisp1 = params->rkisp1; 284da57dffaSLaurent Pinchart u32 lsc_status, sram_addr, lsc_table_sel; 285da57dffaSLaurent Pinchart unsigned int i, j; 286cd42f802SHeiko Stuebner 287cf655fafSLaurent Pinchart lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS); 288cd42f802SHeiko Stuebner 289cd42f802SHeiko Stuebner /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */ 290cf655fafSLaurent Pinchart sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 291cd42f802SHeiko Stuebner RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 : 292cd42f802SHeiko Stuebner RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153; 293cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr); 294cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr); 295cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr); 296cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr); 297cd42f802SHeiko Stuebner 298cd42f802SHeiko Stuebner /* program data tables (table size is 9 * 17 = 153) */ 299cd42f802SHeiko Stuebner for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) { 300cf655fafSLaurent Pinchart const __u16 *r_tbl = pconfig->r_data_tbl[i]; 301cf655fafSLaurent Pinchart const __u16 *gr_tbl = pconfig->gr_data_tbl[i]; 302cf655fafSLaurent Pinchart const __u16 *gb_tbl = pconfig->gb_data_tbl[i]; 303cf655fafSLaurent Pinchart const __u16 *b_tbl = pconfig->b_data_tbl[i]; 304cf655fafSLaurent Pinchart 305cd42f802SHeiko Stuebner /* 306cd42f802SHeiko Stuebner * 17 sectors with 2 values in one DWORD = 9 307cd42f802SHeiko Stuebner * DWORDs (2nd value of last DWORD unused) 308cd42f802SHeiko Stuebner */ 309cd42f802SHeiko Stuebner for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) { 310cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 311cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 312cf655fafSLaurent Pinchart r_tbl[j], r_tbl[j + 1])); 313cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 314cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 315cf655fafSLaurent Pinchart gr_tbl[j], gr_tbl[j + 1])); 316cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 317cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 318cf655fafSLaurent Pinchart gb_tbl[j], gb_tbl[j + 1])); 319cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 320cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 321cf655fafSLaurent Pinchart b_tbl[j], b_tbl[j + 1])); 322cd42f802SHeiko Stuebner } 323cd42f802SHeiko Stuebner 324cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 325cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(r_tbl[j], 0)); 326cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 327cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gr_tbl[j], 0)); 328cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 329cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gb_tbl[j], 0)); 330cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 331cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(b_tbl[j], 0)); 332cd42f802SHeiko Stuebner } 333cf655fafSLaurent Pinchart 334cf655fafSLaurent Pinchart lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 335cf655fafSLaurent Pinchart RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1; 336cf655fafSLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel); 337cd42f802SHeiko Stuebner } 338cd42f802SHeiko Stuebner 339e6938cc1SHelen Koike static void rkisp1_lsc_config(struct rkisp1_params *params, 340e6938cc1SHelen Koike const struct rkisp1_cif_isp_lsc_config *arg) 341e6938cc1SHelen Koike { 342cf655fafSLaurent Pinchart struct rkisp1_device *rkisp1 = params->rkisp1; 343da57dffaSLaurent Pinchart u32 lsc_ctrl, data; 344da57dffaSLaurent Pinchart unsigned int i; 345e6938cc1SHelen Koike 346e6938cc1SHelen Koike /* To config must be off , store the current status firstly */ 347cf655fafSLaurent Pinchart lsc_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_CTRL); 348e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 349e6938cc1SHelen Koike RKISP1_CIF_ISP_LSC_CTRL_ENA); 3505e8d9d72SHeiko Stuebner params->ops->lsc_matrix_config(params, arg); 351e6938cc1SHelen Koike 352e6938cc1SHelen Koike for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) { 353e6938cc1SHelen Koike /* program x size tables */ 354e6938cc1SHelen Koike data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2], 355e6938cc1SHelen Koike arg->x_size_tbl[i * 2 + 1]); 35610e36b21SLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XSIZE(i), data); 357e6938cc1SHelen Koike 358e6938cc1SHelen Koike /* program x grad tables */ 3594c3501f1SLaurent Pinchart data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2], 360e6938cc1SHelen Koike arg->x_grad_tbl[i * 2 + 1]); 36110e36b21SLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XGRAD(i), data); 362e6938cc1SHelen Koike 363e6938cc1SHelen Koike /* program y size tables */ 364e6938cc1SHelen Koike data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2], 365e6938cc1SHelen Koike arg->y_size_tbl[i * 2 + 1]); 36610e36b21SLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YSIZE(i), data); 367e6938cc1SHelen Koike 368e6938cc1SHelen Koike /* program y grad tables */ 3694c3501f1SLaurent Pinchart data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2], 370e6938cc1SHelen Koike arg->y_grad_tbl[i * 2 + 1]); 37110e36b21SLaurent Pinchart rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YGRAD(i), data); 372e6938cc1SHelen Koike } 373e6938cc1SHelen Koike 374e6938cc1SHelen Koike /* restore the lsc ctrl status */ 375cf655fafSLaurent Pinchart if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) 376cf655fafSLaurent Pinchart rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 377e6938cc1SHelen Koike RKISP1_CIF_ISP_LSC_CTRL_ENA); 378cf655fafSLaurent Pinchart else 379cf655fafSLaurent Pinchart rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 380e6938cc1SHelen Koike RKISP1_CIF_ISP_LSC_CTRL_ENA); 381e6938cc1SHelen Koike } 382e6938cc1SHelen Koike 383e6938cc1SHelen Koike /* ISP Filtering function */ 384e6938cc1SHelen Koike static void rkisp1_flt_config(struct rkisp1_params *params, 385e6938cc1SHelen Koike const struct rkisp1_cif_isp_flt_config *arg) 386e6938cc1SHelen Koike { 387e6938cc1SHelen Koike u32 filt_mode; 388e6938cc1SHelen Koike 3890ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_BL0, 3900ef7dc30SLaurent Pinchart arg->thresh_bl0); 3910ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_BL1, 3920ef7dc30SLaurent Pinchart arg->thresh_bl1); 3930ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_SH0, 3940ef7dc30SLaurent Pinchart arg->thresh_sh0); 3950ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_SH1, 3960ef7dc30SLaurent Pinchart arg->thresh_sh1); 3970ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_BL0, 3980ef7dc30SLaurent Pinchart arg->fac_bl0); 3990ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_BL1, 4000ef7dc30SLaurent Pinchart arg->fac_bl1); 4010ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_MID, 4020ef7dc30SLaurent Pinchart arg->fac_mid); 4030ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_SH0, 4040ef7dc30SLaurent Pinchart arg->fac_sh0); 4050ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_SH1, 4060ef7dc30SLaurent Pinchart arg->fac_sh1); 4070ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_LUM_WEIGHT, 4080ef7dc30SLaurent Pinchart arg->lum_weight); 409e6938cc1SHelen Koike 4100ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE, 411e6938cc1SHelen Koike (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) | 412e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) | 413e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) | 4140ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1)); 415e6938cc1SHelen Koike 416e6938cc1SHelen Koike /* avoid to override the old enable value */ 417e6938cc1SHelen Koike filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE); 418e6938cc1SHelen Koike filt_mode &= RKISP1_CIF_ISP_FLT_ENA; 419e6938cc1SHelen Koike if (arg->mode) 420e6938cc1SHelen Koike filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR; 421e6938cc1SHelen Koike filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) | 422e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) | 423e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1); 4240ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE, filt_mode); 425e6938cc1SHelen Koike } 426e6938cc1SHelen Koike 427e6938cc1SHelen Koike /* ISP demosaic interface function */ 428e6938cc1SHelen Koike static int rkisp1_bdm_config(struct rkisp1_params *params, 429e6938cc1SHelen Koike const struct rkisp1_cif_isp_bdm_config *arg) 430e6938cc1SHelen Koike { 431e6938cc1SHelen Koike u32 bdm_th; 432e6938cc1SHelen Koike 433e6938cc1SHelen Koike /* avoid to override the old enable value */ 434e6938cc1SHelen Koike bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC); 435e6938cc1SHelen Koike bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS; 436e6938cc1SHelen Koike bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS; 437e6938cc1SHelen Koike /* set demosaic threshold */ 4380ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC, bdm_th); 439e6938cc1SHelen Koike return 0; 440e6938cc1SHelen Koike } 441e6938cc1SHelen Koike 442e6938cc1SHelen Koike /* ISP GAMMA correction interface function */ 443e6938cc1SHelen Koike static void rkisp1_sdg_config(struct rkisp1_params *params, 444e6938cc1SHelen Koike const struct rkisp1_cif_isp_sdg_config *arg) 445e6938cc1SHelen Koike { 446e6938cc1SHelen Koike unsigned int i; 447e6938cc1SHelen Koike 4480ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_DX_LO, 4490ef7dc30SLaurent Pinchart arg->xa_pnts.gamma_dx0); 4500ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_DX_HI, 4510ef7dc30SLaurent Pinchart arg->xa_pnts.gamma_dx1); 452e6938cc1SHelen Koike 453e6938cc1SHelen Koike for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) { 4540ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 4550ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4, 4560ef7dc30SLaurent Pinchart arg->curve_r.gamma_y[i]); 4570ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 4580ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4, 4590ef7dc30SLaurent Pinchart arg->curve_g.gamma_y[i]); 4600ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 4610ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4, 4620ef7dc30SLaurent Pinchart arg->curve_b.gamma_y[i]); 463e6938cc1SHelen Koike } 464e6938cc1SHelen Koike } 465e6938cc1SHelen Koike 466e6938cc1SHelen Koike /* ISP GAMMA correction interface function */ 467dce8ccb2SHeiko Stuebner static void rkisp1_goc_config_v10(struct rkisp1_params *params, 468e6938cc1SHelen Koike const struct rkisp1_cif_isp_goc_config *arg) 469e6938cc1SHelen Koike { 470e6938cc1SHelen Koike unsigned int i; 471e6938cc1SHelen Koike 472e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 473e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 4740ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V10, 4750ef7dc30SLaurent Pinchart arg->mode); 476e6938cc1SHelen Koike 477ef357e02SHeiko Stuebner for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++) 4780ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 4790ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V10 + i * 4, 4800ef7dc30SLaurent Pinchart arg->gamma_y[i]); 481e6938cc1SHelen Koike } 482e6938cc1SHelen Koike 483cd42f802SHeiko Stuebner static void rkisp1_goc_config_v12(struct rkisp1_params *params, 484cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_goc_config *arg) 485cd42f802SHeiko Stuebner { 486cd42f802SHeiko Stuebner unsigned int i; 487cd42f802SHeiko Stuebner u32 value; 488cd42f802SHeiko Stuebner 489cd42f802SHeiko Stuebner rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 490cd42f802SHeiko Stuebner RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 4910ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V12, 4920ef7dc30SLaurent Pinchart arg->mode); 493cd42f802SHeiko Stuebner 494cd42f802SHeiko Stuebner for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 / 2; i++) { 495cd42f802SHeiko Stuebner value = RKISP1_CIF_ISP_GAMMA_VALUE_V12( 496cd42f802SHeiko Stuebner arg->gamma_y[2 * i + 1], 497cd42f802SHeiko Stuebner arg->gamma_y[2 * i]); 4980ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 4990ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V12 + i * 4, value); 500cd42f802SHeiko Stuebner } 501cd42f802SHeiko Stuebner } 502cd42f802SHeiko Stuebner 503e6938cc1SHelen Koike /* ISP Cross Talk */ 504e6938cc1SHelen Koike static void rkisp1_ctk_config(struct rkisp1_params *params, 505e6938cc1SHelen Koike const struct rkisp1_cif_isp_ctk_config *arg) 506e6938cc1SHelen Koike { 507e6938cc1SHelen Koike unsigned int i, j, k = 0; 508e6938cc1SHelen Koike 509e6938cc1SHelen Koike for (i = 0; i < 3; i++) 510e6938cc1SHelen Koike for (j = 0; j < 3; j++) 5110ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 5120ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++, 5130ef7dc30SLaurent Pinchart arg->coeff[i][j]); 514e6938cc1SHelen Koike for (i = 0; i < 3; i++) 5150ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 5160ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_CT_OFFSET_R + i * 4, 5170ef7dc30SLaurent Pinchart arg->ct_offset[i]); 518e6938cc1SHelen Koike } 519e6938cc1SHelen Koike 520e6938cc1SHelen Koike static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en) 521e6938cc1SHelen Koike { 522e6938cc1SHelen Koike if (en) 523e6938cc1SHelen Koike return; 524e6938cc1SHelen Koike 525e6938cc1SHelen Koike /* Write back the default values. */ 5260ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_0, 0x80); 5270ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_1, 0); 5280ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_2, 0); 5290ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_3, 0); 5300ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_4, 0x80); 5310ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_5, 0); 5320ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_6, 0); 5330ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_7, 0); 5340ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_8, 0x80); 535e6938cc1SHelen Koike 5360ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_R, 0); 5370ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_G, 0); 5380ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_B, 0); 539e6938cc1SHelen Koike } 540e6938cc1SHelen Koike 541e6938cc1SHelen Koike /* ISP White Balance Mode */ 542dce8ccb2SHeiko Stuebner static void rkisp1_awb_meas_config_v10(struct rkisp1_params *params, 543e6938cc1SHelen Koike const struct rkisp1_cif_isp_awb_meas_config *arg) 544e6938cc1SHelen Koike { 545e6938cc1SHelen Koike u32 reg_val = 0; 546e6938cc1SHelen Koike /* based on the mode,configure the awb module */ 547e6938cc1SHelen Koike if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) { 548e6938cc1SHelen Koike /* Reference Cb and Cr */ 5490ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_REF_V10, 550e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) | 5510ef7dc30SLaurent Pinchart arg->awb_ref_cb); 552e6938cc1SHelen Koike /* Yc Threshold */ 5530ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_THRESH_V10, 554e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) | 555e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) | 556e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) | 5570ef7dc30SLaurent Pinchart arg->min_c); 558e6938cc1SHelen Koike } 559e6938cc1SHelen Koike 560dce8ccb2SHeiko Stuebner reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10); 561e6938cc1SHelen Koike if (arg->enable_ymax_cmp) 562e6938cc1SHelen Koike reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN; 563e6938cc1SHelen Koike else 564e6938cc1SHelen Koike reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN; 5650ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10, reg_val); 566e6938cc1SHelen Koike 567e6938cc1SHelen Koike /* window offset */ 5680ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_V_OFFS_V10, 5690ef7dc30SLaurent Pinchart arg->awb_wnd.v_offs); 5700ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_H_OFFS_V10, 5710ef7dc30SLaurent Pinchart arg->awb_wnd.h_offs); 572e6938cc1SHelen Koike /* AWB window size */ 5730ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_V_SIZE_V10, 5740ef7dc30SLaurent Pinchart arg->awb_wnd.v_size); 5750ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_H_SIZE_V10, 5760ef7dc30SLaurent Pinchart arg->awb_wnd.h_size); 577e6938cc1SHelen Koike /* Number of frames */ 5780ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_FRAMES_V10, 5790ef7dc30SLaurent Pinchart arg->frames); 580e6938cc1SHelen Koike } 581e6938cc1SHelen Koike 582cd42f802SHeiko Stuebner static void rkisp1_awb_meas_config_v12(struct rkisp1_params *params, 583cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_awb_meas_config *arg) 584cd42f802SHeiko Stuebner { 585cd42f802SHeiko Stuebner u32 reg_val = 0; 586cd42f802SHeiko Stuebner /* based on the mode,configure the awb module */ 587cd42f802SHeiko Stuebner if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) { 588cd42f802SHeiko Stuebner /* Reference Cb and Cr */ 5890ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_REF_V12, 590cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) | 5910ef7dc30SLaurent Pinchart arg->awb_ref_cb); 592cd42f802SHeiko Stuebner /* Yc Threshold */ 5930ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_THRESH_V12, 594cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) | 595cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) | 596cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) | 5970ef7dc30SLaurent Pinchart arg->min_c); 598cd42f802SHeiko Stuebner } 599cd42f802SHeiko Stuebner 600cd42f802SHeiko Stuebner reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12); 601cd42f802SHeiko Stuebner if (arg->enable_ymax_cmp) 602cd42f802SHeiko Stuebner reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN; 603cd42f802SHeiko Stuebner else 604cd42f802SHeiko Stuebner reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN; 605cd42f802SHeiko Stuebner reg_val &= ~RKISP1_CIF_ISP_AWB_SET_FRAMES_MASK_V12; 606cd42f802SHeiko Stuebner reg_val |= RKISP1_CIF_ISP_AWB_SET_FRAMES_V12(arg->frames); 6070ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12, reg_val); 608cd42f802SHeiko Stuebner 609cd42f802SHeiko Stuebner /* window offset */ 6100ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_OFFS_V12, 6110ef7dc30SLaurent Pinchart arg->awb_wnd.v_offs << 16 | arg->awb_wnd.h_offs); 612cd42f802SHeiko Stuebner /* AWB window size */ 6130ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_SIZE_V12, 6140ef7dc30SLaurent Pinchart arg->awb_wnd.v_size << 16 | arg->awb_wnd.h_size); 615cd42f802SHeiko Stuebner } 616cd42f802SHeiko Stuebner 617e6938cc1SHelen Koike static void 618dce8ccb2SHeiko Stuebner rkisp1_awb_meas_enable_v10(struct rkisp1_params *params, 619e6938cc1SHelen Koike const struct rkisp1_cif_isp_awb_meas_config *arg, 620e6938cc1SHelen Koike bool en) 621e6938cc1SHelen Koike { 622dce8ccb2SHeiko Stuebner u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10); 623e6938cc1SHelen Koike 624e6938cc1SHelen Koike /* switch off */ 625e6938cc1SHelen Koike reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE; 626e6938cc1SHelen Koike 627e6938cc1SHelen Koike if (en) { 628e6938cc1SHelen Koike if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB) 629e6938cc1SHelen Koike reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN; 630e6938cc1SHelen Koike else 631e6938cc1SHelen Koike reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN; 632e6938cc1SHelen Koike 6330ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10, 6340ef7dc30SLaurent Pinchart reg_val); 635e6938cc1SHelen Koike 636e6938cc1SHelen Koike /* Measurements require AWB block be active. */ 637e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 638e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 639e6938cc1SHelen Koike } else { 6400ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10, 6410ef7dc30SLaurent Pinchart reg_val); 642e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 643e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 644e6938cc1SHelen Koike } 645e6938cc1SHelen Koike } 646e6938cc1SHelen Koike 647e6938cc1SHelen Koike static void 648cd42f802SHeiko Stuebner rkisp1_awb_meas_enable_v12(struct rkisp1_params *params, 649cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_awb_meas_config *arg, 650cd42f802SHeiko Stuebner bool en) 651cd42f802SHeiko Stuebner { 652cd42f802SHeiko Stuebner u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12); 653cd42f802SHeiko Stuebner 654cd42f802SHeiko Stuebner /* switch off */ 655cd42f802SHeiko Stuebner reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE; 656cd42f802SHeiko Stuebner 657cd42f802SHeiko Stuebner if (en) { 658cd42f802SHeiko Stuebner if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB) 659cd42f802SHeiko Stuebner reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN; 660cd42f802SHeiko Stuebner else 661cd42f802SHeiko Stuebner reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN; 662cd42f802SHeiko Stuebner 6630ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12, 6640ef7dc30SLaurent Pinchart reg_val); 665cd42f802SHeiko Stuebner 666cd42f802SHeiko Stuebner /* Measurements require AWB block be active. */ 667cd42f802SHeiko Stuebner rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 668cd42f802SHeiko Stuebner RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 669cd42f802SHeiko Stuebner } else { 6700ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12, 6710ef7dc30SLaurent Pinchart reg_val); 672cd42f802SHeiko Stuebner rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 673cd42f802SHeiko Stuebner RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 674cd42f802SHeiko Stuebner } 675cd42f802SHeiko Stuebner } 676cd42f802SHeiko Stuebner 677cd42f802SHeiko Stuebner static void 678dce8ccb2SHeiko Stuebner rkisp1_awb_gain_config_v10(struct rkisp1_params *params, 679e6938cc1SHelen Koike const struct rkisp1_cif_isp_awb_gain_config *arg) 680e6938cc1SHelen Koike { 6810ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_G_V10, 682e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) | 6830ef7dc30SLaurent Pinchart arg->gain_green_b); 684e6938cc1SHelen Koike 6850ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_RB_V10, 686e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) | 6870ef7dc30SLaurent Pinchart arg->gain_blue); 688e6938cc1SHelen Koike } 689e6938cc1SHelen Koike 690cd42f802SHeiko Stuebner static void 691cd42f802SHeiko Stuebner rkisp1_awb_gain_config_v12(struct rkisp1_params *params, 692cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_awb_gain_config *arg) 693cd42f802SHeiko Stuebner { 6940ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_G_V12, 695cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) | 6960ef7dc30SLaurent Pinchart arg->gain_green_b); 697cd42f802SHeiko Stuebner 6980ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_RB_V12, 699cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) | 7000ef7dc30SLaurent Pinchart arg->gain_blue); 701cd42f802SHeiko Stuebner } 702cd42f802SHeiko Stuebner 703dce8ccb2SHeiko Stuebner static void rkisp1_aec_config_v10(struct rkisp1_params *params, 704e6938cc1SHelen Koike const struct rkisp1_cif_isp_aec_config *arg) 705e6938cc1SHelen Koike { 706e6938cc1SHelen Koike unsigned int block_hsize, block_vsize; 707e6938cc1SHelen Koike u32 exp_ctrl; 708e6938cc1SHelen Koike 709e6938cc1SHelen Koike /* avoid to override the old enable value */ 710e6938cc1SHelen Koike exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL); 711e6938cc1SHelen Koike exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA; 712e6938cc1SHelen Koike if (arg->autostop) 713e6938cc1SHelen Koike exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP; 714e6938cc1SHelen Koike if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1) 715e6938cc1SHelen Koike exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1; 7160ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL, exp_ctrl); 717e6938cc1SHelen Koike 7180ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_H_OFFSET_V10, 7190ef7dc30SLaurent Pinchart arg->meas_window.h_offs); 7200ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_V_OFFSET_V10, 7210ef7dc30SLaurent Pinchart arg->meas_window.v_offs); 722e6938cc1SHelen Koike 723e6938cc1SHelen Koike block_hsize = arg->meas_window.h_size / 724dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_EXP_COLUMN_NUM_V10 - 1; 725e6938cc1SHelen Koike block_vsize = arg->meas_window.v_size / 726dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_EXP_ROW_NUM_V10 - 1; 727e6938cc1SHelen Koike 7280ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_H_SIZE_V10, 7290ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_EXP_H_SIZE_SET_V10(block_hsize)); 7300ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_V_SIZE_V10, 7310ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_EXP_V_SIZE_SET_V10(block_vsize)); 732e6938cc1SHelen Koike } 733e6938cc1SHelen Koike 734cd42f802SHeiko Stuebner static void rkisp1_aec_config_v12(struct rkisp1_params *params, 735cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_aec_config *arg) 736cd42f802SHeiko Stuebner { 737cd42f802SHeiko Stuebner u32 exp_ctrl; 738cd42f802SHeiko Stuebner u32 block_hsize, block_vsize; 739cd42f802SHeiko Stuebner u32 wnd_num_idx = 1; 740a3fb9657SColin Ian King static const u32 ae_wnd_num[] = { 5, 9, 15, 15 }; 741cd42f802SHeiko Stuebner 742cd42f802SHeiko Stuebner /* avoid to override the old enable value */ 743cd42f802SHeiko Stuebner exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL); 744cd42f802SHeiko Stuebner exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA; 745cd42f802SHeiko Stuebner if (arg->autostop) 746cd42f802SHeiko Stuebner exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP; 747cd42f802SHeiko Stuebner if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1) 748cd42f802SHeiko Stuebner exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1; 749cd42f802SHeiko Stuebner exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_WNDNUM_SET_V12(wnd_num_idx); 7500ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL, exp_ctrl); 751cd42f802SHeiko Stuebner 7520ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_OFFS_V12, 753cd42f802SHeiko Stuebner RKISP1_CIF_ISP_EXP_V_OFFSET_SET_V12(arg->meas_window.v_offs) | 7540ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_EXP_H_OFFSET_SET_V12(arg->meas_window.h_offs)); 755cd42f802SHeiko Stuebner 756cd42f802SHeiko Stuebner block_hsize = arg->meas_window.h_size / ae_wnd_num[wnd_num_idx] - 1; 757cd42f802SHeiko Stuebner block_vsize = arg->meas_window.v_size / ae_wnd_num[wnd_num_idx] - 1; 758cd42f802SHeiko Stuebner 7590ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_SIZE_V12, 760cd42f802SHeiko Stuebner RKISP1_CIF_ISP_EXP_V_SIZE_SET_V12(block_vsize) | 7610ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_EXP_H_SIZE_SET_V12(block_hsize)); 762cd42f802SHeiko Stuebner } 763cd42f802SHeiko Stuebner 764e6938cc1SHelen Koike static void rkisp1_cproc_config(struct rkisp1_params *params, 765e6938cc1SHelen Koike const struct rkisp1_cif_isp_cproc_config *arg) 766e6938cc1SHelen Koike { 767e6938cc1SHelen Koike struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg = 768e6938cc1SHelen Koike container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config); 769e6938cc1SHelen Koike struct rkisp1_cif_isp_ie_config *cur_ie_config = 770e6938cc1SHelen Koike &cur_other_cfg->ie_config; 771e6938cc1SHelen Koike u32 effect = cur_ie_config->effect; 772e6938cc1SHelen Koike u32 quantization = params->quantization; 773e6938cc1SHelen Koike 7740ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_CONTRAST, 7750ef7dc30SLaurent Pinchart arg->contrast); 7760ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_HUE, arg->hue); 7770ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_SATURATION, arg->sat); 7780ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_BRIGHTNESS, 7790ef7dc30SLaurent Pinchart arg->brightness); 780e6938cc1SHelen Koike 781e6938cc1SHelen Koike if (quantization != V4L2_QUANTIZATION_FULL_RANGE || 782e6938cc1SHelen Koike effect != V4L2_COLORFX_NONE) { 783e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, 784e6938cc1SHelen Koike RKISP1_CIF_C_PROC_YOUT_FULL | 785e6938cc1SHelen Koike RKISP1_CIF_C_PROC_YIN_FULL | 786e6938cc1SHelen Koike RKISP1_CIF_C_PROC_COUT_FULL); 787e6938cc1SHelen Koike } else { 788e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL, 789e6938cc1SHelen Koike RKISP1_CIF_C_PROC_YOUT_FULL | 790e6938cc1SHelen Koike RKISP1_CIF_C_PROC_YIN_FULL | 791e6938cc1SHelen Koike RKISP1_CIF_C_PROC_COUT_FULL); 792e6938cc1SHelen Koike } 793e6938cc1SHelen Koike } 794e6938cc1SHelen Koike 795dce8ccb2SHeiko Stuebner static void rkisp1_hst_config_v10(struct rkisp1_params *params, 796e6938cc1SHelen Koike const struct rkisp1_cif_isp_hst_config *arg) 797e6938cc1SHelen Koike { 798e6938cc1SHelen Koike unsigned int block_hsize, block_vsize; 799e6938cc1SHelen Koike static const u32 hist_weight_regs[] = { 800dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_WEIGHT_00TO30_V10, 801dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_WEIGHT_40TO21_V10, 802dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_WEIGHT_31TO12_V10, 803dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_WEIGHT_22TO03_V10, 804dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_WEIGHT_13TO43_V10, 805dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_WEIGHT_04TO34_V10, 806e6938cc1SHelen Koike }; 807e6938cc1SHelen Koike const u8 *weight; 808e6938cc1SHelen Koike unsigned int i; 809e6938cc1SHelen Koike u32 hist_prop; 810e6938cc1SHelen Koike 811e6938cc1SHelen Koike /* avoid to override the old enable value */ 812dce8ccb2SHeiko Stuebner hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10); 813dce8ccb2SHeiko Stuebner hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10; 814dce8ccb2SHeiko Stuebner hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET_V10(arg->histogram_predivider); 8150ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10, hist_prop); 8160ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_H_OFFS_V10, 8170ef7dc30SLaurent Pinchart arg->meas_window.h_offs); 8180ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_V_OFFS_V10, 8190ef7dc30SLaurent Pinchart arg->meas_window.v_offs); 820e6938cc1SHelen Koike 821e6938cc1SHelen Koike block_hsize = arg->meas_window.h_size / 822dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_COLUMN_NUM_V10 - 1; 823dce8ccb2SHeiko Stuebner block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM_V10 - 1; 824e6938cc1SHelen Koike 8250ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_H_SIZE_V10, 8260ef7dc30SLaurent Pinchart block_hsize); 8270ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_V_SIZE_V10, 8280ef7dc30SLaurent Pinchart block_vsize); 829e6938cc1SHelen Koike 830e6938cc1SHelen Koike weight = arg->hist_weight; 831e6938cc1SHelen Koike for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4) 8320ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, hist_weight_regs[i], 8330ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_HIST_WEIGHT_SET_V10(weight[0], weight[1], 8340ef7dc30SLaurent Pinchart weight[2], weight[3])); 83566d81de7SHeiko Stuebner 8360ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_WEIGHT_44_V10, 837cde4e515SLaurent Pinchart weight[0] & 0x1f); 838e6938cc1SHelen Koike } 839e6938cc1SHelen Koike 840cd42f802SHeiko Stuebner static void rkisp1_hst_config_v12(struct rkisp1_params *params, 841cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_hst_config *arg) 842cd42f802SHeiko Stuebner { 843cd42f802SHeiko Stuebner unsigned int i, j; 844cd42f802SHeiko Stuebner u32 block_hsize, block_vsize; 845cd42f802SHeiko Stuebner u32 wnd_num_idx, hist_weight_num, hist_ctrl, value; 846cd42f802SHeiko Stuebner u8 weight15x15[RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12]; 847a3fb9657SColin Ian King static const u32 hist_wnd_num[] = { 5, 9, 15, 15 }; 848cd42f802SHeiko Stuebner 849cd42f802SHeiko Stuebner /* now we just support 9x9 window */ 850cd42f802SHeiko Stuebner wnd_num_idx = 1; 851cd42f802SHeiko Stuebner memset(weight15x15, 0x00, sizeof(weight15x15)); 852cd42f802SHeiko Stuebner /* avoid to override the old enable value */ 853cd42f802SHeiko Stuebner hist_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12); 854cd42f802SHeiko Stuebner hist_ctrl &= RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 | 855cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12; 856cd42f802SHeiko Stuebner hist_ctrl = hist_ctrl | 857cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_INTRSEL_SET_V12(1) | 858cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_DATASEL_SET_V12(0) | 859cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_WATERLINE_SET_V12(0) | 860cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_AUTOSTOP_SET_V12(0) | 861cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_WNDNUM_SET_V12(1) | 862cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_STEPSIZE_SET_V12(arg->histogram_predivider); 8630ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12, hist_ctrl); 864cd42f802SHeiko Stuebner 8650ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_OFFS_V12, 866cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_OFFS_SET_V12(arg->meas_window.h_offs, 8670ef7dc30SLaurent Pinchart arg->meas_window.v_offs)); 868cd42f802SHeiko Stuebner 869cd42f802SHeiko Stuebner block_hsize = arg->meas_window.h_size / hist_wnd_num[wnd_num_idx] - 1; 870cd42f802SHeiko Stuebner block_vsize = arg->meas_window.v_size / hist_wnd_num[wnd_num_idx] - 1; 8710ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_SIZE_V12, 8720ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_HIST_SIZE_SET_V12(block_hsize, block_vsize)); 873cd42f802SHeiko Stuebner 874cd42f802SHeiko Stuebner for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) { 875cd42f802SHeiko Stuebner for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) { 876cd42f802SHeiko Stuebner weight15x15[i * RKISP1_CIF_ISP_HIST_ROW_NUM_V12 + j] = 877cd42f802SHeiko Stuebner arg->hist_weight[i * hist_wnd_num[wnd_num_idx] + j]; 878cd42f802SHeiko Stuebner } 879cd42f802SHeiko Stuebner } 880cd42f802SHeiko Stuebner 881cd42f802SHeiko Stuebner hist_weight_num = RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12; 882cd42f802SHeiko Stuebner for (i = 0; i < (hist_weight_num / 4); i++) { 883cd42f802SHeiko Stuebner value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12( 884cd42f802SHeiko Stuebner weight15x15[4 * i + 0], 885cd42f802SHeiko Stuebner weight15x15[4 * i + 1], 886cd42f802SHeiko Stuebner weight15x15[4 * i + 2], 887cd42f802SHeiko Stuebner weight15x15[4 * i + 3]); 8880ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 8890ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i, value); 890cd42f802SHeiko Stuebner } 891cd42f802SHeiko Stuebner value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(weight15x15[4 * i + 0], 0, 0, 0); 8920ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i, 8930ef7dc30SLaurent Pinchart value); 894cd42f802SHeiko Stuebner } 895cd42f802SHeiko Stuebner 896e6938cc1SHelen Koike static void 897dce8ccb2SHeiko Stuebner rkisp1_hst_enable_v10(struct rkisp1_params *params, 898e6938cc1SHelen Koike const struct rkisp1_cif_isp_hst_config *arg, bool en) 899e6938cc1SHelen Koike { 900e6938cc1SHelen Koike if (en) { 901e6938cc1SHelen Koike u32 hist_prop = rkisp1_read(params->rkisp1, 902dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_PROP_V10); 903e6938cc1SHelen Koike 904dce8ccb2SHeiko Stuebner hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10; 905e6938cc1SHelen Koike hist_prop |= arg->mode; 906dce8ccb2SHeiko Stuebner rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10, 907e6938cc1SHelen Koike hist_prop); 908e6938cc1SHelen Koike } else { 909dce8ccb2SHeiko Stuebner rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10, 910dce8ccb2SHeiko Stuebner RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10); 911e6938cc1SHelen Koike } 912e6938cc1SHelen Koike } 913e6938cc1SHelen Koike 914cd42f802SHeiko Stuebner static void 915cd42f802SHeiko Stuebner rkisp1_hst_enable_v12(struct rkisp1_params *params, 916cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_hst_config *arg, bool en) 917cd42f802SHeiko Stuebner { 918cd42f802SHeiko Stuebner if (en) { 919cd42f802SHeiko Stuebner u32 hist_ctrl = rkisp1_read(params->rkisp1, 920cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_V12); 921cd42f802SHeiko Stuebner 922cd42f802SHeiko Stuebner hist_ctrl &= ~RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12; 923cd42f802SHeiko Stuebner hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_MODE_SET_V12(arg->mode); 924cd42f802SHeiko Stuebner hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_EN_SET_V12(1); 925cd42f802SHeiko Stuebner rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12, 926cd42f802SHeiko Stuebner hist_ctrl); 927cd42f802SHeiko Stuebner } else { 928cd42f802SHeiko Stuebner rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12, 929cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 | 930cd42f802SHeiko Stuebner RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12); 931cd42f802SHeiko Stuebner } 932cd42f802SHeiko Stuebner } 933cd42f802SHeiko Stuebner 934dce8ccb2SHeiko Stuebner static void rkisp1_afm_config_v10(struct rkisp1_params *params, 935e6938cc1SHelen Koike const struct rkisp1_cif_isp_afc_config *arg) 936e6938cc1SHelen Koike { 937e6938cc1SHelen Koike size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win), 938e6938cc1SHelen Koike arg->num_afm_win); 939e6938cc1SHelen Koike u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL); 940e6938cc1SHelen Koike unsigned int i; 941e6938cc1SHelen Koike 942e6938cc1SHelen Koike /* Switch off to configure. */ 943e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 944e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_ENA); 945e6938cc1SHelen Koike 946e6938cc1SHelen Koike for (i = 0; i < num_of_win; i++) { 9470ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_LT_A + i * 8, 948e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) | 9490ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs)); 9500ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_RB_A + i * 8, 951e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size + 952e6938cc1SHelen Koike arg->afm_win[i].h_offs) | 953e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size + 9540ef7dc30SLaurent Pinchart arg->afm_win[i].v_offs)); 955e6938cc1SHelen Koike } 9560ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_THRES, arg->thres); 9570ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_VAR_SHIFT, 9580ef7dc30SLaurent Pinchart arg->var_shift); 959e6938cc1SHelen Koike /* restore afm status */ 9600ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL, afm_ctrl); 961e6938cc1SHelen Koike } 962e6938cc1SHelen Koike 963cd42f802SHeiko Stuebner static void rkisp1_afm_config_v12(struct rkisp1_params *params, 964cd42f802SHeiko Stuebner const struct rkisp1_cif_isp_afc_config *arg) 965cd42f802SHeiko Stuebner { 966cd42f802SHeiko Stuebner size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win), 967cd42f802SHeiko Stuebner arg->num_afm_win); 968cd42f802SHeiko Stuebner u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL); 969cd42f802SHeiko Stuebner u32 lum_var_shift, afm_var_shift; 970cd42f802SHeiko Stuebner unsigned int i; 971cd42f802SHeiko Stuebner 972cd42f802SHeiko Stuebner /* Switch off to configure. */ 973cd42f802SHeiko Stuebner rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 974cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AFM_ENA); 975cd42f802SHeiko Stuebner 976cd42f802SHeiko Stuebner for (i = 0; i < num_of_win; i++) { 9770ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_LT_A + i * 8, 978cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) | 9790ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs)); 9800ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_RB_A + i * 8, 981cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size + 982cd42f802SHeiko Stuebner arg->afm_win[i].h_offs) | 983cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size + 9840ef7dc30SLaurent Pinchart arg->afm_win[i].v_offs)); 985cd42f802SHeiko Stuebner } 9860ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_THRES, arg->thres); 987cd42f802SHeiko Stuebner 988cd42f802SHeiko Stuebner lum_var_shift = RKISP1_CIF_ISP_AFM_GET_LUM_SHIFT_a_V12(arg->var_shift); 989cd42f802SHeiko Stuebner afm_var_shift = RKISP1_CIF_ISP_AFM_GET_AFM_SHIFT_a_V12(arg->var_shift); 9900ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_VAR_SHIFT, 991cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AFM_SET_SHIFT_a_V12(lum_var_shift, afm_var_shift) | 992cd42f802SHeiko Stuebner RKISP1_CIF_ISP_AFM_SET_SHIFT_b_V12(lum_var_shift, afm_var_shift) | 9930ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_AFM_SET_SHIFT_c_V12(lum_var_shift, afm_var_shift)); 994cd42f802SHeiko Stuebner 995cd42f802SHeiko Stuebner /* restore afm status */ 9960ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL, afm_ctrl); 997cd42f802SHeiko Stuebner } 998cd42f802SHeiko Stuebner 999e6938cc1SHelen Koike static void rkisp1_ie_config(struct rkisp1_params *params, 1000e6938cc1SHelen Koike const struct rkisp1_cif_isp_ie_config *arg) 1001e6938cc1SHelen Koike { 1002e6938cc1SHelen Koike u32 eff_ctrl; 1003e6938cc1SHelen Koike 1004e6938cc1SHelen Koike eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL); 1005e6938cc1SHelen Koike eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK; 1006e6938cc1SHelen Koike 1007e6938cc1SHelen Koike if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) 1008e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL; 1009e6938cc1SHelen Koike 1010e6938cc1SHelen Koike switch (arg->effect) { 1011e6938cc1SHelen Koike case V4L2_COLORFX_SEPIA: 1012e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA; 1013e6938cc1SHelen Koike break; 1014e6938cc1SHelen Koike case V4L2_COLORFX_SET_CBCR: 10150ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_TINT, 10160ef7dc30SLaurent Pinchart arg->eff_tint); 1017e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA; 1018e6938cc1SHelen Koike break; 1019e6938cc1SHelen Koike /* 1020e6938cc1SHelen Koike * Color selection is similar to water color(AQUA): 1021e6938cc1SHelen Koike * grayscale + selected color w threshold 1022e6938cc1SHelen Koike */ 1023e6938cc1SHelen Koike case V4L2_COLORFX_AQUA: 1024e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL; 10250ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_COLOR_SEL, 10260ef7dc30SLaurent Pinchart arg->color_sel); 1027e6938cc1SHelen Koike break; 1028e6938cc1SHelen Koike case V4L2_COLORFX_EMBOSS: 1029e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS; 10300ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_1, 10310ef7dc30SLaurent Pinchart arg->eff_mat_1); 10320ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_2, 10330ef7dc30SLaurent Pinchart arg->eff_mat_2); 10340ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_3, 10350ef7dc30SLaurent Pinchart arg->eff_mat_3); 1036e6938cc1SHelen Koike break; 1037e6938cc1SHelen Koike case V4L2_COLORFX_SKETCH: 1038e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH; 10390ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_3, 10400ef7dc30SLaurent Pinchart arg->eff_mat_3); 10410ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_4, 10420ef7dc30SLaurent Pinchart arg->eff_mat_4); 10430ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_5, 10440ef7dc30SLaurent Pinchart arg->eff_mat_5); 1045e6938cc1SHelen Koike break; 1046e6938cc1SHelen Koike case V4L2_COLORFX_BW: 1047e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE; 1048e6938cc1SHelen Koike break; 1049e6938cc1SHelen Koike case V4L2_COLORFX_NEGATIVE: 1050e6938cc1SHelen Koike eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE; 1051e6938cc1SHelen Koike break; 1052e6938cc1SHelen Koike default: 1053e6938cc1SHelen Koike break; 1054e6938cc1SHelen Koike } 1055e6938cc1SHelen Koike 10560ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL, eff_ctrl); 1057e6938cc1SHelen Koike } 1058e6938cc1SHelen Koike 1059e6938cc1SHelen Koike static void rkisp1_ie_enable(struct rkisp1_params *params, bool en) 1060e6938cc1SHelen Koike { 1061e6938cc1SHelen Koike if (en) { 10623b430c2cSLaurent Pinchart rkisp1_param_set_bits(params, RKISP1_CIF_VI_ICCL, 10633b430c2cSLaurent Pinchart RKISP1_CIF_VI_ICCL_IE_CLK); 10640ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL, 10650ef7dc30SLaurent Pinchart RKISP1_CIF_IMG_EFF_CTRL_ENABLE); 1066e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL, 1067e6938cc1SHelen Koike RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD); 1068e6938cc1SHelen Koike } else { 1069e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL, 1070e6938cc1SHelen Koike RKISP1_CIF_IMG_EFF_CTRL_ENABLE); 10713b430c2cSLaurent Pinchart rkisp1_param_clear_bits(params, RKISP1_CIF_VI_ICCL, 10723b430c2cSLaurent Pinchart RKISP1_CIF_VI_ICCL_IE_CLK); 1073e6938cc1SHelen Koike } 1074e6938cc1SHelen Koike } 1075e6938cc1SHelen Koike 1076711d9149SLaurent Pinchart static void rkisp1_csm_config(struct rkisp1_params *params) 1077e6938cc1SHelen Koike { 1078f7aa2d23SLaurent Pinchart struct csm_coeffs { 1079f7aa2d23SLaurent Pinchart u16 limited[9]; 1080f7aa2d23SLaurent Pinchart u16 full[9]; 1081e6938cc1SHelen Koike }; 1082f7aa2d23SLaurent Pinchart static const struct csm_coeffs rec601_coeffs = { 1083f7aa2d23SLaurent Pinchart .limited = { 1084f7aa2d23SLaurent Pinchart 0x0021, 0x0042, 0x000d, 1085e6938cc1SHelen Koike 0x01ed, 0x01db, 0x0038, 1086e6938cc1SHelen Koike 0x0038, 0x01d1, 0x01f7, 1087f7aa2d23SLaurent Pinchart }, 1088f7aa2d23SLaurent Pinchart .full = { 1089f7aa2d23SLaurent Pinchart 0x0026, 0x004b, 0x000f, 1090f7aa2d23SLaurent Pinchart 0x01ea, 0x01d6, 0x0040, 1091f7aa2d23SLaurent Pinchart 0x0040, 0x01ca, 0x01f6, 1092f7aa2d23SLaurent Pinchart }, 1093e6938cc1SHelen Koike }; 1094f7aa2d23SLaurent Pinchart static const struct csm_coeffs rec709_coeffs = { 1095f7aa2d23SLaurent Pinchart .limited = { 1096f7aa2d23SLaurent Pinchart 0x0018, 0x0050, 0x0008, 1097f7aa2d23SLaurent Pinchart 0x01f3, 0x01d5, 0x0038, 1098f7aa2d23SLaurent Pinchart 0x0038, 0x01cd, 0x01fb, 1099f7aa2d23SLaurent Pinchart }, 1100f7aa2d23SLaurent Pinchart .full = { 1101f7aa2d23SLaurent Pinchart 0x001b, 0x005c, 0x0009, 1102f7aa2d23SLaurent Pinchart 0x01f1, 0x01cf, 0x0040, 1103f7aa2d23SLaurent Pinchart 0x0040, 0x01c6, 0x01fa, 1104f7aa2d23SLaurent Pinchart }, 1105f7aa2d23SLaurent Pinchart }; 1106f7aa2d23SLaurent Pinchart static const struct csm_coeffs rec2020_coeffs = { 1107f7aa2d23SLaurent Pinchart .limited = { 1108f7aa2d23SLaurent Pinchart 0x001d, 0x004c, 0x0007, 1109f7aa2d23SLaurent Pinchart 0x01f0, 0x01d8, 0x0038, 1110f7aa2d23SLaurent Pinchart 0x0038, 0x01cd, 0x01fb, 1111f7aa2d23SLaurent Pinchart }, 1112f7aa2d23SLaurent Pinchart .full = { 1113f7aa2d23SLaurent Pinchart 0x0022, 0x0057, 0x0008, 1114f7aa2d23SLaurent Pinchart 0x01ee, 0x01d2, 0x0040, 1115f7aa2d23SLaurent Pinchart 0x0040, 0x01c5, 0x01fb, 1116f7aa2d23SLaurent Pinchart }, 1117f7aa2d23SLaurent Pinchart }; 1118f7aa2d23SLaurent Pinchart static const struct csm_coeffs smpte240m_coeffs = { 1119f7aa2d23SLaurent Pinchart .limited = { 1120f7aa2d23SLaurent Pinchart 0x0018, 0x004f, 0x000a, 1121f7aa2d23SLaurent Pinchart 0x01f3, 0x01d5, 0x0038, 1122f7aa2d23SLaurent Pinchart 0x0038, 0x01ce, 0x01fa, 1123f7aa2d23SLaurent Pinchart }, 1124f7aa2d23SLaurent Pinchart .full = { 1125f7aa2d23SLaurent Pinchart 0x001b, 0x005a, 0x000b, 1126f7aa2d23SLaurent Pinchart 0x01f1, 0x01cf, 0x0040, 1127f7aa2d23SLaurent Pinchart 0x0040, 0x01c7, 0x01f9, 1128f7aa2d23SLaurent Pinchart }, 1129f7aa2d23SLaurent Pinchart }; 1130f7aa2d23SLaurent Pinchart 1131f7aa2d23SLaurent Pinchart const struct csm_coeffs *coeffs; 1132f7aa2d23SLaurent Pinchart const u16 *csm; 1133e6938cc1SHelen Koike unsigned int i; 1134e6938cc1SHelen Koike 1135f7aa2d23SLaurent Pinchart switch (params->ycbcr_encoding) { 1136f7aa2d23SLaurent Pinchart case V4L2_YCBCR_ENC_601: 1137f7aa2d23SLaurent Pinchart default: 1138f7aa2d23SLaurent Pinchart coeffs = &rec601_coeffs; 1139f7aa2d23SLaurent Pinchart break; 1140f7aa2d23SLaurent Pinchart case V4L2_YCBCR_ENC_709: 1141f7aa2d23SLaurent Pinchart coeffs = &rec709_coeffs; 1142f7aa2d23SLaurent Pinchart break; 1143f7aa2d23SLaurent Pinchart case V4L2_YCBCR_ENC_BT2020: 1144f7aa2d23SLaurent Pinchart coeffs = &rec2020_coeffs; 1145f7aa2d23SLaurent Pinchart break; 1146f7aa2d23SLaurent Pinchart case V4L2_YCBCR_ENC_SMPTE240M: 1147f7aa2d23SLaurent Pinchart coeffs = &smpte240m_coeffs; 1148f7aa2d23SLaurent Pinchart break; 1149f7aa2d23SLaurent Pinchart } 1150e6938cc1SHelen Koike 1151f7aa2d23SLaurent Pinchart if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) { 1152f7aa2d23SLaurent Pinchart csm = coeffs->full; 1153e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1154e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | 1155e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); 1156e6938cc1SHelen Koike } else { 1157f7aa2d23SLaurent Pinchart csm = coeffs->limited; 1158e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 1159e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | 1160e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); 1161e6938cc1SHelen Koike } 1162f7aa2d23SLaurent Pinchart 1163f7aa2d23SLaurent Pinchart for (i = 0; i < 9; i++) 1164f7aa2d23SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CC_COEFF_0 + i * 4, 1165f7aa2d23SLaurent Pinchart csm[i]); 1166e6938cc1SHelen Koike } 1167e6938cc1SHelen Koike 1168e6938cc1SHelen Koike /* ISP De-noise Pre-Filter(DPF) function */ 1169e6938cc1SHelen Koike static void rkisp1_dpf_config(struct rkisp1_params *params, 1170e6938cc1SHelen Koike const struct rkisp1_cif_isp_dpf_config *arg) 1171e6938cc1SHelen Koike { 1172e6938cc1SHelen Koike unsigned int isp_dpf_mode, spatial_coeff, i; 1173e6938cc1SHelen Koike 1174e6938cc1SHelen Koike switch (arg->gain.mode) { 1175e6938cc1SHelen Koike case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS: 1176e6938cc1SHelen Koike isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN | 1177e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP; 1178e6938cc1SHelen Koike break; 1179e6938cc1SHelen Koike case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS: 1180e6938cc1SHelen Koike isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP; 1181e6938cc1SHelen Koike break; 1182e6938cc1SHelen Koike case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS: 1183e6938cc1SHelen Koike isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN | 1184e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP | 1185e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP; 1186e6938cc1SHelen Koike break; 1187e6938cc1SHelen Koike case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS: 1188e6938cc1SHelen Koike isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP; 1189e6938cc1SHelen Koike break; 1190e6938cc1SHelen Koike case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: 1191e6938cc1SHelen Koike isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP | 1192e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP; 1193e6938cc1SHelen Koike break; 1194e6938cc1SHelen Koike case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED: 1195e6938cc1SHelen Koike default: 1196e6938cc1SHelen Koike isp_dpf_mode = 0; 1197e6938cc1SHelen Koike break; 1198e6938cc1SHelen Koike } 1199e6938cc1SHelen Koike 1200e6938cc1SHelen Koike if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC) 1201e6938cc1SHelen Koike isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION; 1202e6938cc1SHelen Koike if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9) 1203e6938cc1SHelen Koike isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9; 1204e6938cc1SHelen Koike if (!arg->rb_flt.r_enable) 1205e6938cc1SHelen Koike isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS; 1206e6938cc1SHelen Koike if (!arg->rb_flt.b_enable) 1207e6938cc1SHelen Koike isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS; 1208e6938cc1SHelen Koike if (!arg->g_flt.gb_enable) 1209e6938cc1SHelen Koike isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS; 1210e6938cc1SHelen Koike if (!arg->g_flt.gr_enable) 1211e6938cc1SHelen Koike isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS; 1212e6938cc1SHelen Koike 1213e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE, 1214e6938cc1SHelen Koike isp_dpf_mode); 12150ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_B, 12160ef7dc30SLaurent Pinchart arg->gain.nf_b_gain); 12170ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_R, 12180ef7dc30SLaurent Pinchart arg->gain.nf_r_gain); 12190ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_GB, 12200ef7dc30SLaurent Pinchart arg->gain.nf_gb_gain); 12210ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_GR, 12220ef7dc30SLaurent Pinchart arg->gain.nf_gr_gain); 1223e6938cc1SHelen Koike 1224e6938cc1SHelen Koike for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) { 12250ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, 12260ef7dc30SLaurent Pinchart RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4, 12270ef7dc30SLaurent Pinchart arg->nll.coeff[i]); 1228e6938cc1SHelen Koike } 1229e6938cc1SHelen Koike 1230e6938cc1SHelen Koike spatial_coeff = arg->g_flt.spatial_coeff[0] | 1231e6938cc1SHelen Koike (arg->g_flt.spatial_coeff[1] << 8) | 1232e6938cc1SHelen Koike (arg->g_flt.spatial_coeff[2] << 16) | 1233e6938cc1SHelen Koike (arg->g_flt.spatial_coeff[3] << 24); 12340ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4, 12350ef7dc30SLaurent Pinchart spatial_coeff); 1236e6938cc1SHelen Koike 1237e6938cc1SHelen Koike spatial_coeff = arg->g_flt.spatial_coeff[4] | 1238e6938cc1SHelen Koike (arg->g_flt.spatial_coeff[5] << 8); 12390ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6, 12400ef7dc30SLaurent Pinchart spatial_coeff); 1241e6938cc1SHelen Koike 1242e6938cc1SHelen Koike spatial_coeff = arg->rb_flt.spatial_coeff[0] | 1243e6938cc1SHelen Koike (arg->rb_flt.spatial_coeff[1] << 8) | 1244e6938cc1SHelen Koike (arg->rb_flt.spatial_coeff[2] << 16) | 1245e6938cc1SHelen Koike (arg->rb_flt.spatial_coeff[3] << 24); 12460ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4, 12470ef7dc30SLaurent Pinchart spatial_coeff); 1248e6938cc1SHelen Koike 1249e6938cc1SHelen Koike spatial_coeff = arg->rb_flt.spatial_coeff[4] | 1250e6938cc1SHelen Koike (arg->rb_flt.spatial_coeff[5] << 8); 12510ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6, 12520ef7dc30SLaurent Pinchart spatial_coeff); 1253e6938cc1SHelen Koike } 1254e6938cc1SHelen Koike 1255e6938cc1SHelen Koike static void 1256e6938cc1SHelen Koike rkisp1_dpf_strength_config(struct rkisp1_params *params, 1257e6938cc1SHelen Koike const struct rkisp1_cif_isp_dpf_strength_config *arg) 1258e6938cc1SHelen Koike { 12590ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_B, arg->b); 12600ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_G, arg->g); 12610ef7dc30SLaurent Pinchart rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_R, arg->r); 1262e6938cc1SHelen Koike } 1263e6938cc1SHelen Koike 1264*ac79beb9SPaul Elder static void rkisp1_compand_write_px_curve(struct rkisp1_params *params, 1265*ac79beb9SPaul Elder unsigned int addr, const u8 *curve) 1266*ac79beb9SPaul Elder { 1267*ac79beb9SPaul Elder const unsigned int points_per_reg = 6; 1268*ac79beb9SPaul Elder const unsigned int num_regs = 1269*ac79beb9SPaul Elder DIV_ROUND_UP(RKISP1_CIF_ISP_COMPAND_NUM_POINTS, 1270*ac79beb9SPaul Elder points_per_reg); 1271*ac79beb9SPaul Elder 1272*ac79beb9SPaul Elder /* 1273*ac79beb9SPaul Elder * The compand curve is specified as a piecewise linear function with 1274*ac79beb9SPaul Elder * 64 points. X coordinates are stored as a log2 of the displacement 1275*ac79beb9SPaul Elder * from the previous point, in 5 bits, with 6 values per register. The 1276*ac79beb9SPaul Elder * last register stores 4 values. 1277*ac79beb9SPaul Elder */ 1278*ac79beb9SPaul Elder for (unsigned int reg = 0; reg < num_regs; ++reg) { 1279*ac79beb9SPaul Elder unsigned int num_points = 1280*ac79beb9SPaul Elder min(RKISP1_CIF_ISP_COMPAND_NUM_POINTS - 1281*ac79beb9SPaul Elder reg * points_per_reg, points_per_reg); 1282*ac79beb9SPaul Elder u32 val = 0; 1283*ac79beb9SPaul Elder 1284*ac79beb9SPaul Elder for (unsigned int i = 0; i < num_points; i++) 1285*ac79beb9SPaul Elder val |= (*curve++ & 0x1f) << (i * 5); 1286*ac79beb9SPaul Elder 1287*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, addr, val); 1288*ac79beb9SPaul Elder addr += 4; 1289*ac79beb9SPaul Elder } 1290*ac79beb9SPaul Elder } 1291*ac79beb9SPaul Elder 1292*ac79beb9SPaul Elder static void 1293*ac79beb9SPaul Elder rkisp1_compand_write_curve_mem(struct rkisp1_params *params, 1294*ac79beb9SPaul Elder unsigned int reg_addr, unsigned int reg_data, 1295*ac79beb9SPaul Elder const u32 curve[RKISP1_CIF_ISP_COMPAND_NUM_POINTS]) 1296*ac79beb9SPaul Elder { 1297*ac79beb9SPaul Elder for (unsigned int i = 0; i < RKISP1_CIF_ISP_COMPAND_NUM_POINTS; i++) { 1298*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, reg_addr, i); 1299*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, reg_data, curve[i]); 1300*ac79beb9SPaul Elder } 1301*ac79beb9SPaul Elder } 1302*ac79beb9SPaul Elder 1303*ac79beb9SPaul Elder static void 1304*ac79beb9SPaul Elder rkisp1_compand_bls_config(struct rkisp1_params *params, 1305*ac79beb9SPaul Elder const struct rkisp1_cif_isp_compand_bls_config *arg) 1306*ac79beb9SPaul Elder { 1307*ac79beb9SPaul Elder static const u32 regs[] = { 1308*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_BLS_A_FIXED, 1309*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_BLS_B_FIXED, 1310*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_BLS_C_FIXED, 1311*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_BLS_D_FIXED, 1312*ac79beb9SPaul Elder }; 1313*ac79beb9SPaul Elder u32 swapped[4]; 1314*ac79beb9SPaul Elder 1315*ac79beb9SPaul Elder rkisp1_bls_swap_regs(params->raw_type, regs, swapped); 1316*ac79beb9SPaul Elder 1317*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, swapped[0], arg->r); 1318*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, swapped[1], arg->gr); 1319*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, swapped[2], arg->gb); 1320*ac79beb9SPaul Elder rkisp1_write(params->rkisp1, swapped[3], arg->b); 1321*ac79beb9SPaul Elder } 1322*ac79beb9SPaul Elder 1323*ac79beb9SPaul Elder static void 1324*ac79beb9SPaul Elder rkisp1_compand_expand_config(struct rkisp1_params *params, 1325*ac79beb9SPaul Elder const struct rkisp1_cif_isp_compand_curve_config *arg) 1326*ac79beb9SPaul Elder { 1327*ac79beb9SPaul Elder rkisp1_compand_write_px_curve(params, RKISP1_CIF_ISP_COMPAND_EXPAND_PX_N(0), 1328*ac79beb9SPaul Elder arg->px); 1329*ac79beb9SPaul Elder rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_EXPAND_Y_ADDR, 1330*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_EXPAND_Y_WRITE_DATA, 1331*ac79beb9SPaul Elder arg->y); 1332*ac79beb9SPaul Elder rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_EXPAND_X_ADDR, 1333*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_EXPAND_X_WRITE_DATA, 1334*ac79beb9SPaul Elder arg->x); 1335*ac79beb9SPaul Elder } 1336*ac79beb9SPaul Elder 1337*ac79beb9SPaul Elder static void 1338*ac79beb9SPaul Elder rkisp1_compand_compress_config(struct rkisp1_params *params, 1339*ac79beb9SPaul Elder const struct rkisp1_cif_isp_compand_curve_config *arg) 1340*ac79beb9SPaul Elder { 1341*ac79beb9SPaul Elder rkisp1_compand_write_px_curve(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_PX_N(0), 1342*ac79beb9SPaul Elder arg->px); 1343*ac79beb9SPaul Elder rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_ADDR, 1344*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_WRITE_DATA, 1345*ac79beb9SPaul Elder arg->y); 1346*ac79beb9SPaul Elder rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_X_ADDR, 1347*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_COMPRESS_X_WRITE_DATA, 1348*ac79beb9SPaul Elder arg->x); 1349*ac79beb9SPaul Elder } 1350*ac79beb9SPaul Elder 1351e6938cc1SHelen Koike static void 1352e6938cc1SHelen Koike rkisp1_isp_isr_other_config(struct rkisp1_params *params, 1353e6938cc1SHelen Koike const struct rkisp1_params_cfg *new_params) 1354e6938cc1SHelen Koike { 1355e6938cc1SHelen Koike unsigned int module_en_update, module_cfg_update, module_ens; 1356e6938cc1SHelen Koike 1357e6938cc1SHelen Koike module_en_update = new_params->module_en_update; 1358e6938cc1SHelen Koike module_cfg_update = new_params->module_cfg_update; 1359e6938cc1SHelen Koike module_ens = new_params->module_ens; 1360e6938cc1SHelen Koike 136174a18d02SPaul Elder if (!rkisp1_has_feature(params->rkisp1, BLS)) { 136274a18d02SPaul Elder module_en_update &= ~RKISP1_CIF_ISP_MODULE_BLS; 136374a18d02SPaul Elder module_cfg_update &= ~RKISP1_CIF_ISP_MODULE_BLS; 136474a18d02SPaul Elder module_ens &= ~RKISP1_CIF_ISP_MODULE_BLS; 136574a18d02SPaul Elder } 136674a18d02SPaul Elder 1367e6938cc1SHelen Koike /* update dpc config */ 1368e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC) 1369e6938cc1SHelen Koike rkisp1_dpcc_config(params, 1370e6938cc1SHelen Koike &new_params->others.dpcc_config); 1371e6938cc1SHelen Koike 1372e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) { 1373e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC) 1374e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1375e6938cc1SHelen Koike RKISP1_CIF_ISP_DPCC_MODE, 13769daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1377e6938cc1SHelen Koike else 1378e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1379e6938cc1SHelen Koike RKISP1_CIF_ISP_DPCC_MODE, 13809daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1381e6938cc1SHelen Koike } 1382e6938cc1SHelen Koike 1383e6938cc1SHelen Koike /* update bls config */ 1384e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS) 1385e6938cc1SHelen Koike rkisp1_bls_config(params, 1386e6938cc1SHelen Koike &new_params->others.bls_config); 1387e6938cc1SHelen Koike 1388e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) { 1389e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_BLS) 1390e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1391e6938cc1SHelen Koike RKISP1_CIF_ISP_BLS_CTRL, 1392e6938cc1SHelen Koike RKISP1_CIF_ISP_BLS_ENA); 1393e6938cc1SHelen Koike else 1394e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1395e6938cc1SHelen Koike RKISP1_CIF_ISP_BLS_CTRL, 1396e6938cc1SHelen Koike RKISP1_CIF_ISP_BLS_ENA); 1397e6938cc1SHelen Koike } 1398e6938cc1SHelen Koike 1399e6938cc1SHelen Koike /* update sdg config */ 1400e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG) 1401e6938cc1SHelen Koike rkisp1_sdg_config(params, 1402e6938cc1SHelen Koike &new_params->others.sdg_config); 1403e6938cc1SHelen Koike 1404e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) { 1405e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_SDG) 1406e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1407e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL, 1408e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 1409e6938cc1SHelen Koike else 1410e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1411e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL, 1412e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 1413e6938cc1SHelen Koike } 1414e6938cc1SHelen Koike 1415e6938cc1SHelen Koike /* update awb gains */ 1416e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) 14175e8d9d72SHeiko Stuebner params->ops->awb_gain_config(params, &new_params->others.awb_gain_config); 1418e6938cc1SHelen Koike 1419e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) { 1420e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN) 1421e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1422e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL, 1423e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 1424e6938cc1SHelen Koike else 1425e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1426e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL, 1427e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 1428e6938cc1SHelen Koike } 1429e6938cc1SHelen Koike 1430e6938cc1SHelen Koike /* update bdm config */ 1431e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM) 1432e6938cc1SHelen Koike rkisp1_bdm_config(params, 1433e6938cc1SHelen Koike &new_params->others.bdm_config); 1434e6938cc1SHelen Koike 1435e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) { 1436e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_BDM) 1437e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1438e6938cc1SHelen Koike RKISP1_CIF_ISP_DEMOSAIC, 1439e6938cc1SHelen Koike RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 1440e6938cc1SHelen Koike else 1441e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1442e6938cc1SHelen Koike RKISP1_CIF_ISP_DEMOSAIC, 1443e6938cc1SHelen Koike RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 1444e6938cc1SHelen Koike } 1445e6938cc1SHelen Koike 1446e6938cc1SHelen Koike /* update filter config */ 1447e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT) 1448e6938cc1SHelen Koike rkisp1_flt_config(params, 1449e6938cc1SHelen Koike &new_params->others.flt_config); 1450e6938cc1SHelen Koike 1451e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) { 1452e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_FLT) 1453e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1454e6938cc1SHelen Koike RKISP1_CIF_ISP_FILT_MODE, 1455e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_ENA); 1456e6938cc1SHelen Koike else 1457e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1458e6938cc1SHelen Koike RKISP1_CIF_ISP_FILT_MODE, 1459e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_ENA); 1460e6938cc1SHelen Koike } 1461e6938cc1SHelen Koike 1462e6938cc1SHelen Koike /* update ctk config */ 1463e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK) 1464e6938cc1SHelen Koike rkisp1_ctk_config(params, 1465e6938cc1SHelen Koike &new_params->others.ctk_config); 1466e6938cc1SHelen Koike 1467e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK) 146818a4ca76SDafna Hirschfeld rkisp1_ctk_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK)); 1469e6938cc1SHelen Koike 1470e6938cc1SHelen Koike /* update goc config */ 1471e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC) 14725e8d9d72SHeiko Stuebner params->ops->goc_config(params, &new_params->others.goc_config); 1473e6938cc1SHelen Koike 1474e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) { 1475e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_GOC) 1476e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1477e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL, 1478e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 1479e6938cc1SHelen Koike else 1480e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1481e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL, 1482e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 1483e6938cc1SHelen Koike } 1484e6938cc1SHelen Koike 1485e6938cc1SHelen Koike /* update cproc config */ 148618a4ca76SDafna Hirschfeld if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC) 1487e6938cc1SHelen Koike rkisp1_cproc_config(params, 1488e6938cc1SHelen Koike &new_params->others.cproc_config); 1489e6938cc1SHelen Koike 1490e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) { 1491e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC) 1492e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1493e6938cc1SHelen Koike RKISP1_CIF_C_PROC_CTRL, 1494e6938cc1SHelen Koike RKISP1_CIF_C_PROC_CTR_ENABLE); 1495e6938cc1SHelen Koike else 1496e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1497e6938cc1SHelen Koike RKISP1_CIF_C_PROC_CTRL, 1498e6938cc1SHelen Koike RKISP1_CIF_C_PROC_CTR_ENABLE); 1499e6938cc1SHelen Koike } 1500e6938cc1SHelen Koike 1501e6938cc1SHelen Koike /* update ie config */ 1502e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE) 150318a4ca76SDafna Hirschfeld rkisp1_ie_config(params, &new_params->others.ie_config); 1504e6938cc1SHelen Koike 1505e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_IE) 150618a4ca76SDafna Hirschfeld rkisp1_ie_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_IE)); 1507e6938cc1SHelen Koike 1508e6938cc1SHelen Koike /* update dpf config */ 1509e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF) 151018a4ca76SDafna Hirschfeld rkisp1_dpf_config(params, &new_params->others.dpf_config); 1511e6938cc1SHelen Koike 1512e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) { 1513e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_DPF) 1514e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1515e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE, 1516e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_EN); 1517e6938cc1SHelen Koike else 1518e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1519e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE, 1520e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_EN); 1521e6938cc1SHelen Koike } 1522e6938cc1SHelen Koike 1523e6938cc1SHelen Koike if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) || 1524e6938cc1SHelen Koike (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) { 1525e6938cc1SHelen Koike /* update dpf strength config */ 1526e6938cc1SHelen Koike rkisp1_dpf_strength_config(params, 1527e6938cc1SHelen Koike &new_params->others.dpf_strength_config); 1528e6938cc1SHelen Koike } 1529e6938cc1SHelen Koike } 1530e6938cc1SHelen Koike 15314b07e2b8SLaurent Pinchart static void 15324b07e2b8SLaurent Pinchart rkisp1_isp_isr_lsc_config(struct rkisp1_params *params, 15334b07e2b8SLaurent Pinchart const struct rkisp1_params_cfg *new_params) 15344b07e2b8SLaurent Pinchart { 15354b07e2b8SLaurent Pinchart unsigned int module_en_update, module_cfg_update, module_ens; 15364b07e2b8SLaurent Pinchart 15374b07e2b8SLaurent Pinchart module_en_update = new_params->module_en_update; 15384b07e2b8SLaurent Pinchart module_cfg_update = new_params->module_cfg_update; 15394b07e2b8SLaurent Pinchart module_ens = new_params->module_ens; 15404b07e2b8SLaurent Pinchart 15414b07e2b8SLaurent Pinchart /* update lsc config */ 15424b07e2b8SLaurent Pinchart if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC) 15434b07e2b8SLaurent Pinchart rkisp1_lsc_config(params, 15444b07e2b8SLaurent Pinchart &new_params->others.lsc_config); 15454b07e2b8SLaurent Pinchart 15464b07e2b8SLaurent Pinchart if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) { 15474b07e2b8SLaurent Pinchart if (module_ens & RKISP1_CIF_ISP_MODULE_LSC) 15484b07e2b8SLaurent Pinchart rkisp1_param_set_bits(params, 15494b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_LSC_CTRL, 15504b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_LSC_CTRL_ENA); 15514b07e2b8SLaurent Pinchart else 15524b07e2b8SLaurent Pinchart rkisp1_param_clear_bits(params, 15534b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_LSC_CTRL, 15544b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_LSC_CTRL_ENA); 15554b07e2b8SLaurent Pinchart } 15564b07e2b8SLaurent Pinchart } 15574b07e2b8SLaurent Pinchart 1558e6938cc1SHelen Koike static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params, 1559e6938cc1SHelen Koike struct rkisp1_params_cfg *new_params) 1560e6938cc1SHelen Koike { 1561e6938cc1SHelen Koike unsigned int module_en_update, module_cfg_update, module_ens; 1562e6938cc1SHelen Koike 1563e6938cc1SHelen Koike module_en_update = new_params->module_en_update; 1564e6938cc1SHelen Koike module_cfg_update = new_params->module_cfg_update; 1565e6938cc1SHelen Koike module_ens = new_params->module_ens; 1566e6938cc1SHelen Koike 1567e6938cc1SHelen Koike /* update awb config */ 1568e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB) 15695e8d9d72SHeiko Stuebner params->ops->awb_meas_config(params, &new_params->meas.awb_meas_config); 1570e6938cc1SHelen Koike 1571e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB) 15725e8d9d72SHeiko Stuebner params->ops->awb_meas_enable(params, 1573e6938cc1SHelen Koike &new_params->meas.awb_meas_config, 1574e6938cc1SHelen Koike !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB)); 1575e6938cc1SHelen Koike 1576e6938cc1SHelen Koike /* update afc config */ 1577e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC) 15785e8d9d72SHeiko Stuebner params->ops->afm_config(params, 1579e6938cc1SHelen Koike &new_params->meas.afc_config); 1580e6938cc1SHelen Koike 1581e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) { 1582e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_AFC) 1583e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1584e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_CTRL, 1585e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_ENA); 1586e6938cc1SHelen Koike else 1587e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1588e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_CTRL, 1589e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_ENA); 1590e6938cc1SHelen Koike } 1591e6938cc1SHelen Koike 1592e6938cc1SHelen Koike /* update hst config */ 1593e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST) 15945e8d9d72SHeiko Stuebner params->ops->hst_config(params, 1595e6938cc1SHelen Koike &new_params->meas.hst_config); 1596e6938cc1SHelen Koike 1597e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_HST) 15985e8d9d72SHeiko Stuebner params->ops->hst_enable(params, 1599e6938cc1SHelen Koike &new_params->meas.hst_config, 1600e6938cc1SHelen Koike !!(module_ens & RKISP1_CIF_ISP_MODULE_HST)); 1601e6938cc1SHelen Koike 1602e6938cc1SHelen Koike /* update aec config */ 1603e6938cc1SHelen Koike if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC) 16045e8d9d72SHeiko Stuebner params->ops->aec_config(params, 1605e6938cc1SHelen Koike &new_params->meas.aec_config); 1606e6938cc1SHelen Koike 1607e6938cc1SHelen Koike if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) { 1608e6938cc1SHelen Koike if (module_ens & RKISP1_CIF_ISP_MODULE_AEC) 1609e6938cc1SHelen Koike rkisp1_param_set_bits(params, 1610e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_CTRL, 1611e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_ENA); 1612e6938cc1SHelen Koike else 1613e6938cc1SHelen Koike rkisp1_param_clear_bits(params, 1614e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_CTRL, 1615e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_ENA); 1616e6938cc1SHelen Koike } 1617e6938cc1SHelen Koike } 1618e6938cc1SHelen Koike 16196c53a7b6SJacopo Mondi /*------------------------------------------------------------------------------ 16206c53a7b6SJacopo Mondi * Extensible parameters format handling 16216c53a7b6SJacopo Mondi */ 16226c53a7b6SJacopo Mondi 16236c53a7b6SJacopo Mondi static void 16246c53a7b6SJacopo Mondi rkisp1_ext_params_bls(struct rkisp1_params *params, 16256c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 16266c53a7b6SJacopo Mondi { 16276c53a7b6SJacopo Mondi const struct rkisp1_ext_params_bls_config *bls = &block->bls; 16286c53a7b6SJacopo Mondi 16296c53a7b6SJacopo Mondi if (bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 16306c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL, 16316c53a7b6SJacopo Mondi RKISP1_CIF_ISP_BLS_ENA); 16326c53a7b6SJacopo Mondi return; 16336c53a7b6SJacopo Mondi } 16346c53a7b6SJacopo Mondi 16356c53a7b6SJacopo Mondi rkisp1_bls_config(params, &bls->config); 16366c53a7b6SJacopo Mondi 16376c53a7b6SJacopo Mondi if ((bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 16386c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(bls->header.type))) 16396c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_BLS_CTRL, 16406c53a7b6SJacopo Mondi RKISP1_CIF_ISP_BLS_ENA); 16416c53a7b6SJacopo Mondi } 16426c53a7b6SJacopo Mondi 16436c53a7b6SJacopo Mondi static void 16446c53a7b6SJacopo Mondi rkisp1_ext_params_dpcc(struct rkisp1_params *params, 16456c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 16466c53a7b6SJacopo Mondi { 16476c53a7b6SJacopo Mondi const struct rkisp1_ext_params_dpcc_config *dpcc = &block->dpcc; 16486c53a7b6SJacopo Mondi 16496c53a7b6SJacopo Mondi if (dpcc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 16506c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, 16516c53a7b6SJacopo Mondi RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 16526c53a7b6SJacopo Mondi return; 16536c53a7b6SJacopo Mondi } 16546c53a7b6SJacopo Mondi 16556c53a7b6SJacopo Mondi rkisp1_dpcc_config(params, &dpcc->config); 16566c53a7b6SJacopo Mondi 16576c53a7b6SJacopo Mondi if ((dpcc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 16586c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(dpcc->header.type))) 16596c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPCC_MODE, 16606c53a7b6SJacopo Mondi RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 16616c53a7b6SJacopo Mondi } 16626c53a7b6SJacopo Mondi 16636c53a7b6SJacopo Mondi static void 16646c53a7b6SJacopo Mondi rkisp1_ext_params_sdg(struct rkisp1_params *params, 16656c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 16666c53a7b6SJacopo Mondi { 16676c53a7b6SJacopo Mondi const struct rkisp1_ext_params_sdg_config *sdg = &block->sdg; 16686c53a7b6SJacopo Mondi 16696c53a7b6SJacopo Mondi if (sdg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 16706c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 16716c53a7b6SJacopo Mondi RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 16726c53a7b6SJacopo Mondi return; 16736c53a7b6SJacopo Mondi } 16746c53a7b6SJacopo Mondi 16756c53a7b6SJacopo Mondi rkisp1_sdg_config(params, &sdg->config); 16766c53a7b6SJacopo Mondi 16776c53a7b6SJacopo Mondi if ((sdg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 16786c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(sdg->header.type))) 16796c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 16806c53a7b6SJacopo Mondi RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 16816c53a7b6SJacopo Mondi } 16826c53a7b6SJacopo Mondi 16836c53a7b6SJacopo Mondi static void 16846c53a7b6SJacopo Mondi rkisp1_ext_params_lsc(struct rkisp1_params *params, 16856c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 16866c53a7b6SJacopo Mondi { 16876c53a7b6SJacopo Mondi const struct rkisp1_ext_params_lsc_config *lsc = &block->lsc; 16886c53a7b6SJacopo Mondi 16896c53a7b6SJacopo Mondi if (lsc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 16906c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 16916c53a7b6SJacopo Mondi RKISP1_CIF_ISP_LSC_CTRL_ENA); 16926c53a7b6SJacopo Mondi return; 16936c53a7b6SJacopo Mondi } 16946c53a7b6SJacopo Mondi 16956c53a7b6SJacopo Mondi rkisp1_lsc_config(params, &lsc->config); 16966c53a7b6SJacopo Mondi 16976c53a7b6SJacopo Mondi if ((lsc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 16986c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(lsc->header.type))) 16996c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 17006c53a7b6SJacopo Mondi RKISP1_CIF_ISP_LSC_CTRL_ENA); 17016c53a7b6SJacopo Mondi } 17026c53a7b6SJacopo Mondi 17036c53a7b6SJacopo Mondi static void 17046c53a7b6SJacopo Mondi rkisp1_ext_params_awbg(struct rkisp1_params *params, 17056c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 17066c53a7b6SJacopo Mondi { 17076c53a7b6SJacopo Mondi const struct rkisp1_ext_params_awb_gain_config *awbg = &block->awbg; 17086c53a7b6SJacopo Mondi 17096c53a7b6SJacopo Mondi if (awbg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 17106c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 17116c53a7b6SJacopo Mondi RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 17126c53a7b6SJacopo Mondi return; 17136c53a7b6SJacopo Mondi } 17146c53a7b6SJacopo Mondi 17156c53a7b6SJacopo Mondi params->ops->awb_gain_config(params, &awbg->config); 17166c53a7b6SJacopo Mondi 17176c53a7b6SJacopo Mondi if ((awbg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 17186c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(awbg->header.type))) 17196c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 17206c53a7b6SJacopo Mondi RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 17216c53a7b6SJacopo Mondi } 17226c53a7b6SJacopo Mondi 17236c53a7b6SJacopo Mondi static void 17246c53a7b6SJacopo Mondi rkisp1_ext_params_flt(struct rkisp1_params *params, 17256c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 17266c53a7b6SJacopo Mondi { 17276c53a7b6SJacopo Mondi const struct rkisp1_ext_params_flt_config *flt = &block->flt; 17286c53a7b6SJacopo Mondi 17296c53a7b6SJacopo Mondi if (flt->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 17306c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE, 17316c53a7b6SJacopo Mondi RKISP1_CIF_ISP_FLT_ENA); 17326c53a7b6SJacopo Mondi return; 17336c53a7b6SJacopo Mondi } 17346c53a7b6SJacopo Mondi 17356c53a7b6SJacopo Mondi rkisp1_flt_config(params, &flt->config); 17366c53a7b6SJacopo Mondi 17376c53a7b6SJacopo Mondi if ((flt->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 17386c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(flt->header.type))) 17396c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_FILT_MODE, 17406c53a7b6SJacopo Mondi RKISP1_CIF_ISP_FLT_ENA); 17416c53a7b6SJacopo Mondi } 17426c53a7b6SJacopo Mondi 17436c53a7b6SJacopo Mondi static void 17446c53a7b6SJacopo Mondi rkisp1_ext_params_bdm(struct rkisp1_params *params, 17456c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 17466c53a7b6SJacopo Mondi { 17476c53a7b6SJacopo Mondi const struct rkisp1_ext_params_bdm_config *bdm = &block->bdm; 17486c53a7b6SJacopo Mondi 17496c53a7b6SJacopo Mondi if (bdm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 17506c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC, 17516c53a7b6SJacopo Mondi RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 17526c53a7b6SJacopo Mondi return; 17536c53a7b6SJacopo Mondi } 17546c53a7b6SJacopo Mondi 17556c53a7b6SJacopo Mondi rkisp1_bdm_config(params, &bdm->config); 17566c53a7b6SJacopo Mondi 17576c53a7b6SJacopo Mondi if ((bdm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 17586c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(bdm->header.type))) 17596c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DEMOSAIC, 17606c53a7b6SJacopo Mondi RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 17616c53a7b6SJacopo Mondi } 17626c53a7b6SJacopo Mondi 17636c53a7b6SJacopo Mondi static void 17646c53a7b6SJacopo Mondi rkisp1_ext_params_ctk(struct rkisp1_params *params, 17656c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 17666c53a7b6SJacopo Mondi { 17676c53a7b6SJacopo Mondi const struct rkisp1_ext_params_ctk_config *ctk = &block->ctk; 17686c53a7b6SJacopo Mondi 17696c53a7b6SJacopo Mondi if (ctk->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 17706c53a7b6SJacopo Mondi rkisp1_ctk_enable(params, false); 17716c53a7b6SJacopo Mondi return; 17726c53a7b6SJacopo Mondi } 17736c53a7b6SJacopo Mondi 17746c53a7b6SJacopo Mondi rkisp1_ctk_config(params, &ctk->config); 17756c53a7b6SJacopo Mondi 17766c53a7b6SJacopo Mondi if ((ctk->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 17776c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(ctk->header.type))) 17786c53a7b6SJacopo Mondi rkisp1_ctk_enable(params, true); 17796c53a7b6SJacopo Mondi } 17806c53a7b6SJacopo Mondi 17816c53a7b6SJacopo Mondi static void 17826c53a7b6SJacopo Mondi rkisp1_ext_params_goc(struct rkisp1_params *params, 17836c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 17846c53a7b6SJacopo Mondi { 17856c53a7b6SJacopo Mondi const struct rkisp1_ext_params_goc_config *goc = &block->goc; 17866c53a7b6SJacopo Mondi 17876c53a7b6SJacopo Mondi if (goc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 17886c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 17896c53a7b6SJacopo Mondi RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 17906c53a7b6SJacopo Mondi return; 17916c53a7b6SJacopo Mondi } 17926c53a7b6SJacopo Mondi 17936c53a7b6SJacopo Mondi params->ops->goc_config(params, &goc->config); 17946c53a7b6SJacopo Mondi 17956c53a7b6SJacopo Mondi /* 17966c53a7b6SJacopo Mondi * Unconditionally re-enable the GOC module which gets disabled by 17976c53a7b6SJacopo Mondi * goc_config(). 17986c53a7b6SJacopo Mondi */ 17996c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 18006c53a7b6SJacopo Mondi RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 18016c53a7b6SJacopo Mondi } 18026c53a7b6SJacopo Mondi 18036c53a7b6SJacopo Mondi static void 18046c53a7b6SJacopo Mondi rkisp1_ext_params_dpf(struct rkisp1_params *params, 18056c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 18066c53a7b6SJacopo Mondi { 18076c53a7b6SJacopo Mondi const struct rkisp1_ext_params_dpf_config *dpf = &block->dpf; 18086c53a7b6SJacopo Mondi 18096c53a7b6SJacopo Mondi if (dpf->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 18106c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE, 18116c53a7b6SJacopo Mondi RKISP1_CIF_ISP_DPF_MODE_EN); 18126c53a7b6SJacopo Mondi return; 18136c53a7b6SJacopo Mondi } 18146c53a7b6SJacopo Mondi 18156c53a7b6SJacopo Mondi rkisp1_dpf_config(params, &dpf->config); 18166c53a7b6SJacopo Mondi 18176c53a7b6SJacopo Mondi if ((dpf->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 18186c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(dpf->header.type))) 18196c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE, 18206c53a7b6SJacopo Mondi RKISP1_CIF_ISP_DPF_MODE_EN); 18216c53a7b6SJacopo Mondi } 18226c53a7b6SJacopo Mondi 18236c53a7b6SJacopo Mondi static void 18246c53a7b6SJacopo Mondi rkisp1_ext_params_dpfs(struct rkisp1_params *params, 18256c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 18266c53a7b6SJacopo Mondi { 18276c53a7b6SJacopo Mondi const struct rkisp1_ext_params_dpf_strength_config *dpfs = &block->dpfs; 18286c53a7b6SJacopo Mondi 18296c53a7b6SJacopo Mondi rkisp1_dpf_strength_config(params, &dpfs->config); 18306c53a7b6SJacopo Mondi } 18316c53a7b6SJacopo Mondi 18326c53a7b6SJacopo Mondi static void 18336c53a7b6SJacopo Mondi rkisp1_ext_params_cproc(struct rkisp1_params *params, 18346c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 18356c53a7b6SJacopo Mondi { 18366c53a7b6SJacopo Mondi const struct rkisp1_ext_params_cproc_config *cproc = &block->cproc; 18376c53a7b6SJacopo Mondi 18386c53a7b6SJacopo Mondi if (cproc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 18396c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, 18406c53a7b6SJacopo Mondi RKISP1_CIF_C_PROC_CTR_ENABLE); 18416c53a7b6SJacopo Mondi return; 18426c53a7b6SJacopo Mondi } 18436c53a7b6SJacopo Mondi 18446c53a7b6SJacopo Mondi rkisp1_cproc_config(params, &cproc->config); 18456c53a7b6SJacopo Mondi 18466c53a7b6SJacopo Mondi if ((cproc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 18476c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(cproc->header.type))) 18486c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL, 18496c53a7b6SJacopo Mondi RKISP1_CIF_C_PROC_CTR_ENABLE); 18506c53a7b6SJacopo Mondi } 18516c53a7b6SJacopo Mondi 18526c53a7b6SJacopo Mondi static void 18536c53a7b6SJacopo Mondi rkisp1_ext_params_ie(struct rkisp1_params *params, 18546c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 18556c53a7b6SJacopo Mondi { 18566c53a7b6SJacopo Mondi const struct rkisp1_ext_params_ie_config *ie = &block->ie; 18576c53a7b6SJacopo Mondi 18586c53a7b6SJacopo Mondi if (ie->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 18596c53a7b6SJacopo Mondi rkisp1_ie_enable(params, false); 18606c53a7b6SJacopo Mondi return; 18616c53a7b6SJacopo Mondi } 18626c53a7b6SJacopo Mondi 18636c53a7b6SJacopo Mondi rkisp1_ie_config(params, &ie->config); 18646c53a7b6SJacopo Mondi 18656c53a7b6SJacopo Mondi if ((ie->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 18666c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(ie->header.type))) 18676c53a7b6SJacopo Mondi rkisp1_ie_enable(params, true); 18686c53a7b6SJacopo Mondi } 18696c53a7b6SJacopo Mondi 18706c53a7b6SJacopo Mondi static void 18716c53a7b6SJacopo Mondi rkisp1_ext_params_awbm(struct rkisp1_params *params, 18726c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 18736c53a7b6SJacopo Mondi { 18746c53a7b6SJacopo Mondi const struct rkisp1_ext_params_awb_meas_config *awbm = &block->awbm; 18756c53a7b6SJacopo Mondi 18766c53a7b6SJacopo Mondi if (awbm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 18776c53a7b6SJacopo Mondi params->ops->awb_meas_enable(params, &awbm->config, 18786c53a7b6SJacopo Mondi false); 18796c53a7b6SJacopo Mondi return; 18806c53a7b6SJacopo Mondi } 18816c53a7b6SJacopo Mondi 18826c53a7b6SJacopo Mondi params->ops->awb_meas_config(params, &awbm->config); 18836c53a7b6SJacopo Mondi 18846c53a7b6SJacopo Mondi if ((awbm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 18856c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(awbm->header.type))) 18866c53a7b6SJacopo Mondi params->ops->awb_meas_enable(params, &awbm->config, 18876c53a7b6SJacopo Mondi true); 18886c53a7b6SJacopo Mondi } 18896c53a7b6SJacopo Mondi 18906c53a7b6SJacopo Mondi static void 18916c53a7b6SJacopo Mondi rkisp1_ext_params_hstm(struct rkisp1_params *params, 18926c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 18936c53a7b6SJacopo Mondi { 18946c53a7b6SJacopo Mondi const struct rkisp1_ext_params_hst_config *hst = &block->hst; 18956c53a7b6SJacopo Mondi 18966c53a7b6SJacopo Mondi if (hst->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 18976c53a7b6SJacopo Mondi params->ops->hst_enable(params, &hst->config, false); 18986c53a7b6SJacopo Mondi return; 18996c53a7b6SJacopo Mondi } 19006c53a7b6SJacopo Mondi 19016c53a7b6SJacopo Mondi params->ops->hst_config(params, &hst->config); 19026c53a7b6SJacopo Mondi 19036c53a7b6SJacopo Mondi if ((hst->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 19046c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(hst->header.type))) 19056c53a7b6SJacopo Mondi params->ops->hst_enable(params, &hst->config, true); 19066c53a7b6SJacopo Mondi } 19076c53a7b6SJacopo Mondi 19086c53a7b6SJacopo Mondi static void 19096c53a7b6SJacopo Mondi rkisp1_ext_params_aecm(struct rkisp1_params *params, 19106c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 19116c53a7b6SJacopo Mondi { 19126c53a7b6SJacopo Mondi const struct rkisp1_ext_params_aec_config *aec = &block->aec; 19136c53a7b6SJacopo Mondi 19146c53a7b6SJacopo Mondi if (aec->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 19156c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL, 19166c53a7b6SJacopo Mondi RKISP1_CIF_ISP_EXP_ENA); 19176c53a7b6SJacopo Mondi return; 19186c53a7b6SJacopo Mondi } 19196c53a7b6SJacopo Mondi 19206c53a7b6SJacopo Mondi params->ops->aec_config(params, &aec->config); 19216c53a7b6SJacopo Mondi 19226c53a7b6SJacopo Mondi if ((aec->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 19236c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(aec->header.type))) 19246c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL, 19256c53a7b6SJacopo Mondi RKISP1_CIF_ISP_EXP_ENA); 19266c53a7b6SJacopo Mondi } 19276c53a7b6SJacopo Mondi 19286c53a7b6SJacopo Mondi static void 19296c53a7b6SJacopo Mondi rkisp1_ext_params_afcm(struct rkisp1_params *params, 19306c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block) 19316c53a7b6SJacopo Mondi { 19326c53a7b6SJacopo Mondi const struct rkisp1_ext_params_afc_config *afc = &block->afc; 19336c53a7b6SJacopo Mondi 19346c53a7b6SJacopo Mondi if (afc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 19356c53a7b6SJacopo Mondi rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 19366c53a7b6SJacopo Mondi RKISP1_CIF_ISP_AFM_ENA); 19376c53a7b6SJacopo Mondi return; 19386c53a7b6SJacopo Mondi } 19396c53a7b6SJacopo Mondi 19406c53a7b6SJacopo Mondi params->ops->afm_config(params, &afc->config); 19416c53a7b6SJacopo Mondi 19426c53a7b6SJacopo Mondi if ((afc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 19436c53a7b6SJacopo Mondi !(params->enabled_blocks & BIT(afc->header.type))) 19446c53a7b6SJacopo Mondi rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 19456c53a7b6SJacopo Mondi RKISP1_CIF_ISP_AFM_ENA); 19466c53a7b6SJacopo Mondi } 19476c53a7b6SJacopo Mondi 1948*ac79beb9SPaul Elder static void rkisp1_ext_params_compand_bls(struct rkisp1_params *params, 1949*ac79beb9SPaul Elder const union rkisp1_ext_params_config *block) 1950*ac79beb9SPaul Elder { 1951*ac79beb9SPaul Elder const struct rkisp1_ext_params_compand_bls_config *bls = 1952*ac79beb9SPaul Elder &block->compand_bls; 1953*ac79beb9SPaul Elder 1954*ac79beb9SPaul Elder if (bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1955*ac79beb9SPaul Elder rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1956*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE); 1957*ac79beb9SPaul Elder return; 1958*ac79beb9SPaul Elder } 1959*ac79beb9SPaul Elder 1960*ac79beb9SPaul Elder rkisp1_compand_bls_config(params, &bls->config); 1961*ac79beb9SPaul Elder 1962*ac79beb9SPaul Elder if ((bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1963*ac79beb9SPaul Elder !(params->enabled_blocks & BIT(bls->header.type))) 1964*ac79beb9SPaul Elder rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1965*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE); 1966*ac79beb9SPaul Elder } 1967*ac79beb9SPaul Elder 1968*ac79beb9SPaul Elder static void rkisp1_ext_params_compand_expand(struct rkisp1_params *params, 1969*ac79beb9SPaul Elder const union rkisp1_ext_params_config *block) 1970*ac79beb9SPaul Elder { 1971*ac79beb9SPaul Elder const struct rkisp1_ext_params_compand_curve_config *curve = 1972*ac79beb9SPaul Elder &block->compand_curve; 1973*ac79beb9SPaul Elder 1974*ac79beb9SPaul Elder if (curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1975*ac79beb9SPaul Elder rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1976*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE); 1977*ac79beb9SPaul Elder return; 1978*ac79beb9SPaul Elder } 1979*ac79beb9SPaul Elder 1980*ac79beb9SPaul Elder rkisp1_compand_expand_config(params, &curve->config); 1981*ac79beb9SPaul Elder 1982*ac79beb9SPaul Elder if ((curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1983*ac79beb9SPaul Elder !(params->enabled_blocks & BIT(curve->header.type))) 1984*ac79beb9SPaul Elder rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1985*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE); 1986*ac79beb9SPaul Elder } 1987*ac79beb9SPaul Elder 1988*ac79beb9SPaul Elder static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params, 1989*ac79beb9SPaul Elder const union rkisp1_ext_params_config *block) 1990*ac79beb9SPaul Elder { 1991*ac79beb9SPaul Elder const struct rkisp1_ext_params_compand_curve_config *curve = 1992*ac79beb9SPaul Elder &block->compand_curve; 1993*ac79beb9SPaul Elder 1994*ac79beb9SPaul Elder if (curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1995*ac79beb9SPaul Elder rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1996*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE); 1997*ac79beb9SPaul Elder return; 1998*ac79beb9SPaul Elder } 1999*ac79beb9SPaul Elder 2000*ac79beb9SPaul Elder rkisp1_compand_compress_config(params, &curve->config); 2001*ac79beb9SPaul Elder 2002*ac79beb9SPaul Elder if ((curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 2003*ac79beb9SPaul Elder !(params->enabled_blocks & BIT(curve->header.type))) 2004*ac79beb9SPaul Elder rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 2005*ac79beb9SPaul Elder RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE); 2006*ac79beb9SPaul Elder } 2007*ac79beb9SPaul Elder 20086c53a7b6SJacopo Mondi typedef void (*rkisp1_block_handler)(struct rkisp1_params *params, 20096c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *config); 20106c53a7b6SJacopo Mondi 20116c53a7b6SJacopo Mondi static const struct rkisp1_ext_params_handler { 20126c53a7b6SJacopo Mondi size_t size; 20136c53a7b6SJacopo Mondi rkisp1_block_handler handler; 20146c53a7b6SJacopo Mondi unsigned int group; 2015f1463972SLaurent Pinchart unsigned int features; 20166c53a7b6SJacopo Mondi } rkisp1_ext_params_handlers[] = { 20176c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = { 20186c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_bls_config), 20196c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_bls, 20206c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 202174a18d02SPaul Elder .features = RKISP1_FEATURE_BLS, 20226c53a7b6SJacopo Mondi }, 20236c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = { 20246c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_dpcc_config), 20256c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_dpcc, 20266c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20276c53a7b6SJacopo Mondi }, 20286c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = { 20296c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_sdg_config), 20306c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_sdg, 20316c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20326c53a7b6SJacopo Mondi }, 20336c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = { 20346c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_awb_gain_config), 20356c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_awbg, 20366c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20376c53a7b6SJacopo Mondi }, 20386c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = { 20396c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_flt_config), 20406c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_flt, 20416c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20426c53a7b6SJacopo Mondi }, 20436c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = { 20446c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_bdm_config), 20456c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_bdm, 20466c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20476c53a7b6SJacopo Mondi }, 20486c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = { 20496c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_ctk_config), 20506c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_ctk, 20516c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20526c53a7b6SJacopo Mondi }, 20536c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = { 20546c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_goc_config), 20556c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_goc, 20566c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20576c53a7b6SJacopo Mondi }, 20586c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = { 20596c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_dpf_config), 20606c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_dpf, 20616c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20626c53a7b6SJacopo Mondi }, 20636c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = { 20646c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_dpf_strength_config), 20656c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_dpfs, 20666c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20676c53a7b6SJacopo Mondi }, 20686c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = { 20696c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_cproc_config), 20706c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_cproc, 20716c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20726c53a7b6SJacopo Mondi }, 20736c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = { 20746c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_ie_config), 20756c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_ie, 20766c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20776c53a7b6SJacopo Mondi }, 20786c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = { 20796c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_lsc_config), 20806c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_lsc, 20816c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC, 20826c53a7b6SJacopo Mondi }, 20836c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = { 20846c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_awb_meas_config), 20856c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_awbm, 20866c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20876c53a7b6SJacopo Mondi }, 20886c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = { 20896c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_hst_config), 20906c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_hstm, 20916c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20926c53a7b6SJacopo Mondi }, 20936c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = { 20946c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_aec_config), 20956c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_aecm, 20966c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 20976c53a7b6SJacopo Mondi }, 20986c53a7b6SJacopo Mondi [RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = { 20996c53a7b6SJacopo Mondi .size = sizeof(struct rkisp1_ext_params_afc_config), 21006c53a7b6SJacopo Mondi .handler = rkisp1_ext_params_afcm, 21016c53a7b6SJacopo Mondi .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 21026c53a7b6SJacopo Mondi }, 2103*ac79beb9SPaul Elder [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = { 2104*ac79beb9SPaul Elder .size = sizeof(struct rkisp1_ext_params_compand_bls_config), 2105*ac79beb9SPaul Elder .handler = rkisp1_ext_params_compand_bls, 2106*ac79beb9SPaul Elder .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 2107*ac79beb9SPaul Elder .features = RKISP1_FEATURE_COMPAND, 2108*ac79beb9SPaul Elder }, 2109*ac79beb9SPaul Elder [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = { 2110*ac79beb9SPaul Elder .size = sizeof(struct rkisp1_ext_params_compand_curve_config), 2111*ac79beb9SPaul Elder .handler = rkisp1_ext_params_compand_expand, 2112*ac79beb9SPaul Elder .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 2113*ac79beb9SPaul Elder .features = RKISP1_FEATURE_COMPAND, 2114*ac79beb9SPaul Elder }, 2115*ac79beb9SPaul Elder [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = { 2116*ac79beb9SPaul Elder .size = sizeof(struct rkisp1_ext_params_compand_curve_config), 2117*ac79beb9SPaul Elder .handler = rkisp1_ext_params_compand_compress, 2118*ac79beb9SPaul Elder .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 2119*ac79beb9SPaul Elder .features = RKISP1_FEATURE_COMPAND, 2120*ac79beb9SPaul Elder }, 21216c53a7b6SJacopo Mondi }; 21226c53a7b6SJacopo Mondi 21236c53a7b6SJacopo Mondi static void rkisp1_ext_params_config(struct rkisp1_params *params, 21246c53a7b6SJacopo Mondi struct rkisp1_ext_params_cfg *cfg, 21256c53a7b6SJacopo Mondi u32 block_group_mask) 21266c53a7b6SJacopo Mondi { 21276c53a7b6SJacopo Mondi size_t block_offset = 0; 21286c53a7b6SJacopo Mondi 21296c53a7b6SJacopo Mondi if (WARN_ON(!cfg)) 21306c53a7b6SJacopo Mondi return; 21316c53a7b6SJacopo Mondi 21326c53a7b6SJacopo Mondi /* Walk the list of parameter blocks and process them. */ 21336c53a7b6SJacopo Mondi while (block_offset < cfg->data_size) { 21346c53a7b6SJacopo Mondi const struct rkisp1_ext_params_handler *block_handler; 21356c53a7b6SJacopo Mondi const union rkisp1_ext_params_config *block; 21366c53a7b6SJacopo Mondi 21376c53a7b6SJacopo Mondi block = (const union rkisp1_ext_params_config *) 21386c53a7b6SJacopo Mondi &cfg->data[block_offset]; 21396c53a7b6SJacopo Mondi block_offset += block->header.size; 21406c53a7b6SJacopo Mondi 2141f1463972SLaurent Pinchart /* 2142f1463972SLaurent Pinchart * Make sure the block is supported by the platform and in the 2143f1463972SLaurent Pinchart * list of groups to configure. 2144f1463972SLaurent Pinchart */ 21456c53a7b6SJacopo Mondi block_handler = &rkisp1_ext_params_handlers[block->header.type]; 21466c53a7b6SJacopo Mondi if (!(block_handler->group & block_group_mask)) 21476c53a7b6SJacopo Mondi continue; 21486c53a7b6SJacopo Mondi 2149f1463972SLaurent Pinchart if ((params->rkisp1->info->features & block_handler->features) != 2150f1463972SLaurent Pinchart block_handler->features) 2151f1463972SLaurent Pinchart continue; 2152f1463972SLaurent Pinchart 21536c53a7b6SJacopo Mondi block_handler->handler(params, block); 21546c53a7b6SJacopo Mondi 21556c53a7b6SJacopo Mondi if (block->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) 21566c53a7b6SJacopo Mondi params->enabled_blocks &= ~BIT(block->header.type); 21576c53a7b6SJacopo Mondi else if (block->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) 21586c53a7b6SJacopo Mondi params->enabled_blocks |= BIT(block->header.type); 21596c53a7b6SJacopo Mondi } 21606c53a7b6SJacopo Mondi } 21616c53a7b6SJacopo Mondi 21624b07e2b8SLaurent Pinchart static void rkisp1_params_complete_buffer(struct rkisp1_params *params, 21633bdae13aSJacopo Mondi struct rkisp1_params_buffer *buf, 2164e6938cc1SHelen Koike unsigned int frame_sequence) 2165e6938cc1SHelen Koike { 21664b07e2b8SLaurent Pinchart list_del(&buf->queue); 2167e6938cc1SHelen Koike 21684b07e2b8SLaurent Pinchart buf->vb.sequence = frame_sequence; 21694b07e2b8SLaurent Pinchart vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); 2170e6938cc1SHelen Koike } 2171e6938cc1SHelen Koike 2172e6938cc1SHelen Koike void rkisp1_params_isr(struct rkisp1_device *rkisp1) 2173e6938cc1SHelen Koike { 2174e6938cc1SHelen Koike struct rkisp1_params *params = &rkisp1->params; 21753bdae13aSJacopo Mondi struct rkisp1_params_buffer *cur_buf; 2176e6938cc1SHelen Koike 2177e6938cc1SHelen Koike spin_lock(¶ms->config_lock); 2178e6938cc1SHelen Koike 2179092e276dSJacopo Mondi cur_buf = list_first_entry_or_null(¶ms->params, 2180092e276dSJacopo Mondi struct rkisp1_params_buffer, queue); 2181092e276dSJacopo Mondi if (!cur_buf) 21824b07e2b8SLaurent Pinchart goto unlock; 21834b07e2b8SLaurent Pinchart 21846c53a7b6SJacopo Mondi if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { 2185092e276dSJacopo Mondi rkisp1_isp_isr_other_config(params, cur_buf->cfg); 2186092e276dSJacopo Mondi rkisp1_isp_isr_lsc_config(params, cur_buf->cfg); 2187092e276dSJacopo Mondi rkisp1_isp_isr_meas_config(params, cur_buf->cfg); 21886c53a7b6SJacopo Mondi } else { 21896c53a7b6SJacopo Mondi rkisp1_ext_params_config(params, cur_buf->cfg, 21906c53a7b6SJacopo Mondi RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS | 21916c53a7b6SJacopo Mondi RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC); 21926c53a7b6SJacopo Mondi } 21934b07e2b8SLaurent Pinchart 21944b07e2b8SLaurent Pinchart /* update shadow register immediately */ 21954b07e2b8SLaurent Pinchart rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 21964b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 21974b07e2b8SLaurent Pinchart 21984b07e2b8SLaurent Pinchart /* 21994b07e2b8SLaurent Pinchart * This isr is called when the ISR finishes processing a frame 22004b07e2b8SLaurent Pinchart * (RKISP1_CIF_ISP_FRAME). Configurations performed here will be 22014b07e2b8SLaurent Pinchart * applied on the next frame. Since frame_sequence is updated on the 22024b07e2b8SLaurent Pinchart * vertical sync signal, we should use frame_sequence + 1 here to 22034b07e2b8SLaurent Pinchart * indicate to userspace on which frame these parameters are being 22044b07e2b8SLaurent Pinchart * applied. 22054b07e2b8SLaurent Pinchart */ 22064b07e2b8SLaurent Pinchart rkisp1_params_complete_buffer(params, cur_buf, 22074b07e2b8SLaurent Pinchart rkisp1->isp.frame_sequence + 1); 22084b07e2b8SLaurent Pinchart 22094b07e2b8SLaurent Pinchart unlock: 2210e6938cc1SHelen Koike spin_unlock(¶ms->config_lock); 2211e6938cc1SHelen Koike } 2212e6938cc1SHelen Koike 2213e6938cc1SHelen Koike static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = { 2214e6938cc1SHelen Koike { 2215e6938cc1SHelen Koike 0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT 2216e6938cc1SHelen Koike }, 2217e6938cc1SHelen Koike RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128 2218e6938cc1SHelen Koike }; 2219e6938cc1SHelen Koike 2220e6938cc1SHelen Koike static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = { 2221e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_MEASURING_MODE_0, 2222e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0, 2223e6938cc1SHelen Koike { 2224e6938cc1SHelen Koike RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2, 2225e6938cc1SHelen Koike RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1 2226e6938cc1SHelen Koike } 2227e6938cc1SHelen Koike }; 2228e6938cc1SHelen Koike 2229e6938cc1SHelen Koike static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = { 2230e6938cc1SHelen Koike RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED, 2231e6938cc1SHelen Koike 3, 2232e6938cc1SHelen Koike { 2233e6938cc1SHelen Koike RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2, 2234e6938cc1SHelen Koike RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1 2235e6938cc1SHelen Koike }, 2236e6938cc1SHelen Koike { 2237e6938cc1SHelen Koike 0, /* To be filled in with 0x01 at runtime. */ 2238e6938cc1SHelen Koike } 2239e6938cc1SHelen Koike }; 2240e6938cc1SHelen Koike 2241e6938cc1SHelen Koike static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = { 2242e6938cc1SHelen Koike 1, 2243e6938cc1SHelen Koike { 2244e6938cc1SHelen Koike { 2245e6938cc1SHelen Koike 300, 225, 200, 150 2246e6938cc1SHelen Koike } 2247e6938cc1SHelen Koike }, 2248e6938cc1SHelen Koike 4, 2249e6938cc1SHelen Koike 14 2250e6938cc1SHelen Koike }; 2251e6938cc1SHelen Koike 22524b07e2b8SLaurent Pinchart void rkisp1_params_pre_configure(struct rkisp1_params *params, 22534b07e2b8SLaurent Pinchart enum rkisp1_fmt_raw_pat_type bayer_pat, 22544b07e2b8SLaurent Pinchart enum v4l2_quantization quantization, 22554b07e2b8SLaurent Pinchart enum v4l2_ycbcr_encoding ycbcr_encoding) 2256e6938cc1SHelen Koike { 2257e6938cc1SHelen Koike struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; 22583bdae13aSJacopo Mondi struct rkisp1_params_buffer *cur_buf; 22594b07e2b8SLaurent Pinchart 22604b07e2b8SLaurent Pinchart params->quantization = quantization; 22614b07e2b8SLaurent Pinchart params->ycbcr_encoding = ycbcr_encoding; 22624b07e2b8SLaurent Pinchart params->raw_type = bayer_pat; 2263e6938cc1SHelen Koike 22645e8d9d72SHeiko Stuebner params->ops->awb_meas_config(params, &rkisp1_awb_params_default_config); 22655e8d9d72SHeiko Stuebner params->ops->awb_meas_enable(params, &rkisp1_awb_params_default_config, 2266e6938cc1SHelen Koike true); 2267e6938cc1SHelen Koike 22685e8d9d72SHeiko Stuebner params->ops->aec_config(params, &rkisp1_aec_params_default_config); 2269e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL, 2270e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_ENA); 2271e6938cc1SHelen Koike 22725e8d9d72SHeiko Stuebner params->ops->afm_config(params, &rkisp1_afc_params_default_config); 2273e6938cc1SHelen Koike rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 2274e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_ENA); 2275e6938cc1SHelen Koike 2276e6938cc1SHelen Koike memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); 22775e8d9d72SHeiko Stuebner params->ops->hst_config(params, &hst); 2278dce8ccb2SHeiko Stuebner rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10, 2279e6938cc1SHelen Koike rkisp1_hst_params_default_config.mode); 2280e6938cc1SHelen Koike 2281711d9149SLaurent Pinchart rkisp1_csm_config(params); 2282e6938cc1SHelen Koike 2283e6938cc1SHelen Koike spin_lock_irq(¶ms->config_lock); 2284e6938cc1SHelen Koike 2285e6938cc1SHelen Koike /* apply the first buffer if there is one already */ 2286e6938cc1SHelen Koike 2287092e276dSJacopo Mondi cur_buf = list_first_entry_or_null(¶ms->params, 2288092e276dSJacopo Mondi struct rkisp1_params_buffer, queue); 2289092e276dSJacopo Mondi if (!cur_buf) 22904b07e2b8SLaurent Pinchart goto unlock; 22914b07e2b8SLaurent Pinchart 22926c53a7b6SJacopo Mondi if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { 2293092e276dSJacopo Mondi rkisp1_isp_isr_other_config(params, cur_buf->cfg); 2294092e276dSJacopo Mondi rkisp1_isp_isr_meas_config(params, cur_buf->cfg); 22956c53a7b6SJacopo Mondi } else { 22966c53a7b6SJacopo Mondi rkisp1_ext_params_config(params, cur_buf->cfg, 22976c53a7b6SJacopo Mondi RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS); 22986c53a7b6SJacopo Mondi } 22994b07e2b8SLaurent Pinchart 23004b07e2b8SLaurent Pinchart /* update shadow register immediately */ 23014b07e2b8SLaurent Pinchart rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 23024b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 23034b07e2b8SLaurent Pinchart 23044b07e2b8SLaurent Pinchart unlock: 2305e6938cc1SHelen Koike spin_unlock_irq(¶ms->config_lock); 2306e6938cc1SHelen Koike } 2307e6938cc1SHelen Koike 23084b07e2b8SLaurent Pinchart void rkisp1_params_post_configure(struct rkisp1_params *params) 2309e6938cc1SHelen Koike { 23103bdae13aSJacopo Mondi struct rkisp1_params_buffer *cur_buf; 23114b07e2b8SLaurent Pinchart 23124b07e2b8SLaurent Pinchart spin_lock_irq(¶ms->config_lock); 23134b07e2b8SLaurent Pinchart 23144b07e2b8SLaurent Pinchart /* 23154b07e2b8SLaurent Pinchart * Apply LSC parameters from the first buffer (if any is already 23164b07e2b8SLaurent Pinchart * available. This must be done after the ISP gets started in the 23174b07e2b8SLaurent Pinchart * ISP8000Nano v18.02 (found in the i.MX8MP) as access to the LSC RAM 23184b07e2b8SLaurent Pinchart * is gated by the ISP_CTRL.ISP_ENABLE bit. As this initialization 23194b07e2b8SLaurent Pinchart * ordering doesn't affect other ISP versions negatively, do so 23204b07e2b8SLaurent Pinchart * unconditionally. 23214b07e2b8SLaurent Pinchart */ 2322092e276dSJacopo Mondi cur_buf = list_first_entry_or_null(¶ms->params, 2323092e276dSJacopo Mondi struct rkisp1_params_buffer, queue); 2324092e276dSJacopo Mondi if (!cur_buf) 23254b07e2b8SLaurent Pinchart goto unlock; 23264b07e2b8SLaurent Pinchart 23276c53a7b6SJacopo Mondi if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) 2328092e276dSJacopo Mondi rkisp1_isp_isr_lsc_config(params, cur_buf->cfg); 23296c53a7b6SJacopo Mondi else 23306c53a7b6SJacopo Mondi rkisp1_ext_params_config(params, cur_buf->cfg, 23316c53a7b6SJacopo Mondi RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC); 23324b07e2b8SLaurent Pinchart 23334b07e2b8SLaurent Pinchart /* update shadow register immediately */ 23344b07e2b8SLaurent Pinchart rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 23354b07e2b8SLaurent Pinchart RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 23364b07e2b8SLaurent Pinchart 23374b07e2b8SLaurent Pinchart rkisp1_params_complete_buffer(params, cur_buf, 0); 23384b07e2b8SLaurent Pinchart 23394b07e2b8SLaurent Pinchart unlock: 23404b07e2b8SLaurent Pinchart spin_unlock_irq(¶ms->config_lock); 2341e6938cc1SHelen Koike } 2342e6938cc1SHelen Koike 234327ba4427SSebastian Fricke /* 234427ba4427SSebastian Fricke * Not called when the camera is active, therefore there is no need to acquire 234527ba4427SSebastian Fricke * a lock. 234627ba4427SSebastian Fricke */ 2347e6938cc1SHelen Koike void rkisp1_params_disable(struct rkisp1_params *params) 2348e6938cc1SHelen Koike { 2349e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, 23509daa2b84SLaurent Pinchart RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 2351e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 2352e6938cc1SHelen Koike RKISP1_CIF_ISP_LSC_CTRL_ENA); 2353e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL, 2354e6938cc1SHelen Koike RKISP1_CIF_ISP_BLS_ENA); 2355e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 2356e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 2357e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 2358e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 2359e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC, 2360e6938cc1SHelen Koike RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 2361e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE, 2362e6938cc1SHelen Koike RKISP1_CIF_ISP_FLT_ENA); 23635e8d9d72SHeiko Stuebner params->ops->awb_meas_enable(params, NULL, false); 2364e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 2365e6938cc1SHelen Koike RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 2366e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL, 2367e6938cc1SHelen Koike RKISP1_CIF_ISP_EXP_ENA); 2368e6938cc1SHelen Koike rkisp1_ctk_enable(params, false); 2369e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, 2370e6938cc1SHelen Koike RKISP1_CIF_C_PROC_CTR_ENABLE); 23715e8d9d72SHeiko Stuebner params->ops->hst_enable(params, NULL, false); 2372e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 2373e6938cc1SHelen Koike RKISP1_CIF_ISP_AFM_ENA); 2374e6938cc1SHelen Koike rkisp1_ie_enable(params, false); 2375e6938cc1SHelen Koike rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE, 2376e6938cc1SHelen Koike RKISP1_CIF_ISP_DPF_MODE_EN); 2377e6938cc1SHelen Koike } 2378e6938cc1SHelen Koike 2379dce8ccb2SHeiko Stuebner static const struct rkisp1_params_ops rkisp1_v10_params_ops = { 2380dce8ccb2SHeiko Stuebner .lsc_matrix_config = rkisp1_lsc_matrix_config_v10, 2381dce8ccb2SHeiko Stuebner .goc_config = rkisp1_goc_config_v10, 2382dce8ccb2SHeiko Stuebner .awb_meas_config = rkisp1_awb_meas_config_v10, 2383dce8ccb2SHeiko Stuebner .awb_meas_enable = rkisp1_awb_meas_enable_v10, 2384dce8ccb2SHeiko Stuebner .awb_gain_config = rkisp1_awb_gain_config_v10, 2385dce8ccb2SHeiko Stuebner .aec_config = rkisp1_aec_config_v10, 2386dce8ccb2SHeiko Stuebner .hst_config = rkisp1_hst_config_v10, 2387dce8ccb2SHeiko Stuebner .hst_enable = rkisp1_hst_enable_v10, 2388dce8ccb2SHeiko Stuebner .afm_config = rkisp1_afm_config_v10, 23895e8d9d72SHeiko Stuebner }; 23905e8d9d72SHeiko Stuebner 23911f3ba4b8SLaurent Pinchart static const struct rkisp1_params_ops rkisp1_v12_params_ops = { 2392cd42f802SHeiko Stuebner .lsc_matrix_config = rkisp1_lsc_matrix_config_v12, 2393cd42f802SHeiko Stuebner .goc_config = rkisp1_goc_config_v12, 2394cd42f802SHeiko Stuebner .awb_meas_config = rkisp1_awb_meas_config_v12, 2395cd42f802SHeiko Stuebner .awb_meas_enable = rkisp1_awb_meas_enable_v12, 2396cd42f802SHeiko Stuebner .awb_gain_config = rkisp1_awb_gain_config_v12, 2397cd42f802SHeiko Stuebner .aec_config = rkisp1_aec_config_v12, 2398cd42f802SHeiko Stuebner .hst_config = rkisp1_hst_config_v12, 2399cd42f802SHeiko Stuebner .hst_enable = rkisp1_hst_enable_v12, 2400cd42f802SHeiko Stuebner .afm_config = rkisp1_afm_config_v12, 2401cd42f802SHeiko Stuebner }; 2402cd42f802SHeiko Stuebner 2403e6938cc1SHelen Koike static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv, 2404e6938cc1SHelen Koike struct v4l2_fmtdesc *f) 2405e6938cc1SHelen Koike { 2406e6938cc1SHelen Koike struct video_device *video = video_devdata(file); 2407e6938cc1SHelen Koike 2408f848c031SJacopo Mondi if (f->index >= ARRAY_SIZE(rkisp1_params_formats) || 2409f848c031SJacopo Mondi f->type != video->queue->type) 2410e6938cc1SHelen Koike return -EINVAL; 2411e6938cc1SHelen Koike 2412f848c031SJacopo Mondi f->pixelformat = rkisp1_params_formats[f->index].dataformat; 2413e6938cc1SHelen Koike 2414e6938cc1SHelen Koike return 0; 2415e6938cc1SHelen Koike } 2416e6938cc1SHelen Koike 2417e6938cc1SHelen Koike static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh, 2418e6938cc1SHelen Koike struct v4l2_format *f) 2419e6938cc1SHelen Koike { 2420e6938cc1SHelen Koike struct video_device *video = video_devdata(file); 2421e6938cc1SHelen Koike struct rkisp1_params *params = video_get_drvdata(video); 2422e6938cc1SHelen Koike struct v4l2_meta_format *meta = &f->fmt.meta; 2423e6938cc1SHelen Koike 2424e6938cc1SHelen Koike if (f->type != video->queue->type) 2425e6938cc1SHelen Koike return -EINVAL; 2426e6938cc1SHelen Koike 2427f848c031SJacopo Mondi *meta = *params->metafmt; 2428f848c031SJacopo Mondi 2429f848c031SJacopo Mondi return 0; 2430f848c031SJacopo Mondi } 2431f848c031SJacopo Mondi 2432f848c031SJacopo Mondi static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh, 2433f848c031SJacopo Mondi struct v4l2_format *f) 2434f848c031SJacopo Mondi { 2435f848c031SJacopo Mondi struct video_device *video = video_devdata(file); 2436f848c031SJacopo Mondi struct v4l2_meta_format *meta = &f->fmt.meta; 2437f848c031SJacopo Mondi 2438f848c031SJacopo Mondi if (f->type != video->queue->type) 2439f848c031SJacopo Mondi return -EINVAL; 2440f848c031SJacopo Mondi 2441f848c031SJacopo Mondi *meta = *rkisp1_params_get_format_info(meta->dataformat); 2442f848c031SJacopo Mondi 2443f848c031SJacopo Mondi return 0; 2444f848c031SJacopo Mondi } 2445f848c031SJacopo Mondi 2446f848c031SJacopo Mondi static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh, 2447f848c031SJacopo Mondi struct v4l2_format *f) 2448f848c031SJacopo Mondi { 2449f848c031SJacopo Mondi struct video_device *video = video_devdata(file); 2450f848c031SJacopo Mondi struct rkisp1_params *params = video_get_drvdata(video); 2451f848c031SJacopo Mondi struct v4l2_meta_format *meta = &f->fmt.meta; 2452f848c031SJacopo Mondi 2453f848c031SJacopo Mondi if (f->type != video->queue->type) 2454f848c031SJacopo Mondi return -EINVAL; 2455f848c031SJacopo Mondi 2456f848c031SJacopo Mondi if (vb2_is_busy(video->queue)) 2457f848c031SJacopo Mondi return -EBUSY; 2458f848c031SJacopo Mondi 2459f848c031SJacopo Mondi params->metafmt = rkisp1_params_get_format_info(meta->dataformat); 2460f848c031SJacopo Mondi *meta = *params->metafmt; 2461e6938cc1SHelen Koike 2462e6938cc1SHelen Koike return 0; 2463e6938cc1SHelen Koike } 2464e6938cc1SHelen Koike 2465e6938cc1SHelen Koike static int rkisp1_params_querycap(struct file *file, 2466e6938cc1SHelen Koike void *priv, struct v4l2_capability *cap) 2467e6938cc1SHelen Koike { 2468e6938cc1SHelen Koike struct video_device *vdev = video_devdata(file); 2469e6938cc1SHelen Koike 2470e6938cc1SHelen Koike strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver)); 2471e6938cc1SHelen Koike strscpy(cap->card, vdev->name, sizeof(cap->card)); 2472e6938cc1SHelen Koike strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info)); 2473e6938cc1SHelen Koike 2474e6938cc1SHelen Koike return 0; 2475e6938cc1SHelen Koike } 2476e6938cc1SHelen Koike 2477e6938cc1SHelen Koike /* ISP params video device IOCTLs */ 2478e6938cc1SHelen Koike static const struct v4l2_ioctl_ops rkisp1_params_ioctl = { 2479e6938cc1SHelen Koike .vidioc_reqbufs = vb2_ioctl_reqbufs, 2480e6938cc1SHelen Koike .vidioc_querybuf = vb2_ioctl_querybuf, 2481e6938cc1SHelen Koike .vidioc_create_bufs = vb2_ioctl_create_bufs, 2482e6938cc1SHelen Koike .vidioc_qbuf = vb2_ioctl_qbuf, 2483e6938cc1SHelen Koike .vidioc_dqbuf = vb2_ioctl_dqbuf, 2484e6938cc1SHelen Koike .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 2485e6938cc1SHelen Koike .vidioc_expbuf = vb2_ioctl_expbuf, 2486e6938cc1SHelen Koike .vidioc_streamon = vb2_ioctl_streamon, 2487e6938cc1SHelen Koike .vidioc_streamoff = vb2_ioctl_streamoff, 2488e6938cc1SHelen Koike .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out, 2489e6938cc1SHelen Koike .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out, 2490f848c031SJacopo Mondi .vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out, 2491f848c031SJacopo Mondi .vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out, 2492e6938cc1SHelen Koike .vidioc_querycap = rkisp1_params_querycap, 2493e6938cc1SHelen Koike .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 2494e6938cc1SHelen Koike .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 2495e6938cc1SHelen Koike }; 2496e6938cc1SHelen Koike 2497e6938cc1SHelen Koike static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq, 2498e6938cc1SHelen Koike unsigned int *num_buffers, 2499e6938cc1SHelen Koike unsigned int *num_planes, 2500e6938cc1SHelen Koike unsigned int sizes[], 2501e6938cc1SHelen Koike struct device *alloc_devs[]) 2502e6938cc1SHelen Koike { 250316398399SJacopo Mondi struct rkisp1_params *params = vq->drv_priv; 250416398399SJacopo Mondi 2505e6938cc1SHelen Koike *num_buffers = clamp_t(u32, *num_buffers, 2506e6938cc1SHelen Koike RKISP1_ISP_PARAMS_REQ_BUFS_MIN, 2507e6938cc1SHelen Koike RKISP1_ISP_PARAMS_REQ_BUFS_MAX); 2508e6938cc1SHelen Koike 2509e6938cc1SHelen Koike *num_planes = 1; 2510e6938cc1SHelen Koike 251116398399SJacopo Mondi sizes[0] = params->metafmt->buffersize; 2512e6938cc1SHelen Koike 2513e6938cc1SHelen Koike return 0; 2514e6938cc1SHelen Koike } 2515e6938cc1SHelen Koike 2516092e276dSJacopo Mondi static int rkisp1_params_vb2_buf_init(struct vb2_buffer *vb) 2517092e276dSJacopo Mondi { 2518092e276dSJacopo Mondi struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2519092e276dSJacopo Mondi struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 252016398399SJacopo Mondi struct rkisp1_params *params = vb->vb2_queue->drv_priv; 2521092e276dSJacopo Mondi 252216398399SJacopo Mondi params_buf->cfg = kvmalloc(params->metafmt->buffersize, 252316398399SJacopo Mondi GFP_KERNEL); 2524092e276dSJacopo Mondi if (!params_buf->cfg) 2525092e276dSJacopo Mondi return -ENOMEM; 2526092e276dSJacopo Mondi 2527092e276dSJacopo Mondi return 0; 2528092e276dSJacopo Mondi } 2529092e276dSJacopo Mondi 2530092e276dSJacopo Mondi static void rkisp1_params_vb2_buf_cleanup(struct vb2_buffer *vb) 2531092e276dSJacopo Mondi { 2532092e276dSJacopo Mondi struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2533092e276dSJacopo Mondi struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 2534092e276dSJacopo Mondi 2535092e276dSJacopo Mondi kvfree(params_buf->cfg); 2536092e276dSJacopo Mondi params_buf->cfg = NULL; 2537092e276dSJacopo Mondi } 2538092e276dSJacopo Mondi 2539e6938cc1SHelen Koike static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) 2540e6938cc1SHelen Koike { 2541e6938cc1SHelen Koike struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2542092e276dSJacopo Mondi struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 2543e6938cc1SHelen Koike struct vb2_queue *vq = vb->vb2_queue; 2544e6938cc1SHelen Koike struct rkisp1_params *params = vq->drv_priv; 2545e6938cc1SHelen Koike 2546e6938cc1SHelen Koike spin_lock_irq(¶ms->config_lock); 2547e6938cc1SHelen Koike list_add_tail(¶ms_buf->queue, ¶ms->params); 2548e6938cc1SHelen Koike spin_unlock_irq(¶ms->config_lock); 2549e6938cc1SHelen Koike } 2550e6938cc1SHelen Koike 25516c53a7b6SJacopo Mondi static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params, 25526c53a7b6SJacopo Mondi struct vb2_buffer *vb) 2553e6938cc1SHelen Koike { 2554092e276dSJacopo Mondi struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2555092e276dSJacopo Mondi struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 25566c53a7b6SJacopo Mondi size_t header_size = offsetof(struct rkisp1_ext_params_cfg, data); 25576c53a7b6SJacopo Mondi struct rkisp1_ext_params_cfg *cfg = params_buf->cfg; 25586c53a7b6SJacopo Mondi size_t payload_size = vb2_get_plane_payload(vb, 0); 25596c53a7b6SJacopo Mondi struct rkisp1_ext_params_cfg *usr_cfg = 25606c53a7b6SJacopo Mondi vb2_plane_vaddr(&vbuf->vb2_buf, 0); 25616c53a7b6SJacopo Mondi size_t block_offset = 0; 25626c53a7b6SJacopo Mondi size_t cfg_size; 2563092e276dSJacopo Mondi 25646c53a7b6SJacopo Mondi /* 25656c53a7b6SJacopo Mondi * Validate the buffer payload size before copying the parameters. The 25666c53a7b6SJacopo Mondi * payload has to be smaller than the destination buffer size and larger 25676c53a7b6SJacopo Mondi * than the header size. 25686c53a7b6SJacopo Mondi */ 25696c53a7b6SJacopo Mondi if (payload_size > params->metafmt->buffersize) { 25706c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 25716c53a7b6SJacopo Mondi "Too large buffer payload size %zu\n", payload_size); 25726c53a7b6SJacopo Mondi return -EINVAL; 25736c53a7b6SJacopo Mondi } 25746c53a7b6SJacopo Mondi 25756c53a7b6SJacopo Mondi if (payload_size < header_size) { 25766c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 25776c53a7b6SJacopo Mondi "Buffer payload %zu smaller than header size %zu\n", 25786c53a7b6SJacopo Mondi payload_size, header_size); 25796c53a7b6SJacopo Mondi return -EINVAL; 25806c53a7b6SJacopo Mondi } 25816c53a7b6SJacopo Mondi 25826c53a7b6SJacopo Mondi /* 25836c53a7b6SJacopo Mondi * Copy the parameters buffer to the internal scratch buffer to avoid 25846c53a7b6SJacopo Mondi * userspace modifying the buffer content while the driver processes it. 25856c53a7b6SJacopo Mondi */ 25866c53a7b6SJacopo Mondi memcpy(cfg, usr_cfg, payload_size); 25876c53a7b6SJacopo Mondi 25886c53a7b6SJacopo Mondi /* Only v1 is supported at the moment. */ 25896c53a7b6SJacopo Mondi if (cfg->version != RKISP1_EXT_PARAM_BUFFER_V1) { 25906c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 25916c53a7b6SJacopo Mondi "Unsupported extensible format version: %u\n", 25926c53a7b6SJacopo Mondi cfg->version); 25936c53a7b6SJacopo Mondi return -EINVAL; 25946c53a7b6SJacopo Mondi } 25956c53a7b6SJacopo Mondi 25966c53a7b6SJacopo Mondi /* Validate the size reported in the parameters buffer header. */ 25976c53a7b6SJacopo Mondi cfg_size = header_size + cfg->data_size; 25986c53a7b6SJacopo Mondi if (cfg_size != payload_size) { 25996c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 26006c53a7b6SJacopo Mondi "Data size %zu different than buffer payload size %zu\n", 26016c53a7b6SJacopo Mondi cfg_size, payload_size); 26026c53a7b6SJacopo Mondi return -EINVAL; 26036c53a7b6SJacopo Mondi } 26046c53a7b6SJacopo Mondi 26056c53a7b6SJacopo Mondi /* Walk the list of parameter blocks and validate them. */ 26066c53a7b6SJacopo Mondi cfg_size = cfg->data_size; 26076c53a7b6SJacopo Mondi while (cfg_size >= sizeof(struct rkisp1_ext_params_block_header)) { 26086c53a7b6SJacopo Mondi const struct rkisp1_ext_params_block_header *block; 26096c53a7b6SJacopo Mondi const struct rkisp1_ext_params_handler *handler; 26106c53a7b6SJacopo Mondi 26116c53a7b6SJacopo Mondi block = (const struct rkisp1_ext_params_block_header *) 26126c53a7b6SJacopo Mondi &cfg->data[block_offset]; 26136c53a7b6SJacopo Mondi 26146c53a7b6SJacopo Mondi if (block->type >= ARRAY_SIZE(rkisp1_ext_params_handlers)) { 26156c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 26166c53a7b6SJacopo Mondi "Invalid parameters block type\n"); 26176c53a7b6SJacopo Mondi return -EINVAL; 26186c53a7b6SJacopo Mondi } 26196c53a7b6SJacopo Mondi 26206c53a7b6SJacopo Mondi if (block->size > cfg_size) { 26216c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 26226c53a7b6SJacopo Mondi "Premature end of parameters data\n"); 26236c53a7b6SJacopo Mondi return -EINVAL; 26246c53a7b6SJacopo Mondi } 26256c53a7b6SJacopo Mondi 26266c53a7b6SJacopo Mondi if ((block->flags & (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE | 26276c53a7b6SJacopo Mondi RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) == 26286c53a7b6SJacopo Mondi (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE | 26296c53a7b6SJacopo Mondi RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) { 26306c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 26316c53a7b6SJacopo Mondi "Invalid parameters block flags\n"); 26326c53a7b6SJacopo Mondi return -EINVAL; 26336c53a7b6SJacopo Mondi } 26346c53a7b6SJacopo Mondi 26356c53a7b6SJacopo Mondi handler = &rkisp1_ext_params_handlers[block->type]; 26366c53a7b6SJacopo Mondi if (block->size != handler->size) { 26376c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 26386c53a7b6SJacopo Mondi "Invalid parameters block size\n"); 26396c53a7b6SJacopo Mondi return -EINVAL; 26406c53a7b6SJacopo Mondi } 26416c53a7b6SJacopo Mondi 26426c53a7b6SJacopo Mondi block_offset += block->size; 26436c53a7b6SJacopo Mondi cfg_size -= block->size; 26446c53a7b6SJacopo Mondi } 26456c53a7b6SJacopo Mondi 26466c53a7b6SJacopo Mondi if (cfg_size) { 26476c53a7b6SJacopo Mondi dev_dbg(params->rkisp1->dev, 26486c53a7b6SJacopo Mondi "Unexpected data after the parameters buffer end\n"); 26496c53a7b6SJacopo Mondi return -EINVAL; 26506c53a7b6SJacopo Mondi } 26516c53a7b6SJacopo Mondi 26526c53a7b6SJacopo Mondi return 0; 26536c53a7b6SJacopo Mondi } 26546c53a7b6SJacopo Mondi 26556c53a7b6SJacopo Mondi static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb) 26566c53a7b6SJacopo Mondi { 26576c53a7b6SJacopo Mondi struct rkisp1_params *params = vb->vb2_queue->drv_priv; 26586c53a7b6SJacopo Mondi struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 26596c53a7b6SJacopo Mondi struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 26606c53a7b6SJacopo Mondi struct rkisp1_params_cfg *cfg = vb2_plane_vaddr(&vbuf->vb2_buf, 0); 26616c53a7b6SJacopo Mondi size_t payload = vb2_get_plane_payload(vb, 0); 26626c53a7b6SJacopo Mondi 26636c53a7b6SJacopo Mondi if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_EXT_PARAMS) 26646c53a7b6SJacopo Mondi return rkisp1_params_prepare_ext_params(params, vb); 26656c53a7b6SJacopo Mondi 26666c53a7b6SJacopo Mondi /* 26676c53a7b6SJacopo Mondi * For the fixed parameters format the payload size must be exactly the 26686c53a7b6SJacopo Mondi * size of the parameters structure. 26696c53a7b6SJacopo Mondi */ 26706c53a7b6SJacopo Mondi if (payload != sizeof(*cfg)) 2671e6938cc1SHelen Koike return -EINVAL; 2672e6938cc1SHelen Koike 2673092e276dSJacopo Mondi /* 2674092e276dSJacopo Mondi * Copy the parameters buffer to the internal scratch buffer to avoid 2675092e276dSJacopo Mondi * userspace modifying the buffer content while the driver processes it. 2676092e276dSJacopo Mondi */ 26776c53a7b6SJacopo Mondi memcpy(params_buf->cfg, cfg, payload); 2678e6938cc1SHelen Koike 2679e6938cc1SHelen Koike return 0; 2680e6938cc1SHelen Koike } 2681e6938cc1SHelen Koike 2682e6938cc1SHelen Koike static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) 2683e6938cc1SHelen Koike { 2684e6938cc1SHelen Koike struct rkisp1_params *params = vq->drv_priv; 26853bdae13aSJacopo Mondi struct rkisp1_params_buffer *buf; 2686e6938cc1SHelen Koike LIST_HEAD(tmp_list); 2687e6938cc1SHelen Koike 2688e6938cc1SHelen Koike /* 2689e6938cc1SHelen Koike * we first move the buffers into a local list 'tmp_list' 2690e6938cc1SHelen Koike * and then we can iterate it and call vb2_buffer_done 2691e6938cc1SHelen Koike * without holding the lock 2692e6938cc1SHelen Koike */ 2693e6938cc1SHelen Koike spin_lock_irq(¶ms->config_lock); 2694e6938cc1SHelen Koike list_splice_init(¶ms->params, &tmp_list); 2695e6938cc1SHelen Koike spin_unlock_irq(¶ms->config_lock); 2696e6938cc1SHelen Koike 2697e6938cc1SHelen Koike list_for_each_entry(buf, &tmp_list, queue) 2698e6938cc1SHelen Koike vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 26996c53a7b6SJacopo Mondi 27006c53a7b6SJacopo Mondi params->enabled_blocks = 0; 2701e6938cc1SHelen Koike } 2702e6938cc1SHelen Koike 2703a109073bSRikard Falkeborn static const struct vb2_ops rkisp1_params_vb2_ops = { 2704e6938cc1SHelen Koike .queue_setup = rkisp1_params_vb2_queue_setup, 2705092e276dSJacopo Mondi .buf_init = rkisp1_params_vb2_buf_init, 2706092e276dSJacopo Mondi .buf_cleanup = rkisp1_params_vb2_buf_cleanup, 2707e6938cc1SHelen Koike .wait_prepare = vb2_ops_wait_prepare, 2708e6938cc1SHelen Koike .wait_finish = vb2_ops_wait_finish, 2709e6938cc1SHelen Koike .buf_queue = rkisp1_params_vb2_buf_queue, 2710e6938cc1SHelen Koike .buf_prepare = rkisp1_params_vb2_buf_prepare, 2711e6938cc1SHelen Koike .stop_streaming = rkisp1_params_vb2_stop_streaming, 2712e6938cc1SHelen Koike }; 2713e6938cc1SHelen Koike 2714a109073bSRikard Falkeborn static const struct v4l2_file_operations rkisp1_params_fops = { 2715e6938cc1SHelen Koike .mmap = vb2_fop_mmap, 2716e6938cc1SHelen Koike .unlocked_ioctl = video_ioctl2, 2717e6938cc1SHelen Koike .poll = vb2_fop_poll, 2718e6938cc1SHelen Koike .open = v4l2_fh_open, 2719e6938cc1SHelen Koike .release = vb2_fop_release 2720e6938cc1SHelen Koike }; 2721e6938cc1SHelen Koike 2722e6938cc1SHelen Koike static int rkisp1_params_init_vb2_queue(struct vb2_queue *q, 2723e6938cc1SHelen Koike struct rkisp1_params *params) 2724e6938cc1SHelen Koike { 2725e6938cc1SHelen Koike struct rkisp1_vdev_node *node; 2726e6938cc1SHelen Koike 2727e6938cc1SHelen Koike node = container_of(q, struct rkisp1_vdev_node, buf_queue); 2728e6938cc1SHelen Koike 2729e6938cc1SHelen Koike q->type = V4L2_BUF_TYPE_META_OUTPUT; 2730e6938cc1SHelen Koike q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 2731e6938cc1SHelen Koike q->drv_priv = params; 2732e6938cc1SHelen Koike q->ops = &rkisp1_params_vb2_ops; 2733e6938cc1SHelen Koike q->mem_ops = &vb2_vmalloc_memops; 27343bdae13aSJacopo Mondi q->buf_struct_size = sizeof(struct rkisp1_params_buffer); 2735e6938cc1SHelen Koike q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 2736e6938cc1SHelen Koike q->lock = &node->vlock; 2737e6938cc1SHelen Koike 2738e6938cc1SHelen Koike return vb2_queue_init(q); 2739e6938cc1SHelen Koike } 2740e6938cc1SHelen Koike 2741e6938cc1SHelen Koike int rkisp1_params_register(struct rkisp1_device *rkisp1) 2742e6938cc1SHelen Koike { 2743e6938cc1SHelen Koike struct rkisp1_params *params = &rkisp1->params; 2744e6938cc1SHelen Koike struct rkisp1_vdev_node *node = ¶ms->vnode; 2745e6938cc1SHelen Koike struct video_device *vdev = &node->vdev; 2746e6938cc1SHelen Koike int ret; 2747e6938cc1SHelen Koike 2748e6938cc1SHelen Koike params->rkisp1 = rkisp1; 2749e6938cc1SHelen Koike mutex_init(&node->vlock); 2750e6938cc1SHelen Koike INIT_LIST_HEAD(¶ms->params); 2751e6938cc1SHelen Koike spin_lock_init(¶ms->config_lock); 2752e6938cc1SHelen Koike 2753e6938cc1SHelen Koike strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name)); 2754e6938cc1SHelen Koike 2755e6938cc1SHelen Koike video_set_drvdata(vdev, params); 2756e6938cc1SHelen Koike vdev->ioctl_ops = &rkisp1_params_ioctl; 2757e6938cc1SHelen Koike vdev->fops = &rkisp1_params_fops; 2758e6938cc1SHelen Koike vdev->release = video_device_release_empty; 2759e6938cc1SHelen Koike /* 2760e6938cc1SHelen Koike * Provide a mutex to v4l2 core. It will be used 2761e6938cc1SHelen Koike * to protect all fops and v4l2 ioctls. 2762e6938cc1SHelen Koike */ 2763e6938cc1SHelen Koike vdev->lock = &node->vlock; 2764e6938cc1SHelen Koike vdev->v4l2_dev = &rkisp1->v4l2_dev; 2765e6938cc1SHelen Koike vdev->queue = &node->buf_queue; 2766e6938cc1SHelen Koike vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT; 2767e6938cc1SHelen Koike vdev->vfl_dir = VFL_DIR_TX; 2768e6938cc1SHelen Koike rkisp1_params_init_vb2_queue(vdev->queue, params); 276916398399SJacopo Mondi 277016398399SJacopo Mondi params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED]; 277116398399SJacopo Mondi 277216398399SJacopo Mondi if (params->rkisp1->info->isp_ver == RKISP1_V12) 277316398399SJacopo Mondi params->ops = &rkisp1_v12_params_ops; 277416398399SJacopo Mondi else 277516398399SJacopo Mondi params->ops = &rkisp1_v10_params_ops; 277616398399SJacopo Mondi 2777e6938cc1SHelen Koike video_set_drvdata(vdev, params); 2778e6938cc1SHelen Koike 2779e6938cc1SHelen Koike node->pad.flags = MEDIA_PAD_FL_SOURCE; 2780e6938cc1SHelen Koike ret = media_entity_pads_init(&vdev->entity, 1, &node->pad); 2781e6938cc1SHelen Koike if (ret) 27828ba4862eSLaurent Pinchart goto error; 27838ba4862eSLaurent Pinchart 2784e6938cc1SHelen Koike ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 2785e6938cc1SHelen Koike if (ret) { 2786e6938cc1SHelen Koike dev_err(rkisp1->dev, 2787e6938cc1SHelen Koike "failed to register %s, ret=%d\n", vdev->name, ret); 27888ba4862eSLaurent Pinchart goto error; 2789e6938cc1SHelen Koike } 27908ba4862eSLaurent Pinchart 2791e6938cc1SHelen Koike return 0; 27928ba4862eSLaurent Pinchart 27938ba4862eSLaurent Pinchart error: 2794e6938cc1SHelen Koike media_entity_cleanup(&vdev->entity); 27958ba4862eSLaurent Pinchart mutex_destroy(&node->vlock); 2796e6938cc1SHelen Koike return ret; 2797e6938cc1SHelen Koike } 2798e6938cc1SHelen Koike 2799e6938cc1SHelen Koike void rkisp1_params_unregister(struct rkisp1_device *rkisp1) 2800e6938cc1SHelen Koike { 2801e6938cc1SHelen Koike struct rkisp1_params *params = &rkisp1->params; 2802e6938cc1SHelen Koike struct rkisp1_vdev_node *node = ¶ms->vnode; 2803e6938cc1SHelen Koike struct video_device *vdev = &node->vdev; 2804e6938cc1SHelen Koike 28058ba4862eSLaurent Pinchart if (!video_is_registered(vdev)) 28068ba4862eSLaurent Pinchart return; 28078ba4862eSLaurent Pinchart 2808e6938cc1SHelen Koike vb2_video_unregister_device(vdev); 2809e6938cc1SHelen Koike media_entity_cleanup(&vdev->entity); 28108ba4862eSLaurent Pinchart mutex_destroy(&node->vlock); 2811e6938cc1SHelen Koike } 2812