162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Rockchip ISP1 Driver - Params subdevice
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <media/v4l2-common.h>
962306a36Sopenharmony_ci#include <media/v4l2-event.h>
1062306a36Sopenharmony_ci#include <media/v4l2-ioctl.h>
1162306a36Sopenharmony_ci#include <media/videobuf2-core.h>
1262306a36Sopenharmony_ci#include <media/videobuf2-vmalloc.h>	/* for ISP params */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "rkisp1-common.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define RKISP1_PARAMS_DEV_NAME	RKISP1_DRIVER_NAME "_params"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN	2
1962306a36Sopenharmony_ci#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX	8
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define RKISP1_ISP_DPCC_METHODS_SET(n) \
2262306a36Sopenharmony_ci			(RKISP1_CIF_ISP_DPCC_METHODS_SET_1 + 0x4 * (n))
2362306a36Sopenharmony_ci#define RKISP1_ISP_DPCC_LINE_THRESH(n) \
2462306a36Sopenharmony_ci			(RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))
2562306a36Sopenharmony_ci#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \
2662306a36Sopenharmony_ci			(RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))
2762306a36Sopenharmony_ci#define RKISP1_ISP_DPCC_PG_FAC(n) \
2862306a36Sopenharmony_ci			(RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))
2962306a36Sopenharmony_ci#define RKISP1_ISP_DPCC_RND_THRESH(n) \
3062306a36Sopenharmony_ci			(RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))
3162306a36Sopenharmony_ci#define RKISP1_ISP_DPCC_RG_FAC(n) \
3262306a36Sopenharmony_ci			(RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))
3362306a36Sopenharmony_ci#define RKISP1_ISP_CC_COEFF(n) \
3462306a36Sopenharmony_ci			(RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic inline void
3762306a36Sopenharmony_cirkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	u32 val;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	val = rkisp1_read(params->rkisp1, reg);
4262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, reg, val | bit_mask);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic inline void
4662306a36Sopenharmony_cirkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	u32 val;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	val = rkisp1_read(params->rkisp1, reg);
5162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, reg, val & ~bit_mask);
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* ISP BP interface function */
5562306a36Sopenharmony_cistatic void rkisp1_dpcc_config(struct rkisp1_params *params,
5662306a36Sopenharmony_ci			       const struct rkisp1_cif_isp_dpcc_config *arg)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	unsigned int i;
5962306a36Sopenharmony_ci	u32 mode;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	/*
6262306a36Sopenharmony_ci	 * The enable bit is controlled in rkisp1_isp_isr_other_config() and
6362306a36Sopenharmony_ci	 * must be preserved. The grayscale mode should be configured
6462306a36Sopenharmony_ci	 * automatically based on the media bus code on the ISP sink pad, so
6562306a36Sopenharmony_ci	 * only the STAGE1_ENABLE bit can be set by userspace.
6662306a36Sopenharmony_ci	 */
6762306a36Sopenharmony_ci	mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);
6862306a36Sopenharmony_ci	mode &= RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE;
6962306a36Sopenharmony_ci	mode |= arg->mode & RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE;
7062306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE, mode);
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_OUTPUT_MODE,
7362306a36Sopenharmony_ci		     arg->output_mode & RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_MASK);
7462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_SET_USE,
7562306a36Sopenharmony_ci		     arg->set_use & RKISP1_CIF_ISP_DPCC_SET_USE_MASK);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {
7862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_METHODS_SET(i),
7962306a36Sopenharmony_ci			     arg->methods[i].method &
8062306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPCC_METHODS_SET_MASK);
8162306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_THRESH(i),
8262306a36Sopenharmony_ci			     arg->methods[i].line_thresh &
8362306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPCC_LINE_THRESH_MASK);
8462306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_MAD_FAC(i),
8562306a36Sopenharmony_ci			     arg->methods[i].line_mad_fac &
8662306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_MASK);
8762306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_PG_FAC(i),
8862306a36Sopenharmony_ci			     arg->methods[i].pg_fac &
8962306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPCC_PG_FAC_MASK);
9062306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RND_THRESH(i),
9162306a36Sopenharmony_ci			     arg->methods[i].rnd_thresh &
9262306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPCC_RND_THRESH_MASK);
9362306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RG_FAC(i),
9462306a36Sopenharmony_ci			     arg->methods[i].rg_fac &
9562306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPCC_RG_FAC_MASK);
9662306a36Sopenharmony_ci	}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RND_OFFS,
9962306a36Sopenharmony_ci		     arg->rnd_offs & RKISP1_CIF_ISP_DPCC_RND_OFFS_MASK);
10062306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RO_LIMITS,
10162306a36Sopenharmony_ci		     arg->ro_limits & RKISP1_CIF_ISP_DPCC_RO_LIMIT_MASK);
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/* ISP black level subtraction interface function */
10562306a36Sopenharmony_cistatic void rkisp1_bls_config(struct rkisp1_params *params,
10662306a36Sopenharmony_ci			      const struct rkisp1_cif_isp_bls_config *arg)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	/* avoid to override the old enable value */
10962306a36Sopenharmony_ci	u32 new_control;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);
11262306a36Sopenharmony_ci	new_control &= RKISP1_CIF_ISP_BLS_ENA;
11362306a36Sopenharmony_ci	/* fixed subtraction values */
11462306a36Sopenharmony_ci	if (!arg->enable_auto) {
11562306a36Sopenharmony_ci		const struct rkisp1_cif_isp_bls_fixed_val *pval =
11662306a36Sopenharmony_ci								&arg->fixed_val;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		switch (params->raw_type) {
11962306a36Sopenharmony_ci		case RKISP1_RAW_BGGR:
12062306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED,
12162306a36Sopenharmony_ci				     pval->r);
12262306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED,
12362306a36Sopenharmony_ci				     pval->gr);
12462306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED,
12562306a36Sopenharmony_ci				     pval->gb);
12662306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED,
12762306a36Sopenharmony_ci				     pval->b);
12862306a36Sopenharmony_ci			break;
12962306a36Sopenharmony_ci		case RKISP1_RAW_GBRG:
13062306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED,
13162306a36Sopenharmony_ci				     pval->r);
13262306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED,
13362306a36Sopenharmony_ci				     pval->gr);
13462306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED,
13562306a36Sopenharmony_ci				     pval->gb);
13662306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED,
13762306a36Sopenharmony_ci				     pval->b);
13862306a36Sopenharmony_ci			break;
13962306a36Sopenharmony_ci		case RKISP1_RAW_GRBG:
14062306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED,
14162306a36Sopenharmony_ci				     pval->r);
14262306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED,
14362306a36Sopenharmony_ci				     pval->gr);
14462306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED,
14562306a36Sopenharmony_ci				     pval->gb);
14662306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED,
14762306a36Sopenharmony_ci				     pval->b);
14862306a36Sopenharmony_ci			break;
14962306a36Sopenharmony_ci		case RKISP1_RAW_RGGB:
15062306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED,
15162306a36Sopenharmony_ci				     pval->r);
15262306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED,
15362306a36Sopenharmony_ci				     pval->gr);
15462306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED,
15562306a36Sopenharmony_ci				     pval->gb);
15662306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED,
15762306a36Sopenharmony_ci				     pval->b);
15862306a36Sopenharmony_ci			break;
15962306a36Sopenharmony_ci		default:
16062306a36Sopenharmony_ci			break;
16162306a36Sopenharmony_ci		}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	} else {
16462306a36Sopenharmony_ci		if (arg->en_windows & BIT(1)) {
16562306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_START,
16662306a36Sopenharmony_ci				     arg->bls_window2.h_offs);
16762306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_STOP,
16862306a36Sopenharmony_ci				     arg->bls_window2.h_size);
16962306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V2_START,
17062306a36Sopenharmony_ci				     arg->bls_window2.v_offs);
17162306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V2_STOP,
17262306a36Sopenharmony_ci				     arg->bls_window2.v_size);
17362306a36Sopenharmony_ci			new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;
17462306a36Sopenharmony_ci		}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci		if (arg->en_windows & BIT(0)) {
17762306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H1_START,
17862306a36Sopenharmony_ci				     arg->bls_window1.h_offs);
17962306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H1_STOP,
18062306a36Sopenharmony_ci				     arg->bls_window1.h_size);
18162306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V1_START,
18262306a36Sopenharmony_ci				     arg->bls_window1.v_offs);
18362306a36Sopenharmony_ci			rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_V1_STOP,
18462306a36Sopenharmony_ci				     arg->bls_window1.v_size);
18562306a36Sopenharmony_ci			new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;
18662306a36Sopenharmony_ci		}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_SAMPLES,
18962306a36Sopenharmony_ci			     arg->bls_samples);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci		new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;
19262306a36Sopenharmony_ci	}
19362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL, new_control);
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/* ISP LS correction interface function */
19762306a36Sopenharmony_cistatic void
19862306a36Sopenharmony_cirkisp1_lsc_matrix_config_v10(struct rkisp1_params *params,
19962306a36Sopenharmony_ci			     const struct rkisp1_cif_isp_lsc_config *pconfig)
20062306a36Sopenharmony_ci{
20162306a36Sopenharmony_ci	struct rkisp1_device *rkisp1 = params->rkisp1;
20262306a36Sopenharmony_ci	u32 lsc_status, sram_addr, lsc_table_sel;
20362306a36Sopenharmony_ci	unsigned int i, j;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	/* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
20862306a36Sopenharmony_ci	sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?
20962306a36Sopenharmony_ci		    RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
21062306a36Sopenharmony_ci		    RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
21162306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr);
21262306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr);
21362306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr);
21462306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	/* program data tables (table size is 9 * 17 = 153) */
21762306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
21862306a36Sopenharmony_ci		const __u16 *r_tbl = pconfig->r_data_tbl[i];
21962306a36Sopenharmony_ci		const __u16 *gr_tbl = pconfig->gr_data_tbl[i];
22062306a36Sopenharmony_ci		const __u16 *gb_tbl = pconfig->gb_data_tbl[i];
22162306a36Sopenharmony_ci		const __u16 *b_tbl = pconfig->b_data_tbl[i];
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci		/*
22462306a36Sopenharmony_ci		 * 17 sectors with 2 values in one DWORD = 9
22562306a36Sopenharmony_ci		 * DWORDs (2nd value of last DWORD unused)
22662306a36Sopenharmony_ci		 */
22762306a36Sopenharmony_ci		for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
22862306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,
22962306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(
23062306a36Sopenharmony_ci					r_tbl[j], r_tbl[j + 1]));
23162306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,
23262306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(
23362306a36Sopenharmony_ci					gr_tbl[j], gr_tbl[j + 1]));
23462306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,
23562306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(
23662306a36Sopenharmony_ci					gb_tbl[j], gb_tbl[j + 1]));
23762306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,
23862306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(
23962306a36Sopenharmony_ci					b_tbl[j], b_tbl[j + 1]));
24062306a36Sopenharmony_ci		}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,
24362306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(r_tbl[j], 0));
24462306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,
24562306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gr_tbl[j], 0));
24662306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,
24762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gb_tbl[j], 0));
24862306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,
24962306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(b_tbl[j], 0));
25062306a36Sopenharmony_ci	}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?
25362306a36Sopenharmony_ci			RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1;
25462306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel);
25562306a36Sopenharmony_ci}
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistatic void
25862306a36Sopenharmony_cirkisp1_lsc_matrix_config_v12(struct rkisp1_params *params,
25962306a36Sopenharmony_ci			     const struct rkisp1_cif_isp_lsc_config *pconfig)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	struct rkisp1_device *rkisp1 = params->rkisp1;
26262306a36Sopenharmony_ci	u32 lsc_status, sram_addr, lsc_table_sel;
26362306a36Sopenharmony_ci	unsigned int i, j;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	/* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
26862306a36Sopenharmony_ci	sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?
26962306a36Sopenharmony_ci		    RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
27062306a36Sopenharmony_ci		    RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
27162306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr);
27262306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr);
27362306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr);
27462306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	/* program data tables (table size is 9 * 17 = 153) */
27762306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
27862306a36Sopenharmony_ci		const __u16 *r_tbl = pconfig->r_data_tbl[i];
27962306a36Sopenharmony_ci		const __u16 *gr_tbl = pconfig->gr_data_tbl[i];
28062306a36Sopenharmony_ci		const __u16 *gb_tbl = pconfig->gb_data_tbl[i];
28162306a36Sopenharmony_ci		const __u16 *b_tbl = pconfig->b_data_tbl[i];
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci		/*
28462306a36Sopenharmony_ci		 * 17 sectors with 2 values in one DWORD = 9
28562306a36Sopenharmony_ci		 * DWORDs (2nd value of last DWORD unused)
28662306a36Sopenharmony_ci		 */
28762306a36Sopenharmony_ci		for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
28862306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,
28962306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
29062306a36Sopenharmony_ci					r_tbl[j], r_tbl[j + 1]));
29162306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,
29262306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
29362306a36Sopenharmony_ci					gr_tbl[j], gr_tbl[j + 1]));
29462306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,
29562306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
29662306a36Sopenharmony_ci					gb_tbl[j], gb_tbl[j + 1]));
29762306a36Sopenharmony_ci			rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,
29862306a36Sopenharmony_ci				     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
29962306a36Sopenharmony_ci					b_tbl[j], b_tbl[j + 1]));
30062306a36Sopenharmony_ci		}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA,
30362306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(r_tbl[j], 0));
30462306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA,
30562306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gr_tbl[j], 0));
30662306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA,
30762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gb_tbl[j], 0));
30862306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA,
30962306a36Sopenharmony_ci			     RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(b_tbl[j], 0));
31062306a36Sopenharmony_ci	}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ?
31362306a36Sopenharmony_ci			RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1;
31462306a36Sopenharmony_ci	rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel);
31562306a36Sopenharmony_ci}
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_cistatic void rkisp1_lsc_config(struct rkisp1_params *params,
31862306a36Sopenharmony_ci			      const struct rkisp1_cif_isp_lsc_config *arg)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	struct rkisp1_device *rkisp1 = params->rkisp1;
32162306a36Sopenharmony_ci	u32 lsc_ctrl, data;
32262306a36Sopenharmony_ci	unsigned int i;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	/* To config must be off , store the current status firstly */
32562306a36Sopenharmony_ci	lsc_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_CTRL);
32662306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
32762306a36Sopenharmony_ci				RKISP1_CIF_ISP_LSC_CTRL_ENA);
32862306a36Sopenharmony_ci	params->ops->lsc_matrix_config(params, arg);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {
33162306a36Sopenharmony_ci		/* program x size tables */
33262306a36Sopenharmony_ci		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],
33362306a36Sopenharmony_ci						    arg->x_size_tbl[i * 2 + 1]);
33462306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XSIZE(i), data);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		/* program x grad tables */
33762306a36Sopenharmony_ci		data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2],
33862306a36Sopenharmony_ci						    arg->x_grad_tbl[i * 2 + 1]);
33962306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XGRAD(i), data);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci		/* program y size tables */
34262306a36Sopenharmony_ci		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],
34362306a36Sopenharmony_ci						    arg->y_size_tbl[i * 2 + 1]);
34462306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YSIZE(i), data);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci		/* program y grad tables */
34762306a36Sopenharmony_ci		data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2],
34862306a36Sopenharmony_ci						    arg->y_grad_tbl[i * 2 + 1]);
34962306a36Sopenharmony_ci		rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YGRAD(i), data);
35062306a36Sopenharmony_ci	}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	/* restore the lsc ctrl status */
35362306a36Sopenharmony_ci	if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA)
35462306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
35562306a36Sopenharmony_ci				      RKISP1_CIF_ISP_LSC_CTRL_ENA);
35662306a36Sopenharmony_ci	else
35762306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
35862306a36Sopenharmony_ci					RKISP1_CIF_ISP_LSC_CTRL_ENA);
35962306a36Sopenharmony_ci}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci/* ISP Filtering function */
36262306a36Sopenharmony_cistatic void rkisp1_flt_config(struct rkisp1_params *params,
36362306a36Sopenharmony_ci			      const struct rkisp1_cif_isp_flt_config *arg)
36462306a36Sopenharmony_ci{
36562306a36Sopenharmony_ci	u32 filt_mode;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_BL0,
36862306a36Sopenharmony_ci		     arg->thresh_bl0);
36962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_BL1,
37062306a36Sopenharmony_ci		     arg->thresh_bl1);
37162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_SH0,
37262306a36Sopenharmony_ci		     arg->thresh_sh0);
37362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_THRESH_SH1,
37462306a36Sopenharmony_ci		     arg->thresh_sh1);
37562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_BL0,
37662306a36Sopenharmony_ci		     arg->fac_bl0);
37762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_BL1,
37862306a36Sopenharmony_ci		     arg->fac_bl1);
37962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_MID,
38062306a36Sopenharmony_ci		     arg->fac_mid);
38162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_SH0,
38262306a36Sopenharmony_ci		     arg->fac_sh0);
38362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_FAC_SH1,
38462306a36Sopenharmony_ci		     arg->fac_sh1);
38562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_LUM_WEIGHT,
38662306a36Sopenharmony_ci		     arg->lum_weight);
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE,
38962306a36Sopenharmony_ci		     (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |
39062306a36Sopenharmony_ci		     RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
39162306a36Sopenharmony_ci		     RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
39262306a36Sopenharmony_ci		     RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1));
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	/* avoid to override the old enable value */
39562306a36Sopenharmony_ci	filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);
39662306a36Sopenharmony_ci	filt_mode &= RKISP1_CIF_ISP_FLT_ENA;
39762306a36Sopenharmony_ci	if (arg->mode)
39862306a36Sopenharmony_ci		filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;
39962306a36Sopenharmony_ci	filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
40062306a36Sopenharmony_ci		     RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
40162306a36Sopenharmony_ci		     RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);
40262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE, filt_mode);
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci/* ISP demosaic interface function */
40662306a36Sopenharmony_cistatic int rkisp1_bdm_config(struct rkisp1_params *params,
40762306a36Sopenharmony_ci			     const struct rkisp1_cif_isp_bdm_config *arg)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	u32 bdm_th;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	/* avoid to override the old enable value */
41262306a36Sopenharmony_ci	bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);
41362306a36Sopenharmony_ci	bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
41462306a36Sopenharmony_ci	bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
41562306a36Sopenharmony_ci	/* set demosaic threshold */
41662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC, bdm_th);
41762306a36Sopenharmony_ci	return 0;
41862306a36Sopenharmony_ci}
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci/* ISP GAMMA correction interface function */
42162306a36Sopenharmony_cistatic void rkisp1_sdg_config(struct rkisp1_params *params,
42262306a36Sopenharmony_ci			      const struct rkisp1_cif_isp_sdg_config *arg)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	unsigned int i;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_DX_LO,
42762306a36Sopenharmony_ci		     arg->xa_pnts.gamma_dx0);
42862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_DX_HI,
42962306a36Sopenharmony_ci		     arg->xa_pnts.gamma_dx1);
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {
43262306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
43362306a36Sopenharmony_ci			     RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4,
43462306a36Sopenharmony_ci			     arg->curve_r.gamma_y[i]);
43562306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
43662306a36Sopenharmony_ci			     RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4,
43762306a36Sopenharmony_ci			     arg->curve_g.gamma_y[i]);
43862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
43962306a36Sopenharmony_ci			     RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4,
44062306a36Sopenharmony_ci			     arg->curve_b.gamma_y[i]);
44162306a36Sopenharmony_ci	}
44262306a36Sopenharmony_ci}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci/* ISP GAMMA correction interface function */
44562306a36Sopenharmony_cistatic void rkisp1_goc_config_v10(struct rkisp1_params *params,
44662306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_goc_config *arg)
44762306a36Sopenharmony_ci{
44862306a36Sopenharmony_ci	unsigned int i;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
45162306a36Sopenharmony_ci				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
45262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V10,
45362306a36Sopenharmony_ci		     arg->mode);
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++)
45662306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
45762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V10 + i * 4,
45862306a36Sopenharmony_ci			     arg->gamma_y[i]);
45962306a36Sopenharmony_ci}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cistatic void rkisp1_goc_config_v12(struct rkisp1_params *params,
46262306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_goc_config *arg)
46362306a36Sopenharmony_ci{
46462306a36Sopenharmony_ci	unsigned int i;
46562306a36Sopenharmony_ci	u32 value;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
46862306a36Sopenharmony_ci				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
46962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V12,
47062306a36Sopenharmony_ci		     arg->mode);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 / 2; i++) {
47362306a36Sopenharmony_ci		value = RKISP1_CIF_ISP_GAMMA_VALUE_V12(
47462306a36Sopenharmony_ci			arg->gamma_y[2 * i + 1],
47562306a36Sopenharmony_ci			arg->gamma_y[2 * i]);
47662306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
47762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V12 + i * 4, value);
47862306a36Sopenharmony_ci	}
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci/* ISP Cross Talk */
48262306a36Sopenharmony_cistatic void rkisp1_ctk_config(struct rkisp1_params *params,
48362306a36Sopenharmony_ci			      const struct rkisp1_cif_isp_ctk_config *arg)
48462306a36Sopenharmony_ci{
48562306a36Sopenharmony_ci	unsigned int i, j, k = 0;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	for (i = 0; i < 3; i++)
48862306a36Sopenharmony_ci		for (j = 0; j < 3; j++)
48962306a36Sopenharmony_ci			rkisp1_write(params->rkisp1,
49062306a36Sopenharmony_ci				     RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++,
49162306a36Sopenharmony_ci				     arg->coeff[i][j]);
49262306a36Sopenharmony_ci	for (i = 0; i < 3; i++)
49362306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
49462306a36Sopenharmony_ci			     RKISP1_CIF_ISP_CT_OFFSET_R + i * 4,
49562306a36Sopenharmony_ci			     arg->ct_offset[i]);
49662306a36Sopenharmony_ci}
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_cistatic void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)
49962306a36Sopenharmony_ci{
50062306a36Sopenharmony_ci	if (en)
50162306a36Sopenharmony_ci		return;
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	/* Write back the default values. */
50462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_0, 0x80);
50562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_1, 0);
50662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_2, 0);
50762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_3, 0);
50862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_4, 0x80);
50962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_5, 0);
51062306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_6, 0);
51162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_7, 0);
51262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_COEFF_8, 0x80);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_R, 0);
51562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_G, 0);
51662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CT_OFFSET_B, 0);
51762306a36Sopenharmony_ci}
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci/* ISP White Balance Mode */
52062306a36Sopenharmony_cistatic void rkisp1_awb_meas_config_v10(struct rkisp1_params *params,
52162306a36Sopenharmony_ci				       const struct rkisp1_cif_isp_awb_meas_config *arg)
52262306a36Sopenharmony_ci{
52362306a36Sopenharmony_ci	u32 reg_val = 0;
52462306a36Sopenharmony_ci	/* based on the mode,configure the awb module */
52562306a36Sopenharmony_ci	if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
52662306a36Sopenharmony_ci		/* Reference Cb and Cr */
52762306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_REF_V10,
52862306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
52962306a36Sopenharmony_ci			     arg->awb_ref_cb);
53062306a36Sopenharmony_ci		/* Yc Threshold */
53162306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_THRESH_V10,
53262306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
53362306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
53462306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
53562306a36Sopenharmony_ci			     arg->min_c);
53662306a36Sopenharmony_ci	}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10);
53962306a36Sopenharmony_ci	if (arg->enable_ymax_cmp)
54062306a36Sopenharmony_ci		reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
54162306a36Sopenharmony_ci	else
54262306a36Sopenharmony_ci		reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
54362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10, reg_val);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	/* window offset */
54662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_V_OFFS_V10,
54762306a36Sopenharmony_ci		     arg->awb_wnd.v_offs);
54862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_H_OFFS_V10,
54962306a36Sopenharmony_ci		     arg->awb_wnd.h_offs);
55062306a36Sopenharmony_ci	/* AWB window size */
55162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_V_SIZE_V10,
55262306a36Sopenharmony_ci		     arg->awb_wnd.v_size);
55362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_WND_H_SIZE_V10,
55462306a36Sopenharmony_ci		     arg->awb_wnd.h_size);
55562306a36Sopenharmony_ci	/* Number of frames */
55662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_FRAMES_V10,
55762306a36Sopenharmony_ci		     arg->frames);
55862306a36Sopenharmony_ci}
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_cistatic void rkisp1_awb_meas_config_v12(struct rkisp1_params *params,
56162306a36Sopenharmony_ci				       const struct rkisp1_cif_isp_awb_meas_config *arg)
56262306a36Sopenharmony_ci{
56362306a36Sopenharmony_ci	u32 reg_val = 0;
56462306a36Sopenharmony_ci	/* based on the mode,configure the awb module */
56562306a36Sopenharmony_ci	if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
56662306a36Sopenharmony_ci		/* Reference Cb and Cr */
56762306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_REF_V12,
56862306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
56962306a36Sopenharmony_ci			     arg->awb_ref_cb);
57062306a36Sopenharmony_ci		/* Yc Threshold */
57162306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_THRESH_V12,
57262306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
57362306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
57462306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
57562306a36Sopenharmony_ci			     arg->min_c);
57662306a36Sopenharmony_ci	}
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);
57962306a36Sopenharmony_ci	if (arg->enable_ymax_cmp)
58062306a36Sopenharmony_ci		reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
58162306a36Sopenharmony_ci	else
58262306a36Sopenharmony_ci		reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
58362306a36Sopenharmony_ci	reg_val &= ~RKISP1_CIF_ISP_AWB_SET_FRAMES_MASK_V12;
58462306a36Sopenharmony_ci	reg_val |= RKISP1_CIF_ISP_AWB_SET_FRAMES_V12(arg->frames);
58562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12, reg_val);
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci	/* window offset */
58862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_OFFS_V12,
58962306a36Sopenharmony_ci		     arg->awb_wnd.v_offs << 16 | arg->awb_wnd.h_offs);
59062306a36Sopenharmony_ci	/* AWB window size */
59162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_SIZE_V12,
59262306a36Sopenharmony_ci		     arg->awb_wnd.v_size << 16 | arg->awb_wnd.h_size);
59362306a36Sopenharmony_ci}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_cistatic void
59662306a36Sopenharmony_cirkisp1_awb_meas_enable_v10(struct rkisp1_params *params,
59762306a36Sopenharmony_ci			   const struct rkisp1_cif_isp_awb_meas_config *arg,
59862306a36Sopenharmony_ci			   bool en)
59962306a36Sopenharmony_ci{
60062306a36Sopenharmony_ci	u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10);
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	/* switch off */
60362306a36Sopenharmony_ci	reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	if (en) {
60662306a36Sopenharmony_ci		if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
60762306a36Sopenharmony_ci			reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
60862306a36Sopenharmony_ci		else
60962306a36Sopenharmony_ci			reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10,
61262306a36Sopenharmony_ci			     reg_val);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci		/* Measurements require AWB block be active. */
61562306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
61662306a36Sopenharmony_ci				      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
61762306a36Sopenharmony_ci	} else {
61862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V10,
61962306a36Sopenharmony_ci			     reg_val);
62062306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
62162306a36Sopenharmony_ci					RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
62262306a36Sopenharmony_ci	}
62362306a36Sopenharmony_ci}
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_cistatic void
62662306a36Sopenharmony_cirkisp1_awb_meas_enable_v12(struct rkisp1_params *params,
62762306a36Sopenharmony_ci			   const struct rkisp1_cif_isp_awb_meas_config *arg,
62862306a36Sopenharmony_ci			   bool en)
62962306a36Sopenharmony_ci{
63062306a36Sopenharmony_ci	u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	/* switch off */
63362306a36Sopenharmony_ci	reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	if (en) {
63662306a36Sopenharmony_ci		if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
63762306a36Sopenharmony_ci			reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
63862306a36Sopenharmony_ci		else
63962306a36Sopenharmony_ci			reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12,
64262306a36Sopenharmony_ci			     reg_val);
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci		/* Measurements require AWB block be active. */
64562306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
64662306a36Sopenharmony_ci				      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
64762306a36Sopenharmony_ci	} else {
64862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12,
64962306a36Sopenharmony_ci			     reg_val);
65062306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
65162306a36Sopenharmony_ci					RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
65262306a36Sopenharmony_ci	}
65362306a36Sopenharmony_ci}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_cistatic void
65662306a36Sopenharmony_cirkisp1_awb_gain_config_v10(struct rkisp1_params *params,
65762306a36Sopenharmony_ci			   const struct rkisp1_cif_isp_awb_gain_config *arg)
65862306a36Sopenharmony_ci{
65962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_G_V10,
66062306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
66162306a36Sopenharmony_ci		     arg->gain_green_b);
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_RB_V10,
66462306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
66562306a36Sopenharmony_ci		     arg->gain_blue);
66662306a36Sopenharmony_ci}
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_cistatic void
66962306a36Sopenharmony_cirkisp1_awb_gain_config_v12(struct rkisp1_params *params,
67062306a36Sopenharmony_ci			   const struct rkisp1_cif_isp_awb_gain_config *arg)
67162306a36Sopenharmony_ci{
67262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_G_V12,
67362306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
67462306a36Sopenharmony_ci		     arg->gain_green_b);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB_GAIN_RB_V12,
67762306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
67862306a36Sopenharmony_ci		     arg->gain_blue);
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic void rkisp1_aec_config_v10(struct rkisp1_params *params,
68262306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_aec_config *arg)
68362306a36Sopenharmony_ci{
68462306a36Sopenharmony_ci	unsigned int block_hsize, block_vsize;
68562306a36Sopenharmony_ci	u32 exp_ctrl;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	/* avoid to override the old enable value */
68862306a36Sopenharmony_ci	exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
68962306a36Sopenharmony_ci	exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
69062306a36Sopenharmony_ci	if (arg->autostop)
69162306a36Sopenharmony_ci		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
69262306a36Sopenharmony_ci	if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
69362306a36Sopenharmony_ci		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
69462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL, exp_ctrl);
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_H_OFFSET_V10,
69762306a36Sopenharmony_ci		     arg->meas_window.h_offs);
69862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_V_OFFSET_V10,
69962306a36Sopenharmony_ci		     arg->meas_window.v_offs);
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	block_hsize = arg->meas_window.h_size /
70262306a36Sopenharmony_ci		      RKISP1_CIF_ISP_EXP_COLUMN_NUM_V10 - 1;
70362306a36Sopenharmony_ci	block_vsize = arg->meas_window.v_size /
70462306a36Sopenharmony_ci		      RKISP1_CIF_ISP_EXP_ROW_NUM_V10 - 1;
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_H_SIZE_V10,
70762306a36Sopenharmony_ci		     RKISP1_CIF_ISP_EXP_H_SIZE_SET_V10(block_hsize));
70862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_V_SIZE_V10,
70962306a36Sopenharmony_ci		     RKISP1_CIF_ISP_EXP_V_SIZE_SET_V10(block_vsize));
71062306a36Sopenharmony_ci}
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_cistatic void rkisp1_aec_config_v12(struct rkisp1_params *params,
71362306a36Sopenharmony_ci			       const struct rkisp1_cif_isp_aec_config *arg)
71462306a36Sopenharmony_ci{
71562306a36Sopenharmony_ci	u32 exp_ctrl;
71662306a36Sopenharmony_ci	u32 block_hsize, block_vsize;
71762306a36Sopenharmony_ci	u32 wnd_num_idx = 1;
71862306a36Sopenharmony_ci	static const u32 ae_wnd_num[] = { 5, 9, 15, 15 };
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	/* avoid to override the old enable value */
72162306a36Sopenharmony_ci	exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
72262306a36Sopenharmony_ci	exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
72362306a36Sopenharmony_ci	if (arg->autostop)
72462306a36Sopenharmony_ci		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
72562306a36Sopenharmony_ci	if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
72662306a36Sopenharmony_ci		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
72762306a36Sopenharmony_ci	exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_WNDNUM_SET_V12(wnd_num_idx);
72862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL, exp_ctrl);
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_OFFS_V12,
73162306a36Sopenharmony_ci		     RKISP1_CIF_ISP_EXP_V_OFFSET_SET_V12(arg->meas_window.v_offs) |
73262306a36Sopenharmony_ci		     RKISP1_CIF_ISP_EXP_H_OFFSET_SET_V12(arg->meas_window.h_offs));
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	block_hsize = arg->meas_window.h_size / ae_wnd_num[wnd_num_idx] - 1;
73562306a36Sopenharmony_ci	block_vsize = arg->meas_window.v_size / ae_wnd_num[wnd_num_idx] - 1;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_EXP_SIZE_V12,
73862306a36Sopenharmony_ci		     RKISP1_CIF_ISP_EXP_V_SIZE_SET_V12(block_vsize) |
73962306a36Sopenharmony_ci		     RKISP1_CIF_ISP_EXP_H_SIZE_SET_V12(block_hsize));
74062306a36Sopenharmony_ci}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cistatic void rkisp1_cproc_config(struct rkisp1_params *params,
74362306a36Sopenharmony_ci				const struct rkisp1_cif_isp_cproc_config *arg)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =
74662306a36Sopenharmony_ci		container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);
74762306a36Sopenharmony_ci	struct rkisp1_cif_isp_ie_config *cur_ie_config =
74862306a36Sopenharmony_ci						&cur_other_cfg->ie_config;
74962306a36Sopenharmony_ci	u32 effect = cur_ie_config->effect;
75062306a36Sopenharmony_ci	u32 quantization = params->quantization;
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_CONTRAST,
75362306a36Sopenharmony_ci		     arg->contrast);
75462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_HUE, arg->hue);
75562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_SATURATION, arg->sat);
75662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_C_PROC_BRIGHTNESS,
75762306a36Sopenharmony_ci		     arg->brightness);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||
76062306a36Sopenharmony_ci	    effect != V4L2_COLORFX_NONE) {
76162306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
76262306a36Sopenharmony_ci					RKISP1_CIF_C_PROC_YOUT_FULL |
76362306a36Sopenharmony_ci					RKISP1_CIF_C_PROC_YIN_FULL |
76462306a36Sopenharmony_ci					RKISP1_CIF_C_PROC_COUT_FULL);
76562306a36Sopenharmony_ci	} else {
76662306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,
76762306a36Sopenharmony_ci				      RKISP1_CIF_C_PROC_YOUT_FULL |
76862306a36Sopenharmony_ci				      RKISP1_CIF_C_PROC_YIN_FULL |
76962306a36Sopenharmony_ci				      RKISP1_CIF_C_PROC_COUT_FULL);
77062306a36Sopenharmony_ci	}
77162306a36Sopenharmony_ci}
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_cistatic void rkisp1_hst_config_v10(struct rkisp1_params *params,
77462306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_hst_config *arg)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	unsigned int block_hsize, block_vsize;
77762306a36Sopenharmony_ci	static const u32 hist_weight_regs[] = {
77862306a36Sopenharmony_ci		RKISP1_CIF_ISP_HIST_WEIGHT_00TO30_V10,
77962306a36Sopenharmony_ci		RKISP1_CIF_ISP_HIST_WEIGHT_40TO21_V10,
78062306a36Sopenharmony_ci		RKISP1_CIF_ISP_HIST_WEIGHT_31TO12_V10,
78162306a36Sopenharmony_ci		RKISP1_CIF_ISP_HIST_WEIGHT_22TO03_V10,
78262306a36Sopenharmony_ci		RKISP1_CIF_ISP_HIST_WEIGHT_13TO43_V10,
78362306a36Sopenharmony_ci		RKISP1_CIF_ISP_HIST_WEIGHT_04TO34_V10,
78462306a36Sopenharmony_ci	};
78562306a36Sopenharmony_ci	const u8 *weight;
78662306a36Sopenharmony_ci	unsigned int i;
78762306a36Sopenharmony_ci	u32 hist_prop;
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci	/* avoid to override the old enable value */
79062306a36Sopenharmony_ci	hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10);
79162306a36Sopenharmony_ci	hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10;
79262306a36Sopenharmony_ci	hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET_V10(arg->histogram_predivider);
79362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP_V10, hist_prop);
79462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_H_OFFS_V10,
79562306a36Sopenharmony_ci		     arg->meas_window.h_offs);
79662306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_V_OFFS_V10,
79762306a36Sopenharmony_ci		     arg->meas_window.v_offs);
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	block_hsize = arg->meas_window.h_size /
80062306a36Sopenharmony_ci		      RKISP1_CIF_ISP_HIST_COLUMN_NUM_V10 - 1;
80162306a36Sopenharmony_ci	block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM_V10 - 1;
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_H_SIZE_V10,
80462306a36Sopenharmony_ci		     block_hsize);
80562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_V_SIZE_V10,
80662306a36Sopenharmony_ci		     block_vsize);
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	weight = arg->hist_weight;
80962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)
81062306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, hist_weight_regs[i],
81162306a36Sopenharmony_ci			     RKISP1_CIF_ISP_HIST_WEIGHT_SET_V10(weight[0], weight[1],
81262306a36Sopenharmony_ci								weight[2], weight[3]));
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_WEIGHT_44_V10,
81562306a36Sopenharmony_ci		     weight[0] & 0x1F);
81662306a36Sopenharmony_ci}
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_cistatic void rkisp1_hst_config_v12(struct rkisp1_params *params,
81962306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_hst_config *arg)
82062306a36Sopenharmony_ci{
82162306a36Sopenharmony_ci	unsigned int i, j;
82262306a36Sopenharmony_ci	u32 block_hsize, block_vsize;
82362306a36Sopenharmony_ci	u32 wnd_num_idx, hist_weight_num, hist_ctrl, value;
82462306a36Sopenharmony_ci	u8 weight15x15[RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12];
82562306a36Sopenharmony_ci	static const u32 hist_wnd_num[] = { 5, 9, 15, 15 };
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	/* now we just support 9x9 window */
82862306a36Sopenharmony_ci	wnd_num_idx = 1;
82962306a36Sopenharmony_ci	memset(weight15x15, 0x00, sizeof(weight15x15));
83062306a36Sopenharmony_ci	/* avoid to override the old enable value */
83162306a36Sopenharmony_ci	hist_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12);
83262306a36Sopenharmony_ci	hist_ctrl &= RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
83362306a36Sopenharmony_ci		     RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12;
83462306a36Sopenharmony_ci	hist_ctrl = hist_ctrl |
83562306a36Sopenharmony_ci		    RKISP1_CIF_ISP_HIST_CTRL_INTRSEL_SET_V12(1) |
83662306a36Sopenharmony_ci		    RKISP1_CIF_ISP_HIST_CTRL_DATASEL_SET_V12(0) |
83762306a36Sopenharmony_ci		    RKISP1_CIF_ISP_HIST_CTRL_WATERLINE_SET_V12(0) |
83862306a36Sopenharmony_ci		    RKISP1_CIF_ISP_HIST_CTRL_AUTOSTOP_SET_V12(0) |
83962306a36Sopenharmony_ci		    RKISP1_CIF_ISP_HIST_CTRL_WNDNUM_SET_V12(1) |
84062306a36Sopenharmony_ci		    RKISP1_CIF_ISP_HIST_CTRL_STEPSIZE_SET_V12(arg->histogram_predivider);
84162306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12, hist_ctrl);
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_OFFS_V12,
84462306a36Sopenharmony_ci		     RKISP1_CIF_ISP_HIST_OFFS_SET_V12(arg->meas_window.h_offs,
84562306a36Sopenharmony_ci						      arg->meas_window.v_offs));
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	block_hsize = arg->meas_window.h_size / hist_wnd_num[wnd_num_idx] - 1;
84862306a36Sopenharmony_ci	block_vsize = arg->meas_window.v_size / hist_wnd_num[wnd_num_idx] - 1;
84962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_SIZE_V12,
85062306a36Sopenharmony_ci		     RKISP1_CIF_ISP_HIST_SIZE_SET_V12(block_hsize, block_vsize));
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ci	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
85362306a36Sopenharmony_ci		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
85462306a36Sopenharmony_ci			weight15x15[i * RKISP1_CIF_ISP_HIST_ROW_NUM_V12 + j] =
85562306a36Sopenharmony_ci				arg->hist_weight[i * hist_wnd_num[wnd_num_idx] + j];
85662306a36Sopenharmony_ci		}
85762306a36Sopenharmony_ci	}
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	hist_weight_num = RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12;
86062306a36Sopenharmony_ci	for (i = 0; i < (hist_weight_num / 4); i++) {
86162306a36Sopenharmony_ci		value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(
86262306a36Sopenharmony_ci				 weight15x15[4 * i + 0],
86362306a36Sopenharmony_ci				 weight15x15[4 * i + 1],
86462306a36Sopenharmony_ci				 weight15x15[4 * i + 2],
86562306a36Sopenharmony_ci				 weight15x15[4 * i + 3]);
86662306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
86762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i, value);
86862306a36Sopenharmony_ci	}
86962306a36Sopenharmony_ci	value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(weight15x15[4 * i + 0], 0, 0, 0);
87062306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i,
87162306a36Sopenharmony_ci		     value);
87262306a36Sopenharmony_ci}
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_cistatic void
87562306a36Sopenharmony_cirkisp1_hst_enable_v10(struct rkisp1_params *params,
87662306a36Sopenharmony_ci		      const struct rkisp1_cif_isp_hst_config *arg, bool en)
87762306a36Sopenharmony_ci{
87862306a36Sopenharmony_ci	if (en)	{
87962306a36Sopenharmony_ci		u32 hist_prop = rkisp1_read(params->rkisp1,
88062306a36Sopenharmony_ci					    RKISP1_CIF_ISP_HIST_PROP_V10);
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci		hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10;
88362306a36Sopenharmony_ci		hist_prop |= arg->mode;
88462306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
88562306a36Sopenharmony_ci				      hist_prop);
88662306a36Sopenharmony_ci	} else {
88762306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
88862306a36Sopenharmony_ci					RKISP1_CIF_ISP_HIST_PROP_MODE_MASK_V10);
88962306a36Sopenharmony_ci	}
89062306a36Sopenharmony_ci}
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_cistatic void
89362306a36Sopenharmony_cirkisp1_hst_enable_v12(struct rkisp1_params *params,
89462306a36Sopenharmony_ci		      const struct rkisp1_cif_isp_hst_config *arg, bool en)
89562306a36Sopenharmony_ci{
89662306a36Sopenharmony_ci	if (en) {
89762306a36Sopenharmony_ci		u32 hist_ctrl = rkisp1_read(params->rkisp1,
89862306a36Sopenharmony_ci					    RKISP1_CIF_ISP_HIST_CTRL_V12);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci		hist_ctrl &= ~RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12;
90162306a36Sopenharmony_ci		hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_MODE_SET_V12(arg->mode);
90262306a36Sopenharmony_ci		hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_EN_SET_V12(1);
90362306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,
90462306a36Sopenharmony_ci				      hist_ctrl);
90562306a36Sopenharmony_ci	} else {
90662306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,
90762306a36Sopenharmony_ci					RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
90862306a36Sopenharmony_ci					RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12);
90962306a36Sopenharmony_ci	}
91062306a36Sopenharmony_ci}
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_cistatic void rkisp1_afm_config_v10(struct rkisp1_params *params,
91362306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_afc_config *arg)
91462306a36Sopenharmony_ci{
91562306a36Sopenharmony_ci	size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
91662306a36Sopenharmony_ci				  arg->num_afm_win);
91762306a36Sopenharmony_ci	u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
91862306a36Sopenharmony_ci	unsigned int i;
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	/* Switch off to configure. */
92162306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
92262306a36Sopenharmony_ci				RKISP1_CIF_ISP_AFM_ENA);
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_ci	for (i = 0; i < num_of_win; i++) {
92562306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_LT_A + i * 8,
92662306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
92762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs));
92862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_RB_A + i * 8,
92962306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
93062306a36Sopenharmony_ci							 arg->afm_win[i].h_offs) |
93162306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
93262306a36Sopenharmony_ci							 arg->afm_win[i].v_offs));
93362306a36Sopenharmony_ci	}
93462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_THRES, arg->thres);
93562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_VAR_SHIFT,
93662306a36Sopenharmony_ci		     arg->var_shift);
93762306a36Sopenharmony_ci	/* restore afm status */
93862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL, afm_ctrl);
93962306a36Sopenharmony_ci}
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_cistatic void rkisp1_afm_config_v12(struct rkisp1_params *params,
94262306a36Sopenharmony_ci				  const struct rkisp1_cif_isp_afc_config *arg)
94362306a36Sopenharmony_ci{
94462306a36Sopenharmony_ci	size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
94562306a36Sopenharmony_ci				  arg->num_afm_win);
94662306a36Sopenharmony_ci	u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
94762306a36Sopenharmony_ci	u32 lum_var_shift, afm_var_shift;
94862306a36Sopenharmony_ci	unsigned int i;
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	/* Switch off to configure. */
95162306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
95262306a36Sopenharmony_ci				RKISP1_CIF_ISP_AFM_ENA);
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	for (i = 0; i < num_of_win; i++) {
95562306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_LT_A + i * 8,
95662306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
95762306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs));
95862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_RB_A + i * 8,
95962306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
96062306a36Sopenharmony_ci							 arg->afm_win[i].h_offs) |
96162306a36Sopenharmony_ci			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
96262306a36Sopenharmony_ci							 arg->afm_win[i].v_offs));
96362306a36Sopenharmony_ci	}
96462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_THRES, arg->thres);
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	lum_var_shift = RKISP1_CIF_ISP_AFM_GET_LUM_SHIFT_a_V12(arg->var_shift);
96762306a36Sopenharmony_ci	afm_var_shift = RKISP1_CIF_ISP_AFM_GET_AFM_SHIFT_a_V12(arg->var_shift);
96862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_VAR_SHIFT,
96962306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AFM_SET_SHIFT_a_V12(lum_var_shift, afm_var_shift) |
97062306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AFM_SET_SHIFT_b_V12(lum_var_shift, afm_var_shift) |
97162306a36Sopenharmony_ci		     RKISP1_CIF_ISP_AFM_SET_SHIFT_c_V12(lum_var_shift, afm_var_shift));
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	/* restore afm status */
97462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL, afm_ctrl);
97562306a36Sopenharmony_ci}
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_cistatic void rkisp1_ie_config(struct rkisp1_params *params,
97862306a36Sopenharmony_ci			     const struct rkisp1_cif_isp_ie_config *arg)
97962306a36Sopenharmony_ci{
98062306a36Sopenharmony_ci	u32 eff_ctrl;
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);
98362306a36Sopenharmony_ci	eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
98662306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	switch (arg->effect) {
98962306a36Sopenharmony_ci	case V4L2_COLORFX_SEPIA:
99062306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
99162306a36Sopenharmony_ci		break;
99262306a36Sopenharmony_ci	case V4L2_COLORFX_SET_CBCR:
99362306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_TINT,
99462306a36Sopenharmony_ci			     arg->eff_tint);
99562306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
99662306a36Sopenharmony_ci		break;
99762306a36Sopenharmony_ci		/*
99862306a36Sopenharmony_ci		 * Color selection is similar to water color(AQUA):
99962306a36Sopenharmony_ci		 * grayscale + selected color w threshold
100062306a36Sopenharmony_ci		 */
100162306a36Sopenharmony_ci	case V4L2_COLORFX_AQUA:
100262306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;
100362306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_COLOR_SEL,
100462306a36Sopenharmony_ci			     arg->color_sel);
100562306a36Sopenharmony_ci		break;
100662306a36Sopenharmony_ci	case V4L2_COLORFX_EMBOSS:
100762306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;
100862306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_1,
100962306a36Sopenharmony_ci			     arg->eff_mat_1);
101062306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_2,
101162306a36Sopenharmony_ci			     arg->eff_mat_2);
101262306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_3,
101362306a36Sopenharmony_ci			     arg->eff_mat_3);
101462306a36Sopenharmony_ci		break;
101562306a36Sopenharmony_ci	case V4L2_COLORFX_SKETCH:
101662306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;
101762306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_3,
101862306a36Sopenharmony_ci			     arg->eff_mat_3);
101962306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_4,
102062306a36Sopenharmony_ci			     arg->eff_mat_4);
102162306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_MAT_5,
102262306a36Sopenharmony_ci			     arg->eff_mat_5);
102362306a36Sopenharmony_ci		break;
102462306a36Sopenharmony_ci	case V4L2_COLORFX_BW:
102562306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;
102662306a36Sopenharmony_ci		break;
102762306a36Sopenharmony_ci	case V4L2_COLORFX_NEGATIVE:
102862306a36Sopenharmony_ci		eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;
102962306a36Sopenharmony_ci		break;
103062306a36Sopenharmony_ci	default:
103162306a36Sopenharmony_ci		break;
103262306a36Sopenharmony_ci	}
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL, eff_ctrl);
103562306a36Sopenharmony_ci}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_cistatic void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
103862306a36Sopenharmony_ci{
103962306a36Sopenharmony_ci	if (en) {
104062306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_VI_ICCL,
104162306a36Sopenharmony_ci				      RKISP1_CIF_VI_ICCL_IE_CLK);
104262306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL,
104362306a36Sopenharmony_ci			     RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
104462306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
104562306a36Sopenharmony_ci				      RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);
104662306a36Sopenharmony_ci	} else {
104762306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
104862306a36Sopenharmony_ci					RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
104962306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_VI_ICCL,
105062306a36Sopenharmony_ci					RKISP1_CIF_VI_ICCL_IE_CLK);
105162306a36Sopenharmony_ci	}
105262306a36Sopenharmony_ci}
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_cistatic void rkisp1_csm_config(struct rkisp1_params *params)
105562306a36Sopenharmony_ci{
105662306a36Sopenharmony_ci	struct csm_coeffs {
105762306a36Sopenharmony_ci		u16 limited[9];
105862306a36Sopenharmony_ci		u16 full[9];
105962306a36Sopenharmony_ci	};
106062306a36Sopenharmony_ci	static const struct csm_coeffs rec601_coeffs = {
106162306a36Sopenharmony_ci		.limited = {
106262306a36Sopenharmony_ci			0x0021, 0x0042, 0x000d,
106362306a36Sopenharmony_ci			0x01ed, 0x01db, 0x0038,
106462306a36Sopenharmony_ci			0x0038, 0x01d1, 0x01f7,
106562306a36Sopenharmony_ci		},
106662306a36Sopenharmony_ci		.full = {
106762306a36Sopenharmony_ci			0x0026, 0x004b, 0x000f,
106862306a36Sopenharmony_ci			0x01ea, 0x01d6, 0x0040,
106962306a36Sopenharmony_ci			0x0040, 0x01ca, 0x01f6,
107062306a36Sopenharmony_ci		},
107162306a36Sopenharmony_ci	};
107262306a36Sopenharmony_ci	static const struct csm_coeffs rec709_coeffs = {
107362306a36Sopenharmony_ci		.limited = {
107462306a36Sopenharmony_ci			0x0018, 0x0050, 0x0008,
107562306a36Sopenharmony_ci			0x01f3, 0x01d5, 0x0038,
107662306a36Sopenharmony_ci			0x0038, 0x01cd, 0x01fb,
107762306a36Sopenharmony_ci		},
107862306a36Sopenharmony_ci		.full = {
107962306a36Sopenharmony_ci			0x001b, 0x005c, 0x0009,
108062306a36Sopenharmony_ci			0x01f1, 0x01cf, 0x0040,
108162306a36Sopenharmony_ci			0x0040, 0x01c6, 0x01fa,
108262306a36Sopenharmony_ci		},
108362306a36Sopenharmony_ci	};
108462306a36Sopenharmony_ci	static const struct csm_coeffs rec2020_coeffs = {
108562306a36Sopenharmony_ci		.limited = {
108662306a36Sopenharmony_ci			0x001d, 0x004c, 0x0007,
108762306a36Sopenharmony_ci			0x01f0, 0x01d8, 0x0038,
108862306a36Sopenharmony_ci			0x0038, 0x01cd, 0x01fb,
108962306a36Sopenharmony_ci		},
109062306a36Sopenharmony_ci		.full = {
109162306a36Sopenharmony_ci			0x0022, 0x0057, 0x0008,
109262306a36Sopenharmony_ci			0x01ee, 0x01d2, 0x0040,
109362306a36Sopenharmony_ci			0x0040, 0x01c5, 0x01fb,
109462306a36Sopenharmony_ci		},
109562306a36Sopenharmony_ci	};
109662306a36Sopenharmony_ci	static const struct csm_coeffs smpte240m_coeffs = {
109762306a36Sopenharmony_ci		.limited = {
109862306a36Sopenharmony_ci			0x0018, 0x004f, 0x000a,
109962306a36Sopenharmony_ci			0x01f3, 0x01d5, 0x0038,
110062306a36Sopenharmony_ci			0x0038, 0x01ce, 0x01fa,
110162306a36Sopenharmony_ci		},
110262306a36Sopenharmony_ci		.full = {
110362306a36Sopenharmony_ci			0x001b, 0x005a, 0x000b,
110462306a36Sopenharmony_ci			0x01f1, 0x01cf, 0x0040,
110562306a36Sopenharmony_ci			0x0040, 0x01c7, 0x01f9,
110662306a36Sopenharmony_ci		},
110762306a36Sopenharmony_ci	};
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	const struct csm_coeffs *coeffs;
111062306a36Sopenharmony_ci	const u16 *csm;
111162306a36Sopenharmony_ci	unsigned int i;
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci	switch (params->ycbcr_encoding) {
111462306a36Sopenharmony_ci	case V4L2_YCBCR_ENC_601:
111562306a36Sopenharmony_ci	default:
111662306a36Sopenharmony_ci		coeffs = &rec601_coeffs;
111762306a36Sopenharmony_ci		break;
111862306a36Sopenharmony_ci	case V4L2_YCBCR_ENC_709:
111962306a36Sopenharmony_ci		coeffs = &rec709_coeffs;
112062306a36Sopenharmony_ci		break;
112162306a36Sopenharmony_ci	case V4L2_YCBCR_ENC_BT2020:
112262306a36Sopenharmony_ci		coeffs = &rec2020_coeffs;
112362306a36Sopenharmony_ci		break;
112462306a36Sopenharmony_ci	case V4L2_YCBCR_ENC_SMPTE240M:
112562306a36Sopenharmony_ci		coeffs = &smpte240m_coeffs;
112662306a36Sopenharmony_ci		break;
112762306a36Sopenharmony_ci	}
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci	if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) {
113062306a36Sopenharmony_ci		csm = coeffs->full;
113162306a36Sopenharmony_ci		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
113262306a36Sopenharmony_ci				      RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
113362306a36Sopenharmony_ci				      RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
113462306a36Sopenharmony_ci	} else {
113562306a36Sopenharmony_ci		csm = coeffs->limited;
113662306a36Sopenharmony_ci		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
113762306a36Sopenharmony_ci					RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
113862306a36Sopenharmony_ci					RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
113962306a36Sopenharmony_ci	}
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci	for (i = 0; i < 9; i++)
114262306a36Sopenharmony_ci		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CC_COEFF_0 + i * 4,
114362306a36Sopenharmony_ci			     csm[i]);
114462306a36Sopenharmony_ci}
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci/* ISP De-noise Pre-Filter(DPF) function */
114762306a36Sopenharmony_cistatic void rkisp1_dpf_config(struct rkisp1_params *params,
114862306a36Sopenharmony_ci			      const struct rkisp1_cif_isp_dpf_config *arg)
114962306a36Sopenharmony_ci{
115062306a36Sopenharmony_ci	unsigned int isp_dpf_mode, spatial_coeff, i;
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	switch (arg->gain.mode) {
115362306a36Sopenharmony_ci	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:
115462306a36Sopenharmony_ci		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
115562306a36Sopenharmony_ci			       RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
115662306a36Sopenharmony_ci		break;
115762306a36Sopenharmony_ci	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:
115862306a36Sopenharmony_ci		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
115962306a36Sopenharmony_ci		break;
116062306a36Sopenharmony_ci	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:
116162306a36Sopenharmony_ci		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
116262306a36Sopenharmony_ci			       RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |
116362306a36Sopenharmony_ci			       RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
116462306a36Sopenharmony_ci		break;
116562306a36Sopenharmony_ci	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:
116662306a36Sopenharmony_ci		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
116762306a36Sopenharmony_ci		break;
116862306a36Sopenharmony_ci	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:
116962306a36Sopenharmony_ci		isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |
117062306a36Sopenharmony_ci			       RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
117162306a36Sopenharmony_ci		break;
117262306a36Sopenharmony_ci	case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:
117362306a36Sopenharmony_ci	default:
117462306a36Sopenharmony_ci		isp_dpf_mode = 0;
117562306a36Sopenharmony_ci		break;
117662306a36Sopenharmony_ci	}
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
117962306a36Sopenharmony_ci		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;
118062306a36Sopenharmony_ci	if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)
118162306a36Sopenharmony_ci		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;
118262306a36Sopenharmony_ci	if (!arg->rb_flt.r_enable)
118362306a36Sopenharmony_ci		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;
118462306a36Sopenharmony_ci	if (!arg->rb_flt.b_enable)
118562306a36Sopenharmony_ci		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;
118662306a36Sopenharmony_ci	if (!arg->g_flt.gb_enable)
118762306a36Sopenharmony_ci		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;
118862306a36Sopenharmony_ci	if (!arg->g_flt.gr_enable)
118962306a36Sopenharmony_ci		isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;
119062306a36Sopenharmony_ci
119162306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,
119262306a36Sopenharmony_ci			      isp_dpf_mode);
119362306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_B,
119462306a36Sopenharmony_ci		     arg->gain.nf_b_gain);
119562306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_R,
119662306a36Sopenharmony_ci		     arg->gain.nf_r_gain);
119762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_GB,
119862306a36Sopenharmony_ci		     arg->gain.nf_gb_gain);
119962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_NF_GAIN_GR,
120062306a36Sopenharmony_ci		     arg->gain.nf_gr_gain);
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {
120362306a36Sopenharmony_ci		rkisp1_write(params->rkisp1,
120462306a36Sopenharmony_ci			     RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4,
120562306a36Sopenharmony_ci			     arg->nll.coeff[i]);
120662306a36Sopenharmony_ci	}
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci	spatial_coeff = arg->g_flt.spatial_coeff[0] |
120962306a36Sopenharmony_ci			(arg->g_flt.spatial_coeff[1] << 8) |
121062306a36Sopenharmony_ci			(arg->g_flt.spatial_coeff[2] << 16) |
121162306a36Sopenharmony_ci			(arg->g_flt.spatial_coeff[3] << 24);
121262306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4,
121362306a36Sopenharmony_ci		     spatial_coeff);
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_ci	spatial_coeff = arg->g_flt.spatial_coeff[4] |
121662306a36Sopenharmony_ci			(arg->g_flt.spatial_coeff[5] << 8);
121762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6,
121862306a36Sopenharmony_ci		     spatial_coeff);
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci	spatial_coeff = arg->rb_flt.spatial_coeff[0] |
122162306a36Sopenharmony_ci			(arg->rb_flt.spatial_coeff[1] << 8) |
122262306a36Sopenharmony_ci			(arg->rb_flt.spatial_coeff[2] << 16) |
122362306a36Sopenharmony_ci			(arg->rb_flt.spatial_coeff[3] << 24);
122462306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4,
122562306a36Sopenharmony_ci		     spatial_coeff);
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci	spatial_coeff = arg->rb_flt.spatial_coeff[4] |
122862306a36Sopenharmony_ci			(arg->rb_flt.spatial_coeff[5] << 8);
122962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6,
123062306a36Sopenharmony_ci		     spatial_coeff);
123162306a36Sopenharmony_ci}
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_cistatic void
123462306a36Sopenharmony_cirkisp1_dpf_strength_config(struct rkisp1_params *params,
123562306a36Sopenharmony_ci			   const struct rkisp1_cif_isp_dpf_strength_config *arg)
123662306a36Sopenharmony_ci{
123762306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_B, arg->b);
123862306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_G, arg->g);
123962306a36Sopenharmony_ci	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_R, arg->r);
124062306a36Sopenharmony_ci}
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_cistatic void
124362306a36Sopenharmony_cirkisp1_isp_isr_other_config(struct rkisp1_params *params,
124462306a36Sopenharmony_ci			    const struct rkisp1_params_cfg *new_params)
124562306a36Sopenharmony_ci{
124662306a36Sopenharmony_ci	unsigned int module_en_update, module_cfg_update, module_ens;
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci	module_en_update = new_params->module_en_update;
124962306a36Sopenharmony_ci	module_cfg_update = new_params->module_cfg_update;
125062306a36Sopenharmony_ci	module_ens = new_params->module_ens;
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci	/* update dpc config */
125362306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)
125462306a36Sopenharmony_ci		rkisp1_dpcc_config(params,
125562306a36Sopenharmony_ci				   &new_params->others.dpcc_config);
125662306a36Sopenharmony_ci
125762306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {
125862306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC)
125962306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
126062306a36Sopenharmony_ci					      RKISP1_CIF_ISP_DPCC_MODE,
126162306a36Sopenharmony_ci					      RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);
126262306a36Sopenharmony_ci		else
126362306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
126462306a36Sopenharmony_ci						RKISP1_CIF_ISP_DPCC_MODE,
126562306a36Sopenharmony_ci						RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);
126662306a36Sopenharmony_ci	}
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	/* update bls config */
126962306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)
127062306a36Sopenharmony_ci		rkisp1_bls_config(params,
127162306a36Sopenharmony_ci				  &new_params->others.bls_config);
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {
127462306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_BLS)
127562306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
127662306a36Sopenharmony_ci					      RKISP1_CIF_ISP_BLS_CTRL,
127762306a36Sopenharmony_ci					      RKISP1_CIF_ISP_BLS_ENA);
127862306a36Sopenharmony_ci		else
127962306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
128062306a36Sopenharmony_ci						RKISP1_CIF_ISP_BLS_CTRL,
128162306a36Sopenharmony_ci						RKISP1_CIF_ISP_BLS_ENA);
128262306a36Sopenharmony_ci	}
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	/* update sdg config */
128562306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)
128662306a36Sopenharmony_ci		rkisp1_sdg_config(params,
128762306a36Sopenharmony_ci				  &new_params->others.sdg_config);
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {
129062306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_SDG)
129162306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
129262306a36Sopenharmony_ci					      RKISP1_CIF_ISP_CTRL,
129362306a36Sopenharmony_ci					      RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
129462306a36Sopenharmony_ci		else
129562306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
129662306a36Sopenharmony_ci						RKISP1_CIF_ISP_CTRL,
129762306a36Sopenharmony_ci						RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
129862306a36Sopenharmony_ci	}
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	/* update awb gains */
130162306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
130262306a36Sopenharmony_ci		params->ops->awb_gain_config(params, &new_params->others.awb_gain_config);
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {
130562306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
130662306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
130762306a36Sopenharmony_ci					      RKISP1_CIF_ISP_CTRL,
130862306a36Sopenharmony_ci					      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
130962306a36Sopenharmony_ci		else
131062306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
131162306a36Sopenharmony_ci						RKISP1_CIF_ISP_CTRL,
131262306a36Sopenharmony_ci						RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
131362306a36Sopenharmony_ci	}
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci	/* update bdm config */
131662306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)
131762306a36Sopenharmony_ci		rkisp1_bdm_config(params,
131862306a36Sopenharmony_ci				  &new_params->others.bdm_config);
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {
132162306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_BDM)
132262306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
132362306a36Sopenharmony_ci					      RKISP1_CIF_ISP_DEMOSAIC,
132462306a36Sopenharmony_ci					      RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
132562306a36Sopenharmony_ci		else
132662306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
132762306a36Sopenharmony_ci						RKISP1_CIF_ISP_DEMOSAIC,
132862306a36Sopenharmony_ci						RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
132962306a36Sopenharmony_ci	}
133062306a36Sopenharmony_ci
133162306a36Sopenharmony_ci	/* update filter config */
133262306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)
133362306a36Sopenharmony_ci		rkisp1_flt_config(params,
133462306a36Sopenharmony_ci				  &new_params->others.flt_config);
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {
133762306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_FLT)
133862306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
133962306a36Sopenharmony_ci					      RKISP1_CIF_ISP_FILT_MODE,
134062306a36Sopenharmony_ci					      RKISP1_CIF_ISP_FLT_ENA);
134162306a36Sopenharmony_ci		else
134262306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
134362306a36Sopenharmony_ci						RKISP1_CIF_ISP_FILT_MODE,
134462306a36Sopenharmony_ci						RKISP1_CIF_ISP_FLT_ENA);
134562306a36Sopenharmony_ci	}
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci	/* update ctk config */
134862306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)
134962306a36Sopenharmony_ci		rkisp1_ctk_config(params,
135062306a36Sopenharmony_ci				  &new_params->others.ctk_config);
135162306a36Sopenharmony_ci
135262306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)
135362306a36Sopenharmony_ci		rkisp1_ctk_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci	/* update goc config */
135662306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)
135762306a36Sopenharmony_ci		params->ops->goc_config(params, &new_params->others.goc_config);
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {
136062306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_GOC)
136162306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
136262306a36Sopenharmony_ci					      RKISP1_CIF_ISP_CTRL,
136362306a36Sopenharmony_ci					      RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
136462306a36Sopenharmony_ci		else
136562306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
136662306a36Sopenharmony_ci						RKISP1_CIF_ISP_CTRL,
136762306a36Sopenharmony_ci						RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
136862306a36Sopenharmony_ci	}
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	/* update cproc config */
137162306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)
137262306a36Sopenharmony_ci		rkisp1_cproc_config(params,
137362306a36Sopenharmony_ci				    &new_params->others.cproc_config);
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {
137662306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC)
137762306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
137862306a36Sopenharmony_ci					      RKISP1_CIF_C_PROC_CTRL,
137962306a36Sopenharmony_ci					      RKISP1_CIF_C_PROC_CTR_ENABLE);
138062306a36Sopenharmony_ci		else
138162306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
138262306a36Sopenharmony_ci						RKISP1_CIF_C_PROC_CTRL,
138362306a36Sopenharmony_ci						RKISP1_CIF_C_PROC_CTR_ENABLE);
138462306a36Sopenharmony_ci	}
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	/* update ie config */
138762306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)
138862306a36Sopenharmony_ci		rkisp1_ie_config(params, &new_params->others.ie_config);
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)
139162306a36Sopenharmony_ci		rkisp1_ie_enable(params, !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	/* update dpf config */
139462306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)
139562306a36Sopenharmony_ci		rkisp1_dpf_config(params, &new_params->others.dpf_config);
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {
139862306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_DPF)
139962306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
140062306a36Sopenharmony_ci					      RKISP1_CIF_ISP_DPF_MODE,
140162306a36Sopenharmony_ci					      RKISP1_CIF_ISP_DPF_MODE_EN);
140262306a36Sopenharmony_ci		else
140362306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
140462306a36Sopenharmony_ci						RKISP1_CIF_ISP_DPF_MODE,
140562306a36Sopenharmony_ci						RKISP1_CIF_ISP_DPF_MODE_EN);
140662306a36Sopenharmony_ci	}
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci	if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||
140962306a36Sopenharmony_ci	    (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {
141062306a36Sopenharmony_ci		/* update dpf strength config */
141162306a36Sopenharmony_ci		rkisp1_dpf_strength_config(params,
141262306a36Sopenharmony_ci					   &new_params->others.dpf_strength_config);
141362306a36Sopenharmony_ci	}
141462306a36Sopenharmony_ci}
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_cistatic void
141762306a36Sopenharmony_cirkisp1_isp_isr_lsc_config(struct rkisp1_params *params,
141862306a36Sopenharmony_ci			  const struct rkisp1_params_cfg *new_params)
141962306a36Sopenharmony_ci{
142062306a36Sopenharmony_ci	unsigned int module_en_update, module_cfg_update, module_ens;
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci	module_en_update = new_params->module_en_update;
142362306a36Sopenharmony_ci	module_cfg_update = new_params->module_cfg_update;
142462306a36Sopenharmony_ci	module_ens = new_params->module_ens;
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci	/* update lsc config */
142762306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)
142862306a36Sopenharmony_ci		rkisp1_lsc_config(params,
142962306a36Sopenharmony_ci				  &new_params->others.lsc_config);
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {
143262306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_LSC)
143362306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
143462306a36Sopenharmony_ci					      RKISP1_CIF_ISP_LSC_CTRL,
143562306a36Sopenharmony_ci					      RKISP1_CIF_ISP_LSC_CTRL_ENA);
143662306a36Sopenharmony_ci		else
143762306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
143862306a36Sopenharmony_ci						RKISP1_CIF_ISP_LSC_CTRL,
143962306a36Sopenharmony_ci						RKISP1_CIF_ISP_LSC_CTRL_ENA);
144062306a36Sopenharmony_ci	}
144162306a36Sopenharmony_ci}
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_cistatic void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,
144462306a36Sopenharmony_ci				       struct  rkisp1_params_cfg *new_params)
144562306a36Sopenharmony_ci{
144662306a36Sopenharmony_ci	unsigned int module_en_update, module_cfg_update, module_ens;
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	module_en_update = new_params->module_en_update;
144962306a36Sopenharmony_ci	module_cfg_update = new_params->module_cfg_update;
145062306a36Sopenharmony_ci	module_ens = new_params->module_ens;
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci	/* update awb config */
145362306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)
145462306a36Sopenharmony_ci		params->ops->awb_meas_config(params, &new_params->meas.awb_meas_config);
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)
145762306a36Sopenharmony_ci		params->ops->awb_meas_enable(params,
145862306a36Sopenharmony_ci					     &new_params->meas.awb_meas_config,
145962306a36Sopenharmony_ci					     !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci	/* update afc config */
146262306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)
146362306a36Sopenharmony_ci		params->ops->afm_config(params,
146462306a36Sopenharmony_ci					&new_params->meas.afc_config);
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {
146762306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_AFC)
146862306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
146962306a36Sopenharmony_ci					      RKISP1_CIF_ISP_AFM_CTRL,
147062306a36Sopenharmony_ci					      RKISP1_CIF_ISP_AFM_ENA);
147162306a36Sopenharmony_ci		else
147262306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
147362306a36Sopenharmony_ci						RKISP1_CIF_ISP_AFM_CTRL,
147462306a36Sopenharmony_ci						RKISP1_CIF_ISP_AFM_ENA);
147562306a36Sopenharmony_ci	}
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	/* update hst config */
147862306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)
147962306a36Sopenharmony_ci		params->ops->hst_config(params,
148062306a36Sopenharmony_ci					&new_params->meas.hst_config);
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)
148362306a36Sopenharmony_ci		params->ops->hst_enable(params,
148462306a36Sopenharmony_ci					&new_params->meas.hst_config,
148562306a36Sopenharmony_ci					!!(module_ens & RKISP1_CIF_ISP_MODULE_HST));
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci	/* update aec config */
148862306a36Sopenharmony_ci	if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)
148962306a36Sopenharmony_ci		params->ops->aec_config(params,
149062306a36Sopenharmony_ci					&new_params->meas.aec_config);
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {
149362306a36Sopenharmony_ci		if (module_ens & RKISP1_CIF_ISP_MODULE_AEC)
149462306a36Sopenharmony_ci			rkisp1_param_set_bits(params,
149562306a36Sopenharmony_ci					      RKISP1_CIF_ISP_EXP_CTRL,
149662306a36Sopenharmony_ci					      RKISP1_CIF_ISP_EXP_ENA);
149762306a36Sopenharmony_ci		else
149862306a36Sopenharmony_ci			rkisp1_param_clear_bits(params,
149962306a36Sopenharmony_ci						RKISP1_CIF_ISP_EXP_CTRL,
150062306a36Sopenharmony_ci						RKISP1_CIF_ISP_EXP_ENA);
150162306a36Sopenharmony_ci	}
150262306a36Sopenharmony_ci}
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_cistatic bool rkisp1_params_get_buffer(struct rkisp1_params *params,
150562306a36Sopenharmony_ci				     struct rkisp1_buffer **buf,
150662306a36Sopenharmony_ci				     struct rkisp1_params_cfg **cfg)
150762306a36Sopenharmony_ci{
150862306a36Sopenharmony_ci	if (list_empty(&params->params))
150962306a36Sopenharmony_ci		return false;
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	*buf = list_first_entry(&params->params, struct rkisp1_buffer, queue);
151262306a36Sopenharmony_ci	*cfg = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0);
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_ci	return true;
151562306a36Sopenharmony_ci}
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_cistatic void rkisp1_params_complete_buffer(struct rkisp1_params *params,
151862306a36Sopenharmony_ci					  struct rkisp1_buffer *buf,
151962306a36Sopenharmony_ci					  unsigned int frame_sequence)
152062306a36Sopenharmony_ci{
152162306a36Sopenharmony_ci	list_del(&buf->queue);
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_ci	buf->vb.sequence = frame_sequence;
152462306a36Sopenharmony_ci	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
152562306a36Sopenharmony_ci}
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_civoid rkisp1_params_isr(struct rkisp1_device *rkisp1)
152862306a36Sopenharmony_ci{
152962306a36Sopenharmony_ci	struct rkisp1_params *params = &rkisp1->params;
153062306a36Sopenharmony_ci	struct rkisp1_params_cfg *new_params;
153162306a36Sopenharmony_ci	struct rkisp1_buffer *cur_buf;
153262306a36Sopenharmony_ci
153362306a36Sopenharmony_ci	spin_lock(&params->config_lock);
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_ci	if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params))
153662306a36Sopenharmony_ci		goto unlock;
153762306a36Sopenharmony_ci
153862306a36Sopenharmony_ci	rkisp1_isp_isr_other_config(params, new_params);
153962306a36Sopenharmony_ci	rkisp1_isp_isr_lsc_config(params, new_params);
154062306a36Sopenharmony_ci	rkisp1_isp_isr_meas_config(params, new_params);
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_ci	/* update shadow register immediately */
154362306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
154462306a36Sopenharmony_ci			      RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	/*
154762306a36Sopenharmony_ci	 * This isr is called when the ISR finishes processing a frame
154862306a36Sopenharmony_ci	 * (RKISP1_CIF_ISP_FRAME). Configurations performed here will be
154962306a36Sopenharmony_ci	 * applied on the next frame. Since frame_sequence is updated on the
155062306a36Sopenharmony_ci	 * vertical sync signal, we should use frame_sequence + 1 here to
155162306a36Sopenharmony_ci	 * indicate to userspace on which frame these parameters are being
155262306a36Sopenharmony_ci	 * applied.
155362306a36Sopenharmony_ci	 */
155462306a36Sopenharmony_ci	rkisp1_params_complete_buffer(params, cur_buf,
155562306a36Sopenharmony_ci				      rkisp1->isp.frame_sequence + 1);
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_ciunlock:
155862306a36Sopenharmony_ci	spin_unlock(&params->config_lock);
155962306a36Sopenharmony_ci}
156062306a36Sopenharmony_ci
156162306a36Sopenharmony_cistatic const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {
156262306a36Sopenharmony_ci	{
156362306a36Sopenharmony_ci		0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT
156462306a36Sopenharmony_ci	},
156562306a36Sopenharmony_ci	RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128
156662306a36Sopenharmony_ci};
156762306a36Sopenharmony_ci
156862306a36Sopenharmony_cistatic const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {
156962306a36Sopenharmony_ci	RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
157062306a36Sopenharmony_ci	RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,
157162306a36Sopenharmony_ci	{
157262306a36Sopenharmony_ci		RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
157362306a36Sopenharmony_ci		RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
157462306a36Sopenharmony_ci	}
157562306a36Sopenharmony_ci};
157662306a36Sopenharmony_ci
157762306a36Sopenharmony_cistatic const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {
157862306a36Sopenharmony_ci	RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
157962306a36Sopenharmony_ci	3,
158062306a36Sopenharmony_ci	{
158162306a36Sopenharmony_ci		RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
158262306a36Sopenharmony_ci		RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
158362306a36Sopenharmony_ci	},
158462306a36Sopenharmony_ci	{
158562306a36Sopenharmony_ci		0, /* To be filled in with 0x01 at runtime. */
158662306a36Sopenharmony_ci	}
158762306a36Sopenharmony_ci};
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_cistatic const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {
159062306a36Sopenharmony_ci	1,
159162306a36Sopenharmony_ci	{
159262306a36Sopenharmony_ci		{
159362306a36Sopenharmony_ci			300, 225, 200, 150
159462306a36Sopenharmony_ci		}
159562306a36Sopenharmony_ci	},
159662306a36Sopenharmony_ci	4,
159762306a36Sopenharmony_ci	14
159862306a36Sopenharmony_ci};
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_civoid rkisp1_params_pre_configure(struct rkisp1_params *params,
160162306a36Sopenharmony_ci				 enum rkisp1_fmt_raw_pat_type bayer_pat,
160262306a36Sopenharmony_ci				 enum v4l2_quantization quantization,
160362306a36Sopenharmony_ci				 enum v4l2_ycbcr_encoding ycbcr_encoding)
160462306a36Sopenharmony_ci{
160562306a36Sopenharmony_ci	struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;
160662306a36Sopenharmony_ci	struct rkisp1_params_cfg *new_params;
160762306a36Sopenharmony_ci	struct rkisp1_buffer *cur_buf;
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci	params->quantization = quantization;
161062306a36Sopenharmony_ci	params->ycbcr_encoding = ycbcr_encoding;
161162306a36Sopenharmony_ci	params->raw_type = bayer_pat;
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	params->ops->awb_meas_config(params, &rkisp1_awb_params_default_config);
161462306a36Sopenharmony_ci	params->ops->awb_meas_enable(params, &rkisp1_awb_params_default_config,
161562306a36Sopenharmony_ci				     true);
161662306a36Sopenharmony_ci
161762306a36Sopenharmony_ci	params->ops->aec_config(params, &rkisp1_aec_params_default_config);
161862306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
161962306a36Sopenharmony_ci			      RKISP1_CIF_ISP_EXP_ENA);
162062306a36Sopenharmony_ci
162162306a36Sopenharmony_ci	params->ops->afm_config(params, &rkisp1_afc_params_default_config);
162262306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
162362306a36Sopenharmony_ci			      RKISP1_CIF_ISP_AFM_ENA);
162462306a36Sopenharmony_ci
162562306a36Sopenharmony_ci	memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
162662306a36Sopenharmony_ci	params->ops->hst_config(params, &hst);
162762306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
162862306a36Sopenharmony_ci			      rkisp1_hst_params_default_config.mode);
162962306a36Sopenharmony_ci
163062306a36Sopenharmony_ci	rkisp1_csm_config(params);
163162306a36Sopenharmony_ci
163262306a36Sopenharmony_ci	spin_lock_irq(&params->config_lock);
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci	/* apply the first buffer if there is one already */
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci	if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params))
163762306a36Sopenharmony_ci		goto unlock;
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci	rkisp1_isp_isr_other_config(params, new_params);
164062306a36Sopenharmony_ci	rkisp1_isp_isr_meas_config(params, new_params);
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_ci	/* update shadow register immediately */
164362306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
164462306a36Sopenharmony_ci			      RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
164562306a36Sopenharmony_ci
164662306a36Sopenharmony_ciunlock:
164762306a36Sopenharmony_ci	spin_unlock_irq(&params->config_lock);
164862306a36Sopenharmony_ci}
164962306a36Sopenharmony_ci
165062306a36Sopenharmony_civoid rkisp1_params_post_configure(struct rkisp1_params *params)
165162306a36Sopenharmony_ci{
165262306a36Sopenharmony_ci	struct rkisp1_params_cfg *new_params;
165362306a36Sopenharmony_ci	struct rkisp1_buffer *cur_buf;
165462306a36Sopenharmony_ci
165562306a36Sopenharmony_ci	spin_lock_irq(&params->config_lock);
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	/*
165862306a36Sopenharmony_ci	 * Apply LSC parameters from the first buffer (if any is already
165962306a36Sopenharmony_ci	 * available. This must be done after the ISP gets started in the
166062306a36Sopenharmony_ci	 * ISP8000Nano v18.02 (found in the i.MX8MP) as access to the LSC RAM
166162306a36Sopenharmony_ci	 * is gated by the ISP_CTRL.ISP_ENABLE bit. As this initialization
166262306a36Sopenharmony_ci	 * ordering doesn't affect other ISP versions negatively, do so
166362306a36Sopenharmony_ci	 * unconditionally.
166462306a36Sopenharmony_ci	 */
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci	if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params))
166762306a36Sopenharmony_ci		goto unlock;
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	rkisp1_isp_isr_lsc_config(params, new_params);
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci	/* update shadow register immediately */
167262306a36Sopenharmony_ci	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
167362306a36Sopenharmony_ci			      RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci	rkisp1_params_complete_buffer(params, cur_buf, 0);
167662306a36Sopenharmony_ci
167762306a36Sopenharmony_ciunlock:
167862306a36Sopenharmony_ci	spin_unlock_irq(&params->config_lock);
167962306a36Sopenharmony_ci}
168062306a36Sopenharmony_ci
168162306a36Sopenharmony_ci/*
168262306a36Sopenharmony_ci * Not called when the camera is active, therefore there is no need to acquire
168362306a36Sopenharmony_ci * a lock.
168462306a36Sopenharmony_ci */
168562306a36Sopenharmony_civoid rkisp1_params_disable(struct rkisp1_params *params)
168662306a36Sopenharmony_ci{
168762306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,
168862306a36Sopenharmony_ci				RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE);
168962306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
169062306a36Sopenharmony_ci				RKISP1_CIF_ISP_LSC_CTRL_ENA);
169162306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
169262306a36Sopenharmony_ci				RKISP1_CIF_ISP_BLS_ENA);
169362306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
169462306a36Sopenharmony_ci				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
169562306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
169662306a36Sopenharmony_ci				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
169762306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,
169862306a36Sopenharmony_ci				RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
169962306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,
170062306a36Sopenharmony_ci				RKISP1_CIF_ISP_FLT_ENA);
170162306a36Sopenharmony_ci	params->ops->awb_meas_enable(params, NULL, false);
170262306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
170362306a36Sopenharmony_ci				RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
170462306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
170562306a36Sopenharmony_ci				RKISP1_CIF_ISP_EXP_ENA);
170662306a36Sopenharmony_ci	rkisp1_ctk_enable(params, false);
170762306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
170862306a36Sopenharmony_ci				RKISP1_CIF_C_PROC_CTR_ENABLE);
170962306a36Sopenharmony_ci	params->ops->hst_enable(params, NULL, false);
171062306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
171162306a36Sopenharmony_ci				RKISP1_CIF_ISP_AFM_ENA);
171262306a36Sopenharmony_ci	rkisp1_ie_enable(params, false);
171362306a36Sopenharmony_ci	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
171462306a36Sopenharmony_ci				RKISP1_CIF_ISP_DPF_MODE_EN);
171562306a36Sopenharmony_ci}
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_cistatic const struct rkisp1_params_ops rkisp1_v10_params_ops = {
171862306a36Sopenharmony_ci	.lsc_matrix_config = rkisp1_lsc_matrix_config_v10,
171962306a36Sopenharmony_ci	.goc_config = rkisp1_goc_config_v10,
172062306a36Sopenharmony_ci	.awb_meas_config = rkisp1_awb_meas_config_v10,
172162306a36Sopenharmony_ci	.awb_meas_enable = rkisp1_awb_meas_enable_v10,
172262306a36Sopenharmony_ci	.awb_gain_config = rkisp1_awb_gain_config_v10,
172362306a36Sopenharmony_ci	.aec_config = rkisp1_aec_config_v10,
172462306a36Sopenharmony_ci	.hst_config = rkisp1_hst_config_v10,
172562306a36Sopenharmony_ci	.hst_enable = rkisp1_hst_enable_v10,
172662306a36Sopenharmony_ci	.afm_config = rkisp1_afm_config_v10,
172762306a36Sopenharmony_ci};
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_cistatic struct rkisp1_params_ops rkisp1_v12_params_ops = {
173062306a36Sopenharmony_ci	.lsc_matrix_config = rkisp1_lsc_matrix_config_v12,
173162306a36Sopenharmony_ci	.goc_config = rkisp1_goc_config_v12,
173262306a36Sopenharmony_ci	.awb_meas_config = rkisp1_awb_meas_config_v12,
173362306a36Sopenharmony_ci	.awb_meas_enable = rkisp1_awb_meas_enable_v12,
173462306a36Sopenharmony_ci	.awb_gain_config = rkisp1_awb_gain_config_v12,
173562306a36Sopenharmony_ci	.aec_config = rkisp1_aec_config_v12,
173662306a36Sopenharmony_ci	.hst_config = rkisp1_hst_config_v12,
173762306a36Sopenharmony_ci	.hst_enable = rkisp1_hst_enable_v12,
173862306a36Sopenharmony_ci	.afm_config = rkisp1_afm_config_v12,
173962306a36Sopenharmony_ci};
174062306a36Sopenharmony_ci
174162306a36Sopenharmony_cistatic int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
174262306a36Sopenharmony_ci					   struct v4l2_fmtdesc *f)
174362306a36Sopenharmony_ci{
174462306a36Sopenharmony_ci	struct video_device *video = video_devdata(file);
174562306a36Sopenharmony_ci	struct rkisp1_params *params = video_get_drvdata(video);
174662306a36Sopenharmony_ci
174762306a36Sopenharmony_ci	if (f->index > 0 || f->type != video->queue->type)
174862306a36Sopenharmony_ci		return -EINVAL;
174962306a36Sopenharmony_ci
175062306a36Sopenharmony_ci	f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_ci	return 0;
175362306a36Sopenharmony_ci}
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_cistatic int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
175662306a36Sopenharmony_ci					struct v4l2_format *f)
175762306a36Sopenharmony_ci{
175862306a36Sopenharmony_ci	struct video_device *video = video_devdata(file);
175962306a36Sopenharmony_ci	struct rkisp1_params *params = video_get_drvdata(video);
176062306a36Sopenharmony_ci	struct v4l2_meta_format *meta = &f->fmt.meta;
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci	if (f->type != video->queue->type)
176362306a36Sopenharmony_ci		return -EINVAL;
176462306a36Sopenharmony_ci
176562306a36Sopenharmony_ci	memset(meta, 0, sizeof(*meta));
176662306a36Sopenharmony_ci	meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
176762306a36Sopenharmony_ci	meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
176862306a36Sopenharmony_ci
176962306a36Sopenharmony_ci	return 0;
177062306a36Sopenharmony_ci}
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_cistatic int rkisp1_params_querycap(struct file *file,
177362306a36Sopenharmony_ci				  void *priv, struct v4l2_capability *cap)
177462306a36Sopenharmony_ci{
177562306a36Sopenharmony_ci	struct video_device *vdev = video_devdata(file);
177662306a36Sopenharmony_ci
177762306a36Sopenharmony_ci	strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
177862306a36Sopenharmony_ci	strscpy(cap->card, vdev->name, sizeof(cap->card));
177962306a36Sopenharmony_ci	strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
178062306a36Sopenharmony_ci
178162306a36Sopenharmony_ci	return 0;
178262306a36Sopenharmony_ci}
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_ci/* ISP params video device IOCTLs */
178562306a36Sopenharmony_cistatic const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
178662306a36Sopenharmony_ci	.vidioc_reqbufs = vb2_ioctl_reqbufs,
178762306a36Sopenharmony_ci	.vidioc_querybuf = vb2_ioctl_querybuf,
178862306a36Sopenharmony_ci	.vidioc_create_bufs = vb2_ioctl_create_bufs,
178962306a36Sopenharmony_ci	.vidioc_qbuf = vb2_ioctl_qbuf,
179062306a36Sopenharmony_ci	.vidioc_dqbuf = vb2_ioctl_dqbuf,
179162306a36Sopenharmony_ci	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
179262306a36Sopenharmony_ci	.vidioc_expbuf = vb2_ioctl_expbuf,
179362306a36Sopenharmony_ci	.vidioc_streamon = vb2_ioctl_streamon,
179462306a36Sopenharmony_ci	.vidioc_streamoff = vb2_ioctl_streamoff,
179562306a36Sopenharmony_ci	.vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
179662306a36Sopenharmony_ci	.vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
179762306a36Sopenharmony_ci	.vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
179862306a36Sopenharmony_ci	.vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
179962306a36Sopenharmony_ci	.vidioc_querycap = rkisp1_params_querycap,
180062306a36Sopenharmony_ci	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
180162306a36Sopenharmony_ci	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
180262306a36Sopenharmony_ci};
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_cistatic int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
180562306a36Sopenharmony_ci					 unsigned int *num_buffers,
180662306a36Sopenharmony_ci					 unsigned int *num_planes,
180762306a36Sopenharmony_ci					 unsigned int sizes[],
180862306a36Sopenharmony_ci					 struct device *alloc_devs[])
180962306a36Sopenharmony_ci{
181062306a36Sopenharmony_ci	*num_buffers = clamp_t(u32, *num_buffers,
181162306a36Sopenharmony_ci			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
181262306a36Sopenharmony_ci			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
181362306a36Sopenharmony_ci
181462306a36Sopenharmony_ci	*num_planes = 1;
181562306a36Sopenharmony_ci
181662306a36Sopenharmony_ci	sizes[0] = sizeof(struct rkisp1_params_cfg);
181762306a36Sopenharmony_ci
181862306a36Sopenharmony_ci	return 0;
181962306a36Sopenharmony_ci}
182062306a36Sopenharmony_ci
182162306a36Sopenharmony_cistatic void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
182262306a36Sopenharmony_ci{
182362306a36Sopenharmony_ci	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
182462306a36Sopenharmony_ci	struct rkisp1_buffer *params_buf =
182562306a36Sopenharmony_ci		container_of(vbuf, struct rkisp1_buffer, vb);
182662306a36Sopenharmony_ci	struct vb2_queue *vq = vb->vb2_queue;
182762306a36Sopenharmony_ci	struct rkisp1_params *params = vq->drv_priv;
182862306a36Sopenharmony_ci
182962306a36Sopenharmony_ci	spin_lock_irq(&params->config_lock);
183062306a36Sopenharmony_ci	list_add_tail(&params_buf->queue, &params->params);
183162306a36Sopenharmony_ci	spin_unlock_irq(&params->config_lock);
183262306a36Sopenharmony_ci}
183362306a36Sopenharmony_ci
183462306a36Sopenharmony_cistatic int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
183562306a36Sopenharmony_ci{
183662306a36Sopenharmony_ci	if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
183762306a36Sopenharmony_ci		return -EINVAL;
183862306a36Sopenharmony_ci
183962306a36Sopenharmony_ci	vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
184062306a36Sopenharmony_ci
184162306a36Sopenharmony_ci	return 0;
184262306a36Sopenharmony_ci}
184362306a36Sopenharmony_ci
184462306a36Sopenharmony_cistatic void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
184562306a36Sopenharmony_ci{
184662306a36Sopenharmony_ci	struct rkisp1_params *params = vq->drv_priv;
184762306a36Sopenharmony_ci	struct rkisp1_buffer *buf;
184862306a36Sopenharmony_ci	LIST_HEAD(tmp_list);
184962306a36Sopenharmony_ci
185062306a36Sopenharmony_ci	/*
185162306a36Sopenharmony_ci	 * we first move the buffers into a local list 'tmp_list'
185262306a36Sopenharmony_ci	 * and then we can iterate it and call vb2_buffer_done
185362306a36Sopenharmony_ci	 * without holding the lock
185462306a36Sopenharmony_ci	 */
185562306a36Sopenharmony_ci	spin_lock_irq(&params->config_lock);
185662306a36Sopenharmony_ci	list_splice_init(&params->params, &tmp_list);
185762306a36Sopenharmony_ci	spin_unlock_irq(&params->config_lock);
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	list_for_each_entry(buf, &tmp_list, queue)
186062306a36Sopenharmony_ci		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
186162306a36Sopenharmony_ci}
186262306a36Sopenharmony_ci
186362306a36Sopenharmony_cistatic const struct vb2_ops rkisp1_params_vb2_ops = {
186462306a36Sopenharmony_ci	.queue_setup = rkisp1_params_vb2_queue_setup,
186562306a36Sopenharmony_ci	.wait_prepare = vb2_ops_wait_prepare,
186662306a36Sopenharmony_ci	.wait_finish = vb2_ops_wait_finish,
186762306a36Sopenharmony_ci	.buf_queue = rkisp1_params_vb2_buf_queue,
186862306a36Sopenharmony_ci	.buf_prepare = rkisp1_params_vb2_buf_prepare,
186962306a36Sopenharmony_ci	.stop_streaming = rkisp1_params_vb2_stop_streaming,
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci};
187262306a36Sopenharmony_ci
187362306a36Sopenharmony_cistatic const struct v4l2_file_operations rkisp1_params_fops = {
187462306a36Sopenharmony_ci	.mmap = vb2_fop_mmap,
187562306a36Sopenharmony_ci	.unlocked_ioctl = video_ioctl2,
187662306a36Sopenharmony_ci	.poll = vb2_fop_poll,
187762306a36Sopenharmony_ci	.open = v4l2_fh_open,
187862306a36Sopenharmony_ci	.release = vb2_fop_release
187962306a36Sopenharmony_ci};
188062306a36Sopenharmony_ci
188162306a36Sopenharmony_cistatic int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
188262306a36Sopenharmony_ci					struct rkisp1_params *params)
188362306a36Sopenharmony_ci{
188462306a36Sopenharmony_ci	struct rkisp1_vdev_node *node;
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	node = container_of(q, struct rkisp1_vdev_node, buf_queue);
188762306a36Sopenharmony_ci
188862306a36Sopenharmony_ci	q->type = V4L2_BUF_TYPE_META_OUTPUT;
188962306a36Sopenharmony_ci	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
189062306a36Sopenharmony_ci	q->drv_priv = params;
189162306a36Sopenharmony_ci	q->ops = &rkisp1_params_vb2_ops;
189262306a36Sopenharmony_ci	q->mem_ops = &vb2_vmalloc_memops;
189362306a36Sopenharmony_ci	q->buf_struct_size = sizeof(struct rkisp1_buffer);
189462306a36Sopenharmony_ci	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
189562306a36Sopenharmony_ci	q->lock = &node->vlock;
189662306a36Sopenharmony_ci
189762306a36Sopenharmony_ci	return vb2_queue_init(q);
189862306a36Sopenharmony_ci}
189962306a36Sopenharmony_ci
190062306a36Sopenharmony_cistatic void rkisp1_init_params(struct rkisp1_params *params)
190162306a36Sopenharmony_ci{
190262306a36Sopenharmony_ci	params->vdev_fmt.fmt.meta.dataformat =
190362306a36Sopenharmony_ci		V4L2_META_FMT_RK_ISP1_PARAMS;
190462306a36Sopenharmony_ci	params->vdev_fmt.fmt.meta.buffersize =
190562306a36Sopenharmony_ci		sizeof(struct rkisp1_params_cfg);
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci	if (params->rkisp1->info->isp_ver == RKISP1_V12)
190862306a36Sopenharmony_ci		params->ops = &rkisp1_v12_params_ops;
190962306a36Sopenharmony_ci	else
191062306a36Sopenharmony_ci		params->ops = &rkisp1_v10_params_ops;
191162306a36Sopenharmony_ci}
191262306a36Sopenharmony_ci
191362306a36Sopenharmony_ciint rkisp1_params_register(struct rkisp1_device *rkisp1)
191462306a36Sopenharmony_ci{
191562306a36Sopenharmony_ci	struct rkisp1_params *params = &rkisp1->params;
191662306a36Sopenharmony_ci	struct rkisp1_vdev_node *node = &params->vnode;
191762306a36Sopenharmony_ci	struct video_device *vdev = &node->vdev;
191862306a36Sopenharmony_ci	int ret;
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_ci	params->rkisp1 = rkisp1;
192162306a36Sopenharmony_ci	mutex_init(&node->vlock);
192262306a36Sopenharmony_ci	INIT_LIST_HEAD(&params->params);
192362306a36Sopenharmony_ci	spin_lock_init(&params->config_lock);
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci	strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));
192662306a36Sopenharmony_ci
192762306a36Sopenharmony_ci	video_set_drvdata(vdev, params);
192862306a36Sopenharmony_ci	vdev->ioctl_ops = &rkisp1_params_ioctl;
192962306a36Sopenharmony_ci	vdev->fops = &rkisp1_params_fops;
193062306a36Sopenharmony_ci	vdev->release = video_device_release_empty;
193162306a36Sopenharmony_ci	/*
193262306a36Sopenharmony_ci	 * Provide a mutex to v4l2 core. It will be used
193362306a36Sopenharmony_ci	 * to protect all fops and v4l2 ioctls.
193462306a36Sopenharmony_ci	 */
193562306a36Sopenharmony_ci	vdev->lock = &node->vlock;
193662306a36Sopenharmony_ci	vdev->v4l2_dev = &rkisp1->v4l2_dev;
193762306a36Sopenharmony_ci	vdev->queue = &node->buf_queue;
193862306a36Sopenharmony_ci	vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
193962306a36Sopenharmony_ci	vdev->vfl_dir = VFL_DIR_TX;
194062306a36Sopenharmony_ci	rkisp1_params_init_vb2_queue(vdev->queue, params);
194162306a36Sopenharmony_ci	rkisp1_init_params(params);
194262306a36Sopenharmony_ci	video_set_drvdata(vdev, params);
194362306a36Sopenharmony_ci
194462306a36Sopenharmony_ci	node->pad.flags = MEDIA_PAD_FL_SOURCE;
194562306a36Sopenharmony_ci	ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
194662306a36Sopenharmony_ci	if (ret)
194762306a36Sopenharmony_ci		goto error;
194862306a36Sopenharmony_ci
194962306a36Sopenharmony_ci	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
195062306a36Sopenharmony_ci	if (ret) {
195162306a36Sopenharmony_ci		dev_err(rkisp1->dev,
195262306a36Sopenharmony_ci			"failed to register %s, ret=%d\n", vdev->name, ret);
195362306a36Sopenharmony_ci		goto error;
195462306a36Sopenharmony_ci	}
195562306a36Sopenharmony_ci
195662306a36Sopenharmony_ci	return 0;
195762306a36Sopenharmony_ci
195862306a36Sopenharmony_cierror:
195962306a36Sopenharmony_ci	media_entity_cleanup(&vdev->entity);
196062306a36Sopenharmony_ci	mutex_destroy(&node->vlock);
196162306a36Sopenharmony_ci	return ret;
196262306a36Sopenharmony_ci}
196362306a36Sopenharmony_ci
196462306a36Sopenharmony_civoid rkisp1_params_unregister(struct rkisp1_device *rkisp1)
196562306a36Sopenharmony_ci{
196662306a36Sopenharmony_ci	struct rkisp1_params *params = &rkisp1->params;
196762306a36Sopenharmony_ci	struct rkisp1_vdev_node *node = &params->vnode;
196862306a36Sopenharmony_ci	struct video_device *vdev = &node->vdev;
196962306a36Sopenharmony_ci
197062306a36Sopenharmony_ci	if (!video_is_registered(vdev))
197162306a36Sopenharmony_ci		return;
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_ci	vb2_video_unregister_device(vdev);
197462306a36Sopenharmony_ci	media_entity_cleanup(&vdev->entity);
197562306a36Sopenharmony_ci	mutex_destroy(&node->vlock);
197662306a36Sopenharmony_ci}
1977