2812 lines · c
1// SPDX-License-Identifier: (GPL-2.0+ OR MIT)2/*3 * Rockchip ISP1 Driver - Params subdevice4 *5 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.6 */7 8#include <linux/math.h>9#include <linux/string.h>10 11#include <media/v4l2-common.h>12#include <media/v4l2-event.h>13#include <media/v4l2-ioctl.h>14#include <media/videobuf2-core.h>15#include <media/videobuf2-vmalloc.h> /* for ISP params */16 17#include "rkisp1-common.h"18 19#define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params"20 21#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 222#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 823 24#define RKISP1_ISP_DPCC_METHODS_SET(n) \25 (RKISP1_CIF_ISP_DPCC_METHODS_SET_1 + 0x4 * (n))26#define RKISP1_ISP_DPCC_LINE_THRESH(n) \27 (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))28#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \29 (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))30#define RKISP1_ISP_DPCC_PG_FAC(n) \31 (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))32#define RKISP1_ISP_DPCC_RND_THRESH(n) \33 (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))34#define RKISP1_ISP_DPCC_RG_FAC(n) \35 (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))36#define RKISP1_ISP_CC_COEFF(n) \37 (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)38 39#define RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS BIT(0)40#define RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC BIT(1)41 42union rkisp1_ext_params_config {43 struct rkisp1_ext_params_block_header header;44 struct rkisp1_ext_params_bls_config bls;45 struct rkisp1_ext_params_dpcc_config dpcc;46 struct rkisp1_ext_params_sdg_config sdg;47 struct rkisp1_ext_params_lsc_config lsc;48 struct rkisp1_ext_params_awb_gain_config awbg;49 struct rkisp1_ext_params_flt_config flt;50 struct rkisp1_ext_params_bdm_config bdm;51 struct rkisp1_ext_params_ctk_config ctk;52 struct rkisp1_ext_params_goc_config goc;53 struct rkisp1_ext_params_dpf_config dpf;54 struct rkisp1_ext_params_dpf_strength_config dpfs;55 struct rkisp1_ext_params_cproc_config cproc;56 struct rkisp1_ext_params_ie_config ie;57 struct rkisp1_ext_params_awb_meas_config awbm;58 struct rkisp1_ext_params_hst_config hst;59 struct rkisp1_ext_params_aec_config aec;60 struct rkisp1_ext_params_afc_config afc;61 struct rkisp1_ext_params_compand_bls_config compand_bls;62 struct rkisp1_ext_params_compand_curve_config compand_curve;63};64 65enum rkisp1_params_formats {66 RKISP1_PARAMS_FIXED,67 RKISP1_PARAMS_EXTENSIBLE,68};69 70static const struct v4l2_meta_format rkisp1_params_formats[] = {71 [RKISP1_PARAMS_FIXED] = {72 .dataformat = V4L2_META_FMT_RK_ISP1_PARAMS,73 .buffersize = sizeof(struct rkisp1_params_cfg),74 },75 [RKISP1_PARAMS_EXTENSIBLE] = {76 .dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS,77 .buffersize = sizeof(struct rkisp1_ext_params_cfg),78 },79};80 81static const struct v4l2_meta_format *82rkisp1_params_get_format_info(u32 dataformat)83{84 for (unsigned int i = 0; i < ARRAY_SIZE(rkisp1_params_formats); i++) {85 if (rkisp1_params_formats[i].dataformat == dataformat)86 return &rkisp1_params_formats[i];87 }88 89 return &rkisp1_params_formats[RKISP1_PARAMS_FIXED];90}91 92static inline void93rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)94{95 u32 val;96 97 val = rkisp1_read(params->rkisp1, reg);98 rkisp1_write(params->rkisp1, reg, val | bit_mask);99}100 101static inline void102rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)103{104 u32 val;105 106 val = rkisp1_read(params->rkisp1, reg);107 rkisp1_write(params->rkisp1, reg, val & ~bit_mask);108}109 110/* ISP BP interface function */111static void rkisp1_dpcc_config(struct rkisp1_params *params,112 const struct rkisp1_cif_isp_dpcc_config *arg)113{114 unsigned int i;115 u32 mode;116 117 /*118 * The enable bit is controlled in rkisp1_isp_isr_other_config() and119 * must be preserved. The grayscale mode should be configured120 * automatically based on the media bus code on the ISP sink pad, so121 * only the STAGE1_ENABLE bit can be set by userspace.122 */123 mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);124 mode &= RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE;125 mode |= arg->mode & RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE;126 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE, mode);127 128 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_OUTPUT_MODE,129 arg->output_mode & RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_MASK);130 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_SET_USE,131 arg->set_use & RKISP1_CIF_ISP_DPCC_SET_USE_MASK);132 133 for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {134 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_METHODS_SET(i),135 arg->methods[i].method &136 RKISP1_CIF_ISP_DPCC_METHODS_SET_MASK);137 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_THRESH(i),138 arg->methods[i].line_thresh &139 RKISP1_CIF_ISP_DPCC_LINE_THRESH_MASK);140 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_MAD_FAC(i),141 arg->methods[i].line_mad_fac &142 RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_MASK);143 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_PG_FAC(i),144 arg->methods[i].pg_fac &145 RKISP1_CIF_ISP_DPCC_PG_FAC_MASK);146 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RND_THRESH(i),147 arg->methods[i].rnd_thresh &148 RKISP1_CIF_ISP_DPCC_RND_THRESH_MASK);149 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RG_FAC(i),150 arg->methods[i].rg_fac &151 RKISP1_CIF_ISP_DPCC_RG_FAC_MASK);152 }153 154 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RND_OFFS,155 arg->rnd_offs & RKISP1_CIF_ISP_DPCC_RND_OFFS_MASK);156 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RO_LIMITS,157 arg->ro_limits & RKISP1_CIF_ISP_DPCC_RO_LIMIT_MASK);158}159 160/* ISP black level subtraction interface function */161static void rkisp1_bls_config(struct rkisp1_params *params,162 const struct rkisp1_cif_isp_bls_config *arg)163{164 /* avoid to override the old enable value */165 u32 new_control;166 167 new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);168 new_control &= RKISP1_CIF_ISP_BLS_ENA;169 /* fixed subtraction values */170 if (!arg->enable_auto) {171 static const u32 regs[] = {172 RKISP1_CIF_ISP_BLS_A_FIXED,173 RKISP1_CIF_ISP_BLS_B_FIXED,174 RKISP1_CIF_ISP_BLS_C_FIXED,175 RKISP1_CIF_ISP_BLS_D_FIXED,176 };177 u32 swapped[4];178 179 rkisp1_bls_swap_regs(params->raw_type, regs, swapped);180 181 rkisp1_write(params->rkisp1, swapped[0], arg->fixed_val.r);182 rkisp1_write(params->rkisp1, swapped[1], arg->fixed_val.gr);183 rkisp1_write(params->rkisp1, swapped[2], arg->fixed_val.gb);184 rkisp1_write(params->rkisp1, swapped[3], arg->fixed_val.b);185 } else {186 if (arg->en_windows & BIT(1)) {187 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_START,188 arg->bls_window2.h_offs);189 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_STOP,190 arg->bls_window2.h_size);191 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V2_START,192 arg->bls_window2.v_offs);193 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V2_STOP,194 arg->bls_window2.v_size);195 new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;196 }197 198 if (arg->en_windows & BIT(0)) {199 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H1_START,200 arg->bls_window1.h_offs);201 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H1_STOP,202 arg->bls_window1.h_size);203 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V1_START,204 arg->bls_window1.v_offs);205 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V1_STOP,206 arg->bls_window1.v_size);207 new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;208 }209 210 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_SAMPLES,211 arg->bls_samples);212 213 new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;214 }215 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL, new_control);216}217 218/* ISP LS correction interface function */219static void220rkisp1_lsc_matrix_config_v10(struct rkisp1_params *params,221 const struct rkisp1_cif_isp_lsc_config *pconfig)222{223 struct rkisp1_device *rkisp1 = params->rkisp1;224 u32 lsc_status, sram_addr, lsc_table_sel;225 unsigned int i, j;226 227 lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS);228 229 /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */230 sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?231 RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :232 RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;233 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr);234 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr);235 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr);236 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr);237 238 /* program data tables (table size is 9 * 17 = 153) */239 for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {240 const __u16 *r_tbl = pconfig->r_data_tbl[i];241 const __u16 *gr_tbl = pconfig->gr_data_tbl[i];242 const __u16 *gb_tbl = pconfig->gb_data_tbl[i];243 const __u16 *b_tbl = pconfig->b_data_tbl[i];244 245 /*246 * 17 sectors with 2 values in one DWORD = 9247 * DWORDs (2nd value of last DWORD unused)248 */249 for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {250 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,251 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(252 r_tbl[j], r_tbl[j + 1]));253 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,254 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(255 gr_tbl[j], gr_tbl[j + 1]));256 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,257 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(258 gb_tbl[j], gb_tbl[j + 1]));259 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,260 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(261 b_tbl[j], b_tbl[j + 1]));262 }263 264 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,265 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(r_tbl[j], 0));266 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,267 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gr_tbl[j], 0));268 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,269 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gb_tbl[j], 0));270 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,271 RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(b_tbl[j], 0));272 }273 274 lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?275 RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1;276 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel);277}278 279static void280rkisp1_lsc_matrix_config_v12(struct rkisp1_params *params,281 const struct rkisp1_cif_isp_lsc_config *pconfig)282{283 struct rkisp1_device *rkisp1 = params->rkisp1;284 u32 lsc_status, sram_addr, lsc_table_sel;285 unsigned int i, j;286 287 lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS);288 289 /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */290 sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?291 RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :292 RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;293 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr);294 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr);295 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr);296 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr);297 298 /* program data tables (table size is 9 * 17 = 153) */299 for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {300 const __u16 *r_tbl = pconfig->r_data_tbl[i];301 const __u16 *gr_tbl = pconfig->gr_data_tbl[i];302 const __u16 *gb_tbl = pconfig->gb_data_tbl[i];303 const __u16 *b_tbl = pconfig->b_data_tbl[i];304 305 /*306 * 17 sectors with 2 values in one DWORD = 9307 * DWORDs (2nd value of last DWORD unused)308 */309 for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {310 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,311 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(312 r_tbl[j], r_tbl[j + 1]));313 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,314 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(315 gr_tbl[j], gr_tbl[j + 1]));316 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,317 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(318 gb_tbl[j], gb_tbl[j + 1]));319 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,320 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(321 b_tbl[j], b_tbl[j + 1]));322 }323 324 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,325 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(r_tbl[j], 0));326 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,327 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gr_tbl[j], 0));328 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,329 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gb_tbl[j], 0));330 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,331 RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(b_tbl[j], 0));332 }333 334 lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?335 RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1;336 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel);337}338 339static void rkisp1_lsc_config(struct rkisp1_params *params,340 const struct rkisp1_cif_isp_lsc_config *arg)341{342 struct rkisp1_device *rkisp1 = params->rkisp1;343 u32 lsc_ctrl, data;344 unsigned int i;345 346 /* To config must be off , store the current status firstly */347 lsc_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_CTRL);348 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,349 RKISP1_CIF_ISP_LSC_CTRL_ENA);350 params->ops->lsc_matrix_config(params, arg);351 352 for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {353 /* program x size tables */354 data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],355 arg->x_size_tbl[i * 2 + 1]);356 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XSIZE(i), data);357 358 /* program x grad tables */359 data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2],360 arg->x_grad_tbl[i * 2 + 1]);361 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XGRAD(i), data);362 363 /* program y size tables */364 data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],365 arg->y_size_tbl[i * 2 + 1]);366 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YSIZE(i), data);367 368 /* program y grad tables */369 data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2],370 arg->y_grad_tbl[i * 2 + 1]);371 rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YGRAD(i), data);372 }373 374 /* restore the lsc ctrl status */375 if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA)376 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL,377 RKISP1_CIF_ISP_LSC_CTRL_ENA);378 else379 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,380 RKISP1_CIF_ISP_LSC_CTRL_ENA);381}382 383/* ISP Filtering function */384static void rkisp1_flt_config(struct rkisp1_params *params,385 const struct rkisp1_cif_isp_flt_config *arg)386{387 u32 filt_mode;388 389 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_BL0,390 arg->thresh_bl0);391 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_BL1,392 arg->thresh_bl1);393 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_SH0,394 arg->thresh_sh0);395 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_SH1,396 arg->thresh_sh1);397 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_BL0,398 arg->fac_bl0);399 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_BL1,400 arg->fac_bl1);401 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_MID,402 arg->fac_mid);403 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_SH0,404 arg->fac_sh0);405 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_SH1,406 arg->fac_sh1);407 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_LUM_WEIGHT,408 arg->lum_weight);409 410 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE,411 (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |412 RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |413 RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |414 RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1));415 416 /* avoid to override the old enable value */417 filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);418 filt_mode &= RKISP1_CIF_ISP_FLT_ENA;419 if (arg->mode)420 filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;421 filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |422 RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |423 RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);424 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE, filt_mode);425}426 427/* ISP demosaic interface function */428static int rkisp1_bdm_config(struct rkisp1_params *params,429 const struct rkisp1_cif_isp_bdm_config *arg)430{431 u32 bdm_th;432 433 /* avoid to override the old enable value */434 bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);435 bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;436 bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;437 /* set demosaic threshold */438 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC, bdm_th);439 return 0;440}441 442/* ISP GAMMA correction interface function */443static void rkisp1_sdg_config(struct rkisp1_params *params,444 const struct rkisp1_cif_isp_sdg_config *arg)445{446 unsigned int i;447 448 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_DX_LO,449 arg->xa_pnts.gamma_dx0);450 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_DX_HI,451 arg->xa_pnts.gamma_dx1);452 453 for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {454 rkisp1_write(params->rkisp1,455 RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4,456 arg->curve_r.gamma_y[i]);457 rkisp1_write(params->rkisp1,458 RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4,459 arg->curve_g.gamma_y[i]);460 rkisp1_write(params->rkisp1,461 RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4,462 arg->curve_b.gamma_y[i]);463 }464}465 466/* ISP GAMMA correction interface function */467static void rkisp1_goc_config_v10(struct rkisp1_params *params,468 const struct rkisp1_cif_isp_goc_config *arg)469{470 unsigned int i;471 472 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,473 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);474 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V10,475 arg->mode);476 477 for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++)478 rkisp1_write(params->rkisp1,479 RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V10 + i * 4,480 arg->gamma_y[i]);481}482 483static void rkisp1_goc_config_v12(struct rkisp1_params *params,484 const struct rkisp1_cif_isp_goc_config *arg)485{486 unsigned int i;487 u32 value;488 489 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,490 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);491 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V12,492 arg->mode);493 494 for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 / 2; i++) {495 value = RKISP1_CIF_ISP_GAMMA_VALUE_V12(496 arg->gamma_y[2 * i + 1],497 arg->gamma_y[2 * i]);498 rkisp1_write(params->rkisp1,499 RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V12 + i * 4, value);500 }501}502 503/* ISP Cross Talk */504static void rkisp1_ctk_config(struct rkisp1_params *params,505 const struct rkisp1_cif_isp_ctk_config *arg)506{507 unsigned int i, j, k = 0;508 509 for (i = 0; i < 3; i++)510 for (j = 0; j < 3; j++)511 rkisp1_write(params->rkisp1,512 RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++,513 arg->coeff[i][j]);514 for (i = 0; i < 3; i++)515 rkisp1_write(params->rkisp1,516 RKISP1_CIF_ISP_CT_OFFSET_R + i * 4,517 arg->ct_offset[i]);518}519 520static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)521{522 if (en)523 return;524 525 /* Write back the default values. */526 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_0, 0x80);527 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_1, 0);528 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_2, 0);529 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_3, 0);530 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_4, 0x80);531 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_5, 0);532 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_6, 0);533 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_7, 0);534 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_8, 0x80);535 536 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_R, 0);537 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_G, 0);538 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_B, 0);539}540 541/* ISP White Balance Mode */542static void rkisp1_awb_meas_config_v10(struct rkisp1_params *params,543 const struct rkisp1_cif_isp_awb_meas_config *arg)544{545 u32 reg_val = 0;546 /* based on the mode,configure the awb module */547 if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {548 /* Reference Cb and Cr */549 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_REF_V10,550 RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |551 arg->awb_ref_cb);552 /* Yc Threshold */553 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_THRESH_V10,554 RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |555 RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |556 RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |557 arg->min_c);558 }559 560 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10);561 if (arg->enable_ymax_cmp)562 reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;563 else564 reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;565 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10, reg_val);566 567 /* window offset */568 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_V_OFFS_V10,569 arg->awb_wnd.v_offs);570 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_H_OFFS_V10,571 arg->awb_wnd.h_offs);572 /* AWB window size */573 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_V_SIZE_V10,574 arg->awb_wnd.v_size);575 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_H_SIZE_V10,576 arg->awb_wnd.h_size);577 /* Number of frames */578 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_FRAMES_V10,579 arg->frames);580}581 582static void rkisp1_awb_meas_config_v12(struct rkisp1_params *params,583 const struct rkisp1_cif_isp_awb_meas_config *arg)584{585 u32 reg_val = 0;586 /* based on the mode,configure the awb module */587 if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {588 /* Reference Cb and Cr */589 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_REF_V12,590 RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |591 arg->awb_ref_cb);592 /* Yc Threshold */593 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_THRESH_V12,594 RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |595 RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |596 RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |597 arg->min_c);598 }599 600 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);601 if (arg->enable_ymax_cmp)602 reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;603 else604 reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;605 reg_val &= ~RKISP1_CIF_ISP_AWB_SET_FRAMES_MASK_V12;606 reg_val |= RKISP1_CIF_ISP_AWB_SET_FRAMES_V12(arg->frames);607 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12, reg_val);608 609 /* window offset */610 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_OFFS_V12,611 arg->awb_wnd.v_offs << 16 | arg->awb_wnd.h_offs);612 /* AWB window size */613 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_SIZE_V12,614 arg->awb_wnd.v_size << 16 | arg->awb_wnd.h_size);615}616 617static void618rkisp1_awb_meas_enable_v10(struct rkisp1_params *params,619 const struct rkisp1_cif_isp_awb_meas_config *arg,620 bool en)621{622 u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10);623 624 /* switch off */625 reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;626 627 if (en) {628 if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)629 reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;630 else631 reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;632 633 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10,634 reg_val);635 636 /* Measurements require AWB block be active. */637 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,638 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);639 } else {640 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10,641 reg_val);642 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,643 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);644 }645}646 647static void648rkisp1_awb_meas_enable_v12(struct rkisp1_params *params,649 const struct rkisp1_cif_isp_awb_meas_config *arg,650 bool en)651{652 u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);653 654 /* switch off */655 reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;656 657 if (en) {658 if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)659 reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;660 else661 reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;662 663 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12,664 reg_val);665 666 /* Measurements require AWB block be active. */667 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,668 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);669 } else {670 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12,671 reg_val);672 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,673 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);674 }675}676 677static void678rkisp1_awb_gain_config_v10(struct rkisp1_params *params,679 const struct rkisp1_cif_isp_awb_gain_config *arg)680{681 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_G_V10,682 RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |683 arg->gain_green_b);684 685 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_RB_V10,686 RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |687 arg->gain_blue);688}689 690static void691rkisp1_awb_gain_config_v12(struct rkisp1_params *params,692 const struct rkisp1_cif_isp_awb_gain_config *arg)693{694 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_G_V12,695 RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |696 arg->gain_green_b);697 698 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_RB_V12,699 RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |700 arg->gain_blue);701}702 703static void rkisp1_aec_config_v10(struct rkisp1_params *params,704 const struct rkisp1_cif_isp_aec_config *arg)705{706 unsigned int block_hsize, block_vsize;707 u32 exp_ctrl;708 709 /* avoid to override the old enable value */710 exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);711 exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;712 if (arg->autostop)713 exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;714 if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)715 exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;716 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL, exp_ctrl);717 718 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_H_OFFSET_V10,719 arg->meas_window.h_offs);720 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_V_OFFSET_V10,721 arg->meas_window.v_offs);722 723 block_hsize = arg->meas_window.h_size /724 RKISP1_CIF_ISP_EXP_COLUMN_NUM_V10 - 1;725 block_vsize = arg->meas_window.v_size /726 RKISP1_CIF_ISP_EXP_ROW_NUM_V10 - 1;727 728 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_H_SIZE_V10,729 RKISP1_CIF_ISP_EXP_H_SIZE_SET_V10(block_hsize));730 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_V_SIZE_V10,731 RKISP1_CIF_ISP_EXP_V_SIZE_SET_V10(block_vsize));732}733 734static void rkisp1_aec_config_v12(struct rkisp1_params *params,735 const struct rkisp1_cif_isp_aec_config *arg)736{737 u32 exp_ctrl;738 u32 block_hsize, block_vsize;739 u32 wnd_num_idx = 1;740 static const u32 ae_wnd_num[] = { 5, 9, 15, 15 };741 742 /* avoid to override the old enable value */743 exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);744 exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;745 if (arg->autostop)746 exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;747 if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)748 exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;749 exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_WNDNUM_SET_V12(wnd_num_idx);750 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL, exp_ctrl);751 752 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_OFFS_V12,753 RKISP1_CIF_ISP_EXP_V_OFFSET_SET_V12(arg->meas_window.v_offs) |754 RKISP1_CIF_ISP_EXP_H_OFFSET_SET_V12(arg->meas_window.h_offs));755 756 block_hsize = arg->meas_window.h_size / ae_wnd_num[wnd_num_idx] - 1;757 block_vsize = arg->meas_window.v_size / ae_wnd_num[wnd_num_idx] - 1;758 759 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_SIZE_V12,760 RKISP1_CIF_ISP_EXP_V_SIZE_SET_V12(block_vsize) |761 RKISP1_CIF_ISP_EXP_H_SIZE_SET_V12(block_hsize));762}763 764static void rkisp1_cproc_config(struct rkisp1_params *params,765 const struct rkisp1_cif_isp_cproc_config *arg)766{767 struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =768 container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);769 struct rkisp1_cif_isp_ie_config *cur_ie_config =770 &cur_other_cfg->ie_config;771 u32 effect = cur_ie_config->effect;772 u32 quantization = params->quantization;773 774 rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_CONTRAST,775 arg->contrast);776 rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_HUE, arg->hue);777 rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_SATURATION, arg->sat);778 rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_BRIGHTNESS,779 arg->brightness);780 781 if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||782 effect != V4L2_COLORFX_NONE) {783 rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,784 RKISP1_CIF_C_PROC_YOUT_FULL |785 RKISP1_CIF_C_PROC_YIN_FULL |786 RKISP1_CIF_C_PROC_COUT_FULL);787 } else {788 rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,789 RKISP1_CIF_C_PROC_YOUT_FULL |790 RKISP1_CIF_C_PROC_YIN_FULL |791 RKISP1_CIF_C_PROC_COUT_FULL);792 }793}794 795static void rkisp1_hst_config_v10(struct rkisp1_params *params,796 const struct rkisp1_cif_isp_hst_config *arg)797{798 unsigned int block_hsize, block_vsize;799 static const u32 hist_weight_regs[] = {800 RKISP1_CIF_ISP_HIST_WEIGHT_00TO30_V10,801 RKISP1_CIF_ISP_HIST_WEIGHT_40TO21_V10,802 RKISP1_CIF_ISP_HIST_WEIGHT_31TO12_V10,803 RKISP1_CIF_ISP_HIST_WEIGHT_22TO03_V10,804 RKISP1_CIF_ISP_HIST_WEIGHT_13TO43_V10,805 RKISP1_CIF_ISP_HIST_WEIGHT_04TO34_V10,806 };807 const u8 *weight;808 unsigned int i;809 u32 hist_prop;810 811 /* avoid to override the old enable value */812 hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10);813 hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10;814 hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET_V10(arg->histogram_predivider);815 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10, hist_prop);816 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_H_OFFS_V10,817 arg->meas_window.h_offs);818 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_V_OFFS_V10,819 arg->meas_window.v_offs);820 821 block_hsize = arg->meas_window.h_size /822 RKISP1_CIF_ISP_HIST_COLUMN_NUM_V10 - 1;823 block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM_V10 - 1;824 825 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_H_SIZE_V10,826 block_hsize);827 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_V_SIZE_V10,828 block_vsize);829 830 weight = arg->hist_weight;831 for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)832 rkisp1_write(params->rkisp1, hist_weight_regs[i],833 RKISP1_CIF_ISP_HIST_WEIGHT_SET_V10(weight[0], weight[1],834 weight[2], weight[3]));835 836 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_WEIGHT_44_V10,837 weight[0] & 0x1f);838}839 840static void rkisp1_hst_config_v12(struct rkisp1_params *params,841 const struct rkisp1_cif_isp_hst_config *arg)842{843 unsigned int i, j;844 u32 block_hsize, block_vsize;845 u32 wnd_num_idx, hist_weight_num, hist_ctrl, value;846 u8 weight15x15[RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12];847 static const u32 hist_wnd_num[] = { 5, 9, 15, 15 };848 849 /* now we just support 9x9 window */850 wnd_num_idx = 1;851 memset(weight15x15, 0x00, sizeof(weight15x15));852 /* avoid to override the old enable value */853 hist_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12);854 hist_ctrl &= RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |855 RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12;856 hist_ctrl = hist_ctrl |857 RKISP1_CIF_ISP_HIST_CTRL_INTRSEL_SET_V12(1) |858 RKISP1_CIF_ISP_HIST_CTRL_DATASEL_SET_V12(0) |859 RKISP1_CIF_ISP_HIST_CTRL_WATERLINE_SET_V12(0) |860 RKISP1_CIF_ISP_HIST_CTRL_AUTOSTOP_SET_V12(0) |861 RKISP1_CIF_ISP_HIST_CTRL_WNDNUM_SET_V12(1) |862 RKISP1_CIF_ISP_HIST_CTRL_STEPSIZE_SET_V12(arg->histogram_predivider);863 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12, hist_ctrl);864 865 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_OFFS_V12,866 RKISP1_CIF_ISP_HIST_OFFS_SET_V12(arg->meas_window.h_offs,867 arg->meas_window.v_offs));868 869 block_hsize = arg->meas_window.h_size / hist_wnd_num[wnd_num_idx] - 1;870 block_vsize = arg->meas_window.v_size / hist_wnd_num[wnd_num_idx] - 1;871 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_SIZE_V12,872 RKISP1_CIF_ISP_HIST_SIZE_SET_V12(block_hsize, block_vsize));873 874 for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {875 for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {876 weight15x15[i * RKISP1_CIF_ISP_HIST_ROW_NUM_V12 + j] =877 arg->hist_weight[i * hist_wnd_num[wnd_num_idx] + j];878 }879 }880 881 hist_weight_num = RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12;882 for (i = 0; i < (hist_weight_num / 4); i++) {883 value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(884 weight15x15[4 * i + 0],885 weight15x15[4 * i + 1],886 weight15x15[4 * i + 2],887 weight15x15[4 * i + 3]);888 rkisp1_write(params->rkisp1,889 RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i, value);890 }891 value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(weight15x15[4 * i + 0], 0, 0, 0);892 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i,893 value);894}895 896static void897rkisp1_hst_enable_v10(struct rkisp1_params *params,898 const struct rkisp1_cif_isp_hst_config *arg, bool en)899{900 if (en) {901 u32 hist_prop = rkisp1_read(params->rkisp1,902 RKISP1_CIF_ISP_HIST_PROP_V10);903 904 hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10;905 hist_prop |= arg->mode;906 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,907 hist_prop);908 } else {909 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,910 RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10);911 }912}913 914static void915rkisp1_hst_enable_v12(struct rkisp1_params *params,916 const struct rkisp1_cif_isp_hst_config *arg, bool en)917{918 if (en) {919 u32 hist_ctrl = rkisp1_read(params->rkisp1,920 RKISP1_CIF_ISP_HIST_CTRL_V12);921 922 hist_ctrl &= ~RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12;923 hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_MODE_SET_V12(arg->mode);924 hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_EN_SET_V12(1);925 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,926 hist_ctrl);927 } else {928 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,929 RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |930 RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12);931 }932}933 934static void rkisp1_afm_config_v10(struct rkisp1_params *params,935 const struct rkisp1_cif_isp_afc_config *arg)936{937 size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),938 arg->num_afm_win);939 u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);940 unsigned int i;941 942 /* Switch off to configure. */943 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,944 RKISP1_CIF_ISP_AFM_ENA);945 946 for (i = 0; i < num_of_win; i++) {947 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_LT_A + i * 8,948 RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |949 RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs));950 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_RB_A + i * 8,951 RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +952 arg->afm_win[i].h_offs) |953 RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +954 arg->afm_win[i].v_offs));955 }956 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_THRES, arg->thres);957 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_VAR_SHIFT,958 arg->var_shift);959 /* restore afm status */960 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL, afm_ctrl);961}962 963static void rkisp1_afm_config_v12(struct rkisp1_params *params,964 const struct rkisp1_cif_isp_afc_config *arg)965{966 size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),967 arg->num_afm_win);968 u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);969 u32 lum_var_shift, afm_var_shift;970 unsigned int i;971 972 /* Switch off to configure. */973 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,974 RKISP1_CIF_ISP_AFM_ENA);975 976 for (i = 0; i < num_of_win; i++) {977 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_LT_A + i * 8,978 RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |979 RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs));980 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_RB_A + i * 8,981 RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +982 arg->afm_win[i].h_offs) |983 RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +984 arg->afm_win[i].v_offs));985 }986 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_THRES, arg->thres);987 988 lum_var_shift = RKISP1_CIF_ISP_AFM_GET_LUM_SHIFT_a_V12(arg->var_shift);989 afm_var_shift = RKISP1_CIF_ISP_AFM_GET_AFM_SHIFT_a_V12(arg->var_shift);990 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_VAR_SHIFT,991 RKISP1_CIF_ISP_AFM_SET_SHIFT_a_V12(lum_var_shift, afm_var_shift) |992 RKISP1_CIF_ISP_AFM_SET_SHIFT_b_V12(lum_var_shift, afm_var_shift) |993 RKISP1_CIF_ISP_AFM_SET_SHIFT_c_V12(lum_var_shift, afm_var_shift));994 995 /* restore afm status */996 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL, afm_ctrl);997}998 999static void rkisp1_ie_config(struct rkisp1_params *params,1000 const struct rkisp1_cif_isp_ie_config *arg)1001{1002 u32 eff_ctrl;1003 1004 eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);1005 eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;1006 1007 if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)1008 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;1009 1010 switch (arg->effect) {1011 case V4L2_COLORFX_SEPIA:1012 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;1013 break;1014 case V4L2_COLORFX_SET_CBCR:1015 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_TINT,1016 arg->eff_tint);1017 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;1018 break;1019 /*1020 * Color selection is similar to water color(AQUA):1021 * grayscale + selected color w threshold1022 */1023 case V4L2_COLORFX_AQUA:1024 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;1025 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_COLOR_SEL,1026 arg->color_sel);1027 break;1028 case V4L2_COLORFX_EMBOSS:1029 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;1030 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_1,1031 arg->eff_mat_1);1032 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_2,1033 arg->eff_mat_2);1034 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_3,1035 arg->eff_mat_3);1036 break;1037 case V4L2_COLORFX_SKETCH:1038 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;1039 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_3,1040 arg->eff_mat_3);1041 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_4,1042 arg->eff_mat_4);1043 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_5,1044 arg->eff_mat_5);1045 break;1046 case V4L2_COLORFX_BW:1047 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;1048 break;1049 case V4L2_COLORFX_NEGATIVE:1050 eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;1051 break;1052 default:1053 break;1054 }1055 1056 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL, eff_ctrl);1057}1058 1059static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)1060{1061 if (en) {1062 rkisp1_param_set_bits(params, RKISP1_CIF_VI_ICCL,1063 RKISP1_CIF_VI_ICCL_IE_CLK);1064 rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL,1065 RKISP1_CIF_IMG_EFF_CTRL_ENABLE);1066 rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,1067 RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);1068 } else {1069 rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,1070 RKISP1_CIF_IMG_EFF_CTRL_ENABLE);1071 rkisp1_param_clear_bits(params, RKISP1_CIF_VI_ICCL,1072 RKISP1_CIF_VI_ICCL_IE_CLK);1073 }1074}1075 1076static void rkisp1_csm_config(struct rkisp1_params *params)1077{1078 struct csm_coeffs {1079 u16 limited[9];1080 u16 full[9];1081 };1082 static const struct csm_coeffs rec601_coeffs = {1083 .limited = {1084 0x0021, 0x0042, 0x000d,1085 0x01ed, 0x01db, 0x0038,1086 0x0038, 0x01d1, 0x01f7,1087 },1088 .full = {1089 0x0026, 0x004b, 0x000f,1090 0x01ea, 0x01d6, 0x0040,1091 0x0040, 0x01ca, 0x01f6,1092 },1093 };1094 static const struct csm_coeffs rec709_coeffs = {1095 .limited = {1096 0x0018, 0x0050, 0x0008,1097 0x01f3, 0x01d5, 0x0038,1098 0x0038, 0x01cd, 0x01fb,1099 },1100 .full = {1101 0x001b, 0x005c, 0x0009,1102 0x01f1, 0x01cf, 0x0040,1103 0x0040, 0x01c6, 0x01fa,1104 },1105 };1106 static const struct csm_coeffs rec2020_coeffs = {1107 .limited = {1108 0x001d, 0x004c, 0x0007,1109 0x01f0, 0x01d8, 0x0038,1110 0x0038, 0x01cd, 0x01fb,1111 },1112 .full = {1113 0x0022, 0x0057, 0x0008,1114 0x01ee, 0x01d2, 0x0040,1115 0x0040, 0x01c5, 0x01fb,1116 },1117 };1118 static const struct csm_coeffs smpte240m_coeffs = {1119 .limited = {1120 0x0018, 0x004f, 0x000a,1121 0x01f3, 0x01d5, 0x0038,1122 0x0038, 0x01ce, 0x01fa,1123 },1124 .full = {1125 0x001b, 0x005a, 0x000b,1126 0x01f1, 0x01cf, 0x0040,1127 0x0040, 0x01c7, 0x01f9,1128 },1129 };1130 1131 const struct csm_coeffs *coeffs;1132 const u16 *csm;1133 unsigned int i;1134 1135 switch (params->ycbcr_encoding) {1136 case V4L2_YCBCR_ENC_601:1137 default:1138 coeffs = &rec601_coeffs;1139 break;1140 case V4L2_YCBCR_ENC_709:1141 coeffs = &rec709_coeffs;1142 break;1143 case V4L2_YCBCR_ENC_BT2020:1144 coeffs = &rec2020_coeffs;1145 break;1146 case V4L2_YCBCR_ENC_SMPTE240M:1147 coeffs = &smpte240m_coeffs;1148 break;1149 }1150 1151 if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) {1152 csm = coeffs->full;1153 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,1154 RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |1155 RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);1156 } else {1157 csm = coeffs->limited;1158 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,1159 RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |1160 RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);1161 }1162 1163 for (i = 0; i < 9; i++)1164 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CC_COEFF_0 + i * 4,1165 csm[i]);1166}1167 1168/* ISP De-noise Pre-Filter(DPF) function */1169static void rkisp1_dpf_config(struct rkisp1_params *params,1170 const struct rkisp1_cif_isp_dpf_config *arg)1171{1172 unsigned int isp_dpf_mode, spatial_coeff, i;1173 1174 switch (arg->gain.mode) {1175 case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:1176 isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |1177 RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;1178 break;1179 case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:1180 isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;1181 break;1182 case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:1183 isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |1184 RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |1185 RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;1186 break;1187 case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:1188 isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;1189 break;1190 case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:1191 isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |1192 RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;1193 break;1194 case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:1195 default:1196 isp_dpf_mode = 0;1197 break;1198 }1199 1200 if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)1201 isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;1202 if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)1203 isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;1204 if (!arg->rb_flt.r_enable)1205 isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;1206 if (!arg->rb_flt.b_enable)1207 isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;1208 if (!arg->g_flt.gb_enable)1209 isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;1210 if (!arg->g_flt.gr_enable)1211 isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;1212 1213 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,1214 isp_dpf_mode);1215 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_B,1216 arg->gain.nf_b_gain);1217 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_R,1218 arg->gain.nf_r_gain);1219 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_GB,1220 arg->gain.nf_gb_gain);1221 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_GR,1222 arg->gain.nf_gr_gain);1223 1224 for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {1225 rkisp1_write(params->rkisp1,1226 RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4,1227 arg->nll.coeff[i]);1228 }1229 1230 spatial_coeff = arg->g_flt.spatial_coeff[0] |1231 (arg->g_flt.spatial_coeff[1] << 8) |1232 (arg->g_flt.spatial_coeff[2] << 16) |1233 (arg->g_flt.spatial_coeff[3] << 24);1234 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4,1235 spatial_coeff);1236 1237 spatial_coeff = arg->g_flt.spatial_coeff[4] |1238 (arg->g_flt.spatial_coeff[5] << 8);1239 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6,1240 spatial_coeff);1241 1242 spatial_coeff = arg->rb_flt.spatial_coeff[0] |1243 (arg->rb_flt.spatial_coeff[1] << 8) |1244 (arg->rb_flt.spatial_coeff[2] << 16) |1245 (arg->rb_flt.spatial_coeff[3] << 24);1246 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4,1247 spatial_coeff);1248 1249 spatial_coeff = arg->rb_flt.spatial_coeff[4] |1250 (arg->rb_flt.spatial_coeff[5] << 8);1251 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6,1252 spatial_coeff);1253}1254 1255static void1256rkisp1_dpf_strength_config(struct rkisp1_params *params,1257 const struct rkisp1_cif_isp_dpf_strength_config *arg)1258{1259 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_B, arg->b);1260 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_G, arg->g);1261 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_R, arg->r);1262}1263 1264static void rkisp1_compand_write_px_curve(struct rkisp1_params *params,1265 unsigned int addr, const u8 *curve)1266{1267 const unsigned int points_per_reg = 6;1268 const unsigned int num_regs =1269 DIV_ROUND_UP(RKISP1_CIF_ISP_COMPAND_NUM_POINTS,1270 points_per_reg);1271 1272 /*1273 * The compand curve is specified as a piecewise linear function with1274 * 64 points. X coordinates are stored as a log2 of the displacement1275 * from the previous point, in 5 bits, with 6 values per register. The1276 * last register stores 4 values.1277 */1278 for (unsigned int reg = 0; reg < num_regs; ++reg) {1279 unsigned int num_points =1280 min(RKISP1_CIF_ISP_COMPAND_NUM_POINTS -1281 reg * points_per_reg, points_per_reg);1282 u32 val = 0;1283 1284 for (unsigned int i = 0; i < num_points; i++)1285 val |= (*curve++ & 0x1f) << (i * 5);1286 1287 rkisp1_write(params->rkisp1, addr, val);1288 addr += 4;1289 }1290}1291 1292static void1293rkisp1_compand_write_curve_mem(struct rkisp1_params *params,1294 unsigned int reg_addr, unsigned int reg_data,1295 const u32 curve[RKISP1_CIF_ISP_COMPAND_NUM_POINTS])1296{1297 for (unsigned int i = 0; i < RKISP1_CIF_ISP_COMPAND_NUM_POINTS; i++) {1298 rkisp1_write(params->rkisp1, reg_addr, i);1299 rkisp1_write(params->rkisp1, reg_data, curve[i]);1300 }1301}1302 1303static void1304rkisp1_compand_bls_config(struct rkisp1_params *params,1305 const struct rkisp1_cif_isp_compand_bls_config *arg)1306{1307 static const u32 regs[] = {1308 RKISP1_CIF_ISP_COMPAND_BLS_A_FIXED,1309 RKISP1_CIF_ISP_COMPAND_BLS_B_FIXED,1310 RKISP1_CIF_ISP_COMPAND_BLS_C_FIXED,1311 RKISP1_CIF_ISP_COMPAND_BLS_D_FIXED,1312 };1313 u32 swapped[4];1314 1315 rkisp1_bls_swap_regs(params->raw_type, regs, swapped);1316 1317 rkisp1_write(params->rkisp1, swapped[0], arg->r);1318 rkisp1_write(params->rkisp1, swapped[1], arg->gr);1319 rkisp1_write(params->rkisp1, swapped[2], arg->gb);1320 rkisp1_write(params->rkisp1, swapped[3], arg->b);1321}1322 1323static void1324rkisp1_compand_expand_config(struct rkisp1_params *params,1325 const struct rkisp1_cif_isp_compand_curve_config *arg)1326{1327 rkisp1_compand_write_px_curve(params, RKISP1_CIF_ISP_COMPAND_EXPAND_PX_N(0),1328 arg->px);1329 rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_EXPAND_Y_ADDR,1330 RKISP1_CIF_ISP_COMPAND_EXPAND_Y_WRITE_DATA,1331 arg->y);1332 rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_EXPAND_X_ADDR,1333 RKISP1_CIF_ISP_COMPAND_EXPAND_X_WRITE_DATA,1334 arg->x);1335}1336 1337static void1338rkisp1_compand_compress_config(struct rkisp1_params *params,1339 const struct rkisp1_cif_isp_compand_curve_config *arg)1340{1341 rkisp1_compand_write_px_curve(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_PX_N(0),1342 arg->px);1343 rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_ADDR,1344 RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_WRITE_DATA,1345 arg->y);1346 rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_X_ADDR,1347 RKISP1_CIF_ISP_COMPAND_COMPRESS_X_WRITE_DATA,1348 arg->x);1349}1350 1351static void1352rkisp1_isp_isr_other_config(struct rkisp1_params *params,1353 const struct rkisp1_params_cfg *new_params)1354{1355 unsigned int module_en_update, module_cfg_update, module_ens;1356 1357 module_en_update = new_params->module_en_update;1358 module_cfg_update = new_params->module_cfg_update;1359 module_ens = new_params->module_ens;1360 1361 if (!rkisp1_has_feature(params->rkisp1, BLS)) {1362 module_en_update &= ~RKISP1_CIF_ISP_MODULE_BLS;1363 module_cfg_update &= ~RKISP1_CIF_ISP_MODULE_BLS;1364 module_ens &= ~RKISP1_CIF_ISP_MODULE_BLS;1365 }1366 1367 /* update dpc config */1368 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)1369 rkisp1_dpcc_config(params,1370 &new_params->others.dpcc_config);1371 1372 if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {1373 if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC)1374 rkisp1_param_set_bits(params,1375 RKISP1_CIF_ISP_DPCC_MODE,1376 RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);1377 else1378 rkisp1_param_clear_bits(params,1379 RKISP1_CIF_ISP_DPCC_MODE,1380 RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);1381 }1382 1383 /* update bls config */1384 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)1385 rkisp1_bls_config(params,1386 &new_params->others.bls_config);1387 1388 if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {1389 if (module_ens & RKISP1_CIF_ISP_MODULE_BLS)1390 rkisp1_param_set_bits(params,1391 RKISP1_CIF_ISP_BLS_CTRL,1392 RKISP1_CIF_ISP_BLS_ENA);1393 else1394 rkisp1_param_clear_bits(params,1395 RKISP1_CIF_ISP_BLS_CTRL,1396 RKISP1_CIF_ISP_BLS_ENA);1397 }1398 1399 /* update sdg config */1400 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)1401 rkisp1_sdg_config(params,1402 &new_params->others.sdg_config);1403 1404 if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {1405 if (module_ens & RKISP1_CIF_ISP_MODULE_SDG)1406 rkisp1_param_set_bits(params,1407 RKISP1_CIF_ISP_CTRL,1408 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);1409 else1410 rkisp1_param_clear_bits(params,1411 RKISP1_CIF_ISP_CTRL,1412 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);1413 }1414 1415 /* update awb gains */1416 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)1417 params->ops->awb_gain_config(params, &new_params->others.awb_gain_config);1418 1419 if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {1420 if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)1421 rkisp1_param_set_bits(params,1422 RKISP1_CIF_ISP_CTRL,1423 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);1424 else1425 rkisp1_param_clear_bits(params,1426 RKISP1_CIF_ISP_CTRL,1427 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);1428 }1429 1430 /* update bdm config */1431 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)1432 rkisp1_bdm_config(params,1433 &new_params->others.bdm_config);1434 1435 if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {1436 if (module_ens & RKISP1_CIF_ISP_MODULE_BDM)1437 rkisp1_param_set_bits(params,1438 RKISP1_CIF_ISP_DEMOSAIC,1439 RKISP1_CIF_ISP_DEMOSAIC_BYPASS);1440 else1441 rkisp1_param_clear_bits(params,1442 RKISP1_CIF_ISP_DEMOSAIC,1443 RKISP1_CIF_ISP_DEMOSAIC_BYPASS);1444 }1445 1446 /* update filter config */1447 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)1448 rkisp1_flt_config(params,1449 &new_params->others.flt_config);1450 1451 if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {1452 if (module_ens & RKISP1_CIF_ISP_MODULE_FLT)1453 rkisp1_param_set_bits(params,1454 RKISP1_CIF_ISP_FILT_MODE,1455 RKISP1_CIF_ISP_FLT_ENA);1456 else1457 rkisp1_param_clear_bits(params,1458 RKISP1_CIF_ISP_FILT_MODE,1459 RKISP1_CIF_ISP_FLT_ENA);1460 }1461 1462 /* update ctk config */1463 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)1464 rkisp1_ctk_config(params,1465 &new_params->others.ctk_config);1466 1467 if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)1468 rkisp1_ctk_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));1469 1470 /* update goc config */1471 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)1472 params->ops->goc_config(params, &new_params->others.goc_config);1473 1474 if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {1475 if (module_ens & RKISP1_CIF_ISP_MODULE_GOC)1476 rkisp1_param_set_bits(params,1477 RKISP1_CIF_ISP_CTRL,1478 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);1479 else1480 rkisp1_param_clear_bits(params,1481 RKISP1_CIF_ISP_CTRL,1482 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);1483 }1484 1485 /* update cproc config */1486 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)1487 rkisp1_cproc_config(params,1488 &new_params->others.cproc_config);1489 1490 if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {1491 if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC)1492 rkisp1_param_set_bits(params,1493 RKISP1_CIF_C_PROC_CTRL,1494 RKISP1_CIF_C_PROC_CTR_ENABLE);1495 else1496 rkisp1_param_clear_bits(params,1497 RKISP1_CIF_C_PROC_CTRL,1498 RKISP1_CIF_C_PROC_CTR_ENABLE);1499 }1500 1501 /* update ie config */1502 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)1503 rkisp1_ie_config(params, &new_params->others.ie_config);1504 1505 if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)1506 rkisp1_ie_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));1507 1508 /* update dpf config */1509 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)1510 rkisp1_dpf_config(params, &new_params->others.dpf_config);1511 1512 if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {1513 if (module_ens & RKISP1_CIF_ISP_MODULE_DPF)1514 rkisp1_param_set_bits(params,1515 RKISP1_CIF_ISP_DPF_MODE,1516 RKISP1_CIF_ISP_DPF_MODE_EN);1517 else1518 rkisp1_param_clear_bits(params,1519 RKISP1_CIF_ISP_DPF_MODE,1520 RKISP1_CIF_ISP_DPF_MODE_EN);1521 }1522 1523 if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||1524 (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {1525 /* update dpf strength config */1526 rkisp1_dpf_strength_config(params,1527 &new_params->others.dpf_strength_config);1528 }1529}1530 1531static void1532rkisp1_isp_isr_lsc_config(struct rkisp1_params *params,1533 const struct rkisp1_params_cfg *new_params)1534{1535 unsigned int module_en_update, module_cfg_update, module_ens;1536 1537 module_en_update = new_params->module_en_update;1538 module_cfg_update = new_params->module_cfg_update;1539 module_ens = new_params->module_ens;1540 1541 /* update lsc config */1542 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)1543 rkisp1_lsc_config(params,1544 &new_params->others.lsc_config);1545 1546 if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {1547 if (module_ens & RKISP1_CIF_ISP_MODULE_LSC)1548 rkisp1_param_set_bits(params,1549 RKISP1_CIF_ISP_LSC_CTRL,1550 RKISP1_CIF_ISP_LSC_CTRL_ENA);1551 else1552 rkisp1_param_clear_bits(params,1553 RKISP1_CIF_ISP_LSC_CTRL,1554 RKISP1_CIF_ISP_LSC_CTRL_ENA);1555 }1556}1557 1558static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,1559 struct rkisp1_params_cfg *new_params)1560{1561 unsigned int module_en_update, module_cfg_update, module_ens;1562 1563 module_en_update = new_params->module_en_update;1564 module_cfg_update = new_params->module_cfg_update;1565 module_ens = new_params->module_ens;1566 1567 /* update awb config */1568 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)1569 params->ops->awb_meas_config(params, &new_params->meas.awb_meas_config);1570 1571 if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)1572 params->ops->awb_meas_enable(params,1573 &new_params->meas.awb_meas_config,1574 !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));1575 1576 /* update afc config */1577 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)1578 params->ops->afm_config(params,1579 &new_params->meas.afc_config);1580 1581 if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {1582 if (module_ens & RKISP1_CIF_ISP_MODULE_AFC)1583 rkisp1_param_set_bits(params,1584 RKISP1_CIF_ISP_AFM_CTRL,1585 RKISP1_CIF_ISP_AFM_ENA);1586 else1587 rkisp1_param_clear_bits(params,1588 RKISP1_CIF_ISP_AFM_CTRL,1589 RKISP1_CIF_ISP_AFM_ENA);1590 }1591 1592 /* update hst config */1593 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)1594 params->ops->hst_config(params,1595 &new_params->meas.hst_config);1596 1597 if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)1598 params->ops->hst_enable(params,1599 &new_params->meas.hst_config,1600 !!(module_ens & RKISP1_CIF_ISP_MODULE_HST));1601 1602 /* update aec config */1603 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)1604 params->ops->aec_config(params,1605 &new_params->meas.aec_config);1606 1607 if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {1608 if (module_ens & RKISP1_CIF_ISP_MODULE_AEC)1609 rkisp1_param_set_bits(params,1610 RKISP1_CIF_ISP_EXP_CTRL,1611 RKISP1_CIF_ISP_EXP_ENA);1612 else1613 rkisp1_param_clear_bits(params,1614 RKISP1_CIF_ISP_EXP_CTRL,1615 RKISP1_CIF_ISP_EXP_ENA);1616 }1617}1618 1619/*------------------------------------------------------------------------------1620 * Extensible parameters format handling1621 */1622 1623static void1624rkisp1_ext_params_bls(struct rkisp1_params *params,1625 const union rkisp1_ext_params_config *block)1626{1627 const struct rkisp1_ext_params_bls_config *bls = &block->bls;1628 1629 if (bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1630 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,1631 RKISP1_CIF_ISP_BLS_ENA);1632 return;1633 }1634 1635 rkisp1_bls_config(params, &bls->config);1636 1637 if ((bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1638 !(params->enabled_blocks & BIT(bls->header.type)))1639 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_BLS_CTRL,1640 RKISP1_CIF_ISP_BLS_ENA);1641}1642 1643static void1644rkisp1_ext_params_dpcc(struct rkisp1_params *params,1645 const union rkisp1_ext_params_config *block)1646{1647 const struct rkisp1_ext_params_dpcc_config *dpcc = &block->dpcc;1648 1649 if (dpcc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1650 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,1651 RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);1652 return;1653 }1654 1655 rkisp1_dpcc_config(params, &dpcc->config);1656 1657 if ((dpcc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1658 !(params->enabled_blocks & BIT(dpcc->header.type)))1659 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPCC_MODE,1660 RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);1661}1662 1663static void1664rkisp1_ext_params_sdg(struct rkisp1_params *params,1665 const union rkisp1_ext_params_config *block)1666{1667 const struct rkisp1_ext_params_sdg_config *sdg = &block->sdg;1668 1669 if (sdg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1670 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,1671 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);1672 return;1673 }1674 1675 rkisp1_sdg_config(params, &sdg->config);1676 1677 if ((sdg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1678 !(params->enabled_blocks & BIT(sdg->header.type)))1679 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,1680 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);1681}1682 1683static void1684rkisp1_ext_params_lsc(struct rkisp1_params *params,1685 const union rkisp1_ext_params_config *block)1686{1687 const struct rkisp1_ext_params_lsc_config *lsc = &block->lsc;1688 1689 if (lsc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1690 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,1691 RKISP1_CIF_ISP_LSC_CTRL_ENA);1692 return;1693 }1694 1695 rkisp1_lsc_config(params, &lsc->config);1696 1697 if ((lsc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1698 !(params->enabled_blocks & BIT(lsc->header.type)))1699 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL,1700 RKISP1_CIF_ISP_LSC_CTRL_ENA);1701}1702 1703static void1704rkisp1_ext_params_awbg(struct rkisp1_params *params,1705 const union rkisp1_ext_params_config *block)1706{1707 const struct rkisp1_ext_params_awb_gain_config *awbg = &block->awbg;1708 1709 if (awbg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1710 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,1711 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);1712 return;1713 }1714 1715 params->ops->awb_gain_config(params, &awbg->config);1716 1717 if ((awbg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1718 !(params->enabled_blocks & BIT(awbg->header.type)))1719 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,1720 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);1721}1722 1723static void1724rkisp1_ext_params_flt(struct rkisp1_params *params,1725 const union rkisp1_ext_params_config *block)1726{1727 const struct rkisp1_ext_params_flt_config *flt = &block->flt;1728 1729 if (flt->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1730 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,1731 RKISP1_CIF_ISP_FLT_ENA);1732 return;1733 }1734 1735 rkisp1_flt_config(params, &flt->config);1736 1737 if ((flt->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1738 !(params->enabled_blocks & BIT(flt->header.type)))1739 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_FILT_MODE,1740 RKISP1_CIF_ISP_FLT_ENA);1741}1742 1743static void1744rkisp1_ext_params_bdm(struct rkisp1_params *params,1745 const union rkisp1_ext_params_config *block)1746{1747 const struct rkisp1_ext_params_bdm_config *bdm = &block->bdm;1748 1749 if (bdm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1750 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,1751 RKISP1_CIF_ISP_DEMOSAIC_BYPASS);1752 return;1753 }1754 1755 rkisp1_bdm_config(params, &bdm->config);1756 1757 if ((bdm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1758 !(params->enabled_blocks & BIT(bdm->header.type)))1759 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DEMOSAIC,1760 RKISP1_CIF_ISP_DEMOSAIC_BYPASS);1761}1762 1763static void1764rkisp1_ext_params_ctk(struct rkisp1_params *params,1765 const union rkisp1_ext_params_config *block)1766{1767 const struct rkisp1_ext_params_ctk_config *ctk = &block->ctk;1768 1769 if (ctk->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1770 rkisp1_ctk_enable(params, false);1771 return;1772 }1773 1774 rkisp1_ctk_config(params, &ctk->config);1775 1776 if ((ctk->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1777 !(params->enabled_blocks & BIT(ctk->header.type)))1778 rkisp1_ctk_enable(params, true);1779}1780 1781static void1782rkisp1_ext_params_goc(struct rkisp1_params *params,1783 const union rkisp1_ext_params_config *block)1784{1785 const struct rkisp1_ext_params_goc_config *goc = &block->goc;1786 1787 if (goc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1788 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,1789 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);1790 return;1791 }1792 1793 params->ops->goc_config(params, &goc->config);1794 1795 /*1796 * Unconditionally re-enable the GOC module which gets disabled by1797 * goc_config().1798 */1799 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,1800 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);1801}1802 1803static void1804rkisp1_ext_params_dpf(struct rkisp1_params *params,1805 const union rkisp1_ext_params_config *block)1806{1807 const struct rkisp1_ext_params_dpf_config *dpf = &block->dpf;1808 1809 if (dpf->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1810 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,1811 RKISP1_CIF_ISP_DPF_MODE_EN);1812 return;1813 }1814 1815 rkisp1_dpf_config(params, &dpf->config);1816 1817 if ((dpf->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1818 !(params->enabled_blocks & BIT(dpf->header.type)))1819 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,1820 RKISP1_CIF_ISP_DPF_MODE_EN);1821}1822 1823static void1824rkisp1_ext_params_dpfs(struct rkisp1_params *params,1825 const union rkisp1_ext_params_config *block)1826{1827 const struct rkisp1_ext_params_dpf_strength_config *dpfs = &block->dpfs;1828 1829 rkisp1_dpf_strength_config(params, &dpfs->config);1830}1831 1832static void1833rkisp1_ext_params_cproc(struct rkisp1_params *params,1834 const union rkisp1_ext_params_config *block)1835{1836 const struct rkisp1_ext_params_cproc_config *cproc = &block->cproc;1837 1838 if (cproc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1839 rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,1840 RKISP1_CIF_C_PROC_CTR_ENABLE);1841 return;1842 }1843 1844 rkisp1_cproc_config(params, &cproc->config);1845 1846 if ((cproc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1847 !(params->enabled_blocks & BIT(cproc->header.type)))1848 rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,1849 RKISP1_CIF_C_PROC_CTR_ENABLE);1850}1851 1852static void1853rkisp1_ext_params_ie(struct rkisp1_params *params,1854 const union rkisp1_ext_params_config *block)1855{1856 const struct rkisp1_ext_params_ie_config *ie = &block->ie;1857 1858 if (ie->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1859 rkisp1_ie_enable(params, false);1860 return;1861 }1862 1863 rkisp1_ie_config(params, &ie->config);1864 1865 if ((ie->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1866 !(params->enabled_blocks & BIT(ie->header.type)))1867 rkisp1_ie_enable(params, true);1868}1869 1870static void1871rkisp1_ext_params_awbm(struct rkisp1_params *params,1872 const union rkisp1_ext_params_config *block)1873{1874 const struct rkisp1_ext_params_awb_meas_config *awbm = &block->awbm;1875 1876 if (awbm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1877 params->ops->awb_meas_enable(params, &awbm->config,1878 false);1879 return;1880 }1881 1882 params->ops->awb_meas_config(params, &awbm->config);1883 1884 if ((awbm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1885 !(params->enabled_blocks & BIT(awbm->header.type)))1886 params->ops->awb_meas_enable(params, &awbm->config,1887 true);1888}1889 1890static void1891rkisp1_ext_params_hstm(struct rkisp1_params *params,1892 const union rkisp1_ext_params_config *block)1893{1894 const struct rkisp1_ext_params_hst_config *hst = &block->hst;1895 1896 if (hst->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1897 params->ops->hst_enable(params, &hst->config, false);1898 return;1899 }1900 1901 params->ops->hst_config(params, &hst->config);1902 1903 if ((hst->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1904 !(params->enabled_blocks & BIT(hst->header.type)))1905 params->ops->hst_enable(params, &hst->config, true);1906}1907 1908static void1909rkisp1_ext_params_aecm(struct rkisp1_params *params,1910 const union rkisp1_ext_params_config *block)1911{1912 const struct rkisp1_ext_params_aec_config *aec = &block->aec;1913 1914 if (aec->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1915 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,1916 RKISP1_CIF_ISP_EXP_ENA);1917 return;1918 }1919 1920 params->ops->aec_config(params, &aec->config);1921 1922 if ((aec->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1923 !(params->enabled_blocks & BIT(aec->header.type)))1924 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,1925 RKISP1_CIF_ISP_EXP_ENA);1926}1927 1928static void1929rkisp1_ext_params_afcm(struct rkisp1_params *params,1930 const union rkisp1_ext_params_config *block)1931{1932 const struct rkisp1_ext_params_afc_config *afc = &block->afc;1933 1934 if (afc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1935 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,1936 RKISP1_CIF_ISP_AFM_ENA);1937 return;1938 }1939 1940 params->ops->afm_config(params, &afc->config);1941 1942 if ((afc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1943 !(params->enabled_blocks & BIT(afc->header.type)))1944 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,1945 RKISP1_CIF_ISP_AFM_ENA);1946}1947 1948static void rkisp1_ext_params_compand_bls(struct rkisp1_params *params,1949 const union rkisp1_ext_params_config *block)1950{1951 const struct rkisp1_ext_params_compand_bls_config *bls =1952 &block->compand_bls;1953 1954 if (bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1955 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL,1956 RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE);1957 return;1958 }1959 1960 rkisp1_compand_bls_config(params, &bls->config);1961 1962 if ((bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1963 !(params->enabled_blocks & BIT(bls->header.type)))1964 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL,1965 RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE);1966}1967 1968static void rkisp1_ext_params_compand_expand(struct rkisp1_params *params,1969 const union rkisp1_ext_params_config *block)1970{1971 const struct rkisp1_ext_params_compand_curve_config *curve =1972 &block->compand_curve;1973 1974 if (curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1975 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL,1976 RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE);1977 return;1978 }1979 1980 rkisp1_compand_expand_config(params, &curve->config);1981 1982 if ((curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&1983 !(params->enabled_blocks & BIT(curve->header.type)))1984 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL,1985 RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE);1986}1987 1988static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params,1989 const union rkisp1_ext_params_config *block)1990{1991 const struct rkisp1_ext_params_compand_curve_config *curve =1992 &block->compand_curve;1993 1994 if (curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {1995 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL,1996 RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);1997 return;1998 }1999 2000 rkisp1_compand_compress_config(params, &curve->config);2001 2002 if ((curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&2003 !(params->enabled_blocks & BIT(curve->header.type)))2004 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL,2005 RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);2006}2007 2008typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,2009 const union rkisp1_ext_params_config *config);2010 2011static const struct rkisp1_ext_params_handler {2012 size_t size;2013 rkisp1_block_handler handler;2014 unsigned int group;2015 unsigned int features;2016} rkisp1_ext_params_handlers[] = {2017 [RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = {2018 .size = sizeof(struct rkisp1_ext_params_bls_config),2019 .handler = rkisp1_ext_params_bls,2020 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2021 .features = RKISP1_FEATURE_BLS,2022 },2023 [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = {2024 .size = sizeof(struct rkisp1_ext_params_dpcc_config),2025 .handler = rkisp1_ext_params_dpcc,2026 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2027 },2028 [RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = {2029 .size = sizeof(struct rkisp1_ext_params_sdg_config),2030 .handler = rkisp1_ext_params_sdg,2031 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2032 },2033 [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = {2034 .size = sizeof(struct rkisp1_ext_params_awb_gain_config),2035 .handler = rkisp1_ext_params_awbg,2036 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2037 },2038 [RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = {2039 .size = sizeof(struct rkisp1_ext_params_flt_config),2040 .handler = rkisp1_ext_params_flt,2041 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2042 },2043 [RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = {2044 .size = sizeof(struct rkisp1_ext_params_bdm_config),2045 .handler = rkisp1_ext_params_bdm,2046 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2047 },2048 [RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = {2049 .size = sizeof(struct rkisp1_ext_params_ctk_config),2050 .handler = rkisp1_ext_params_ctk,2051 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2052 },2053 [RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = {2054 .size = sizeof(struct rkisp1_ext_params_goc_config),2055 .handler = rkisp1_ext_params_goc,2056 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2057 },2058 [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = {2059 .size = sizeof(struct rkisp1_ext_params_dpf_config),2060 .handler = rkisp1_ext_params_dpf,2061 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2062 },2063 [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = {2064 .size = sizeof(struct rkisp1_ext_params_dpf_strength_config),2065 .handler = rkisp1_ext_params_dpfs,2066 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2067 },2068 [RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = {2069 .size = sizeof(struct rkisp1_ext_params_cproc_config),2070 .handler = rkisp1_ext_params_cproc,2071 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2072 },2073 [RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = {2074 .size = sizeof(struct rkisp1_ext_params_ie_config),2075 .handler = rkisp1_ext_params_ie,2076 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2077 },2078 [RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = {2079 .size = sizeof(struct rkisp1_ext_params_lsc_config),2080 .handler = rkisp1_ext_params_lsc,2081 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC,2082 },2083 [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = {2084 .size = sizeof(struct rkisp1_ext_params_awb_meas_config),2085 .handler = rkisp1_ext_params_awbm,2086 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2087 },2088 [RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = {2089 .size = sizeof(struct rkisp1_ext_params_hst_config),2090 .handler = rkisp1_ext_params_hstm,2091 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2092 },2093 [RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = {2094 .size = sizeof(struct rkisp1_ext_params_aec_config),2095 .handler = rkisp1_ext_params_aecm,2096 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2097 },2098 [RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = {2099 .size = sizeof(struct rkisp1_ext_params_afc_config),2100 .handler = rkisp1_ext_params_afcm,2101 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2102 },2103 [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = {2104 .size = sizeof(struct rkisp1_ext_params_compand_bls_config),2105 .handler = rkisp1_ext_params_compand_bls,2106 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2107 .features = RKISP1_FEATURE_COMPAND,2108 },2109 [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = {2110 .size = sizeof(struct rkisp1_ext_params_compand_curve_config),2111 .handler = rkisp1_ext_params_compand_expand,2112 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2113 .features = RKISP1_FEATURE_COMPAND,2114 },2115 [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = {2116 .size = sizeof(struct rkisp1_ext_params_compand_curve_config),2117 .handler = rkisp1_ext_params_compand_compress,2118 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2119 .features = RKISP1_FEATURE_COMPAND,2120 },2121};2122 2123static void rkisp1_ext_params_config(struct rkisp1_params *params,2124 struct rkisp1_ext_params_cfg *cfg,2125 u32 block_group_mask)2126{2127 size_t block_offset = 0;2128 2129 if (WARN_ON(!cfg))2130 return;2131 2132 /* Walk the list of parameter blocks and process them. */2133 while (block_offset < cfg->data_size) {2134 const struct rkisp1_ext_params_handler *block_handler;2135 const union rkisp1_ext_params_config *block;2136 2137 block = (const union rkisp1_ext_params_config *)2138 &cfg->data[block_offset];2139 block_offset += block->header.size;2140 2141 /*2142 * Make sure the block is supported by the platform and in the2143 * list of groups to configure.2144 */2145 block_handler = &rkisp1_ext_params_handlers[block->header.type];2146 if (!(block_handler->group & block_group_mask))2147 continue;2148 2149 if ((params->rkisp1->info->features & block_handler->features) !=2150 block_handler->features)2151 continue;2152 2153 block_handler->handler(params, block);2154 2155 if (block->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)2156 params->enabled_blocks &= ~BIT(block->header.type);2157 else if (block->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE)2158 params->enabled_blocks |= BIT(block->header.type);2159 }2160}2161 2162static void rkisp1_params_complete_buffer(struct rkisp1_params *params,2163 struct rkisp1_params_buffer *buf,2164 unsigned int frame_sequence)2165{2166 list_del(&buf->queue);2167 2168 buf->vb.sequence = frame_sequence;2169 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);2170}2171 2172void rkisp1_params_isr(struct rkisp1_device *rkisp1)2173{2174 struct rkisp1_params *params = &rkisp1->params;2175 struct rkisp1_params_buffer *cur_buf;2176 2177 spin_lock(¶ms->config_lock);2178 2179 cur_buf = list_first_entry_or_null(¶ms->params,2180 struct rkisp1_params_buffer, queue);2181 if (!cur_buf)2182 goto unlock;2183 2184 if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) {2185 rkisp1_isp_isr_other_config(params, cur_buf->cfg);2186 rkisp1_isp_isr_lsc_config(params, cur_buf->cfg);2187 rkisp1_isp_isr_meas_config(params, cur_buf->cfg);2188 } else {2189 rkisp1_ext_params_config(params, cur_buf->cfg,2190 RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS |2191 RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC);2192 }2193 2194 /* update shadow register immediately */2195 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,2196 RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);2197 2198 /*2199 * This isr is called when the ISR finishes processing a frame2200 * (RKISP1_CIF_ISP_FRAME). Configurations performed here will be2201 * applied on the next frame. Since frame_sequence is updated on the2202 * vertical sync signal, we should use frame_sequence + 1 here to2203 * indicate to userspace on which frame these parameters are being2204 * applied.2205 */2206 rkisp1_params_complete_buffer(params, cur_buf,2207 rkisp1->isp.frame_sequence + 1);2208 2209unlock:2210 spin_unlock(¶ms->config_lock);2211}2212 2213static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {2214 {2215 0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT2216 },2217 RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 1282218};2219 2220static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {2221 RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,2222 RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,2223 {2224 RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,2225 RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 12226 }2227};2228 2229static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {2230 RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,2231 3,2232 {2233 RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,2234 RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 12235 },2236 {2237 0, /* To be filled in with 0x01 at runtime. */2238 }2239};2240 2241static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {2242 1,2243 {2244 {2245 300, 225, 200, 1502246 }2247 },2248 4,2249 142250};2251 2252void rkisp1_params_pre_configure(struct rkisp1_params *params,2253 enum rkisp1_fmt_raw_pat_type bayer_pat,2254 enum v4l2_quantization quantization,2255 enum v4l2_ycbcr_encoding ycbcr_encoding)2256{2257 struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;2258 struct rkisp1_params_buffer *cur_buf;2259 2260 params->quantization = quantization;2261 params->ycbcr_encoding = ycbcr_encoding;2262 params->raw_type = bayer_pat;2263 2264 params->ops->awb_meas_config(params, &rkisp1_awb_params_default_config);2265 params->ops->awb_meas_enable(params, &rkisp1_awb_params_default_config,2266 true);2267 2268 params->ops->aec_config(params, &rkisp1_aec_params_default_config);2269 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,2270 RKISP1_CIF_ISP_EXP_ENA);2271 2272 params->ops->afm_config(params, &rkisp1_afc_params_default_config);2273 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,2274 RKISP1_CIF_ISP_AFM_ENA);2275 2276 memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));2277 params->ops->hst_config(params, &hst);2278 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,2279 rkisp1_hst_params_default_config.mode);2280 2281 rkisp1_csm_config(params);2282 2283 spin_lock_irq(¶ms->config_lock);2284 2285 /* apply the first buffer if there is one already */2286 2287 cur_buf = list_first_entry_or_null(¶ms->params,2288 struct rkisp1_params_buffer, queue);2289 if (!cur_buf)2290 goto unlock;2291 2292 if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) {2293 rkisp1_isp_isr_other_config(params, cur_buf->cfg);2294 rkisp1_isp_isr_meas_config(params, cur_buf->cfg);2295 } else {2296 rkisp1_ext_params_config(params, cur_buf->cfg,2297 RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS);2298 }2299 2300 /* update shadow register immediately */2301 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,2302 RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);2303 2304unlock:2305 spin_unlock_irq(¶ms->config_lock);2306}2307 2308void rkisp1_params_post_configure(struct rkisp1_params *params)2309{2310 struct rkisp1_params_buffer *cur_buf;2311 2312 spin_lock_irq(¶ms->config_lock);2313 2314 /*2315 * Apply LSC parameters from the first buffer (if any is already2316 * available. This must be done after the ISP gets started in the2317 * ISP8000Nano v18.02 (found in the i.MX8MP) as access to the LSC RAM2318 * is gated by the ISP_CTRL.ISP_ENABLE bit. As this initialization2319 * ordering doesn't affect other ISP versions negatively, do so2320 * unconditionally.2321 */2322 cur_buf = list_first_entry_or_null(¶ms->params,2323 struct rkisp1_params_buffer, queue);2324 if (!cur_buf)2325 goto unlock;2326 2327 if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS)2328 rkisp1_isp_isr_lsc_config(params, cur_buf->cfg);2329 else2330 rkisp1_ext_params_config(params, cur_buf->cfg,2331 RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC);2332 2333 /* update shadow register immediately */2334 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,2335 RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);2336 2337 rkisp1_params_complete_buffer(params, cur_buf, 0);2338 2339unlock:2340 spin_unlock_irq(¶ms->config_lock);2341}2342 2343/*2344 * Not called when the camera is active, therefore there is no need to acquire2345 * a lock.2346 */2347void rkisp1_params_disable(struct rkisp1_params *params)2348{2349 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,2350 RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);2351 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,2352 RKISP1_CIF_ISP_LSC_CTRL_ENA);2353 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,2354 RKISP1_CIF_ISP_BLS_ENA);2355 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,2356 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);2357 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,2358 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);2359 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,2360 RKISP1_CIF_ISP_DEMOSAIC_BYPASS);2361 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,2362 RKISP1_CIF_ISP_FLT_ENA);2363 params->ops->awb_meas_enable(params, NULL, false);2364 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,2365 RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);2366 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,2367 RKISP1_CIF_ISP_EXP_ENA);2368 rkisp1_ctk_enable(params, false);2369 rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,2370 RKISP1_CIF_C_PROC_CTR_ENABLE);2371 params->ops->hst_enable(params, NULL, false);2372 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,2373 RKISP1_CIF_ISP_AFM_ENA);2374 rkisp1_ie_enable(params, false);2375 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,2376 RKISP1_CIF_ISP_DPF_MODE_EN);2377}2378 2379static const struct rkisp1_params_ops rkisp1_v10_params_ops = {2380 .lsc_matrix_config = rkisp1_lsc_matrix_config_v10,2381 .goc_config = rkisp1_goc_config_v10,2382 .awb_meas_config = rkisp1_awb_meas_config_v10,2383 .awb_meas_enable = rkisp1_awb_meas_enable_v10,2384 .awb_gain_config = rkisp1_awb_gain_config_v10,2385 .aec_config = rkisp1_aec_config_v10,2386 .hst_config = rkisp1_hst_config_v10,2387 .hst_enable = rkisp1_hst_enable_v10,2388 .afm_config = rkisp1_afm_config_v10,2389};2390 2391static const struct rkisp1_params_ops rkisp1_v12_params_ops = {2392 .lsc_matrix_config = rkisp1_lsc_matrix_config_v12,2393 .goc_config = rkisp1_goc_config_v12,2394 .awb_meas_config = rkisp1_awb_meas_config_v12,2395 .awb_meas_enable = rkisp1_awb_meas_enable_v12,2396 .awb_gain_config = rkisp1_awb_gain_config_v12,2397 .aec_config = rkisp1_aec_config_v12,2398 .hst_config = rkisp1_hst_config_v12,2399 .hst_enable = rkisp1_hst_enable_v12,2400 .afm_config = rkisp1_afm_config_v12,2401};2402 2403static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,2404 struct v4l2_fmtdesc *f)2405{2406 struct video_device *video = video_devdata(file);2407 2408 if (f->index >= ARRAY_SIZE(rkisp1_params_formats) ||2409 f->type != video->queue->type)2410 return -EINVAL;2411 2412 f->pixelformat = rkisp1_params_formats[f->index].dataformat;2413 2414 return 0;2415}2416 2417static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,2418 struct v4l2_format *f)2419{2420 struct video_device *video = video_devdata(file);2421 struct rkisp1_params *params = video_get_drvdata(video);2422 struct v4l2_meta_format *meta = &f->fmt.meta;2423 2424 if (f->type != video->queue->type)2425 return -EINVAL;2426 2427 *meta = *params->metafmt;2428 2429 return 0;2430}2431 2432static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh,2433 struct v4l2_format *f)2434{2435 struct video_device *video = video_devdata(file);2436 struct v4l2_meta_format *meta = &f->fmt.meta;2437 2438 if (f->type != video->queue->type)2439 return -EINVAL;2440 2441 *meta = *rkisp1_params_get_format_info(meta->dataformat);2442 2443 return 0;2444}2445 2446static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh,2447 struct v4l2_format *f)2448{2449 struct video_device *video = video_devdata(file);2450 struct rkisp1_params *params = video_get_drvdata(video);2451 struct v4l2_meta_format *meta = &f->fmt.meta;2452 2453 if (f->type != video->queue->type)2454 return -EINVAL;2455 2456 if (vb2_is_busy(video->queue))2457 return -EBUSY;2458 2459 params->metafmt = rkisp1_params_get_format_info(meta->dataformat);2460 *meta = *params->metafmt;2461 2462 return 0;2463}2464 2465static int rkisp1_params_querycap(struct file *file,2466 void *priv, struct v4l2_capability *cap)2467{2468 struct video_device *vdev = video_devdata(file);2469 2470 strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));2471 strscpy(cap->card, vdev->name, sizeof(cap->card));2472 strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));2473 2474 return 0;2475}2476 2477/* ISP params video device IOCTLs */2478static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {2479 .vidioc_reqbufs = vb2_ioctl_reqbufs,2480 .vidioc_querybuf = vb2_ioctl_querybuf,2481 .vidioc_create_bufs = vb2_ioctl_create_bufs,2482 .vidioc_qbuf = vb2_ioctl_qbuf,2483 .vidioc_dqbuf = vb2_ioctl_dqbuf,2484 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,2485 .vidioc_expbuf = vb2_ioctl_expbuf,2486 .vidioc_streamon = vb2_ioctl_streamon,2487 .vidioc_streamoff = vb2_ioctl_streamoff,2488 .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,2489 .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,2490 .vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out,2491 .vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out,2492 .vidioc_querycap = rkisp1_params_querycap,2493 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,2494 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,2495};2496 2497static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,2498 unsigned int *num_buffers,2499 unsigned int *num_planes,2500 unsigned int sizes[],2501 struct device *alloc_devs[])2502{2503 struct rkisp1_params *params = vq->drv_priv;2504 2505 *num_buffers = clamp_t(u32, *num_buffers,2506 RKISP1_ISP_PARAMS_REQ_BUFS_MIN,2507 RKISP1_ISP_PARAMS_REQ_BUFS_MAX);2508 2509 *num_planes = 1;2510 2511 sizes[0] = params->metafmt->buffersize;2512 2513 return 0;2514}2515 2516static int rkisp1_params_vb2_buf_init(struct vb2_buffer *vb)2517{2518 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);2519 struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);2520 struct rkisp1_params *params = vb->vb2_queue->drv_priv;2521 2522 params_buf->cfg = kvmalloc(params->metafmt->buffersize,2523 GFP_KERNEL);2524 if (!params_buf->cfg)2525 return -ENOMEM;2526 2527 return 0;2528}2529 2530static void rkisp1_params_vb2_buf_cleanup(struct vb2_buffer *vb)2531{2532 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);2533 struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);2534 2535 kvfree(params_buf->cfg);2536 params_buf->cfg = NULL;2537}2538 2539static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)2540{2541 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);2542 struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);2543 struct vb2_queue *vq = vb->vb2_queue;2544 struct rkisp1_params *params = vq->drv_priv;2545 2546 spin_lock_irq(¶ms->config_lock);2547 list_add_tail(¶ms_buf->queue, ¶ms->params);2548 spin_unlock_irq(¶ms->config_lock);2549}2550 2551static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,2552 struct vb2_buffer *vb)2553{2554 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);2555 struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);2556 size_t header_size = offsetof(struct rkisp1_ext_params_cfg, data);2557 struct rkisp1_ext_params_cfg *cfg = params_buf->cfg;2558 size_t payload_size = vb2_get_plane_payload(vb, 0);2559 struct rkisp1_ext_params_cfg *usr_cfg =2560 vb2_plane_vaddr(&vbuf->vb2_buf, 0);2561 size_t block_offset = 0;2562 size_t cfg_size;2563 2564 /*2565 * Validate the buffer payload size before copying the parameters. The2566 * payload has to be smaller than the destination buffer size and larger2567 * than the header size.2568 */2569 if (payload_size > params->metafmt->buffersize) {2570 dev_dbg(params->rkisp1->dev,2571 "Too large buffer payload size %zu\n", payload_size);2572 return -EINVAL;2573 }2574 2575 if (payload_size < header_size) {2576 dev_dbg(params->rkisp1->dev,2577 "Buffer payload %zu smaller than header size %zu\n",2578 payload_size, header_size);2579 return -EINVAL;2580 }2581 2582 /*2583 * Copy the parameters buffer to the internal scratch buffer to avoid2584 * userspace modifying the buffer content while the driver processes it.2585 */2586 memcpy(cfg, usr_cfg, payload_size);2587 2588 /* Only v1 is supported at the moment. */2589 if (cfg->version != RKISP1_EXT_PARAM_BUFFER_V1) {2590 dev_dbg(params->rkisp1->dev,2591 "Unsupported extensible format version: %u\n",2592 cfg->version);2593 return -EINVAL;2594 }2595 2596 /* Validate the size reported in the parameters buffer header. */2597 cfg_size = header_size + cfg->data_size;2598 if (cfg_size != payload_size) {2599 dev_dbg(params->rkisp1->dev,2600 "Data size %zu different than buffer payload size %zu\n",2601 cfg_size, payload_size);2602 return -EINVAL;2603 }2604 2605 /* Walk the list of parameter blocks and validate them. */2606 cfg_size = cfg->data_size;2607 while (cfg_size >= sizeof(struct rkisp1_ext_params_block_header)) {2608 const struct rkisp1_ext_params_block_header *block;2609 const struct rkisp1_ext_params_handler *handler;2610 2611 block = (const struct rkisp1_ext_params_block_header *)2612 &cfg->data[block_offset];2613 2614 if (block->type >= ARRAY_SIZE(rkisp1_ext_params_handlers)) {2615 dev_dbg(params->rkisp1->dev,2616 "Invalid parameters block type\n");2617 return -EINVAL;2618 }2619 2620 if (block->size > cfg_size) {2621 dev_dbg(params->rkisp1->dev,2622 "Premature end of parameters data\n");2623 return -EINVAL;2624 }2625 2626 if ((block->flags & (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |2627 RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) ==2628 (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |2629 RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) {2630 dev_dbg(params->rkisp1->dev,2631 "Invalid parameters block flags\n");2632 return -EINVAL;2633 }2634 2635 handler = &rkisp1_ext_params_handlers[block->type];2636 if (block->size != handler->size) {2637 dev_dbg(params->rkisp1->dev,2638 "Invalid parameters block size\n");2639 return -EINVAL;2640 }2641 2642 block_offset += block->size;2643 cfg_size -= block->size;2644 }2645 2646 if (cfg_size) {2647 dev_dbg(params->rkisp1->dev,2648 "Unexpected data after the parameters buffer end\n");2649 return -EINVAL;2650 }2651 2652 return 0;2653}2654 2655static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)2656{2657 struct rkisp1_params *params = vb->vb2_queue->drv_priv;2658 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);2659 struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);2660 struct rkisp1_params_cfg *cfg = vb2_plane_vaddr(&vbuf->vb2_buf, 0);2661 size_t payload = vb2_get_plane_payload(vb, 0);2662 2663 if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_EXT_PARAMS)2664 return rkisp1_params_prepare_ext_params(params, vb);2665 2666 /*2667 * For the fixed parameters format the payload size must be exactly the2668 * size of the parameters structure.2669 */2670 if (payload != sizeof(*cfg))2671 return -EINVAL;2672 2673 /*2674 * Copy the parameters buffer to the internal scratch buffer to avoid2675 * userspace modifying the buffer content while the driver processes it.2676 */2677 memcpy(params_buf->cfg, cfg, payload);2678 2679 return 0;2680}2681 2682static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)2683{2684 struct rkisp1_params *params = vq->drv_priv;2685 struct rkisp1_params_buffer *buf;2686 LIST_HEAD(tmp_list);2687 2688 /*2689 * we first move the buffers into a local list 'tmp_list'2690 * and then we can iterate it and call vb2_buffer_done2691 * without holding the lock2692 */2693 spin_lock_irq(¶ms->config_lock);2694 list_splice_init(¶ms->params, &tmp_list);2695 spin_unlock_irq(¶ms->config_lock);2696 2697 list_for_each_entry(buf, &tmp_list, queue)2698 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);2699 2700 params->enabled_blocks = 0;2701}2702 2703static const struct vb2_ops rkisp1_params_vb2_ops = {2704 .queue_setup = rkisp1_params_vb2_queue_setup,2705 .buf_init = rkisp1_params_vb2_buf_init,2706 .buf_cleanup = rkisp1_params_vb2_buf_cleanup,2707 .wait_prepare = vb2_ops_wait_prepare,2708 .wait_finish = vb2_ops_wait_finish,2709 .buf_queue = rkisp1_params_vb2_buf_queue,2710 .buf_prepare = rkisp1_params_vb2_buf_prepare,2711 .stop_streaming = rkisp1_params_vb2_stop_streaming,2712};2713 2714static const struct v4l2_file_operations rkisp1_params_fops = {2715 .mmap = vb2_fop_mmap,2716 .unlocked_ioctl = video_ioctl2,2717 .poll = vb2_fop_poll,2718 .open = v4l2_fh_open,2719 .release = vb2_fop_release2720};2721 2722static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,2723 struct rkisp1_params *params)2724{2725 struct rkisp1_vdev_node *node;2726 2727 node = container_of(q, struct rkisp1_vdev_node, buf_queue);2728 2729 q->type = V4L2_BUF_TYPE_META_OUTPUT;2730 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;2731 q->drv_priv = params;2732 q->ops = &rkisp1_params_vb2_ops;2733 q->mem_ops = &vb2_vmalloc_memops;2734 q->buf_struct_size = sizeof(struct rkisp1_params_buffer);2735 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;2736 q->lock = &node->vlock;2737 2738 return vb2_queue_init(q);2739}2740 2741int rkisp1_params_register(struct rkisp1_device *rkisp1)2742{2743 struct rkisp1_params *params = &rkisp1->params;2744 struct rkisp1_vdev_node *node = ¶ms->vnode;2745 struct video_device *vdev = &node->vdev;2746 int ret;2747 2748 params->rkisp1 = rkisp1;2749 mutex_init(&node->vlock);2750 INIT_LIST_HEAD(¶ms->params);2751 spin_lock_init(¶ms->config_lock);2752 2753 strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));2754 2755 video_set_drvdata(vdev, params);2756 vdev->ioctl_ops = &rkisp1_params_ioctl;2757 vdev->fops = &rkisp1_params_fops;2758 vdev->release = video_device_release_empty;2759 /*2760 * Provide a mutex to v4l2 core. It will be used2761 * to protect all fops and v4l2 ioctls.2762 */2763 vdev->lock = &node->vlock;2764 vdev->v4l2_dev = &rkisp1->v4l2_dev;2765 vdev->queue = &node->buf_queue;2766 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;2767 vdev->vfl_dir = VFL_DIR_TX;2768 rkisp1_params_init_vb2_queue(vdev->queue, params);2769 2770 params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED];2771 2772 if (params->rkisp1->info->isp_ver == RKISP1_V12)2773 params->ops = &rkisp1_v12_params_ops;2774 else2775 params->ops = &rkisp1_v10_params_ops;2776 2777 video_set_drvdata(vdev, params);2778 2779 node->pad.flags = MEDIA_PAD_FL_SOURCE;2780 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);2781 if (ret)2782 goto error;2783 2784 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);2785 if (ret) {2786 dev_err(rkisp1->dev,2787 "failed to register %s, ret=%d\n", vdev->name, ret);2788 goto error;2789 }2790 2791 return 0;2792 2793error:2794 media_entity_cleanup(&vdev->entity);2795 mutex_destroy(&node->vlock);2796 return ret;2797}2798 2799void rkisp1_params_unregister(struct rkisp1_device *rkisp1)2800{2801 struct rkisp1_params *params = &rkisp1->params;2802 struct rkisp1_vdev_node *node = ¶ms->vnode;2803 struct video_device *vdev = &node->vdev;2804 2805 if (!video_is_registered(vdev))2806 return;2807 2808 vb2_video_unregister_device(vdev);2809 media_entity_cleanup(&vdev->entity);2810 mutex_destroy(&node->vlock);2811}2812