Commit cd42f802 authored by Heiko Stuebner's avatar Heiko Stuebner Committed by Mauro Carvalho Chehab
Browse files

media: rockchip: rkisp1: add support for v12 isp variants



The rkisp1 evolved over soc generations and the rk3326/px30 introduced
the so called v12 - probably meaning v1.2.

Add the new register definitions.

Signed-off-by: default avatarHeiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: default avatarDafna Hirschfeld <dafna.hirschfeld@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent dce8ccb2
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

The Rockchip Image Signal Processor Driver (rkisp1)
===================================================

Versions and their differences
------------------------------

The rkisp1 block underwent some changes between SoC implementations.
The vendor designates them as:

- V10: used at least in rk3288 and rk3399
- V11: declared in the original vendor code, but not used
- V12: used at least in rk3326 and px30
- V13: used at least in rk1808
- V20: used in rk3568 and beyond

Right now the kernel supports rkisp1 implementations based
on V10 and V12 variants. V11 does not seem to be actually used
and V13 will need some more additions but isn't researched yet,
especially as it seems to be limited to the rk1808 which hasn't
reached much market spread.

V20 on the other hand will probably be used in future SoCs and
has seen really big changes in the vendor kernel, so will need
quite a bit of research.

Changes from V10 to V12
-----------------------

- V12 supports a new CSI-host implementation but can still
  also use the same implementation from V10
- The module for lens shading correction got changed
  from 12bit to 13bit width
- The AWB and AEC modules got replaced to support finer
  grained data collection

Changes from V12 to V13
-----------------------

The list for V13 is incomplete and needs further investigation.

- V13 does not support the old CSI-host implementation anymore
+13 −0
Original line number Diff line number Diff line
@@ -414,6 +414,10 @@ static int rkisp1_config_mipi(struct rkisp1_device *rkisp1)

	rkisp1_write(rkisp1, mipi_ctrl, RKISP1_CIF_MIPI_CTRL);

	/* V12 could also use a newer csi2-host, but we don't want that yet */
	if (rkisp1->media_dev.hw_revision == RKISP1_V12)
		rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_CSI0_CTRL0);

	/* Configure Data Type and Virtual Channel */
	rkisp1_write(rkisp1,
		     RKISP1_CIF_MIPI_DATA_SEL_DT(sink_fmt->mipi_dt) |
@@ -533,6 +537,15 @@ static void rkisp1_config_clk(struct rkisp1_device *rkisp1)
		  RKISP1_CIF_ICCL_DCROP_CLK;

	rkisp1_write(rkisp1, val, RKISP1_CIF_ICCL);

	/* ensure sp and mp can run at the same time in V12 */
	if (rkisp1->media_dev.hw_revision == RKISP1_V12) {
		val = RKISP1_CIF_CLK_CTRL_MI_Y12 | RKISP1_CIF_CLK_CTRL_MI_SP |
		      RKISP1_CIF_CLK_CTRL_MI_RAW0 | RKISP1_CIF_CLK_CTRL_MI_RAW1 |
		      RKISP1_CIF_CLK_CTRL_MI_READ | RKISP1_CIF_CLK_CTRL_MI_RAWRD |
		      RKISP1_CIF_CLK_CTRL_CP | RKISP1_CIF_CLK_CTRL_IE;
		rkisp1_write(rkisp1, val, RKISP1_CIF_VI_ISP_CLK_CTRL_V12);
	}
}

static void rkisp1_isp_start(struct rkisp1_device *rkisp1)
+337 −1
Original line number Diff line number Diff line
@@ -255,6 +255,78 @@ rkisp1_lsc_matrix_config_v10(struct rkisp1_params *params,
		     RKISP1_CIF_ISP_LSC_TABLE_SEL);
}

static void
rkisp1_lsc_matrix_config_v12(struct rkisp1_params *params,
			     const struct rkisp1_cif_isp_lsc_config *pconfig)
{
	unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;

	isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);

	/* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
	sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
		     RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
		     RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
	rkisp1_write(params->rkisp1, sram_addr, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);

	/* program data tables (table size is 9 * 17 = 153) */
	for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
		/*
		 * 17 sectors with 2 values in one DWORD = 9
		 * DWORDs (2nd value of last DWORD unused)
		 */
		for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
					pconfig->r_data_tbl[i][j],
					pconfig->r_data_tbl[i][j + 1]);
			rkisp1_write(params->rkisp1, data,
				     RKISP1_CIF_ISP_LSC_R_TABLE_DATA);

			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
					pconfig->gr_data_tbl[i][j],
					pconfig->gr_data_tbl[i][j + 1]);
			rkisp1_write(params->rkisp1, data,
				     RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);

			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
					pconfig->gb_data_tbl[i][j],
					pconfig->gb_data_tbl[i][j + 1]);
			rkisp1_write(params->rkisp1, data,
				     RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);

			data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(
					pconfig->b_data_tbl[i][j],
					pconfig->b_data_tbl[i][j + 1]);
			rkisp1_write(params->rkisp1, data,
				     RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
		}

		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->r_data_tbl[i][j], 0);
		rkisp1_write(params->rkisp1, data,
			     RKISP1_CIF_ISP_LSC_R_TABLE_DATA);

		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->gr_data_tbl[i][j], 0);
		rkisp1_write(params->rkisp1, data,
			     RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);

		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->gb_data_tbl[i][j], 0);
		rkisp1_write(params->rkisp1, data,
			     RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);

		data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->b_data_tbl[i][j], 0);
		rkisp1_write(params->rkisp1, data,
			     RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
	}
	isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
			    RKISP1_CIF_ISP_LSC_TABLE_0 :
			    RKISP1_CIF_ISP_LSC_TABLE_1;
	rkisp1_write(params->rkisp1, isp_lsc_table_sel,
		     RKISP1_CIF_ISP_LSC_TABLE_SEL);
}

static void rkisp1_lsc_config(struct rkisp1_params *params,
			      const struct rkisp1_cif_isp_lsc_config *arg)
{
@@ -396,6 +468,25 @@ static void rkisp1_goc_config_v10(struct rkisp1_params *params,
			     RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V10 + i * 4);
}

static void rkisp1_goc_config_v12(struct rkisp1_params *params,
				  const struct rkisp1_cif_isp_goc_config *arg)
{
	unsigned int i;
	u32 value;

	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
				RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
	rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE_V12);

	for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 / 2; i++) {
		value = RKISP1_CIF_ISP_GAMMA_VALUE_V12(
			arg->gamma_y[2 * i + 1],
			arg->gamma_y[2 * i]);
		rkisp1_write(params->rkisp1, value,
			     RKISP1_CIF_ISP_GAMMA_OUT_Y_0_V12 + i * 4);
	}
}

/* ISP Cross Talk */
static void rkisp1_ctk_config(struct rkisp1_params *params,
			      const struct rkisp1_cif_isp_ctk_config *arg)
@@ -473,6 +564,45 @@ static void rkisp1_awb_meas_config_v10(struct rkisp1_params *params,
		     arg->frames, RKISP1_CIF_ISP_AWB_FRAMES_V10);
}

static void rkisp1_awb_meas_config_v12(struct rkisp1_params *params,
				       const struct rkisp1_cif_isp_awb_meas_config *arg)
{
	u32 reg_val = 0;
	/* based on the mode,configure the awb module */
	if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
		/* Reference Cb and Cr */
		rkisp1_write(params->rkisp1,
			     RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
			     arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF_V12);
		/* Yc Threshold */
		rkisp1_write(params->rkisp1,
			     RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
			     RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
			     RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
			     arg->min_c, RKISP1_CIF_ISP_AWB_THRESH_V12);
	}

	reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);
	if (arg->enable_ymax_cmp)
		reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
	else
		reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
	reg_val &= ~RKISP1_CIF_ISP_AWB_SET_FRAMES_MASK_V12;
	reg_val |= RKISP1_CIF_ISP_AWB_SET_FRAMES_V12(arg->frames);
	rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP_V12);

	/* window offset */
	rkisp1_write(params->rkisp1,
		     arg->awb_wnd.v_offs << 16 |
		     arg->awb_wnd.h_offs,
		     RKISP1_CIF_ISP_AWB_OFFS_V12);
	/* AWB window size */
	rkisp1_write(params->rkisp1,
		     arg->awb_wnd.v_size << 16 |
		     arg->awb_wnd.h_size,
		     RKISP1_CIF_ISP_AWB_SIZE_V12);
}

static void
rkisp1_awb_meas_enable_v10(struct rkisp1_params *params,
			   const struct rkisp1_cif_isp_awb_meas_config *arg,
@@ -502,6 +632,35 @@ rkisp1_awb_meas_enable_v10(struct rkisp1_params *params,
	}
}

static void
rkisp1_awb_meas_enable_v12(struct rkisp1_params *params,
			   const struct rkisp1_cif_isp_awb_meas_config *arg,
			   bool en)
{
	u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP_V12);

	/* switch off */
	reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;

	if (en) {
		if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
			reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
		else
			reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;

		rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP_V12);

		/* Measurements require AWB block be active. */
		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
				      RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
	} else {
		rkisp1_write(params->rkisp1,
			     reg_val, RKISP1_CIF_ISP_AWB_PROP_V12);
		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
					RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
	}
}

static void
rkisp1_awb_gain_config_v10(struct rkisp1_params *params,
			   const struct rkisp1_cif_isp_awb_gain_config *arg)
@@ -515,6 +674,19 @@ rkisp1_awb_gain_config_v10(struct rkisp1_params *params,
		     arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB_V10);
}

static void
rkisp1_awb_gain_config_v12(struct rkisp1_params *params,
			   const struct rkisp1_cif_isp_awb_gain_config *arg)
{
	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
		     arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G_V12);

	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
		     arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB_V12);
}

static void rkisp1_aec_config_v10(struct rkisp1_params *params,
				  const struct rkisp1_cif_isp_aec_config *arg)
{
@@ -548,6 +720,38 @@ static void rkisp1_aec_config_v10(struct rkisp1_params *params,
		     RKISP1_CIF_ISP_EXP_V_SIZE_V10);
}

static void rkisp1_aec_config_v12(struct rkisp1_params *params,
			       const struct rkisp1_cif_isp_aec_config *arg)
{
	u32 exp_ctrl;
	u32 block_hsize, block_vsize;
	u32 wnd_num_idx = 1;
	const u32 ae_wnd_num[] = { 5, 9, 15, 15 };

	/* avoid to override the old enable value */
	exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
	exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
	if (arg->autostop)
		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
	if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
		exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
	exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_WNDNUM_SET_V12(wnd_num_idx);
	rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);

	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_EXP_V_OFFSET_SET_V12(arg->meas_window.v_offs) |
		     RKISP1_CIF_ISP_EXP_H_OFFSET_SET_V12(arg->meas_window.h_offs),
		     RKISP1_CIF_ISP_EXP_OFFS_V12);

	block_hsize = arg->meas_window.h_size / ae_wnd_num[wnd_num_idx] - 1;
	block_vsize = arg->meas_window.v_size / ae_wnd_num[wnd_num_idx] - 1;

	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_EXP_V_SIZE_SET_V12(block_vsize) |
		     RKISP1_CIF_ISP_EXP_H_SIZE_SET_V12(block_hsize),
		     RKISP1_CIF_ISP_EXP_SIZE_V12);
}

static void rkisp1_cproc_config(struct rkisp1_params *params,
				const struct rkisp1_cif_isp_cproc_config *arg)
{
@@ -625,6 +829,64 @@ static void rkisp1_hst_config_v10(struct rkisp1_params *params,
	rkisp1_write(params->rkisp1, weight[0] & 0x1F, RKISP1_CIF_ISP_HIST_WEIGHT_44_V10);
}

static void rkisp1_hst_config_v12(struct rkisp1_params *params,
				  const struct rkisp1_cif_isp_hst_config *arg)
{
	unsigned int i, j;
	u32 block_hsize, block_vsize;
	u32 wnd_num_idx, hist_weight_num, hist_ctrl, value;
	u8 weight15x15[RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12];
	const u32 hist_wnd_num[] = { 5, 9, 15, 15 };

	/* now we just support 9x9 window */
	wnd_num_idx = 1;
	memset(weight15x15, 0x00, sizeof(weight15x15));
	/* avoid to override the old enable value */
	hist_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_CTRL_V12);
	hist_ctrl &= RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
		     RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12;
	hist_ctrl = hist_ctrl |
		    RKISP1_CIF_ISP_HIST_CTRL_INTRSEL_SET_V12(1) |
		    RKISP1_CIF_ISP_HIST_CTRL_DATASEL_SET_V12(0) |
		    RKISP1_CIF_ISP_HIST_CTRL_WATERLINE_SET_V12(0) |
		    RKISP1_CIF_ISP_HIST_CTRL_AUTOSTOP_SET_V12(0) |
		    RKISP1_CIF_ISP_HIST_CTRL_WNDNUM_SET_V12(1) |
		    RKISP1_CIF_ISP_HIST_CTRL_STEPSIZE_SET_V12(arg->histogram_predivider);
	rkisp1_write(params->rkisp1, hist_ctrl, RKISP1_CIF_ISP_HIST_CTRL_V12);

	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_HIST_OFFS_SET_V12(arg->meas_window.h_offs,
						      arg->meas_window.v_offs),
		     RKISP1_CIF_ISP_HIST_OFFS_V12);

	block_hsize = arg->meas_window.h_size / hist_wnd_num[wnd_num_idx] - 1;
	block_vsize = arg->meas_window.v_size / hist_wnd_num[wnd_num_idx] - 1;
	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_HIST_SIZE_SET_V12(block_hsize, block_vsize),
		     RKISP1_CIF_ISP_HIST_SIZE_V12);

	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
			weight15x15[i * RKISP1_CIF_ISP_HIST_ROW_NUM_V12 + j] =
				arg->hist_weight[i * hist_wnd_num[wnd_num_idx] + j];
		}
	}

	hist_weight_num = RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12;
	for (i = 0; i < (hist_weight_num / 4); i++) {
		value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(
				 weight15x15[4 * i + 0],
				 weight15x15[4 * i + 1],
				 weight15x15[4 * i + 2],
				 weight15x15[4 * i + 3]);
		rkisp1_write(params->rkisp1, value,
				 RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i);
	}
	value = RKISP1_CIF_ISP_HIST_WEIGHT_SET_V12(weight15x15[4 * i + 0], 0, 0, 0);
	rkisp1_write(params->rkisp1, value,
				 RKISP1_CIF_ISP_HIST_WEIGHT_V12 + 4 * i);
}

static void
rkisp1_hst_enable_v10(struct rkisp1_params *params,
		      const struct rkisp1_cif_isp_hst_config *arg, bool en)
@@ -643,6 +905,26 @@ rkisp1_hst_enable_v10(struct rkisp1_params *params,
	}
}

static void
rkisp1_hst_enable_v12(struct rkisp1_params *params,
		      const struct rkisp1_cif_isp_hst_config *arg, bool en)
{
	if (en) {
		u32 hist_ctrl = rkisp1_read(params->rkisp1,
					    RKISP1_CIF_ISP_HIST_CTRL_V12);

		hist_ctrl &= ~RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12;
		hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_MODE_SET_V12(arg->mode);
		hist_ctrl |= RKISP1_CIF_ISP_HIST_CTRL_EN_SET_V12(1);
		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,
				      hist_ctrl);
	} else {
		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_CTRL_V12,
					RKISP1_CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
					RKISP1_CIF_ISP_HIST_CTRL_EN_MASK_V12);
	}
}

static void rkisp1_afm_config_v10(struct rkisp1_params *params,
				  const struct rkisp1_cif_isp_afc_config *arg)
{
@@ -674,6 +956,45 @@ static void rkisp1_afm_config_v10(struct rkisp1_params *params,
	rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
}

static void rkisp1_afm_config_v12(struct rkisp1_params *params,
				  const struct rkisp1_cif_isp_afc_config *arg)
{
	size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
				  arg->num_afm_win);
	u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
	u32 lum_var_shift, afm_var_shift;
	unsigned int i;

	/* Switch off to configure. */
	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
				RKISP1_CIF_ISP_AFM_ENA);

	for (i = 0; i < num_of_win; i++) {
		rkisp1_write(params->rkisp1,
			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
			     RKISP1_CIF_ISP_AFM_LT_A + i * 8);
		rkisp1_write(params->rkisp1,
			     RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
							 arg->afm_win[i].h_offs) |
			     RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
							 arg->afm_win[i].v_offs),
			     RKISP1_CIF_ISP_AFM_RB_A + i * 8);
	}
	rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);

	lum_var_shift = RKISP1_CIF_ISP_AFM_GET_LUM_SHIFT_a_V12(arg->var_shift);
	afm_var_shift = RKISP1_CIF_ISP_AFM_GET_AFM_SHIFT_a_V12(arg->var_shift);
	rkisp1_write(params->rkisp1,
		     RKISP1_CIF_ISP_AFM_SET_SHIFT_a_V12(lum_var_shift, afm_var_shift) |
		     RKISP1_CIF_ISP_AFM_SET_SHIFT_b_V12(lum_var_shift, afm_var_shift) |
		     RKISP1_CIF_ISP_AFM_SET_SHIFT_c_V12(lum_var_shift, afm_var_shift),
		     RKISP1_CIF_ISP_AFM_VAR_SHIFT);

	/* restore afm status */
	rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
}

static void rkisp1_ie_config(struct rkisp1_params *params,
			     const struct rkisp1_cif_isp_ie_config *arg)
{
@@ -1305,6 +1626,18 @@ static const struct rkisp1_params_ops rkisp1_v10_params_ops = {
	.afm_config = rkisp1_afm_config_v10,
};

static struct rkisp1_params_ops rkisp1_v12_params_ops = {
	.lsc_matrix_config = rkisp1_lsc_matrix_config_v12,
	.goc_config = rkisp1_goc_config_v12,
	.awb_meas_config = rkisp1_awb_meas_config_v12,
	.awb_meas_enable = rkisp1_awb_meas_enable_v12,
	.awb_gain_config = rkisp1_awb_gain_config_v12,
	.aec_config = rkisp1_aec_config_v12,
	.hst_config = rkisp1_hst_config_v12,
	.hst_enable = rkisp1_hst_enable_v12,
	.afm_config = rkisp1_afm_config_v12,
};

static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
					   struct v4l2_fmtdesc *f)
{
@@ -1471,6 +1804,9 @@ static void rkisp1_init_params(struct rkisp1_params *params)
	params->vdev_fmt.fmt.meta.buffersize =
		sizeof(struct rkisp1_params_cfg);

	if (params->rkisp1->media_dev.hw_revision == RKISP1_V12)
		params->ops = &rkisp1_v12_params_ops;
	else
		params->ops = &rkisp1_v10_params_ops;
}

+143 −0

File changed.

Preview size limit exceeded, changes collapsed.

+72 −1
Original line number Diff line number Diff line
@@ -195,6 +195,27 @@ static void rkisp1_stats_get_awb_meas_v10(struct rkisp1_stats *stats,
				RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
}

static void rkisp1_stats_get_awb_meas_v12(struct rkisp1_stats *stats,
					  struct rkisp1_stat_buffer *pbuf)
{
	/* Protect against concurrent access from ISR? */
	struct rkisp1_device *rkisp1 = stats->rkisp1;
	u32 reg_val;

	pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AWB;
	reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_WHITE_CNT_V12);
	pbuf->params.awb.awb_mean[0].cnt =
				RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(reg_val);
	reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_MEAN_V12);

	pbuf->params.awb.awb_mean[0].mean_cr_or_r =
				RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(reg_val);
	pbuf->params.awb.awb_mean[0].mean_cb_or_b =
				RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(reg_val);
	pbuf->params.awb.awb_mean[0].mean_y_or_g =
				RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
}

static void rkisp1_stats_get_aec_meas_v10(struct rkisp1_stats *stats,
					  struct rkisp1_stat_buffer *pbuf)
{
@@ -208,6 +229,30 @@ static void rkisp1_stats_get_aec_meas_v10(struct rkisp1_stats *stats,
					RKISP1_CIF_ISP_EXP_MEAN_00_V10 + i * 4);
}

static void rkisp1_stats_get_aec_meas_v12(struct rkisp1_stats *stats,
					  struct rkisp1_stat_buffer *pbuf)
{
	struct rkisp1_device *rkisp1 = stats->rkisp1;
	u32 value;
	int i;

	pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP;
	for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX_V12 / 4; i++) {
		value = rkisp1_read(rkisp1, RKISP1_CIF_ISP_EXP_MEAN_V12 + i * 4);
		pbuf->params.ae.exp_mean[4 * i + 0] =
				RKISP1_CIF_ISP_EXP_GET_MEAN_xy0_V12(value);
		pbuf->params.ae.exp_mean[4 * i + 1] =
				RKISP1_CIF_ISP_EXP_GET_MEAN_xy1_V12(value);
		pbuf->params.ae.exp_mean[4 * i + 2] =
				RKISP1_CIF_ISP_EXP_GET_MEAN_xy2_V12(value);
		pbuf->params.ae.exp_mean[4 * i + 3] =
				RKISP1_CIF_ISP_EXP_GET_MEAN_xy3_V12(value);
	}

	value = rkisp1_read(rkisp1, RKISP1_CIF_ISP_EXP_MEAN_V12 + i * 4);
	pbuf->params.ae.exp_mean[4 * i + 0] = RKISP1_CIF_ISP_EXP_GET_MEAN_xy0_V12(value);
}

static void rkisp1_stats_get_afc_meas(struct rkisp1_stats *stats,
				      struct rkisp1_stat_buffer *pbuf)
{
@@ -239,6 +284,23 @@ static void rkisp1_stats_get_hst_meas_v10(struct rkisp1_stats *stats,
	}
}

static void rkisp1_stats_get_hst_meas_v12(struct rkisp1_stats *stats,
					  struct rkisp1_stat_buffer *pbuf)
{
	struct rkisp1_device *rkisp1 = stats->rkisp1;
	u32 value;
	int i;

	pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST;
	for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 / 2; i++) {
		value = rkisp1_read(rkisp1, RKISP1_CIF_ISP_HIST_BIN_V12 + i * 4);
		pbuf->params.hist.hist_bins[2 * i] =
					RKISP1_CIF_ISP_HIST_GET_BIN0_V12(value);
		pbuf->params.hist.hist_bins[2 * i + 1] =
					RKISP1_CIF_ISP_HIST_GET_BIN1_V12(value);
	}
}

static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats,
				      struct rkisp1_stat_buffer *pbuf)
{
@@ -292,6 +354,12 @@ static const struct rkisp1_stats_ops rkisp1_v10_stats_ops = {
	.get_hst_meas = rkisp1_stats_get_hst_meas_v10,
};

static struct rkisp1_stats_ops rkisp1_v12_stats_ops = {
	.get_awb_meas = rkisp1_stats_get_awb_meas_v12,
	.get_aec_meas = rkisp1_stats_get_aec_meas_v12,
	.get_hst_meas = rkisp1_stats_get_hst_meas_v12,
};

static void
rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
{
@@ -359,6 +427,9 @@ static void rkisp1_init_stats(struct rkisp1_stats *stats)
	stats->vdev_fmt.fmt.meta.buffersize =
		sizeof(struct rkisp1_stat_buffer);

	if (stats->rkisp1->media_dev.hw_revision == RKISP1_V12)
		stats->ops = &rkisp1_v12_stats_ops;
	else
		stats->ops = &rkisp1_v10_stats_ops;
}