xref: /linux/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c (revision cd42f8023f16e8c5614be529972e9ffbb309db85)
1e6938cc1SHelen Koike // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2e6938cc1SHelen Koike /*
3e6938cc1SHelen Koike  * Rockchip ISP1 Driver - Params subdevice
4e6938cc1SHelen Koike  *
5e6938cc1SHelen Koike  * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
6e6938cc1SHelen Koike  */
7e6938cc1SHelen Koike 
8e6938cc1SHelen Koike #include <media/v4l2-common.h>
9e6938cc1SHelen Koike #include <media/v4l2-event.h>
10e6938cc1SHelen Koike #include <media/v4l2-ioctl.h>
11e6938cc1SHelen Koike #include <media/videobuf2-core.h>
12e6938cc1SHelen Koike #include <media/videobuf2-vmalloc.h>	/* for ISP params */
13e6938cc1SHelen Koike 
14e6938cc1SHelen Koike #include "rkisp1-common.h"
15e6938cc1SHelen Koike 
16e6938cc1SHelen Koike #define RKISP1_PARAMS_DEV_NAME	RKISP1_DRIVER_NAME "_params"
17e6938cc1SHelen Koike 
18e6938cc1SHelen Koike #define RKISP1_ISP_PARAMS_REQ_BUFS_MIN	2
19e6938cc1SHelen Koike #define RKISP1_ISP_PARAMS_REQ_BUFS_MAX	8
20e6938cc1SHelen Koike 
21e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_LINE_THRESH(n) \
22e6938cc1SHelen Koike 			(RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))
23e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \
24e6938cc1SHelen Koike 			(RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))
25e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_PG_FAC(n) \
26e6938cc1SHelen Koike 			(RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))
27e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_RND_THRESH(n) \
28e6938cc1SHelen Koike 			(RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))
29e6938cc1SHelen Koike #define RKISP1_ISP_DPCC_RG_FAC(n) \
30e6938cc1SHelen Koike 			(RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))
31e6938cc1SHelen Koike #define RKISP1_ISP_CC_COEFF(n) \
32e6938cc1SHelen Koike 			(RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
33e6938cc1SHelen Koike 
34e6938cc1SHelen Koike static inline void
35e6938cc1SHelen Koike rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
36e6938cc1SHelen Koike {
37e6938cc1SHelen Koike 	u32 val;
38e6938cc1SHelen Koike 
39e6938cc1SHelen Koike 	val = rkisp1_read(params->rkisp1, reg);
40e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, val | bit_mask, reg);
41e6938cc1SHelen Koike }
42e6938cc1SHelen Koike 
43e6938cc1SHelen Koike static inline void
44e6938cc1SHelen Koike rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
45e6938cc1SHelen Koike {
46e6938cc1SHelen Koike 	u32 val;
47e6938cc1SHelen Koike 
48e6938cc1SHelen Koike 	val = rkisp1_read(params->rkisp1, reg);
49e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, val & ~bit_mask, reg);
50e6938cc1SHelen Koike }
51e6938cc1SHelen Koike 
52e6938cc1SHelen Koike /* ISP BP interface function */
53e6938cc1SHelen Koike static void rkisp1_dpcc_config(struct rkisp1_params *params,
54e6938cc1SHelen Koike 			       const struct rkisp1_cif_isp_dpcc_config *arg)
55e6938cc1SHelen Koike {
56e6938cc1SHelen Koike 	unsigned int i;
57e6938cc1SHelen Koike 	u32 mode;
58e6938cc1SHelen Koike 
59e6938cc1SHelen Koike 	/* avoid to override the old enable value */
60e6938cc1SHelen Koike 	mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);
61e6938cc1SHelen Koike 	mode &= RKISP1_CIF_ISP_DPCC_ENA;
62e6938cc1SHelen Koike 	mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA;
63e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, mode, RKISP1_CIF_ISP_DPCC_MODE);
64e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->output_mode,
65e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_OUTPUT_MODE);
66e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->set_use,
67e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_SET_USE);
68e6938cc1SHelen Koike 
69e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->methods[0].method,
70e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_METHODS_SET_1);
71e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->methods[1].method,
72e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_METHODS_SET_2);
73e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->methods[2].method,
74e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_METHODS_SET_3);
75e6938cc1SHelen Koike 	for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {
76e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->methods[i].line_thresh,
77e6938cc1SHelen Koike 			     RKISP1_ISP_DPCC_LINE_THRESH(i));
78e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->methods[i].line_mad_fac,
79e6938cc1SHelen Koike 			     RKISP1_ISP_DPCC_LINE_MAD_FAC(i));
80e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->methods[i].pg_fac,
81e6938cc1SHelen Koike 			     RKISP1_ISP_DPCC_PG_FAC(i));
82e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->methods[i].rnd_thresh,
83e6938cc1SHelen Koike 			     RKISP1_ISP_DPCC_RND_THRESH(i));
84e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->methods[i].rg_fac,
85e6938cc1SHelen Koike 			     RKISP1_ISP_DPCC_RG_FAC(i));
86e6938cc1SHelen Koike 	}
87e6938cc1SHelen Koike 
88e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->rnd_offs,
89e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_RND_OFFS);
90e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->ro_limits,
91e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPCC_RO_LIMITS);
92e6938cc1SHelen Koike }
93e6938cc1SHelen Koike 
94e6938cc1SHelen Koike /* ISP black level subtraction interface function */
95e6938cc1SHelen Koike static void rkisp1_bls_config(struct rkisp1_params *params,
96e6938cc1SHelen Koike 			      const struct rkisp1_cif_isp_bls_config *arg)
97e6938cc1SHelen Koike {
98e6938cc1SHelen Koike 	/* avoid to override the old enable value */
99e6938cc1SHelen Koike 	u32 new_control;
100e6938cc1SHelen Koike 
101e6938cc1SHelen Koike 	new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);
102e6938cc1SHelen Koike 	new_control &= RKISP1_CIF_ISP_BLS_ENA;
103e6938cc1SHelen Koike 	/* fixed subtraction values */
104e6938cc1SHelen Koike 	if (!arg->enable_auto) {
105e6938cc1SHelen Koike 		const struct rkisp1_cif_isp_bls_fixed_val *pval =
106e6938cc1SHelen Koike 								&arg->fixed_val;
107e6938cc1SHelen Koike 
108e6938cc1SHelen Koike 		switch (params->raw_type) {
109e6938cc1SHelen Koike 		case RKISP1_RAW_BGGR:
110e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
111e6938cc1SHelen Koike 				     pval->r, RKISP1_CIF_ISP_BLS_D_FIXED);
112e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
113e6938cc1SHelen Koike 				     pval->gr, RKISP1_CIF_ISP_BLS_C_FIXED);
114e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
115e6938cc1SHelen Koike 				     pval->gb, RKISP1_CIF_ISP_BLS_B_FIXED);
116e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
117e6938cc1SHelen Koike 				     pval->b, RKISP1_CIF_ISP_BLS_A_FIXED);
118e6938cc1SHelen Koike 			break;
119e6938cc1SHelen Koike 		case RKISP1_RAW_GBRG:
120e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
121e6938cc1SHelen Koike 				     pval->r, RKISP1_CIF_ISP_BLS_C_FIXED);
122e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
123e6938cc1SHelen Koike 				     pval->gr, RKISP1_CIF_ISP_BLS_D_FIXED);
124e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
125e6938cc1SHelen Koike 				     pval->gb, RKISP1_CIF_ISP_BLS_A_FIXED);
126e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
127e6938cc1SHelen Koike 				     pval->b, RKISP1_CIF_ISP_BLS_B_FIXED);
128e6938cc1SHelen Koike 			break;
129e6938cc1SHelen Koike 		case RKISP1_RAW_GRBG:
130e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
131e6938cc1SHelen Koike 				     pval->r, RKISP1_CIF_ISP_BLS_B_FIXED);
132e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
133e6938cc1SHelen Koike 				     pval->gr, RKISP1_CIF_ISP_BLS_A_FIXED);
134e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
135e6938cc1SHelen Koike 				     pval->gb, RKISP1_CIF_ISP_BLS_D_FIXED);
136e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
137e6938cc1SHelen Koike 				     pval->b, RKISP1_CIF_ISP_BLS_C_FIXED);
138e6938cc1SHelen Koike 			break;
139e6938cc1SHelen Koike 		case RKISP1_RAW_RGGB:
140e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
141e6938cc1SHelen Koike 				     pval->r, RKISP1_CIF_ISP_BLS_A_FIXED);
142e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
143e6938cc1SHelen Koike 				     pval->gr, RKISP1_CIF_ISP_BLS_B_FIXED);
144e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
145e6938cc1SHelen Koike 				     pval->gb, RKISP1_CIF_ISP_BLS_C_FIXED);
146e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1,
147e6938cc1SHelen Koike 				     pval->b, RKISP1_CIF_ISP_BLS_D_FIXED);
148e6938cc1SHelen Koike 			break;
149e6938cc1SHelen Koike 		default:
150e6938cc1SHelen Koike 			break;
151e6938cc1SHelen Koike 		}
152e6938cc1SHelen Koike 
153e6938cc1SHelen Koike 	} else {
154e6938cc1SHelen Koike 		if (arg->en_windows & BIT(1)) {
155e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window2.h_offs,
156e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_H2_START);
157e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window2.h_size,
158e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_H2_STOP);
159e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window2.v_offs,
160e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_V2_START);
161e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window2.v_size,
162e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_V2_STOP);
163e6938cc1SHelen Koike 			new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;
164e6938cc1SHelen Koike 		}
165e6938cc1SHelen Koike 
166e6938cc1SHelen Koike 		if (arg->en_windows & BIT(0)) {
167e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window1.h_offs,
168e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_H1_START);
169e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window1.h_size,
170e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_H1_STOP);
171e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window1.v_offs,
172e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_V1_START);
173e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->bls_window1.v_size,
174e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_BLS_V1_STOP);
175e6938cc1SHelen Koike 			new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;
176e6938cc1SHelen Koike 		}
177e6938cc1SHelen Koike 
178e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->bls_samples,
179e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_BLS_SAMPLES);
180e6938cc1SHelen Koike 
181e6938cc1SHelen Koike 		new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;
182e6938cc1SHelen Koike 	}
183e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, new_control, RKISP1_CIF_ISP_BLS_CTRL);
184e6938cc1SHelen Koike }
185e6938cc1SHelen Koike 
186e6938cc1SHelen Koike /* ISP LS correction interface function */
187e6938cc1SHelen Koike static void
188dce8ccb2SHeiko Stuebner rkisp1_lsc_matrix_config_v10(struct rkisp1_params *params,
189e6938cc1SHelen Koike 			     const struct rkisp1_cif_isp_lsc_config *pconfig)
190e6938cc1SHelen Koike {
191e6938cc1SHelen Koike 	unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;
192e6938cc1SHelen Koike 
193e6938cc1SHelen Koike 	isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
194e6938cc1SHelen Koike 
195e6938cc1SHelen Koike 	/* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
196e6938cc1SHelen Koike 	sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
197e6938cc1SHelen Koike 		    RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
198e6938cc1SHelen Koike 		    RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
199e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, sram_addr,
200e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
201e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, sram_addr,
202e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
203e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, sram_addr,
204e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
205e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, sram_addr,
206e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);
207e6938cc1SHelen Koike 
208e6938cc1SHelen Koike 	/* program data tables (table size is 9 * 17 = 153) */
209e6938cc1SHelen Koike 	for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
210e6938cc1SHelen Koike 		/*
211e6938cc1SHelen Koike 		 * 17 sectors with 2 values in one DWORD = 9
212e6938cc1SHelen Koike 		 * DWORDs (2nd value of last DWORD unused)
213e6938cc1SHelen Koike 		 */
214e6938cc1SHelen Koike 		for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
215dce8ccb2SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->r_data_tbl[i][j],
216e6938cc1SHelen Koike 								 pconfig->r_data_tbl[i][j + 1]);
217e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, data,
218e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
219e6938cc1SHelen Koike 
220dce8ccb2SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gr_data_tbl[i][j],
221e6938cc1SHelen Koike 								 pconfig->gr_data_tbl[i][j + 1]);
222e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, data,
223e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
224e6938cc1SHelen Koike 
225dce8ccb2SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gb_data_tbl[i][j],
226e6938cc1SHelen Koike 								 pconfig->gb_data_tbl[i][j + 1]);
227e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, data,
228e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
229e6938cc1SHelen Koike 
230dce8ccb2SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->b_data_tbl[i][j],
231e6938cc1SHelen Koike 								 pconfig->b_data_tbl[i][j + 1]);
232e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, data,
233e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
234e6938cc1SHelen Koike 		}
235dce8ccb2SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->r_data_tbl[i][j], 0);
236e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
237e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
238e6938cc1SHelen Koike 
239dce8ccb2SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gr_data_tbl[i][j], 0);
240e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
241e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
242e6938cc1SHelen Koike 
243dce8ccb2SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gb_data_tbl[i][j], 0);
244e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
245e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
246e6938cc1SHelen Koike 
247dce8ccb2SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->b_data_tbl[i][j], 0);
248e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
249e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
250e6938cc1SHelen Koike 	}
251e6938cc1SHelen Koike 	isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
252e6938cc1SHelen Koike 			    RKISP1_CIF_ISP_LSC_TABLE_0 :
253e6938cc1SHelen Koike 			    RKISP1_CIF_ISP_LSC_TABLE_1;
254e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, isp_lsc_table_sel,
255e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_LSC_TABLE_SEL);
256e6938cc1SHelen Koike }
257e6938cc1SHelen Koike 
258*cd42f802SHeiko Stuebner static void
259*cd42f802SHeiko Stuebner rkisp1_lsc_matrix_config_v12(struct rkisp1_params *params,
260*cd42f802SHeiko Stuebner 			     const struct rkisp1_cif_isp_lsc_config *pconfig)
261*cd42f802SHeiko Stuebner {
262*cd42f802SHeiko Stuebner 	unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;
263*cd42f802SHeiko Stuebner 
264*cd42f802SHeiko Stuebner 	isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
265*cd42f802SHeiko Stuebner 
266*cd42f802SHeiko Stuebner 	/* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
267*cd42f802SHeiko Stuebner 	sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
268*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
269*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
270*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
271*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
272*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
273*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);
274*cd42f802SHeiko Stuebner 
275*cd42f802SHeiko Stuebner 	/* program data tables (table size is 9 * 17 = 153) */
276*cd42f802SHeiko Stuebner 	for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
277*cd42f802SHeiko Stuebner 		/*
278*cd42f802SHeiko Stuebner 		 * 17 sectors with 2 values in one DWORD = 9
279*cd42f802SHeiko Stuebner 		 * DWORDs (2nd value of last DWORD unused)
280*cd42f802SHeiko Stuebner 		 */
281*cd42f802SHeiko Stuebner 		for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
282*cd42f802SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
283*cd42f802SHeiko Stuebner 					pconfig->r_data_tbl[i][j],
284*cd42f802SHeiko Stuebner 					pconfig->r_data_tbl[i][j + 1]);
285*cd42f802SHeiko Stuebner 			rkisp1_write(params->rkisp1, data,
286*cd42f802SHeiko Stuebner 				     RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
287*cd42f802SHeiko Stuebner 
288*cd42f802SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
289*cd42f802SHeiko Stuebner 					pconfig->gr_data_tbl[i][j],
290*cd42f802SHeiko Stuebner 					pconfig->gr_data_tbl[i][j + 1]);
291*cd42f802SHeiko Stuebner 			rkisp1_write(params->rkisp1, data,
292*cd42f802SHeiko Stuebner 				     RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
293*cd42f802SHeiko Stuebner 
294*cd42f802SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
295*cd42f802SHeiko Stuebner 					pconfig->gb_data_tbl[i][j],
296*cd42f802SHeiko Stuebner 					pconfig->gb_data_tbl[i][j + 1]);
297*cd42f802SHeiko Stuebner 			rkisp1_write(params->rkisp1, data,
298*cd42f802SHeiko Stuebner 				     RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
299*cd42f802SHeiko Stuebner 
300*cd42f802SHeiko Stuebner 			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
301*cd42f802SHeiko Stuebner 					pconfig->b_data_tbl[i][j],
302*cd42f802SHeiko Stuebner 					pconfig->b_data_tbl[i][j + 1]);
303*cd42f802SHeiko Stuebner 			rkisp1_write(params->rkisp1, data,
304*cd42f802SHeiko Stuebner 				     RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
305*cd42f802SHeiko Stuebner 		}
306*cd42f802SHeiko Stuebner 
307*cd42f802SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->r_data_tbl[i][j], 0);
308*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, data,
309*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
310*cd42f802SHeiko Stuebner 
311*cd42f802SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->gr_data_tbl[i][j], 0);
312*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, data,
313*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
314*cd42f802SHeiko Stuebner 
315*cd42f802SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->gb_data_tbl[i][j], 0);
316*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, data,
317*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
318*cd42f802SHeiko Stuebner 
319*cd42f802SHeiko Stuebner 		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->b_data_tbl[i][j], 0);
320*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, data,
321*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
322*cd42f802SHeiko Stuebner 	}
323*cd42f802SHeiko Stuebner 	isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
324*cd42f802SHeiko Stuebner 			    RKISP1_CIF_ISP_LSC_TABLE_0 :
325*cd42f802SHeiko Stuebner 			    RKISP1_CIF_ISP_LSC_TABLE_1;
326*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, isp_lsc_table_sel,
327*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_LSC_TABLE_SEL);
328*cd42f802SHeiko Stuebner }
329*cd42f802SHeiko Stuebner 
330e6938cc1SHelen Koike static void rkisp1_lsc_config(struct rkisp1_params *params,
331e6938cc1SHelen Koike 			      const struct rkisp1_cif_isp_lsc_config *arg)
332e6938cc1SHelen Koike {
333e6938cc1SHelen Koike 	unsigned int i, data;
334e6938cc1SHelen Koike 	u32 lsc_ctrl;
335e6938cc1SHelen Koike 
336e6938cc1SHelen Koike 	/* To config must be off , store the current status firstly */
337e6938cc1SHelen Koike 	lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL);
338e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
339e6938cc1SHelen Koike 				RKISP1_CIF_ISP_LSC_CTRL_ENA);
3405e8d9d72SHeiko Stuebner 	params->ops->lsc_matrix_config(params, arg);
341e6938cc1SHelen Koike 
342e6938cc1SHelen Koike 	for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {
343e6938cc1SHelen Koike 		/* program x size tables */
344e6938cc1SHelen Koike 		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],
345e6938cc1SHelen Koike 						    arg->x_size_tbl[i * 2 + 1]);
346e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
347e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4);
348e6938cc1SHelen Koike 
349e6938cc1SHelen Koike 		/* program x grad tables */
350e6938cc1SHelen Koike 		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
351e6938cc1SHelen Koike 						    arg->x_grad_tbl[i * 2 + 1]);
352e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
353e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4);
354e6938cc1SHelen Koike 
355e6938cc1SHelen Koike 		/* program y size tables */
356e6938cc1SHelen Koike 		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],
357e6938cc1SHelen Koike 						    arg->y_size_tbl[i * 2 + 1]);
358e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
359e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4);
360e6938cc1SHelen Koike 
361e6938cc1SHelen Koike 		/* program y grad tables */
362e6938cc1SHelen Koike 		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
363e6938cc1SHelen Koike 						    arg->y_grad_tbl[i * 2 + 1]);
364e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, data,
365e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4);
366e6938cc1SHelen Koike 	}
367e6938cc1SHelen Koike 
368e6938cc1SHelen Koike 	/* restore the lsc ctrl status */
369e6938cc1SHelen Koike 	if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) {
370e6938cc1SHelen Koike 		rkisp1_param_set_bits(params,
371e6938cc1SHelen Koike 				      RKISP1_CIF_ISP_LSC_CTRL,
372e6938cc1SHelen Koike 				      RKISP1_CIF_ISP_LSC_CTRL_ENA);
373e6938cc1SHelen Koike 	} else {
374e6938cc1SHelen Koike 		rkisp1_param_clear_bits(params,
375e6938cc1SHelen Koike 					RKISP1_CIF_ISP_LSC_CTRL,
376e6938cc1SHelen Koike 					RKISP1_CIF_ISP_LSC_CTRL_ENA);
377e6938cc1SHelen Koike 	}
378e6938cc1SHelen Koike }
379e6938cc1SHelen Koike 
380e6938cc1SHelen Koike /* ISP Filtering function */
381e6938cc1SHelen Koike static void rkisp1_flt_config(struct rkisp1_params *params,
382e6938cc1SHelen Koike 			      const struct rkisp1_cif_isp_flt_config *arg)
383e6938cc1SHelen Koike {
384e6938cc1SHelen Koike 	u32 filt_mode;
385e6938cc1SHelen Koike 
386e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
387e6938cc1SHelen Koike 		     arg->thresh_bl0, RKISP1_CIF_ISP_FILT_THRESH_BL0);
388e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
389e6938cc1SHelen Koike 		     arg->thresh_bl1, RKISP1_CIF_ISP_FILT_THRESH_BL1);
390e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
391e6938cc1SHelen Koike 		     arg->thresh_sh0, RKISP1_CIF_ISP_FILT_THRESH_SH0);
392e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
393e6938cc1SHelen Koike 		     arg->thresh_sh1, RKISP1_CIF_ISP_FILT_THRESH_SH1);
394e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->fac_bl0, RKISP1_CIF_ISP_FILT_FAC_BL0);
395e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->fac_bl1, RKISP1_CIF_ISP_FILT_FAC_BL1);
396e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->fac_mid, RKISP1_CIF_ISP_FILT_FAC_MID);
397e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->fac_sh0, RKISP1_CIF_ISP_FILT_FAC_SH0);
398e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->fac_sh1, RKISP1_CIF_ISP_FILT_FAC_SH1);
399e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
400e6938cc1SHelen Koike 		     arg->lum_weight, RKISP1_CIF_ISP_FILT_LUM_WEIGHT);
401e6938cc1SHelen Koike 
402e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
403e6938cc1SHelen Koike 		     (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |
404e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
405e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
406e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1),
407e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_FILT_MODE);
408e6938cc1SHelen Koike 
409e6938cc1SHelen Koike 	/* avoid to override the old enable value */
410e6938cc1SHelen Koike 	filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);
411e6938cc1SHelen Koike 	filt_mode &= RKISP1_CIF_ISP_FLT_ENA;
412e6938cc1SHelen Koike 	if (arg->mode)
413e6938cc1SHelen Koike 		filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;
414e6938cc1SHelen Koike 	filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
415e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
416e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);
417e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, filt_mode, RKISP1_CIF_ISP_FILT_MODE);
418e6938cc1SHelen Koike }
419e6938cc1SHelen Koike 
420e6938cc1SHelen Koike /* ISP demosaic interface function */
421e6938cc1SHelen Koike static int rkisp1_bdm_config(struct rkisp1_params *params,
422e6938cc1SHelen Koike 			     const struct rkisp1_cif_isp_bdm_config *arg)
423e6938cc1SHelen Koike {
424e6938cc1SHelen Koike 	u32 bdm_th;
425e6938cc1SHelen Koike 
426e6938cc1SHelen Koike 	/* avoid to override the old enable value */
427e6938cc1SHelen Koike 	bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);
428e6938cc1SHelen Koike 	bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
429e6938cc1SHelen Koike 	bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
430e6938cc1SHelen Koike 	/* set demosaic threshold */
431e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, bdm_th, RKISP1_CIF_ISP_DEMOSAIC);
432e6938cc1SHelen Koike 	return 0;
433e6938cc1SHelen Koike }
434e6938cc1SHelen Koike 
435e6938cc1SHelen Koike /* ISP GAMMA correction interface function */
436e6938cc1SHelen Koike static void rkisp1_sdg_config(struct rkisp1_params *params,
437e6938cc1SHelen Koike 			      const struct rkisp1_cif_isp_sdg_config *arg)
438e6938cc1SHelen Koike {
439e6938cc1SHelen Koike 	unsigned int i;
440e6938cc1SHelen Koike 
441e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
442e6938cc1SHelen Koike 		     arg->xa_pnts.gamma_dx0, RKISP1_CIF_ISP_GAMMA_DX_LO);
443e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
444e6938cc1SHelen Koike 		     arg->xa_pnts.gamma_dx1, RKISP1_CIF_ISP_GAMMA_DX_HI);
445e6938cc1SHelen Koike 
446e6938cc1SHelen Koike 	for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {
447e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->curve_r.gamma_y[i],
448e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4);
449e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->curve_g.gamma_y[i],
450e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4);
451e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->curve_b.gamma_y[i],
452e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4);
453e6938cc1SHelen Koike 	}
454e6938cc1SHelen Koike }
455e6938cc1SHelen Koike 
456e6938cc1SHelen Koike /* ISP GAMMA correction interface function */
457dce8ccb2SHeiko Stuebner static void rkisp1_goc_config_v10(struct rkisp1_params *params,
458e6938cc1SHelen Koike 				  const struct rkisp1_cif_isp_goc_config *arg)
459e6938cc1SHelen Koike {
460e6938cc1SHelen Koike 	unsigned int i;
461e6938cc1SHelen Koike 
462e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
463e6938cc1SHelen Koike 				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
464dce8ccb2SHeiko Stuebner 	rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V10);
465e6938cc1SHelen Koike 
466ef357e02SHeiko Stuebner 	for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++)
467e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->gamma_y[i],
468dce8ccb2SHeiko Stuebner 			     RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V10 + i * 4);
469e6938cc1SHelen Koike }
470e6938cc1SHelen Koike 
471*cd42f802SHeiko Stuebner static void rkisp1_goc_config_v12(struct rkisp1_params *params,
472*cd42f802SHeiko Stuebner 				  const struct rkisp1_cif_isp_goc_config *arg)
473*cd42f802SHeiko Stuebner {
474*cd42f802SHeiko Stuebner 	unsigned int i;
475*cd42f802SHeiko Stuebner 	u32 value;
476*cd42f802SHeiko Stuebner 
477*cd42f802SHeiko Stuebner 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
478*cd42f802SHeiko Stuebner 				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
479*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V12);
480*cd42f802SHeiko Stuebner 
481*cd42f802SHeiko Stuebner 	for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 / 2; i++) {
482*cd42f802SHeiko Stuebner 		value = RKISP1_CIF_ISP_GAMMA_VALUE_V12(
483*cd42f802SHeiko Stuebner 			arg->gamma_y[2 * i + 1],
484*cd42f802SHeiko Stuebner 			arg->gamma_y[2 * i]);
485*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, value,
486*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V12 + i * 4);
487*cd42f802SHeiko Stuebner 	}
488*cd42f802SHeiko Stuebner }
489*cd42f802SHeiko Stuebner 
490e6938cc1SHelen Koike /* ISP Cross Talk */
491e6938cc1SHelen Koike static void rkisp1_ctk_config(struct rkisp1_params *params,
492e6938cc1SHelen Koike 			      const struct rkisp1_cif_isp_ctk_config *arg)
493e6938cc1SHelen Koike {
494e6938cc1SHelen Koike 	unsigned int i, j, k = 0;
495e6938cc1SHelen Koike 
496e6938cc1SHelen Koike 	for (i = 0; i < 3; i++)
497e6938cc1SHelen Koike 		for (j = 0; j < 3; j++)
498e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, arg->coeff[i][j],
499e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++);
500e6938cc1SHelen Koike 	for (i = 0; i < 3; i++)
501e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->ct_offset[i],
502e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_CT_OFFSET_R + i * 4);
503e6938cc1SHelen Koike }
504e6938cc1SHelen Koike 
505e6938cc1SHelen Koike static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)
506e6938cc1SHelen Koike {
507e6938cc1SHelen Koike 	if (en)
508e6938cc1SHelen Koike 		return;
509e6938cc1SHelen Koike 
510e6938cc1SHelen Koike 	/* Write back the default values. */
511e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_0);
512e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_1);
513e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_2);
514e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_3);
515e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_4);
516e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_5);
517e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_6);
518e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_7);
519e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_8);
520e6938cc1SHelen Koike 
521e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_R);
522e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_G);
523e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_B);
524e6938cc1SHelen Koike }
525e6938cc1SHelen Koike 
526e6938cc1SHelen Koike /* ISP White Balance Mode */
527dce8ccb2SHeiko Stuebner static void rkisp1_awb_meas_config_v10(struct rkisp1_params *params,
528e6938cc1SHelen Koike 				       const struct rkisp1_cif_isp_awb_meas_config *arg)
529e6938cc1SHelen Koike {
530e6938cc1SHelen Koike 	u32 reg_val = 0;
531e6938cc1SHelen Koike 	/* based on the mode,configure the awb module */
532e6938cc1SHelen Koike 	if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
533e6938cc1SHelen Koike 		/* Reference Cb and Cr */
534e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1,
535e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
536dce8ccb2SHeiko Stuebner 			     arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF_V10);
537e6938cc1SHelen Koike 		/* Yc Threshold */
538e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1,
539e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
540e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
541e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
542dce8ccb2SHeiko Stuebner 			     arg->min_c, RKISP1_CIF_ISP_AWB_THRESH_V10);
543e6938cc1SHelen Koike 	}
544e6938cc1SHelen Koike 
545dce8ccb2SHeiko Stuebner 	reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10);
546e6938cc1SHelen Koike 	if (arg->enable_ymax_cmp)
547e6938cc1SHelen Koike 		reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
548e6938cc1SHelen Koike 	else
549e6938cc1SHelen Koike 		reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
550dce8ccb2SHeiko Stuebner 	rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP_V10);
551e6938cc1SHelen Koike 
552e6938cc1SHelen Koike 	/* window offset */
553e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
554dce8ccb2SHeiko Stuebner 		     arg->awb_wnd.v_offs, RKISP1_CIF_ISP_AWB_WND_V_OFFS_V10);
555e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
556dce8ccb2SHeiko Stuebner 		     arg->awb_wnd.h_offs, RKISP1_CIF_ISP_AWB_WND_H_OFFS_V10);
557e6938cc1SHelen Koike 	/* AWB window size */
558e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
559dce8ccb2SHeiko Stuebner 		     arg->awb_wnd.v_size, RKISP1_CIF_ISP_AWB_WND_V_SIZE_V10);
560e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
561dce8ccb2SHeiko Stuebner 		     arg->awb_wnd.h_size, RKISP1_CIF_ISP_AWB_WND_H_SIZE_V10);
562e6938cc1SHelen Koike 	/* Number of frames */
563e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
564dce8ccb2SHeiko Stuebner 		     arg->frames, RKISP1_CIF_ISP_AWB_FRAMES_V10);
565e6938cc1SHelen Koike }
566e6938cc1SHelen Koike 
567*cd42f802SHeiko Stuebner static void rkisp1_awb_meas_config_v12(struct rkisp1_params *params,
568*cd42f802SHeiko Stuebner 				       const struct rkisp1_cif_isp_awb_meas_config *arg)
569*cd42f802SHeiko Stuebner {
570*cd42f802SHeiko Stuebner 	u32 reg_val = 0;
571*cd42f802SHeiko Stuebner 	/* based on the mode,configure the awb module */
572*cd42f802SHeiko Stuebner 	if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
573*cd42f802SHeiko Stuebner 		/* Reference Cb and Cr */
574*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1,
575*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
576*cd42f802SHeiko Stuebner 			     arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF_V12);
577*cd42f802SHeiko Stuebner 		/* Yc Threshold */
578*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1,
579*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
580*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
581*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
582*cd42f802SHeiko Stuebner 			     arg->min_c, RKISP1_CIF_ISP_AWB_THRESH_V12);
583*cd42f802SHeiko Stuebner 	}
584*cd42f802SHeiko Stuebner 
585*cd42f802SHeiko Stuebner 	reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);
586*cd42f802SHeiko Stuebner 	if (arg->enable_ymax_cmp)
587*cd42f802SHeiko Stuebner 		reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
588*cd42f802SHeiko Stuebner 	else
589*cd42f802SHeiko Stuebner 		reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
590*cd42f802SHeiko Stuebner 	reg_val &= ~RKISP1_CIF_ISP_AWB_SET_FRAMES_MASK_V12;
591*cd42f802SHeiko Stuebner 	reg_val |= RKISP1_CIF_ISP_AWB_SET_FRAMES_V12(arg->frames);
592*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP_V12);
593*cd42f802SHeiko Stuebner 
594*cd42f802SHeiko Stuebner 	/* window offset */
595*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
596*cd42f802SHeiko Stuebner 		     arg->awb_wnd.v_offs << 16 |
597*cd42f802SHeiko Stuebner 		     arg->awb_wnd.h_offs,
598*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AWB_OFFS_V12);
599*cd42f802SHeiko Stuebner 	/* AWB window size */
600*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
601*cd42f802SHeiko Stuebner 		     arg->awb_wnd.v_size << 16 |
602*cd42f802SHeiko Stuebner 		     arg->awb_wnd.h_size,
603*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AWB_SIZE_V12);
604*cd42f802SHeiko Stuebner }
605*cd42f802SHeiko Stuebner 
606e6938cc1SHelen Koike static void
607dce8ccb2SHeiko Stuebner rkisp1_awb_meas_enable_v10(struct rkisp1_params *params,
608e6938cc1SHelen Koike 			   const struct rkisp1_cif_isp_awb_meas_config *arg,
609e6938cc1SHelen Koike 			   bool en)
610e6938cc1SHelen Koike {
611dce8ccb2SHeiko Stuebner 	u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10);
612e6938cc1SHelen Koike 
613e6938cc1SHelen Koike 	/* switch off */
614e6938cc1SHelen Koike 	reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
615e6938cc1SHelen Koike 
616e6938cc1SHelen Koike 	if (en) {
617e6938cc1SHelen Koike 		if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
618e6938cc1SHelen Koike 			reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
619e6938cc1SHelen Koike 		else
620e6938cc1SHelen Koike 			reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
621e6938cc1SHelen Koike 
622dce8ccb2SHeiko Stuebner 		rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP_V10);
623e6938cc1SHelen Koike 
624e6938cc1SHelen Koike 		/* Measurements require AWB block be active. */
625e6938cc1SHelen Koike 		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
626e6938cc1SHelen Koike 				      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
627e6938cc1SHelen Koike 	} else {
628e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1,
629dce8ccb2SHeiko Stuebner 			     reg_val, RKISP1_CIF_ISP_AWB_PROP_V10);
630e6938cc1SHelen Koike 		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
631e6938cc1SHelen Koike 					RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
632e6938cc1SHelen Koike 	}
633e6938cc1SHelen Koike }
634e6938cc1SHelen Koike 
635e6938cc1SHelen Koike static void
636*cd42f802SHeiko Stuebner rkisp1_awb_meas_enable_v12(struct rkisp1_params *params,
637*cd42f802SHeiko Stuebner 			   const struct rkisp1_cif_isp_awb_meas_config *arg,
638*cd42f802SHeiko Stuebner 			   bool en)
639*cd42f802SHeiko Stuebner {
640*cd42f802SHeiko Stuebner 	u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);
641*cd42f802SHeiko Stuebner 
642*cd42f802SHeiko Stuebner 	/* switch off */
643*cd42f802SHeiko Stuebner 	reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
644*cd42f802SHeiko Stuebner 
645*cd42f802SHeiko Stuebner 	if (en) {
646*cd42f802SHeiko Stuebner 		if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
647*cd42f802SHeiko Stuebner 			reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
648*cd42f802SHeiko Stuebner 		else
649*cd42f802SHeiko Stuebner 			reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
650*cd42f802SHeiko Stuebner 
651*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP_V12);
652*cd42f802SHeiko Stuebner 
653*cd42f802SHeiko Stuebner 		/* Measurements require AWB block be active. */
654*cd42f802SHeiko Stuebner 		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
655*cd42f802SHeiko Stuebner 				      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
656*cd42f802SHeiko Stuebner 	} else {
657*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1,
658*cd42f802SHeiko Stuebner 			     reg_val, RKISP1_CIF_ISP_AWB_PROP_V12);
659*cd42f802SHeiko Stuebner 		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
660*cd42f802SHeiko Stuebner 					RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
661*cd42f802SHeiko Stuebner 	}
662*cd42f802SHeiko Stuebner }
663*cd42f802SHeiko Stuebner 
664*cd42f802SHeiko Stuebner static void
665dce8ccb2SHeiko Stuebner rkisp1_awb_gain_config_v10(struct rkisp1_params *params,
666e6938cc1SHelen Koike 			   const struct rkisp1_cif_isp_awb_gain_config *arg)
667e6938cc1SHelen Koike {
668e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
669e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
670dce8ccb2SHeiko Stuebner 		     arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G_V10);
671e6938cc1SHelen Koike 
672e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
673e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
674dce8ccb2SHeiko Stuebner 		     arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB_V10);
675e6938cc1SHelen Koike }
676e6938cc1SHelen Koike 
677*cd42f802SHeiko Stuebner static void
678*cd42f802SHeiko Stuebner rkisp1_awb_gain_config_v12(struct rkisp1_params *params,
679*cd42f802SHeiko Stuebner 			   const struct rkisp1_cif_isp_awb_gain_config *arg)
680*cd42f802SHeiko Stuebner {
681*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
682*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
683*cd42f802SHeiko Stuebner 		     arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G_V12);
684*cd42f802SHeiko Stuebner 
685*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
686*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
687*cd42f802SHeiko Stuebner 		     arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB_V12);
688*cd42f802SHeiko Stuebner }
689*cd42f802SHeiko Stuebner 
690dce8ccb2SHeiko Stuebner static void rkisp1_aec_config_v10(struct rkisp1_params *params,
691e6938cc1SHelen Koike 				  const struct rkisp1_cif_isp_aec_config *arg)
692e6938cc1SHelen Koike {
693e6938cc1SHelen Koike 	unsigned int block_hsize, block_vsize;
694e6938cc1SHelen Koike 	u32 exp_ctrl;
695e6938cc1SHelen Koike 
696e6938cc1SHelen Koike 	/* avoid to override the old enable value */
697e6938cc1SHelen Koike 	exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
698e6938cc1SHelen Koike 	exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
699e6938cc1SHelen Koike 	if (arg->autostop)
700e6938cc1SHelen Koike 		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
701e6938cc1SHelen Koike 	if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
702e6938cc1SHelen Koike 		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
703e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);
704e6938cc1SHelen Koike 
705e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
706dce8ccb2SHeiko Stuebner 		     arg->meas_window.h_offs, RKISP1_CIF_ISP_EXP_H_OFFSET_V10);
707e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
708dce8ccb2SHeiko Stuebner 		     arg->meas_window.v_offs, RKISP1_CIF_ISP_EXP_V_OFFSET_V10);
709e6938cc1SHelen Koike 
710e6938cc1SHelen Koike 	block_hsize = arg->meas_window.h_size /
711dce8ccb2SHeiko Stuebner 		      RKISP1_CIF_ISP_EXP_COLUMN_NUM_V10 - 1;
712e6938cc1SHelen Koike 	block_vsize = arg->meas_window.v_size /
713dce8ccb2SHeiko Stuebner 		      RKISP1_CIF_ISP_EXP_ROW_NUM_V10 - 1;
714e6938cc1SHelen Koike 
715e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
716dce8ccb2SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_H_SIZE_SET_V10(block_hsize),
717dce8ccb2SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_H_SIZE_V10);
718e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
719dce8ccb2SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_V_SIZE_SET_V10(block_vsize),
720dce8ccb2SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_V_SIZE_V10);
721e6938cc1SHelen Koike }
722e6938cc1SHelen Koike 
723*cd42f802SHeiko Stuebner static void rkisp1_aec_config_v12(struct rkisp1_params *params,
724*cd42f802SHeiko Stuebner 			       const struct rkisp1_cif_isp_aec_config *arg)
725*cd42f802SHeiko Stuebner {
726*cd42f802SHeiko Stuebner 	u32 exp_ctrl;
727*cd42f802SHeiko Stuebner 	u32 block_hsize, block_vsize;
728*cd42f802SHeiko Stuebner 	u32 wnd_num_idx = 1;
729*cd42f802SHeiko Stuebner 	const u32 ae_wnd_num[] = { 5, 9, 15, 15 };
730*cd42f802SHeiko Stuebner 
731*cd42f802SHeiko Stuebner 	/* avoid to override the old enable value */
732*cd42f802SHeiko Stuebner 	exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
733*cd42f802SHeiko Stuebner 	exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
734*cd42f802SHeiko Stuebner 	if (arg->autostop)
735*cd42f802SHeiko Stuebner 		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
736*cd42f802SHeiko Stuebner 	if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
737*cd42f802SHeiko Stuebner 		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
738*cd42f802SHeiko Stuebner 	exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_WNDNUM_SET_V12(wnd_num_idx);
739*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);
740*cd42f802SHeiko Stuebner 
741*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
742*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_V_OFFSET_SET_V12(arg->meas_window.v_offs) |
743*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_H_OFFSET_SET_V12(arg->meas_window.h_offs),
744*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_OFFS_V12);
745*cd42f802SHeiko Stuebner 
746*cd42f802SHeiko Stuebner 	block_hsize = arg->meas_window.h_size / ae_wnd_num[wnd_num_idx] - 1;
747*cd42f802SHeiko Stuebner 	block_vsize = arg->meas_window.v_size / ae_wnd_num[wnd_num_idx] - 1;
748*cd42f802SHeiko Stuebner 
749*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
750*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_V_SIZE_SET_V12(block_vsize) |
751*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_H_SIZE_SET_V12(block_hsize),
752*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_EXP_SIZE_V12);
753*cd42f802SHeiko Stuebner }
754*cd42f802SHeiko Stuebner 
755e6938cc1SHelen Koike static void rkisp1_cproc_config(struct rkisp1_params *params,
756e6938cc1SHelen Koike 				const struct rkisp1_cif_isp_cproc_config *arg)
757e6938cc1SHelen Koike {
758e6938cc1SHelen Koike 	struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =
759e6938cc1SHelen Koike 		container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);
760e6938cc1SHelen Koike 	struct rkisp1_cif_isp_ie_config *cur_ie_config =
761e6938cc1SHelen Koike 						&cur_other_cfg->ie_config;
762e6938cc1SHelen Koike 	u32 effect = cur_ie_config->effect;
763e6938cc1SHelen Koike 	u32 quantization = params->quantization;
764e6938cc1SHelen Koike 
765e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->contrast, RKISP1_CIF_C_PROC_CONTRAST);
766e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->hue, RKISP1_CIF_C_PROC_HUE);
767e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->sat, RKISP1_CIF_C_PROC_SATURATION);
768e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->brightness,
769e6938cc1SHelen Koike 		     RKISP1_CIF_C_PROC_BRIGHTNESS);
770e6938cc1SHelen Koike 
771e6938cc1SHelen Koike 	if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||
772e6938cc1SHelen Koike 	    effect != V4L2_COLORFX_NONE) {
773e6938cc1SHelen Koike 		rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
774e6938cc1SHelen Koike 					RKISP1_CIF_C_PROC_YOUT_FULL |
775e6938cc1SHelen Koike 					RKISP1_CIF_C_PROC_YIN_FULL |
776e6938cc1SHelen Koike 					RKISP1_CIF_C_PROC_COUT_FULL);
777e6938cc1SHelen Koike 	} else {
778e6938cc1SHelen Koike 		rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,
779e6938cc1SHelen Koike 				      RKISP1_CIF_C_PROC_YOUT_FULL |
780e6938cc1SHelen Koike 				      RKISP1_CIF_C_PROC_YIN_FULL |
781e6938cc1SHelen Koike 				      RKISP1_CIF_C_PROC_COUT_FULL);
782e6938cc1SHelen Koike 	}
783e6938cc1SHelen Koike }
784e6938cc1SHelen Koike 
785dce8ccb2SHeiko Stuebner static void rkisp1_hst_config_v10(struct rkisp1_params *params,
786e6938cc1SHelen Koike 				  const struct rkisp1_cif_isp_hst_config *arg)
787e6938cc1SHelen Koike {
788e6938cc1SHelen Koike 	unsigned int block_hsize, block_vsize;
789e6938cc1SHelen Koike 	static const u32 hist_weight_regs[] = {
790dce8ccb2SHeiko Stuebner 		RKISP1_CIF_ISP_HIST_WEIGHT_00TO30_V10,
791dce8ccb2SHeiko Stuebner 		RKISP1_CIF_ISP_HIST_WEIGHT_40TO21_V10,
792dce8ccb2SHeiko Stuebner 		RKISP1_CIF_ISP_HIST_WEIGHT_31TO12_V10,
793dce8ccb2SHeiko Stuebner 		RKISP1_CIF_ISP_HIST_WEIGHT_22TO03_V10,
794dce8ccb2SHeiko Stuebner 		RKISP1_CIF_ISP_HIST_WEIGHT_13TO43_V10,
795dce8ccb2SHeiko Stuebner 		RKISP1_CIF_ISP_HIST_WEIGHT_04TO34_V10,
796e6938cc1SHelen Koike 	};
797e6938cc1SHelen Koike 	const u8 *weight;
798e6938cc1SHelen Koike 	unsigned int i;
799e6938cc1SHelen Koike 	u32 hist_prop;
800e6938cc1SHelen Koike 
801e6938cc1SHelen Koike 	/* avoid to override the old enable value */
802dce8ccb2SHeiko Stuebner 	hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10);
803dce8ccb2SHeiko Stuebner 	hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10;
804dce8ccb2SHeiko Stuebner 	hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET_V10(arg->histogram_predivider);
805dce8ccb2SHeiko Stuebner 	rkisp1_write(params->rkisp1, hist_prop, RKISP1_CIF_ISP_HIST_PROP_V10);
806e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
807e6938cc1SHelen Koike 		     arg->meas_window.h_offs,
808dce8ccb2SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_H_OFFS_V10);
809e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1,
810e6938cc1SHelen Koike 		     arg->meas_window.v_offs,
811dce8ccb2SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_V_OFFS_V10);
812e6938cc1SHelen Koike 
813e6938cc1SHelen Koike 	block_hsize = arg->meas_window.h_size /
814dce8ccb2SHeiko Stuebner 		      RKISP1_CIF_ISP_HIST_COLUMN_NUM_V10 - 1;
815dce8ccb2SHeiko Stuebner 	block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM_V10 - 1;
816e6938cc1SHelen Koike 
817dce8ccb2SHeiko Stuebner 	rkisp1_write(params->rkisp1, block_hsize, RKISP1_CIF_ISP_HIST_H_SIZE_V10);
818dce8ccb2SHeiko Stuebner 	rkisp1_write(params->rkisp1, block_vsize, RKISP1_CIF_ISP_HIST_V_SIZE_V10);
819e6938cc1SHelen Koike 
820e6938cc1SHelen Koike 	weight = arg->hist_weight;
821e6938cc1SHelen Koike 	for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)
822e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1,
823dce8ccb2SHeiko Stuebner 			     RKISP1_CIF_ISP_HIST_WEIGHT_SET_V10(weight[0],
824e6938cc1SHelen Koike 							    weight[1],
825e6938cc1SHelen Koike 							    weight[2],
826e6938cc1SHelen Koike 							    weight[3]),
827e6938cc1SHelen Koike 				 hist_weight_regs[i]);
82866d81de7SHeiko Stuebner 
829dce8ccb2SHeiko Stuebner 	rkisp1_write(params->rkisp1, weight[0] & 0x1F, RKISP1_CIF_ISP_HIST_WEIGHT_44_V10);
830e6938cc1SHelen Koike }
831e6938cc1SHelen Koike 
832*cd42f802SHeiko Stuebner static void rkisp1_hst_config_v12(struct rkisp1_params *params,
833*cd42f802SHeiko Stuebner 				  const struct rkisp1_cif_isp_hst_config *arg)
834*cd42f802SHeiko Stuebner {
835*cd42f802SHeiko Stuebner 	unsigned int i, j;
836*cd42f802SHeiko Stuebner 	u32 block_hsize, block_vsize;
837*cd42f802SHeiko Stuebner 	u32 wnd_num_idx, hist_weight_num, hist_ctrl, value;
838*cd42f802SHeiko Stuebner 	u8 weight15x15[RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12];
839*cd42f802SHeiko Stuebner 	const u32 hist_wnd_num[] = { 5, 9, 15, 15 };
840*cd42f802SHeiko Stuebner 
841*cd42f802SHeiko Stuebner 	/* now we just support 9x9 window */
842*cd42f802SHeiko Stuebner 	wnd_num_idx = 1;
843*cd42f802SHeiko Stuebner 	memset(weight15x15, 0x00, sizeof(weight15x15));
844*cd42f802SHeiko Stuebner 	/* avoid to override the old enable value */
845*cd42f802SHeiko Stuebner 	hist_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12);
846*cd42f802SHeiko Stuebner 	hist_ctrl &= RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
847*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12;
848*cd42f802SHeiko Stuebner 	hist_ctrl = hist_ctrl |
849*cd42f802SHeiko Stuebner 		    RKISP1_CIF_ISP_HIST_CTRL_INTRSEL_SET_V12(1) |
850*cd42f802SHeiko Stuebner 		    RKISP1_CIF_ISP_HIST_CTRL_DATASEL_SET_V12(0) |
851*cd42f802SHeiko Stuebner 		    RKISP1_CIF_ISP_HIST_CTRL_WATERLINE_SET_V12(0) |
852*cd42f802SHeiko Stuebner 		    RKISP1_CIF_ISP_HIST_CTRL_AUTOSTOP_SET_V12(0) |
853*cd42f802SHeiko Stuebner 		    RKISP1_CIF_ISP_HIST_CTRL_WNDNUM_SET_V12(1) |
854*cd42f802SHeiko Stuebner 		    RKISP1_CIF_ISP_HIST_CTRL_STEPSIZE_SET_V12(arg->histogram_predivider);
855*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, hist_ctrl, RKISP1_CIF_ISP_HIST_CTRL_V12);
856*cd42f802SHeiko Stuebner 
857*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
858*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_OFFS_SET_V12(arg->meas_window.h_offs,
859*cd42f802SHeiko Stuebner 						      arg->meas_window.v_offs),
860*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_OFFS_V12);
861*cd42f802SHeiko Stuebner 
862*cd42f802SHeiko Stuebner 	block_hsize = arg->meas_window.h_size / hist_wnd_num[wnd_num_idx] - 1;
863*cd42f802SHeiko Stuebner 	block_vsize = arg->meas_window.v_size / hist_wnd_num[wnd_num_idx] - 1;
864*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
865*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_SIZE_SET_V12(block_hsize, block_vsize),
866*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_HIST_SIZE_V12);
867*cd42f802SHeiko Stuebner 
868*cd42f802SHeiko Stuebner 	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
869*cd42f802SHeiko Stuebner 		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
870*cd42f802SHeiko Stuebner 			weight15x15[i * RKISP1_CIF_ISP_HIST_ROW_NUM_V12 + j] =
871*cd42f802SHeiko Stuebner 				arg->hist_weight[i * hist_wnd_num[wnd_num_idx] + j];
872*cd42f802SHeiko Stuebner 		}
873*cd42f802SHeiko Stuebner 	}
874*cd42f802SHeiko Stuebner 
875*cd42f802SHeiko Stuebner 	hist_weight_num = RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12;
876*cd42f802SHeiko Stuebner 	for (i = 0; i < (hist_weight_num / 4); i++) {
877*cd42f802SHeiko Stuebner 		value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(
878*cd42f802SHeiko Stuebner 				 weight15x15[4 * i + 0],
879*cd42f802SHeiko Stuebner 				 weight15x15[4 * i + 1],
880*cd42f802SHeiko Stuebner 				 weight15x15[4 * i + 2],
881*cd42f802SHeiko Stuebner 				 weight15x15[4 * i + 3]);
882*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1, value,
883*cd42f802SHeiko Stuebner 				 RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i);
884*cd42f802SHeiko Stuebner 	}
885*cd42f802SHeiko Stuebner 	value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(weight15x15[4 * i + 0], 0, 0, 0);
886*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, value,
887*cd42f802SHeiko Stuebner 				 RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i);
888*cd42f802SHeiko Stuebner }
889*cd42f802SHeiko Stuebner 
890e6938cc1SHelen Koike static void
891dce8ccb2SHeiko Stuebner rkisp1_hst_enable_v10(struct rkisp1_params *params,
892e6938cc1SHelen Koike 		      const struct rkisp1_cif_isp_hst_config *arg, bool en)
893e6938cc1SHelen Koike {
894e6938cc1SHelen Koike 	if (en)	{
895e6938cc1SHelen Koike 		u32 hist_prop = rkisp1_read(params->rkisp1,
896dce8ccb2SHeiko Stuebner 					    RKISP1_CIF_ISP_HIST_PROP_V10);
897e6938cc1SHelen Koike 
898dce8ccb2SHeiko Stuebner 		hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10;
899e6938cc1SHelen Koike 		hist_prop |= arg->mode;
900dce8ccb2SHeiko Stuebner 		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
901e6938cc1SHelen Koike 				      hist_prop);
902e6938cc1SHelen Koike 	} else {
903dce8ccb2SHeiko Stuebner 		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
904dce8ccb2SHeiko Stuebner 					RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10);
905e6938cc1SHelen Koike 	}
906e6938cc1SHelen Koike }
907e6938cc1SHelen Koike 
908*cd42f802SHeiko Stuebner static void
909*cd42f802SHeiko Stuebner rkisp1_hst_enable_v12(struct rkisp1_params *params,
910*cd42f802SHeiko Stuebner 		      const struct rkisp1_cif_isp_hst_config *arg, bool en)
911*cd42f802SHeiko Stuebner {
912*cd42f802SHeiko Stuebner 	if (en) {
913*cd42f802SHeiko Stuebner 		u32 hist_ctrl = rkisp1_read(params->rkisp1,
914*cd42f802SHeiko Stuebner 					    RKISP1_CIF_ISP_HIST_CTRL_V12);
915*cd42f802SHeiko Stuebner 
916*cd42f802SHeiko Stuebner 		hist_ctrl &= ~RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12;
917*cd42f802SHeiko Stuebner 		hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_MODE_SET_V12(arg->mode);
918*cd42f802SHeiko Stuebner 		hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_EN_SET_V12(1);
919*cd42f802SHeiko Stuebner 		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,
920*cd42f802SHeiko Stuebner 				      hist_ctrl);
921*cd42f802SHeiko Stuebner 	} else {
922*cd42f802SHeiko Stuebner 		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,
923*cd42f802SHeiko Stuebner 					RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
924*cd42f802SHeiko Stuebner 					RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12);
925*cd42f802SHeiko Stuebner 	}
926*cd42f802SHeiko Stuebner }
927*cd42f802SHeiko Stuebner 
928dce8ccb2SHeiko Stuebner static void rkisp1_afm_config_v10(struct rkisp1_params *params,
929e6938cc1SHelen Koike 				  const struct rkisp1_cif_isp_afc_config *arg)
930e6938cc1SHelen Koike {
931e6938cc1SHelen Koike 	size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
932e6938cc1SHelen Koike 				  arg->num_afm_win);
933e6938cc1SHelen Koike 	u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
934e6938cc1SHelen Koike 	unsigned int i;
935e6938cc1SHelen Koike 
936e6938cc1SHelen Koike 	/* Switch off to configure. */
937e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
938e6938cc1SHelen Koike 				RKISP1_CIF_ISP_AFM_ENA);
939e6938cc1SHelen Koike 
940e6938cc1SHelen Koike 	for (i = 0; i < num_of_win; i++) {
941e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1,
942e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
943e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
944e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AFM_LT_A + i * 8);
945e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1,
946e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
947e6938cc1SHelen Koike 							 arg->afm_win[i].h_offs) |
948e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
949e6938cc1SHelen Koike 							 arg->afm_win[i].v_offs),
950e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_AFM_RB_A + i * 8);
951e6938cc1SHelen Koike 	}
952e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);
953e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->var_shift,
954e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_AFM_VAR_SHIFT);
955e6938cc1SHelen Koike 	/* restore afm status */
956e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
957e6938cc1SHelen Koike }
958e6938cc1SHelen Koike 
959*cd42f802SHeiko Stuebner static void rkisp1_afm_config_v12(struct rkisp1_params *params,
960*cd42f802SHeiko Stuebner 				  const struct rkisp1_cif_isp_afc_config *arg)
961*cd42f802SHeiko Stuebner {
962*cd42f802SHeiko Stuebner 	size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
963*cd42f802SHeiko Stuebner 				  arg->num_afm_win);
964*cd42f802SHeiko Stuebner 	u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
965*cd42f802SHeiko Stuebner 	u32 lum_var_shift, afm_var_shift;
966*cd42f802SHeiko Stuebner 	unsigned int i;
967*cd42f802SHeiko Stuebner 
968*cd42f802SHeiko Stuebner 	/* Switch off to configure. */
969*cd42f802SHeiko Stuebner 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
970*cd42f802SHeiko Stuebner 				RKISP1_CIF_ISP_AFM_ENA);
971*cd42f802SHeiko Stuebner 
972*cd42f802SHeiko Stuebner 	for (i = 0; i < num_of_win; i++) {
973*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1,
974*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
975*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
976*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AFM_LT_A + i * 8);
977*cd42f802SHeiko Stuebner 		rkisp1_write(params->rkisp1,
978*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
979*cd42f802SHeiko Stuebner 							 arg->afm_win[i].h_offs) |
980*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
981*cd42f802SHeiko Stuebner 							 arg->afm_win[i].v_offs),
982*cd42f802SHeiko Stuebner 			     RKISP1_CIF_ISP_AFM_RB_A + i * 8);
983*cd42f802SHeiko Stuebner 	}
984*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);
985*cd42f802SHeiko Stuebner 
986*cd42f802SHeiko Stuebner 	lum_var_shift = RKISP1_CIF_ISP_AFM_GET_LUM_SHIFT_a_V12(arg->var_shift);
987*cd42f802SHeiko Stuebner 	afm_var_shift = RKISP1_CIF_ISP_AFM_GET_AFM_SHIFT_a_V12(arg->var_shift);
988*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1,
989*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AFM_SET_SHIFT_a_V12(lum_var_shift, afm_var_shift) |
990*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AFM_SET_SHIFT_b_V12(lum_var_shift, afm_var_shift) |
991*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AFM_SET_SHIFT_c_V12(lum_var_shift, afm_var_shift),
992*cd42f802SHeiko Stuebner 		     RKISP1_CIF_ISP_AFM_VAR_SHIFT);
993*cd42f802SHeiko Stuebner 
994*cd42f802SHeiko Stuebner 	/* restore afm status */
995*cd42f802SHeiko Stuebner 	rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
996*cd42f802SHeiko Stuebner }
997*cd42f802SHeiko Stuebner 
998e6938cc1SHelen Koike static void rkisp1_ie_config(struct rkisp1_params *params,
999e6938cc1SHelen Koike 			     const struct rkisp1_cif_isp_ie_config *arg)
1000e6938cc1SHelen Koike {
1001e6938cc1SHelen Koike 	u32 eff_ctrl;
1002e6938cc1SHelen Koike 
1003e6938cc1SHelen Koike 	eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);
1004e6938cc1SHelen Koike 	eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;
1005e6938cc1SHelen Koike 
1006e6938cc1SHelen Koike 	if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
1007e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;
1008e6938cc1SHelen Koike 
1009e6938cc1SHelen Koike 	switch (arg->effect) {
1010e6938cc1SHelen Koike 	case V4L2_COLORFX_SEPIA:
1011e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
1012e6938cc1SHelen Koike 		break;
1013e6938cc1SHelen Koike 	case V4L2_COLORFX_SET_CBCR:
1014e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_tint,
1015e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_TINT);
1016e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
1017e6938cc1SHelen Koike 		break;
1018e6938cc1SHelen Koike 		/*
1019e6938cc1SHelen Koike 		 * Color selection is similar to water color(AQUA):
1020e6938cc1SHelen Koike 		 * grayscale + selected color w threshold
1021e6938cc1SHelen Koike 		 */
1022e6938cc1SHelen Koike 	case V4L2_COLORFX_AQUA:
1023e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;
1024e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->color_sel,
1025e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_COLOR_SEL);
1026e6938cc1SHelen Koike 		break;
1027e6938cc1SHelen Koike 	case V4L2_COLORFX_EMBOSS:
1028e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;
1029e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_mat_1,
1030e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_MAT_1);
1031e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_mat_2,
1032e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_MAT_2);
1033e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_mat_3,
1034e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_MAT_3);
1035e6938cc1SHelen Koike 		break;
1036e6938cc1SHelen Koike 	case V4L2_COLORFX_SKETCH:
1037e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;
1038e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_mat_3,
1039e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_MAT_3);
1040e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_mat_4,
1041e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_MAT_4);
1042e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->eff_mat_5,
1043e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_MAT_5);
1044e6938cc1SHelen Koike 		break;
1045e6938cc1SHelen Koike 	case V4L2_COLORFX_BW:
1046e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;
1047e6938cc1SHelen Koike 		break;
1048e6938cc1SHelen Koike 	case V4L2_COLORFX_NEGATIVE:
1049e6938cc1SHelen Koike 		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;
1050e6938cc1SHelen Koike 		break;
1051e6938cc1SHelen Koike 	default:
1052e6938cc1SHelen Koike 		break;
1053e6938cc1SHelen Koike 	}
1054e6938cc1SHelen Koike 
1055e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, eff_ctrl, RKISP1_CIF_IMG_EFF_CTRL);
1056e6938cc1SHelen Koike }
1057e6938cc1SHelen Koike 
1058e6938cc1SHelen Koike static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
1059e6938cc1SHelen Koike {
1060e6938cc1SHelen Koike 	if (en) {
1061e6938cc1SHelen Koike 		rkisp1_param_set_bits(params, RKISP1_CIF_ICCL,
1062e6938cc1SHelen Koike 				      RKISP1_CIF_ICCL_IE_CLK);
1063e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL_ENABLE,
1064e6938cc1SHelen Koike 			     RKISP1_CIF_IMG_EFF_CTRL);
1065e6938cc1SHelen Koike 		rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
1066e6938cc1SHelen Koike 				      RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);
1067e6938cc1SHelen Koike 	} else {
1068e6938cc1SHelen Koike 		rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
1069e6938cc1SHelen Koike 					RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
1070e6938cc1SHelen Koike 		rkisp1_param_clear_bits(params, RKISP1_CIF_ICCL,
1071e6938cc1SHelen Koike 					RKISP1_CIF_ICCL_IE_CLK);
1072e6938cc1SHelen Koike 	}
1073e6938cc1SHelen Koike }
1074e6938cc1SHelen Koike 
1075e6938cc1SHelen Koike static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
1076e6938cc1SHelen Koike {
1077e6938cc1SHelen Koike 	static const u16 full_range_coeff[] = {
1078e6938cc1SHelen Koike 		0x0026, 0x004b, 0x000f,
1079e6938cc1SHelen Koike 		0x01ea, 0x01d6, 0x0040,
1080e6938cc1SHelen Koike 		0x0040, 0x01ca, 0x01f6
1081e6938cc1SHelen Koike 	};
1082e6938cc1SHelen Koike 	static const u16 limited_range_coeff[] = {
1083e6938cc1SHelen Koike 		0x0021, 0x0040, 0x000d,
1084e6938cc1SHelen Koike 		0x01ed, 0x01db, 0x0038,
1085e6938cc1SHelen Koike 		0x0038, 0x01d1, 0x01f7,
1086e6938cc1SHelen Koike 	};
1087e6938cc1SHelen Koike 	unsigned int i;
1088e6938cc1SHelen Koike 
1089e6938cc1SHelen Koike 	if (full_range) {
1090e6938cc1SHelen Koike 		for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
1091e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, full_range_coeff[i],
1092e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
1093e6938cc1SHelen Koike 
1094e6938cc1SHelen Koike 		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
1095e6938cc1SHelen Koike 				      RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
1096e6938cc1SHelen Koike 				      RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
1097e6938cc1SHelen Koike 	} else {
1098e6938cc1SHelen Koike 		for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++)
1099e6938cc1SHelen Koike 			rkisp1_write(params->rkisp1, limited_range_coeff[i],
1100e6938cc1SHelen Koike 				     RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
1101e6938cc1SHelen Koike 
1102e6938cc1SHelen Koike 		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
1103e6938cc1SHelen Koike 					RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
1104e6938cc1SHelen Koike 					RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
1105e6938cc1SHelen Koike 	}
1106e6938cc1SHelen Koike }
1107e6938cc1SHelen Koike 
1108e6938cc1SHelen Koike /* ISP De-noise Pre-Filter(DPF) function */
1109e6938cc1SHelen Koike static void rkisp1_dpf_config(struct rkisp1_params *params,
1110e6938cc1SHelen Koike 			      const struct rkisp1_cif_isp_dpf_config *arg)
1111e6938cc1SHelen Koike {
1112e6938cc1SHelen Koike 	unsigned int isp_dpf_mode, spatial_coeff, i;
1113e6938cc1SHelen Koike 
1114e6938cc1SHelen Koike 	switch (arg->gain.mode) {
1115e6938cc1SHelen Koike 	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:
1116e6938cc1SHelen Koike 		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
1117e6938cc1SHelen Koike 			       RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
1118e6938cc1SHelen Koike 		break;
1119e6938cc1SHelen Koike 	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:
1120e6938cc1SHelen Koike 		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
1121e6938cc1SHelen Koike 		break;
1122e6938cc1SHelen Koike 	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:
1123e6938cc1SHelen Koike 		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
1124e6938cc1SHelen Koike 			       RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |
1125e6938cc1SHelen Koike 			       RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
1126e6938cc1SHelen Koike 		break;
1127e6938cc1SHelen Koike 	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:
1128e6938cc1SHelen Koike 		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
1129e6938cc1SHelen Koike 		break;
1130e6938cc1SHelen Koike 	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:
1131e6938cc1SHelen Koike 		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |
1132e6938cc1SHelen Koike 			       RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
1133e6938cc1SHelen Koike 		break;
1134e6938cc1SHelen Koike 	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:
1135e6938cc1SHelen Koike 	default:
1136e6938cc1SHelen Koike 		isp_dpf_mode = 0;
1137e6938cc1SHelen Koike 		break;
1138e6938cc1SHelen Koike 	}
1139e6938cc1SHelen Koike 
1140e6938cc1SHelen Koike 	if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
1141e6938cc1SHelen Koike 		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;
1142e6938cc1SHelen Koike 	if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)
1143e6938cc1SHelen Koike 		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;
1144e6938cc1SHelen Koike 	if (!arg->rb_flt.r_enable)
1145e6938cc1SHelen Koike 		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;
1146e6938cc1SHelen Koike 	if (!arg->rb_flt.b_enable)
1147e6938cc1SHelen Koike 		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;
1148e6938cc1SHelen Koike 	if (!arg->g_flt.gb_enable)
1149e6938cc1SHelen Koike 		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;
1150e6938cc1SHelen Koike 	if (!arg->g_flt.gr_enable)
1151e6938cc1SHelen Koike 		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;
1152e6938cc1SHelen Koike 
1153e6938cc1SHelen Koike 	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,
1154e6938cc1SHelen Koike 			      isp_dpf_mode);
1155e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->gain.nf_b_gain,
1156e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_NF_GAIN_B);
1157e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->gain.nf_r_gain,
1158e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_NF_GAIN_R);
1159e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->gain.nf_gb_gain,
1160e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_NF_GAIN_GB);
1161e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->gain.nf_gr_gain,
1162e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_NF_GAIN_GR);
1163e6938cc1SHelen Koike 
1164e6938cc1SHelen Koike 	for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {
1165e6938cc1SHelen Koike 		rkisp1_write(params->rkisp1, arg->nll.coeff[i],
1166e6938cc1SHelen Koike 			     RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4);
1167e6938cc1SHelen Koike 	}
1168e6938cc1SHelen Koike 
1169e6938cc1SHelen Koike 	spatial_coeff = arg->g_flt.spatial_coeff[0] |
1170e6938cc1SHelen Koike 			(arg->g_flt.spatial_coeff[1] << 8) |
1171e6938cc1SHelen Koike 			(arg->g_flt.spatial_coeff[2] << 16) |
1172e6938cc1SHelen Koike 			(arg->g_flt.spatial_coeff[3] << 24);
1173e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, spatial_coeff,
1174e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4);
1175e6938cc1SHelen Koike 
1176e6938cc1SHelen Koike 	spatial_coeff = arg->g_flt.spatial_coeff[4] |
1177e6938cc1SHelen Koike 			(arg->g_flt.spatial_coeff[5] << 8);
1178e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, spatial_coeff,
1179e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6);
1180e6938cc1SHelen Koike 
1181e6938cc1SHelen Koike 	spatial_coeff = arg->rb_flt.spatial_coeff[0] |
1182e6938cc1SHelen Koike 			(arg->rb_flt.spatial_coeff[1] << 8) |
1183e6938cc1SHelen Koike 			(arg->rb_flt.spatial_coeff[2] << 16) |
1184e6938cc1SHelen Koike 			(arg->rb_flt.spatial_coeff[3] << 24);
1185e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, spatial_coeff,
1186e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4);
1187e6938cc1SHelen Koike 
1188e6938cc1SHelen Koike 	spatial_coeff = arg->rb_flt.spatial_coeff[4] |
1189e6938cc1SHelen Koike 			(arg->rb_flt.spatial_coeff[5] << 8);
1190e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, spatial_coeff,
1191e6938cc1SHelen Koike 		     RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6);
1192e6938cc1SHelen Koike }
1193e6938cc1SHelen Koike 
1194e6938cc1SHelen Koike static void
1195e6938cc1SHelen Koike rkisp1_dpf_strength_config(struct rkisp1_params *params,
1196e6938cc1SHelen Koike 			   const struct rkisp1_cif_isp_dpf_strength_config *arg)
1197e6938cc1SHelen Koike {
1198e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->b, RKISP1_CIF_ISP_DPF_STRENGTH_B);
1199e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->g, RKISP1_CIF_ISP_DPF_STRENGTH_G);
1200e6938cc1SHelen Koike 	rkisp1_write(params->rkisp1, arg->r, RKISP1_CIF_ISP_DPF_STRENGTH_R);
1201e6938cc1SHelen Koike }
1202e6938cc1SHelen Koike 
1203e6938cc1SHelen Koike static void
1204e6938cc1SHelen Koike rkisp1_isp_isr_other_config(struct rkisp1_params *params,
1205e6938cc1SHelen Koike 			    const struct rkisp1_params_cfg *new_params)
1206e6938cc1SHelen Koike {
1207e6938cc1SHelen Koike 	unsigned int module_en_update, module_cfg_update, module_ens;
1208e6938cc1SHelen Koike 
1209e6938cc1SHelen Koike 	module_en_update = new_params->module_en_update;
1210e6938cc1SHelen Koike 	module_cfg_update = new_params->module_cfg_update;
1211e6938cc1SHelen Koike 	module_ens = new_params->module_ens;
1212e6938cc1SHelen Koike 
1213e6938cc1SHelen Koike 	/* update dpc config */
1214e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)
1215e6938cc1SHelen Koike 		rkisp1_dpcc_config(params,
1216e6938cc1SHelen Koike 				   &new_params->others.dpcc_config);
1217e6938cc1SHelen Koike 
1218e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {
1219e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC)
1220e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1221e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_DPCC_MODE,
1222e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_DPCC_ENA);
1223e6938cc1SHelen Koike 		else
1224e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1225e6938cc1SHelen Koike 						RKISP1_CIF_ISP_DPCC_MODE,
1226e6938cc1SHelen Koike 						RKISP1_CIF_ISP_DPCC_ENA);
1227e6938cc1SHelen Koike 	}
1228e6938cc1SHelen Koike 
1229e6938cc1SHelen Koike 	/* update bls config */
1230e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)
1231e6938cc1SHelen Koike 		rkisp1_bls_config(params,
1232e6938cc1SHelen Koike 				  &new_params->others.bls_config);
1233e6938cc1SHelen Koike 
1234e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {
1235e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_BLS)
1236e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1237e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_BLS_CTRL,
1238e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_BLS_ENA);
1239e6938cc1SHelen Koike 		else
1240e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1241e6938cc1SHelen Koike 						RKISP1_CIF_ISP_BLS_CTRL,
1242e6938cc1SHelen Koike 						RKISP1_CIF_ISP_BLS_ENA);
1243e6938cc1SHelen Koike 	}
1244e6938cc1SHelen Koike 
1245e6938cc1SHelen Koike 	/* update sdg config */
1246e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)
1247e6938cc1SHelen Koike 		rkisp1_sdg_config(params,
1248e6938cc1SHelen Koike 				  &new_params->others.sdg_config);
1249e6938cc1SHelen Koike 
1250e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {
1251e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_SDG)
1252e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1253e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_CTRL,
1254e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
1255e6938cc1SHelen Koike 		else
1256e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1257e6938cc1SHelen Koike 						RKISP1_CIF_ISP_CTRL,
1258e6938cc1SHelen Koike 						RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
1259e6938cc1SHelen Koike 	}
1260e6938cc1SHelen Koike 
1261e6938cc1SHelen Koike 	/* update lsc config */
1262e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)
1263e6938cc1SHelen Koike 		rkisp1_lsc_config(params,
1264e6938cc1SHelen Koike 				  &new_params->others.lsc_config);
1265e6938cc1SHelen Koike 
1266e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {
1267e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_LSC)
1268e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1269e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_LSC_CTRL,
1270e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_LSC_CTRL_ENA);
1271e6938cc1SHelen Koike 		else
1272e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1273e6938cc1SHelen Koike 						RKISP1_CIF_ISP_LSC_CTRL,
1274e6938cc1SHelen Koike 						RKISP1_CIF_ISP_LSC_CTRL_ENA);
1275e6938cc1SHelen Koike 	}
1276e6938cc1SHelen Koike 
1277e6938cc1SHelen Koike 	/* update awb gains */
1278e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
12795e8d9d72SHeiko Stuebner 		params->ops->awb_gain_config(params, &new_params->others.awb_gain_config);
1280e6938cc1SHelen Koike 
1281e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {
1282e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
1283e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1284e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_CTRL,
1285e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
1286e6938cc1SHelen Koike 		else
1287e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1288e6938cc1SHelen Koike 						RKISP1_CIF_ISP_CTRL,
1289e6938cc1SHelen Koike 						RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
1290e6938cc1SHelen Koike 	}
1291e6938cc1SHelen Koike 
1292e6938cc1SHelen Koike 	/* update bdm config */
1293e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)
1294e6938cc1SHelen Koike 		rkisp1_bdm_config(params,
1295e6938cc1SHelen Koike 				  &new_params->others.bdm_config);
1296e6938cc1SHelen Koike 
1297e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {
1298e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_BDM)
1299e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1300e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_DEMOSAIC,
1301e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
1302e6938cc1SHelen Koike 		else
1303e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1304e6938cc1SHelen Koike 						RKISP1_CIF_ISP_DEMOSAIC,
1305e6938cc1SHelen Koike 						RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
1306e6938cc1SHelen Koike 	}
1307e6938cc1SHelen Koike 
1308e6938cc1SHelen Koike 	/* update filter config */
1309e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)
1310e6938cc1SHelen Koike 		rkisp1_flt_config(params,
1311e6938cc1SHelen Koike 				  &new_params->others.flt_config);
1312e6938cc1SHelen Koike 
1313e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {
1314e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_FLT)
1315e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1316e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_FILT_MODE,
1317e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_FLT_ENA);
1318e6938cc1SHelen Koike 		else
1319e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1320e6938cc1SHelen Koike 						RKISP1_CIF_ISP_FILT_MODE,
1321e6938cc1SHelen Koike 						RKISP1_CIF_ISP_FLT_ENA);
1322e6938cc1SHelen Koike 	}
1323e6938cc1SHelen Koike 
1324e6938cc1SHelen Koike 	/* update ctk config */
1325e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)
1326e6938cc1SHelen Koike 		rkisp1_ctk_config(params,
1327e6938cc1SHelen Koike 				  &new_params->others.ctk_config);
1328e6938cc1SHelen Koike 
1329e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)
133018a4ca76SDafna Hirschfeld 		rkisp1_ctk_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));
1331e6938cc1SHelen Koike 
1332e6938cc1SHelen Koike 	/* update goc config */
1333e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)
13345e8d9d72SHeiko Stuebner 		params->ops->goc_config(params, &new_params->others.goc_config);
1335e6938cc1SHelen Koike 
1336e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {
1337e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_GOC)
1338e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1339e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_CTRL,
1340e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
1341e6938cc1SHelen Koike 		else
1342e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1343e6938cc1SHelen Koike 						RKISP1_CIF_ISP_CTRL,
1344e6938cc1SHelen Koike 						RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
1345e6938cc1SHelen Koike 	}
1346e6938cc1SHelen Koike 
1347e6938cc1SHelen Koike 	/* update cproc config */
134818a4ca76SDafna Hirschfeld 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)
1349e6938cc1SHelen Koike 		rkisp1_cproc_config(params,
1350e6938cc1SHelen Koike 				    &new_params->others.cproc_config);
1351e6938cc1SHelen Koike 
1352e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {
1353e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC)
1354e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1355e6938cc1SHelen Koike 					      RKISP1_CIF_C_PROC_CTRL,
1356e6938cc1SHelen Koike 					      RKISP1_CIF_C_PROC_CTR_ENABLE);
1357e6938cc1SHelen Koike 		else
1358e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1359e6938cc1SHelen Koike 						RKISP1_CIF_C_PROC_CTRL,
1360e6938cc1SHelen Koike 						RKISP1_CIF_C_PROC_CTR_ENABLE);
1361e6938cc1SHelen Koike 	}
1362e6938cc1SHelen Koike 
1363e6938cc1SHelen Koike 	/* update ie config */
1364e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)
136518a4ca76SDafna Hirschfeld 		rkisp1_ie_config(params, &new_params->others.ie_config);
1366e6938cc1SHelen Koike 
1367e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)
136818a4ca76SDafna Hirschfeld 		rkisp1_ie_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));
1369e6938cc1SHelen Koike 
1370e6938cc1SHelen Koike 	/* update dpf config */
1371e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)
137218a4ca76SDafna Hirschfeld 		rkisp1_dpf_config(params, &new_params->others.dpf_config);
1373e6938cc1SHelen Koike 
1374e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {
1375e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_DPF)
1376e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1377e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_DPF_MODE,
1378e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_DPF_MODE_EN);
1379e6938cc1SHelen Koike 		else
1380e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1381e6938cc1SHelen Koike 						RKISP1_CIF_ISP_DPF_MODE,
1382e6938cc1SHelen Koike 						RKISP1_CIF_ISP_DPF_MODE_EN);
1383e6938cc1SHelen Koike 	}
1384e6938cc1SHelen Koike 
1385e6938cc1SHelen Koike 	if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||
1386e6938cc1SHelen Koike 	    (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {
1387e6938cc1SHelen Koike 		/* update dpf strength config */
1388e6938cc1SHelen Koike 		rkisp1_dpf_strength_config(params,
1389e6938cc1SHelen Koike 					   &new_params->others.dpf_strength_config);
1390e6938cc1SHelen Koike 	}
1391e6938cc1SHelen Koike }
1392e6938cc1SHelen Koike 
1393e6938cc1SHelen Koike static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,
1394e6938cc1SHelen Koike 				       struct  rkisp1_params_cfg *new_params)
1395e6938cc1SHelen Koike {
1396e6938cc1SHelen Koike 	unsigned int module_en_update, module_cfg_update, module_ens;
1397e6938cc1SHelen Koike 
1398e6938cc1SHelen Koike 	module_en_update = new_params->module_en_update;
1399e6938cc1SHelen Koike 	module_cfg_update = new_params->module_cfg_update;
1400e6938cc1SHelen Koike 	module_ens = new_params->module_ens;
1401e6938cc1SHelen Koike 
1402e6938cc1SHelen Koike 	/* update awb config */
1403e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)
14045e8d9d72SHeiko Stuebner 		params->ops->awb_meas_config(params, &new_params->meas.awb_meas_config);
1405e6938cc1SHelen Koike 
1406e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)
14075e8d9d72SHeiko Stuebner 		params->ops->awb_meas_enable(params,
1408e6938cc1SHelen Koike 					     &new_params->meas.awb_meas_config,
1409e6938cc1SHelen Koike 					     !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));
1410e6938cc1SHelen Koike 
1411e6938cc1SHelen Koike 	/* update afc config */
1412e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)
14135e8d9d72SHeiko Stuebner 		params->ops->afm_config(params,
1414e6938cc1SHelen Koike 					&new_params->meas.afc_config);
1415e6938cc1SHelen Koike 
1416e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {
1417e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_AFC)
1418e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1419e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_AFM_CTRL,
1420e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_AFM_ENA);
1421e6938cc1SHelen Koike 		else
1422e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1423e6938cc1SHelen Koike 						RKISP1_CIF_ISP_AFM_CTRL,
1424e6938cc1SHelen Koike 						RKISP1_CIF_ISP_AFM_ENA);
1425e6938cc1SHelen Koike 	}
1426e6938cc1SHelen Koike 
1427e6938cc1SHelen Koike 	/* update hst config */
1428e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)
14295e8d9d72SHeiko Stuebner 		params->ops->hst_config(params,
1430e6938cc1SHelen Koike 					&new_params->meas.hst_config);
1431e6938cc1SHelen Koike 
1432e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)
14335e8d9d72SHeiko Stuebner 		params->ops->hst_enable(params,
1434e6938cc1SHelen Koike 					&new_params->meas.hst_config,
1435e6938cc1SHelen Koike 					!!(module_ens & RKISP1_CIF_ISP_MODULE_HST));
1436e6938cc1SHelen Koike 
1437e6938cc1SHelen Koike 	/* update aec config */
1438e6938cc1SHelen Koike 	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)
14395e8d9d72SHeiko Stuebner 		params->ops->aec_config(params,
1440e6938cc1SHelen Koike 					&new_params->meas.aec_config);
1441e6938cc1SHelen Koike 
1442e6938cc1SHelen Koike 	if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {
1443e6938cc1SHelen Koike 		if (module_ens & RKISP1_CIF_ISP_MODULE_AEC)
1444e6938cc1SHelen Koike 			rkisp1_param_set_bits(params,
1445e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_EXP_CTRL,
1446e6938cc1SHelen Koike 					      RKISP1_CIF_ISP_EXP_ENA);
1447e6938cc1SHelen Koike 		else
1448e6938cc1SHelen Koike 			rkisp1_param_clear_bits(params,
1449e6938cc1SHelen Koike 						RKISP1_CIF_ISP_EXP_CTRL,
1450e6938cc1SHelen Koike 						RKISP1_CIF_ISP_EXP_ENA);
1451e6938cc1SHelen Koike 	}
1452e6938cc1SHelen Koike }
1453e6938cc1SHelen Koike 
1454e6938cc1SHelen Koike static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params,
1455e6938cc1SHelen Koike 					   unsigned int frame_sequence)
1456e6938cc1SHelen Koike {
1457e6938cc1SHelen Koike 	struct rkisp1_params_cfg *new_params;
1458e6938cc1SHelen Koike 	struct rkisp1_buffer *cur_buf = NULL;
1459e6938cc1SHelen Koike 
1460e6938cc1SHelen Koike 	if (list_empty(&params->params))
1461e6938cc1SHelen Koike 		return;
1462e6938cc1SHelen Koike 
1463e6938cc1SHelen Koike 	cur_buf = list_first_entry(&params->params,
1464e6938cc1SHelen Koike 				   struct rkisp1_buffer, queue);
1465e6938cc1SHelen Koike 
146607e59d91SDafna Hirschfeld 	new_params = (struct rkisp1_params_cfg *)vb2_plane_vaddr(&cur_buf->vb.vb2_buf, 0);
1467e6938cc1SHelen Koike 
1468e6938cc1SHelen Koike 	rkisp1_isp_isr_other_config(params, new_params);
1469e6938cc1SHelen Koike 	rkisp1_isp_isr_meas_config(params, new_params);
1470e6938cc1SHelen Koike 
1471e6938cc1SHelen Koike 	/* update shadow register immediately */
1472e6938cc1SHelen Koike 	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
1473e6938cc1SHelen Koike 
1474e6938cc1SHelen Koike 	list_del(&cur_buf->queue);
1475e6938cc1SHelen Koike 
1476e6938cc1SHelen Koike 	cur_buf->vb.sequence = frame_sequence;
1477e6938cc1SHelen Koike 	vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
1478e6938cc1SHelen Koike }
1479e6938cc1SHelen Koike 
1480e6938cc1SHelen Koike void rkisp1_params_isr(struct rkisp1_device *rkisp1)
1481e6938cc1SHelen Koike {
1482e6938cc1SHelen Koike 	/*
1483e6938cc1SHelen Koike 	 * This isr is called when the ISR finishes processing a frame (RKISP1_CIF_ISP_FRAME).
1484e6938cc1SHelen Koike 	 * Configurations performed here will be applied on the next frame.
1485e6938cc1SHelen Koike 	 * Since frame_sequence is updated on the vertical sync signal, we should use
1486e6938cc1SHelen Koike 	 * frame_sequence + 1 here to indicate to userspace on which frame these parameters
1487e6938cc1SHelen Koike 	 * are being applied.
1488e6938cc1SHelen Koike 	 */
1489e6938cc1SHelen Koike 	unsigned int frame_sequence = rkisp1->isp.frame_sequence + 1;
1490e6938cc1SHelen Koike 	struct rkisp1_params *params = &rkisp1->params;
1491e6938cc1SHelen Koike 
1492e6938cc1SHelen Koike 	spin_lock(&params->config_lock);
1493e6938cc1SHelen Koike 	rkisp1_params_apply_params_cfg(params, frame_sequence);
1494e6938cc1SHelen Koike 
1495e6938cc1SHelen Koike 	spin_unlock(&params->config_lock);
1496e6938cc1SHelen Koike }
1497e6938cc1SHelen Koike 
1498e6938cc1SHelen Koike static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {
1499e6938cc1SHelen Koike 	{
1500e6938cc1SHelen Koike 		0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT
1501e6938cc1SHelen Koike 	},
1502e6938cc1SHelen Koike 	RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128
1503e6938cc1SHelen Koike };
1504e6938cc1SHelen Koike 
1505e6938cc1SHelen Koike static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {
1506e6938cc1SHelen Koike 	RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
1507e6938cc1SHelen Koike 	RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,
1508e6938cc1SHelen Koike 	{
1509e6938cc1SHelen Koike 		RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
1510e6938cc1SHelen Koike 		RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
1511e6938cc1SHelen Koike 	}
1512e6938cc1SHelen Koike };
1513e6938cc1SHelen Koike 
1514e6938cc1SHelen Koike static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {
1515e6938cc1SHelen Koike 	RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
1516e6938cc1SHelen Koike 	3,
1517e6938cc1SHelen Koike 	{
1518e6938cc1SHelen Koike 		RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
1519e6938cc1SHelen Koike 		RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
1520e6938cc1SHelen Koike 	},
1521e6938cc1SHelen Koike 	{
1522e6938cc1SHelen Koike 		0, /* To be filled in with 0x01 at runtime. */
1523e6938cc1SHelen Koike 	}
1524e6938cc1SHelen Koike };
1525e6938cc1SHelen Koike 
1526e6938cc1SHelen Koike static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {
1527e6938cc1SHelen Koike 	1,
1528e6938cc1SHelen Koike 	{
1529e6938cc1SHelen Koike 		{
1530e6938cc1SHelen Koike 			300, 225, 200, 150
1531e6938cc1SHelen Koike 		}
1532e6938cc1SHelen Koike 	},
1533e6938cc1SHelen Koike 	4,
1534e6938cc1SHelen Koike 	14
1535e6938cc1SHelen Koike };
1536e6938cc1SHelen Koike 
1537e6938cc1SHelen Koike static void rkisp1_params_config_parameter(struct rkisp1_params *params)
1538e6938cc1SHelen Koike {
1539e6938cc1SHelen Koike 	struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;
1540e6938cc1SHelen Koike 
15415e8d9d72SHeiko Stuebner 	params->ops->awb_meas_config(params, &rkisp1_awb_params_default_config);
15425e8d9d72SHeiko Stuebner 	params->ops->awb_meas_enable(params, &rkisp1_awb_params_default_config,
1543e6938cc1SHelen Koike 				     true);
1544e6938cc1SHelen Koike 
15455e8d9d72SHeiko Stuebner 	params->ops->aec_config(params, &rkisp1_aec_params_default_config);
1546e6938cc1SHelen Koike 	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
1547e6938cc1SHelen Koike 			      RKISP1_CIF_ISP_EXP_ENA);
1548e6938cc1SHelen Koike 
15495e8d9d72SHeiko Stuebner 	params->ops->afm_config(params, &rkisp1_afc_params_default_config);
1550e6938cc1SHelen Koike 	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
1551e6938cc1SHelen Koike 			      RKISP1_CIF_ISP_AFM_ENA);
1552e6938cc1SHelen Koike 
1553e6938cc1SHelen Koike 	memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
15545e8d9d72SHeiko Stuebner 	params->ops->hst_config(params, &hst);
1555dce8ccb2SHeiko Stuebner 	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
1556e6938cc1SHelen Koike 			      rkisp1_hst_params_default_config.mode);
1557e6938cc1SHelen Koike 
1558e6938cc1SHelen Koike 	/* set the  range */
1559e6938cc1SHelen Koike 	if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
1560e6938cc1SHelen Koike 		rkisp1_csm_config(params, true);
1561e6938cc1SHelen Koike 	else
1562e6938cc1SHelen Koike 		rkisp1_csm_config(params, false);
1563e6938cc1SHelen Koike 
1564e6938cc1SHelen Koike 	spin_lock_irq(&params->config_lock);
1565e6938cc1SHelen Koike 
1566e6938cc1SHelen Koike 	/* apply the first buffer if there is one already */
1567e6938cc1SHelen Koike 	rkisp1_params_apply_params_cfg(params, 0);
1568e6938cc1SHelen Koike 
1569e6938cc1SHelen Koike 	spin_unlock_irq(&params->config_lock);
1570e6938cc1SHelen Koike }
1571e6938cc1SHelen Koike 
1572e6938cc1SHelen Koike void rkisp1_params_configure(struct rkisp1_params *params,
1573e6938cc1SHelen Koike 			     enum rkisp1_fmt_raw_pat_type bayer_pat,
1574e6938cc1SHelen Koike 			     enum v4l2_quantization quantization)
1575e6938cc1SHelen Koike {
1576e6938cc1SHelen Koike 	params->quantization = quantization;
1577e6938cc1SHelen Koike 	params->raw_type = bayer_pat;
1578e6938cc1SHelen Koike 	rkisp1_params_config_parameter(params);
1579e6938cc1SHelen Koike }
1580e6938cc1SHelen Koike 
158127ba4427SSebastian Fricke /*
158227ba4427SSebastian Fricke  * Not called when the camera is active, therefore there is no need to acquire
158327ba4427SSebastian Fricke  * a lock.
158427ba4427SSebastian Fricke  */
1585e6938cc1SHelen Koike void rkisp1_params_disable(struct rkisp1_params *params)
1586e6938cc1SHelen Koike {
1587e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,
1588e6938cc1SHelen Koike 				RKISP1_CIF_ISP_DPCC_ENA);
1589e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
1590e6938cc1SHelen Koike 				RKISP1_CIF_ISP_LSC_CTRL_ENA);
1591e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
1592e6938cc1SHelen Koike 				RKISP1_CIF_ISP_BLS_ENA);
1593e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
1594e6938cc1SHelen Koike 				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
1595e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
1596e6938cc1SHelen Koike 				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
1597e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,
1598e6938cc1SHelen Koike 				RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
1599e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,
1600e6938cc1SHelen Koike 				RKISP1_CIF_ISP_FLT_ENA);
16015e8d9d72SHeiko Stuebner 	params->ops->awb_meas_enable(params, NULL, false);
1602e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
1603e6938cc1SHelen Koike 				RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
1604e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
1605e6938cc1SHelen Koike 				RKISP1_CIF_ISP_EXP_ENA);
1606e6938cc1SHelen Koike 	rkisp1_ctk_enable(params, false);
1607e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
1608e6938cc1SHelen Koike 				RKISP1_CIF_C_PROC_CTR_ENABLE);
16095e8d9d72SHeiko Stuebner 	params->ops->hst_enable(params, NULL, false);
1610e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
1611e6938cc1SHelen Koike 				RKISP1_CIF_ISP_AFM_ENA);
1612e6938cc1SHelen Koike 	rkisp1_ie_enable(params, false);
1613e6938cc1SHelen Koike 	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
1614e6938cc1SHelen Koike 				RKISP1_CIF_ISP_DPF_MODE_EN);
1615e6938cc1SHelen Koike }
1616e6938cc1SHelen Koike 
1617dce8ccb2SHeiko Stuebner static const struct rkisp1_params_ops rkisp1_v10_params_ops = {
1618dce8ccb2SHeiko Stuebner 	.lsc_matrix_config = rkisp1_lsc_matrix_config_v10,
1619dce8ccb2SHeiko Stuebner 	.goc_config = rkisp1_goc_config_v10,
1620dce8ccb2SHeiko Stuebner 	.awb_meas_config = rkisp1_awb_meas_config_v10,
1621dce8ccb2SHeiko Stuebner 	.awb_meas_enable = rkisp1_awb_meas_enable_v10,
1622dce8ccb2SHeiko Stuebner 	.awb_gain_config = rkisp1_awb_gain_config_v10,
1623dce8ccb2SHeiko Stuebner 	.aec_config = rkisp1_aec_config_v10,
1624dce8ccb2SHeiko Stuebner 	.hst_config = rkisp1_hst_config_v10,
1625dce8ccb2SHeiko Stuebner 	.hst_enable = rkisp1_hst_enable_v10,
1626dce8ccb2SHeiko Stuebner 	.afm_config = rkisp1_afm_config_v10,
16275e8d9d72SHeiko Stuebner };
16285e8d9d72SHeiko Stuebner 
1629*cd42f802SHeiko Stuebner static struct rkisp1_params_ops rkisp1_v12_params_ops = {
1630*cd42f802SHeiko Stuebner 	.lsc_matrix_config = rkisp1_lsc_matrix_config_v12,
1631*cd42f802SHeiko Stuebner 	.goc_config = rkisp1_goc_config_v12,
1632*cd42f802SHeiko Stuebner 	.awb_meas_config = rkisp1_awb_meas_config_v12,
1633*cd42f802SHeiko Stuebner 	.awb_meas_enable = rkisp1_awb_meas_enable_v12,
1634*cd42f802SHeiko Stuebner 	.awb_gain_config = rkisp1_awb_gain_config_v12,
1635*cd42f802SHeiko Stuebner 	.aec_config = rkisp1_aec_config_v12,
1636*cd42f802SHeiko Stuebner 	.hst_config = rkisp1_hst_config_v12,
1637*cd42f802SHeiko Stuebner 	.hst_enable = rkisp1_hst_enable_v12,
1638*cd42f802SHeiko Stuebner 	.afm_config = rkisp1_afm_config_v12,
1639*cd42f802SHeiko Stuebner };
1640*cd42f802SHeiko Stuebner 
1641e6938cc1SHelen Koike static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
1642e6938cc1SHelen Koike 					   struct v4l2_fmtdesc *f)
1643e6938cc1SHelen Koike {
1644e6938cc1SHelen Koike 	struct video_device *video = video_devdata(file);
1645e6938cc1SHelen Koike 	struct rkisp1_params *params = video_get_drvdata(video);
1646e6938cc1SHelen Koike 
1647e6938cc1SHelen Koike 	if (f->index > 0 || f->type != video->queue->type)
1648e6938cc1SHelen Koike 		return -EINVAL;
1649e6938cc1SHelen Koike 
1650e6938cc1SHelen Koike 	f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
1651e6938cc1SHelen Koike 
1652e6938cc1SHelen Koike 	return 0;
1653e6938cc1SHelen Koike }
1654e6938cc1SHelen Koike 
1655e6938cc1SHelen Koike static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
1656e6938cc1SHelen Koike 					struct v4l2_format *f)
1657e6938cc1SHelen Koike {
1658e6938cc1SHelen Koike 	struct video_device *video = video_devdata(file);
1659e6938cc1SHelen Koike 	struct rkisp1_params *params = video_get_drvdata(video);
1660e6938cc1SHelen Koike 	struct v4l2_meta_format *meta = &f->fmt.meta;
1661e6938cc1SHelen Koike 
1662e6938cc1SHelen Koike 	if (f->type != video->queue->type)
1663e6938cc1SHelen Koike 		return -EINVAL;
1664e6938cc1SHelen Koike 
1665e6938cc1SHelen Koike 	memset(meta, 0, sizeof(*meta));
1666e6938cc1SHelen Koike 	meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
1667e6938cc1SHelen Koike 	meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
1668e6938cc1SHelen Koike 
1669e6938cc1SHelen Koike 	return 0;
1670e6938cc1SHelen Koike }
1671e6938cc1SHelen Koike 
1672e6938cc1SHelen Koike static int rkisp1_params_querycap(struct file *file,
1673e6938cc1SHelen Koike 				  void *priv, struct v4l2_capability *cap)
1674e6938cc1SHelen Koike {
1675e6938cc1SHelen Koike 	struct video_device *vdev = video_devdata(file);
1676e6938cc1SHelen Koike 
1677e6938cc1SHelen Koike 	strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
1678e6938cc1SHelen Koike 	strscpy(cap->card, vdev->name, sizeof(cap->card));
1679e6938cc1SHelen Koike 	strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
1680e6938cc1SHelen Koike 
1681e6938cc1SHelen Koike 	return 0;
1682e6938cc1SHelen Koike }
1683e6938cc1SHelen Koike 
1684e6938cc1SHelen Koike /* ISP params video device IOCTLs */
1685e6938cc1SHelen Koike static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
1686e6938cc1SHelen Koike 	.vidioc_reqbufs = vb2_ioctl_reqbufs,
1687e6938cc1SHelen Koike 	.vidioc_querybuf = vb2_ioctl_querybuf,
1688e6938cc1SHelen Koike 	.vidioc_create_bufs = vb2_ioctl_create_bufs,
1689e6938cc1SHelen Koike 	.vidioc_qbuf = vb2_ioctl_qbuf,
1690e6938cc1SHelen Koike 	.vidioc_dqbuf = vb2_ioctl_dqbuf,
1691e6938cc1SHelen Koike 	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1692e6938cc1SHelen Koike 	.vidioc_expbuf = vb2_ioctl_expbuf,
1693e6938cc1SHelen Koike 	.vidioc_streamon = vb2_ioctl_streamon,
1694e6938cc1SHelen Koike 	.vidioc_streamoff = vb2_ioctl_streamoff,
1695e6938cc1SHelen Koike 	.vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
1696e6938cc1SHelen Koike 	.vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
1697e6938cc1SHelen Koike 	.vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
1698e6938cc1SHelen Koike 	.vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
1699e6938cc1SHelen Koike 	.vidioc_querycap = rkisp1_params_querycap,
1700e6938cc1SHelen Koike 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1701e6938cc1SHelen Koike 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1702e6938cc1SHelen Koike };
1703e6938cc1SHelen Koike 
1704e6938cc1SHelen Koike static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
1705e6938cc1SHelen Koike 					 unsigned int *num_buffers,
1706e6938cc1SHelen Koike 					 unsigned int *num_planes,
1707e6938cc1SHelen Koike 					 unsigned int sizes[],
1708e6938cc1SHelen Koike 					 struct device *alloc_devs[])
1709e6938cc1SHelen Koike {
1710e6938cc1SHelen Koike 	*num_buffers = clamp_t(u32, *num_buffers,
1711e6938cc1SHelen Koike 			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
1712e6938cc1SHelen Koike 			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
1713e6938cc1SHelen Koike 
1714e6938cc1SHelen Koike 	*num_planes = 1;
1715e6938cc1SHelen Koike 
1716e6938cc1SHelen Koike 	sizes[0] = sizeof(struct rkisp1_params_cfg);
1717e6938cc1SHelen Koike 
1718e6938cc1SHelen Koike 	return 0;
1719e6938cc1SHelen Koike }
1720e6938cc1SHelen Koike 
1721e6938cc1SHelen Koike static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
1722e6938cc1SHelen Koike {
1723e6938cc1SHelen Koike 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1724e6938cc1SHelen Koike 	struct rkisp1_buffer *params_buf =
1725e6938cc1SHelen Koike 		container_of(vbuf, struct rkisp1_buffer, vb);
1726e6938cc1SHelen Koike 	struct vb2_queue *vq = vb->vb2_queue;
1727e6938cc1SHelen Koike 	struct rkisp1_params *params = vq->drv_priv;
1728e6938cc1SHelen Koike 
1729e6938cc1SHelen Koike 	spin_lock_irq(&params->config_lock);
1730e6938cc1SHelen Koike 	list_add_tail(&params_buf->queue, &params->params);
1731e6938cc1SHelen Koike 	spin_unlock_irq(&params->config_lock);
1732e6938cc1SHelen Koike }
1733e6938cc1SHelen Koike 
1734e6938cc1SHelen Koike static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
1735e6938cc1SHelen Koike {
1736e6938cc1SHelen Koike 	if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
1737e6938cc1SHelen Koike 		return -EINVAL;
1738e6938cc1SHelen Koike 
1739e6938cc1SHelen Koike 	vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
1740e6938cc1SHelen Koike 
1741e6938cc1SHelen Koike 	return 0;
1742e6938cc1SHelen Koike }
1743e6938cc1SHelen Koike 
1744e6938cc1SHelen Koike static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
1745e6938cc1SHelen Koike {
1746e6938cc1SHelen Koike 	struct rkisp1_params *params = vq->drv_priv;
1747e6938cc1SHelen Koike 	struct rkisp1_buffer *buf;
1748e6938cc1SHelen Koike 	LIST_HEAD(tmp_list);
1749e6938cc1SHelen Koike 
1750e6938cc1SHelen Koike 	/*
1751e6938cc1SHelen Koike 	 * we first move the buffers into a local list 'tmp_list'
1752e6938cc1SHelen Koike 	 * and then we can iterate it and call vb2_buffer_done
1753e6938cc1SHelen Koike 	 * without holding the lock
1754e6938cc1SHelen Koike 	 */
1755e6938cc1SHelen Koike 	spin_lock_irq(&params->config_lock);
1756e6938cc1SHelen Koike 	list_splice_init(&params->params, &tmp_list);
1757e6938cc1SHelen Koike 	spin_unlock_irq(&params->config_lock);
1758e6938cc1SHelen Koike 
1759e6938cc1SHelen Koike 	list_for_each_entry(buf, &tmp_list, queue)
1760e6938cc1SHelen Koike 		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
1761e6938cc1SHelen Koike }
1762e6938cc1SHelen Koike 
1763a109073bSRikard Falkeborn static const struct vb2_ops rkisp1_params_vb2_ops = {
1764e6938cc1SHelen Koike 	.queue_setup = rkisp1_params_vb2_queue_setup,
1765e6938cc1SHelen Koike 	.wait_prepare = vb2_ops_wait_prepare,
1766e6938cc1SHelen Koike 	.wait_finish = vb2_ops_wait_finish,
1767e6938cc1SHelen Koike 	.buf_queue = rkisp1_params_vb2_buf_queue,
1768e6938cc1SHelen Koike 	.buf_prepare = rkisp1_params_vb2_buf_prepare,
1769e6938cc1SHelen Koike 	.stop_streaming = rkisp1_params_vb2_stop_streaming,
1770e6938cc1SHelen Koike 
1771e6938cc1SHelen Koike };
1772e6938cc1SHelen Koike 
1773a109073bSRikard Falkeborn static const struct v4l2_file_operations rkisp1_params_fops = {
1774e6938cc1SHelen Koike 	.mmap = vb2_fop_mmap,
1775e6938cc1SHelen Koike 	.unlocked_ioctl = video_ioctl2,
1776e6938cc1SHelen Koike 	.poll = vb2_fop_poll,
1777e6938cc1SHelen Koike 	.open = v4l2_fh_open,
1778e6938cc1SHelen Koike 	.release = vb2_fop_release
1779e6938cc1SHelen Koike };
1780e6938cc1SHelen Koike 
1781e6938cc1SHelen Koike static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
1782e6938cc1SHelen Koike 					struct rkisp1_params *params)
1783e6938cc1SHelen Koike {
1784e6938cc1SHelen Koike 	struct rkisp1_vdev_node *node;
1785e6938cc1SHelen Koike 
1786e6938cc1SHelen Koike 	node = container_of(q, struct rkisp1_vdev_node, buf_queue);
1787e6938cc1SHelen Koike 
1788e6938cc1SHelen Koike 	q->type = V4L2_BUF_TYPE_META_OUTPUT;
1789e6938cc1SHelen Koike 	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1790e6938cc1SHelen Koike 	q->drv_priv = params;
1791e6938cc1SHelen Koike 	q->ops = &rkisp1_params_vb2_ops;
1792e6938cc1SHelen Koike 	q->mem_ops = &vb2_vmalloc_memops;
1793e6938cc1SHelen Koike 	q->buf_struct_size = sizeof(struct rkisp1_buffer);
1794e6938cc1SHelen Koike 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1795e6938cc1SHelen Koike 	q->lock = &node->vlock;
1796e6938cc1SHelen Koike 
1797e6938cc1SHelen Koike 	return vb2_queue_init(q);
1798e6938cc1SHelen Koike }
1799e6938cc1SHelen Koike 
1800e6938cc1SHelen Koike static void rkisp1_init_params(struct rkisp1_params *params)
1801e6938cc1SHelen Koike {
1802e6938cc1SHelen Koike 	params->vdev_fmt.fmt.meta.dataformat =
1803e6938cc1SHelen Koike 		V4L2_META_FMT_RK_ISP1_PARAMS;
1804e6938cc1SHelen Koike 	params->vdev_fmt.fmt.meta.buffersize =
1805e6938cc1SHelen Koike 		sizeof(struct rkisp1_params_cfg);
18065e8d9d72SHeiko Stuebner 
1807*cd42f802SHeiko Stuebner 	if (params->rkisp1->media_dev.hw_revision == RKISP1_V12)
1808*cd42f802SHeiko Stuebner 		params->ops = &rkisp1_v12_params_ops;
1809*cd42f802SHeiko Stuebner 	else
1810dce8ccb2SHeiko Stuebner 		params->ops = &rkisp1_v10_params_ops;
1811e6938cc1SHelen Koike }
1812e6938cc1SHelen Koike 
1813e6938cc1SHelen Koike int rkisp1_params_register(struct rkisp1_device *rkisp1)
1814e6938cc1SHelen Koike {
1815e6938cc1SHelen Koike 	struct rkisp1_params *params = &rkisp1->params;
1816e6938cc1SHelen Koike 	struct rkisp1_vdev_node *node = &params->vnode;
1817e6938cc1SHelen Koike 	struct video_device *vdev = &node->vdev;
1818e6938cc1SHelen Koike 	int ret;
1819e6938cc1SHelen Koike 
1820e6938cc1SHelen Koike 	params->rkisp1 = rkisp1;
1821e6938cc1SHelen Koike 	mutex_init(&node->vlock);
1822e6938cc1SHelen Koike 	INIT_LIST_HEAD(&params->params);
1823e6938cc1SHelen Koike 	spin_lock_init(&params->config_lock);
1824e6938cc1SHelen Koike 
1825e6938cc1SHelen Koike 	strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));
1826e6938cc1SHelen Koike 
1827e6938cc1SHelen Koike 	video_set_drvdata(vdev, params);
1828e6938cc1SHelen Koike 	vdev->ioctl_ops = &rkisp1_params_ioctl;
1829e6938cc1SHelen Koike 	vdev->fops = &rkisp1_params_fops;
1830e6938cc1SHelen Koike 	vdev->release = video_device_release_empty;
1831e6938cc1SHelen Koike 	/*
1832e6938cc1SHelen Koike 	 * Provide a mutex to v4l2 core. It will be used
1833e6938cc1SHelen Koike 	 * to protect all fops and v4l2 ioctls.
1834e6938cc1SHelen Koike 	 */
1835e6938cc1SHelen Koike 	vdev->lock = &node->vlock;
1836e6938cc1SHelen Koike 	vdev->v4l2_dev = &rkisp1->v4l2_dev;
1837e6938cc1SHelen Koike 	vdev->queue = &node->buf_queue;
1838e6938cc1SHelen Koike 	vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
1839e6938cc1SHelen Koike 	vdev->vfl_dir = VFL_DIR_TX;
1840e6938cc1SHelen Koike 	rkisp1_params_init_vb2_queue(vdev->queue, params);
1841e6938cc1SHelen Koike 	rkisp1_init_params(params);
1842e6938cc1SHelen Koike 	video_set_drvdata(vdev, params);
1843e6938cc1SHelen Koike 
1844e6938cc1SHelen Koike 	node->pad.flags = MEDIA_PAD_FL_SOURCE;
1845e6938cc1SHelen Koike 	ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
1846e6938cc1SHelen Koike 	if (ret)
1847e6938cc1SHelen Koike 		return ret;
1848e6938cc1SHelen Koike 	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1849e6938cc1SHelen Koike 	if (ret) {
1850e6938cc1SHelen Koike 		dev_err(rkisp1->dev,
1851e6938cc1SHelen Koike 			"failed to register %s, ret=%d\n", vdev->name, ret);
1852e6938cc1SHelen Koike 		goto err_cleanup_media_entity;
1853e6938cc1SHelen Koike 	}
1854e6938cc1SHelen Koike 	return 0;
1855e6938cc1SHelen Koike err_cleanup_media_entity:
1856e6938cc1SHelen Koike 	media_entity_cleanup(&vdev->entity);
1857e6938cc1SHelen Koike 	return ret;
1858e6938cc1SHelen Koike }
1859e6938cc1SHelen Koike 
1860e6938cc1SHelen Koike void rkisp1_params_unregister(struct rkisp1_device *rkisp1)
1861e6938cc1SHelen Koike {
1862e6938cc1SHelen Koike 	struct rkisp1_params *params = &rkisp1->params;
1863e6938cc1SHelen Koike 	struct rkisp1_vdev_node *node = &params->vnode;
1864e6938cc1SHelen Koike 	struct video_device *vdev = &node->vdev;
1865e6938cc1SHelen Koike 
1866e6938cc1SHelen Koike 	vb2_video_unregister_device(vdev);
1867e6938cc1SHelen Koike 	media_entity_cleanup(&vdev->entity);
1868e6938cc1SHelen Koike }
1869