File Index
Files and directories
Sign in
FILE

rkisp1-params.c

File preview with syntax highlighting.

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