From d80d956f282c25444facd727f56c5376f2eeefec Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 6 Dec 2024 10:25:31 +0800 Subject: [PATCH] media: rockchip: isp: add isp35 Change-Id: I1f254e64426307983d3a223c761ea9480772b32c Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/Kconfig | 30 +- drivers/media/platform/rockchip/isp/Makefile | 8 + drivers/media/platform/rockchip/isp/capture.c | 54 +- .../media/platform/rockchip/isp/capture_v35.c | 1658 ++++ .../media/platform/rockchip/isp/capture_v3x.h | 14 +- drivers/media/platform/rockchip/isp/common.h | 2 + drivers/media/platform/rockchip/isp/csi.c | 10 +- drivers/media/platform/rockchip/isp/dev.c | 11 +- drivers/media/platform/rockchip/isp/dev.h | 2 +- drivers/media/platform/rockchip/isp/hw.c | 263 +- .../media/platform/rockchip/isp/isp_params.c | 19 +- .../media/platform/rockchip/isp/isp_params.h | 4 + .../platform/rockchip/isp/isp_params_v35.c | 8539 +++++++++++++++++ .../platform/rockchip/isp/isp_params_v35.h | 64 + .../media/platform/rockchip/isp/isp_pdaf.c | 48 +- .../media/platform/rockchip/isp/isp_pdaf.h | 2 +- .../media/platform/rockchip/isp/isp_rockit.c | 2 +- .../media/platform/rockchip/isp/isp_sditf.c | 2 + .../media/platform/rockchip/isp/isp_sditf.h | 2 +- .../media/platform/rockchip/isp/isp_stats.c | 61 +- .../media/platform/rockchip/isp/isp_stats.h | 3 + .../platform/rockchip/isp/isp_stats_v21.c | 18 +- .../platform/rockchip/isp/isp_stats_v21.h | 2 - .../platform/rockchip/isp/isp_stats_v2x.c | 18 +- .../platform/rockchip/isp/isp_stats_v2x.h | 2 - .../platform/rockchip/isp/isp_stats_v32.c | 42 +- .../platform/rockchip/isp/isp_stats_v32.h | 4 - .../platform/rockchip/isp/isp_stats_v33.c | 40 +- .../platform/rockchip/isp/isp_stats_v33.h | 4 - .../platform/rockchip/isp/isp_stats_v35.c | 636 ++ .../platform/rockchip/isp/isp_stats_v35.h | 19 + .../platform/rockchip/isp/isp_stats_v39.c | 26 +- .../platform/rockchip/isp/isp_stats_v39.h | 4 - .../platform/rockchip/isp/isp_stats_v3x.c | 18 +- .../platform/rockchip/isp/isp_stats_v3x.h | 2 - drivers/media/platform/rockchip/isp/procfs.c | 161 + drivers/media/platform/rockchip/isp/regs.c | 5 +- .../media/platform/rockchip/isp/regs_v3x.h | 169 +- drivers/media/platform/rockchip/isp/rkisp.c | 117 +- drivers/media/platform/rockchip/isp/rkisp.h | 2 + include/soc/rockchip/rockchip_rockit.h | 4 +- include/uapi/linux/rk-isp2-config.h | 26 + include/uapi/linux/rk-isp35-config.h | 1751 ++++ 43 files changed, 13507 insertions(+), 361 deletions(-) create mode 100644 drivers/media/platform/rockchip/isp/capture_v35.c create mode 100644 drivers/media/platform/rockchip/isp/isp_params_v35.c create mode 100644 drivers/media/platform/rockchip/isp/isp_params_v35.h create mode 100644 drivers/media/platform/rockchip/isp/isp_stats_v35.c create mode 100644 drivers/media/platform/rockchip/isp/isp_stats_v35.h create mode 100644 include/uapi/linux/rk-isp35-config.h diff --git a/drivers/media/platform/rockchip/isp/Kconfig b/drivers/media/platform/rockchip/isp/Kconfig index 3c4303870179..9cdcbe8124f5 100644 --- a/drivers/media/platform/rockchip/isp/Kconfig +++ b/drivers/media/platform/rockchip/isp/Kconfig @@ -40,16 +40,6 @@ config VIDEO_ROCKCHIP_ISP_VERSION_V32 depends on CPU_RV1106 || CPU_RK3562 default y -config VIDEO_ROCKCHIP_ISP_VERSION_V39 - bool "isp39 for rk3576" - depends on CPU_RK3576 - default y - -config VIDEO_ROCKCHIP_ISP_VERSION_V39_DBG - bool "isp39 params debug for rk3576" - depends on VIDEO_ROCKCHIP_ISP_VERSION_V39 - default n - config VIDEO_ROCKCHIP_ISP_VERSION_V33 bool "isp33 for rv1103b" depends on CPU_RV1103B @@ -60,6 +50,26 @@ config VIDEO_ROCKCHIP_ISP_VERSION_V33_DBG depends on VIDEO_ROCKCHIP_ISP_VERSION_V33 default n +config VIDEO_ROCKCHIP_ISP_VERSION_V35 + bool "isp35 for rv1126b" + depends on CPU_RV1126B + default y + +config VIDEO_ROCKCHIP_ISP_VERSION_V35_DBG + bool "isp35 params debug for rv1126b" + depends on VIDEO_ROCKCHIP_ISP_VERSION_V35 + default n + +config VIDEO_ROCKCHIP_ISP_VERSION_V39 + bool "isp39 for rk3576" + depends on CPU_RK3576 + default y + +config VIDEO_ROCKCHIP_ISP_VERSION_V39_DBG + bool "isp39 params debug for rk3576" + depends on VIDEO_ROCKCHIP_ISP_VERSION_V39 + default n + config VIDEO_ROCKCHIP_THUNDER_BOOT_ISP bool "Rockchip Image Signal Processing Thunderboot helper" depends on ROCKCHIP_THUNDER_BOOT diff --git a/drivers/media/platform/rockchip/isp/Makefile b/drivers/media/platform/rockchip/isp/Makefile index 202a30b2aa18..06fe2e11075e 100644 --- a/drivers/media/platform/rockchip/isp/Makefile +++ b/drivers/media/platform/rockchip/isp/Makefile @@ -57,6 +57,14 @@ video_rkisp-$(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) += \ isp_stats_v33.o \ isp_rockit.o +video_rkisp-$(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) += \ + capture_v35.o \ + isp_params_v35.o \ + isp_stats_v35.o \ + isp_pdaf.o \ + isp_sditf.o \ + isp_rockit.o + video_rkisp-$(CONFIG_ROCKCHIP_DVBM) += \ isp_dvbm.o diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index a4019fa5711b..b62ec33a73df 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -863,10 +863,8 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, t = &dev->cap_dev.stream[i]; if (t->out_isp_fmt.fmt_type != FMT_YUV || !t->streaming) continue; - /* isp v32 v33 mp wrap can't use for iqtool */ - if (i == RKISP_STREAM_MP && - (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) && - dev->cap_dev.wrap_line) + /* mp wrap can't use for iqtool */ + if (i == RKISP_STREAM_MP && dev->cap_dev.wrap_line) continue; if (t->out_fmt.plane_fmt[0].sizeimage > imagsize) { imagsize = t->out_fmt.plane_fmt[0].sizeimage; @@ -896,10 +894,20 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, plane_fmt = pixm->plane_fmt + i; - w = (fmt->fmt_type == FMT_FBC) ? - ALIGN(pixm->width, 16) : pixm->width; - h = (fmt->fmt_type == FMT_FBC) ? - ALIGN(pixm->height, 16) : pixm->height; + switch (fmt->fmt_type) { + case FMT_FBC: + w = ALIGN(pixm->width, 16); + h = ALIGN(pixm->height, 16); + break; + case FMT_TILE: + w = (pixm->width + 3) / 4; + h = pixm->height / 4; + break; + default: + w = pixm->width; + h = pixm->height; + break; + } if (stream->id == RKISP_STREAM_LDC) w = ALIGN(pixm->width, 32); /* mainpath for warp default */ @@ -921,6 +929,8 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, stream->id != RKISP_STREAM_SP) /* compact mode need bytesperline 4byte align */ bytesperline = ALIGN(width * fmt->bpp[i] / 8, 256); + else if (fmt->fmt_type == FMT_TILE) + bytesperline = width * fmt->bpp[i]; else bytesperline = width * DIV_ROUND_UP(fmt->bpp[i], 8); @@ -1297,8 +1307,7 @@ static int rkisp_get_wrap_line(struct rkisp_stream *stream, struct rkisp_wrap_in { struct rkisp_device *dev = stream->ispdev; - if (stream->id != RKISP_STREAM_MP && - dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) + if (!stream->ops->set_wrap) return -EINVAL; arg->width = dev->cap_dev.wrap_width; @@ -1382,10 +1391,8 @@ static int rkisp_set_iqtool_connect_id(struct rkisp_stream *stream, int stream_i goto err; } - if ((dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) && - (stream_id == RKISP_STREAM_MP) && - dev->cap_dev.wrap_line) { - v4l2_err(&dev->v4l2_dev, "isp v32 v33 mp wrap can't use for iqtool"); + if (stream_id == RKISP_STREAM_MP && dev->cap_dev.wrap_line) { + v4l2_err(&dev->v4l2_dev, "mp wrap can't use for iqtool"); goto err; } @@ -1579,6 +1586,16 @@ static int rkisp_enum_fmt_vid_cap_mplane(struct file *file, void *priv, "Shield pix data 16-bit", sizeof(f->description)); break; + case V4L2_PIX_FMT_TILE420: + strscpy(f->description, + "Rockchip yuv420 tile", + sizeof(f->description)); + break; + case V4L2_PIX_FMT_TILE422: + strscpy(f->description, + "Rockchip yuv422 tile", + sizeof(f->description)); + break; default: break; } @@ -1807,9 +1824,6 @@ static void rkisp_stream_fast(struct work_struct *work) struct v4l2_subdev *sd = ispdev->active_sensor->sd; int ret; - if (ispdev->isp_ver != ISP_V32 && ispdev->isp_ver != ISP_V33) - return; - mutex_lock(&ispdev->hw_dev->dev_lock); rkisp_chk_tb_over(ispdev); mutex_unlock(&ispdev->hw_dev->dev_lock); @@ -1954,6 +1968,8 @@ int rkisp_register_stream_vdevs(struct rkisp_device *dev) ret = rkisp_register_stream_v39(dev); } else if (dev->isp_ver == ISP_V33) { ret = rkisp_register_stream_v33(dev); + } else if (dev->isp_ver == ISP_V35) { + ret = rkisp_register_stream_v35(dev); } INIT_WORK(&cap_dev->fast_work, rkisp_stream_fast); @@ -1976,6 +1992,8 @@ void rkisp_unregister_stream_vdevs(struct rkisp_device *dev) rkisp_unregister_stream_v39(dev); else if (dev->isp_ver == ISP_V33) rkisp_unregister_stream_v33(dev); + else if (dev->isp_ver == ISP_V35) + rkisp_unregister_stream_v35(dev); } void rkisp_mi_isr(u32 mis_val, struct rkisp_device *dev) @@ -1994,6 +2012,8 @@ void rkisp_mi_isr(u32 mis_val, struct rkisp_device *dev) rkisp_mi_v39_isr(mis_val, dev); else if (dev->isp_ver == ISP_V33) rkisp_mi_v33_isr(mis_val, dev); + else if (dev->isp_ver == ISP_V35) + rkisp_mi_v35_isr(mis_val, dev); } void rkisp_mipi_v3x_isr(unsigned int phy, unsigned int packet, diff --git a/drivers/media/platform/rockchip/isp/capture_v35.c b/drivers/media/platform/rockchip/isp/capture_v35.c new file mode 100644 index 000000000000..bb3c759479c0 --- /dev/null +++ b/drivers/media/platform/rockchip/isp/capture_v35.c @@ -0,0 +1,1658 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dev.h" +#include "regs.h" + +/* ISP35 + * |-->mainpath------------------->ddr + *output->|-->selfpath------------------->ddr + */ + +#define CIF_ISP_REQ_BUFS_MIN 0 + +static int mi_frame_end(struct rkisp_stream *stream, u32 state); +static int mi_frame_start(struct rkisp_stream *stream, u32 irq); +static int rkisp_create_dummy_buf(struct rkisp_stream *stream); + +static const struct capture_fmt mp_fmts[] = { + /* yuv422 */ + { + .fourcc = V4L2_PIX_FMT_UYVY, + .fmt_type = FMT_YUV, + .bpp = { 16 }, + .cplanes = 1, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_MP_WRITE_YUVINT, + .output_format = ISP32_MI_OUTPUT_YUV422, + }, { + .fourcc = V4L2_PIX_FMT_NV16, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_MP_WRITE_YUV_SPLA, + .output_format = ISP32_MI_OUTPUT_YUV422, + }, { + .fourcc = V4L2_PIX_FMT_NV61, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 1, + .write_format = MI_CTRL_MP_WRITE_YUV_SPLA, + .output_format = ISP32_MI_OUTPUT_YUV422, + }, + /* yuv420 */ + { + .fourcc = V4L2_PIX_FMT_NV21, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 1, + .write_format = MI_CTRL_MP_WRITE_YUV_SPLA, + .output_format = ISP32_MI_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV12, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_MP_WRITE_YUV_SPLA, + .output_format = ISP32_MI_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV21M, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 2, + .uv_swap = 1, + .write_format = MI_CTRL_MP_WRITE_YUV_SPLA, + .output_format = ISP32_MI_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV12M, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 2, + .uv_swap = 0, + .write_format = MI_CTRL_MP_WRITE_YUV_SPLA, + .output_format = ISP32_MI_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_GREY, + .fmt_type = FMT_YUV, + .bpp = { 8 }, + .cplanes = 1, + .mplanes = 1, + .uv_swap = 0, + .write_format = 0, + .output_format = ISP32_MI_OUTPUT_YUV400, + }, { + .fourcc = V4L2_PIX_FMT_TILE422, + .fmt_type = FMT_TILE, + .bpp = { 32 }, + .cplanes = 1, + .mplanes = 1, + .uv_swap = 0, + .write_format = 0, + .output_format = ISP32_MI_OUTPUT_YUV422 | ISP35_MI_MP_TILE, + }, { + .fourcc = V4L2_PIX_FMT_TILE420, + .fmt_type = FMT_TILE, + .bpp = { 24 }, + .cplanes = 1, + .mplanes = 1, + .uv_swap = 0, + .write_format = 0, + .output_format = ISP32_MI_OUTPUT_YUV420 | ISP35_MI_MP_TILE, + }, +}; + +static const struct capture_fmt sp_fmts[] = { + /* yuv422 */ + { + .fourcc = V4L2_PIX_FMT_UYVY, + .fmt_type = FMT_YUV, + .bpp = { 16 }, + .cplanes = 1, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_SP_WRITE_INT, + .output_format = MI_CTRL_SP_OUTPUT_YUV422, + }, { + .fourcc = V4L2_PIX_FMT_NV16, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_SP_WRITE_SPLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV422, + }, { + .fourcc = V4L2_PIX_FMT_NV61, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 1, + .write_format = MI_CTRL_SP_WRITE_SPLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV422, + }, + /* yuv420 */ + { + .fourcc = V4L2_PIX_FMT_NV21, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 1, + .write_format = MI_CTRL_SP_WRITE_SPLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV12, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_SP_WRITE_SPLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV21M, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 2, + .uv_swap = 1, + .write_format = MI_CTRL_SP_WRITE_SPLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV12M, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 2, + .uv_swap = 0, + .write_format = MI_CTRL_SP_WRITE_SPLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV420, + }, + /* yuv400 */ + { + .fourcc = V4L2_PIX_FMT_GREY, + .fmt_type = FMT_YUV, + .bpp = { 8 }, + .cplanes = 1, + .mplanes = 1, + .uv_swap = 0, + .write_format = MI_CTRL_SP_WRITE_PLA, + .output_format = MI_CTRL_SP_OUTPUT_YUV400, + }, + /* rgb */ + { + .fourcc = V4L2_PIX_FMT_XBGR32, + .fmt_type = FMT_RGB, + .bpp = { 32 }, + .mplanes = 1, + .write_format = MI_CTRL_SP_WRITE_PLA, + .output_format = MI_CTRL_SP_OUTPUT_ARGB888, + }, { + .fourcc = V4L2_PIX_FMT_RGB565, + .fmt_type = FMT_RGB, + .bpp = { 16 }, + .mplanes = 1, + .write_format = MI_CTRL_SP_WRITE_PLA, + .output_format = MI_CTRL_SP_OUTPUT_RGB565, + }, { + .fourcc = V4L2_PIX_FMT_RGB24, + .fmt_type = FMT_RGB, + .bpp = { 24 }, + .mplanes = 1, + .write_format = MI_CTRL_SP_WRITE_PLA, + .output_format = MI_CTRL_SP_OUTPUT_RGB888, + }, +}; + +static struct stream_config rkisp_mp_stream_cfg = { + .fmts = mp_fmts, + .fmt_size = ARRAY_SIZE(mp_fmts), + .max_rsz_width = CIF_ISP_INPUT_W_MAX_V35, + .max_rsz_height = CIF_ISP_INPUT_H_MAX_V35, + .min_rsz_width = STREAM_MIN_RSZ_OUTPUT_WIDTH, + .min_rsz_height = STREAM_MIN_RSZ_OUTPUT_HEIGHT, + .frame_end_id = CIF_MI_MP_FRAME, + /* registers */ + .rsz = { + .ctrl = ISP39_MAIN_SCALE_CTRL, + .update = ISP39_MAIN_SCALE_UPDATE, + .src_size = ISP39_MAIN_SCALE_SRC_SIZE, + .dst_size = ISP39_MAIN_SCALE_DST_SIZE, + .scale_hy_offs_mi = ISP39_MAIN_SCALE_HY_OFFS_MI, + .scale_hc_offs_mi = ISP39_MAIN_SCALE_HC_OFFS_MI, + .scale_in_crop_offs = ISP39_MAIN_SCALE_IN_CROP_OFFSET, + .scale_hy_offs = ISP39_MAIN_SCALE_HY_OFFS, + .scale_hc_offs = ISP39_MAIN_SCALE_HC_OFFS, + .scale_hy_size = ISP39_MAIN_SCALE_HY_SIZE, + .scale_hc_size = ISP39_MAIN_SCALE_HC_SIZE, + .scale_hy = ISP39_MAIN_SCALE_HY_FAC, + .scale_hcr = ISP39_MAIN_SCALE_HC_FAC, + .scale_vy = ISP39_MAIN_SCALE_VY_FAC, + .scale_vc = ISP39_MAIN_SCALE_VC_FAC, + .scale_hy_shd = ISP39_MAIN_SCALE_HY_FAC_SHD, + .scale_hcr_shd = ISP39_MAIN_SCALE_HC_FAC_SHD, + .scale_vy_shd = ISP39_MAIN_SCALE_VY_FAC_SHD, + .scale_vc_shd = ISP39_MAIN_SCALE_VC_FAC_SHD, + .ctrl_shd = ISP39_MAIN_SCALE_CTRL_SHD, + }, + .dual_crop = { + .ctrl = CIF_DUAL_CROP_CTRL, + .yuvmode_mask = CIF_DUAL_CROP_MP_MODE_YUV, + .rawmode_mask = CIF_DUAL_CROP_MP_MODE_RAW, + .h_offset = CIF_DUAL_CROP_M_H_OFFS, + .v_offset = CIF_DUAL_CROP_M_V_OFFS, + .h_size = CIF_DUAL_CROP_M_H_SIZE, + .v_size = CIF_DUAL_CROP_M_V_SIZE, + }, + .mi = { + .y_size_init = CIF_MI_MP_Y_SIZE_INIT, + .cb_size_init = CIF_MI_MP_CB_SIZE_INIT, + .cr_size_init = CIF_MI_MP_CR_SIZE_INIT, + .y_base_ad_init = CIF_MI_MP_Y_BASE_AD_INIT, + .cb_base_ad_init = CIF_MI_MP_CB_BASE_AD_INIT, + .cr_base_ad_init = CIF_MI_MP_CR_BASE_AD_INIT, + .y_offs_cnt_init = CIF_MI_MP_Y_OFFS_CNT_INIT, + .cb_offs_cnt_init = CIF_MI_MP_CB_OFFS_CNT_INIT, + .cr_offs_cnt_init = CIF_MI_MP_CR_OFFS_CNT_INIT, + .y_base_ad_shd = CIF_MI_MP_Y_BASE_AD_SHD, + .y_pic_size = ISP3X_MI_MP_WR_Y_PIC_SIZE, + }, +}; + +static struct stream_config rkisp_sp_stream_cfg = { + .fmts = sp_fmts, + .fmt_size = ARRAY_SIZE(sp_fmts), + .max_rsz_width = STREAM_MAX_SP_RSZ_OUTPUT_WIDTH, + .max_rsz_height = STREAM_MAX_SP_RSZ_OUTPUT_HEIGHT, + .min_rsz_width = STREAM_MIN_RSZ_OUTPUT_WIDTH, + .min_rsz_height = STREAM_MIN_RSZ_OUTPUT_HEIGHT, + .frame_end_id = CIF_MI_SP_FRAME, + /* registers */ + .rsz = { + .ctrl = ISP32_SELF_SCALE_CTRL, + .update = ISP32_SELF_SCALE_UPDATE, + .src_size = ISP32_SELF_SCALE_SRC_SIZE, + .dst_size = ISP32_SELF_SCALE_DST_SIZE, + .scale_hy_offs_mi = ISP32_SELF_SCALE_HY_OFFS_MI, + .scale_hc_offs_mi = ISP32_SELF_SCALE_HC_OFFS_MI, + .scale_in_crop_offs = ISP32_SELF_SCALE_IN_CROP_OFFSET, + .scale_hy_offs = ISP32_SELF_SCALE_HY_OFFS, + .scale_hc_offs = ISP32_SELF_SCALE_HC_OFFS, + .scale_hy_size = ISP32_SELF_SCALE_HY_SIZE, + .scale_hc_size = ISP32_SELF_SCALE_HC_SIZE, + .scale_hy = ISP32_SELF_SCALE_HY_FAC, + .scale_hcr = ISP32_SELF_SCALE_HC_FAC, + .scale_vy = ISP32_SELF_SCALE_VY_FAC, + .scale_vc = ISP32_SELF_SCALE_VC_FAC, + .scale_hy_shd = ISP32_SELF_SCALE_HY_FAC_SHD, + .scale_hcr_shd = ISP32_SELF_SCALE_HC_FAC_SHD, + .scale_vy_shd = ISP32_SELF_SCALE_VY_FAC_SHD, + .scale_vc_shd = ISP32_SELF_SCALE_VC_FAC_SHD, + .ctrl_shd = ISP32_SELF_SCALE_CTRL_SHD, + }, + .dual_crop = { + .ctrl = CIF_DUAL_CROP_CTRL, + .yuvmode_mask = CIF_DUAL_CROP_SP_MODE_YUV, + .rawmode_mask = CIF_DUAL_CROP_SP_MODE_RAW, + .h_offset = CIF_DUAL_CROP_S_H_OFFS, + .v_offset = CIF_DUAL_CROP_S_V_OFFS, + .h_size = CIF_DUAL_CROP_S_H_SIZE, + .v_size = CIF_DUAL_CROP_S_V_SIZE, + }, + .mi = { + .y_size_init = CIF_MI_SP_Y_SIZE_INIT, + .cb_size_init = CIF_MI_SP_CB_SIZE_INIT, + .cr_size_init = CIF_MI_SP_CR_SIZE_INIT, + .y_base_ad_init = CIF_MI_SP_Y_BASE_AD_INIT, + .cb_base_ad_init = CIF_MI_SP_CB_BASE_AD_INIT, + .cr_base_ad_init = CIF_MI_SP_CR_BASE_AD_INIT, + .y_offs_cnt_init = CIF_MI_SP_Y_OFFS_CNT_INIT, + .cb_offs_cnt_init = CIF_MI_SP_CB_OFFS_CNT_INIT, + .cr_offs_cnt_init = CIF_MI_SP_CR_OFFS_CNT_INIT, + .y_base_ad_shd = CIF_MI_SP_Y_BASE_AD_SHD, + .y_pic_size = ISP3X_MI_SP_WR_Y_PIC_SIZE, + }, +}; + +static void stream_self_update(struct rkisp_stream *stream) +{ + u32 val, mask = ISP3X_MPSELF_UPD | ISP3X_SPSELF_UPD; + + switch (stream->id) { + case RKISP_STREAM_MP: + val = ISP3X_MPSELF_UPD; + break; + case RKISP_STREAM_SP: + val = ISP3X_SPSELF_UPD; + break; + default: + return; + } + + rkisp_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL2, mask, val, true); +} + +static int get_stream_irq_mask(struct rkisp_stream *stream) +{ + int ret; + + switch (stream->id) { + case RKISP_STREAM_SP: + ret = ISP_FRAME_SP; + break; + case RKISP_STREAM_MP: + ret = ISP_FRAME_MP; + break; + default: + ret = 0; + } + + return ret; +} + +/* configure dual-crop unit */ +static int rkisp_stream_config_dcrop(struct rkisp_stream *stream, bool async) +{ + struct rkisp_device *dev = stream->ispdev; + struct v4l2_rect *dcrop = &stream->dcrop; + struct v4l2_rect *input_win; + + /* dual-crop unit get data from isp */ + input_win = rkisp_get_isp_sd_win(&dev->isp_sdev); + + if (dcrop->width == input_win->width && + dcrop->height == input_win->height && + dcrop->left == 0 && dcrop->top == 0 && + dev->unite_div < ISP_UNITE_DIV2) { + rkisp_disable_dcrop(stream, async); + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, + "stream %d crop disabled\n", stream->id); + return 0; + } + + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, + "stream %d crop: %dx%d -> %dx%d\n", stream->id, + input_win->width, input_win->height, + dcrop->width, dcrop->height); + + rkisp_config_dcrop(stream, dcrop, async); + + return 0; +} + +/* configure scale unit */ +static int rkisp_stream_config_rsz(struct rkisp_stream *stream, bool async) +{ + struct rkisp_device *dev = stream->ispdev; + struct v4l2_pix_format_mplane output_fmt = stream->out_fmt; + struct ispsd_out_fmt *input_isp_fmt = + rkisp_get_ispsd_out_fmt(&dev->isp_sdev); + struct v4l2_rect in_y, in_c, out_y, out_c; + + if (input_isp_fmt->fmt_type == FMT_BAYER) + goto disable; + + /* set input and output sizes for scale calculation + * input/output yuv422 + */ + in_y.width = stream->dcrop.width; + in_y.height = stream->dcrop.height; + in_c.width = in_y.width / 2; + in_c.height = in_y.height; + + out_y.width = output_fmt.width; + out_y.height = output_fmt.height; + out_c.width = out_y.width / 2; + out_c.height = out_y.height; + if (in_c.width == out_c.width && in_c.height == out_c.height) + goto disable; + + /* set RSZ input and output */ + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, + "stream %d rsz/scale: %dx%d -> %dx%d\n", + stream->id, stream->dcrop.width, stream->dcrop.height, + output_fmt.width, output_fmt.height); + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, + "chroma scaling %dx%d -> %dx%d\n", + in_c.width, in_c.height, out_c.width, out_c.height); + + /* calculate and set scale */ + rkisp_config_rsz(stream, &in_y, &in_c, &out_y, &out_c, async); + + return 0; + +disable: + rkisp_disable_rsz(stream, async); + + return 0; +} + +/***************************** stream operations*******************************/ + +/* + * memory base addresses should be with respect + * to the burst alignment restriction for AXI. + */ +static u32 calc_burst_len(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + u32 y_size = stream->out_fmt.plane_fmt[0].bytesperline * stream->out_fmt.height; + u32 cb_size = stream->out_fmt.plane_fmt[1].sizeimage; + u32 cr_size = stream->out_fmt.plane_fmt[2].sizeimage; + u32 cb_offs, cr_offs; + u32 bus = 16, burst; + int i; + + /* y/c base addr: burstN * bus alignment */ + cb_offs = y_size; + cr_offs = cr_size ? (cb_size + cb_offs) : 0; + + if (!(cb_offs % (bus * 16)) && !(cr_offs % (bus * 16))) + burst = CIF_MI_CTRL_BURST_LEN_LUM_16 | + CIF_MI_CTRL_BURST_LEN_CHROM_16; + else if (!(cb_offs % (bus * 8)) && !(cr_offs % (bus * 8))) + burst = CIF_MI_CTRL_BURST_LEN_LUM_8 | + CIF_MI_CTRL_BURST_LEN_CHROM_8; + else + burst = CIF_MI_CTRL_BURST_LEN_LUM_4 | + CIF_MI_CTRL_BURST_LEN_CHROM_4; + + if (cb_offs % (bus * 4) || cr_offs % (bus * 4)) + v4l2_warn(&dev->v4l2_dev, + "%dx%d fmt:0x%x not support, should be %d aligned\n", + stream->out_fmt.width, + stream->out_fmt.height, + stream->out_fmt.pixelformat, + (cr_offs == 0) ? bus * 4 : bus * 16); + + stream->burst = burst; + for (i = 0; i <= RKISP_STREAM_SP; i++) + if (burst > dev->cap_dev.stream[i].burst) + burst = dev->cap_dev.stream[i].burst; + + if (stream->interlaced) { + if (!stream->out_fmt.width % (bus * 16)) + stream->burst = CIF_MI_CTRL_BURST_LEN_LUM_16 | + CIF_MI_CTRL_BURST_LEN_CHROM_16; + else if (!stream->out_fmt.width % (bus * 8)) + stream->burst = CIF_MI_CTRL_BURST_LEN_LUM_8 | + CIF_MI_CTRL_BURST_LEN_CHROM_8; + else + stream->burst = CIF_MI_CTRL_BURST_LEN_LUM_4 | + CIF_MI_CTRL_BURST_LEN_CHROM_4; + if (stream->out_fmt.width % (bus * 4)) + v4l2_warn(&dev->v4l2_dev, + "interlaced: width should be %d aligned\n", + bus * 4); + burst = min(stream->burst, burst); + stream->burst = burst; + } + + return burst; +} + +/* + * configure memory interface for mainpath + * This should only be called when stream-on + */ +static int mp_config_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct capture_fmt *fmt = &stream->out_isp_fmt; + struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; + u32 val, mask, height = out_fmt->height; + + /* + * NOTE: plane_fmt[0].sizeimage is total size of all planes for single + * memory plane formats, so calculate the size explicitly. + */ + if (dev->cap_dev.wrap_line) { + height = dev->cap_dev.wrap_line; + rkisp_unite_clear_bits(dev, ISP32_MI_WR_WRAP_CTRL, BIT(0), false); + } + val = out_fmt->plane_fmt[0].bytesperline; + if (fmt->fmt_type != FMT_TILE) + val /= DIV_ROUND_UP(fmt->bpp[0], 8); + else + height /= 4; + rkisp_unite_write(dev, ISP3X_MI_MP_WR_Y_LLENGTH, val, false); + val *= height; + rkisp_unite_write(dev, stream->config->mi.y_pic_size, val, false); + val = out_fmt->plane_fmt[0].bytesperline * height; + rkisp_unite_write(dev, stream->config->mi.y_size_init, val, false); + + val = out_fmt->plane_fmt[1].sizeimage; + if (dev->cap_dev.wrap_line) + val = out_fmt->plane_fmt[0].bytesperline * height / 2; + rkisp_unite_write(dev, stream->config->mi.cb_size_init, val, false); + + val = out_fmt->plane_fmt[2].sizeimage; + if (dev->cap_dev.wrap_line) + val = out_fmt->plane_fmt[0].bytesperline * height / 2; + rkisp_unite_write(dev, stream->config->mi.cr_size_init, val, false); + + val = stream->out_isp_fmt.uv_swap ? ISP3X_MI_XTD_FORMAT_MP_UV_SWAP : 0; + mask = ISP3X_MI_XTD_FORMAT_MP_UV_SWAP; + rkisp_unite_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false); + + mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_MP_YUV_MODE; + val = rkisp_read_reg_cache(dev, ISP3X_MPFBC_CTRL) & ~mask; + if (stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV21 || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV12 || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV21M || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV12M || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_YUV420 || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_TILE420) + val |= ISP3X_SEPERATE_YUV_CFG; + else + val |= ISP3X_SEPERATE_YUV_CFG | ISP3X_MP_YUV_MODE; + rkisp_unite_write(dev, ISP3X_MPFBC_CTRL, val, false); + + val = stream->out_isp_fmt.output_format; + rkisp_unite_write(dev, ISP32_MI_MP_WR_CTRL, val, false); + + val = calc_burst_len(stream) | CIF_MI_CTRL_INIT_BASE_EN | + CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_MP_AUTOUPDATE_ENABLE | + stream->out_isp_fmt.write_format; + mask = GENMASK(19, 16) | MI_CTRL_MP_FMT_MASK; + rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false); + + mi_frame_end_int_enable(stream); + /* set up first buffer */ + mi_frame_end(stream, FRAME_INIT); + + rkisp_unite_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); + rkisp_unite_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); + rkisp_unite_write(dev, stream->config->mi.cr_offs_cnt_init, 0, false); + return 0; +} + +static int mbus_code_sp_in_fmt(u32 in_mbus_code, u32 out_fourcc, u32 *format) +{ + switch (in_mbus_code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + *format = MI_CTRL_SP_INPUT_YUV422; + break; + default: + return -EINVAL; + } + + /* + * Only SP can support output format of YCbCr4:0:0, + * and the input format of SP must be YCbCr4:0:0 + * when outputting YCbCr4:0:0. + * The output format of isp is YCbCr4:2:2, + * so the CbCr data is discarded here. + */ + if (out_fourcc == V4L2_PIX_FMT_GREY) + *format = MI_CTRL_SP_INPUT_YUV400; + + return 0; +} + +/* + * configure memory interface for selfpath + * This should only be called when stream-on + */ +static int sp_config_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; + struct capture_fmt *fmt = &stream->out_isp_fmt; + struct ispsd_out_fmt *input_isp_fmt = + rkisp_get_ispsd_out_fmt(&dev->isp_sdev); + u32 sp_in_fmt, val, mask; + + if (mbus_code_sp_in_fmt(input_isp_fmt->mbus_code, + out_fmt->pixelformat, &sp_in_fmt)) { + v4l2_err(&dev->v4l2_dev, "Can't find the input format\n"); + return -EINVAL; + } + + /* + * NOTE: plane_fmt[0].sizeimage is total size of all planes for single + * memory plane formats, so calculate the size explicitly. + */ + val = out_fmt->plane_fmt[0].bytesperline; + val /= DIV_ROUND_UP(fmt->bpp[0], 8); + rkisp_unite_write(dev, ISP3X_MI_SP_WR_Y_LLENGTH, val, false); + val *= out_fmt->height; + rkisp_unite_write(dev, stream->config->mi.y_pic_size, val, false); + val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height; + rkisp_unite_write(dev, stream->config->mi.y_size_init, val, false); + + val = out_fmt->plane_fmt[1].sizeimage; + rkisp_unite_write(dev, stream->config->mi.cb_size_init, val, false); + + val = out_fmt->plane_fmt[2].sizeimage; + rkisp_unite_write(dev, stream->config->mi.cr_size_init, val, false); + + val = stream->out_isp_fmt.uv_swap ? ISP3X_MI_XTD_FORMAT_SP_UV_SWAP : 0; + mask = ISP3X_MI_XTD_FORMAT_SP_UV_SWAP; + rkisp_unite_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false); + + mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_SP_YUV_MODE; + val = rkisp_read_reg_cache(dev, ISP3X_MPFBC_CTRL) & ~mask; + if (stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV21 || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV12 || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV21M || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV12M || + stream->out_fmt.pixelformat == V4L2_PIX_FMT_YUV420) + val |= ISP3X_SEPERATE_YUV_CFG; + else + val |= ISP3X_SEPERATE_YUV_CFG | ISP3X_SP_YUV_MODE; + rkisp_unite_write(dev, ISP3X_MPFBC_CTRL, val, false); + + val = calc_burst_len(stream) | CIF_MI_CTRL_INIT_BASE_EN | + CIF_MI_CTRL_INIT_OFFSET_EN | stream->out_isp_fmt.write_format | + sp_in_fmt | stream->out_isp_fmt.output_format | + CIF_MI_SP_AUTOUPDATE_ENABLE; + mask = GENMASK(19, 16) | MI_CTRL_SP_FMT_MASK; + rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false); + + mi_frame_end_int_enable(stream); + /* set up first buffer */ + mi_frame_end(stream, FRAME_INIT); + + rkisp_unite_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); + rkisp_unite_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); + rkisp_unite_write(dev, stream->config->mi.cr_offs_cnt_init, 0, false); + return 0; +} + +static void mp_enable_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + u32 mask = CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE; + u32 val = CIF_MI_CTRL_MP_ENABLE; + + rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false); +} + +static void sp_enable_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct capture_fmt *fmt = &stream->out_isp_fmt; + u32 val = CIF_MI_CTRL_SP_ENABLE; + u32 mask = CIF_MI_SP_Y_FULL_YUV2RGB | CIF_MI_SP_CBCR_FULL_YUV2RGB; + + if (fmt->fmt_type == FMT_RGB && + dev->isp_sdev.quantization == V4L2_QUANTIZATION_FULL_RANGE) + val |= mask; + rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false); +} + +static void mp_disable_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + u32 mask = CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE; + + rkisp_unite_clear_bits(dev, ISP3X_MI_WR_CTRL, mask, false); +} + +static void sp_disable_mi(struct rkisp_stream *stream) +{ + rkisp_unite_clear_bits(stream->ispdev, ISP3X_MI_WR_CTRL, CIF_MI_CTRL_SP_ENABLE, false); +} + +static void update_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct rkisp_dummy_buffer *dummy_buf = &stream->dummy_buf; + struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; + u32 div = stream->out_isp_fmt.fourcc == V4L2_PIX_FMT_UYVY ? 1 : 2; + u32 val, reg; + + if (stream->next_buf) { + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + rkisp_write(dev, reg, val, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + rkisp_write(dev, reg, val, false); + + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + rkisp_write(dev, reg, val, false); + + if (dev->unite_div > ISP_UNITE_DIV1) { + /* right of image, or right top of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); + + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); + } + + if (stream->is_pause) { + /* single sensor mode with pingpong buffer: + * if mi on, addr will auto update at frame end + * else addr need update by SELF_UPD. + * + * multi sensor mode with single buffer: + * mi and buffer will update by readback. + */ + stream->ops->enable_mi(stream); + if (dev->hw_dev->is_single && + stream->ops->is_stream_stopped(stream)) { + /* isp no start and mi close, force to enable it */ + stream_self_update(stream); + if (!stream->ops->is_stream_stopped(stream)) { + if (!stream->curr_buf) { + stream->curr_buf = stream->next_buf; + stream->next_buf = NULL; + } + /* maybe no next buf to preclose mi */ + stream->ops->disable_mi(stream); + } else { + /* isp working and mi closed + * config buf and enable mi, capture at next frame + */ + stream->is_pause = false; + } + } else { + /* isp working and mi no to close + * config buf will auto update at frame end + */ + stream->is_pause = false; + } + } + + /* single buf force updated at readback for multidevice */ + if (!dev->hw_dev->is_single) { + stream->curr_buf = stream->next_buf; + stream->next_buf = NULL; + } + } else if (dummy_buf->mem_priv) { + val = dummy_buf->dma_addr; + reg = stream->config->mi.y_base_ad_init; + rkisp_unite_write(dev, reg, val, false); + val += stream->out_fmt.plane_fmt[0].bytesperline * dev->cap_dev.wrap_line; + reg = stream->config->mi.cb_base_ad_init; + rkisp_unite_write(dev, reg, val, false); + reg = stream->config->mi.cr_base_ad_init; + rkisp_unite_write(dev, reg, val, false); + } else if (!stream->is_pause) { + stream->is_pause = true; + /* no next buf to preclose mi */ + stream->ops->disable_mi(stream); + /* no buf, force to close mi */ + if (!stream->curr_buf && dev->hw_dev->is_single) + stream_self_update(stream); + } + + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, + "%s stream:%d cur:%p next:%p Y:0x%x CB:0x%x | Y_SHD:0x%x pause:%d stop:%d\n", + __func__, stream->id, stream->curr_buf, stream->next_buf, + rkisp_read(dev, stream->config->mi.y_base_ad_init, false), + rkisp_read(dev, stream->config->mi.cb_base_ad_init, false), + rkisp_read(dev, stream->config->mi.y_base_ad_shd, true), + stream->is_pause, stream->ops->is_stream_stopped(stream)); +} + +static int mp_set_wrap(struct rkisp_stream *stream, int line) +{ + struct rkisp_device *dev = stream->ispdev; + + dev->cap_dev.wrap_line = line; + return 0; +} + +static struct streams_ops rkisp_mp_streams_ops = { + .config_mi = mp_config_mi, + .enable_mi = mp_enable_mi, + .disable_mi = mp_disable_mi, + .set_data_path = stream_data_path, + .is_stream_stopped = mp_is_stream_stopped, + .update_mi = update_mi, + .frame_end = mi_frame_end, + .frame_start = mi_frame_start, + .set_wrap = mp_set_wrap, +}; + +static struct streams_ops rkisp_sp_streams_ops = { + .config_mi = sp_config_mi, + .enable_mi = sp_enable_mi, + .disable_mi = sp_disable_mi, + .set_data_path = stream_data_path, + .is_stream_stopped = sp_is_stream_stopped, + .update_mi = update_mi, + .frame_end = mi_frame_end, + .frame_start = mi_frame_start, +}; + +static int mi_frame_start(struct rkisp_stream *stream, u32 irq) +{ + struct rkisp_device *dev = stream->ispdev; + unsigned long lock_flags = 0; + + /* readback start to update stream buf if null */ + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + if (stream->streaming) { + /* only dynamic clipping and scaling at readback */ + if (!irq && stream->is_crop_upd) { + rkisp_stream_config_dcrop(stream, false); + rkisp_stream_config_rsz(stream, false); + stream->is_crop_upd = false; + } + if (!list_empty(&stream->buf_queue) && + ((dev->hw_dev->is_single && !stream->next_buf) || + (!dev->hw_dev->is_single && !stream->curr_buf))) { + stream->next_buf = list_first_entry(&stream->buf_queue, + struct rkisp_buffer, queue); + list_del(&stream->next_buf->queue); + stream->ops->update_mi(stream); + } else if (dev->hw_dev->is_single && + stream->next_buf && !stream->curr_buf) { + if (stream->ops->is_stream_stopped(stream)) { + stream->ops->enable_mi(stream); + stream_self_update(stream); + } + if (!stream->ops->is_stream_stopped(stream)) { + stream->curr_buf = stream->next_buf; + stream->next_buf = NULL; + if (!list_empty(&stream->buf_queue)) { + stream->next_buf = list_first_entry(&stream->buf_queue, + struct rkisp_buffer, queue); + list_del(&stream->next_buf->queue); + } + stream->ops->update_mi(stream); + } + } + /* check frame loss */ + if (stream->ops->is_stream_stopped(stream)) + stream->dbg.frameloss++; + } + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + + return 0; +} + +/* + * This function is called when a frame end come. The next frame + * is processing and we should set up buffer for next-next frame, + * otherwise it will overflow. + */ +static int mi_frame_end(struct rkisp_stream *stream, u32 state) +{ + struct rkisp_device *dev = stream->ispdev; + struct capture_fmt *isp_fmt = &stream->out_isp_fmt; + unsigned long lock_flags = 0; + struct rkisp_buffer *buf = NULL; + u32 i; + + /* STREAM_VIR or STREAM_MP wrap buf from rockit */ + if (stream->id == RKISP_STREAM_VIR || + (stream->id == RKISP_STREAM_MP && dev->cap_dev.wrap_line && + !stream->dummy_buf.mem_priv && stream->dummy_buf.dbuf)) + return 0; + + if (dev->cap_dev.is_done_early && + (state == FRAME_IRQ || state == FRAME_WORK)) { + /* skip mainpath wrap mode */ + if (stream->id == RKISP_STREAM_MP && dev->cap_dev.wrap_line) + return 0; + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + if (state == FRAME_IRQ && stream->curr_buf) + stream->frame_early = false; + else + stream->frame_early = true; + buf = stream->curr_buf; + stream->curr_buf = NULL; + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + if ((!stream->frame_early && state == FRAME_WORK) || + (stream->frame_early && state == FRAME_IRQ)) + goto end; + } else { + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + buf = stream->curr_buf; + stream->curr_buf = NULL; + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + } + + if (buf) { + struct vb2_buffer *vb2_buf = &buf->vb.vb2_buf; + struct rkisp_stream *vir = &dev->cap_dev.stream[RKISP_STREAM_VIR]; + u64 ns = 0; + + if (dev->skip_frame || stream->skip_frame) { + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + list_add_tail(&buf->queue, &stream->buf_queue); + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + if (stream->skip_frame) + stream->skip_frame--; + goto end; + } + + for (i = 0; i < isp_fmt->mplanes; i++) { + u32 payload_size = stream->out_fmt.plane_fmt[i].sizeimage; + + vb2_set_plane_payload(vb2_buf, i, payload_size); + } + + rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true); + if (!ns) + ns = rkisp_time_get_ns(dev); + buf->vb.sequence = i; + vb2_buf->timestamp = ns; + ns = rkisp_time_get_ns(dev); + stream->dbg.interval = ns - stream->dbg.timestamp; + stream->dbg.delay = ns - vb2_buf->timestamp; + stream->dbg.timestamp = ns; + stream->dbg.id = i; + + if (vir->streaming && vir->conn_id == stream->id) { + spin_lock_irqsave(&vir->vbq_lock, lock_flags); + list_add_tail(&buf->queue, &dev->cap_dev.vir_cpy.queue); + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); + if (!completion_done(&dev->cap_dev.vir_cpy.cmpl)) + complete(&dev->cap_dev.vir_cpy.cmpl); + } else { + if (vb2_buf->memory) + rkisp_stream_buf_done(stream, buf); + else + rkisp_rockit_buf_done(stream, ROCKIT_DVBM_END, buf); + } + } + +end: + if (state == FRAME_WORK) + return 0; + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + if (stream->next_buf) { + stream->curr_buf = stream->next_buf; + stream->next_buf = NULL; + } + if (!list_empty(&stream->buf_queue)) { + stream->next_buf = list_first_entry(&stream->buf_queue, + struct rkisp_buffer, queue); + list_del(&stream->next_buf->queue); + } + stream->ops->update_mi(stream); + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + return 0; +} + +/***************************** vb2 operations*******************************/ + +/* + * Set flags and wait, it should stop in interrupt. + * If it didn't, stop it by force. + */ +static void rkisp_stream_stop(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct v4l2_device *v4l2_dev = &dev->v4l2_dev; + unsigned long lock_flags = 0; + int ret = 0; + bool is_wait = dev->hw_dev->is_shutdown ? false : true; + + stream->stopping = true; + stream->is_pause = false; + if (stream->ops->disable_mi && dev->hw_dev->is_single) + stream->ops->disable_mi(stream); + if (IS_HDR_RDBK(dev->rd_mode)) { + spin_lock_irqsave(&dev->hw_dev->rdbk_lock, lock_flags); + if (dev->hw_dev->cur_dev_id != dev->dev_id || dev->hw_dev->is_idle) { + is_wait = false; + if (stream->ops->disable_mi) + stream->ops->disable_mi(stream); + /* force update to close */ + if (dev->hw_dev->is_single) + stream_self_update(stream); + } + if (atomic_read(&dev->cap_dev.refcnt) == 1 && !is_wait) + dev->isp_state = ISP_STOP; + spin_unlock_irqrestore(&dev->hw_dev->rdbk_lock, lock_flags); + } + if (is_wait && !stream->ops->is_stream_stopped(stream)) { + ret = wait_event_timeout(stream->done, + !stream->streaming, + msecs_to_jiffies(500)); + if (!ret) + v4l2_warn(v4l2_dev, "%s id:%d timeout\n", + __func__, stream->id); + } + + stream->stopping = false; + stream->streaming = false; + if (stream->ops->disable_mi) + stream->ops->disable_mi(stream); + if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) { + rkisp_disable_dcrop(stream, true); + rkisp_disable_rsz(stream, true); + } + ret = get_stream_irq_mask(stream); + dev->irq_ends_mask &= ~ret; + + stream->burst = + CIF_MI_CTRL_BURST_LEN_LUM_16 | + CIF_MI_CTRL_BURST_LEN_CHROM_16; + stream->interlaced = false; +} + +/* + * Most of registers inside rockchip isp1 have shadow register since + * they must be not changed during processing a frame. + * Usually, each sub-module updates its shadow register after + * processing the last pixel of a frame. + */ +static int rkisp_start(struct rkisp_stream *stream) +{ + int ret; + + stream->is_pause = false; + if (stream->ops->set_data_path) + stream->ops->set_data_path(stream); + if (stream->ops->config_mi) { + ret = stream->ops->config_mi(stream); + if (ret) + return ret; + } + if (stream->ops->enable_mi && !stream->is_pause) + stream->ops->enable_mi(stream); + + stream->streaming = true; + stream->skip_frame = 0; + return 0; +} + +static int rkisp_queue_setup(struct vb2_queue *queue, + unsigned int *num_buffers, + unsigned int *num_planes, + unsigned int sizes[], + struct device *alloc_ctxs[]) +{ + struct rkisp_stream *stream = queue->drv_priv; + struct rkisp_device *dev = stream->ispdev; + const struct v4l2_pix_format_mplane *pixm = NULL; + const struct capture_fmt *isp_fmt = NULL; + u32 i; + + pixm = &stream->out_fmt; + isp_fmt = &stream->out_isp_fmt; + *num_planes = isp_fmt->mplanes; + + for (i = 0; i < isp_fmt->mplanes; i++) { + const struct v4l2_plane_pix_format *plane_fmt; + u32 height = pixm->height; + + if (dev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) + height = dev->cap_dev.wrap_line; + plane_fmt = &pixm->plane_fmt[i]; + /* height to align with 16 when allocating memory + * so that Rockchip encoder can use DMA buffer directly + */ + sizes[i] = (isp_fmt->fmt_type == FMT_YUV) ? + plane_fmt->sizeimage / height * + ALIGN(height, 16) : + plane_fmt->sizeimage; + } + + rkisp_chk_tb_over(dev); + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s %s count %d, size %d\n", + stream->vnode.vdev.name, v4l2_type_names[queue->type], *num_buffers, sizes[0]); + + return 0; +} + +/* + * The vb2_buffer are stored in rkisp_buffer, in order to unify + * mplane buffer and none-mplane buffer. + */ +static void rkisp_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rkisp_buffer *ispbuf = to_rkisp_buffer(vbuf); + struct vb2_queue *queue = vb->vb2_queue; + struct rkisp_stream *stream = queue->drv_priv; + struct rkisp_device *dev = stream->ispdev; + struct v4l2_pix_format_mplane *pixm = &stream->out_fmt; + struct capture_fmt *isp_fmt = &stream->out_isp_fmt; + unsigned long lock_flags = 0; + struct sg_table *sgt; + u32 height, offset; + int i; + + memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr)); + for (i = 0; i < isp_fmt->mplanes; i++) { + ispbuf->vaddr[i] = vb2_plane_vaddr(vb, i); + if (rkisp_buf_dbg && ispbuf->vaddr[i]) { + u64 *data = ispbuf->vaddr[i]; + + *data = RKISP_DATA_CHECK; + } + if (stream->ispdev->hw_dev->is_dma_sg_ops) { + sgt = vb2_dma_sg_plane_desc(vb, i); + ispbuf->buff_addr[i] = sg_dma_address(sgt->sgl); + } else { + ispbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i); + } + } + /* + * NOTE: plane_fmt[0].sizeimage is total size of all planes for single + * memory plane formats, so calculate the size explicitly. + */ + if (isp_fmt->mplanes == 1) { + for (i = 0; i < isp_fmt->cplanes - 1; i++) { + height = pixm->height; + if (dev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) + height = dev->cap_dev.wrap_line; + offset = (i == 0) ? + pixm->plane_fmt[i].bytesperline * height : + pixm->plane_fmt[i].sizeimage; + ispbuf->buff_addr[i + 1] = + ispbuf->buff_addr[i] + offset; + } + } + + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, + "stream:%d queue buf:0x%x\n", + stream->id, ispbuf->buff_addr[0]); + + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + list_add_tail(&ispbuf->queue, &stream->buf_queue); + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); +} + +static int rkisp_create_dummy_buf(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct rkisp_dummy_buffer *buf = &stream->dummy_buf; + int ret = 0; + + /* mainpath for warp default */ + if (!dev->cap_dev.wrap_line || stream->id != RKISP_STREAM_MP) + return 0; + + if (!buf->dbuf) { + buf->size = dev->cap_dev.wrap_width * dev->cap_dev.wrap_line * 2; + if (stream->out_isp_fmt.output_format == ISP32_MI_OUTPUT_YUV420) + buf->size = buf->size - buf->size / 4; + buf->is_need_dbuf = true; + ret = rkisp_alloc_buffer(stream->ispdev, buf); + } + if (ret == 0) { + ret = rkisp_dvbm_init(stream); + if (ret < 0) + rkisp_free_buffer(dev, buf); + } + + return ret; +} + +static void rkisp_destroy_dummy_buf(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + + if (!dev->cap_dev.wrap_line || stream->id != RKISP_STREAM_MP) + return; + rkisp_dvbm_deinit(dev); + rkisp_free_buffer(dev, &stream->dummy_buf); + stream->dummy_buf.dma_addr = 0; +} + +static void destroy_buf_queue(struct rkisp_stream *stream, + enum vb2_buffer_state state) +{ + unsigned long lock_flags = 0; + struct rkisp_buffer *buf; + + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + if (stream->curr_buf) { + list_add_tail(&stream->curr_buf->queue, &stream->buf_queue); + if (stream->curr_buf == stream->next_buf) + stream->next_buf = NULL; + stream->curr_buf = NULL; + } + if (stream->next_buf) { + list_add_tail(&stream->next_buf->queue, &stream->buf_queue); + stream->next_buf = NULL; + } + while (!list_empty(&stream->buf_queue)) { + buf = list_first_entry(&stream->buf_queue, + struct rkisp_buffer, queue); + list_del(&buf->queue); + if (buf->vb.vb2_buf.memory) + vb2_buffer_done(&buf->vb.vb2_buf, state); + } + while (!list_empty(&stream->buf_done_list)) { + buf = list_first_entry(&stream->buf_done_list, + struct rkisp_buffer, queue); + list_del(&buf->queue); + if (buf->vb.vb2_buf.memory) + vb2_buffer_done(&buf->vb.vb2_buf, state); + } + rkisp_rockit_buf_state_clear(stream); + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + rkisp_rockit_buf_free(stream); +} + +static void rkisp_stop_streaming(struct vb2_queue *queue) +{ + struct rkisp_stream *stream = queue->drv_priv; + struct rkisp_vdev_node *node = &stream->vnode; + struct rkisp_device *dev = stream->ispdev; + struct v4l2_device *v4l2_dev = &dev->v4l2_dev; + int ret; + + mutex_lock(&dev->hw_dev->dev_lock); + + v4l2_dbg(1, rkisp_debug, v4l2_dev, "%s %s %d\n", + __func__, node->vdev.name, stream->id); + + if (!stream->streaming) + goto end; + + if (stream->id == RKISP_STREAM_VIR) { + stream->stopping = true; + if (!dev->hw_dev->is_shutdown) + wait_event_timeout(stream->done, + stream->frame_end, + msecs_to_jiffies(500)); + stream->streaming = false; + stream->stopping = false; + destroy_buf_queue(stream, VB2_BUF_STATE_ERROR); + if (!completion_done(&dev->cap_dev.vir_cpy.cmpl)) { + complete(&dev->cap_dev.vir_cpy.cmpl); + stream->conn_id = -1; + } + goto end; + } + + rkisp_stream_stop(stream); + /* call to the other devices */ + video_device_pipeline_stop(&node->vdev); + ret = dev->pipe.set_stream(&dev->pipe, false); + if (ret < 0) + v4l2_err(v4l2_dev, "pipeline stream-off failed:%d\n", ret); + + /* release buffers */ + destroy_buf_queue(stream, VB2_BUF_STATE_ERROR); + + ret = dev->pipe.close(&dev->pipe); + if (ret < 0) + v4l2_err(v4l2_dev, "pipeline close failed error:%d\n", ret); + rkisp_destroy_dummy_buf(stream); + atomic_dec(&dev->cap_dev.refcnt); + tasklet_disable(&stream->buf_done_tasklet); +end: + mutex_unlock(&dev->hw_dev->dev_lock); + + if (dev->is_pre_on && stream->id == RKISP_STREAM_MP) { + dev->is_pre_on = false; + dev->params_vdev.first_cfg_params = false; + v4l2_pipeline_pm_put(&stream->vnode.vdev.entity); + } +} + +static int rkisp_stream_start(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct v4l2_device *v4l2_dev = &dev->v4l2_dev; + bool async = (dev->isp_state & ISP_STOP) ? false : true; + int ret; + + /* + * can't be async now, otherwise the latter started stream fails to + * produce mi interrupt. + */ + ret = rkisp_stream_config_dcrop(stream, false); + if (ret < 0) { + v4l2_err(v4l2_dev, "config dcrop failed with error %d\n", ret); + return ret; + } + + ret = rkisp_stream_config_rsz(stream, async); + if (ret < 0) { + v4l2_err(v4l2_dev, "config rsz failed with error %d\n", ret); + return ret; + } + + return rkisp_start(stream); +} + +static int +rkisp_start_streaming(struct vb2_queue *queue, unsigned int count) +{ + struct rkisp_stream *stream = queue->drv_priv; + struct rkisp_vdev_node *node = &stream->vnode; + struct rkisp_device *dev = stream->ispdev; + struct v4l2_device *v4l2_dev = &dev->v4l2_dev; + int ret = -EINVAL; + + mutex_lock(&dev->hw_dev->dev_lock); + if (dev->is_pre_on && + !dev->hw_dev->is_single && + !atomic_read(&dev->hw_dev->refcnt) && + !atomic_read(&dev->cap_dev.refcnt)) + rkisp_hw_enum_isp_size(dev->hw_dev); + + v4l2_dbg(1, rkisp_debug, v4l2_dev, "%s %s id:%d\n", + __func__, node->vdev.name, stream->id); + + if (WARN_ON(stream->streaming)) { + mutex_unlock(&dev->hw_dev->dev_lock); + return -EBUSY; + } + + if (stream->id == RKISP_STREAM_VIR) { + struct rkisp_stream *t = &dev->cap_dev.stream[stream->conn_id]; + + if (t->streaming) { + INIT_WORK(&dev->cap_dev.vir_cpy.work, rkisp_stream_vir_cpy_image); + init_completion(&dev->cap_dev.vir_cpy.cmpl); + INIT_LIST_HEAD(&dev->cap_dev.vir_cpy.queue); + dev->cap_dev.vir_cpy.stream = stream; + schedule_work(&dev->cap_dev.vir_cpy.work); + ret = 0; + } else { + v4l2_err(&dev->v4l2_dev, "no stream enable for iqtool\n"); + destroy_buf_queue(stream, VB2_BUF_STATE_QUEUED); + ret = -EINVAL; + } + mutex_unlock(&dev->hw_dev->dev_lock); + return ret; + } + + memset(&stream->dbg, 0, sizeof(stream->dbg)); + + atomic_inc(&dev->cap_dev.refcnt); + if (!dev->isp_inp || !stream->linked) { + v4l2_err(v4l2_dev, "check %s link or isp input\n", node->vdev.name); + goto buffer_done; + } + + if (atomic_read(&dev->cap_dev.refcnt) == 1 && + (dev->isp_inp & INP_CIF)) { + /* update sensor info when first streaming */ + ret = rkisp_update_sensor_info(dev); + if (ret < 0) { + v4l2_err(v4l2_dev, "update sensor info failed %d\n", ret); + goto buffer_done; + } + } + + ret = rkisp_create_dummy_buf(stream); + if (ret < 0) + goto buffer_done; + + if (count == 0 && !stream->dummy_buf.dbuf && + list_empty(&stream->buf_queue)) { + v4l2_err(v4l2_dev, "no buf for %s\n", node->vdev.name); + ret = -EINVAL; + goto buffer_done; + } + + /* enable clocks/power-domains */ + ret = dev->pipe.open(&dev->pipe, &node->vdev.entity, true); + if (ret < 0) { + v4l2_err(v4l2_dev, "open isp pipeline failed %d\n", ret); + goto destroy_dummy_buf; + } + + /* configure stream hardware to start */ + ret = rkisp_stream_start(stream); + if (ret < 0) { + v4l2_err(v4l2_dev, "start %s failed\n", node->vdev.name); + goto close_pipe; + } + + /* start sub-devices */ + ret = dev->pipe.set_stream(&dev->pipe, true); + if (ret < 0) + goto stop_stream; + + ret = video_device_pipeline_start(&node->vdev, &dev->pipe.pipe); + if (ret < 0) { + v4l2_err(v4l2_dev, "start pipeline failed %d\n", ret); + goto pipe_stream_off; + } + tasklet_enable(&stream->buf_done_tasklet); + mutex_unlock(&dev->hw_dev->dev_lock); + return 0; + +pipe_stream_off: + dev->pipe.set_stream(&dev->pipe, false); +stop_stream: + rkisp_stream_stop(stream); +close_pipe: + dev->pipe.close(&dev->pipe); +destroy_dummy_buf: + rkisp_destroy_dummy_buf(stream); +buffer_done: + destroy_buf_queue(stream, VB2_BUF_STATE_QUEUED); + atomic_dec(&dev->cap_dev.refcnt); + stream->streaming = false; + mutex_unlock(&dev->hw_dev->dev_lock); + return ret; +} + +static const struct vb2_ops rkisp_vb2_ops = { + .queue_setup = rkisp_queue_setup, + .buf_queue = rkisp_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = rkisp_stop_streaming, + .start_streaming = rkisp_start_streaming, +}; + +static int rkisp_init_vb2_queue(struct vb2_queue *q, + struct rkisp_stream *stream, + enum v4l2_buf_type buf_type) +{ + q->type = buf_type; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + q->drv_priv = stream; + q->ops = &rkisp_vb2_ops; + q->mem_ops = stream->ispdev->hw_dev->mem_ops; + q->buf_struct_size = sizeof(struct rkisp_buffer); + q->min_buffers_needed = CIF_ISP_REQ_BUFS_MIN; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &stream->apilock; + q->dev = stream->ispdev->hw_dev->dev; + q->allow_cache_hints = 1; + q->bidirectional = 1; + if (stream->ispdev->hw_dev->is_dma_contig) + q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS; + q->gfp_flags = GFP_DMA32; + return vb2_queue_init(q); +} + +static int rkisp_stream_init(struct rkisp_device *dev, u32 id) +{ + struct rkisp_capture_device *cap_dev = &dev->cap_dev; + struct rkisp_stream *stream; + struct video_device *vdev; + struct rkisp_vdev_node *node; + int ret = 0; + + stream = &cap_dev->stream[id]; + stream->id = id; + stream->ispdev = dev; + vdev = &stream->vnode.vdev; + + INIT_LIST_HEAD(&stream->buf_queue); + init_waitqueue_head(&stream->done); + spin_lock_init(&stream->vbq_lock); + stream->linked = true; + + switch (id) { + case RKISP_STREAM_SP: + strscpy(vdev->name, SP_VDEV_NAME, sizeof(vdev->name)); + stream->ops = &rkisp_sp_streams_ops; + stream->config = &rkisp_sp_stream_cfg; + break; + case RKISP_STREAM_VIR: + strscpy(vdev->name, VIR_VDEV_NAME, sizeof(vdev->name)); + stream->ops = NULL; + stream->config = &rkisp_mp_stream_cfg; + stream->conn_id = -1; + break; + default: + strscpy(vdev->name, MP_VDEV_NAME, sizeof(vdev->name)); + stream->ops = &rkisp_mp_streams_ops; + stream->config = &rkisp_mp_stream_cfg; + } + + rockit_isp_ops.rkisp_stream_start = rkisp_stream_start; + rockit_isp_ops.rkisp_stream_stop = rkisp_stream_stop; + + node = vdev_to_node(vdev); + rkisp_init_vb2_queue(&node->buf_queue, stream, + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + ret = rkisp_register_stream_vdev(stream); + if (ret < 0) + return ret; + + stream->streaming = false; + stream->interlaced = false; + stream->burst = + CIF_MI_CTRL_BURST_LEN_LUM_16 | + CIF_MI_CTRL_BURST_LEN_CHROM_16; + atomic_set(&stream->sequence, 0); + return 0; +} + +int rkisp_register_stream_v35(struct rkisp_device *dev) +{ + struct rkisp_capture_device *cap_dev = &dev->cap_dev; + int ret; + + ret = rkisp_stream_init(dev, RKISP_STREAM_MP); + if (ret < 0) + goto err; + ret = rkisp_stream_init(dev, RKISP_STREAM_SP); + if (ret < 0) + goto err_free_mp; + ret = rkisp_stream_init(dev, RKISP_STREAM_VIR); + if (ret < 0) + goto err_free_sp; + rkisp_dvbm_get(dev); + rkisp_rockit_dev_init(dev); + return 0; +err_free_sp: + rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_SP]); +err_free_mp: + rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_MP]); +err: + return ret; +} + +void rkisp_unregister_stream_v35(struct rkisp_device *dev) +{ + struct rkisp_capture_device *cap_dev = &dev->cap_dev; + struct rkisp_stream *stream; + + stream = &cap_dev->stream[RKISP_STREAM_MP]; + rkisp_unregister_stream_vdev(stream); + stream = &cap_dev->stream[RKISP_STREAM_SP]; + rkisp_unregister_stream_vdev(stream); + stream = &cap_dev->stream[RKISP_STREAM_VIR]; + rkisp_unregister_stream_vdev(stream); + rkisp_rockit_dev_deinit(); +} + +/**************** Interrupter Handler ****************/ + +void rkisp_mi_v35_isr(u32 mis_val, struct rkisp_device *dev) +{ + struct rkisp_stream *stream; + unsigned int i, seq; + u64 ns = 0; + + v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, + "mi isr:0x%x\n", mis_val); + + if ((dev->unite_div == ISP_UNITE_DIV2 && dev->unite_index != ISP_UNITE_RIGHT) || + (dev->unite_div == ISP_UNITE_DIV4 && dev->unite_index != ISP_UNITE_RIGHT_B)) { + rkisp_write(dev, ISP3X_MI_ICR, mis_val, true); + goto end; + } + + for (i = 0; i <= RKISP_STREAM_SP; ++i) { + stream = &dev->cap_dev.stream[i]; + + if (!(mis_val & CIF_MI_FRAME(stream))) + continue; + + mi_frame_end_int_clear(stream); + + if (i == RKISP_STREAM_MP) + rkisp_dvbm_event(dev, CIF_MI_MP_FRAME); + + if (stream->stopping) { + /* + * Make sure stream is actually stopped, whose state + * can be read from the shadow register, before + * wake_up() thread which would immediately free all + * frame buffers. disable_mi() takes effect at the next + * frame end that sync the configurations to shadow + * regs. + */ + if (!dev->hw_dev->is_single) { + stream->stopping = false; + stream->streaming = false; + stream->ops->disable_mi(stream); + wake_up(&stream->done); + } else if (stream->ops->is_stream_stopped(stream)) { + stream->stopping = false; + stream->streaming = false; + wake_up(&stream->done); + } + } else if (stream->id == RKISP_STREAM_MP && dev->cap_dev.wrap_line) { + ns = rkisp_time_get_ns(dev); + stream->dbg.interval = ns - stream->dbg.timestamp; + stream->dbg.timestamp = ns; + rkisp_dmarx_get_frame(dev, &seq, NULL, &ns, true); + stream->dbg.delay = stream->dbg.timestamp - ns; + stream->dbg.id = seq; + } else { + mi_frame_end(stream, FRAME_IRQ); + } + } +end: + if (mis_val & ISP3X_MI_MP_FRAME) { + stream = &dev->cap_dev.stream[RKISP_STREAM_MP]; + if (!stream->streaming) + dev->irq_ends_mask &= ~ISP_FRAME_MP; + rkisp_check_idle(dev, ISP_FRAME_MP); + } + if (mis_val & ISP3X_MI_SP_FRAME) { + stream = &dev->cap_dev.stream[RKISP_STREAM_SP]; + if (!stream->streaming) + dev->irq_ends_mask &= ~ISP_FRAME_SP; + rkisp_check_idle(dev, ISP_FRAME_SP); + } +} diff --git a/drivers/media/platform/rockchip/isp/capture_v3x.h b/drivers/media/platform/rockchip/isp/capture_v3x.h index be9860dc1ae1..e906995ea1e7 100644 --- a/drivers/media/platform/rockchip/isp/capture_v3x.h +++ b/drivers/media/platform/rockchip/isp/capture_v3x.h @@ -40,7 +40,19 @@ static inline void rkisp_unregister_stream_v33(struct rkisp_device *dev) {} static inline void rkisp_mi_v33_isr(u32 mis_val, struct rkisp_device *dev) {} #endif -#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) +int rkisp_register_stream_v35(struct rkisp_device *dev); +void rkisp_unregister_stream_v35(struct rkisp_device *dev); +void rkisp_mi_v35_isr(u32 mis_val, struct rkisp_device *dev); +#else +static inline int rkisp_register_stream_v35(struct rkisp_device *dev) { return -EINVAL; } +static inline void rkisp_unregister_stream_v35(struct rkisp_device *dev) {} +static inline void rkisp_mi_v35_isr(u32 mis_val, struct rkisp_device *dev) {} +#endif + +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) || \ +IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) || \ +IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) void rkisp_rockit_buf_state_clear(struct rkisp_stream *stream); int rkisp_rockit_buf_free(struct rkisp_stream *stream); void rkisp_rockit_dev_init(struct rkisp_device *dev); diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index eb5bfe9ee317..73d7b7858f98 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -79,6 +79,7 @@ enum rkisp_isp_ver { ISP_V32_L = 0x80, ISP_V33 = 0x90, ISP_V39 = 0xa0, + ISP_V35 = 0xb0, }; enum rkisp_sd_type { @@ -105,6 +106,7 @@ enum rkisp_fmt_pix_type { FMT_EBD, FMT_SPD, FMT_FBC, + FMT_TILE, FMT_MAX }; diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index e296e196d475..ac1214b18f83 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -418,7 +418,7 @@ int rkisp_expander_config(struct rkisp_device *dev, u32 i, val, num, d0, d1, drop_bit = 0; u32 output_bit, input_bit, max; - if (dev->isp_ver != ISP_V39) + if (dev->isp_ver != ISP_V39 && dev->isp_ver != ISP_V35) return 0; if (!on) { @@ -618,7 +618,8 @@ int rkisp_csi_config_patch(struct rkisp_device *dev, bool is_pre_cfg) RKISP_VICAP_CMD_INIT_BUF, &init_buf); } if (dev->is_pre_on && !is_pre_cfg) { - if (dev->isp_ver == ISP_V33 && dev->cap_dev.wrap_line) { + if (dev->cap_dev.wrap_line && + (dev->isp_ver == ISP_V33 || dev->isp_ver == ISP_V35)) { val = ISP33_SW_ISP2ENC_PATH_EN | ISP33_PP_ENC_PIPE_EN; rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, val, false); } @@ -670,8 +671,9 @@ int rkisp_csi_config_patch(struct rkisp_device *dev, bool is_pre_cfg) val = 0; if (IS_HDR_RDBK(dev->hdr.op_mode)) val |= SW_MPIP_DROP_FRM_DIS; - if (dev->isp_ver == ISP_V33 && dev->cap_dev.wrap_line) { - val |= ISP33_SW_ISP2ENC_PATH_EN; + if (dev->cap_dev.wrap_line) { + if (dev->isp_ver == ISP_V33 || dev->isp_ver == ISP_V35) + val |= ISP33_SW_ISP2ENC_PATH_EN; if (IS_HDR_RDBK(dev->hdr.op_mode)) val |= ISP33_PP_ENC_PIPE_EN; } diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 5bafd453da9b..11d907dc79f1 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -1,5 +1,5 @@ /* - * Rockchip isp1 driver + * Rockchip isp driver * * Copyright (C) 2017 Rockchip Electronics Co., Ltd. * @@ -308,7 +308,8 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, rkisp_vicap_buf[dev->dev_id] = RKISP_VICAP_BUF_CNT_MAX; dev->vicap_buf_cnt = rkisp_vicap_buf[dev->dev_id]; dev->is_m_online = rkisp_m_online[dev->dev_id]; - if (hw->isp_ver != ISP_V33 || hw->is_single) { + if (hw->is_single || + (hw->isp_ver != ISP_V33 && hw->isp_ver != ISP_V35)) { dev->is_m_online = false; rkisp_m_online[dev->dev_id] = false; } @@ -324,7 +325,7 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, v4l2_subdev_call(dev->active_sensor->sd, core, ioctl, RKISP_VICAP_CMD_MULTI_ONLINE, &ret); } - if (hw->isp_ver == ISP_V33) { + if (hw->isp_ver == ISP_V33 || hw->isp_ver == ISP_V35) { if (dev->unite_div != ISP_UNITE_DIV1) rkisp_hdr_wrap_line[dev->dev_id] = 0; dev->hdr_wrap_line = rkisp_hdr_wrap_line[dev->dev_id]; @@ -1276,7 +1277,7 @@ static int rkisp_pm_resume(struct device *dev) { struct rkisp_device *isp_dev = dev_get_drvdata(dev); - if (isp_dev->isp_ver == ISP_V33) + if (isp_dev->isp_ver == ISP_V33 || isp_dev->isp_ver == ISP_V35) return rkisp_resume(dev); return 0; } @@ -1285,7 +1286,7 @@ static void rkisp_pm_complete(struct device *dev) { struct rkisp_device *isp_dev = dev_get_drvdata(dev); - if (isp_dev->isp_ver == ISP_V33) + if (isp_dev->isp_ver == ISP_V33 || isp_dev->isp_ver == ISP_V35) return; rkisp_resume(dev); } diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index be4e668cf780..f5eba75d5b55 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -229,7 +229,7 @@ struct rkisp_device { struct rkisp_csi_device csi_dev; struct rkisp_bridge_device br_dev; struct rkisp_luma_vdev luma_vdev; - struct rkisp_pdaf_vdev pdaf_vdev; + struct rkisp_pdaf_vdev *pdaf_vdev; struct rkisp_procfs procfs; struct rkisp_pipeline pipe; enum rkisp_isp_ver isp_ver; diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 137abacb7707..f8e447b5f86e 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -79,7 +79,7 @@ static void default_sw_reg_flag(struct rkisp_device *dev) ISP_RAWHIST_BIG3_BASE, ISP_YUVAE_CTRL, ISP_RAWAF_CTRL, ISP21_RAWAWB_CTRL, }; - u32 v30_reg[] = { + u32 v3x_reg[] = { ISP3X_VI_ISP_PATH, ISP3X_IMG_EFF_CTRL, ISP3X_CMSK_CTRL0, ISP3X_CCM_CTRL, ISP3X_CPROC_CTRL, ISP3X_DUAL_CROP_CTRL, ISP3X_GAMMA_OUT_CTRL, ISP3X_SELF_RESIZE_CTRL, ISP3X_MAIN_RESIZE_CTRL, @@ -93,56 +93,12 @@ static void default_sw_reg_flag(struct rkisp_device *dev) ISP3X_RAWAE_BIG2_BASE, ISP3X_RAWAE_BIG3_BASE, ISP3X_RAWHIST_LITE_CTRL, ISP3X_RAWHIST_BIG1_BASE, ISP3X_RAWHIST_BIG2_BASE, ISP3X_RAWHIST_BIG3_BASE, ISP3X_RAWAF_CTRL, ISP3X_RAWAWB_CTRL, - }; - u32 v32_reg[] = { - ISP3X_VI_ISP_PATH, ISP3X_IMG_EFF_CTRL, ISP3X_CMSK_CTRL0, - ISP3X_CCM_CTRL, ISP3X_CPROC_CTRL, ISP3X_DUAL_CROP_CTRL, - ISP3X_GAMMA_OUT_CTRL, ISP3X_SELF_RESIZE_CTRL, ISP3X_MAIN_RESIZE_CTRL, ISP32_BP_RESIZE_BASE, ISP3X_MI_BP_WR_CTRL, ISP32_MI_MPDS_WR_CTRL, - ISP32_MI_BPDS_WR_CTRL, ISP32_MI_WR_WRAP_CTRL, - ISP3X_LSC_CTRL, ISP3X_DEBAYER_CONTROL, ISP3X_CAC_CTRL, - ISP3X_YNR_GLOBAL_CTRL, ISP3X_CNR_CTRL, ISP3X_SHARP_EN, - ISP3X_BAY3D_CTRL, ISP3X_GIC_CONTROL, ISP3X_BLS_CTRL, - ISP3X_DPCC0_MODE, ISP3X_DPCC1_MODE, ISP3X_DPCC2_MODE, - ISP3X_HDRMGE_CTRL, ISP3X_DRC_CTRL0, ISP3X_BAYNR_CTRL, - ISP3X_LDCH_STS, ISP3X_DHAZ_CTRL, ISP3X_3DLUT_CTRL, - ISP3X_GAIN_CTRL, ISP3X_RAWAE_LITE_CTRL, ISP3X_RAWAE_BIG1_BASE, - ISP3X_RAWAE_BIG2_BASE, ISP3X_RAWAE_BIG3_BASE, ISP3X_RAWHIST_LITE_CTRL, - ISP3X_RAWHIST_BIG1_BASE, ISP3X_RAWHIST_BIG2_BASE, ISP3X_RAWHIST_BIG3_BASE, - ISP3X_RAWAF_CTRL, ISP3X_RAWAWB_CTRL, - }; - u32 v39_reg[] = { - ISP3X_VI_ISP_PATH, ISP3X_IMG_EFF_CTRL, ISP3X_CMSK_CTRL0, - ISP3X_CCM_CTRL, ISP3X_CPROC_CTRL, ISP3X_DUAL_CROP_CTRL, - ISP3X_GAMMA_OUT_CTRL, ISP39_MAIN_SCALE_CTRL, ISP32_SELF_SCALE_CTRL, + ISP32_MI_BPDS_WR_CTRL, ISP32_MI_WR_WRAP_CTRL, ISP3X_MI_WR_CTRL, ISP39_LDCV_CTRL, ISP39_YUVME_CTRL, ISP39_RGBIR_CTRL, ISP39_EXPD_CTRL, ISP39_W3A_CTRL0, ISP39_W3A_CTRL1, - ISP3X_LSC_CTRL, ISP3X_DEBAYER_CONTROL, ISP3X_CAC_CTRL, - ISP3X_YNR_GLOBAL_CTRL, ISP3X_CNR_CTRL, ISP3X_SHARP_EN, - ISP3X_BAY3D_CTRL, ISP3X_GIC_CONTROL, ISP3X_BLS_CTRL, - ISP3X_DPCC0_MODE, ISP3X_DPCC1_MODE, ISP3X_DPCC2_MODE, - ISP3X_HDRMGE_CTRL, ISP3X_DRC_CTRL0, ISP3X_BAYNR_CTRL, - ISP3X_LDCH_STS, ISP3X_DHAZ_CTRL, ISP3X_3DLUT_CTRL, - ISP3X_GAIN_CTRL, ISP3X_RAWAE_LITE_CTRL, ISP3X_RAWAE_BIG1_BASE, - ISP3X_RAWAE_BIG2_BASE, ISP3X_RAWAE_BIG3_BASE, ISP3X_RAWHIST_LITE_CTRL, - ISP3X_RAWHIST_BIG1_BASE, ISP3X_RAWHIST_BIG2_BASE, ISP3X_RAWHIST_BIG3_BASE, - ISP3X_RAWAF_CTRL, ISP3X_RAWAWB_CTRL, - }; - u32 v33_reg[] = { - ISP3X_VI_ISP_PATH, ISP3X_IMG_EFF_CTRL, ISP3X_CMSK_CTRL0, - ISP3X_CCM_CTRL, ISP3X_CPROC_CTRL, ISP3X_DUAL_CROP_CTRL, - ISP3X_GAMMA_OUT_CTRL, ISP39_MAIN_SCALE_CTRL, ISP33_BP_SCALE_CTRL, - ISP32_SELF_SCALE_CTRL, ISP3X_MI_WR_CTRL, ISP3X_MI_BP_WR_CTRL, - ISP32_MI_WR_WRAP_CTRL, ISP3X_LSC_CTRL, ISP3X_DEBAYER_CONTROL, - ISP3X_CAC_CTRL, ISP3X_YNR_GLOBAL_CTRL, ISP3X_CNR_CTRL, - ISP3X_SHARP_EN, ISP33_BAY3D_CTRL0, ISP3X_GIC_CONTROL, - ISP3X_BLS_CTRL, ISP3X_DPCC0_MODE, ISP3X_DPCC1_MODE, - ISP3X_DPCC2_MODE, ISP3X_HDRMGE_CTRL, ISP3X_DRC_CTRL0, - ISP33_ENH_CTRL, ISP3X_LDCH_STS, ISP33_HIST_CTRL, - ISP33_HSV_CTRL, ISP3X_GAIN_CTRL, ISP39_W3A_CTRL0, - ISP3X_RAWAE_LITE_CTRL, ISP3X_RAWAE_BIG1_BASE, - ISP3X_RAWHIST_LITE_CTRL, ISP3X_RAWHIST_BIG1_BASE, - ISP3X_RAWAWB_CTRL, + ISP33_BP_SCALE_CTRL, ISP33_BAY3D_CTRL0, ISP33_HIST_CTRL, + ISP35_AI_CTRL, ISP35_AIAWB_CTRL0 }; u32 i, j, *flag, *reg, size; @@ -155,25 +111,10 @@ static void default_sw_reg_flag(struct rkisp_device *dev) reg = v21_reg; size = ARRAY_SIZE(v21_reg); break; - case ISP_V30: - reg = v30_reg; - size = ARRAY_SIZE(v30_reg); - break; - case ISP_V32: - case ISP_V32_L: - reg = v32_reg; - size = ARRAY_SIZE(v32_reg); - break; - case ISP_V39: - reg = v39_reg; - size = ARRAY_SIZE(v39_reg); - break; - case ISP_V33: - reg = v33_reg; - size = ARRAY_SIZE(v33_reg); - break; default: - return; + reg = v3x_reg; + size = ARRAY_SIZE(v3x_reg); + break; } for (i = 0; i < size; i++) { @@ -453,15 +394,20 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) for (j = 0; j < ARRAY_SIZE(self_upd_reg); j++) { reg = reg_buf + self_upd_reg[j]; *reg &= ~ISP21_SELF_FORCE_UPD; - if (self_upd_reg[j] == ISP3X_3DLUT_BASE && *reg & ISP_3DLUT_EN) { + if (self_upd_reg[j] == ISP3X_3DLUT_BASE && + *reg & ISP_3DLUT_EN && + dev->isp_ver != ISP_V35) { reg = reg_buf + ISP3X_3DLUT_UPDATE; *reg = 1; } } - if (dev->isp_ver == ISP_V39) { - reg = reg_buf + ISP39_VI3A_CTRL0; - if (*reg) - *reg |= ISP39_W3A_FORCE_UPD; + if (dev->isp_ver == ISP_V35) { + reg = reg_buf + ISP3X_SWS_CFG; + *reg &= ~ISP3X_3A_DDR_WRITE_EN; + reg = reg_buf + ISP39_W3A_CTRL0; + *reg &= ~ISP39_W3A_FORCE_UPD; + reg = reg_buf + ISP35_AIAWB_CTRL0; + *reg &= ~ISP35_AIAWB_SELF_UPD; } reg = reg_buf + ISP_CTRL; *reg &= ~(CIF_ISP_CTRL_ISP_ENABLE | @@ -479,7 +425,7 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) (j == 0x4840 || j == 0x4a80 || j == 0x4b40 || j == 0x5660) || (dev->isp_ver == ISP_V39 && (j > ISP39_DHAZ_HIST_IIR0 && j < ISP39_DHAZ_LINE_CNT)) || - (dev->isp_ver == ISP_V33 && + ((dev->isp_ver == ISP_V33 || dev->isp_ver == ISP_V35) && ((j > ISP33_ENH_IIR0 && j < ISP33_ENH_ERR_FLAG) || (j > ISP33_HIST_IIR0 && j < ISP33_HIST_STAB) || (j >= ISP33_SHARP_NOISE_CURVE0 && j <= ISP33_SHARP_NOISE_CURVE8)))) @@ -546,7 +492,7 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL); reg = reg_buf + SELF_RESIZE_CTRL; if (*reg & 0xf) { - if (dev->isp_ver == ISP_V32_L || dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33) + if (dev->isp_ver >= ISP_V32_L) writel(ISP32_SCALE_FORCE_UPD | ISP32_SCALE_GEN_UPD, base + ISP32_SELF_SCALE_UPDATE); else @@ -554,7 +500,7 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) } reg = reg_buf + MAIN_RESIZE_CTRL; if (*reg & 0xf) { - if (dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33) + if (dev->isp_ver >= ISP_V33) writel(ISP32_SCALE_FORCE_UPD | ISP32_SCALE_GEN_UPD, base + ISP39_MAIN_SCALE_UPDATE); else @@ -594,40 +540,57 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) val = rkisp_read_reg_cache(isp, ISP3X_CAC_BASE); writel(val, base + ISP3X_CAC_BASE); } + if (dev->isp_ver == ISP_V35) { + reg = reg_buf + ISP39_W3A_CTRL0; + if (*reg & ISP39_W3A_EN) { + reg = reg_buf + ISP3X_SWS_CFG; + *reg |= ISP3X_3A_DDR_WRITE_EN; + writel(*reg, base + ISP3X_SWS_CFG); + } + reg = reg_buf + ISP35_AIAWB_CTRL0; + if (*reg & ISP35_AIAWB_EN) { + *reg |= ISP35_AIAWB_SELF_UPD; + writel(*reg, base + ISP35_AIAWB_CTRL0); + } + } } if (dev->is_single) { rkisp_params_cfgsram(&isp->params_vdev, false, true); - if (dev->isp_ver == ISP_V39) { - reg = reg_buf + ISP3X_ISP_CTRL1; - *reg |= ISP3X_DHAZ_FST_FRAME; - writel(*reg, dev->base_addr + ISP3X_ISP_CTRL1); - reg = reg_buf + ISP3X_BAY3D_CTRL; - if (*reg & 1) - writel(*reg | BIT(31), dev->base_addr + ISP3X_BAY3D_CTRL); - /* w3a addr will update by ISP_CFG_UPD */ - reg = reg_buf + ISP39_W3A_AEBIG_ADDR_SHD; - writel(*reg, dev->base_addr + ISP39_W3A_AEBIG_ADDR); - reg = reg_buf + ISP39_W3A_AE0_ADDR_SHD; - writel(*reg, dev->base_addr + ISP39_W3A_AE0_ADDR); - reg = reg_buf + ISP39_W3A_AF_ADDR_SHD; - writel(*reg, dev->base_addr + ISP39_W3A_AF_ADDR); - reg = reg_buf + ISP39_W3A_AWB_ADDR_SHD; - writel(*reg, dev->base_addr + ISP39_W3A_AWB_ADDR); - reg = reg_buf + ISP39_W3A_PDAF_ADDR_SHD; - writel(*reg, dev->base_addr + ISP39_W3A_PDAF_ADDR); - } else if (dev->isp_ver == ISP_V33) { - reg = reg_buf + ISP33_BAY3D_CTRL0; - if (*reg & 1) - writel(*reg | BIT(31), dev->base_addr + ISP33_BAY3D_CTRL0); - /* w3a addr will update by ISP_CFG_UPD */ + if (dev->isp_ver >= ISP_V33) { + if (dev->isp_ver == ISP_V39) { + reg = reg_buf + ISP3X_ISP_CTRL1; + *reg |= ISP3X_DHAZ_FST_FRAME; + writel(*reg, dev->base_addr + ISP3X_ISP_CTRL1); + reg = reg_buf + ISP3X_BAY3D_CTRL; + if (*reg & 1) + writel(*reg | BIT(31), dev->base_addr + ISP3X_BAY3D_CTRL); + } else { + reg = reg_buf + ISP33_BAY3D_CTRL0; + if (*reg & 1) + writel(*reg | BIT(31), dev->base_addr + ISP33_BAY3D_CTRL0); + } + /* V33 and V39 w3a addr will update by ISP_CFG_UPD */ reg = reg_buf + ISP39_W3A_AEBIG_ADDR_SHD; writel(*reg, dev->base_addr + ISP39_W3A_AEBIG_ADDR); reg = reg_buf + ISP39_W3A_AE0_ADDR_SHD; writel(*reg, dev->base_addr + ISP39_W3A_AE0_ADDR); reg = reg_buf + ISP39_W3A_AWB_ADDR_SHD; writel(*reg, dev->base_addr + ISP39_W3A_AWB_ADDR); + if (dev->isp_ver != ISP_V33) { + reg = reg_buf + ISP39_W3A_AF_ADDR_SHD; + writel(*reg, dev->base_addr + ISP39_W3A_AF_ADDR); + reg = reg_buf + ISP39_W3A_PDAF_ADDR_SHD; + writel(*reg, dev->base_addr + ISP39_W3A_PDAF_ADDR); + } + if (dev->isp_ver == ISP_V35) { + reg = reg_buf + ISP39_W3A_CTRL0; + if (*reg & ISP39_W3A_EN) { + *reg |= ISP39_W3A_FORCE_UPD; + writel(*reg, dev->base_addr + ISP39_W3A_CTRL0); + } + } } reg = reg_buf + ISP_CTRL; @@ -638,14 +601,14 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) if (dev->unite == ISP_UNITE_TWO) writel(*reg, dev->base_next_addr + ISP_CTRL); - if (dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33) { + if (dev->isp_ver >= ISP_V33) { reg = reg_buf + ISP39_W3A_AEBIG_ADDR; writel(*reg, dev->base_addr + ISP39_W3A_AEBIG_ADDR); reg = reg_buf + ISP39_W3A_AE0_ADDR; writel(*reg, dev->base_addr + ISP39_W3A_AE0_ADDR); reg = reg_buf + ISP39_W3A_AWB_ADDR; writel(*reg, dev->base_addr + ISP39_W3A_AWB_ADDR); - if (dev->isp_ver == ISP_V39) { + if (dev->isp_ver != ISP_V33) { reg = reg_buf + ISP39_W3A_AF_ADDR; writel(*reg, dev->base_addr + ISP39_W3A_AF_ADDR); reg = reg_buf + ISP39_W3A_PDAF_ADDR; @@ -709,6 +672,16 @@ static const char * const rv1126_isp_clks[] = { "hclk_isp", }; +static const char * const rv1126b_isp_clks[] = { + "clk_isp_core", + "aclk_isp", + "hclk_isp", + "clk_isp_vicap", + "clk_core_vpsl", + "aclk_vpsl", + "hclk_vpsl", +}; + static const struct isp_clk_info rk3562_isp_clk_rate[] = { { .clk_rate = 300, @@ -815,37 +788,7 @@ static const struct isp_clk_info rv1126_isp_clk_rate[] = { } }; -static struct isp_irqs_data rk3562_isp_irqs[] = { - {"isp_irq", isp_irq_hdl}, - {"mi_irq", mi_irq_hdl}, - {"mipi_irq", mipi_irq_hdl} -}; - -static struct isp_irqs_data rk3568_isp_irqs[] = { - {"isp_irq", isp_irq_hdl}, - {"mi_irq", mi_irq_hdl}, - {"mipi_irq", mipi_irq_hdl} -}; - -static struct isp_irqs_data rk3576_isp_irqs[] = { - {"isp_irq", isp_irq_hdl}, - {"mi_irq", mi_irq_hdl}, - {"mipi_irq", mipi_irq_hdl} -}; - -static struct isp_irqs_data rk3588_isp_irqs[] = { - {"isp_irq", isp_irq_hdl}, - {"mi_irq", mi_irq_hdl}, - {"mipi_irq", mipi_irq_hdl} -}; - -static struct isp_irqs_data rv1106_isp_irqs[] = { - {"isp_irq", isp_irq_hdl}, - {"mi_irq", mi_irq_hdl}, - {"mipi_irq", mipi_irq_hdl} -}; - -static struct isp_irqs_data rv1126_isp_irqs[] = { +static struct isp_irqs_data isp_irqs[] = { {"isp_irq", isp_irq_hdl}, {"mi_irq", mi_irq_hdl}, {"mipi_irq", mipi_irq_hdl} @@ -857,8 +800,8 @@ static const struct isp_match_data rv1103b_isp_match_data = { .isp_ver = ISP_V33, .clk_rate_tbl = rv1106_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rv1106_isp_clk_rate), - .irqs = rv1106_isp_irqs, - .num_irqs = ARRAY_SIZE(rv1106_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -868,8 +811,8 @@ static const struct isp_match_data rv1106_isp_match_data = { .isp_ver = ISP_V32, .clk_rate_tbl = rv1106_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rv1106_isp_clk_rate), - .irqs = rv1106_isp_irqs, - .num_irqs = ARRAY_SIZE(rv1106_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -879,8 +822,19 @@ static const struct isp_match_data rv1126_isp_match_data = { .isp_ver = ISP_V20, .clk_rate_tbl = rv1126_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rv1126_isp_clk_rate), - .irqs = rv1126_isp_irqs, - .num_irqs = ARRAY_SIZE(rv1126_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), + .unite = false, +}; + +static const struct isp_match_data rv1126b_isp_match_data = { + .clks = rv1126b_isp_clks, + .num_clks = ARRAY_SIZE(rv1126b_isp_clks), + .isp_ver = ISP_V35, + .clk_rate_tbl = rv1126_isp_clk_rate, + .num_clk_rate_tbl = ARRAY_SIZE(rv1126_isp_clk_rate), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -890,8 +844,8 @@ static const struct isp_match_data rk3562_isp_match_data = { .isp_ver = ISP_V32_L, .clk_rate_tbl = rk3562_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rk3562_isp_clk_rate), - .irqs = rk3562_isp_irqs, - .num_irqs = ARRAY_SIZE(rk3562_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -901,8 +855,8 @@ static const struct isp_match_data rk3568_isp_match_data = { .isp_ver = ISP_V21, .clk_rate_tbl = rk3568_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rk3568_isp_clk_rate), - .irqs = rk3568_isp_irqs, - .num_irqs = ARRAY_SIZE(rk3568_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -912,8 +866,8 @@ static const struct isp_match_data rk3576_isp_match_data = { .isp_ver = ISP_V39, .clk_rate_tbl = rk3576_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rk3576_isp_clk_rate), - .irqs = rk3576_isp_irqs, - .num_irqs = ARRAY_SIZE(rk3576_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -923,8 +877,8 @@ static const struct isp_match_data rk3588_isp_match_data = { .isp_ver = ISP_V30, .clk_rate_tbl = rk3588_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rk3588_isp_clk_rate), - .irqs = rk3588_isp_irqs, - .num_irqs = ARRAY_SIZE(rk3588_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = false, }; @@ -934,8 +888,8 @@ static const struct isp_match_data rk3588_isp_unite_match_data = { .isp_ver = ISP_V30, .clk_rate_tbl = rk3588_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rk3588_isp_clk_rate), - .irqs = rk3588_isp_irqs, - .num_irqs = ARRAY_SIZE(rk3588_isp_irqs), + .irqs = isp_irqs, + .num_irqs = ARRAY_SIZE(isp_irqs), .unite = true, }; @@ -984,6 +938,12 @@ static const struct of_device_id rkisp_hw_of_match[] = { .compatible = "rockchip,rv1126-rkisp", .data = &rv1126_isp_match_data, }, +#endif +#ifdef CONFIG_CPU_RV1126B + { + .compatible = "rockchip,rv1126b-rkisp", + .data = &rv1126b_isp_match_data, + }, #endif {}, }; @@ -1110,6 +1070,13 @@ void rkisp_soft_reset(struct rkisp_hw_dev *dev, bool is_secure) writel(0x02000400, dev->base_addr + ISP39_DEBAYER_G_FILTER_VSIGMA1); writel(0x00cd0155, dev->base_addr + ISP39_DEBAYER_G_FILTER_VSIGMA2); writel(0x00800092, dev->base_addr + ISP39_DEBAYER_G_FILTER_VSIGMA3); + } else if (dev->isp_ver == ISP_V35) { + writel(0, dev->base_addr + ISP32_BLS_ISP_OB_PREDGAIN); + writel(ISP39_ADRC_CMPS_BYP_EN, dev->base_addr + ISP3X_DRC_CTRL0); + writel(ISP39_W3A_PDAF2DDR_HOLD_DIS | ISP39_W3A_3A_HOLD_DIS | ISP35_W3A_B3DNROUT_ILG_BYPASS, + dev->base_addr + ISP39_W3A_CTRL0); + writel(0, dev->base_addr + ISP39_LDCH_OUT_SIZE); + writel(0x3801, dev->base_addr + ISP33_BAY3D_CTRL1); } } @@ -1590,7 +1557,7 @@ static int __init rkisp_hw_drv_init(void) ret = platform_driver_register(&rkisp_hw_drv); if (!ret) ret = platform_driver_register(&rkisp_plat_drv); -#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) platform_driver_register(&rkisp_sditf_drv); #endif #if IS_BUILTIN(CONFIG_VIDEO_ROCKCHIP_ISP) && IS_BUILTIN(CONFIG_VIDEO_ROCKCHIP_ISPP) @@ -1602,7 +1569,7 @@ static int __init rkisp_hw_drv_init(void) static void __exit rkisp_hw_drv_exit(void) { -#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) platform_driver_unregister(&rkisp_sditf_drv); #endif platform_driver_unregister(&rkisp_plat_drv); diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 2bdd87dd2c17..cedb6221ee55 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -16,6 +16,7 @@ #include "isp_params_v32.h" #include "isp_params_v39.h" #include "isp_params_v33.h" +#include "isp_params_v35.h" #include "regs.h" #define PARAMS_NAME DRIVER_NAME "-input-params" @@ -102,6 +103,8 @@ static int rkisp_get_params(struct rkisp_isp_params_vdev *params_vdev, void *arg ret = rkisp_get_params_v39(params_vdev, arg); else if (params_vdev->dev->isp_ver == ISP_V33) ret = rkisp_get_params_v33(params_vdev, arg); + else if (params_vdev->dev->isp_ver == ISP_V35) + ret = rkisp_get_params_v35(params_vdev, arg); return ret; } @@ -117,6 +120,7 @@ static long rkisp_params_ioctl_default(struct file *file, void *fh, break; case RKISP_CMD_GET_PARAMS_V39: case RKISP_CMD_GET_PARAMS_V33: + case RKISP_CMD_GET_PARAMS_V35: ret = rkisp_get_params(params, arg); break; default: @@ -248,7 +252,7 @@ static void rkisp_params_vb2_buf_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); dev_info(dev->dev, "params seq:%d for rtt\n", params->frame_id); dev->is_first_double = false; - if (dev->isp_ver == ISP_V33) { + if (dev->isp_ver >= ISP_V33) { dev->skip_frame = 1; dev->is_wait_aiq = true; } @@ -439,6 +443,8 @@ static int rkisp_init_params_vdev(struct rkisp_isp_params_vdev *params_vdev) ret = rkisp_init_params_vdev_v39(params_vdev); else if (dev->isp_ver == ISP_V33) ret = rkisp_init_params_vdev_v33(params_vdev); + else if (dev->isp_ver == ISP_V35) + ret = rkisp_init_params_vdev_v35(params_vdev); params_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS; return ret; @@ -462,6 +468,8 @@ static void rkisp_uninit_params_vdev(struct rkisp_isp_params_vdev *params_vdev) rkisp_uninit_params_vdev_v39(params_vdev); else if (dev->isp_ver == ISP_V33) rkisp_uninit_params_vdev_v33(params_vdev); + else if (dev->isp_ver == ISP_V35) + rkisp_uninit_params_vdev_v35(params_vdev); } void rkisp_params_cfg(struct rkisp_isp_params_vdev *params_vdev, @@ -614,6 +622,15 @@ int rkisp_params_aiisp_start(struct rkisp_isp_params_vdev *params_vdev, return ret; } +int rkisp_params_get_aiawb_buffd(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + int ret = -EINVAL; + + if (params_vdev->ops->get_aiawb_buffd) + ret = params_vdev->ops->get_aiawb_buffd(params_vdev, arg); + return ret; +} + int rkisp_register_params_vdev(struct rkisp_isp_params_vdev *params_vdev, struct v4l2_device *v4l2_dev, struct rkisp_device *dev) diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index 403cecc23bee..0cc858a3882c 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "common.h" @@ -56,6 +57,7 @@ struct rkisp_isp_params_ops { struct rkisp_bnr_buf_info *bnrbuf); void (*aiisp_event)(struct rkisp_isp_params_vdev *params_vdev, u32 irq); int (*aiisp_start)(struct rkisp_isp_params_vdev *params_vdev, struct rkisp_aiisp_st *st); + int (*get_aiawb_buffd)(struct rkisp_isp_params_vdev *params_vdev, void *arg); }; /* @@ -79,6 +81,7 @@ struct rkisp_isp_params_vdev { struct isp32_isp_params_cfg *isp32_params; struct isp39_isp_params_cfg *isp39_params; struct isp33_isp_params_cfg *isp33_params; + struct isp35_isp_params_cfg *isp35_params; }; struct v4l2_format vdev_fmt; bool streamon; @@ -173,4 +176,5 @@ int rkisp_params_init_bnr_buf(struct rkisp_isp_params_vdev *params_vdev, struct rkisp_bnr_buf_info *bnrbuf); void rkisp_params_aiisp_event(struct rkisp_isp_params_vdev *params_vdev, u32 irq); int rkisp_params_aiisp_start(struct rkisp_isp_params_vdev *params_vdev, struct rkisp_aiisp_st *st); +int rkisp_params_get_aiawb_buffd(struct rkisp_isp_params_vdev *params_vdev, void *arg); #endif /* _RKISP_ISP_PARAM_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.c b/drivers/media/platform/rockchip/isp/isp_params_v35.c new file mode 100644 index 000000000000..5653db4538c4 --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.c @@ -0,0 +1,8539 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ + +#include +#include +#include +#include +#include "dev.h" +#include "regs.h" +#include "isp_params_v35.h" + +#define ISP35_MODULE_EN BIT(0) +#define ISP35_SELF_FORCE_UPD BIT(31) + +static inline void +isp3_param_write_direct(struct rkisp_isp_params_vdev *params_vdev, + u32 value, u32 addr) +{ + void __iomem *base = params_vdev->dev->hw_dev->base_addr; + + writel(value, base + addr); +} + +static inline void +isp3_param_write(struct rkisp_isp_params_vdev *params_vdev, + u32 value, u32 addr, u32 id) +{ + rkisp_idx_write(params_vdev->dev, addr, value, id, false); +} + +static inline u32 +isp3_param_read_direct(struct rkisp_isp_params_vdev *params_vdev, u32 addr) +{ + return rkisp_read(params_vdev->dev, addr, true); +} + +static inline u32 +isp3_param_read(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) +{ + return rkisp_idx_read(params_vdev->dev, addr, id, false); +} + +static inline u32 +isp3_param_read_cache(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) +{ + return rkisp_idx_read_reg_cache(params_vdev->dev, addr, id); +} + +static inline void +isp3_param_set_bits(struct rkisp_isp_params_vdev *params_vdev, + u32 reg, u32 bit_mask, u32 id) +{ + rkisp_idx_set_bits(params_vdev->dev, reg, 0, bit_mask, id, false); +} + +static inline void +isp3_param_clear_bits(struct rkisp_isp_params_vdev *params_vdev, + u32 reg, u32 bit_mask, u32 id) +{ + rkisp_idx_clear_bits(params_vdev->dev, reg, bit_mask, id, false); +} + +static void +isp_dpcc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp39_dpcc_cfg *arg, u32 id) +{ + u32 value; + int i; + + value = isp3_param_read(params_vdev, ISP3X_DPCC0_MODE, id); + value &= ISP_DPCC_EN; + + value |= !!arg->stage1_enable << 2 | + !!arg->grayscale_mode << 1; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_MODE, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_MODE, id); + + value = !!arg->border_bypass_mode << 8 | + (arg->sw_rk_out_sel & 0x03) << 5 | + !!arg->sw_dpcc_output_sel << 4 | + !!arg->stage1_rb_3x3 << 3 | + !!arg->stage1_g_3x3 << 2 | + !!arg->stage1_incl_rb_center << 1 | + !!arg->stage1_incl_green_center; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_OUTPUT_MODE, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_OUTPUT_MODE, id); + + value = !!arg->stage1_use_fix_set << 3 | + !!arg->stage1_use_set_3 << 2 | + !!arg->stage1_use_set_2 << 1 | + !!arg->stage1_use_set_1; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_SET_USE, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_SET_USE, id); + + value = !!arg->sw_rk_red_blue1_en << 13 | + !!arg->rg_red_blue1_enable << 12 | + !!arg->rnd_red_blue1_enable << 11 | + !!arg->ro_red_blue1_enable << 10 | + !!arg->lc_red_blue1_enable << 9 | + !!arg->pg_red_blue1_enable << 8 | + !!arg->sw_rk_green1_en << 5 | + !!arg->rg_green1_enable << 4 | + !!arg->rnd_green1_enable << 3 | + !!arg->ro_green1_enable << 2 | + !!arg->lc_green1_enable << 1 | + !!arg->pg_green1_enable; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_METHODS_SET_1, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_METHODS_SET_1, id); + + value = !!arg->sw_rk_red_blue2_en << 13 | + !!arg->rg_red_blue2_enable << 12 | + !!arg->rnd_red_blue2_enable << 11 | + !!arg->ro_red_blue2_enable << 10 | + !!arg->lc_red_blue2_enable << 9 | + !!arg->pg_red_blue2_enable << 8 | + !!arg->sw_rk_green2_en << 5 | + !!arg->rg_green2_enable << 4 | + !!arg->rnd_green2_enable << 3 | + !!arg->ro_green2_enable << 2 | + !!arg->lc_green2_enable << 1 | + !!arg->pg_green2_enable; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_METHODS_SET_2, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_METHODS_SET_2, id); + + value = !!arg->sw_rk_red_blue3_en << 13 | + !!arg->rg_red_blue3_enable << 12 | + !!arg->rnd_red_blue3_enable << 11 | + !!arg->ro_red_blue3_enable << 10 | + !!arg->lc_red_blue3_enable << 9 | + !!arg->pg_red_blue3_enable << 8 | + !!arg->sw_rk_green3_en << 5 | + !!arg->rg_green3_enable << 4 | + !!arg->rnd_green3_enable << 3 | + !!arg->ro_green3_enable << 2 | + !!arg->lc_green3_enable << 1 | + !!arg->pg_green3_enable; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_METHODS_SET_3, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_METHODS_SET_3, id); + + value = ISP_PACK_4BYTE(arg->line_thr_1_g, arg->line_thr_1_rb, + arg->sw_mindis1_g, arg->sw_mindis1_rb); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_LINE_THRESH_1, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_LINE_THRESH_1, id); + + value = ISP_PACK_4BYTE(arg->line_mad_fac_1_g, arg->line_mad_fac_1_rb, + arg->sw_dis_scale_max1, arg->sw_dis_scale_min1); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_LINE_MAD_FAC_1, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_LINE_MAD_FAC_1, id); + + value = ISP_PACK_4BYTE(arg->pg_fac_1_g, arg->pg_fac_1_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PG_FAC_1, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PG_FAC_1, id); + + value = ISP_PACK_4BYTE(arg->rnd_thr_1_g, arg->rnd_thr_1_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RND_THRESH_1, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RND_THRESH_1, id); + + value = ISP_PACK_4BYTE(arg->rg_fac_1_g, arg->rg_fac_1_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RG_FAC_1, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RG_FAC_1, id); + + value = ISP_PACK_4BYTE(arg->line_thr_2_g, arg->line_thr_2_rb, + arg->sw_mindis2_g, arg->sw_mindis2_rb); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_LINE_THRESH_2, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_LINE_THRESH_2, id); + + value = ISP_PACK_4BYTE(arg->line_mad_fac_2_g, arg->line_mad_fac_2_rb, + arg->sw_dis_scale_max2, arg->sw_dis_scale_min2); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_LINE_MAD_FAC_2, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_LINE_MAD_FAC_2, id); + + value = ISP_PACK_4BYTE(arg->pg_fac_2_g, arg->pg_fac_2_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PG_FAC_2, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PG_FAC_2, id); + + value = ISP_PACK_4BYTE(arg->rnd_thr_2_g, arg->rnd_thr_2_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RND_THRESH_2, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RND_THRESH_2, id); + + value = ISP_PACK_4BYTE(arg->rg_fac_2_g, arg->rg_fac_2_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RG_FAC_2, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RG_FAC_2, id); + + value = ISP_PACK_4BYTE(arg->line_thr_3_g, arg->line_thr_3_rb, + arg->sw_mindis3_g, arg->sw_mindis3_rb); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_LINE_THRESH_3, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_LINE_THRESH_3, id); + + value = ISP_PACK_4BYTE(arg->line_mad_fac_3_g, arg->line_mad_fac_3_rb, + arg->sw_dis_scale_max3, arg->sw_dis_scale_min3); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_LINE_MAD_FAC_3, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_LINE_MAD_FAC_3, id); + + value = ISP_PACK_4BYTE(arg->pg_fac_3_g, arg->pg_fac_3_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PG_FAC_3, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PG_FAC_3, id); + + value = ISP_PACK_4BYTE(arg->rnd_thr_3_g, arg->rnd_thr_3_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RND_THRESH_3, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RND_THRESH_3, id); + + value = ISP_PACK_4BYTE(arg->rg_fac_3_g, arg->rg_fac_3_rb, 0, 0); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RG_FAC_3, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RG_FAC_3, id); + + value = (arg->ro_lim_3_rb & 0x03) << 10 | + (arg->ro_lim_3_g & 0x03) << 8 | + (arg->ro_lim_2_rb & 0x03) << 6 | + (arg->ro_lim_2_g & 0x03) << 4 | + (arg->ro_lim_1_rb & 0x03) << 2 | + (arg->ro_lim_1_g & 0x03); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RO_LIMITS, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RO_LIMITS, id); + + value = (arg->rnd_offs_3_rb & 0x03) << 10 | + (arg->rnd_offs_3_g & 0x03) << 8 | + (arg->rnd_offs_2_rb & 0x03) << 6 | + (arg->rnd_offs_2_g & 0x03) << 4 | + (arg->rnd_offs_1_rb & 0x03) << 2 | + (arg->rnd_offs_1_g & 0x03); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_RND_OFFS, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_RND_OFFS, id); + + value = !!arg->bpt_rb_3x3 << 11 | + !!arg->bpt_g_3x3 << 10 | + !!arg->bpt_incl_rb_center << 9 | + !!arg->bpt_incl_green_center << 8 | + !!arg->bpt_use_fix_set << 7 | + !!arg->bpt_use_set_3 << 6 | + !!arg->bpt_use_set_2 << 5 | + !!arg->bpt_use_set_1 << 4 | + !!arg->bpt_cor_en << 1 | + !!arg->bpt_det_en; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_BPT_CTRL, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_BPT_CTRL, id); + + isp3_param_write(params_vdev, arg->bp_number, ISP3X_DPCC0_BPT_NUMBER, id); + isp3_param_write(params_vdev, arg->bp_number, ISP3X_DPCC1_BPT_NUMBER, id); + isp3_param_write(params_vdev, arg->bp_table_addr, ISP3X_DPCC0_BPT_ADDR, id); + isp3_param_write(params_vdev, arg->bp_table_addr, ISP3X_DPCC1_BPT_ADDR, id); + + value = ISP_PACK_2SHORT(arg->bpt_h_addr, arg->bpt_v_addr); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_BPT_DATA, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_BPT_DATA, id); + + isp3_param_write(params_vdev, arg->bp_cnt, ISP3X_DPCC0_BP_CNT, id); + isp3_param_write(params_vdev, arg->bp_cnt, ISP3X_DPCC1_BP_CNT, id); + + isp3_param_write(params_vdev, arg->sw_pdaf_en, ISP3X_DPCC0_PDAF_EN, id); + isp3_param_write(params_vdev, arg->sw_pdaf_en, ISP3X_DPCC1_PDAF_EN, id); + + value = 0; + for (i = 0; i < ISP35_DPCC_PDAF_POINT_NUM; i++) + value |= !!arg->pdaf_point_en[i] << i; + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PDAF_POINT_EN, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PDAF_POINT_EN, id); + + value = ISP_PACK_2SHORT(arg->pdaf_offsetx, arg->pdaf_offsety); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PDAF_OFFSET, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PDAF_OFFSET, id); + + value = ISP_PACK_2SHORT(arg->pdaf_wrapx, arg->pdaf_wrapy); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PDAF_WRAP, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PDAF_WRAP, id); + + value = ISP_PACK_2SHORT(arg->pdaf_wrapx_num, arg->pdaf_wrapy_num); + isp3_param_write(params_vdev, value, ISP_DPCC0_PDAF_SCOPE, id); + isp3_param_write(params_vdev, value, ISP_DPCC1_PDAF_SCOPE, id); + + for (i = 0; i < ISP35_DPCC_PDAF_POINT_NUM / 2; i++) { + value = ISP_PACK_4BYTE(arg->point[2 * i].x, arg->point[2 * i].y, + arg->point[2 * i + 1].x, arg->point[2 * i + 1].y); + isp3_param_write(params_vdev, value, ISP3X_DPCC0_PDAF_POINT_0 + 4 * i, id); + isp3_param_write(params_vdev, value, ISP3X_DPCC1_PDAF_POINT_0 + 4 * i, id); + } + + isp3_param_write(params_vdev, arg->pdaf_forward_med, ISP3X_DPCC0_PDAF_FORWARD_MED, id); + isp3_param_write(params_vdev, arg->pdaf_forward_med, ISP3X_DPCC1_PDAF_FORWARD_MED, id); +} + +static void +isp_dpcc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_DPCC0_MODE, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_DPCC0_MODE, id); + isp3_param_write(params_vdev, val, ISP3X_DPCC1_MODE, id); +} + +static void +isp_bls_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_bls_cfg *arg, u32 id) +{ + const struct isp2x_bls_fixed_val *pval; + u32 new_control, value; + + new_control = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, id); + new_control &= (ISP_BLS_ENA | ISP32_BLS_BLS2_EN); + + pval = &arg->bls1_val; + if (arg->bls1_en) + new_control |= ISP_BLS_BLS1_EN; + switch (params_vdev->raw_type) { + case RAW_BGGR: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_D_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_C_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_B_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_A_FIXED, id); + break; + case RAW_GBRG: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_C_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_D_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_A_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_B_FIXED, id); + break; + case RAW_GRBG: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_B_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_A_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_D_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_C_FIXED, id); + break; + case RAW_RGGB: + default: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_A_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_B_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_C_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_D_FIXED, id); + break; + } + + /* fixed subtraction values */ + pval = &arg->fixed_val; + if (!arg->enable_auto) { + switch (params_vdev->raw_type) { + case RAW_BGGR: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS_D_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS_C_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS_B_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS_A_FIXED, id); + break; + case RAW_GBRG: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS_C_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS_D_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS_A_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS_B_FIXED, id); + break; + case RAW_GRBG: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS_B_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS_A_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS_D_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS_C_FIXED, id); + break; + case RAW_RGGB: + default: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS_A_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS_B_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS_C_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS_D_FIXED, id); + break; + } + } else { + if (arg->en_windows & BIT(1)) { + value = arg->bls_window2.h_offs; + isp3_param_write(params_vdev, value, ISP3X_BLS_H2_START, id); + value = arg->bls_window2.h_offs + arg->bls_window2.h_size; + isp3_param_write(params_vdev, value, ISP3X_BLS_H2_STOP, id); + value = arg->bls_window2.v_offs; + isp3_param_write(params_vdev, value, ISP3X_BLS_V2_START, id); + value = arg->bls_window2.v_offs + arg->bls_window2.v_size; + isp3_param_write(params_vdev, value, ISP3X_BLS_V2_STOP, id); + new_control |= ISP_BLS_WINDOW_2; + } + + if (arg->en_windows & BIT(0)) { + value = arg->bls_window1.h_offs; + isp3_param_write(params_vdev, value, ISP3X_BLS_H1_START, id); + value = arg->bls_window1.h_offs + arg->bls_window1.h_size; + isp3_param_write(params_vdev, value, ISP3X_BLS_H1_STOP, id); + value = arg->bls_window1.v_offs; + isp3_param_write(params_vdev, value, ISP3X_BLS_V1_START, id); + value = arg->bls_window1.v_offs + arg->bls_window1.v_size; + isp3_param_write(params_vdev, value, ISP3X_BLS_V1_STOP, id); + new_control |= ISP_BLS_WINDOW_1; + } + + isp3_param_write(params_vdev, arg->bls_samples, ISP3X_BLS_SAMPLES, id); + + new_control |= ISP_BLS_MODE_MEASURED; + } + isp3_param_write(params_vdev, new_control, ISP3X_BLS_CTRL, id); + + value = ISP_PACK_2SHORT(arg->isp_ob_offset, arg->isp_ob_offset1); + isp3_param_write(params_vdev, value, ISP32_BLS_ISP_OB_OFFSET, id); + isp3_param_write(params_vdev, arg->isp_ob_predgain, ISP32_BLS_ISP_OB_PREDGAIN, id); + isp3_param_write(params_vdev, arg->isp_ob_max, ISP32_BLS_ISP_OB_MAX, id); +} + +static void +isp_bls_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_BLS_CTRL, id); +} + +static void +isp_lsc_matrix_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_lsc_cfg *pconfig, + bool is_check, u32 id) +{ + u32 data = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id); + int i, j; + + if (is_check && !(data & ISP35_MODULE_EN)) + return; + + isp3_param_write_direct(params_vdev, 0, ISP3X_LSC_R_TABLE_ADDR); + isp3_param_write_direct(params_vdev, 0, ISP3X_LSC_GR_TABLE_ADDR); + isp3_param_write_direct(params_vdev, 0, ISP3X_LSC_GB_TABLE_ADDR); + isp3_param_write_direct(params_vdev, 0, ISP3X_LSC_B_TABLE_ADDR); + + /* program data tables (table size is 9 * 17 = 153) */ + for (i = 0; i < CIF_ISP_LSC_SECTORS_MAX * CIF_ISP_LSC_SECTORS_MAX; + i += CIF_ISP_LSC_SECTORS_MAX) { + /* + * 17 sectors with 2 values in one DWORD = 9 + * DWORDs (2nd value of last DWORD unused) + */ + for (j = 0; j < CIF_ISP_LSC_SECTORS_MAX - 1; j += 2) { + data = ISP_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i + j], + pconfig->r_data_tbl[i + j + 1]); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_R_TABLE_DATA); + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i + j], + pconfig->gr_data_tbl[i + j + 1]); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_GR_TABLE_DATA); + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i + j], + pconfig->gb_data_tbl[i + j + 1]); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_GB_TABLE_DATA); + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i + j], + pconfig->b_data_tbl[i + j + 1]); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_B_TABLE_DATA); + } + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i + j], 0); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_R_TABLE_DATA); + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i + j], 0); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_GR_TABLE_DATA); + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i + j], 0); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_GB_TABLE_DATA); + + data = ISP_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i + j], 0); + isp3_param_write_direct(params_vdev, data, ISP3X_LSC_B_TABLE_DATA); + } +} + +static void +isp_lsc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_lsc_cfg *arg, u32 id) +{ + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct rkisp_device *dev = params_vdev->dev; + u32 i, data, ctrl; + + for (i = 0; i < ISP35_LSC_SIZE_TBL_SIZE / 4; i++) { + /* program x size tables */ + data = CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2], arg->x_size_tbl[i * 2 + 1]); + isp3_param_write(params_vdev, data, ISP3X_LSC_XSIZE_01 + i * 4, id); + data = CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2 + 8], arg->x_size_tbl[i * 2 + 9]); + isp3_param_write(params_vdev, data, ISP3X_LSC_XSIZE_89 + i * 4, id); + + /* program x grad tables */ + data = CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2], arg->x_grad_tbl[i * 2 + 1]); + isp3_param_write(params_vdev, data, ISP3X_LSC_XGRAD_01 + i * 4, id); + data = CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2 + 8], arg->x_grad_tbl[i * 2 + 9]); + isp3_param_write(params_vdev, data, ISP3X_LSC_XGRAD_89 + i * 4, id); + + /* program y size tables */ + data = CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2], arg->y_size_tbl[i * 2 + 1]); + isp3_param_write(params_vdev, data, ISP3X_LSC_YSIZE_01 + i * 4, id); + data = CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2 + 8], arg->y_size_tbl[i * 2 + 9]); + isp3_param_write(params_vdev, data, ISP3X_LSC_YSIZE_89 + i * 4, id); + + /* program y grad tables */ + data = CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2], arg->y_grad_tbl[i * 2 + 1]); + isp3_param_write(params_vdev, data, ISP3X_LSC_YGRAD_01 + i * 4, id); + data = CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2 + 8], arg->y_grad_tbl[i * 2 + 9]); + isp3_param_write(params_vdev, data, ISP3X_LSC_YGRAD_89 + i * 4, id); + } + + ctrl = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id); + ctrl &= ISP35_MODULE_EN; + ctrl |= !!arg->sector_16x16 << 2; + isp3_param_write(params_vdev, ctrl, ISP3X_LSC_CTRL, id); + + if (dev->hw_dev->is_single) + isp_lsc_matrix_cfg_sram(params_vdev, arg, false, id); + params_rec->others.lsc_cfg = *arg; +} + +static void +isp_lsc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_LSC_CTRL, id); +} + +static void +isp_debayer_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_debayer_cfg *arg, u32 id) +{ + u32 i, value; + + value = isp3_param_read(params_vdev, ISP3X_DEBAYER_CONTROL, id); + value &= ISP_DEBAYER_EN; + + value |= !!arg->bypass << 1 | !!arg->g_out_flt_en << 4 | + !!arg->cnt_flt_en << 8; + isp3_param_write(params_vdev, value, ISP3X_DEBAYER_CONTROL, id); + + value = 0; + for (i = 0; i < ISP35_DEBAYER_LUMA_NUM; i++) + value |= ((arg->luma_dx[i] & 0xf) << (i * 4)); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_LUMA_DX, id); + + value = (arg->g_interp_sharp_strg_max_limit & 0x3F) << 24 | arg->drct_method_thred << 16 | + (arg->lo_drct_thred & 0x0F) << 12 | (arg->hi_drct_thred & 0x0F) << 8 | + (arg->hi_texture_thred & 0x0F) << 4 | !!arg->g_interp_clip_en; + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_INTERP, id); + + value = (arg->lo_drct_flt_coeff4 & 0x1F) << 24 | (arg->lo_drct_flt_coeff3 & 0x1F) << 16 | + (arg->lo_drct_flt_coeff2 & 0x1F) << 8 | (arg->lo_drct_flt_coeff1 & 0x1F); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_INTERP_FILTER1, id); + + value = (arg->hi_drct_flt_coeff4 & 0x1F) << 24 | (arg->hi_drct_flt_coeff3 & 0x1F) << 16 | + (arg->hi_drct_flt_coeff2 & 0x1F) << 8 | (arg->hi_drct_flt_coeff1 & 0x1F); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_INTERP_FILTER2, id); + + value = (arg->grad_lo_flt_alpha & 0x7f) << 16 | (arg->g_interp_sharp_strg_offset & 0xfff); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_INTERP_OFFSET_ALPHA, id); + + for (i = 0; i < ISP35_DEBAYER_DRCT_OFFSET_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->drct_offset[i * 2], arg->drct_offset[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_INTERP_DRCT_OFFSET0 + i * 4, id); + } + + value = (arg->gflt_offset & 0x7ff) << 16 | (arg->gflt_ratio & 0x7ff) << 4 | !!arg->gflt_mode; + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_FILTER_MODE_OFFSET, id); + + value = ISP_PACK_4BYTE(arg->gflt_coe0, arg->gflt_coe1, arg->gflt_coe2, 0); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_FILTER_FILTER, id); + + for (i = 0; i < ISP35_DEBAYER_VSIGMA_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->gflt_vsigma[i * 2], arg->gflt_vsigma[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_G_FILTER_VSIGMA0 + i * 4, id); + } + + value = ISP_PACK_4BYTE(arg->cnr_lo_guide_lpf_coe0, arg->cnr_lo_guide_lpf_coe1, + arg->cnr_lo_guide_lpf_coe2, 0); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_GUIDE_GAUS, id); + + value = ISP_PACK_4BYTE(arg->cnr_pre_flt_coe0, arg->cnr_pre_flt_coe1 << 8, + arg->cnr_pre_flt_coe2, 0); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_CE_GAUS, id); + + value = ISP_PACK_4BYTE(arg->cnr_alpha_lpf_coe0, arg->cnr_alpha_lpf_coe1, + arg->cnr_alpha_lpf_coe2, 0); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_ALPHA_GAUS, id); + + value = !!arg->cnr_trans_en << 31 | (arg->cnr_log_guide_offset & 0xfff) << 16 | + (arg->cnr_log_grad_offset & 0x1fff); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_LOG_OFFSET, id); + + value = (arg->cnr_moire_alpha_scale & 0xfffff) << 12 | (arg->cnr_moire_alpha_offset & 0xfff); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_ALPHA, id); + + value = (arg->cnr_edge_alpha_scale & 0xfffff) << 12 | (arg->cnr_edge_alpha_offset & 0xfff); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_EDGE, id); + + value = (arg->cnr_lo_flt_wgt_slope & 0xfff) << 16 | + (arg->cnr_lo_flt_strg_shift & 0x3f) << 8 | arg->cnr_lo_flt_strg_inv; + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_IIR_0, id); + + value = (arg->cnr_lo_flt_wgt_min_thred & 0x3f) << 8 | (arg->cnr_lo_flt_wgt_max_limit & 0x7f); + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_IIR_1, id); + + value = (arg->cnr_hi_flt_cur_wgt & 0x7f) << 24 | + (arg->cnr_hi_flt_wgt_min_limit & 0x7f) << 16 | arg->cnr_hi_flt_vsigma; + isp3_param_write(params_vdev, value, ISP39_DEBAYER_C_FILTER_BF, id); +} + +static void +isp_debayer_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_DEBAYER_CONTROL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_DEBAYER_CONTROL, id); +} + +static void +isp_awbgain_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_awb_gain_cfg *arg, u32 id) +{ + struct rkisp_device *dev = params_vdev->dev; + + if (!arg->gain0_red || !arg->gain0_blue || + !arg->gain1_red || !arg->gain1_blue || + !arg->gain2_red || !arg->gain2_blue || + !arg->gain0_green_r || !arg->gain0_green_b || + !arg->gain1_green_r || !arg->gain1_green_b || + !arg->gain2_green_r || !arg->gain2_green_b) { + dev_err(dev->dev, "awb gain is zero!\n"); + return; + } + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->gain0_green_b, arg->gain0_green_r), + ISP3X_ISP_AWB_GAIN0_G, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->gain0_blue, arg->gain0_red), + ISP3X_ISP_AWB_GAIN0_RB, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->gain1_green_b, arg->gain1_green_r), + ISP3X_ISP_AWB_GAIN1_G, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->gain1_blue, arg->gain1_red), + ISP3X_ISP_AWB_GAIN1_RB, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->gain2_green_b, arg->gain2_green_r), + ISP3X_ISP_AWB_GAIN2_G, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->gain2_blue, arg->gain2_red), + ISP3X_ISP_AWB_GAIN2_RB, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->awb1_gain_gb, arg->awb1_gain_gr), + ISP32_ISP_AWB1_GAIN_G, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->awb1_gain_b, arg->awb1_gain_r), + ISP32_ISP_AWB1_GAIN_RB, id); +} + +static void +isp_awbgain_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_ISP_CTRL0, id); + + if (en == !!(val & CIF_ISP_CTRL_ISP_AWB_ENA)) + return; + if (en) + val |= CIF_ISP_CTRL_ISP_AWB_ENA; + else + val &= CIF_ISP_CTRL_ISP_AWB_ENA; + isp3_param_write(params_vdev, val, ISP3X_ISP_CTRL0, id); +} + +static void +isp_ccm_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_ccm_cfg *arg, u32 id) +{ + u32 value; + u32 i; + + value = isp3_param_read(params_vdev, ISP3X_CCM_CTRL, id); + value &= ISP_CCM_EN; + + value |= !!arg->sat_decay_en << 4 | + !!arg->asym_adj_en << 3 | + !!arg->enh_adj_en << 2 | + !!arg->highy_adjust_dis << 1; + isp3_param_write(params_vdev, value, ISP3X_CCM_CTRL, id); + + value = ISP_PACK_2SHORT(arg->coeff0_r, arg->coeff1_r); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF0_R, id); + + value = ISP_PACK_2SHORT(arg->coeff2_r, arg->offset_r); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF1_R, id); + + value = ISP_PACK_2SHORT(arg->coeff0_g, arg->coeff1_g); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF0_G, id); + + value = ISP_PACK_2SHORT(arg->coeff2_g, arg->offset_g); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF1_G, id); + + value = ISP_PACK_2SHORT(arg->coeff0_b, arg->coeff1_b); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF0_B, id); + + value = ISP_PACK_2SHORT(arg->coeff2_b, arg->offset_b); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF1_B, id); + + value = ISP_PACK_2SHORT(arg->coeff0_y, arg->coeff1_y); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF0_Y, id); + + value = ISP_PACK_2SHORT(arg->coeff2_y, 0); + isp3_param_write(params_vdev, value, ISP3X_CCM_COEFF1_Y, id); + + for (i = 0; i < ISP35_CCM_CURVE_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->alp_y[2 * i], arg->alp_y[2 * i + 1]); + isp3_param_write(params_vdev, value, ISP3X_CCM_ALP_Y0 + 4 * i, id); + } + + value = (arg->right_bit & 0xf) << 4 | (arg->bound_bit & 0xf); + isp3_param_write(params_vdev, value, ISP3X_CCM_BOUND_BIT, id); + + value = ISP_PACK_2SHORT(arg->color_coef0_r2y, arg->color_coef1_g2y); + isp3_param_write(params_vdev, value, ISP32_CCM_ENHANCE0, id); + + value = ISP_PACK_2SHORT(arg->color_coef2_b2y, arg->color_enh_rat_max); + isp3_param_write(params_vdev, value, ISP32_CCM_ENHANCE1, id); + + value = arg->hf_low | arg->hf_up << 8 | arg->hf_scale << 16; + isp3_param_write(params_vdev, value, ISP33_CCM_HF_THD, id); + + for (i = 0; i < ISP35_CCM_HF_FACTOR_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->hf_factor[i * 2], + arg->hf_factor[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_CCM_HF_FACTOR0 + i * 4, id); + } + value = arg->hf_factor[i * 2]; + isp3_param_write(params_vdev, value, ISP33_CCM_HF_FACTOR8, id); +} + +static void +isp_ccm_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_CCM_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_CCM_CTRL, id); +} + +static void +isp_goc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_gammaout_cfg *arg, u32 id) +{ + int i; + u32 value; + + value = isp3_param_read(params_vdev, ISP3X_GAMMA_OUT_CTRL, id); + value &= ISP3X_GAMMA_OUT_EN; + value |= !!arg->equ_segm << 1 | !!arg->finalx4_dense_en << 2; + isp3_param_write(params_vdev, value, ISP3X_GAMMA_OUT_CTRL, id); + + isp3_param_write(params_vdev, arg->offset, ISP3X_GAMMA_OUT_OFFSET, id); + for (i = 0; i < ISP35_GAMMA_OUT_MAX_SAMPLES / 2; i++) { + value = ISP_PACK_2SHORT(arg->gamma_y[2 * i], + arg->gamma_y[2 * i + 1]); + isp3_param_write(params_vdev, value, ISP3X_GAMMA_OUT_Y0 + i * 4, id); + } + isp3_param_write(params_vdev, arg->gamma_y[2 * i], ISP3X_GAMMA_OUT_Y0 + i * 4, id); +} + +static void +isp_goc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_GAMMA_OUT_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_GAMMA_OUT_CTRL, id); +} + +static void +isp_cproc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_cproc_cfg *arg, u32 id) +{ + u32 quantization = params_vdev->quantization; + + isp3_param_write(params_vdev, arg->contrast, ISP3X_CPROC_CONTRAST, id); + isp3_param_write(params_vdev, arg->hue, ISP3X_CPROC_HUE, id); + isp3_param_write(params_vdev, arg->sat, ISP3X_CPROC_SATURATION, id); + isp3_param_write(params_vdev, arg->brightness, ISP3X_CPROC_BRIGHTNESS, id); + + if (quantization != V4L2_QUANTIZATION_FULL_RANGE) { + isp3_param_clear_bits(params_vdev, ISP3X_CPROC_CTRL, + CIF_C_PROC_YOUT_FULL | + CIF_C_PROC_YIN_FULL | + CIF_C_PROC_COUT_FULL, id); + } else { + isp3_param_set_bits(params_vdev, ISP3X_CPROC_CTRL, + CIF_C_PROC_YOUT_FULL | + CIF_C_PROC_YIN_FULL | + CIF_C_PROC_COUT_FULL, id); + } +} + +static void +isp_cproc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_CPROC_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_CPROC_CTRL, id); +} + +static void +isp_ie_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_IMG_EFF_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val = ISP35_MODULE_EN; + else + val = 0; + isp3_param_write(params_vdev, val, ISP3X_IMG_EFF_CTRL, id); +} + +static void +isp_rawaf_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawaf_meas_cfg *arg, u32 id) +{ + struct rkisp_device *dev = params_vdev->dev; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + u32 width = out_crop->width, height = out_crop->height; + u32 i, var, ctrl; + u16 h_size, v_size; + u16 h_offs, v_offs; + u8 gaus_en, viir_en; + size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->win), arg->num_afm_win); + + if (dev->unite_div > ISP_UNITE_DIV1) + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + + for (i = 0; i < num_of_win; i++) { + h_size = arg->win[i].h_size; + v_size = arg->win[i].v_size; + h_offs = arg->win[i].h_offs < 2 ? 2 : arg->win[i].h_offs; + v_offs = arg->win[i].v_offs < 1 ? 1 : arg->win[i].v_offs; + + if (!v_size || v_size + v_offs - 2 > height) + v_size = height - v_offs - 2; + if (!h_size || h_size + h_offs - 2 > width) + h_size = width - h_offs - 2; + + if (i == 0) { + h_size = h_size / 15 * 15; + v_size = v_size / 15 * 15; + } + + /* + * (horizontal left row), value must be greater or equal 2 + * (vertical top line), value must be greater or equal 1 + */ + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(v_offs, h_offs), + ISP3X_RAWAF_OFFSET_WINA + i * 8, id); + + /* + * value must be smaller than [width of picture -2] + * value must be lower than (number of lines -2) + */ + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(v_size, h_size), + ISP3X_RAWAF_SIZE_WINA + i * 8, id); + } + + var = (arg->tnrin_shift & 0xf) << 20 | + (arg->hldg_dilate_num & 0x7) << 16 | + !!arg->aehgl_en << 13 | !!arg->bls_en << 12 | + (arg->bls_offset & 0x1FF); + isp3_param_write(params_vdev, var, ISP32L_RAWAF_CTRL1, id); + + for (i = 0; i < ISP35_RAWAF_GAMMA_NUM / 2; i++) { + var = ISP_PACK_2SHORT(arg->gamma_y[2 * i], arg->gamma_y[2 * i + 1]); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_GAMMA_Y0 + i * 4, id); + } + var = ISP_PACK_2SHORT(arg->gamma_y[16], 0); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_GAMMA_Y8, id); + + var = (arg->v2iir_shift_winb & 0xf) << 28 | (arg->v1iir_shift_winb & 0xf) << 24 | + (arg->h2iir_shift_winb & 0xf) << 20 | (arg->h1iir_shift_winb & 0xf) << 16 | + (arg->v2iir_shift_wina & 0x7) << 12 | (arg->v1iir_shift_wina & 0x7) << 8 | + (arg->h2iir_shift_wina & 0x7) << 4 | (arg->h1iir_shift_wina & 0x7); + isp3_param_write(params_vdev, var, ISP39_RAWAF_HVIIR_VAR_SHIFT, id); + + var = ISP_PACK_2SHORT(arg->h_fv_thresh, arg->v_fv_thresh); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_HIIR_THRESH, id); + + for (i = 0; i < ISP35_RAWAF_VFIR_COE_NUM; i++) { + var = ISP_PACK_2SHORT(arg->v1fir_coe[i], arg->v2fir_coe[i]); + isp3_param_write(params_vdev, var, ISP32_RAWAF_V_FIR_COE0 + i * 4, id); + } + + for (i = 0; i < ISP35_RAWAF_GAUS_COE_NUM / 4; i++) { + var = ISP_PACK_4BYTE(arg->gaus_coe[i * 4], arg->gaus_coe[i * 4 + 1], + arg->gaus_coe[i * 4 + 2], arg->gaus_coe[i * 4 + 3]); + isp3_param_write(params_vdev, var, ISP32_RAWAF_GAUS_COE03 + i * 4, id); + } + var = ISP_PACK_4BYTE(arg->gaus_coe[ISP35_RAWAF_GAUS_COE_NUM - 1], 0, 0, 0); + isp3_param_write(params_vdev, var, ISP32_RAWAF_GAUS_COE8, id); + + isp3_param_write(params_vdev, arg->highlit_thresh, ISP3X_RAWAF_HIGHLIT_THRESH, id); + + var = ISP_PACK_2SHORT(arg->h_fv_limit, arg->h_fv_slope); + isp3_param_write(params_vdev, var, ISP32L_RAWAF_CORING_H, id); + var = ISP_PACK_2SHORT(arg->v_fv_limit, arg->v_fv_slope); + isp3_param_write(params_vdev, var, ISP32L_RAWAF_CORING_V, id); + + if (!arg->hiir_en || !arg->viir_en || !arg->aehgl_en) + dev_err(params_vdev->dev->dev, + "af hiir:%d viir:%d aehgl:%d no enable together\n", + arg->hiir_en, arg->viir_en, arg->aehgl_en); + viir_en = arg->viir_en; + gaus_en = arg->gaus_en; + + ctrl = isp3_param_read(params_vdev, ISP3X_RAWAF_CTRL, id); + ctrl &= ISP3X_RAWAF_EN; + if (arg->hiir_en) { + ctrl |= ISP3X_RAWAF_HIIR_EN; + for (i = 0; i < ISP35_RAWAF_HIIR_COE_NUM / 2; i++) { + var = ISP_PACK_2SHORT(arg->h1iir1_coe[i * 2], arg->h1iir1_coe[i * 2 + 1]); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_H1_IIR1_COE01 + i * 4, id); + var = ISP_PACK_2SHORT(arg->h1iir2_coe[i * 2], arg->h1iir2_coe[i * 2 + 1]); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_H1_IIR2_COE01 + i * 4, id); + + var = ISP_PACK_2SHORT(arg->h2iir1_coe[i * 2], arg->h2iir1_coe[i * 2 + 1]); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_H2_IIR1_COE01 + i * 4, id); + var = ISP_PACK_2SHORT(arg->h2iir2_coe[i * 2], arg->h2iir2_coe[i * 2 + 1]); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_H2_IIR2_COE01 + i * 4, id); + } + } + if (viir_en) { + ctrl |= ISP3X_RAWAF_VIIR_EN; + for (i = 0; i < ISP35_RAWAF_VIIR_COE_NUM; i++) { + var = ISP_PACK_2SHORT(arg->v1iir_coe[i], arg->v2iir_coe[i]); + isp3_param_write(params_vdev, var, ISP3X_RAWAF_V_IIR_COE0 + i * 4, id); + } + } + if (arg->ldg_en) { + ctrl |= ISP3X_RAWAF_LDG_EN; + for (i = 0; i < ISP35_RAWAF_CURVE_NUM; i++) { + isp3_param_write(params_vdev, + arg->curve_h[i].ldg_lumth | + arg->curve_h[i].ldg_gain << 8 | + arg->curve_h[i].ldg_gslp << 16, + ISP3X_RAWAF_H_CURVEL + i * 16, id); + isp3_param_write(params_vdev, + arg->curve_v[i].ldg_lumth | + arg->curve_v[i].ldg_gain << 8 | + arg->curve_v[i].ldg_gslp << 16, + ISP3X_RAWAF_V_CURVEL + i * 16, id); + } + } + + ctrl |= !!gaus_en << 2 | !!arg->gamma_en << 1 | + !!arg->v1_fv_mode << 10 | !!arg->h1_fv_mode << 8 | + !!arg->v2_fv_mode << 11 | !!arg->h2_fv_mode << 9 | + !!arg->y_mode << 13 | !!arg->ae_mode << 12 | + !!arg->vldg_sel << 14 | (arg->v_dnscl_mode & 0x3) << 16 | + !!arg->bnr_be_sel << 20 | !!arg->from_ynr << 19 | + !!arg->hiir_left_border_mode << 21 | !!arg->avg_ds_en << 22 | + !!arg->avg_ds_mode << 23 | !!arg->h1_acc_mode << 24 | + !!arg->h2_acc_mode << 25 | !!arg->v1_acc_mode << 26 | + !!arg->v2_acc_mode << 27; + isp3_param_write(params_vdev, ctrl, ISP3X_RAWAF_CTRL, id); + + ctrl = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, id); + ctrl &= ~(ISP3X_RAWAF_SEL(3) | ISP32L_BNR2AF_SEL); + ctrl |= ISP3X_RAWAF_SEL(arg->rawaf_sel) | !!arg->bnr2af_sel << 28; + isp3_param_write(params_vdev, ctrl, ISP3X_VI_ISP_PATH, id); +} + +static void +isp_rawaf_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 ctrl = isp3_param_read(params_vdev, ISP3X_RAWAF_CTRL, id); + + if (en == !!(ctrl & ISP35_MODULE_EN)) + return; + + if (en) + ctrl |= ISP35_MODULE_EN; + else + ctrl &= ~ISP35_MODULE_EN; + isp3_param_write(params_vdev, ctrl, ISP3X_RAWAF_CTRL, id); +} + +static void +isp_rawae_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawae_meas_cfg *arg, + u32 addr, u32 id) +{ + struct rkisp_device *ispdev = params_vdev->dev; + struct v4l2_rect *out_crop = &ispdev->isp_sdev.out_crop; + u32 width = out_crop->width, height = out_crop->height; + u32 value, h_size, v_size, h_offs, v_offs; + u32 block_hsize, block_vsize, wnd_num_idx = 0; + const u32 ae_wnd_num[] = { + 1, 5, 15, 15 + }; + + /* avoid to override the old enable value */ + value = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_CTRL, id); + value &= ISP3X_RAWAE_BIG_EN; + + wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } + value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx) | + !!arg->wnd1_en << 4 | + !!arg->debug_en << 8 | + !!arg->bnr_be_sel << 9; + isp3_param_write(params_vdev, value, addr + ISP3X_RAWAE_BIG_CTRL, id); + + h_offs = arg->win0_h_offset & ~0x1; + v_offs = arg->win0_v_offset & ~0x1; + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(h_offs, v_offs), + addr + ISP3X_RAWAE_BIG_OFFSET, id); + + if (ispdev->unite_div > ISP_UNITE_DIV1) + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + + h_size = arg->win0_h_size; + v_size = arg->win0_v_size; + if (!h_size || h_size + h_offs + 1 > width) + h_size = width - h_offs - 1; + if (!v_size || v_size + v_offs + 2 > height) + v_size = height - v_offs - 2; + block_hsize = (h_size / ae_wnd_num[wnd_num_idx]) & ~0x1; + block_vsize = (v_size / ae_wnd_num[wnd_num_idx]) & ~0x1; + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(block_hsize, block_vsize), + addr + ISP3X_RAWAE_BIG_BLK_SIZE, id); + + h_offs = arg->win1_h_offset & ~0x1; + v_offs = arg->win1_v_offset & ~0x1; + isp3_param_write(params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), + addr + ISP3X_RAWAE_BIG_WND1_OFFSET, id); + + v_size = arg->win1_h_size; + h_size = arg->win1_v_size; + if (!h_size || h_size + h_offs > width) + h_size = width - h_offs; + if (!v_size || v_size + v_offs > height) + v_size = height - v_offs; + h_size = (h_size + h_offs) & ~0x1; + v_size = (v_size + v_offs) & ~0x1; + isp3_param_write(params_vdev, ISP_PACK_2SHORT(h_size, v_size), + addr + ISP3X_RAWAE_BIG_WND1_SIZE, id); + + value = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, id); + if (addr == ISP3X_RAWAE_BIG1_BASE) { + value &= ~(ISP3X_RAWAE3_SEL(3) | BIT(29)); + value |= ISP3X_RAWAE3_SEL(arg->rawae_sel & 0xf); + value |= !!arg->bnr2ae_sel << 29; + isp3_param_write(params_vdev, value, ISP3X_VI_ISP_PATH, id); + } else { + value &= ~(ISP3X_RAWAE012_SEL(3) | BIT(30)); + value |= ISP3X_RAWAE012_SEL(arg->rawae_sel & 0xf); + value |= !!arg->bnr2ae_sel << 30; + isp3_param_write(params_vdev, value, ISP3X_VI_ISP_PATH, id); + } +} + +static void +isp_rawae_enable(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 addr, u32 id) +{ + u32 val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, addr + ISP3X_RAWAE_BIG_CTRL, id); +} + +static void +isp_rawae0_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawae_meas_cfg *arg, u32 id) +{ + isp_rawae_config(params_vdev, arg, ISP3X_RAWAE_LITE_BASE, id); +} + +static void +isp_rawae0_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + isp_rawae_enable(params_vdev, en, ISP3X_RAWAE_LITE_BASE, id); +} + +static void +isp_rawae3_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawae_meas_cfg *arg, u32 id) +{ + isp_rawae_config(params_vdev, arg, ISP3X_RAWAE_BIG1_BASE, id); +} + +static void +isp_rawae3_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + isp_rawae_enable(params_vdev, en, ISP3X_RAWAE_BIG1_BASE, id); +} + +static void +isp_rawawb_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawawb_meas_cfg *arg, bool is_check, u32 id) +{ + u32 i, val = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id); + + if (is_check && !(val & ISP35_MODULE_EN)) + return; + + isp3_param_write_direct(params_vdev, ISP33_RAWAWB_WRAM_CLR, ISP3X_RAWAWB_WRAM_CTRL); + for (i = 0; i < ISP35_RAWAWB_WEIGHT_NUM / 5; i++) { + val = (arg->wp_blk_wei_w[5 * i] & 0x3f) | + (arg->wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 | + (arg->wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 | + (arg->wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 | + (arg->wp_blk_wei_w[5 * i + 4] & 0x3f) << 24; + isp3_param_write_direct(params_vdev, val, ISP3X_RAWAWB_WRAM_DATA_BASE); + } +} + +static void +isp_rawawb_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawawb_meas_cfg *arg, u32 id) +{ + struct rkisp_device *dev = params_vdev->dev; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct isp35_rawawb_meas_cfg *arg_rec = ¶ms_rec->meas.rawawb; + const struct isp2x_bls_fixed_val *pval = &arg->bls2_val; + u32 width = out_crop->width, height = out_crop->height; + u32 value, val, mask, h_size, v_size, h_offs, v_offs; + + value = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, id); + value &= ~ISP32_BLS_BLS2_EN; + if (arg->bls2_en) + value |= ISP32_BLS_BLS2_EN; + switch (params_vdev->raw_type) { + case RAW_BGGR: + isp3_param_write(params_vdev, pval->r, ISP32_BLS2_D_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP32_BLS2_C_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP32_BLS2_B_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP32_BLS2_A_FIXED, id); + break; + case RAW_GBRG: + isp3_param_write(params_vdev, pval->r, ISP32_BLS2_C_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP32_BLS2_D_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP32_BLS2_A_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP32_BLS2_B_FIXED, id); + break; + case RAW_GRBG: + isp3_param_write(params_vdev, pval->r, ISP32_BLS2_B_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP32_BLS2_A_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP32_BLS2_D_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP32_BLS2_C_FIXED, id); + break; + case RAW_RGGB: + default: + isp3_param_write(params_vdev, pval->r, ISP32_BLS2_A_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP32_BLS2_B_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP32_BLS2_C_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP32_BLS2_D_FIXED, id); + } + isp3_param_write(params_vdev, value, ISP3X_BLS_CTRL, id); + + value = arg->in_overexposure_threshold << 16 | + !!arg->bnr_be_sel << 10 | + !!arg->ovexp_2ddr_dis << 9 | + !!arg->blk_with_luma_wei_en << 8 | + !!arg->ds16x8_mode_en << 7 | + (arg->blk_measure_illu_idx & 0x7) << 4 | + !!arg->blk_rtdw_measure_en << 3 | + !!arg->blk_measure_xytype << 2 | + !!arg->blk_measure_mode << 1 | + !!arg->blk_measure_enable; + isp3_param_write(params_vdev, value, ISP3X_RAWAWB_BLK_CTRL, id); + + h_offs = arg->h_offs & ~0x1; + v_offs = arg->v_offs & ~0x1; + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(h_offs, v_offs), + ISP3X_RAWAWB_WIN_OFFS, id); + + if (dev->unite_div > ISP_UNITE_DIV1) + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + + h_size = arg->h_size; + v_size = arg->v_size; + if (!h_size || h_size + h_offs > width) + h_size = width - h_offs; + if (!v_size || v_size + v_offs > height) + v_size = height - v_offs; + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(h_size, v_size), + ISP3X_RAWAWB_WIN_SIZE, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->r_max, arg->g_max), + ISP3X_RAWAWB_LIMIT_RG_MAX, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->b_max, arg->y_max), + ISP3X_RAWAWB_LIMIT_BY_MAX, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->r_min, arg->g_min), + ISP3X_RAWAWB_LIMIT_RG_MIN, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->b_min, arg->y_min), + ISP3X_RAWAWB_LIMIT_BY_MIN, id); + + value = !!arg->wp_hist_xytype << 4 | + !!arg->wp_blk_wei_en1 << 3 | + !!arg->wp_blk_wei_en0 << 2 | + !!arg->wp_luma_wei_en1 << 1 | + !!arg->wp_luma_wei_en0; + isp3_param_write(params_vdev, value, ISP3X_RAWAWB_WEIGHT_CURVE_CTRL, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->wp_luma_weicurve_y0, + arg->wp_luma_weicurve_y1, + arg->wp_luma_weicurve_y2, + arg->wp_luma_weicurve_y3), + ISP3X_RAWAWB_YWEIGHT_CURVE_XCOOR03, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->wp_luma_weicurve_y4, + arg->wp_luma_weicurve_y5, + arg->wp_luma_weicurve_y6, + arg->wp_luma_weicurve_y7), + ISP3X_RAWAWB_YWEIGHT_CURVE_XCOOR47, id); + + isp3_param_write(params_vdev, + arg->wp_luma_weicurve_y8, + ISP3X_RAWAWB_YWEIGHT_CURVE_XCOOR8, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->wp_luma_weicurve_w0, + arg->wp_luma_weicurve_w1, + arg->wp_luma_weicurve_w2, + arg->wp_luma_weicurve_w3), + ISP3X_RAWAWB_YWEIGHT_CURVE_YCOOR03, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->wp_luma_weicurve_w4, + arg->wp_luma_weicurve_w5, + arg->wp_luma_weicurve_w6, + arg->wp_luma_weicurve_w7), + ISP3X_RAWAWB_YWEIGHT_CURVE_YCOOR47, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->wp_luma_weicurve_w8, + arg->pre_wbgain_inv_r), + ISP3X_RAWAWB_YWEIGHT_CURVE_YCOOR8, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->pre_wbgain_inv_g, + arg->pre_wbgain_inv_b), + ISP3X_RAWAWB_PRE_WBGAIN_INV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex0_u_0, arg->vertex0_v_0), + ISP3X_RAWAWB_UV_DETC_VERTEX0_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex1_u_0, arg->vertex1_v_0), + ISP3X_RAWAWB_UV_DETC_VERTEX1_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex2_u_0, arg->vertex2_v_0), + ISP3X_RAWAWB_UV_DETC_VERTEX2_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex3_u_0, arg->vertex3_v_0), + ISP3X_RAWAWB_UV_DETC_VERTEX3_0, id); + + isp3_param_write(params_vdev, arg->islope01_0, + ISP3X_RAWAWB_UV_DETC_ISLOPE01_0, id); + + isp3_param_write(params_vdev, arg->islope12_0, + ISP3X_RAWAWB_UV_DETC_ISLOPE12_0, id); + + isp3_param_write(params_vdev, arg->islope23_0, + ISP3X_RAWAWB_UV_DETC_ISLOPE23_0, id); + + isp3_param_write(params_vdev, arg->islope30_0, + ISP3X_RAWAWB_UV_DETC_ISLOPE30_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex0_u_1, + arg->vertex0_v_1), + ISP3X_RAWAWB_UV_DETC_VERTEX0_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex1_u_1, + arg->vertex1_v_1), + ISP3X_RAWAWB_UV_DETC_VERTEX1_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex2_u_1, + arg->vertex2_v_1), + ISP3X_RAWAWB_UV_DETC_VERTEX2_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex3_u_1, + arg->vertex3_v_1), + ISP3X_RAWAWB_UV_DETC_VERTEX3_1, id); + + isp3_param_write(params_vdev, arg->islope01_1, + ISP3X_RAWAWB_UV_DETC_ISLOPE01_1, id); + + isp3_param_write(params_vdev, arg->islope12_1, + ISP3X_RAWAWB_UV_DETC_ISLOPE12_1, id); + + isp3_param_write(params_vdev, arg->islope23_1, + ISP3X_RAWAWB_UV_DETC_ISLOPE23_1, id); + + isp3_param_write(params_vdev, arg->islope30_1, + ISP3X_RAWAWB_UV_DETC_ISLOPE30_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex0_u_2, + arg->vertex0_v_2), + ISP3X_RAWAWB_UV_DETC_VERTEX0_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex1_u_2, + arg->vertex1_v_2), + ISP3X_RAWAWB_UV_DETC_VERTEX1_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex2_u_2, + arg->vertex2_v_2), + ISP3X_RAWAWB_UV_DETC_VERTEX2_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex3_u_2, + arg->vertex3_v_2), + ISP3X_RAWAWB_UV_DETC_VERTEX3_2, id); + + isp3_param_write(params_vdev, arg->islope01_2, + ISP3X_RAWAWB_UV_DETC_ISLOPE01_2, id); + + isp3_param_write(params_vdev, arg->islope12_2, + ISP3X_RAWAWB_UV_DETC_ISLOPE12_2, id); + + isp3_param_write(params_vdev, arg->islope23_2, + ISP3X_RAWAWB_UV_DETC_ISLOPE23_2, id); + + isp3_param_write(params_vdev, arg->islope30_2, + ISP3X_RAWAWB_UV_DETC_ISLOPE30_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex0_u_3, + arg->vertex0_v_3), + ISP3X_RAWAWB_UV_DETC_VERTEX0_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex1_u_3, + arg->vertex1_v_3), + ISP3X_RAWAWB_UV_DETC_VERTEX1_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex2_u_3, + arg->vertex2_v_3), + ISP3X_RAWAWB_UV_DETC_VERTEX2_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->vertex3_u_3, + arg->vertex3_v_3), + ISP3X_RAWAWB_UV_DETC_VERTEX3_3, id); + + isp3_param_write(params_vdev, arg->islope01_3, + ISP3X_RAWAWB_UV_DETC_ISLOPE01_3, id); + + isp3_param_write(params_vdev, arg->islope12_3, + ISP3X_RAWAWB_UV_DETC_ISLOPE12_3, id); + + isp3_param_write(params_vdev, arg->islope23_3, + ISP3X_RAWAWB_UV_DETC_ISLOPE23_3, id); + + isp3_param_write(params_vdev, arg->islope30_3, + ISP3X_RAWAWB_UV_DETC_ISLOPE30_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->rgb2ryuvmat0_y, + arg->rgb2ryuvmat1_y), + ISP3X_RAWAWB_YUV_RGB2ROTY_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->rgb2ryuvmat2_y, + arg->rgb2ryuvofs_y), + ISP3X_RAWAWB_YUV_RGB2ROTY_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->rgb2ryuvmat0_u, + arg->rgb2ryuvmat1_u), + ISP3X_RAWAWB_YUV_RGB2ROTU_0, id); + + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->rgb2ryuvmat2_u, + arg->rgb2ryuvofs_u), + ISP3X_RAWAWB_YUV_RGB2ROTU_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->rgb2ryuvmat0_v, + arg->rgb2ryuvmat1_v), + ISP3X_RAWAWB_YUV_RGB2ROTV_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->rgb2ryuvmat2_v, + arg->rgb2ryuvofs_v), + ISP3X_RAWAWB_YUV_RGB2ROTV_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls0_y, + arg->vec_x21_ls0_y), + ISP3X_RAWAWB_YUV_X_COOR_Y_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls0_u, + arg->vec_x21_ls0_u), + ISP3X_RAWAWB_YUV_X_COOR_U_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls0_v, + arg->vec_x21_ls0_v), + ISP3X_RAWAWB_YUV_X_COOR_V_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->dis_x1x2_ls0, 0, + arg->rotu0_ls0, arg->rotu1_ls0), + ISP3X_RAWAWB_YUV_X1X2_DIS_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->rotu2_ls0, arg->rotu3_ls0, + arg->rotu4_ls0, arg->rotu5_ls0), + ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th0_ls0, arg->th1_ls0), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th2_ls0, arg->th3_ls0), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th4_ls0, arg->th5_ls0), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls1_y, arg->vec_x21_ls1_y), + ISP3X_RAWAWB_YUV_X_COOR_Y_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls1_u, arg->vec_x21_ls1_u), + ISP3X_RAWAWB_YUV_X_COOR_U_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls1_v, arg->vec_x21_ls1_v), + ISP3X_RAWAWB_YUV_X_COOR_V_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->dis_x1x2_ls1, 0, arg->rotu0_ls1, arg->rotu1_ls1), + ISP3X_RAWAWB_YUV_X1X2_DIS_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->rotu2_ls1, arg->rotu3_ls1, + arg->rotu4_ls1, arg->rotu5_ls1), + ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th0_ls1, arg->th1_ls1), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th2_ls1, arg->th3_ls1), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th4_ls1, arg->th5_ls1), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls2_y, arg->vec_x21_ls2_y), + ISP3X_RAWAWB_YUV_X_COOR_Y_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls2_u, arg->vec_x21_ls2_u), + ISP3X_RAWAWB_YUV_X_COOR_U_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls2_v, arg->vec_x21_ls2_v), + ISP3X_RAWAWB_YUV_X_COOR_V_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->dis_x1x2_ls2, 0, arg->rotu0_ls2, arg->rotu1_ls2), + ISP3X_RAWAWB_YUV_X1X2_DIS_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->rotu2_ls2, arg->rotu3_ls2, + arg->rotu4_ls2, arg->rotu5_ls2), + ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th0_ls2, arg->th1_ls2), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th2_ls2, arg->th3_ls2), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th4_ls2, arg->th5_ls2), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls3_y, arg->vec_x21_ls3_y), + ISP3X_RAWAWB_YUV_X_COOR_Y_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls3_u, arg->vec_x21_ls3_u), + ISP3X_RAWAWB_YUV_X_COOR_U_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->coor_x1_ls3_v, arg->vec_x21_ls3_v), + ISP3X_RAWAWB_YUV_X_COOR_V_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->dis_x1x2_ls3, 0, + arg->rotu0_ls3, arg->rotu1_ls3), + ISP3X_RAWAWB_YUV_X1X2_DIS_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->rotu2_ls3, arg->rotu3_ls3, + arg->rotu4_ls3, arg->rotu5_ls3), + ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th0_ls3, arg->th1_ls3), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th2_ls3, arg->th3_ls3), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->th4_ls3, arg->th5_ls3), + ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_3, id); + + value = ISP_PACK_2SHORT(arg->ccm_coeff0_r, arg->ccm_coeff1_r); + isp3_param_write(params_vdev, value, ISP33_RAWAWB_CCM_COEFF0_R, id); + value = arg->ccm_coeff2_r; + isp3_param_write(params_vdev, value, ISP33_RAWAWB_CCM_COEFF1_R, id); + value = ISP_PACK_2SHORT(arg->ccm_coeff0_g, arg->ccm_coeff1_g); + isp3_param_write(params_vdev, value, ISP33_RAWAWB_CCM_COEFF0_G, id); + value = arg->ccm_coeff2_g; + isp3_param_write(params_vdev, value, ISP33_RAWAWB_CCM_COEFF1_G, id); + value = ISP_PACK_2SHORT(arg->ccm_coeff0_b, arg->ccm_coeff1_b); + isp3_param_write(params_vdev, value, ISP33_RAWAWB_CCM_COEFF0_B, id); + value = arg->ccm_coeff2_b; + isp3_param_write(params_vdev, value, ISP33_RAWAWB_CCM_COEFF1_B, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->wt0, arg->wt1), + ISP3X_RAWAWB_RGB2XY_WT01, id); + + isp3_param_write(params_vdev, arg->wt2, + ISP3X_RAWAWB_RGB2XY_WT2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->mat0_x, arg->mat0_y), + ISP3X_RAWAWB_RGB2XY_MAT0_XY, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->mat1_x, arg->mat1_y), + ISP3X_RAWAWB_RGB2XY_MAT1_XY, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->mat2_x, arg->mat2_y), + ISP3X_RAWAWB_RGB2XY_MAT2_XY, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_x0_0, arg->nor_x1_0), + ISP3X_RAWAWB_XY_DETC_NOR_X_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_y0_0, arg->nor_y1_0), + ISP3X_RAWAWB_XY_DETC_NOR_Y_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_x0_0, arg->big_x1_0), + ISP3X_RAWAWB_XY_DETC_BIG_X_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_y0_0, arg->big_y1_0), + ISP3X_RAWAWB_XY_DETC_BIG_Y_0, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_x0_1, arg->nor_x1_1), + ISP3X_RAWAWB_XY_DETC_NOR_X_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_y0_1, arg->nor_y1_1), + ISP3X_RAWAWB_XY_DETC_NOR_Y_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_x0_1, arg->big_x1_1), + ISP3X_RAWAWB_XY_DETC_BIG_X_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_y0_1, arg->big_y1_1), + ISP3X_RAWAWB_XY_DETC_BIG_Y_1, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_x0_2, arg->nor_x1_2), + ISP3X_RAWAWB_XY_DETC_NOR_X_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_y0_2, arg->nor_y1_2), + ISP3X_RAWAWB_XY_DETC_NOR_Y_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_x0_2, arg->big_x1_2), + ISP3X_RAWAWB_XY_DETC_BIG_X_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_y0_2, arg->big_y1_2), + ISP3X_RAWAWB_XY_DETC_BIG_Y_2, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_x0_3, arg->nor_x1_3), + ISP3X_RAWAWB_XY_DETC_NOR_X_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->nor_y0_3, arg->nor_y1_3), + ISP3X_RAWAWB_XY_DETC_NOR_Y_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_x0_3, arg->big_x1_3), + ISP3X_RAWAWB_XY_DETC_BIG_X_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->big_y0_3, arg->big_y1_3), + ISP3X_RAWAWB_XY_DETC_BIG_Y_3, id); + + value = (arg->exc_wp_region0_excen & 0x3) | + !!arg->exc_wp_region0_measen << 2 | + !!arg->exc_wp_region0_domain << 3 | + (arg->exc_wp_region1_excen & 0x3) << 4 | + !!arg->exc_wp_region1_measen << 6 | + !!arg->exc_wp_region1_domain << 7 | + (arg->exc_wp_region2_excen & 0x3) << 8 | + !!arg->exc_wp_region2_measen << 10 | + !!arg->exc_wp_region2_domain << 11 | + (arg->exc_wp_region3_excen & 0x3) << 12 | + !!arg->exc_wp_region3_measen << 14 | + !!arg->exc_wp_region3_domain << 15 | + (arg->exc_wp_region4_excen & 0x3) << 16 | + !!arg->exc_wp_region4_domain << 19 | + (arg->exc_wp_region5_excen & 0x3) << 20 | + !!arg->exc_wp_region5_domain << 23 | + (arg->exc_wp_region6_excen & 0x3) << 24 | + !!arg->exc_wp_region6_domain << 27 | + !!arg->multiwindow_en << 31; + isp3_param_write(params_vdev, value, ISP3X_RAWAWB_MULTIWINDOW_EXC_CTRL, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow0_h_offs, + arg->multiwindow0_v_offs), + ISP3X_RAWAWB_MULTIWINDOW0_OFFS, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow0_h_size, + arg->multiwindow0_v_size), + ISP3X_RAWAWB_MULTIWINDOW0_SIZE, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow1_h_offs, + arg->multiwindow1_v_offs), + ISP3X_RAWAWB_MULTIWINDOW1_OFFS, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow1_h_size, + arg->multiwindow1_v_size), + ISP3X_RAWAWB_MULTIWINDOW1_SIZE, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow2_h_offs, + arg->multiwindow2_v_offs), + ISP3X_RAWAWB_MULTIWINDOW2_OFFS, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow2_h_size, + arg->multiwindow2_v_size), + ISP3X_RAWAWB_MULTIWINDOW2_SIZE, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow3_h_offs, + arg->multiwindow3_v_offs), + ISP3X_RAWAWB_MULTIWINDOW3_OFFS, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->multiwindow3_h_size, + arg->multiwindow3_v_size), + ISP3X_RAWAWB_MULTIWINDOW3_SIZE, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region0_xu0, + arg->exc_wp_region0_xu1), + ISP3X_RAWAWB_EXC_WP_REGION0_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region0_yv0, + arg->exc_wp_region0_yv1), + ISP3X_RAWAWB_EXC_WP_REGION0_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region1_xu0, + arg->exc_wp_region1_xu1), + ISP3X_RAWAWB_EXC_WP_REGION1_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region1_yv0, + arg->exc_wp_region1_yv1), + ISP3X_RAWAWB_EXC_WP_REGION1_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region2_xu0, + arg->exc_wp_region2_xu1), + ISP3X_RAWAWB_EXC_WP_REGION2_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region2_yv0, + arg->exc_wp_region2_yv1), + ISP3X_RAWAWB_EXC_WP_REGION2_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region3_xu0, + arg->exc_wp_region3_xu1), + ISP3X_RAWAWB_EXC_WP_REGION3_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region3_yv0, + arg->exc_wp_region3_yv1), + ISP3X_RAWAWB_EXC_WP_REGION3_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region4_xu0, + arg->exc_wp_region4_xu1), + ISP3X_RAWAWB_EXC_WP_REGION4_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region4_yv0, + arg->exc_wp_region4_yv1), + ISP3X_RAWAWB_EXC_WP_REGION4_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region5_xu0, + arg->exc_wp_region5_xu1), + ISP3X_RAWAWB_EXC_WP_REGION5_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region5_yv0, + arg->exc_wp_region5_yv1), + ISP3X_RAWAWB_EXC_WP_REGION5_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region6_xu0, + arg->exc_wp_region6_xu1), + ISP3X_RAWAWB_EXC_WP_REGION6_XU, id); + + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->exc_wp_region6_yv0, + arg->exc_wp_region6_yv1), + ISP3X_RAWAWB_EXC_WP_REGION6_YV, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->exc_wp_region0_weight, + arg->exc_wp_region1_weight, + arg->exc_wp_region2_weight, + arg->exc_wp_region3_weight), + ISP32_RAWAWB_EXC_WP_WEIGHT0_3, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->exc_wp_region4_weight, + arg->exc_wp_region5_weight, + arg->exc_wp_region6_weight, 0), + ISP32_RAWAWB_EXC_WP_WEIGHT4_6, id); + + if (dev->hw_dev->is_single) + isp_rawawb_cfg_sram(params_vdev, arg, false, id); + memcpy(arg_rec->wp_blk_wei_w, arg->wp_blk_wei_w, ISP35_RAWAWB_WEIGHT_NUM); + + /* avoid to override the old enable value */ + value = isp3_param_read_cache(params_vdev, ISP3X_RAWAWB_CTRL, id); + value &= (ISP35_MODULE_EN | + ISP32_RAWAWB_2DDR_PATH_EN | + ISP32_RAWAWB_2DDR_PATH_DS); + value |= !!arg->low12bit_val << 28 | + !!arg->yuv3d_en1 << 26 | + !!arg->xy_en1 << 25 | + !!arg->uv_en1 << 24 | + (arg->light_num & 0x7) << 20 | + !!arg->rawlsc_bypass_en << 19 | + !!arg->wind_size << 18 | + !!arg->in_overexposure_check_en << 17 | + !!arg->in_rshift_to_12bit_en << 16 | + (arg->yuv3d_ls_idx3 & 0x7) << 13 | + (arg->yuv3d_ls_idx2 & 0x7) << 10 | + (arg->yuv3d_ls_idx1 & 0x7) << 7 | + (arg->yuv3d_ls_idx0 & 0x7) << 4 | + !!arg->yuv3d_en0 << 3 | + !!arg->xy_en0 << 2 | + !!arg->uv_en0 << 1; + isp3_param_write(params_vdev, value, ISP3X_RAWAWB_CTRL, id); + + mask = ISP32_DRC2AWB_SEL | ISP32_BNR2AWB_SEL | ISP3X_RAWAWB_SEL(3); + val = ISP3X_RAWAWB_SEL(arg->rawawb_sel) | + (arg->bnr2awb_sel & 0x1) << 26 | (arg->drc2awb_sel & 0x1) << 27; + value = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, id); + if ((value & mask) != val) { + value &= ~mask; + value |= val; + isp3_param_write(params_vdev, value, ISP3X_VI_ISP_PATH, id); + } +} + +static void +isp_rawawb_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_RAWAWB_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_RAWAWB_CTRL, id); +} + +static void +isp_rawhist_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawhist_meas_cfg *arg, + u32 addr, bool is_check, u32 id) +{ + u32 i, j, wnd_num_idx, value; + u8 weight15x15[ISP35_RAWHISTBIG_WEIGHT_REG_SIZE]; + const u32 hist_wnd_num[] = {5, 5, 15, 15}; + + value = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id); + if (is_check && !(value & ISP3X_RAWHIST_EN)) + return; + + wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } + memset(weight15x15, 0, sizeof(weight15x15)); + for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) { + for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) { + weight15x15[i * ISP35_RAWHISTBIG_ROW_NUM + j] = + arg->weight[i * hist_wnd_num[wnd_num_idx] + j]; + } + } + + for (i = 0; i < (ISP35_RAWHISTBIG_WEIGHT_REG_SIZE / 5); i++) { + value = (weight15x15[5 * i + 0] & 0x3f) | + (weight15x15[5 * i + 1] & 0x3f) << 6 | + (weight15x15[5 * i + 2] & 0x3f) << 12 | + (weight15x15[5 * i + 3] & 0x3f) << 18 | + (weight15x15[5 * i + 4] & 0x3f) << 24; + isp3_param_write_direct(params_vdev, value, + addr + ISP3X_RAWHIST_BIG_WEIGHT_BASE); + } +} + +static void +isp_rawhist_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawhist_meas_cfg *arg, u32 addr, u32 id) +{ + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct rkisp_device *dev = params_vdev->dev; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + u32 width = out_crop->width, height = out_crop->height; + struct isp35_rawhist_meas_cfg *arg_rec; + u32 ctrl, block_hsize, block_vsize, wnd_num_idx; + u32 h_size, v_size, h_offs, v_offs; + const u32 hist_wnd_num[] = {5, 5, 15, 15}; + + wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } + /* avoid to override the old enable value */ + ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id); + ctrl &= ISP3X_RAWHIST_EN; + ctrl |= (arg->stepsize & 0x7) << 1 | + !!arg->debug_en << 7 | + (arg->mode & 0x7) << 8 | + (arg->waterline & 0xfff) << 12 | + (arg->data_sel & 0x7) << 24 | + (arg->wnd_num & 0x3) << 28; + isp3_param_write(params_vdev, ctrl, addr + ISP3X_RAWHIST_BIG_CTRL, id); + + h_offs = arg->h_offset & ~0x1; + v_offs = arg->v_offset & ~0x1; + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(h_offs, v_offs), + addr + ISP3X_RAWHIST_BIG_OFFS, id); + + if (dev->unite_div > ISP_UNITE_DIV1) + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + + h_size = arg->h_size; + v_size = arg->v_size; + if (!h_size || h_size + h_offs + 1 > width) + h_size = width - h_offs - 1; + if (!v_size || v_size + v_offs + 1 > height) + v_size = height - v_offs - 1; + block_hsize = (h_size / hist_wnd_num[wnd_num_idx]) & ~0x1; + block_vsize = (v_size / hist_wnd_num[wnd_num_idx]) & ~0x1; + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(block_hsize, block_vsize), + addr + ISP3X_RAWHIST_BIG_SIZE, id); + + isp3_param_write(params_vdev, + ISP_PACK_4BYTE(arg->rcc, arg->gcc, arg->bcc, arg->off), + addr + ISP3X_RAWHIST_BIG_RAW2Y_CC, id); + + if (dev->hw_dev->is_single) + isp_rawhist_cfg_sram(params_vdev, arg, addr, false, id); + + arg_rec = (addr == ISP3X_RAWHIST_LITE_BASE) ? + ¶ms_rec->meas.rawhist0 : ¶ms_rec->meas.rawhist3; + *arg_rec = *arg; +} + +static void +isp_rawhist_enable(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 addr, u32 id) +{ + u32 val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + val &= ~(ISP35_SELF_FORCE_UPD | ISP35_MODULE_EN); + if (en) + val |= ISP35_MODULE_EN; + isp3_param_write(params_vdev, val, addr + ISP3X_RAWHIST_BIG_CTRL, id); +} + +static void +isp_rawhist0_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawhist_meas_cfg *arg, u32 id) +{ + isp_rawhist_config(params_vdev, arg, ISP3X_RAWHIST_LITE_BASE, id); +} + +static void +isp_rawhist0_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + isp_rawhist_enable(params_vdev, en, ISP3X_RAWHIST_LITE_BASE, id); +} + +static void +isp_rawhist3_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_rawhist_meas_cfg *arg, u32 id) +{ + isp_rawhist_config(params_vdev, arg, ISP3X_RAWHIST_BIG1_BASE, id); +} + +static void +isp_rawhist3_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + isp_rawhist_enable(params_vdev, en, ISP3X_RAWHIST_BIG1_BASE, id); +} + +static void +isp_aiawb_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_aiawb_meas_cfg *arg, u32 id) +{ + const struct isp2x_bls_fixed_val *pval = &arg->bls3_val; + u32 value; + + switch (params_vdev->raw_type) { + case RAW_BGGR: + value = ISP_PACK_2SHORT(pval->b, pval->gb); + isp3_param_write(params_vdev, value, ISP35_BLS3_AB_FIXED, id); + value = ISP_PACK_2SHORT(pval->gr, pval->r); + isp3_param_write(params_vdev, value, ISP35_BLS3_CD_FIXED, id); + break; + case RAW_GBRG: + value = ISP_PACK_2SHORT(pval->gb, pval->b); + isp3_param_write(params_vdev, value, ISP35_BLS3_AB_FIXED, id); + value = ISP_PACK_2SHORT(pval->r, pval->gr); + isp3_param_write(params_vdev, value, ISP35_BLS3_CD_FIXED, id); + break; + case RAW_GRBG: + value = ISP_PACK_2SHORT(pval->gr, pval->r); + isp3_param_write(params_vdev, value, ISP35_BLS3_AB_FIXED, id); + value = ISP_PACK_2SHORT(pval->b, pval->gb); + isp3_param_write(params_vdev, value, ISP35_BLS3_CD_FIXED, id); + break; + case RAW_RGGB: + default: + value = ISP_PACK_2SHORT(pval->r, pval->gr); + isp3_param_write(params_vdev, value, ISP35_BLS3_AB_FIXED, id); + value = ISP_PACK_2SHORT(pval->gb, pval->b); + isp3_param_write(params_vdev, value, ISP35_BLS3_CD_FIXED, id); + } + value = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, id); + value &= ~ISP35_BLS_BLS3_EN; + if (arg->bls3_en) + value |= ISP35_BLS_BLS3_EN; + isp3_param_write(params_vdev, value, ISP3X_BLS_CTRL, id); + + value = isp3_param_read(params_vdev, ISP39_W3A_CTRL0, id); + if ((!arg->rawout_sel && !(value & ISP35_W3A_RAWLSC_SEL)) || + (arg->rawout_sel && value & ISP35_W3A_RAWLSC_SEL)) { + if (arg->rawout_sel) + value &= ~ISP35_W3A_RAWLSC_SEL; + else + value |= ISP35_W3A_RAWLSC_SEL; + isp3_param_write(params_vdev, value, ISP39_W3A_CTRL0, id); + } + + value = isp3_param_read(params_vdev, ISP35_AIAWB_CTRL0, id); + value &= (ISP35_MODULE_EN | ISP35_AIAWB_SYS_UPD_DIS | ISP35_AIAWB_FRMEND_UPD_DIS); + value |= !!arg->ds_mode_config_en << 1 | + (arg->ds_mode & 0x3) << 2 | + !!arg->rgb2w_mode << 4 | + !!arg->rawout_sel << 7 | + (arg->path_sel & 0x7) << 8 | + (arg->in_shift & 0xf) << 12; + isp3_param_write(params_vdev, value, ISP35_AIAWB_CTRL0, id); + + value = arg->exp_thr | (arg->saturation_hthr & 0xfff) << 8 | + (arg->saturation_lthr & 0x7ff) << 20 | !!arg->exp1_check_en << 31; + isp3_param_write(params_vdev, value, ISP35_AIAWB_CTRL1, id); + + value = ISP_PACK_2SHORT(arg->h_offs, arg->v_offs); + isp3_param_write(params_vdev, value, ISP35_AIAWB_WIN_OFFS, id); + + value = ISP_PACK_2SHORT(arg->h_size, arg->v_size); + isp3_param_write(params_vdev, value, ISP35_AIAWB_WIN_SIZE, id); + + value = ISP_PACK_4BYTE(arg->flt_coe[0], arg->flt_coe[1], + arg->flt_coe[2], arg->flt_coe[3]); + isp3_param_write(params_vdev, value, ISP35_AIAWB_FLT_COE0, id); + value = arg->flt_coe[4] & 0xff; + isp3_param_write(params_vdev, value, ISP35_AIAWB_FLT_COE1, id); + + value = ISP_PACK_2SHORT(arg->wbgain_inv_g, arg->wbgain_inv_b); + isp3_param_write(params_vdev, value, ISP35_AIAWB_WBGAIN_INV0, id); + value = ISP_PACK_2SHORT(arg->wbgain_inv_r, arg->expand); + isp3_param_write(params_vdev, value, ISP35_AIAWB_WBGAIN_INV1, id); + + value = ISP_PACK_2SHORT(arg->ms00, arg->ms01); + isp3_param_write(params_vdev, value, ISP35_AIAWB_MATRIX_SCALE, id); + value = ISP_PACK_2SHORT(arg->mr00, arg->mr01); + isp3_param_write(params_vdev, value, ISP35_AIAWB_MATRIX_ROT0, id); + value = ISP_PACK_2SHORT(arg->mr10, arg->mr11); + isp3_param_write(params_vdev, value, ISP35_AIAWB_MATRIX_ROT0, id); +} + +static void +isp_aiawb_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + u32 val, ctrl = isp3_param_read_cache(params_vdev, ISP35_AIAWB_CTRL0, id); + + if (en == !!(ctrl & ISP35_MODULE_EN)) + return; + if (en) { + if (!priv->buf_aiawb[0].mem_priv) { + dev_err(dev->dev, "no aiawb buffer allocated\n"); + return; + } + priv->buf_aiawb_idx = 0; + ctrl |= ISP35_MODULE_EN | ISP35_AIAWB_SELF_UPD | ISP35_AIAWB_SYS_UPD_DIS; + val = priv->buf_aiawb[0].dma_addr; + isp3_param_write(params_vdev, val, ISP35_AIAWB_WR_BASE, id); + } else { + ctrl &= ~(ISP35_MODULE_EN | ISP35_AIAWB_SELF_UPD); + } + isp3_param_write(params_vdev, ctrl, ISP35_AIAWB_CTRL0, id); +} + +static void +isp_awbsync_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_awbsync_meas_cfg *arg, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP35_AWBSYNC_CTRL, id); + + val &= ISP35_MODULE_EN; + val |= ISP35_AWBSYNC_FRM_PROT | + !!arg->sumval_check_en << 2 | !!arg->sumval_mode << 3; + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_CTRL, id); + + val = (arg->scl_b & 0x3ff) | (arg->scl_g & 0x3ff) << 10 | + (arg->scl_r & 0x3ff) << 20; + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_SCL, id); + + val = (arg->sumval_minb & 0x3ff) | (arg->sumval_ming & 0x3ff) << 10 | + (arg->sumval_minr & 0x3ff) << 20; + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_SUMVAL_MIN, id); + + val = (arg->sumval_maxb & 0x3ff) | (arg->sumval_maxg & 0x3ff) << 10 | + (arg->sumval_maxr & 0x3ff) << 20; + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_SUMVAL_MAX, id); + + val = ISP_PACK_2SHORT(arg->win0_h_offs, arg->win0_v_offs); + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_WIN0_OFFS, id); + val = ISP_PACK_2SHORT(arg->win0_r_coor, arg->win0_d_coor); + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_WIN0_RD_COOR, id); + + val = ISP_PACK_2SHORT(arg->win1_h_offs, arg->win1_v_offs); + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_WIN1_OFFS, id); + val = ISP_PACK_2SHORT(arg->win1_r_coor, arg->win1_d_coor); + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_WIN1_RD_COOR, id); + + val = ISP_PACK_2SHORT(arg->win2_h_offs, arg->win2_v_offs); + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_WIN2_OFFS, id); + val = ISP_PACK_2SHORT(arg->win2_r_coor, arg->win2_d_coor); + isp3_param_write(params_vdev, val, ISP35_AWBSYNC_WIN2_RD_COOR, id); +} + +static void +isp_awbsync_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 ctrl = isp3_param_read_cache(params_vdev, ISP35_AWBSYNC_CTRL, id); + + if (en == !!(ctrl & ISP35_MODULE_EN)) + return; + if (en) + ctrl |= ISP35_MODULE_EN; + else + ctrl &= ~ISP35_MODULE_EN; + isp3_param_write(params_vdev, ctrl, ISP35_AWBSYNC_CTRL, id); +} + +static void +isp_hdrmge_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_hdrmge_cfg *arg, + enum rkisp_params_type type, u32 id) +{ + u32 value; + int i; + + if (type == RKISP_PARAMS_SHD || type == RKISP_PARAMS_ALL) { + value = ISP_PACK_2SHORT(arg->short_gain, arg->short_inv_gain); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_GAIN0, id); + + value = ISP_PACK_2SHORT(arg->medium_gain, arg->medium_inv_gain); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_GAIN1, id); + + value = arg->long_gain; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_GAIN2, id); + + value = isp3_param_read_cache(params_vdev, ISP3X_HDRMGE_CTRL, id); + value &= ~(BIT(1) | BIT(4) | BIT(5) | BIT(6) | BIT(7)); + value |= !!arg->short_base_en << 1 | + (arg->dbg_mode & 0x3) << 4 | + !!arg->channel_detection_en << 6 | + !!arg->s_base_mode << 7; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_CTRL, id); + } + + if (type == RKISP_PARAMS_IMD || type == RKISP_PARAMS_ALL) { + value = ISP_PACK_4BYTE(arg->ms_diff_scale, arg->ms_diff_offset, + arg->lm_diff_scale, arg->lm_diff_offset); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_LIGHTZ, id); + value = (arg->ms_abs_diff_scale & 0x7ff) | + (arg->ms_abs_diff_thred_min_limit & 0x3ff) << 12 | + (arg->ms_adb_diff_thred_max_limit & 0x3ff) << 22; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_MS_DIFF, id); + value = (arg->lm_abs_diff_scale & 0x7ff) | + (arg->lm_abs_diff_thred_min_limit & 0x3ff) << 12 | + (arg->lm_abs_diff_thred_max_limit & 0x3ff) << 22; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_LM_DIFF, id); + + for (i = 0; i < ISP35_HDRMGE_WGT_NUM; i++) { + value = ISP_PACK_2SHORT(arg->ms_luma_diff2wgt[i], arg->lm_luma_diff2wgt[i]); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_DIFF_Y0 + 4 * i, id); + } + + for (i = 0; i < ISP35_HDRMGE_WGT_NUM; i++) { + value = (arg->lm_raw_diff2wgt[i] & 0x3ff) << 20 | + (arg->ms_raw_diff2wgt[i] & 0x3ff) << 10 | + (arg->luma2wgt[i] & 0x3ff); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_OVER_Y0 + 4 * i, id); + } + + value = ISP_PACK_2SHORT(arg->channel_detn_short_gain, arg->channel_detn_medium_gain); + isp3_param_write(params_vdev, value, ISP32_HDRMGE_EACH_GAIN, id); + + value = arg->mid_luma_scale; + isp3_param_write(params_vdev, value, ISP35_HDRMGE_FORCE_LONG0, id); + value = ISP_PACK_2SHORT(arg->mid_luma_thred_max_limit, arg->mid_luma_thred_min_limit); + isp3_param_write(params_vdev, value, ISP35_HDRMGE_FORCE_LONG1, id); + } +} + +static void +isp_hdrdrc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_drc_cfg *arg, + enum rkisp_params_type type, u32 id) +{ + u32 i, value, ctrl; + + ctrl = isp3_param_read(params_vdev, ISP3X_DRC_CTRL0, id); + ctrl &= ISP35_MODULE_EN; + ctrl |= !!arg->gainx32_en << 3 | + !!arg->cmps_byp_en << 2 | !!arg->bypass_en << 1; + isp3_param_write(params_vdev, ctrl, ISP3X_DRC_CTRL0, id); + if (ctrl & BIT(29)) + dev_warn(params_vdev->dev->dev, "drc raw_dly_dis=1\n"); + value = isp3_param_read_cache(params_vdev, ISP3X_HDRMGE_CTRL, id); + if (ctrl & BIT(2) && (value & ISP35_MODULE_EN)) + dev_warn(params_vdev->dev->dev, "drc cmps_byp_en=1 but hdr\n"); + + if (type == RKISP_PARAMS_IMD) + return; + + value = (arg->log_transform_offset_bits & 0x0F) << 28 | + (arg->comps_idx_luma_scale & 0x1FFF) << 14 | + (arg->gain_idx_luma_scale & 0x03FFF); + isp3_param_write(params_vdev, value, ISP3X_DRC_CTRL1, id); + + value = arg->adj_gain_idx_luma_scale << 24 | + (arg->hi_detail_ratio & 0xFFF) << 12 | + (arg->lo_detail_ratio & 0xFFF); + isp3_param_write(params_vdev, value, ISP3X_DRC_LPRATIO, id); + + value = arg->bifilt_cur_pixel_wgt << 24 | !!arg->thumb_thred_en << 23 | + (arg->thumb_thred_neg & 0x1ff) << 8 | arg->bifilt_wgt_offset; + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT0, id); + + value = (arg->filt_luma_soft_thred & 0x3ff) << 16 | !!arg->cmps_mode << 4 | + (arg->cmps_offset_bits & 0xf); + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT1, id); + + value = arg->thumb_scale << 16 | (arg->thumb_max_limit & 0xfff); + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT2, id); + + value = (arg->lo_range_inv_sigma & 0x3ff) << 16 | (arg->hi_range_inv_sigma & 0x3ff); + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT3, id); + + value = !!arg->bifilt_soft_thred_en << 31 | (arg->bifilt_soft_thred & 0x7ff) << 16 | + arg->bifilt_hi_wgt << 8 | (arg->bifilt_wgt & 0x1f); + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT4, id); + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->gain_y[2 * i], + arg->gain_y[2 * i + 1]); + isp3_param_write(params_vdev, value, ISP3X_DRC_GAIN_Y0 + 4 * i, id); + } + value = ISP_PACK_2SHORT(arg->gain_y[2 * i], 0); + isp3_param_write(params_vdev, value, ISP3X_DRC_GAIN_Y0 + 4 * i, id); + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->compres_y[2 * i], + arg->compres_y[2 * i + 1]); + isp3_param_write(params_vdev, value, ISP3X_DRC_COMPRES_Y0 + 4 * i, id); + } + value = ISP_PACK_2SHORT(arg->compres_y[2 * i], 0); + isp3_param_write(params_vdev, value, ISP3X_DRC_COMPRES_Y0 + 4 * i, id); + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->scale_y[2 * i], + arg->scale_y[2 * i + 1]); + isp3_param_write(params_vdev, value, ISP3X_DRC_SCALE_Y0 + 4 * i, id); + } + value = ISP_PACK_2SHORT(arg->scale_y[2 * i], 0); + isp3_param_write(params_vdev, value, ISP3X_DRC_SCALE_Y0 + 4 * i, id); + + value = arg->comps_gain_min_limit; + isp3_param_write(params_vdev, value, ISP3X_DRC_IIRWG_GAIN, id); + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->sfthd_y[2 * i], arg->sfthd_y[2 * i + 1]); + isp3_param_write(params_vdev, value, ISP39_DRC_SFTHD_Y0 + 4 * i, id); + } + value = ISP_PACK_2SHORT(arg->sfthd_y[2 * i], 0); + isp3_param_write(params_vdev, value, ISP39_DRC_SFTHD_Y0 + 4 * i, id); + + value = arg->max_luma_wgt | arg->mid_luma_wgt << 8 | arg->min_luma_wgt << 16; + isp3_param_write(params_vdev, value, ISP35_DRC_LUMA_MIX, id); +} + +static void +isp_hdrdrc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 value; + bool real_en; + + value = isp3_param_read(params_vdev, ISP3X_DRC_CTRL0, id); + real_en = !!(value & ISP35_MODULE_EN); + if ((en && real_en) || (!en && !real_en)) + return; + + if (en) + value |= ISP35_MODULE_EN; + else + value &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, value, ISP3X_DRC_CTRL0, id); +} + +static void +isp_gic_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_gic_cfg *arg, u32 id) +{ + u32 value; + s32 i; + + value = isp3_param_read(params_vdev, ISP3X_GIC_CONTROL, id); + value &= ISP35_MODULE_EN; + value |= !!arg->bypass_en << 1 | + !!arg->pro_mode << 2 | + !!arg->manualnoisecurve_en << 3 | + !!arg->manualnoisethred_en << 4 | + !!arg->gain_bypass_en << 5; + isp3_param_write(params_vdev, value, ISP3X_GIC_CONTROL, id); + + value = (arg->medflt_minthred & 0xf) | + (arg->medflt_maxthred & 0xf) << 4 | arg->medflt_ratio << 16; + isp3_param_write(params_vdev, value, ISP33_GIC_MEDFLT_PARA, id); + + value = (arg->medfltuv_minthred & 0xf) | + (arg->medfltuv_maxthred & 0xf) << 4 | arg->medfltuv_ratio << 16; + isp3_param_write(params_vdev, value, ISP33_GIC_MEDFLTUV_PARA, id); + + value = arg->noisecurve_scale; + isp3_param_write(params_vdev, value, ISP33_GIC_NOISE_SCALE, id); + + value = arg->bffltwgt_offset | arg->bffltwgt_scale << 16; + isp3_param_write(params_vdev, value, ISP33_GIC_BILAT_PARA1, id); + + value = arg->bfflt_ratio; + isp3_param_write(params_vdev, value, ISP33_GIC_BILAT_PARA2, id); + + value = ISP_PACK_4BYTE(arg->bfflt_coeff0, arg->bfflt_coeff1, + arg->bfflt_coeff2, 0); + isp3_param_write(params_vdev, value, ISP33_GIC_DISWGT_COEFF, id); + + for (i = 0; i < ISP35_GIC_SIGMA_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->bfflt_vsigma_y[i * 2], + arg->bfflt_vsigma_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_GIC_SIGMA_Y0 + i * 4, id); + } + value = arg->bfflt_vsigma_y[i * 2]; + isp3_param_write(params_vdev, value, ISP33_GIC_SIGMA_Y8, id); + + value = (arg->luma_dx[0] & 0xf) | (arg->luma_dx[1] & 0xf) << 4 | + (arg->luma_dx[2] & 0xf) << 8 | (arg->luma_dx[3] & 0xf) << 12 | + (arg->luma_dx[4] & 0xf) << 16 | (arg->luma_dx[5] & 0xf) << 20 | + (arg->luma_dx[6] & 0xf) << 24; + isp3_param_write(params_vdev, value, ISP33_GIC_LUMA_DX, id); + + for (i = 0; i < ISP35_GIC_THRED_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->thred_y[i * 2], + arg->thred_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_GIC_THRED_Y0 + i * 4, id); + + value = ISP_PACK_2SHORT(arg->minthred_y[i * 2], + arg->minthred_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_GIC_MIN_THRED_Y0 + i * 4, id); + } + + value = arg->autonoisethred_scale; + isp3_param_write(params_vdev, value, ISP33_GIC_THRED_SCALE, id); + + value = ISP_PACK_4BYTE(arg->lofltgr_coeff0, arg->lofltgr_coeff1, + arg->lofltgr_coeff2, arg->lofltgr_coeff3); + isp3_param_write(params_vdev, value, ISP33_GIC_LOFLTGR_COEFF, id); + + value = ISP_PACK_4BYTE(arg->lofltgb_coeff0, arg->lofltgb_coeff1, 0, 0); + isp3_param_write(params_vdev, value, ISP33_GIC_LOFLTGB_COEFF, id); + + value = arg->sumlofltcoeff_inv; + isp3_param_write(params_vdev, value, ISP33_GIC_SUM_LOFLT_INV, id); + + value = ISP_PACK_4BYTE(arg->lofltthred_coeff0, arg->lofltthred_coeff1, 0, 0); + isp3_param_write(params_vdev, value, ISP33_GIC_LOFLTTHRED_COEFF, id); + + value = (arg->global_gain & 0x3ff) | + (arg->globalgain_alpha & 0xf) << 12 | + arg->globalgain_scale << 16; + isp3_param_write(params_vdev, value, ISP33_GIC_GAIN, id); + + value = ISP_PACK_2SHORT(arg->gain_offset, arg->gain_scale); + isp3_param_write(params_vdev, value, ISP33_GIC_GAIN_SLOPE, id); + + value = ISP_PACK_2SHORT(arg->gainadjflt_minthred, + arg->gainadjflt_maxthred); + isp3_param_write(params_vdev, value, ISP33_GIC_GAIN_THRED, id); +} + +static void +isp_gic_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_GIC_CONTROL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + val |= ISP35_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP33_GIC_FST_FRAME, id); + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP3X_GIC_CONTROL, id); +} + +static void +isp_enh_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_enh_cfg *arg, bool is_check, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + u32 i, j, val, ctrl = isp3_param_read(params_vdev, ISP33_ENH_CTRL, id); + + if (is_check && (!(ctrl & ISP35_MODULE_EN) || !arg->iir_wr)) + return; + + val = (arg->pre_wet_frame_cnt0 & 0xf) | + (arg->pre_wet_frame_cnt1 & 0xf) << 4; + isp3_param_write_direct(params_vdev, val, ISP33_ENH_PRE_FRAME); + for (i = 0; i < priv->enh_row; i++) { + val = ISP33_IIR_WR_ID(i) | ISP33_IIR_WR_CLEAR; + isp3_param_write_direct(params_vdev, val, ISP33_ENH_IIR_RW); + for (j = 0; j < priv->enh_col / 4; j++) { + val = ISP_PACK_4BYTE(arg->iir[i][j * 4], arg->iir[i][j * 4 + 1], + arg->iir[i][j * 4 + 2], arg->iir[i][j * 4 + 3]); + isp3_param_write_direct(params_vdev, val, ISP33_ENH_IIR0 + j * 4); + } + } +} + +static void +isp_enh_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_enh_cfg *arg, u32 id) +{ + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct isp33_enh_cfg *arg_rec = ¶ms_rec->others.enh_cfg; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + u32 w = out_crop->width, h = out_crop->height; + u32 i, value, ctrl, het_aliquant; + + if (dev->unite_div > ISP_UNITE_DIV1) + w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + h = h / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + priv->enh_col = ALIGN((w + 127) / 128, 4); + if (priv->enh_col > ISP35_ENH_IIR_COL_MAX) + priv->enh_col = ISP33_ENH_IIR_COL_MAX; + priv->enh_row = (h + 128) / 129; + if (priv->enh_row > ISP35_ENH_IIR_ROW_MAX) + priv->enh_row = ISP33_ENH_IIR_ROW_MAX; + het_aliquant = h % 3; + + ctrl = isp3_param_read(params_vdev, ISP33_ENH_CTRL, id); + ctrl &= ISP35_MODULE_EN; + ctrl |= !!arg->bypass << 1 | + !!arg->blf3_bypass << 2 | + (het_aliquant & 0x3) << 4 | + (priv->enh_row & 0x1f) << 8; + isp3_param_write(params_vdev, ctrl, ISP33_ENH_CTRL, id); + + value = arg->iir_inv_sigma | + arg->iir_soft_thed << 16 | + arg->iir_cur_wgt << 24; + isp3_param_write(params_vdev, value, ISP33_ENH_IIR_FLT, id); + + value = (arg->blf3_inv_sigma & 0x1ff) | + (arg->blf3_cur_wgt & 0x1ff) << 16 | + (arg->blf3_thumb_cur_wgt & 0xf) << 28; + isp3_param_write(params_vdev, value, ISP33_ENH_BILAT_FLT3X3, id); + + value = arg->blf5_inv_sigma | arg->blf5_cur_wgt << 16; + isp3_param_write(params_vdev, value, ISP33_ENH_BILAT_FLT5X5, id); + + value = arg->global_strg; + isp3_param_write(params_vdev, value, ISP33_ENH_GLOBAL_STRG, id); + + for (i = 0; i < ISP35_ENH_LUMA_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->lum2strg[i * 2], arg->lum2strg[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_ENH_LUMA_LUT0 + i * 4, id); + } + value = arg->lum2strg[i * 2]; + isp3_param_write(params_vdev, value, ISP33_ENH_LUMA_LUT8, id); + + for (i = 0; i < ISP35_ENH_DETAIL_NUM / 3; i++) { + value = (arg->detail2strg_idx[i * 3] & 0x3ff) | + (arg->detail2strg_idx[i * 3 + 1] & 0x3ff) << 10 | + (arg->detail2strg_idx[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_ENH_DETAIL_IDX0 + i * 4, id); + } + value = (arg->detail2strg_idx[i * 3] & 0x3ff) | + (arg->detail2strg_idx[i * 3 + 1] & 0x7ff) << 10; + isp3_param_write(params_vdev, value, ISP33_ENH_DETAIL_IDX2, id); + + value = (arg->detail2strg_power0 & 0xf) | + (arg->detail2strg_power1 & 0xf) << 4 | + (arg->detail2strg_power2 & 0xf) << 8 | + (arg->detail2strg_power3 & 0xf) << 12 | + (arg->detail2strg_power4 & 0xf) << 16 | + (arg->detail2strg_power5 & 0xf) << 20 | + (arg->detail2strg_power6 & 0xf) << 24; + isp3_param_write(params_vdev, value, ISP33_ENH_DETAIL_POWER, id); + + for (i = 0; i < ISP35_ENH_DETAIL_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->detail2strg_val[i * 2], + arg->detail2strg_val[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_ENH_DETAIL_VALUE0 + i * 4, id); + } + + if (dev->hw_dev->is_single && arg->iir_wr) + isp_enh_cfg_sram(params_vdev, arg, false, id); + else if (arg->iir_wr) + memcpy(arg_rec, arg, sizeof(struct isp33_enh_cfg)); +} + +static void +isp_enh_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP33_ENH_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + val |= ISP35_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP33_ENH_FST_FRAME, id); + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP33_ENH_CTRL, id); +} + +static void +isp_hist_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_hist_cfg *arg, bool is_check, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + u32 i, j, val, ctrl = isp3_param_read(params_vdev, ISP33_HIST_CTRL, id); + + if (is_check && (!(ctrl & ISP35_MODULE_EN) || !arg->iir_wr)) + return; + + val = (arg->stab_frame_cnt0 & 0xf) | + (arg->stab_frame_cnt1 & 0xf) << 4; + isp3_param_write_direct(params_vdev, val, ISP33_HIST_STAB); + for (i = 0; i < priv->hist_blk_num; i++) { + val = ISP33_IIR_WR_ID(i) | ISP33_IIR_WR_CLEAR; + isp3_param_write_direct(params_vdev, val, ISP33_HIST_RW); + for (j = 0; j < ISP35_HIST_IIR_NUM / 2; j++) { + val = ISP_PACK_2SHORT(arg->iir[i][2 * j], arg->iir[i][2 * j + 1]); + isp3_param_write_direct(params_vdev, val, ISP33_HIST_IIR0 + 4 * j); + } + } +} + +static void +isp_hist_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_hist_cfg *arg, u32 id) +{ + struct rkisp_device *dev = params_vdev->dev; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct isp33_hist_cfg *arg_rec = ¶ms_rec->others.hist_cfg; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + u32 w = out_crop->width, h = out_crop->height; + u32 value, ctrl, thumb_row, thumb_col, blk_het, blk_wid; + int i; + + if (dev->unite_div > ISP_UNITE_DIV1) + w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + h = h / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + + ctrl = isp3_param_read(params_vdev, ISP33_HIST_CTRL, id); + ctrl &= ISP35_MODULE_EN; + ctrl |= !!arg->bypass << 1 | !!arg->mem_mode << 4; + isp3_param_write(params_vdev, ctrl, ISP33_HIST_CTRL, id); + + value = arg->count_scale | arg->count_offset << 8 | + arg->count_min_limit << 16; + isp3_param_write(params_vdev, value, ISP33_HIST_HF_STAT, id); + + value = ISP_PACK_2SHORT(arg->merge_alpha, arg->user_set); + isp3_param_write(params_vdev, value, ISP33_HIST_MAP0, id); + + value = arg->map_count_scale | arg->gain_ref_wgt << 16; + isp3_param_write(params_vdev, value, ISP33_HIST_MAP1, id); + + value = arg->flt_inv_sigma | arg->flt_cur_wgt << 16; + isp3_param_write(params_vdev, value, ISP33_HIST_IIR, id); + + for (i = 0; i < ISP35_HIST_ALPHA_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->pos_alpha[i * 4], + arg->pos_alpha[i * 4 + 1], + arg->pos_alpha[i * 4 + 2], + arg->pos_alpha[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_HIST_POS_ALPHA0 + i * 4, id); + value = ISP_PACK_4BYTE(arg->neg_alpha[i * 4], + arg->neg_alpha[i * 4 + 1], + arg->neg_alpha[i * 4 + 2], + arg->neg_alpha[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_HIST_NEG_ALPHA0 + i * 4, id); + } + value = arg->pos_alpha[i * 4]; + isp3_param_write(params_vdev, value, ISP33_HIST_POS_ALPHA4, id); + value = arg->neg_alpha[i * 4]; + isp3_param_write(params_vdev, value, ISP33_HIST_NEG_ALPHA4, id); + + value = arg->saturate_scale; + isp3_param_write(params_vdev, value, ISP33_HIST_UV_SCL, id); + + thumb_row = arg->thumb_row > ISP33_HIST_THUMB_ROW_MAX ? + ISP33_HIST_THUMB_ROW_MAX : arg->thumb_row & ~1; + thumb_col = arg->thumb_col > ISP33_HIST_THUMB_COL_MAX ? + ISP33_HIST_THUMB_COL_MAX : arg->thumb_col & ~1; + blk_het = ALIGN(h / thumb_row, 2); + blk_wid = ALIGN(w / thumb_col, 2); + priv->hist_blk_num = thumb_row * thumb_col; + value = ISP_PACK_2SHORT(blk_het, blk_wid); + isp3_param_write(params_vdev, value, ISP33_HIST_BLOCK_SIZE, id); + value = ISP_PACK_4BYTE(thumb_row, thumb_col, 0, 0); + isp3_param_write(params_vdev, value, ISP33_HIST_THUMB_SIZE, id); + + if (dev->hw_dev->is_single && arg->iir_wr) + isp_hist_cfg_sram(params_vdev, arg, false, id); + else if (arg->iir_wr) + memcpy(arg_rec, arg, sizeof(struct isp33_hist_cfg)); +} + +static void +isp_hist_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP33_HIST_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + val |= ISP35_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP33_YHIST_FST_FRAME, id); + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP33_HIST_CTRL, id); +} + +static void +isp_hsv_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_hsv_cfg *arg, bool is_check, u32 id) +{ + u32 ctrl = isp3_param_read(params_vdev, ISP3X_3DLUT_CTRL, id); + u32 val, i, j; + + if (is_check && !(ctrl & ISP35_MODULE_EN)) + return; + + ctrl &= ~ISP35_SELF_FORCE_UPD; + ctrl |= ISP35_HSV_FIX_RW_CONFLICT; + isp3_param_write_direct(params_vdev, ctrl, ISP3X_3DLUT_CTRL); + for (i = 0; i < ISP35_HSV_2DLUT_ROW; i++) { + for (j = 0; j < ISP35_HSV_2DLUT_COL - 1; j += 2) { + val = ISP_PACK_2SHORT(arg->lut0_2d[i][j], arg->lut0_2d[i][j + 1]); + isp3_param_write_direct(params_vdev, val, ISP35_HSV_2DLUT0); + } + val = arg->lut0_2d[i][ISP35_HSV_2DLUT_COL - 1]; + isp3_param_write_direct(params_vdev, val, ISP35_HSV_2DLUT0); + } + if (arg->hsv_2dlut12_cfg) { + for (i = 0; i < ISP35_HSV_2DLUT_ROW; i++) { + for (j = 0; j < ISP35_HSV_2DLUT_COL - 1; j += 2) { + val = ISP_PACK_2SHORT(arg->lut1_2d[i][j], arg->lut1_2d[i][j + 1]); + isp3_param_write_direct(params_vdev, val, ISP35_HSV_2DLUT1); + } + val = arg->lut1_2d[i][ISP35_HSV_2DLUT_COL - 1]; + isp3_param_write_direct(params_vdev, val, ISP35_HSV_2DLUT1); + } + for (i = 0; i < ISP35_HSV_2DLUT_ROW; i++) { + for (j = 0; j < ISP35_HSV_2DLUT_COL - 1; j += 2) { + val = ISP_PACK_2SHORT(arg->lut2_2d[i][j], arg->lut2_2d[i][j + 1]); + isp3_param_write_direct(params_vdev, val, ISP35_HSV_2DLUT2); + } + val = arg->lut2_2d[i][ISP35_HSV_2DLUT_COL - 1]; + isp3_param_write_direct(params_vdev, val, ISP35_HSV_2DLUT2); + } + } else { + for (i = 0; i < ISP35_HSV_1DLUT_NUM / 2; i++) { + val = ISP_PACK_2SHORT(arg->lut0_1d[i * 2], arg->lut0_1d[i * 2 + 1]); + isp3_param_write_direct(params_vdev, val, ISP35_HSV_1DLUT); + } + val = arg->lut0_1d[ISP35_HSV_1DLUT_NUM - 1]; + isp3_param_write_direct(params_vdev, val, ISP35_HSV_1DLUT); + + for (i = 0; i < ISP35_HSV_1DLUT_NUM / 2; i++) { + val = ISP_PACK_2SHORT(arg->lut1_1d[i * 2], arg->lut1_1d[i * 2 + 1]); + isp3_param_write_direct(params_vdev, val, ISP35_HSV_1DLUT); + } + val = arg->lut1_1d[ISP35_HSV_1DLUT_NUM - 1]; + isp3_param_write_direct(params_vdev, val, ISP35_HSV_1DLUT); + } + ctrl &= ~ISP35_HSV_FIX_RW_CONFLICT; + isp3_param_write_direct(params_vdev, ctrl, ISP3X_3DLUT_CTRL); +} + +static void +isp_hsv_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_hsv_cfg *arg, u32 id) +{ + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct rkisp_device *dev = params_vdev->dev; + u32 val = isp3_param_read(params_vdev, ISP3X_3DLUT_CTRL, id); + + val &= ISP35_MODULE_EN; + val |= !!arg->hsv_1dlut0_en << 1 | + !!arg->hsv_1dlut1_en << 2 | + !!arg->hsv_2dlut0_en << 3 | + !!arg->hsv_2dlut1_en << 4 | + !!arg->hsv_2dlut2_en << 5 | + !!arg->hsv_2dlut12_cfg << 6; + isp3_param_write(params_vdev, val, ISP3X_3DLUT_CTRL, id); + + val = (arg->hsv_1dlut0_idx_mode & 0x3) | + (arg->hsv_1dlut1_idx_mode & 0x3) << 2 | + (arg->hsv_2dlut0_idx_mode & 0x3) << 4 | + (arg->hsv_2dlut1_idx_mode & 0x3) << 6 | + (arg->hsv_2dlut2_idx_mode & 0x3) << 8 | + (arg->hsv_1dlut0_item_mode & 0x7) << 10 | + (arg->hsv_1dlut1_item_mode & 0x7) << 13 | + (arg->hsv_2dlut0_item_mode & 0x3) << 16 | + (arg->hsv_2dlut1_item_mode & 0x3) << 18 | + (arg->hsv_2dlut2_item_mode & 0x3) << 20; + isp3_param_write(params_vdev, val, ISP35_HSV_MODE_CTRL, id); + if (dev->hw_dev->is_single) + isp_hsv_cfg_sram(params_vdev, arg, false, id); + params_rec->others.hsv_cfg = *arg; +} + +static void +isp_hsv_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_3DLUT_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_3DLUT_CTRL, id); +} + +static void +isp_ldch_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_ldch_cfg *arg, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct isp2x_mesh_head *head; + int buf_idx, i; + u32 value; + + value = isp3_param_read(params_vdev, ISP3X_LDCH_STS, id); + value &= ISP35_MODULE_EN; + value |= !!arg->map13p3_en << 7 | + !!arg->force_map_en << 6 | + !!arg->bic_mode_en << 4 | + !!arg->sample_avr_en << 3 | + !!arg->frm_end_dis << 1; + isp3_param_write(params_vdev, value, ISP3X_LDCH_STS, id); + if (arg->bic_mode_en) { + for (i = 0; i < ISP35_LDCH_BIC_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->bicubic[i * 4], arg->bicubic[i * 4 + 1], + arg->bicubic[i * 4 + 2], arg->bicubic[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP32_LDCH_BIC_TABLE0 + i * 4, id); + } + } + + for (i = 0; i < ISP35_MESH_BUF_NUM; i++) { + if (!priv->buf_ldch[id][i].mem_priv) + continue; + if (arg->buf_fd == priv->buf_ldch[id][i].dma_fd) + break; + } + if (i == ISP35_MESH_BUF_NUM) { + dev_err(dev->dev, "cannot find ldch buf fd(%d)\n", arg->buf_fd); + return; + } + + if (!priv->buf_ldch[id][i].vaddr) { + dev_err(dev->dev, "no ldch buffer allocated\n"); + return; + } + + buf_idx = priv->buf_ldch_idx[id]; + head = (struct isp2x_mesh_head *)priv->buf_ldch[id][buf_idx].vaddr; + head->stat = MESH_BUF_INIT; + + buf_idx = i; + head = (struct isp2x_mesh_head *)priv->buf_ldch[id][buf_idx].vaddr; + head->stat = MESH_BUF_CHIPINUSE; + priv->buf_ldch_idx[id] = buf_idx; + rkisp_prepare_buffer(dev, &priv->buf_ldch[id][buf_idx]); + value = priv->buf_ldch[id][buf_idx].dma_addr + head->data_oft; + isp3_param_write(params_vdev, value, ISP3X_MI_LUT_LDCH_RD_BASE, id); + isp3_param_write(params_vdev, arg->hsize, ISP3X_MI_LUT_LDCH_RD_H_WSIZE, id); + isp3_param_write(params_vdev, arg->vsize, ISP3X_MI_LUT_LDCH_RD_V_SIZE, id); +} + +static void +isp_ldch_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + u32 val = isp3_param_read(params_vdev, ISP3X_LDCH_STS, id); + u32 buf_idx; + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + buf_idx = priv->buf_ldch_idx[id]; + if (!priv->buf_ldch[id][buf_idx].vaddr) { + dev_err(dev->dev, "no ldch buffer allocated\n"); + return; + } + val |= ISP35_MODULE_EN; + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP3X_LDCH_STS, id); +} + +static void +isp_ynr_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_ynr_cfg *arg, u32 id) +{ + u32 i, value; + + value = isp3_param_read(params_vdev, ISP3X_YNR_GLOBAL_CTRL, id); + value &= ISP35_MODULE_EN; + + value |= !!arg->hi_spnr_bypass << 1 | + !!arg->mi_spnr_bypass << 2 | + !!arg->lo_spnr_bypass << 3 | + !!arg->rnr_en << 4 | + !!arg->tex2lo_strg_en << 5 | + !!arg->hi_lp_en << 6 | + !!arg->dsfilt_bypass << 7 | + !!arg->tex2wgt_en << 8; + isp3_param_write(params_vdev, value, ISP3X_YNR_GLOBAL_CTRL, id); + + value = (arg->global_set_gain & 0x3ff) | + (arg->gain_merge_alpha & 0xf) << 12 | + arg->local_gain_scale << 16; + isp3_param_write(params_vdev, value, ISP33_YNR_GAIN_CTRL, id); + + for (i = 0; i < ISP35_YNR_ADJ_NUM / 3; i++) { + value = (arg->lo_spnr_gain2strg[i * 3] & 0x1ff) | + (arg->lo_spnr_gain2strg[i * 3 + 1] & 0x1ff) << 10 | + (arg->lo_spnr_gain2strg[i * 3 + 2] & 0x1ff) << 20; + isp3_param_write(params_vdev, value, ISP33_YNR_GAIN_ADJ_0_2 + i * 4, id); + } + + value = arg->rnr_max_radius; + isp3_param_write(params_vdev, value, ISP33_YNR_RNR_MAX_R, id); + + value = ISP_PACK_2SHORT(arg->rnr_center_h, arg->rnr_center_v); + isp3_param_write(params_vdev, value, ISP33_YNR_RNR_CENTER_COOR, id); + + for (i = 0; i < ISP35_YNR_XY_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->radius2strg[i * 4], + arg->radius2strg[i * 4 + 1], + arg->radius2strg[i * 4 + 2], + arg->radius2strg[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_YNR_RNR_STRENGTH03 + i * 4, id); + } + value = arg->radius2strg[i * 4]; + isp3_param_write(params_vdev, value, ISP33_YNR_RNR_STRENGTH16, id); + + for (i = 0; i < ISP35_YNR_XY_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->luma2sima_x[i * 2], + arg->luma2sima_x[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_YNR_SGM_DX_0_1 + i * 4, id); + + value = ISP_PACK_2SHORT(arg->luma2sima_y[i * 2], + arg->luma2sima_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_YNR_SGM_Y_0_1 + i * 4, id); + } + value = arg->luma2sima_x[i * 2]; + isp3_param_write(params_vdev, value, ISP33_YNR_SGM_DX_16, id); + value = arg->luma2sima_y[i * 2]; + isp3_param_write(params_vdev, value, ISP33_YNR_SGM_Y_16, id); + + for (i = 0; i < ISP35_YNR_TEX2WGT_NUM / 3; i++) { + value = arg->mi_spnr_tex2wgt_scale[i * 3] | + arg->mi_spnr_tex2wgt_scale[i * 3 + 1] << 10 | + arg->mi_spnr_tex2wgt_scale[i * 3 + 2] << 20; + isp3_param_write(params_vdev, value, ISP35_YNR_MI_TEX2WGT_SCALE_0_1_2 + i * 4, id); + value = arg->lo_spnr_tex2wgt_scale[i * 3] | + arg->lo_spnr_tex2wgt_scale[i * 3 + 1] << 10 | + arg->lo_spnr_tex2wgt_scale[i * 3 + 2] << 20; + isp3_param_write(params_vdev, value, ISP35_YNR_LO_TEX2WGT_SCALE_0_1_2 + i * 4, id); + } + + value = (arg->hi_spnr_sigma_min_limit & 0x7ff) | + (arg->hi_spnr_local_gain_alpha & 0x1f) << 11 | + (arg->hi_spnr_strg & 0x3ff) << 16; + isp3_param_write(params_vdev, value, ISP33_YNR_HI_SIGMA_GAIN, id); + + value = (arg->hi_spnr_filt_coeff[0] & 0x3f) | + (arg->hi_spnr_filt_coeff[1] & 0x3f) << 6 | + (arg->hi_spnr_filt_coeff[2] & 0x3f) << 12 | + (arg->hi_spnr_filt_coeff[3] & 0x3f) << 18; + isp3_param_write(params_vdev, value, ISP33_YNR_HI_GAUS_COE, id); + + value = (arg->hi_spnr_filt_wgt_offset & 0x3ff) | + (arg->hi_spnr_filt_center_wgt & 0x1fff) << 10; + isp3_param_write(params_vdev, value, ISP33_YNR_HI_WEIGHT, id); + + value = (arg->hi_spnr_filt1_coeff[0] & 0x1ff) | + (arg->hi_spnr_filt1_coeff[1] & 0x1ff) << 10 | + (arg->hi_spnr_filt1_coeff[2] & 0x1ff) << 20; + isp3_param_write(params_vdev, value, ISP33_YNR_HI_GAUS1_COE_0_2, id); + value = (arg->hi_spnr_filt1_coeff[3] & 0x1ff) | + (arg->hi_spnr_filt1_coeff[4] & 0x1ff) << 10 | + (arg->hi_spnr_filt1_coeff[5] & 0x1ff) << 20; + isp3_param_write(params_vdev, value, ISP33_YNR_HI_GAUS1_COE_3_5, id); + + value = (arg->hi_spnr_filt1_tex_thred & 0x7ff) | + (arg->hi_spnr_filt1_tex_scale & 0x3ff) << 12 | + (arg->hi_spnr_filt1_wgt_alpha & 0x1ff) << 22; + isp3_param_write(params_vdev, value, ISP33_YNR_HI_TEXT, id); + + value = arg->mi_spnr_filt_coeff0 | + arg->mi_spnr_filt_coeff1 << 10 | + arg->mi_spnr_filt_coeff2 << 20; + isp3_param_write(params_vdev, value, ISP33_YNR_MI_GAUS_COE, id); + value = arg->mi_spnr_filt_coeff3 | arg->mi_spnr_filt_coeff4 << 10; + isp3_param_write(params_vdev, value, ISP35_YNR_MI_GAUS_COE1, id); + + value = ISP_PACK_2SHORT(arg->mi_spnr_strg, arg->mi_spnr_soft_thred_scale); + isp3_param_write(params_vdev, value, ISP33_YNR_MI_STRG_DETAIL, id); + + value = arg->mi_spnr_wgt | + (arg->mi_spnr_filt_center_wgt & 0x7ff) << 10 | + !!arg->mi_ehance_scale_en << 23 | + arg->mi_ehance_scale << 24; + isp3_param_write(params_vdev, value, ISP33_YNR_MI_WEIGHT, id); + + value = (arg->dsfilt_diff_offset & 0x3ff) | + (arg->dsfilt_center_wgt & 0x7ff) << 10 | + (arg->dsfilt_strg & 0x3ff) << 21; + isp3_param_write(params_vdev, value, ISP35_YNR_DSIIR_COE, id); + + value = ISP_PACK_2SHORT(arg->lo_spnr_strg, arg->lo_spnr_soft_thred_scale); + isp3_param_write(params_vdev, value, ISP33_YNR_LO_STRG_DETAIL, id); + + value = (arg->lo_spnr_thumb_thred_scale & 0x3ff) | + (arg->tex2lo_strg_mantissa & 0x7ff) << 12 | + (arg->tex2lo_strg_exponent & 0xf) << 24; + isp3_param_write(params_vdev, value, ISP33_YNR_LO_LIMIT_SCALE, id); + + value = arg->lo_spnr_wgt | + (arg->lo_spnr_filt_center_wgt & 0x1fff) << 10 | + arg->lo_enhance_scale << 24; + isp3_param_write(params_vdev, value, ISP33_YNR_LO_WEIGHT, id); + + value = (arg->tex2lo_strg_upper_thred & 0x3ff) | + (arg->tex2lo_strg_lower_thred & 0x3ff) << 12; + isp3_param_write(params_vdev, value, ISP33_YNR_LO_TEXT_THRED, id); + + for (i = 0; i < ISP35_YNR_ADJ_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->lo_gain2wgt[i * 4], + arg->lo_gain2wgt[i * 4 + 1], + arg->lo_gain2wgt[i * 4 + 2], + arg->lo_gain2wgt[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_YNR_FUSION_WEIT_ADJ_0_3 + i * 4, id); + } + value = arg->lo_gain2wgt[i * 4]; + isp3_param_write(params_vdev, value, ISP33_YNR_FUSION_WEIT_ADJ_8, id); +} + +static void +isp_ynr_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_YNR_GLOBAL_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + val |= ISP35_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP3X_YNR_FST_FRAME, id); + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP3X_YNR_GLOBAL_CTRL, id); +} + +static void +isp_cnr_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_cnr_cfg *arg, u32 id) +{ + u32 i, value, ctrl, gain_ctrl; + + gain_ctrl = isp3_param_read(params_vdev, ISP3X_GAIN_CTRL, id); + ctrl = isp3_param_read(params_vdev, ISP3X_CNR_CTRL, id); + ctrl &= ISP35_MODULE_EN; + + ctrl |= !!arg->hsv_alpha_en << 18 | + (arg->loflt_coeff & 0x3f) << 12 | + !!arg->local_alpha_dis << 11 | + !!arg->hiflt_wgt0_mode << 8 | + !!arg->uv_dis << 6 | + (arg->thumb_mode & 0x3) << 4 | + !!arg->yuv422_mode << 2 | + !!arg->exgain_bypass << 1; + value = (arg->global_gain & 0x3ff) | + (arg->global_gain_alpha & 0xf) << 12 | + arg->local_gain_scale << 16; + /* gain disable, using global gain for cnr */ + if (ctrl & ISP35_MODULE_EN && !(gain_ctrl & ISP35_MODULE_EN)) { + ctrl |= BIT(1); + value &= ~ISP3X_CNR_GLOBAL_GAIN_ALPHA_MAX; + value |= BIT(15); + } + isp3_param_write(params_vdev, ctrl, ISP3X_CNR_CTRL, id); + isp3_param_write(params_vdev, value, ISP3X_CNR_EXGAIN, id); + + value = ISP_PACK_2SHORT(arg->lobfflt_vsigma_uv, arg->lobfflt_vsigma_y); + isp3_param_write(params_vdev, value, ISP32_CNR_THUMB1, id); + + value = arg->lobfflt_alpha; + isp3_param_write(params_vdev, value, ISP32_CNR_THUMB_BF_RATIO, id); + + value = ISP_PACK_4BYTE(arg->thumb_bf_coeff0, arg->thumb_bf_coeff1, + arg->thumb_bf_coeff2, arg->thumb_bf_coeff3); + isp3_param_write(params_vdev, value, ISP32_CNR_LBF_WEITD, id); + + value = (arg->loflt_uv_gain & 0xf) | + arg->loflt_vsigma << 4 | + (arg->exp_x_shift_bit & 0x3f) << 12 | + (arg->loflt_wgt_slope & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP32_CNR_IIR_PARA1, id); + + value = ISP_PACK_4BYTE(arg->loflt_wgt_min_thred, arg->loflt_wgt_max_limit, 0, 0); + isp3_param_write(params_vdev, value, ISP32_CNR_IIR_PARA2, id); + + value = ISP_PACK_4BYTE(arg->gaus_flt_coeff[0], arg->gaus_flt_coeff[1], + arg->gaus_flt_coeff[2], arg->gaus_flt_coeff[3]); + isp3_param_write(params_vdev, value, ISP32_CNR_GAUS_COE1, id); + + value = ISP_PACK_4BYTE(arg->gaus_flt_coeff[4], arg->gaus_flt_coeff[5], 0, 0); + isp3_param_write(params_vdev, value, ISP32_CNR_GAUS_COE2, id); + + value = (arg->gaus_flt_alpha & 0x7ff) | + arg->hiflt_wgt_min_limit << 12 | + (arg->hiflt_alpha & 0x7ff) << 20; + isp3_param_write(params_vdev, value, ISP32_CNR_GAUS_RATIO, id); + + value = arg->hiflt_uv_gain | + (arg->hiflt_global_vsigma & 0x3fff) << 8 | + arg->hiflt_cur_wgt << 24; + isp3_param_write(params_vdev, value, ISP32_CNR_BF_PARA1, id); + + value = ISP_PACK_2SHORT(arg->adj_offset, arg->adj_scale); + isp3_param_write(params_vdev, value, ISP32_CNR_BF_PARA2, id); + + for (i = 0; i < ISP35_CNR_SIGMA_Y_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->sgm_ratio[i * 4], arg->sgm_ratio[i * 4 + 1], + arg->sgm_ratio[i * 4 + 2], arg->sgm_ratio[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP32_CNR_SIGMA0 + i * 4, id); + } + value = arg->sgm_ratio[i * 4] | arg->bf_merge_max_limit << 16; + isp3_param_write(params_vdev, value, ISP32_CNR_SIGMA0 + i * 4, id); + + value = arg->loflt_global_sgm_ratio | + (arg->loflt_global_sgm_ratio_alpha & 0xf) << 8 | + (arg->bf_alpha_max_limit & 0x7ff) << 16; + isp3_param_write(params_vdev, value, ISP32_CNR_IIR_GLOBAL_GAIN, id); + + for (i = 0; i < ISP35_CNR_WGT_SIGMA_Y_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->cur_wgt[i * 4], arg->cur_wgt[i * 4 + 1], + arg->cur_wgt[i * 4 + 2], arg->cur_wgt[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP39_CNR_WGT_SIGMA0 + i * 4, id); + } + value = arg->cur_wgt[i * 4]; + isp3_param_write(params_vdev, value, ISP39_CNR_WGT_SIGMA3, id); + + for (i = 0; i < ISP35_CNR_GAUS_SIGMAR_NUM / 3; i++) { + value = (arg->hiflt_vsigma_idx[i * 3] & 0x3ff) | + (arg->hiflt_vsigma_idx[i * 3 + 1] & 0x3ff) << 10 | + (arg->hiflt_vsigma_idx[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP39_CNR_GAUS_X_SIGMAR0 + i * 4, id); + } + value = (arg->hiflt_vsigma_idx[i * 3] & 0x3ff) | + (arg->hiflt_vsigma_idx[i * 3 + 1] & 0x3ff) << 10; + isp3_param_write(params_vdev, value, ISP39_CNR_GAUS_X_SIGMAR2, id); + + for (i = 0; i < ISP35_CNR_GAUS_SIGMAR_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->hiflt_vsigma[i * 2], arg->hiflt_vsigma[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP39_CNR_GAUS_Y_SIGMAR0 + i * 4, id); + } + + for (i = 0; i < ISP35_CNR_WGT_SIGMA_Y_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->lo_flt_vsigma[i * 4], arg->lo_flt_vsigma[i * 4 + 1], + arg->lo_flt_vsigma[i * 4 + 2], arg->lo_flt_vsigma[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP35_CNR_IIR_SIGMAR0 + i * 4, id); + } + value = arg->lo_flt_vsigma[i * 4]; + isp3_param_write(params_vdev, value, ISP35_CNR_IIR_SIGMAR3, id); + + for (i = 0; i < ISP35_CNR_CURVE_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->hsv_adj_alpha_table[i * 4], + arg->hsv_adj_alpha_table[i * 4 + 1], + arg->hsv_adj_alpha_table[i * 4 + 2], + arg->hsv_adj_alpha_table[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP35_CNR_HSV_CURVE0 + i * 4, id); + value = ISP_PACK_4BYTE(arg->sat_adj_alpha_table[i * 4], + arg->sat_adj_alpha_table[i * 4 + 1], + arg->sat_adj_alpha_table[i * 4 + 2], + arg->sat_adj_alpha_table[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP35_CNR_SAT_CURVE0 + i * 4, id); + value = ISP_PACK_4BYTE(arg->gain_adj_alpha_table[i * 4], + arg->gain_adj_alpha_table[i * 4 + 1], + arg->gain_adj_alpha_table[i * 4 + 2], + arg->gain_adj_alpha_table[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP35_CNR_GAIN_ADJ_CURVE0 + i * 4, id); + } + value = arg->hsv_adj_alpha_table[i * 4] | + arg->hsv_adj_alpha_table[i * 4 + 1] << 8; + isp3_param_write(params_vdev, value, ISP35_CNR_HSV_CURVE2, id); + value = arg->sat_adj_alpha_table[i * 4] | + arg->sat_adj_alpha_table[i * 4 + 1] << 8; + isp3_param_write(params_vdev, value, ISP35_CNR_SAT_CURVE2, id); + value = arg->gain_adj_alpha_table[i * 4] | + arg->gain_adj_alpha_table[i * 4 + 1] << 8; + isp3_param_write(params_vdev, value, ISP35_CNR_GAIN_ADJ_CURVE2, id); +} + +static void +isp_cnr_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_CNR_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + val |= ISP35_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP3X_CNR_FST_FRAME, id); + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP3X_CNR_CTRL, id); +} + +static void +isp_sharp_cfg_noise_curve(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_sharp_cfg *arg, u32 id, bool direct) +{ + struct rkisp_device *dev = params_vdev->dev; + u32 i, value; + + for (i = 0; i < ISP35_SHARP_NOISE_CURVE_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->noise_curve_ext[i * 2], + arg->noise_curve_ext[i * 2 + 1]); + rkisp_idx_write(dev, ISP33_SHARP_NOISE_CURVE0 + i * 4, value, id, direct); + } + value = (arg->noise_curve_ext[i * 2] & 0x7ff) | + arg->noise_count_thred_ratio << 12 | + arg->noise_clip_scale << 20; + rkisp_idx_write(dev, ISP33_SHARP_NOISE_CURVE8, value, id, direct); +} + +static void +isp_sharp_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_sharp_cfg *arg, u32 id) +{ + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + u32 i, value; + + value = isp3_param_read(params_vdev, ISP3X_SHARP_EN, id); + value &= ISP35_MODULE_EN; + + value |= !!arg->bypass << 1 | + !!arg->local_gain_bypass << 2 | + !!arg->tex_est_mode << 3 | + !!arg->max_min_flt_mode << 4 | + !!arg->detail_fusion_wgt_mode << 5 | + !!arg->noise_calc_mode << 6 | + !!arg->radius_step_mode << 7 | + !!arg->noise_curve_mode << 8 | + !!arg->gain_wgt_mode << 9 | + !!arg->detail_lp_en << 10 | + (arg->debug_mode & 0x7) << 12; + isp3_param_write(params_vdev, value, ISP3X_SHARP_EN, id); + + value = ISP_PACK_2SHORT(arg->fst_noise_scale, arg->fst_sigma_scale); + isp3_param_write(params_vdev, value, ISP33_SHARP_TEXTURE0, id); + + value = ISP_PACK_2SHORT(arg->fst_sigma_offset, arg->fst_wgt_scale); + isp3_param_write(params_vdev, value, ISP33_SHARP_TEXTURE1, id); + + value = (arg->tex_wgt_mode & 0x3) << 8 | + (arg->noise_est_alpha & 0x3f) << 12; + isp3_param_write(params_vdev, value, ISP33_SHARP_TEXTURE2, id); + + value = ISP_PACK_2SHORT(arg->sec_noise_scale, arg->sec_sigma_scale); + isp3_param_write(params_vdev, value, ISP33_SHARP_TEXTURE3, id); + + value = ISP_PACK_2SHORT(arg->sec_sigma_offset, arg->sec_wgt_scale); + isp3_param_write(params_vdev, value, ISP33_SHARP_TEXTURE4, id); + + value = arg->img_hpf_coeff[0] << 24; + isp3_param_write(params_vdev, value, ISP33_SHARP_HPF_KERNEL0, id); + value = ISP_PACK_4BYTE(arg->img_hpf_coeff[1], arg->img_hpf_coeff[2], + arg->img_hpf_coeff[3], arg->img_hpf_coeff[4]); + isp3_param_write(params_vdev, value, ISP33_SHARP_HPF_KERNEL1, id); + + value = ISP_PACK_4BYTE(arg->img_hpf_coeff[5], arg->texWgt_flt_coeff0, + arg->texWgt_flt_coeff1, arg->texWgt_flt_coeff2); + isp3_param_write(params_vdev, value, ISP33_SHARP_TEXFLT_KERNEL, id); + + value = arg->detail_in_alpha | + (arg->pre_bifilt_slope_fix & 0x7ff) << 8 | + (arg->pre_bifilt_alpha & 0x3f) << 20 | + !!arg->fusion_wgt_min_limit << 28 | + !!arg->fusion_wgt_max_limit << 29; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL0, id); + + value = (arg->luma_dx[6] & 0x0F) << 24 | + (arg->luma_dx[5] & 0x0F) << 20 | + (arg->luma_dx[4] & 0x0F) << 16 | + (arg->luma_dx[3] & 0x0F) << 12 | + (arg->luma_dx[2] & 0x0F) << 8 | + (arg->luma_dx[1] & 0x0F) << 4 | + (arg->luma_dx[0] & 0x0F); + isp3_param_write(params_vdev, value, ISP33_SHARP_LUMA_DX, id); + + for (i = 0; i < ISP35_SHARP_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->pre_bifilt_vsigma_inv[i * 2], + arg->pre_bifilt_vsigma_inv[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_SHARP_PBF_VSIGMA0 + i * 4, id); + } + + value = (arg->pre_bifilt_coeff0 & 0x3f) | + (arg->pre_bifilt_coeff1 & 0x3f) << 8 | + (arg->pre_bifilt_coeff2 & 0x3f) << 16; + isp3_param_write(params_vdev, value, ISP33_SHARP_PBF_KERNEL, id); + + value = ISP_PACK_4BYTE(arg->hi_detail_lpf_coeff[0], arg->hi_detail_lpf_coeff[1], + arg->hi_detail_lpf_coeff[2], arg->hi_detail_lpf_coeff[3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_KERNEL0, id); + value = ISP_PACK_4BYTE(arg->hi_detail_lpf_coeff[4], arg->hi_detail_lpf_coeff[5], + arg->mi_detail_lpf_coeff[0], arg->mi_detail_lpf_coeff[1]); + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_KERNEL1, id); + value = ISP_PACK_4BYTE(arg->mi_detail_lpf_coeff[2], arg->mi_detail_lpf_coeff[3], + arg->mi_detail_lpf_coeff[4], arg->mi_detail_lpf_coeff[5]); + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_KERNEL2, id); + + value = arg->global_gain | arg->gain_merge_alpha << 16 | arg->local_gain_scale << 24; + isp3_param_write(params_vdev, value, ISP33_SHARP_GAIN, id); + + value = ISP_PACK_4BYTE(arg->edge_gain_max_limit, arg->edge_gain_min_limit, + arg->detail_gain_max_limit, arg->detail_gain_min_limit); + isp3_param_write(params_vdev, value, ISP33_SHARP_GAIN_ADJ0, id); + + value = ISP_PACK_4BYTE(arg->hitex_gain_max_limit, arg->hitex_gain_min_limit, 0, 0); + isp3_param_write(params_vdev, value, ISP33_SHARP_GAIN_ADJ1, id); + + value = ISP_PACK_4BYTE(arg->edge_gain_slope, arg->detail_gain_slope, + arg->hitex_gain_slope, 0); + isp3_param_write(params_vdev, value, ISP33_SHARP_GAIN_ADJ2, id); + + value = (arg->edge_gain_offset & 0x3ff) | + (arg->detail_gain_offset & 0x3ff) << 10 | + (arg->hitex_gain_offset & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_GAIN_ADJ3, id); + + value = ISP_PACK_2SHORT(arg->edge_gain_sigma, arg->detail_gain_sigma); + isp3_param_write(params_vdev, value, ISP33_SHARP_GAIN_ADJ4, id); + + value = ISP_PACK_2SHORT(arg->pos_edge_wgt_scale, arg->neg_edge_wgt_scale); + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE0, id); + + value = ISP_PACK_4BYTE(arg->pos_edge_strg, arg->neg_edge_strg, + arg->overshoot_alpha, arg->undershoot_alpha); + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE1, id); + + for (i = 0; i < ISP35_SHARP_EDGE_KERNEL_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->edge_bpf_coeff[i * 4], + arg->edge_bpf_coeff[i * 4 + 1], + arg->edge_bpf_coeff[i * 4 + 2], + arg->edge_bpf_coeff[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE_KERNEL0 + i * 4, id); + } + value = ISP_PACK_4BYTE(arg->edge_bpf_coeff[i * 4], arg->edge_bpf_coeff[i * 4 + 1], 0, 0); + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE_KERNEL2, id); + + for (i = 0; i < ISP35_SHARP_EDGE_WGT_NUM / 3; i++) { + value = (arg->edge_wgt_val[i * 3] & 0x3ff) | + (arg->edge_wgt_val[i * 3 + 1] & 0x3ff) << 10 | + (arg->edge_wgt_val[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE_WGT_VAL0 + i * 4, id); + } + value = (arg->edge_wgt_val[i * 3] & 0x3ff) | + (arg->edge_wgt_val[i * 3 + 1] & 0x3ff) << 10; + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE_WGT_VAL5, id); + + for (i = 0; i < ISP35_SHARP_LUMA_STRG_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->luma2strg[i * 4], arg->luma2strg[i * 4 + 1], + arg->luma2strg[i * 4 + 2], arg->luma2strg[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_LUMA_ADJ_STRG0 + i * 4, id); + } + + value = ISP_PACK_2SHORT(arg->center_x, arg->center_y); + isp3_param_write(params_vdev, value, ISP33_SHARP_CENTER, id); + + value = ISP_PACK_2SHORT(arg->flat_max_limit, arg->edge_min_limit); + isp3_param_write(params_vdev, value, ISP33_SHARP_OUT_LIMIT, id); + + value = arg->tex_x_inv_fix0; + isp3_param_write(params_vdev, value, ISP33_SHARP_TEX_X_INV_FIX0, id); + value = arg->tex_x_inv_fix1; + isp3_param_write(params_vdev, value, ISP33_SHARP_TEX_X_INV_FIX1, id); + value = arg->tex_x_inv_fix2; + isp3_param_write(params_vdev, value, ISP33_SHARP_TEX_X_INV_FIX2, id); + + value = (arg->tex2loss_tex_in_hinr_strg[0] & 0x3ff) << 10 | + (arg->tex2loss_tex_in_hinr_strg[1] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_LOCAL_STRG1, id); + value = (arg->tex2loss_tex_in_hinr_strg[2] & 0x3ff) | + (arg->tex2loss_tex_in_hinr_strg[3] & 0x3ff) << 10; + isp3_param_write(params_vdev, value, ISP33_SHARP_LOCAL_STRG2, id); + + for (i = 0; i < ISP35_SHARP_CONTRAST_STRG_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->contrast2pos_strg[i * 4], + arg->contrast2pos_strg[i * 4 + 1], + arg->contrast2pos_strg[i * 4 + 2], + arg->contrast2pos_strg[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_SCALE_TAB0 + i * 4, id); + value = ISP_PACK_4BYTE(arg->contrast2neg_strg[i * 4], + arg->contrast2neg_strg[i * 4 + 1], + arg->contrast2neg_strg[i * 4 + 2], + arg->contrast2neg_strg[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_SCALE_TAB3 + i * 4, id); + } + value = arg->contrast2pos_strg[i * 4] | arg->pos_detail_strg << 8; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_SCALE_TAB2, id); + value = arg->contrast2neg_strg[i * 4] | arg->neg_detail_strg << 8; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_SCALE_TAB5, id); + + for (i = 0; i < ISP35_SHARP_TEX_CLIP_NUM / 3; i++) { + value = (arg->tex2detail_pos_clip[i * 3] & 0x3ff) | + (arg->tex2detail_pos_clip[i * 3 + 1] & 0x3ff) << 10 | + (arg->tex2detail_pos_clip[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_TEX_CLIP0 + i * 4, id); + value = (arg->tex2detail_neg_clip[i * 3] & 0x3ff) | + (arg->tex2detail_neg_clip[i * 3 + 1] & 0x3ff) << 10 | + (arg->tex2detail_neg_clip[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_TEX_CLIP3 + i * 4, id); + + value = (arg->tex2grain_pos_clip[i * 3] & 0x3ff) | + (arg->tex2grain_pos_clip[i * 3 + 1] & 0x3ff) << 10 | + (arg->tex2grain_pos_clip[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_GRAIN_TEX_CLIP0 + i * 4, id); + value = (arg->tex2grain_neg_clip[i * 3] & 0x3ff) | + (arg->tex2grain_neg_clip[i * 3 + 1] & 0x3ff) << 10 | + (arg->tex2grain_neg_clip[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_GRAIN_TEX_CLIP3 + i * 4, id); + } + + for (i = 0; i < ISP35_SHARP_LUM_CLIP_NUM / 3; i++) { + value = (arg->luma2detail_pos_clip[i * 3] & 0x3ff) | + (arg->luma2detail_pos_clip[i * 3 + 1] & 0x3ff) << 10 | + (arg->luma2detail_pos_clip[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_LUMA_CLIP0 + i * 4, id); + + value = (arg->luma2detail_neg_clip[i * 3] & 0x3ff) | + (arg->luma2detail_neg_clip[i * 3 + 1] & 0x3ff) << 10 | + (arg->luma2detail_neg_clip[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_LUMA_CLIP3 + i * 4, id); + } + value = (arg->luma2detail_pos_clip[i * 3] & 0x3ff) | + (arg->luma2detail_pos_clip[i * 3 + 1] & 0x3ff) << 10; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_LUMA_CLIP2, id); + value = (arg->luma2detail_neg_clip[i * 3] & 0x3ff) | + (arg->luma2detail_neg_clip[i * 3 + 1] & 0x3ff) << 10; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL_LUMA_CLIP5, id); + + value = arg->grain_strg; + isp3_param_write(params_vdev, value, ISP33_SHARP_GRAIN_STRG, id); + + for (i = 0; i < ISP35_SHARP_HUE_NUM / 3; i++) { + value = (arg->hue2strg[i * 3] & 0x3ff) | + (arg->hue2strg[i * 3 + 1] & 0x3ff) << 10 | + (arg->hue2strg[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_HUE_ADJ_TAB0 + i * 4, id); + } + + for (i = 0; i < ISP35_SHARP_DISATANCE_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->distance2strg[i * 4], + arg->distance2strg[i * 4 + 1], + arg->distance2strg[i * 4 + 2], + arg->distance2strg[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_DISATANCE_ADJ0 + i * 4, id); + } + value = ISP_PACK_4BYTE(arg->distance2strg[i * 4], + arg->distance2strg[i * 4 + 1], + arg->distance2strg[i * 4 + 2], 0); + isp3_param_write(params_vdev, value, ISP33_SHARP_DISATANCE_ADJ2, id); + + for (i = 0; i < ISP35_SHARP_TEX_NUM / 3; i++) { + value = (arg->tex2detail_strg[i * 3] & 0x3ff) | + (arg->tex2detail_strg[i * 3 + 1] & 0x3ff) << 10 | + (arg->tex2detail_strg[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP35_SHARP_TEX2DETAIL_STRG0 + i * 4, id); + } + + for (i = 0; i < ISP35_SHARP_TEX_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->hi_tex_threshold[i * 2], + arg->hi_tex_threshold[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_SHARP_NOISE_SIGMA0 + i * 4, id); + } + value = arg->hi_tex_threshold[i * 2]; + isp3_param_write(params_vdev, value, ISP33_SHARP_NOISE_SIGMA4, id); + + for (i = 0; i < ISP35_SHARP_TEX_NUM / 3; i++) { + value = (arg->tex2mf_detail_strg[i * 3] & 0x3ff) | + (arg->tex2mf_detail_strg[i * 3 + 1] & 0x3ff) << 10 | + (arg->tex2mf_detail_strg[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP35_SHARP_TEX2MFDETAIL_STRG0 + i * 4, id); + } + + value = arg->loss_tex_in_hinr_strg; + isp3_param_write(params_vdev, value, ISP33_SHARP_LOSSTEXINHINR_STRG, id); + + value = ISP_PACK_2SHORT(arg->noise_clip_min_limit, arg->noise_clip_max_limit); + isp3_param_write(params_vdev, value, ISP33_SHARP_NOISE_CLIP, id); + + value = arg->edge_wgt_flt_coeff0 | + arg->edge_wgt_flt_coeff1 << 8 | + arg->edge_wgt_flt_coeff2 << 16; + isp3_param_write(params_vdev, value, ISP35_SHARP_EDGEWGTFLT_KERNEL, id); + + value = (arg->edge_glb_clip_thred & 0x3ff) | + (arg->pos_edge_clip & 0x3ff) << 10 | + (arg->neg_edge_clip & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP35_SHARP_EDGE_GLOBAL_CLIP, id); + + value = arg->mf_detail_data_alpha | + arg->pos_mf_detail_strg << 8 | + arg->neg_mf_detail_strg << 16; + isp3_param_write(params_vdev, value, ISP35_SHARP_MFDETAIL, id); + + value = (arg->mf_detail_pos_clip & 0x3ff) | + (arg->sharp_mf_detail_neg_clip & 0x3ff) << 10; + isp3_param_write(params_vdev, value, ISP35_SHARP_MFDETAIL_CLIP, id); + + for (i = 0; i < ISP35_SHARP_SATURATION_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->staturation2strg[i * 4], + arg->staturation2strg[i * 4 + 1], + arg->staturation2strg[i * 4 + 2], + arg->staturation2strg[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP35_SHARP_SATURATION_STRG0 + i * 4, id); + } + value = (arg->staturation2strg[i * 4] & 0x1f) | arg->lo_saturation_strg << 8; + isp3_param_write(params_vdev, value, ISP35_SHARP_SATURATION_STRG2, id); + + /* SHARP_NOISE_CURVE read back is not the config value, need to save */ + isp_sharp_cfg_noise_curve(params_vdev, arg, id, false); + memcpy(¶ms_rec->others.sharp_cfg, arg, sizeof(struct isp33_sharp_cfg)); +} + +static void +isp_sharp_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_SHARP_EN, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) { + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, ISP32_SHP_FST_FRAME, id); + val |= ISP35_MODULE_EN; + } else { + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, ISP3X_SHARP_EN, id); +} + +static void +isp_bay3d_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_bay3d_cfg *arg, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct isp2x_mesh_head *head; + u32 i, value, ctrl, buf_idx; + + ctrl = isp3_param_read(params_vdev, ISP33_BAY3D_CTRL0, id); + if (ctrl & BIT(1) && !arg->bypass_en) + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, ISP3X_RAW3D_FST_FRAME, id); + ctrl &= ISP35_MODULE_EN; + + ctrl |= (arg->iir_rw_fmt & 0x3) << 13 | + !!arg->motion_est_en << 8 | + (arg->out_use_pre_mode & 0x7) << 5 | + !!arg->iir_wr_src << 3 | + !!arg->bypass_en << 1; + isp3_param_write(params_vdev, ctrl, ISP33_BAY3D_CTRL0, id); + + value = isp3_param_read(params_vdev, ISP39_W3A_CTRL0, id); + if ((arg->transf_bypass_en && !(value & ISP35_W3A_B3DNROUT_ILG_BYPASS)) || + (!arg->transf_bypass_en && value & ISP35_W3A_B3DNROUT_ILG_BYPASS)) { + if (arg->transf_bypass_en) + value |= ISP35_W3A_B3DNROUT_ILG_BYPASS; + else + value &= ~ISP35_W3A_B3DNROUT_ILG_BYPASS; + isp3_param_write(params_vdev, value, ISP39_W3A_CTRL0, id); + } + + value = !!arg->md_wgt_out_en << 25 | + !!arg->cur_spnr_out_en << 22 | + !!arg->md_only_lo_en << 21 | + !!arg->pre_spnr_out_en << 20 | + (arg->lo_mge_wgt_mode & 0x3) << 16 | + !!arg->lo_detection_bypass_en << 15 | + !!arg->sig_hfilt_en << 13 | + !!arg->lo_diff_hfilt_en << 12 | + !!arg->lo_wgt_hfilt_en << 11 | + !!arg->lpf_lo_bypass_en << 10 | + !!arg->lo_diff_vfilt_bypass_en << 9 | + !!arg->lpf_hi_bypass_en << 8 | + !!arg->motion_detect_bypass_en << 7 | + !!arg->pre_pix_out_mode << 6 | + !!arg->md_large_lo_md_wgt_bypass_en << 5 | + !!arg->md_large_lo_gauss_filter_bypass_en << 4 | + !!arg->md_large_lo_min_filter_bypass_en << 3 | + !!arg->md_large_lo_use_mode << 2 | + !!arg->tnrsigma_curve_double_en << 1 | + !!arg->transf_bypass_en; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CTRL1, id); + + value = !!arg->pre_spnr_dpc_flt_prewgt_en << 26 | + !!arg->pre_spnr_dpc_flt_mode << 25 | + !!arg->pre_spnr_dpc_nr_bal_mode << 24 | + !!arg->pre_spnr_dpc_flt_en << 23 | + !!arg->pre_lo_avg_lp_en << 22 | + !!arg->pre_hi_bf_lp_en << 21 | + !!arg->pre_hi_gic_lp_en << 20 | + !!arg->pre_spnr_lo_filter_rb_wgt_mode << 15 | + !!arg->pre_spnr_hi_filter_rb_wgt_mode << 14 | + !!arg->pre_spnr_lo_filter_wgt_mode << 13 | + !!arg->pre_spnr_hi_filter_wgt_mode << 12 | + !!arg->pre_spnr_hi_noise_ctrl_en << 11 | + !!arg->pre_spnr_sigma_idx_filt_mode << 10 | + !!arg->pre_spnr_sigma_idx_filt_bypass_en << 9 | + !!arg->pre_spnr_hi_guide_filter_bypass_en << 8 | + !!arg->pre_spnr_sigma_curve_double_en << 7 | + !!arg->pre_spnr_hi_filter_bypass_en << 6 | + !!arg->pre_spnr_lo_filter_bypass_en << 5 | + !!arg->spnr_presigma_use_en << 4 | + !!arg->pre_spnr_hi_filter_gic_enhance_en << 3 | + !!arg->pre_spnr_hi_filter_gic_en << 2 | + !!arg->cur_spnr_filter_bypass_en; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CTRL2, id); + + value = (arg->sigma_calc_mge_wgt_hdr_sht_thred & 0x3f) << 24 | + (arg->mge_wgt_hdr_sht_thred & 0x3f) << 16 | + (arg->kalman_wgt_ds_mode & 0x3) << 3 | + !!arg->mge_wgt_ds_mode << 2 | + !!arg->wgt_cal_mode << 1 | + !!arg->transf_mode; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CTRL3, id); + + value = arg->itransf_mode_offset << 16 | + (arg->transf_mode_scale & 0x3) << 14 | + (arg->transf_mode_offset & 0x1fff); + isp3_param_write(params_vdev, value, ISP33_BAY3D_TRANS0, id); + + value = arg->transf_data_max_limit; + isp3_param_write(params_vdev, value, ISP33_BAY3D_TRANS1, id); + + value = arg->pre_spnr_sigma_ctrl_scale; + isp3_param_write(params_vdev, value, ISP35_BAY3D_PREHI_SIGSCL, id); + + value = arg->pre_spnr_hi_guide_out_wgt; + isp3_param_write(params_vdev, value, ISP35_BAY3D_PREHI_SIGOF, id); + + value = arg->cur_spnr_filter_coeff[0] | + arg->cur_spnr_filter_coeff[1] << 8 | + arg->cur_spnr_filter_coeff[2] << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CURHISPW0, id); + value = arg->cur_spnr_filter_coeff[3] | + arg->cur_spnr_filter_coeff[4] << 8 | + arg->cur_spnr_filter_coeff[5] << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CURHISPW1, id); + + for (i = 0; i < ISP35_BAY3D_XY_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->pre_spnr_luma2sigma_x[i * 2], + arg->pre_spnr_luma2sigma_x[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_BAY3D_IIRSX0 + i * 4, id); + value = ISP_PACK_2SHORT(arg->pre_spnr_luma2sigma_y[i * 2], + arg->pre_spnr_luma2sigma_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_BAY3D_IIRSY0 + i * 4, id); + } + + value = arg->pre_spnr_hi_sigma_scale; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHI_SIGSCL, id); + + value = arg->pre_spnr_hi_wgt_calc_scale; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHI_WSCL, id); + + value = arg->pre_spnr_hi_filter_wgt_min_limit | + arg->pre_spnr_hi_wgt_calc_offset << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHIWMM, id); + + value = arg->pre_spnr_sigma_hdr_sht_offset << 24 | + arg->pre_spnr_sigma_offset << 16 | + arg->pre_spnr_hi_filter_out_wgt; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHISIGOF, id); + + value = ISP_PACK_2SHORT(arg->pre_spnr_sigma_scale, + arg->pre_spnr_sigma_hdr_sht_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHISIGSCL, id); + + value = arg->pre_spnr_hi_filter_coeff[0] | + arg->pre_spnr_hi_filter_coeff[1] << 8 | + arg->pre_spnr_hi_filter_coeff[2] << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHISPW0, id); + value = arg->pre_spnr_hi_filter_coeff[3] | + arg->pre_spnr_hi_filter_coeff[4] << 8 | + arg->pre_spnr_hi_filter_coeff[5] << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHISPW1, id); + + value = arg->pre_spnr_lo_sigma_scale; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PRELOSIGCSL, id); + + value = arg->pre_spnr_lo_wgt_calc_offset | + arg->pre_spnr_lo_wgt_calc_scale << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PRELOSIGOF, id); + + value = arg->pre_spnr_hi_noise_ctrl_offset << 16 | + arg->pre_spnr_hi_noise_ctrl_scale; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PREHI_NRCT, id); + + for (i = 0; i < ISP35_BAY3D_TNRSIG_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->tnr_luma2sigma_x[i * 2], + arg->tnr_luma2sigma_x[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_BAY3D_TNRSX0 + i * 4, id); + value = ISP_PACK_2SHORT(arg->tnr_luma2sigma_y[i * 2], + arg->tnr_luma2sigma_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_BAY3D_TNRSY0 + i * 4, id); + } + + for (i = 0; i < ISP35_BAY3D_LPF_COEFF_NUM / 3; i++) { + value = (arg->lpf_hi_coeff[i * 3] & 0x3ff) | + (arg->lpf_hi_coeff[i * 3 + 1] & 0x3ff) << 10 | + (arg->lpf_hi_coeff[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_BAY3D_HIWD0 + i * 4, id); + value = (arg->lpf_lo_coeff[i * 3] & 0x3ff) | + (arg->lpf_lo_coeff[i * 3 + 1] & 0x3ff) << 10 | + (arg->lpf_lo_coeff[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_BAY3D_LOWD0 + i * 4, id); + } + + value = ISP_PACK_4BYTE(arg->sigma_idx_filt_coeff[0], + arg->sigma_idx_filt_coeff[1], + arg->sigma_idx_filt_coeff[2], + arg->sigma_idx_filt_coeff[3]); + isp3_param_write(params_vdev, value, ISP33_BAY3D_GF3, id); + value = arg->sigma_idx_filt_coeff[4] | + arg->sigma_idx_filt_coeff[5] << 8 | + arg->lo_wgt_cal_first_line_sigma_scale << 16; + isp3_param_write(params_vdev, value, ISP33_BAY3D_GF4, id); + + value = (arg->lo_diff_first_line_scale & 0x3f) << 22 | + (arg->sig_first_line_scale & 0x3f) << 16 | + (arg->lo_wgt_vfilt_wgt & 0x1f) << 5 | + (arg->lo_diff_vfilt_wgt & 0x1f); + isp3_param_write(params_vdev, value, ISP33_BAY3D_VIIR, id); + + value = ISP_PACK_2SHORT(arg->lo_wgt_cal_offset, + arg->lo_wgt_cal_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_LFSCL, id); + + value = ISP_PACK_2SHORT(arg->lo_wgt_cal_max_limit, + arg->mode0_base_ratio); + isp3_param_write(params_vdev, value, ISP33_BAY3D_LFSCLTH, id); + + value = ISP_PACK_2SHORT(arg->lo_diff_wgt_cal_offset, + arg->lo_diff_wgt_cal_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_DSWGTSCL, id); + + value = ISP_PACK_2SHORT(arg->lo_mge_pre_wgt_offset, + arg->lo_mge_pre_wgt_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTLASTSCL, id); + + value = ISP_PACK_2SHORT(arg->mode0_lo_wgt_scale, + arg->mode0_lo_wgt_hdr_sht_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTSCL0, id); + + value = ISP_PACK_2SHORT(arg->mode1_lo_wgt_scale, + arg->mode1_lo_wgt_hdr_sht_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTSCL1, id); + + value = ISP_PACK_2SHORT(arg->mode1_wgt_scale, + arg->mode1_wgt_hdr_sht_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTSCL2, id); + + value = ISP_PACK_2SHORT(arg->mode1_lo_wgt_offset, + arg->mode1_lo_wgt_hdr_sht_offset); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTOFF, id); + + value = (arg->mode1_wgt_offset & 0xfff) << 20 | + (arg->mode1_wgt_min_limit & 0x3ff) << 10 | + (arg->auto_sigma_count_wgt_thred & 0x3ff); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGT1OFF, id); + + value = arg->tnr_out_sigma_sq; + isp3_param_write(params_vdev, value, ISP33_BAY3D_SIGORG, id); + + value = ISP_PACK_2SHORT(arg->lo_wgt_clip_min_limit, + arg->lo_wgt_clip_hdr_sht_min_limit); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTLO_L, id); + + value = ISP_PACK_2SHORT(arg->lo_wgt_clip_max_limit, + arg->lo_wgt_clip_hdr_sht_max_limit); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTLO_H, id); + + value = ISP_PACK_2SHORT(arg->lo_pre_gg_soft_thresh_scale, + arg->lo_pre_rb_soft_thresh_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_STH_SCL, id); + + value = ISP_PACK_2SHORT(arg->lo_pre_soft_thresh_max_limit, + arg->lo_pre_soft_thresh_min_limit); + isp3_param_write(params_vdev, value, ISP33_BAY3D_STH_LIMIT, id); + + value = (arg->motion_est_lo_wgt_thred & 0x3ff) << 16 | + arg->pre_spnr_hi_wgt_min_limit << 8 | + arg->cur_spnr_hi_wgt_min_limit; + isp3_param_write(params_vdev, value, ISP33_BAY3D_HIKEEP, id); + + value = arg->pix_max_limit; + isp3_param_write(params_vdev, value, ISP33_BAY3D_PIXMAX, id); + + value = arg->sigma_num_th; + isp3_param_write(params_vdev, value, ISP33_BAY3D_SIGNUMTH, id); + + value = arg->gain_out_max_limit << 24 | + (arg->out_use_md_noise_bal_nr_strg & 0x7ff) << 11 | + (arg->out_use_hi_noise_bal_nr_strg & 0x7ff); + isp3_param_write(params_vdev, value, ISP33_BAY3D_MONR, id); + + value = ISP_PACK_2SHORT(arg->sigma_scale, arg->sigma_hdr_sht_scale); + isp3_param_write(params_vdev, value, ISP33_BAY3D_SIGSCL, id); + + value = arg->lo_wgt_cal_first_line_vfilt_wgt << 24 | + (arg->lo_diff_vfilt_offset & 0xfff) << 10 | + (arg->lo_wgt_vfilt_offset & 0x3ff); + isp3_param_write(params_vdev, value, ISP33_BAY3D_DSOFF, id); + + value = ISP_PACK_4BYTE(arg->lo_wgt_vfilt_scale, + arg->lo_diff_vfilt_scale_bit, + arg->lo_diff_vfilt_scale, + arg->lo_diff_first_line_vfilt_wgt); + isp3_param_write(params_vdev, value, ISP33_BAY3D_DSSCL, id); + + value = (arg->motion_est_sad_vert_wgt0 & 0x3) << 28 | + (arg->motion_est_up_mvx_cost_scale & 0x7ff) << 16 | + arg->motion_est_up_mvx_cost_offset; + isp3_param_write(params_vdev, value, ISP33_BAY3D_ME0, id); + + value = (arg->motion_est_sad_vert_wgt1 & 0x3) << 28 | + (arg->motion_est_up_left_mvx_cost_scale & 0x7ff) << 16 | + arg->motion_est_up_left_mvx_cost_offset; + isp3_param_write(params_vdev, value, ISP33_BAY3D_ME1, id); + + value = (arg->motion_est_sad_vert_wgt2 & 0x3) << 28 | + (arg->motion_est_up_right_mvx_cost_scale & 0x7ff) << 16 | + arg->motion_est_up_right_mvx_cost_offset; + isp3_param_write(params_vdev, value, ISP33_BAY3D_ME2, id); + + value = arg->lo_wgt_clip_motion_max_limit; + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTMAX, id); + + value = arg->mode1_wgt_max_limit; + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGT1MAX, id); + + value = ISP_PACK_2SHORT(arg->mode0_wgt_out_max_limit, arg->mode0_wgt_out_offset); + isp3_param_write(params_vdev, value, ISP33_BAY3D_WGTM0, id); + + value = (arg->lo_wgt_hflt_coeff2 & 0x7) | + (arg->lo_wgt_hflt_coeff1 & 0xf) << 4 | + (arg->lo_wgt_hflt_coeff0 & 0x1f) << 8 | + (arg->sig_hflt_coeff2 & 0x7) << 16 | + (arg->sig_hflt_coeff1 & 0xf) << 20 | + (arg->sig_hflt_coeff0 & 0x1f) << 24; + isp3_param_write(params_vdev, value, ISP35_BAY3D_LOCOEF0, id); + value = (arg->lo_dif_hflt_coeff2 & 0x7) | + (arg->lo_dif_hflt_coeff1 & 0xf) << 4 | + (arg->lo_dif_hflt_coeff0 & 0x1f) << 8; + isp3_param_write(params_vdev, value, ISP35_BAY3D_LOCOEF1, id); + + value = (arg->pre_spnr_dpc_bright_str & 0x3) | + (arg->pre_spnr_dpc_dark_str & 0x3) << 2 | + (arg->pre_spnr_dpc_str & 0x7) << 4 | + arg->pre_spnr_dpc_wk_scale << 8 | + arg->pre_spnr_dpc_wk_offset << 16; + isp3_param_write(params_vdev, value, ISP35_BAY3D_DPC0, id); + value = ISP_PACK_2SHORT(arg->pre_spnr_dpc_nr_bal_str, + arg->pre_spnr_dpc_soft_thr_scale); + isp3_param_write(params_vdev, value, ISP35_BAY3D_DPC1, id); + + value = ISP_PACK_4BYTE(arg->pre_spnr_lo_val_wgt_out_wgt, + arg->pre_spnr_lo_filter_out_wgt, + arg->pre_spnr_lo_filter_wgt_min, 0); + isp3_param_write(params_vdev, value, ISP33_BAY3D_PRELOWGT, id); + + value = arg->md_large_lo_md_wgt_scale << 16 | + arg->md_large_lo_md_wgt_offset; + isp3_param_write(params_vdev, value, ISP33_BAY3D_MIDBIG0, id); + + value = ISP_PACK_2SHORT(arg->md_large_lo_wgt_cut_offset, + arg->md_large_lo_wgt_add_offset); + isp3_param_write(params_vdev, value, ISP33_BAY3D_MIDBIG1, id); + + value = arg->md_large_lo_wgt_scale; + isp3_param_write(params_vdev, value, ISP33_BAY3D_MIDBIG2, id); + + value = (arg->out_use_hi_noise_bal_nr_off & 0xfff) | + (arg->out_use_md_noise_bal_nr_off & 0xfff) << 16; + isp3_param_write(params_vdev, value, ISP35_BAY3D_MONROFF, id); + + if (params_vdev->dev->hw_dev->is_single && ctrl & ISP35_MODULE_EN) + isp3_param_write(params_vdev, ctrl | ISP35_SELF_FORCE_UPD, ISP33_BAY3D_CTRL0, id); + + for (i = 0; i < ISP35_MESH_BUF_NUM; i++) { + if (!priv->buf_b3dldc[id][i].mem_priv) + continue; + if (arg->lut_buf_fd == priv->buf_b3dldc[id][i].dma_fd) + break; + } + if (i == ISP35_MESH_BUF_NUM) { + if (arg->btnr_ldc_en) + dev_err(dev->dev, "cannot find b3dldc buf fd(%d)\n", arg->lut_buf_fd); + return; + } + if (!priv->buf_b3dldc[id][i].vaddr) { + dev_err(dev->dev, "no b3dldc buffer allocated\n"); + return; + } + buf_idx = priv->buf_b3dldc_idx[id]; + head = (struct isp2x_mesh_head *)priv->buf_b3dldc[id][buf_idx].vaddr; + head->stat = MESH_BUF_INIT; + buf_idx = i; + head = (struct isp2x_mesh_head *)priv->buf_b3dldc[id][buf_idx].vaddr; + head->stat = MESH_BUF_CHIPINUSE; + priv->buf_b3dldc_idx[id] = buf_idx; + rkisp_prepare_buffer(dev, &priv->buf_b3dldc[id][buf_idx]); + + value = !!arg->btnr_ldcltp_mode << 16 | + arg->btnr_ldc_wrap_ext_bound_offset; + isp3_param_write(params_vdev, value, ISP35_B3DLDC_EXTBOUND1, id); + + ctrl = 0; + if (arg->b3dldch_en) { + value = priv->buf_b3dldc[id][buf_idx].dma_addr + head->data_oft; + isp3_param_write(params_vdev, value, ISP35_B3DLDCH_RD_BASE, id); + value = priv->b3dldc_hsize; + isp3_param_write(params_vdev, value, ISP35_B3DLDCH_RD_HWSIZE, id); + value = priv->b3dldch_vsize; + isp3_param_write(params_vdev, value, ISP35_B3DLDCH_RD_VSIZE, id); + ctrl |= !!arg->b3dldch_map13p3_en << 6 | + !!arg->b3dldch_force_map_en << 7 | + ISP35_B3DLDC_EN; + } + isp3_param_write(params_vdev, ctrl, ISP35_B3DLDC_ADR_STS, id); + + ctrl = 0; + if (arg->btnr_ldc_en) { + value = priv->buf_b3dldc[id][buf_idx].dma_addr + head->data1_oft; + isp3_param_write(params_vdev, value, ISP35_B3DLDCV_RD_BASE, id); + value = priv->b3dldc_hsize; + isp3_param_write(params_vdev, value, ISP35_B3DLDCV_RD_HWSIZE, id); + value = priv->b3dldcv_vsize; + isp3_param_write(params_vdev, value, ISP35_B3DLDCV_RD_VSIZE, id); + ctrl |= !!arg->b3dldcv_map13p3_en << 7 | + !!arg->b3dldcv_force_map_en << 8 | + ISP35_B3DLDC_EN; + } + isp3_param_write(params_vdev, ctrl, ISP35_B3DLDC_CTRL, id); +} + +static void +isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; + struct rkisp_device *ispdev = params_vdev->dev; + u32 value, ctrl; + + ctrl = isp3_param_read_cache(params_vdev, ISP33_BAY3D_CTRL0, id); + if (en == !!(ctrl & ISP35_MODULE_EN)) + return; + + if (en) { + if (!priv_val->buf_3dnr_iir.mem_priv) { + dev_err(ispdev->dev, "no bay3d buffer available\n"); + return; + } + + value = priv_val->bay3d_iir_size; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); + value = priv_val->buf_3dnr_iir.dma_addr + value * id; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); + + value = priv_val->bay3d_ds_size; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); + value = priv_val->buf_3dnr_ds.dma_addr + value * id; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_RD_BASE, id); + + value = priv_val->bay3d_wgt_size; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); + isp3_param_write(params_vdev, value, ISP32_MI_BAY3D_CUR_RD_SIZE, id); + value = priv_val->buf_3dnr_wgt.dma_addr + value * id; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); + + ctrl |= ISP35_MODULE_EN; + isp3_param_write(params_vdev, ctrl, ISP33_BAY3D_CTRL0, id); + + value = ISP3X_BAY3D_IIR_WR_AUTO_UPD | ISP3X_BAY3D_CUR_WR_AUTO_UPD | + ISP3X_BAY3D_DS_WR_AUTO_UPD | ISP3X_BAY3D_IIRSELF_UPD | + ISP3X_BAY3D_CURSELF_UPD | ISP3X_BAY3D_DSSELF_UPD | + ISP3X_BAY3D_RDSELF_UPD; + if (priv_val->buf_gain.mem_priv) + value |= ISP3X_GAIN_WR_AUTO_UPD | ISP3X_GAINSELF_UPD; + isp3_param_set_bits(params_vdev, MI_WR_CTRL2, value, id); + + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, ISP3X_RAW3D_FST_FRAME, id); + } else { + ctrl &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, ctrl, ISP33_BAY3D_CTRL0, id); + } +} + +static void +isp_gain_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_gain_cfg *arg, u32 id) +{ + u32 val; + + val = arg->g0; + isp3_param_write(params_vdev, val, ISP3X_GAIN_G0, id); + val = ISP_PACK_2SHORT(arg->g1, arg->g2); + isp3_param_write(params_vdev, val, ISP3X_GAIN_G1_G2, id); +} + +static void +isp_gain_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_GAIN_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_GAIN_CTRL, id); +} + +static void +isp_cac_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_cac_cfg *arg, u32 id) +{ + struct isp33_cac_cfg *arg_rec = ¶ms_vdev->isp35_params->others.cac_cfg; + u32 i, val, ctrl; + + ctrl = isp3_param_read(params_vdev, ISP3X_CAC_CTRL, id); + ctrl &= ISP35_MODULE_EN; + ctrl |= !!arg->bypass_en << 1 | + !!arg->edge_detect_en << 2 | + !!arg->neg_clip0_en << 3 | + !!arg->wgt_color_en << 5; + isp3_param_write(params_vdev, ctrl, ISP3X_CAC_CTRL, id); + + val = arg->psf_table_fix_bit; + isp3_param_write(params_vdev, val, ISP3X_CAC_PSF_PARA, id); + + val = arg->hi_drct_ratio; + isp3_param_write(params_vdev, val, ISP33_CAC_HIGH_DIRECT, id); + + val = arg->over_expo_thred; + isp3_param_write(params_vdev, val, ISP33_CAC_OVER_EXPO0, id); + + val = arg->over_expo_adj; + isp3_param_write(params_vdev, val, ISP33_CAC_OVER_EXPO1, id); + + val = arg->flat_thred | arg->flat_offset << 16; + isp3_param_write(params_vdev, val, ISP33_CAC_FLAT, id); + + val = (arg->chroma_lo_flt_coeff0 & 0x7) | + (arg->chroma_lo_flt_coeff1 & 0x7) << 4 | + (arg->color_lo_flt_coeff0 & 0x7) << 8 | + (arg->color_lo_flt_coeff1 & 0x7) << 12; + isp3_param_write(params_vdev, val, ISP33_CAC_GAUSS_COEFF, id); + + val = ISP_PACK_2SHORT(arg->search_range_ratio, arg->residual_chroma_ratio); + isp3_param_write(params_vdev, val, ISP33_CAC_RATIO, id); + + val = arg->wgt_color_b_min_thred; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_COLOR_B, id); + val = arg->wgt_color_r_min_thred; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_COLOR_R, id); + + val = arg->wgt_color_b_slope; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_COLOR_SLOPE_B, id); + val = arg->wgt_color_r_slope; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_COLOR_SLOPE_R, id); + + val = arg->wgt_color_min_luma; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_COLOR_LUMA0, id); + val = arg->wgt_color_luma_slope; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_COLOR_LUMA1, id); + + val = arg->wgt_over_expo_min_thred; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_OVER_EXPO0, id); + val = arg->wgt_over_expo_slope; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_OVER_EXPO1, id); + + val = arg->wgt_contrast_min_thred; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_CONTRAST0, id); + val = arg->wgt_contrast_slope; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_CONTRAST1, id); + val = arg->wgt_contrast_offset; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_CONTRAST2, id); + + val = arg->wgt_dark_thed; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_DARK_AREA0, id); + val = arg->wgt_dark_slope; + isp3_param_write(params_vdev, val, ISP33_CAC_WGT_DARK_AREA1, id); + + for (i = 0; i < ISP35_CAC_PSF_NUM / 4; i++) { + val = ISP_PACK_4BYTE(arg->psf_b_ker[i * 4], arg->psf_b_ker[i * 4 + 1], + arg->psf_b_ker[i * 4 + 2], arg->psf_b_ker[i * 4 + 3]); + isp3_param_write(params_vdev, val, ISP33_CAC_PSF_B0 + i * 4, id); + val = ISP_PACK_4BYTE(arg->psf_r_ker[i * 4], arg->psf_r_ker[i * 4 + 1], + arg->psf_r_ker[i * 4 + 2], arg->psf_r_ker[i * 4 + 3]); + isp3_param_write(params_vdev, val, ISP33_CAC_PSF_R0 + i * 4, id); + } + val = ISP_PACK_4BYTE(arg->psf_b_ker[i * 4], arg->psf_b_ker[i * 4 + 1], + arg->psf_b_ker[i * 4 + 2], 0); + isp3_param_write(params_vdev, val, ISP33_CAC_PSF_B2, id); + val = ISP_PACK_4BYTE(arg->psf_r_ker[i * 4], arg->psf_r_ker[i * 4 + 1], + arg->psf_r_ker[i * 4 + 2], 0); + isp3_param_write(params_vdev, val, ISP33_CAC_PSF_R2, id); + + memcpy(arg_rec->psf_b_ker, arg->psf_b_ker, sizeof(arg_rec->psf_b_ker)); + memcpy(arg_rec->psf_r_ker, arg->psf_r_ker, sizeof(arg_rec->psf_r_ker)); +} + +static void +isp_cac_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_CAC_CTRL, id); + + if (en == !!(val & ISP35_MODULE_EN)) + return; + if (en) + val |= ISP35_MODULE_EN; + else + val &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_CAC_CTRL, id); +} + +static void +isp_csm_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp21_csm_cfg *arg, u32 id) +{ + u32 i, val; + + for (i = 0; i < ISP35_CSM_COEFF_NUM; i++) { + if (i == 0) + val = (arg->csm_y_offset & 0x3f) << 24 | + (arg->csm_c_offset & 0xff) << 16 | + (arg->csm_coeff[i] & 0x1ff); + else + val = arg->csm_coeff[i] & 0x1ff; + isp3_param_write(params_vdev, val, ISP3X_ISP_CC_COEFF_0 + i * 4, id); + } + + val = isp3_param_read_cache(params_vdev, ISP3X_ISP_CTRL0, id); + val |= CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA; + isp3_param_write(params_vdev, val, ISP3X_ISP_CTRL0, id); +} + +static void +isp_cgc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp21_cgc_cfg *arg, u32 id) +{ + u32 val = isp3_param_read_cache(params_vdev, ISP3X_ISP_CTRL0, id); + u32 eff_ctrl, cproc_ctrl; + + params_vdev->quantization = V4L2_QUANTIZATION_FULL_RANGE; + val &= ~(ISP3X_SW_CGC_YUV_LIMIT | ISP3X_SW_CGC_RATIO_EN); + if (arg->yuv_limit) { + val |= ISP3X_SW_CGC_YUV_LIMIT; + params_vdev->quantization = V4L2_QUANTIZATION_LIM_RANGE; + } + if (arg->ratio_en) + val |= ISP3X_SW_CGC_RATIO_EN; + isp3_param_write(params_vdev, val, ISP3X_ISP_CTRL0, id); + + cproc_ctrl = isp3_param_read(params_vdev, ISP3X_CPROC_CTRL, id); + if (cproc_ctrl & CIF_C_PROC_CTR_ENABLE) { + val = CIF_C_PROC_YOUT_FULL | CIF_C_PROC_YIN_FULL | CIF_C_PROC_COUT_FULL; + if (arg->yuv_limit) + cproc_ctrl &= ~val; + else + cproc_ctrl |= val; + isp3_param_write(params_vdev, cproc_ctrl, ISP3X_CPROC_CTRL, id); + } + + eff_ctrl = isp3_param_read(params_vdev, ISP3X_IMG_EFF_CTRL, id); + if (eff_ctrl & CIF_IMG_EFF_CTRL_ENABLE) { + if (arg->yuv_limit) + eff_ctrl &= ~CIF_IMG_EFF_CTRL_YCBCR_FULL; + else + eff_ctrl |= CIF_IMG_EFF_CTRL_YCBCR_FULL; + isp3_param_write(params_vdev, eff_ctrl, ISP3X_IMG_EFF_CTRL, id); + } +} + +static void +isp_rgbir_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp39_rgbir_cfg *arg, u32 id) +{ + u32 i, value; + + value = arg->coe_theta & 0xfff; + isp3_param_write(params_vdev, value, ISP39_RGBIR_THETA, id); + + value = arg->coe_delta & 0x3fff; + isp3_param_write(params_vdev, value, ISP39_RGBIR_DELTA, id); + + for (i = 0; i < ISP35_RGBIR_SCALE_NUM; i++) { + value = arg->scale[i] & 0x1ff; + isp3_param_write(params_vdev, value, ISP39_RGBIR_SCALE0 + i * 4, id); + } + + for (i = 0; i < ISP35_RGBIR_LUMA_POINT_NUM / 3; i++) { + value = (arg->luma_point[i * 3] & 0x3ff) | + (arg->luma_point[i * 3 + 1] & 0x3ff) << 10 | + (arg->luma_point[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP39_RGBIR_LUMA_POINT0 + i * 4, id); + } + value = (arg->luma_point[i * 3] & 0x3ff) | (arg->luma_point[i * 3 + 1] & 0x7ff) << 10; + isp3_param_write(params_vdev, value, ISP39_RGBIR_LUMA_POINT0 + i * 4, id); + + for (i = 0; i < ISP35_RGBIR_SCALE_MAP_NUM / 3; i++) { + value = (arg->scale_map[i * 3] & 0x1ff) | + (arg->scale_map[i * 3 + 1] & 0x1ff) << 9 | + (arg->scale_map[i * 3 + 2] & 0x1ff) << 18; + isp3_param_write(params_vdev, value, ISP39_RGBIR_SCALE_MAP0 + i * 4, id); + } + value = (arg->scale_map[i * 3] & 0x1ff) | (arg->scale_map[i * 3 + 1] & 0x1ff) << 9; + isp3_param_write(params_vdev, value, ISP39_RGBIR_SCALE_MAP0 + i * 4, id); +} + +static void +isp_rgbir_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 value = 0; + + if (en) + value = ISP35_MODULE_EN; + isp3_param_write(params_vdev, value, ISP39_RGBIR_CTRL, id); +} + +static __maybe_unused +void __isp_isr_other_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + u64 module_cfg_update = new_params->module_cfg_update; + + v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, + "%s id:%d seq:%d module_cfg_update:0x%llx\n", + __func__, id, new_params->frame_id, module_cfg_update); + + if (module_cfg_update & ISP35_MODULE_RGBIR) + isp_rgbir_config(params_vdev, &new_params->others.rgbir_cfg, id); + if (module_cfg_update & ISP35_MODULE_BLS)//bls0 ob TNR blc1, blc2 for awb + isp_bls_config(params_vdev, &new_params->others.bls_cfg, id); + if (module_cfg_update & ISP35_MODULE_AWB_GAIN)//awb0 TNR awb1 + isp_awbgain_config(params_vdev, &new_params->others.awb_gain_cfg, id); + if (module_cfg_update & ISP35_MODULE_DPCC) + isp_dpcc_config(params_vdev, &new_params->others.dpcc_cfg, id); + if (module_cfg_update & ISP35_MODULE_HDRMGE) + isp_hdrmge_config(params_vdev, &new_params->others.hdrmge_cfg, type, id); + if (module_cfg_update & ISP35_MODULE_GAIN) + isp_gain_config(params_vdev, &new_params->others.gain_cfg, id); + if (module_cfg_update & ISP35_MODULE_BAY3D) + isp_bay3d_config(params_vdev, &new_params->others.bay3d_cfg, id); + + if (module_cfg_update & ISP35_MODULE_CAC) + isp_cac_config(params_vdev, &new_params->others.cac_cfg, id); + if (module_cfg_update & ISP35_MODULE_LSC) + isp_lsc_config(params_vdev, &new_params->others.lsc_cfg, id); + if (module_cfg_update & ISP35_MODULE_DEBAYER) + isp_debayer_config(params_vdev, &new_params->others.debayer_cfg, id); + if (module_cfg_update & ISP35_MODULE_DRC) + isp_hdrdrc_config(params_vdev, &new_params->others.drc_cfg, type, id); + if (module_cfg_update & ISP35_MODULE_CCM) + isp_ccm_config(params_vdev, &new_params->others.ccm_cfg, id); + if (module_cfg_update & ISP35_MODULE_GOC) + isp_goc_config(params_vdev, &new_params->others.gammaout_cfg, id); + if (module_cfg_update & ISP35_MODULE_HSV) + isp_hsv_config(params_vdev, &new_params->others.hsv_cfg, id); + /* range csm->cgc->cproc->ie */ + if (module_cfg_update & ISP35_MODULE_CSM) + isp_csm_config(params_vdev, &new_params->others.csm_cfg, id); + if (module_cfg_update & ISP35_MODULE_GIC) + isp_gic_config(params_vdev, &new_params->others.gic_cfg, id); + if (module_cfg_update & ISP35_MODULE_CNR) + isp_cnr_config(params_vdev, &new_params->others.cnr_cfg, id); + if (module_cfg_update & ISP35_MODULE_YNR) + isp_ynr_config(params_vdev, &new_params->others.ynr_cfg, id); + if (module_cfg_update & ISP35_MODULE_SHARP) + isp_sharp_config(params_vdev, &new_params->others.sharp_cfg, id); + if (module_cfg_update & ISP35_MODULE_ENH) + isp_enh_config(params_vdev, &new_params->others.enh_cfg, id); + if (module_cfg_update & ISP35_MODULE_HIST) + isp_hist_config(params_vdev, &new_params->others.hist_cfg, id); + if (module_cfg_update & ISP35_MODULE_LDCH) + isp_ldch_config(params_vdev, &new_params->others.ldch_cfg, id); + if (module_cfg_update & ISP35_MODULE_CGC) + isp_cgc_config(params_vdev, &new_params->others.cgc_cfg, id); + if (module_cfg_update & ISP35_MODULE_CPROC) + isp_cproc_config(params_vdev, &new_params->others.cproc_cfg, id); +} + +static __maybe_unused +void __isp_isr_other_en(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; + u64 module_en_update = new_params->module_en_update; + u64 module_ens = new_params->module_ens; + u64 mask; + u32 gain_ctrl, cnr_ctrl, val; + + mask = ISP35_MODULE_YNR | ISP35_MODULE_CNR | ISP35_MODULE_SHARP; + if ((module_ens & mask) && ((module_ens & mask) != mask)) + dev_err(params_vdev->dev->dev, "ynr cnr sharp no enable together\n"); + v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, + "%s id:%d seq:%d module_en_update:0x%llx module_ens:0x%llx\n", + __func__, id, new_params->frame_id, module_en_update, module_ens); + + if (module_en_update & ISP35_MODULE_RGBIR) + isp_rgbir_enable(params_vdev, !!(module_ens & ISP35_MODULE_RGBIR), id); + if (module_en_update & ISP35_MODULE_BLS) + isp_bls_enable(params_vdev, !!(module_ens & ISP35_MODULE_BLS), id); + if (module_en_update & ISP35_MODULE_AWB_GAIN) + isp_awbgain_enable(params_vdev, !!(module_ens & ISP35_MODULE_AWB_GAIN), id); + if (module_en_update & ISP35_MODULE_DPCC) + isp_dpcc_enable(params_vdev, !!(module_ens & ISP35_MODULE_DPCC), id); + if (module_en_update & ISP35_MODULE_GAIN || + ((priv_val->buf_info_owner == RKISP_INFO2DRR_OWNER_GAIN) && + !(isp3_param_read(params_vdev, ISP3X_GAIN_CTRL, id) & ISP3X_GAIN_2DDR_EN))) + isp_gain_enable(params_vdev, !!(module_ens & ISP35_MODULE_GAIN), id); + if (module_en_update & ISP35_MODULE_BAY3D) + isp_bay3d_enable(params_vdev, !!(module_ens & ISP35_MODULE_BAY3D), id); + + if (module_en_update & ISP35_MODULE_CAC) + isp_cac_enable(params_vdev, !!(module_ens & ISP35_MODULE_CAC), id); + if (module_en_update & ISP35_MODULE_LSC) + isp_lsc_enable(params_vdev, !!(module_ens & ISP35_MODULE_LSC), id); + if (module_en_update & ISP35_MODULE_DEBAYER) + isp_debayer_enable(params_vdev, !!(module_ens & ISP35_MODULE_DEBAYER), id); + if (module_en_update & ISP35_MODULE_DRC) + isp_hdrdrc_enable(params_vdev, !!(module_ens & ISP35_MODULE_DRC), id); + if (module_en_update & ISP35_MODULE_CCM) + isp_ccm_enable(params_vdev, !!(module_ens & ISP35_MODULE_CCM), id); + if (module_en_update & ISP35_MODULE_GOC) + isp_goc_enable(params_vdev, !!(module_ens & ISP35_MODULE_GOC), id); + if (module_en_update & ISP35_MODULE_HSV) + isp_hsv_enable(params_vdev, !!(module_ens & ISP35_MODULE_HSV), id); + if (module_en_update & ISP35_MODULE_GIC) + isp_gic_enable(params_vdev, !!(module_ens & ISP35_MODULE_GIC), id); + if (module_en_update & ISP35_MODULE_CNR) + isp_cnr_enable(params_vdev, !!(module_ens & ISP35_MODULE_CNR), id); + if (module_en_update & ISP35_MODULE_YNR) + isp_ynr_enable(params_vdev, !!(module_ens & ISP35_MODULE_YNR), id); + if (module_en_update & ISP35_MODULE_SHARP) + isp_sharp_enable(params_vdev, !!(module_ens & ISP35_MODULE_SHARP), id); + if (module_en_update & ISP35_MODULE_ENH) + isp_enh_enable(params_vdev, !!(module_ens & ISP35_MODULE_ENH), id); + if (module_en_update & ISP35_MODULE_HIST) + isp_hist_enable(params_vdev, !!(module_ens & ISP35_MODULE_HIST), id); + if (module_en_update & ISP35_MODULE_LDCH) + isp_ldch_enable(params_vdev, !!(module_ens & ISP35_MODULE_LDCH), id); + if (module_en_update & ISP35_MODULE_CPROC) + isp_cproc_enable(params_vdev, !!(module_ens & ISP35_MODULE_CPROC), id); + if (module_en_update & ISP35_MODULE_IE) + isp_ie_enable(params_vdev, !!(module_ens & ISP35_MODULE_IE), id); + /* gain disable, using global gain for cnr */ + gain_ctrl = isp3_param_read_cache(params_vdev, ISP3X_GAIN_CTRL, id); + cnr_ctrl = isp3_param_read_cache(params_vdev, ISP3X_CNR_CTRL, id); + if (!(gain_ctrl & ISP35_MODULE_EN) && cnr_ctrl & ISP35_MODULE_EN) { + cnr_ctrl |= BIT(1); + isp3_param_write(params_vdev, cnr_ctrl, ISP3X_CNR_CTRL, id); + val = isp3_param_read(params_vdev, ISP3X_CNR_EXGAIN, id) & 0x3ff; + isp3_param_write(params_vdev, val | 0x8000, ISP3X_CNR_EXGAIN, id); + } +} + +static __maybe_unused +void __isp_isr_meas_config(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + u64 module_cfg_update = new_params->module_cfg_update; + + params_vdev->cur_frame_id = new_params->frame_id; + + v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, + "%s id:%d seq:%d module_cfg_update:0x%llx\n", + __func__, id, new_params->frame_id, module_cfg_update); + + if (module_cfg_update & ISP35_MODULE_RAWAE0) + isp_rawae0_config(params_vdev, &new_params->meas.rawae0, id); + + if (module_cfg_update & ISP35_MODULE_RAWHIST0) + isp_rawhist0_config(params_vdev, &new_params->meas.rawhist0, id); + + if (module_cfg_update & ISP35_MODULE_RAWAE3) + isp_rawae3_config(params_vdev, &new_params->meas.rawae3, id); + if (module_cfg_update & ISP35_MODULE_RAWHIST3) + isp_rawhist3_config(params_vdev, &new_params->meas.rawhist3, id); + if (module_cfg_update & ISP35_MODULE_AIAWB) + isp_aiawb_config(params_vdev, &new_params->meas.aiawb, id); + if (module_cfg_update & ISP35_MODULE_AWBSYNC) + isp_awbsync_config(params_vdev, &new_params->meas.awbsync, id); + if (module_cfg_update & ISP35_MODULE_RAWAWB) + isp_rawawb_config(params_vdev, &new_params->meas.rawawb, id); + if ((module_cfg_update & ISP35_MODULE_RAWAF)) + isp_rawaf_config(params_vdev, &new_params->meas.rawaf, id); +} + +static __maybe_unused +void __isp_isr_meas_en(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + u64 module_en_update = new_params->module_en_update; + u64 module_ens = new_params->module_ens; + + v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, + "%s id:%d seq:%d module_en_update:0x%llx module_ens:0x%llx\n", + __func__, id, new_params->frame_id, module_en_update, module_ens); + + if (module_en_update & ISP35_MODULE_RAWAE0) + isp_rawae0_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWAE0), id); + if (module_en_update & ISP35_MODULE_RAWHIST0) + isp_rawhist0_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWHIST0), id); + if (module_en_update & ISP35_MODULE_RAWAE3) + isp_rawae3_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWAE3), id); + if (module_en_update & ISP35_MODULE_RAWHIST3) + isp_rawhist3_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWHIST3), id); + if (module_en_update & ISP35_MODULE_AIAWB) + isp_aiawb_enable(params_vdev, !!(module_ens & ISP35_MODULE_AIAWB), id); + if (module_en_update & ISP35_MODULE_AWBSYNC) + isp_awbsync_enable(params_vdev, !!(module_ens & ISP35_MODULE_AWBSYNC), id); + if (module_en_update & ISP35_MODULE_RAWAWB) + isp_rawawb_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWAWB), id); + if (module_en_update & ISP35_MODULE_RAWAF) + isp_rawaf_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWAF), id); +} + +static +void rkisp_params_cfgsram_v35(struct rkisp_isp_params_vdev *params_vdev, bool is_reset) +{ + u32 id = params_vdev->dev->unite_index; + struct isp35_isp_params_cfg *params = params_vdev->isp35_params + id; + + if (is_reset) { + isp_sharp_cfg_noise_curve(params_vdev, ¶ms->others.sharp_cfg, id, true); + params->others.enh_cfg.iir_wr = true; + params->others.hist_cfg.iir_wr = true; + } + isp_enh_cfg_sram(params_vdev, ¶ms->others.enh_cfg, true, id); + isp_hist_cfg_sram(params_vdev, ¶ms->others.hist_cfg, true, id); + params->others.enh_cfg.iir_wr = false; + params->others.hist_cfg.iir_wr = false; + + isp_lsc_matrix_cfg_sram(params_vdev, ¶ms->others.lsc_cfg, true, id); + isp_hsv_cfg_sram(params_vdev, ¶ms->others.hsv_cfg, true, id); + isp_rawawb_cfg_sram(params_vdev, ¶ms->meas.rawawb, true, id); + isp_rawhist_cfg_sram(params_vdev, ¶ms->meas.rawhist0, + ISP3X_RAWHIST_LITE_BASE, true, id); + isp_rawhist_cfg_sram(params_vdev, ¶ms->meas.rawhist3, + ISP3X_RAWHIST_BIG1_BASE, true, id); +} + +static int +rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_isp_params_cfg *new_params) +{ + struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_isp_subdev *isp_sdev = &dev->isp_sdev; + u64 module_en_update, module_ens; + int ret; + + module_en_update = new_params->module_en_update; + module_ens = new_params->module_ens; + + if ((module_en_update & ISP35_MODULE_BAY3D) && (module_ens & ISP35_MODULE_BAY3D)) { + u8 iir_rw_fmt = new_params->others.bay3d_cfg.iir_rw_fmt; + u32 w = isp_sdev->in_crop.width; + u32 h = isp_sdev->in_crop.height; + u32 size, val, w16, w32, w128; + bool is_alloc; + + if (dev->unite_div > ISP_UNITE_DIV1) + w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + h = h / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + w16 = ALIGN(w, 16); + w32 = ALIGN(w, 32); + w128 = ALIGN(w, 128); + priv_val->bay3d_iir_stride = 0; + switch (iir_rw_fmt) { + case 0: + val = w16 * 7 / 4; + size = val * h; + break; + case 1: + size = w16 * h * 2; + break; + case 2: + case 4: + val = ALIGN(w16 * 9 / 4, 16); + size = val * h; + priv_val->bay3d_iir_stride = val; + break; + case 3: + val = ALIGN((w32 + w128 / 8) * 2, 16); + size = val * h; + priv_val->bay3d_iir_stride = val; + break; + default: + dev_err(dev->dev, "bay3d iir_rw_fmt:%d error\n", iir_rw_fmt); + return -EINVAL; + } + + val = ALIGN(size, 16); + priv_val->bay3d_iir_size = val; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; + is_alloc = true; + if (priv_val->buf_3dnr_iir.mem_priv) { + if (val > priv_val->buf_3dnr_iir.size) + rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); + else + is_alloc = false; + } + if (is_alloc) { + priv_val->buf_3dnr_iir.size = val; + ret = rkisp_alloc_buffer(dev, &priv_val->buf_3dnr_iir); + if (ret) { + dev_err(dev->dev, "alloc bay3d iir buf fail:%d\n", ret); + goto err_3dnr; + } + } + + val = (w16 * 36 / 8 + 31) / 32 * 4; + size = val * ((h + 7) / 8); + val = ALIGN(size, 16); + priv_val->bay3d_ds_size = val; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; + is_alloc = true; + if (priv_val->buf_3dnr_ds.mem_priv) { + if (val > priv_val->buf_3dnr_ds.size) + rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); + else + is_alloc = false; + } + if (is_alloc) { + priv_val->buf_3dnr_ds.size = val; + ret = rkisp_alloc_buffer(dev, &priv_val->buf_3dnr_ds); + if (ret) { + rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); + dev_err(dev->dev, "alloc bay3d ds buf fail:%d\n", ret); + goto err_3dnr; + } + } + + val = (((w + 31) / 32 + 1) / 2 * 2 + 3) / 4 * 4; + size = val * ((h + 31) / 32); + val = ALIGN(size, 16); + priv_val->bay3d_wgt_size = val; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; + is_alloc = true; + if (priv_val->buf_3dnr_wgt.mem_priv) { + if (val > priv_val->buf_3dnr_wgt.size) + rkisp_free_buffer(dev, &priv_val->buf_3dnr_wgt); + else + is_alloc = false; + } + if (is_alloc) { + priv_val->buf_3dnr_wgt.size = val; + ret = rkisp_alloc_buffer(dev, &priv_val->buf_3dnr_wgt); + if (ret) { + rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); + dev_err(dev->dev, "alloc bay3d wgt buf fail:%d\n", ret); + goto err_3dnr; + } + } + } + + return 0; +err_3dnr: + return ret; +} + +static bool +rkisp_params_check_bigmode_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_device *dev = params_vdev->dev; + + dev->multi_index = 0; + dev->multi_mode = 0; + if (!dev->hw_dev->is_single) { + dev->is_frm_rd = true; + dev->multi_index = dev->dev_id; + } + + return dev->is_bigmode = false; +} + +static void +rkisp_params_first_cfg_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + struct isp35_isp_params_cfg *params = params_vdev->isp35_params; + struct rkisp_device *dev = params_vdev->dev; + unsigned long flags = 0; + int i; + + rkisp_params_check_bigmode_v35(params_vdev); + spin_lock_irqsave(¶ms_vdev->config_lock, flags); + for (i = 0; i < dev->unite_div; i++) { + u64 module_cfg_update = params->module_cfg_update; + u64 module_en_update = params->module_en_update; + u64 module_ens = params->module_ens; + + if (!module_cfg_update || !module_en_update || !module_ens) + dev_warn(dev->dev, + "id:%d no first iq setting cfg_upd:%llx en_upd:%llx ens:%llx\n", + i, module_cfg_update, module_en_update, module_ens); + + __isp_isr_meas_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + } + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); + + if (dev->hw_dev->is_single && (dev->isp_state & ISP_START)) { + rkisp_set_bits(dev, ISP3X_ISP_CTRL0, 0, CIF_ISP_CTRL_ISP_CFG_UPD, true); + rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); + } +} + +static void rkisp_save_first_param_v35(struct rkisp_isp_params_vdev *params_vdev, void *param) +{ + u32 size; + + if (!params_vdev->dev->is_rtt_first) { + size = params_vdev->vdev_fmt.fmt.meta.buffersize; + memcpy(params_vdev->isp35_params, param, size); + } else { + /* left and right params for unit fast case */ + size = sizeof(struct isp35_isp_params_cfg); + memcpy(params_vdev->isp35_params, param, size); + if (params_vdev->dev->unite_div == ISP_UNITE_DIV2) + memcpy(params_vdev->isp35_params + 1, param, size); + } + rkisp_alloc_internal_buf(params_vdev, params_vdev->isp35_params); +} + +static void rkisp_clear_first_param_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + u32 mult = params_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; + u32 size = sizeof(struct isp35_isp_params_cfg) * mult; + + memset(params_vdev->isp33_params, 0, size); +} + +static void rkisp_deinit_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, + u64 module_id, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf = NULL; + int i; + + if (!priv) + return; + + switch (module_id) { + case ISP35_MODULE_LDCH: + buf = priv->buf_ldch[id]; + break; + case ISP35_MODULE_BAY3D: + buf = priv->buf_b3dldc[id]; + break; + default: + return; + } + + for (i = 0; i < ISP35_MESH_BUF_NUM; i++) + rkisp_free_buffer(params_vdev->dev, buf + i); +} + +static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_meshbuf_size *meshsize) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *ispdev = params_vdev->dev; + struct device *dev = ispdev->dev; + struct isp2x_mesh_head *mesh_head; + struct rkisp_dummy_buffer *buf; + u32 mesh_w = meshsize->meas_width; + u32 mesh_h = meshsize->meas_height; + u32 mesh_size, buf_size; + int i, ret, buf_cnt = meshsize->buf_cnt; + int id = meshsize->unite_isp_id; + bool is_alloc; + + if (!priv) { + dev_err(dev, "priv_val is NULL\n"); + return -EINVAL; + } + + switch (meshsize->module_id) { + case ISP35_MODULE_LDCH: + priv->buf_ldch_idx[id] = 0; + buf = priv->buf_ldch[id]; + mesh_w = ((mesh_w + 15) / 16 + 2) / 2; + mesh_h = (mesh_h + 7) / 8 + 1; + mesh_size = mesh_w * 4 * mesh_h; + break; + case ISP35_MODULE_BAY3D: + priv->buf_b3dldc_idx[id] = 0; + buf = priv->buf_b3dldc[id]; + /* b3d_ldch */ + mesh_w = ALIGN((ALIGN(mesh_w, 16) / 16 + 1) / 2, 2); + mesh_h = ALIGN(mesh_h, 8) / 8 + 1; + mesh_size = ALIGN(mesh_w * mesh_h, 16); + priv->b3dldc_hsize = mesh_w; + priv->b3dldch_vsize = mesh_h; + /* b3d_ldcv */ + mesh_h = ALIGN(meshsize->meas_height, 16) / 16 + 2; + mesh_size += (mesh_w * mesh_h); + priv->b3dldcv_vsize = mesh_h; + break; + default: + return -EINVAL; + } + + if (buf_cnt <= 0 || buf_cnt > ISP35_MESH_BUF_NUM) + buf_cnt = ISP35_MESH_BUF_NUM; + buf_size = PAGE_ALIGN(mesh_size + ALIGN(sizeof(struct isp2x_mesh_head), 16)); + for (i = 0; i < buf_cnt; i++) { + buf->is_need_vaddr = true; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + is_alloc = true; + if (buf->mem_priv) { + if (buf_size > buf->size) { + rkisp_free_buffer(params_vdev->dev, buf); + } else { + is_alloc = false; + buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); + if (buf->dma_fd < 0) + goto err; + } + } + if (is_alloc) { + buf->size = buf_size; + ret = rkisp_alloc_buffer(params_vdev->dev, buf); + if (ret) { + dev_err(dev, "%s failed\n", __func__); + goto err; + } + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; + mesh_head->stat = MESH_BUF_INIT; + mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); + mesh_head->data1_oft = mesh_head->data_oft + + ALIGN(priv->b3dldc_hsize * priv->b3dldch_vsize, 16); + } + buf++; + } + + return 0; +err: + rkisp_deinit_mesh_buf(params_vdev, meshsize->module_id, id); + return -ENOMEM; +} + +static void +rkisp_get_param_size_v35(struct rkisp_isp_params_vdev *params_vdev, + unsigned int sizes[]) +{ + u32 mult = params_vdev->dev->unite_div; + + sizes[0] = sizeof(struct isp35_isp_params_cfg) * mult; + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + +static void +rkisp_params_get_meshbuf_inf_v35(struct rkisp_isp_params_vdev *params_vdev, + void *meshbuf_inf) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_meshbuf_info *meshbuf = meshbuf_inf; + struct rkisp_dummy_buffer *buf; + int i, id = meshbuf->unite_isp_id; + + switch (meshbuf->module_id) { + case ISP35_MODULE_LDCH: + priv->buf_ldch_idx[id] = 0; + buf = priv->buf_ldch[id]; + break; + default: + return; + } + + for (i = 0; i < ISP35_MESH_BUF_NUM; i++) { + if (!buf->mem_priv) { + meshbuf->buf_fd[i] = -1; + meshbuf->buf_size[i] = 0; + } else { + meshbuf->buf_fd[i] = buf->dma_fd; + meshbuf->buf_size[i] = buf->size; + } + buf++; + } +} + +static int +rkisp_params_set_meshbuf_size_v35(struct rkisp_isp_params_vdev *params_vdev, + void *size) +{ + struct rkisp_meshbuf_size *meshsize = size; + + if (!params_vdev->dev->hw_dev->unite) + meshsize->unite_isp_id = 0; + return rkisp_init_mesh_buf(params_vdev, meshsize); +} + +static void +rkisp_params_free_meshbuf_v35(struct rkisp_isp_params_vdev *params_vdev, + u64 module_id) +{ + int id; + + for (id = 0; id < params_vdev->dev->unite_div; id++) + rkisp_deinit_mesh_buf(params_vdev, module_id, id); +} + +static int +rkisp_params_info2ddr_cfg_v35(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_info2ddr *cfg = arg; + struct rkisp_dummy_buffer *buf; + u32 reg, ctrl, mask, size, val, wsize = 0, vsize = 0; + int i, ret; + + if (dev->is_aiisp_en) { + dev_err(dev->dev, "%s no support for aiisp enable\n", __func__); + return -EINVAL; + } + + if (cfg->buf_cnt > RKISP_INFO2DDR_BUF_MAX) + cfg->buf_cnt = RKISP_INFO2DDR_BUF_MAX; + else if (cfg->buf_cnt == 0) + cfg->buf_cnt = 1; + for (val = 0; val < cfg->buf_cnt; val++) + cfg->buf_fd[val] = -1; + + switch (cfg->owner) { + case RKISP_INFO2DRR_OWNER_NULL: + rkisp_clear_reg_cache_bits(dev, ISP3X_RAWAWB_CTRL, + ISP32_RAWAWB_2DDR_PATH_EN); + rkisp_clear_reg_cache_bits(dev, ISP3X_GAIN_CTRL, + ISP3X_GAIN_2DDR_EN); + priv->buf_info_owner = cfg->owner; + return 0; + case RKISP_INFO2DRR_OWNER_GAIN: + ctrl = ISP3X_GAIN_2DDR_MODE(cfg->u.gain.gain2ddr_mode); + ctrl |= ISP3X_GAIN_2DDR_EN; + mask = ISP3X_GAIN_2DDR_MODE(3); + reg = ISP3X_GAIN_CTRL; + + if (cfg->wsize) + wsize = (cfg->wsize + 7) / 8; + else + wsize = (dev->isp_sdev.in_crop.width + 7) / 8; + /* 0 or 3: 4x8mode, 1: 2x8 mode, 2: 1x8mode */ + val = cfg->u.gain.gain2ddr_mode; + val = (val == 1) ? 2 : ((val == 2) ? 1 : 4); + if (cfg->vsize) + vsize = cfg->vsize; + else + vsize = dev->isp_sdev.in_crop.height / val; + break; + case RKISP_INFO2DRR_OWNER_AWB: + ctrl = cfg->u.awb.awb2ddr_sel ? ISP32_RAWAWB_2DDR_PATH_DS : 0; + ctrl |= ISP32_RAWAWB_2DDR_PATH_EN; + mask = ISP32_RAWAWB_2DDR_PATH_DS; + reg = ISP3X_RAWAWB_CTRL; + + val = cfg->u.awb.awb2ddr_sel ? 8 : 1; + if (cfg->wsize) + wsize = cfg->wsize; + else + wsize = dev->isp_sdev.in_crop.width * 4 / val; + if (cfg->vsize) + vsize = cfg->vsize; + else + vsize = dev->isp_sdev.in_crop.height / val; + break; + default: + dev_err(dev->dev, "%s no support owner:%d\n", __func__, cfg->owner); + return -EINVAL; + } + + if (!wsize || !vsize) { + dev_err(dev->dev, "%s inval wsize:%d vsize:%d\n", __func__, wsize, vsize); + return -EINVAL; + } + + wsize = ALIGN(wsize, 16); + size = wsize * vsize; + for (i = 0; i < cfg->buf_cnt; i++) { + buf = &priv->buf_info[i]; + if (buf->mem_priv) + rkisp_free_buffer(dev, buf); + buf->size = size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + buf->is_need_vaddr = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "%s alloc buf failed\n", __func__); + goto err; + } + *(u32 *)buf->vaddr = RKISP_INFO2DDR_BUF_INIT; + cfg->buf_fd[i] = buf->dma_fd; + } + buf = &priv->buf_info[0]; + isp3_param_write(params_vdev, buf->dma_addr, ISP3X_MI_GAIN_WR_BASE, 0); + isp3_param_write(params_vdev, buf->size, ISP3X_MI_GAIN_WR_SIZE, 0); + isp3_param_write(params_vdev, wsize, ISP3X_MI_GAIN_WR_LENGTH, 0); + if (dev->hw_dev->is_single) + rkisp_write(dev, ISP3X_MI_WR_CTRL2, ISP3X_GAINSELF_UPD, true); + rkisp_set_reg_cache_bits(dev, reg, mask, ctrl); + + priv->buf_info_idx = 0; + priv->buf_info_cnt = cfg->buf_cnt; + priv->buf_info_owner = cfg->owner; + + cfg->wsize = wsize; + cfg->vsize = vsize; + return 0; +err: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_info[i]; + rkisp_free_buffer(dev, buf); + cfg->buf_fd[i] = -1; + } + cfg->owner = RKISP_INFO2DRR_OWNER_NULL; + cfg->buf_cnt = 0; + return -ENOMEM; +} + +static void +rkisp_params_get_bay3d_buffd_v35(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ +} + +static int +rkisp_params_get_aiawb_buffd_v35(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_aiawb_buffd *cfg = arg; + struct rkisp_dummy_buffer *buf; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + u32 width = out_crop->width, height = out_crop->height; + int i, size, ret, cnt = cfg->info.buf_cnt; + + if (cnt <= 0 || cnt > RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX; + switch (cfg->ds) { + case RKISP_AIAWB_DS_4X4: + size = (width / 4) * (height / 4) * 8; + break; + case RKISP_AIAWB_DS_8X4: + size = (width / 8) * (height / 4) * 8; + break; + case RKISP_AIAWB_DS_8X8: + size = (width / 8) * (height / 8) * 8; + break; + default: + case RKISP_AIAWB_DS_16X16: + size = (width / 16) * (height / 16) * 8; + break; + } + for (i = 0; i < cnt; i++) { + buf = &priv->buf_aiawb[i]; + if (buf->mem_priv) + rkisp_free_buffer(dev, buf); + buf->size = size; + buf->is_need_vaddr = true; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "%s alloc buf failed\n", __func__); + goto err; + } + buf->index = i; + cfg->info.buf_fd[i] = buf->dma_fd; + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, + "%s ds:%d idx:%d dma:0x%x fd:%d\n", + __func__, cfg->ds, i, (u32)buf->dma_addr, buf->dma_fd); + } + cfg->info.buf_cnt = cnt; + cfg->info.buf_size = size; + priv->buf_aiawb_idx = 0; + priv->buf_aiawb_cnt = cnt; + return 0; +err: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_aiawb[i]; + rkisp_free_buffer(dev, buf); + cfg->info.buf_fd[i] = -1; + } + cfg->info.buf_cnt = 0; + return -ENOMEM; +} + +static void +rkisp_params_stream_stop_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; + struct rkisp_device *ispdev = params_vdev->dev; + int i; + + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_wgt); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); + rkisp_free_buffer(ispdev, &priv_val->buf_gain); + for (i = 0; i < RKISP_STATS_DDR_BUF_NUM; i++) + rkisp_free_buffer(ispdev, &ispdev->stats_vdev.stats_buf[i]); + for (i = 0; i < priv_val->buf_aiawb_cnt; i++) + rkisp_free_buffer(ispdev, &priv_val->buf_aiawb[i]); + priv_val->buf_aiawb_cnt = 0; + priv_val->buf_aiawb_idx = 0; + priv_val->buf_info_owner = 0; + priv_val->buf_info_cnt = 0; + priv_val->buf_info_idx = -1; + for (i = 0; i < RKISP_INFO2DDR_BUF_MAX; i++) + rkisp_free_buffer(ispdev, &priv_val->buf_info[i]); +} + +static void +rkisp_params_fop_release_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + int id; + + for (id = 0; id < params_vdev->dev->unite_div; id++) + rkisp_deinit_mesh_buf(params_vdev, ISP35_MODULE_LDCH, id); +} + +static void +rkisp_params_disable_isp_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + int i; + + params_vdev->isp35_params->module_ens = 0; + params_vdev->isp35_params->module_en_update = ~ISP35_MODULE_FORCE; + for (i = 0; i < params_vdev->dev->unite_div; i++) { + __isp_isr_other_en(params_vdev, params_vdev->isp35_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params_vdev->isp35_params, RKISP_PARAMS_ALL, i); + } +} + +static void +module_data_abandon(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct isp2x_mesh_head *mesh_head; + int i; + + if (params->module_cfg_update & ISP35_MODULE_LDCH) { + const struct isp32_ldch_cfg *arg = ¶ms->others.ldch_cfg; + + for (i = 0; i < ISP35_MESH_BUF_NUM; i++) { + if (priv->buf_ldch[id][i].vaddr && + arg->buf_fd == priv->buf_ldch[id][i].dma_fd) { + mesh_head = priv->buf_ldch[id][i].vaddr; + mesh_head->stat = MESH_BUF_CHIPINUSE; + break; + } + } + } + + if (params->module_cfg_update & ISP35_MODULE_BAY3D) { + const struct isp35_bay3d_cfg *arg = ¶ms->others.bay3d_cfg; + + for (i = 0; i < ISP35_MESH_BUF_NUM; i++) { + if (priv->buf_b3dldc[id][i].vaddr && + arg->lut_buf_fd == priv->buf_b3dldc[id][i].dma_fd) { + mesh_head = priv->buf_b3dldc[id][i].vaddr; + mesh_head->stat = MESH_BUF_CHIPINUSE; + break; + } + } + } +} + +static void +rkisp_params_cfg_v35(struct rkisp_isp_params_vdev *params_vdev, + u32 frame_id, enum rkisp_params_type type) +{ + struct rkisp_device *dev = params_vdev->dev; + struct isp35_isp_params_cfg *params_rec, *new_params = NULL; + struct rkisp_buffer *cur_buf = NULL; + unsigned long flags = 0; + int i; + + spin_lock_irqsave(¶ms_vdev->config_lock, flags); + if (!params_vdev->streamon) + goto unlock; + + /* get buffer by frame_id */ + while (!list_empty(¶ms_vdev->params)) { + cur_buf = list_first_entry(¶ms_vdev->params, struct rkisp_buffer, queue); + new_params = (struct isp35_isp_params_cfg *)(cur_buf->vaddr[0]); + if (new_params->frame_id < frame_id) { + list_del(&cur_buf->queue); + if (list_empty(¶ms_vdev->params)) + break; + for (i = 0; i < dev->unite_div; i++) { + /* update en immediately */ + if (new_params->module_en_update || + (new_params->module_cfg_update & ISP35_MODULE_FORCE)) { + __isp_isr_meas_config(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + new_params->module_cfg_update = 0; + } + if (new_params->module_cfg_update & ISP35_MODULE_LDCH) + module_data_abandon(params_vdev, new_params, i); + new_params++; + } + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + cur_buf = NULL; + continue; + } else if (new_params->frame_id == frame_id) { + list_del(&cur_buf->queue); + } else { + cur_buf = NULL; + } + break; + } + + if (!cur_buf) + goto unlock; + + params_rec = params_vdev->isp35_params; + new_params = (struct isp35_isp_params_cfg *)(cur_buf->vaddr[0]); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, new_params, type, i); + __isp_isr_other_config(params_vdev, new_params, type, i); + __isp_isr_other_en(params_vdev, new_params, type, i); + __isp_isr_meas_en(params_vdev, new_params, type, i); + if (IS_HDR_RDBK(dev->rd_mode)) { + params_rec->others.hdrmge_cfg = new_params->others.hdrmge_cfg; + params_rec->others.drc_cfg = new_params->others.drc_cfg; + params_rec->module_cfg_update = new_params->module_cfg_update; + params_rec++; + } + new_params->module_cfg_update = 0; + new_params++; + } + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + +unlock: + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); +} + +static void +rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev) +{ + u32 value = isp3_param_read(params_vdev, ISP3X_ISP_CTRL1, 0); + int i; + + if (params_vdev->dev->hw_dev->is_single) + return; + value &= (ISP3X_YNR_FST_FRAME | + ISP3X_CNR_FST_FRAME | ISP33_GIC_FST_FRAME | + ISP33_ENH_FST_FRAME | ISP33_YHIST_FST_FRAME | + ISP3X_RAW3D_FST_FRAME | ISP32_SHP_FST_FRAME); + for (i = 0; i < params_vdev->dev->unite_div && value; i++) + isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, i); +} + +static void +rkisp_params_isr_v35(struct rkisp_isp_params_vdev *params_vdev, u32 isp_mis) +{ + struct rkisp_device *dev = params_vdev->dev; + u32 cur_frame_id, i; + + rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); + if (isp_mis & CIF_ISP_V_START) { + if (params_vdev->rdbk_times) + params_vdev->rdbk_times--; + + if (IS_HDR_RDBK(dev->rd_mode) && !params_vdev->rdbk_times) { + struct isp35_isp_params_cfg *params = params_vdev->isp35_params; + + for (i = 0; i < dev->unite_div; i++) { + if (params->module_cfg_update & ISP35_MODULE_HDRMGE) + isp_hdrmge_config(params_vdev, ¶ms->others.hdrmge_cfg, RKISP_PARAMS_SHD, i); + if (params->module_cfg_update & ISP35_MODULE_DRC) + isp_hdrdrc_config(params_vdev, ¶ms->others.drc_cfg, RKISP_PARAMS_SHD, i); + params->module_cfg_update = 0; + params++; + } + return; + } + } + + if ((isp_mis & CIF_ISP_FRAME) && !params_vdev->rdbk_times) + rkisp_params_clear_fstflg(params_vdev); + + if ((isp_mis & CIF_ISP_FRAME) && + !IS_HDR_RDBK(dev->rd_mode) && !params_vdev->rdbk_times) + rkisp_params_cfg_v35(params_vdev, cur_frame_id + 1, RKISP_PARAMS_ALL); +} + +static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { + .save_first_param = rkisp_save_first_param_v35, + .clear_first_param = rkisp_clear_first_param_v35, + .get_param_size = rkisp_get_param_size_v35, + .first_cfg = rkisp_params_first_cfg_v35, + .disable_isp = rkisp_params_disable_isp_v35, + .isr_hdl = rkisp_params_isr_v35, + .param_cfg = rkisp_params_cfg_v35, + .param_cfgsram = rkisp_params_cfgsram_v35, + .get_meshbuf_inf = rkisp_params_get_meshbuf_inf_v35, + .set_meshbuf_size = rkisp_params_set_meshbuf_size_v35, + .free_meshbuf = rkisp_params_free_meshbuf_v35, + .stream_stop = rkisp_params_stream_stop_v35, + .fop_release = rkisp_params_fop_release_v35, + .check_bigmode = rkisp_params_check_bigmode_v35, + .info2ddr_cfg = rkisp_params_info2ddr_cfg_v35, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v35, + .get_aiawb_buffd = rkisp_params_get_aiawb_buffd_v35, +}; + +int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v35 *priv; + int size; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + size = sizeof(struct isp35_isp_params_cfg); + if (params_vdev->dev->hw_dev->unite) + size *= ISP_UNITE_MAX; + params_vdev->isp35_params = vmalloc(size); + if (!params_vdev->isp35_params) { + kfree(priv); + return -ENOMEM; + } + + params_vdev->priv_val = priv; + params_vdev->ops = &rkisp_isp_params_ops_tbl; + rkisp_clear_first_param_v35(params_vdev); + priv->buf_info_owner = 0; + priv->buf_info_cnt = 0; + priv->buf_info_idx = -1; + return 0; +} + +void rkisp_uninit_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + + if (params_vdev->isp35_params) + vfree(params_vdev->isp35_params); + kfree(priv); + params_vdev->priv_val = NULL; +} + +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35_DBG) +static void rkisp_get_params_rawaf(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_rawaf_meas_cfg *arg = ¶ms->meas.rawaf; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RAWAF; + arg->gamma_en = !!(val & BIT(1)); + arg->gaus_en = !!(val & BIT(2)); + arg->h1_fv_mode = !!(val & BIT(8)); + arg->h2_fv_mode = !!(val & BIT(9)); + arg->v1_fv_mode = !!(val & BIT(10)); + arg->v2_fv_mode = !!(val & BIT(11)); + arg->ae_mode = !!(val & BIT(12)); + arg->y_mode = !!(val & BIT(13)); + arg->vldg_sel = !!(val & BIT(14)); + arg->v_dnscl_mode = (val >> 16) & 0x3; + arg->from_ynr = !!(val & BIT(19)); + arg->bnr_be_sel = !!(val & BIT(20)); + arg->hiir_left_border_mode = !!(val & BIT(21)); + arg->avg_ds_en = !!(val & BIT(22)); + arg->avg_ds_mode = !!(val & BIT(23)); + arg->h1_acc_mode = !!(val & BIT(24)); + arg->h2_acc_mode = !!(val & BIT(25)); + arg->v1_acc_mode = !!(val & BIT(26)); + arg->v2_acc_mode = !!(val & BIT(27)); + + val = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, 0); + arg->bnr2af_sel = !!(val & BIT(28)); + arg->rawaf_sel = (val >> 18) & 0x3; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_OFFSET_WINA, 0); + arg->win[0].v_offs = (val & 0x1fff); + arg->win[0].h_offs = (val >> 16) & 0x1fff; + val = isp3_param_read(params_vdev, ISP3X_RAWAF_SIZE_WINA, 0); + arg->win[0].v_size = (val & 0x1fff); + arg->win[0].h_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_OFFSET_WINB, 0); + arg->win[1].v_offs = (val & 0x1fff); + arg->win[1].h_offs = (val >> 16) & 0x1fff; + val = isp3_param_read(params_vdev, ISP3X_RAWAF_SIZE_WINB, 0); + arg->win[1].v_size = (val & 0x1fff); + arg->win[1].h_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP32L_RAWAF_CTRL1, 0); + arg->bls_offset = val & 0x1ff; + arg->bls_en = !!(val & BIT(12)); + arg->aehgl_en = !!(val & BIT(13)); + arg->hldg_dilate_num = (val >> 16) & 0x7; + arg->tnrin_shift = (val >> 20) & 0xf; + + for (i = 0; i < ISP35_RAWAF_GAMMA_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_RAWAF_GAMMA_Y0 + i * 4, 0); + arg->gamma_y[2 * i] = val & 0x3ff; + arg->gamma_y[2 * i + 1] = (val >> 16) & 0x3ff; + } + val = isp3_param_read(params_vdev, ISP3X_RAWAF_GAMMA_Y8, 0); + arg->gamma_y[16] = val & 0x3ff; + + val = isp3_param_read(params_vdev, ISP39_RAWAF_HVIIR_VAR_SHIFT, 0); + arg->h1iir_shift_wina = val & 0x7; + arg->h2iir_shift_wina = (val >> 4) & 0x7; + arg->v1iir_shift_wina = (val >> 8) & 0x7; + arg->v2iir_shift_wina = (val >> 12) & 0x7; + arg->h1iir_shift_winb = (val >> 16) & 0xf; + arg->h2iir_shift_winb = (val >> 20) & 0xf; + arg->v1iir_shift_winb = (val >> 24) & 0xf; + arg->v2iir_shift_winb = (val >> 28) & 0xf; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_HIIR_THRESH, 0); + arg->h_fv_thresh = val & 0xffff; + arg->v_fv_thresh = (val >> 16) & 0xfff; + + for (i = 0; i < ISP35_RAWAF_VFIR_COE_NUM; i++) { + val = isp3_param_read(params_vdev, ISP32_RAWAF_V_FIR_COE0 + i * 4, 0); + arg->v1fir_coe[i] = val & 0xfff; + arg->v2fir_coe[i] = (val >> 16) & 0xfff; + } + + for (i = 0; i < ISP35_RAWAF_GAUS_COE_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP32_RAWAF_GAUS_COE03 + i * 4, 0); + arg->gaus_coe[i * 4] = val & 0xff; + arg->gaus_coe[i * 4 + 1] = (val >> 8) & 0xff; + arg->gaus_coe[i * 4 + 2] = (val >> 16) & 0xff; + arg->gaus_coe[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP32_RAWAF_GAUS_COE8, 0); + arg->gaus_coe[ISP35_RAWAF_GAUS_COE_NUM - 1] = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_HIGHLIT_THRESH, 0); + arg->highlit_thresh = val & 0x3ff; + + val = isp3_param_read(params_vdev, ISP32L_RAWAF_CORING_H, 0); + arg->h_fv_limit = val & 0x3ff; + arg->h_fv_slope = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP32L_RAWAF_CORING_V, 0); + arg->v_fv_limit = val & 0x3ff; + arg->v_fv_slope = (val >> 16) & 0x1ff; + + for (i = 0; i < ISP35_RAWAF_HIIR_COE_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_RAWAF_H1_IIR1_COE01 + i * 4, 0); + arg->h1iir1_coe[i * 2] = val & 0xfff; + arg->h1iir1_coe[i * 2 + 1] = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_H1_IIR2_COE01 + i * 4, 0); + arg->h1iir2_coe[i * 2] = val & 0xfff; + arg->h1iir2_coe[i * 2 + 1] = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_H2_IIR1_COE01 + i * 4, 0); + arg->h2iir1_coe[i * 2] = val & 0xfff; + arg->h2iir1_coe[i * 2 + 1] = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_H2_IIR2_COE01 + i * 4, 0); + arg->h2iir2_coe[i * 2] = val & 0xfff; + arg->h2iir2_coe[i * 2 + 1] = (val >> 16) & 0xfff; + } + + for (i = 0; i < ISP35_RAWAF_VIIR_COE_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_RAWAF_V_IIR_COE0 + i * 4, 0); + arg->v1iir_coe[i] = val & 0xfff; + arg->v2iir_coe[i] = (val >> 16) & 0xfff; + } + + for (i = 0; i < ISP35_RAWAF_CURVE_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_RAWAF_H_CURVEL + i * 16, 0); + arg->curve_h[i].ldg_lumth = val & 0xff; + arg->curve_h[i].ldg_gain = (val >> 8) & 0xff; + arg->curve_h[i].ldg_gslp = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAF_V_CURVEL + i * 16, 0); + arg->curve_v[i].ldg_lumth = val & 0xff; + arg->curve_v[i].ldg_gain = (val >> 8) & 0xff; + arg->curve_v[i].ldg_gslp = (val >> 16) & 0x1fff; + } +} + +static void rkisp_get_params_rawawb(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_rawawb_meas_cfg *arg = ¶ms->meas.rawawb; + struct isp35_rawawb_meas_cfg *arg_rec = ¶ms_vdev->isp35_params->meas.rawawb; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RAWAWB; + arg->uv_en0 = !!(val & BIT(1)); + arg->xy_en0 = !!(val & BIT(2)); + arg->yuv3d_en0 = !!(val & BIT(3)); + arg->yuv3d_ls_idx0 = (val >> 4) & 0x7; + arg->yuv3d_ls_idx1 = (val >> 7) & 0x7; + arg->yuv3d_ls_idx2 = (val >> 10) & 0x7; + arg->yuv3d_ls_idx3 = (val >> 13) & 0x7; + arg->in_rshift_to_12bit_en = !!(val & BIT(16)); + arg->in_overexposure_check_en = !!(val & BIT(17)); + arg->wind_size = !!(val & BIT(18)); + arg->rawlsc_bypass_en = !!(val & BIT(19)); + arg->light_num = (val >> 20) & 0x7; + arg->uv_en1 = !!(val & BIT(24)); + arg->xy_en1 = !!(val & BIT(25)); + arg->yuv3d_en1 = !!(val & BIT(26)); + arg->low12bit_val = !!(val & BIT(28)); + + val = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, 0); + arg->rawawb_sel = (val >> 20) & 0x3; + arg->bnr2awb_sel = !!(val & BIT(26)); + arg->drc2awb_sel = !!(val & BIT(27)); + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_BLK_CTRL, 0); + arg->blk_measure_enable = !!(val & BIT(0)); + arg->blk_measure_mode = !!(val & BIT(1)); + arg->blk_measure_xytype = !!(val & BIT(2)); + arg->blk_rtdw_measure_en = !!(val & BIT(3)); + arg->blk_measure_illu_idx = (val >> 4) & 0x7; + arg->ds16x8_mode_en = !!(val & BIT(7)); + arg->blk_with_luma_wei_en = !!(val & BIT(8)); + arg->ovexp_2ddr_dis = !!(val & BIT(9)); + arg->bnr_be_sel = !!(val & BIT(10)); + arg->in_overexposure_threshold = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_WIN_OFFS, 0); + arg->h_offs = val & 0x1fff; + arg->v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_WIN_SIZE, 0); + arg->h_size = val & 0x1fff; + arg->v_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_LIMIT_RG_MAX, 0); + arg->r_max = val & 0xfff; + arg->g_max = (val >> 16) & 0xfff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_LIMIT_BY_MAX, 0); + arg->b_max = val & 0xfff; + arg->y_max = (val >> 16) & 0xfff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_LIMIT_RG_MIN, 0); + arg->r_min = val & 0xfff; + arg->g_min = (val >> 16) & 0xfff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_LIMIT_BY_MIN, 0); + arg->b_min = val & 0xfff; + arg->y_min = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_WEIGHT_CURVE_CTRL, 0); + arg->wp_luma_wei_en0 = !!(val & BIT(0)); + arg->wp_luma_wei_en1 = !!(val & BIT(1)); + arg->wp_blk_wei_en0 = !!(val & BIT(2)); + arg->wp_blk_wei_en1 = !!(val & BIT(3)); + arg->wp_hist_xytype = !!(val & BIT(4)); + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YWEIGHT_CURVE_XCOOR03, 0); + arg->wp_luma_weicurve_y0 = val & 0xff; + arg->wp_luma_weicurve_y1 = (val >> 8) & 0xff; + arg->wp_luma_weicurve_y2 = (val >> 16) & 0xff; + arg->wp_luma_weicurve_y3 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YWEIGHT_CURVE_XCOOR47, 0); + arg->wp_luma_weicurve_y4 = val & 0xff; + arg->wp_luma_weicurve_y5 = (val >> 8) & 0xff; + arg->wp_luma_weicurve_y6 = (val >> 16) & 0xff; + arg->wp_luma_weicurve_y7 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YWEIGHT_CURVE_XCOOR8, 0); + arg->wp_luma_weicurve_y8 = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YWEIGHT_CURVE_YCOOR03, 0); + arg->wp_luma_weicurve_w0 = val & 0x3f; + arg->wp_luma_weicurve_w1 = (val >> 8) & 0x3f; + arg->wp_luma_weicurve_w2 = (val >> 16) & 0x3f; + arg->wp_luma_weicurve_w3 = (val >> 24) & 0x3f; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YWEIGHT_CURVE_YCOOR47, 0); + arg->wp_luma_weicurve_w4 = val & 0x3f; + arg->wp_luma_weicurve_w5 = (val >> 8) & 0x3f; + arg->wp_luma_weicurve_w6 = (val >> 16) & 0x3f; + arg->wp_luma_weicurve_w7 = (val >> 24) & 0x3f; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YWEIGHT_CURVE_YCOOR8, 0); + arg->wp_luma_weicurve_w8 = val & 0x3f; + arg->pre_wbgain_inv_r = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_PRE_WBGAIN_INV, 0); + arg->pre_wbgain_inv_g = val & 0x1fff; + arg->pre_wbgain_inv_b = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX0_0, 0); + arg->vertex0_u_0 = val & 0x1ff; + arg->vertex0_v_0 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX1_0, 0); + arg->vertex1_u_0 = val & 0x1ff; + arg->vertex1_v_0 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX2_0, 0); + arg->vertex2_u_0 = val & 0x1ff; + arg->vertex2_v_0 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX3_0, 0); + arg->vertex3_u_0 = val & 0x1ff; + arg->vertex3_v_0 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE01_0, 0); + arg->islope01_0 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE12_0, 0); + arg->islope12_0 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE23_0, 0); + arg->islope23_0 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE30_0, 0); + arg->islope30_0 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX0_1, 0); + arg->vertex0_u_1 = val & 0x1ff; + arg->vertex0_v_1 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX1_1, 0); + arg->vertex1_u_1 = val & 0x1ff; + arg->vertex1_v_1 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX2_1, 0); + arg->vertex2_u_1 = val & 0x1ff; + arg->vertex2_v_1 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX3_1, 0); + arg->vertex3_u_1 = val & 0x1ff; + arg->vertex3_v_1 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE01_1, 0); + arg->islope01_1 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE12_1, 0); + arg->islope12_1 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE23_1, 0); + arg->islope23_1 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE30_1, 0); + arg->islope30_1 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX0_2, 0); + arg->vertex0_u_2 = val & 0x1ff; + arg->vertex0_v_2 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX1_2, 0); + arg->vertex1_u_2 = val & 0x1ff; + arg->vertex1_v_2 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX2_2, 0); + arg->vertex2_u_2 = val & 0x1ff; + arg->vertex2_v_2 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX3_2, 0); + arg->vertex3_u_2 = val & 0x1ff; + arg->vertex3_v_2 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE01_2, 0); + arg->islope01_2 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE12_2, 0); + arg->islope12_2 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE23_2, 0); + arg->islope23_2 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE30_2, 0); + arg->islope30_2 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX0_3, 0); + arg->vertex0_u_3 = val & 0x1ff; + arg->vertex0_v_3 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX1_3, 0); + arg->vertex1_u_3 = val & 0x1ff; + arg->vertex1_v_3 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX2_3, 0); + arg->vertex2_u_3 = val & 0x1ff; + arg->vertex2_v_3 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_VERTEX3_3, 0); + arg->vertex3_u_3 = val & 0x1ff; + arg->vertex3_v_3 = (val >> 16) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE01_3, 0); + arg->islope01_3 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE12_3, 0); + arg->islope12_3 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE23_3, 0); + arg->islope23_3 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_UV_DETC_ISLOPE30_3, 0); + arg->islope30_3 = val & 0xfffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_RGB2ROTY_0, 0); + arg->rgb2ryuvmat0_y = val & 0x3ff; + arg->rgb2ryuvmat1_y = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_RGB2ROTY_1, 0); + arg->rgb2ryuvmat2_y = val & 0x3ff; + arg->rgb2ryuvofs_y = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_RGB2ROTU_0, 0); + arg->rgb2ryuvmat0_u = val & 0x3ff; + arg->rgb2ryuvmat1_u = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_RGB2ROTU_1, 0); + arg->rgb2ryuvmat2_u = val & 0x3ff; + arg->rgb2ryuvofs_u = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_RGB2ROTV_0, 0); + arg->rgb2ryuvmat0_v = val & 0x3ff; + arg->rgb2ryuvmat1_v = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_RGB2ROTV_1, 0); + arg->rgb2ryuvmat2_v = val & 0x3ff; + arg->rgb2ryuvofs_v = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_Y_0, 0); + arg->coor_x1_ls0_y = val & 0xfff; + arg->vec_x21_ls0_y = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_U_0, 0); + arg->coor_x1_ls0_u = val & 0xfff; + arg->vec_x21_ls0_u = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_V_0, 0); + arg->coor_x1_ls0_v = val & 0xfff; + arg->vec_x21_ls0_v = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X1X2_DIS_0, 0); + arg->dis_x1x2_ls0 = val & 0x1f; + arg->rotu0_ls0 = (val >> 16) & 0xff; + arg->rotu1_ls0 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_0, 0); + arg->rotu2_ls0 = val & 0xff; + arg->rotu3_ls0 = (val >> 8) & 0xff; + arg->rotu4_ls0 = (val >> 16) & 0xff; + arg->rotu5_ls0 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_0, 0); + arg->th0_ls0 = val & 0xfff; + arg->th1_ls0 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_0, 0); + arg->th2_ls0 = val & 0xfff; + arg->th3_ls0 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_0, 0); + arg->th4_ls0 = val & 0xfff; + arg->th5_ls0 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_Y_1, 0); + arg->coor_x1_ls1_y = val & 0xfff; + arg->vec_x21_ls1_y = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_U_1, 0); + arg->coor_x1_ls1_u = val & 0xfff; + arg->vec_x21_ls1_u = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_V_1, 0); + arg->coor_x1_ls1_v = val & 0xfff; + arg->vec_x21_ls1_v = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X1X2_DIS_1, 0); + arg->dis_x1x2_ls1 = val & 0x1f; + arg->rotu0_ls1 = (val >> 16) & 0xff; + arg->rotu1_ls1 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_1, 0); + arg->rotu2_ls1 = val & 0xff; + arg->rotu3_ls1 = (val >> 8) & 0xff; + arg->rotu4_ls1 = (val >> 16) & 0xff; + arg->rotu5_ls1 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_1, 0); + arg->th0_ls1 = val & 0xfff; + arg->th1_ls1 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_1, 0); + arg->th2_ls1 = val & 0xfff; + arg->th3_ls1 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_1, 0); + arg->th4_ls1 = val & 0xfff; + arg->th5_ls1 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_Y_2, 0); + arg->coor_x1_ls2_y = val & 0xfff; + arg->vec_x21_ls2_y = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_U_2, 0); + arg->coor_x1_ls2_u = val & 0xfff; + arg->vec_x21_ls2_u = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_V_2, 0); + arg->coor_x1_ls2_v = val & 0xfff; + arg->vec_x21_ls2_v = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X1X2_DIS_2, 0); + arg->dis_x1x2_ls2 = val & 0x1f; + arg->rotu0_ls2 = (val >> 16) & 0xff; + arg->rotu1_ls2 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_2, 0); + arg->rotu2_ls2 = val & 0xff; + arg->rotu3_ls2 = (val >> 8) & 0xff; + arg->rotu4_ls2 = (val >> 16) & 0xff; + arg->rotu5_ls2 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_2, 0); + arg->th0_ls2 = val & 0xfff; + arg->th1_ls2 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_2, 0); + arg->th2_ls2 = val & 0xfff; + arg->th3_ls2 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_2, 0); + arg->th4_ls2 = val & 0xfff; + arg->th5_ls2 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_Y_3, 0); + arg->coor_x1_ls3_y = val & 0xfff; + arg->vec_x21_ls3_y = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_U_3, 0); + arg->coor_x1_ls3_u = val & 0xfff; + arg->vec_x21_ls3_u = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X_COOR_V_3, 0); + arg->coor_x1_ls3_v = val & 0xfff; + arg->vec_x21_ls3_v = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_X1X2_DIS_3, 0); + arg->dis_x1x2_ls3 = val & 0x1f; + arg->rotu0_ls3 = (val >> 16) & 0xff; + arg->rotu1_ls3 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_UCOOR_3, 0); + arg->rotu2_ls3 = val & 0xff; + arg->rotu3_ls3 = (val >> 8) & 0xff; + arg->rotu4_ls3 = (val >> 16) & 0xff; + arg->rotu5_ls3 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH0_3, 0); + arg->th0_ls3 = val & 0xfff; + arg->th1_ls3 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH1_3, 0); + arg->th2_ls3 = val & 0xfff; + arg->th3_ls3 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_YUV_INTERP_CURVE_TH2_3, 0); + arg->th4_ls3 = val & 0xfff; + arg->th5_ls3 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP33_RAWAWB_CCM_COEFF0_R, 0); + arg->ccm_coeff0_r = val & 0xffff; + arg->ccm_coeff1_r = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_RAWAWB_CCM_COEFF1_R, 0); + arg->ccm_coeff2_r = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_RAWAWB_CCM_COEFF0_G, 0); + arg->ccm_coeff0_g = val & 0xffff; + arg->ccm_coeff1_g = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_RAWAWB_CCM_COEFF1_G, 0); + arg->ccm_coeff2_g = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_RAWAWB_CCM_COEFF0_B, 0); + arg->ccm_coeff0_b = val & 0xffff; + arg->ccm_coeff1_b = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_RAWAWB_CCM_COEFF1_B, 0); + arg->ccm_coeff2_b = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_WT01, 0); + arg->wt0 = val & 0xfff; + arg->wt1 = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_WT2, 0); + arg->wt2 = val & 0xfff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_MAT0_XY, 0); + arg->mat0_x = val & 0x7fff; + arg->mat0_y = (val >> 16) & 0x7fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_MAT1_XY, 0); + arg->mat1_x = val & 0x7fff; + arg->mat1_y = (val >> 16) & 0x7fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_MAT2_XY, 0); + arg->mat2_x = val & 0x7fff; + arg->mat2_y = (val >> 16) & 0x7fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_0, 0); + arg->nor_x0_0 = val & 0x3fff; + arg->nor_x1_0 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_0, 0); + arg->nor_y0_0 = val & 0x3fff; + arg->nor_y1_0 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_0, 0); + arg->big_x0_0 = val & 0x3fff; + arg->big_x1_0 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_0, 0); + arg->big_y0_0 = val & 0x3fff; + arg->big_y1_0 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_1, 0); + arg->nor_x0_1 = val & 0x3fff; + arg->nor_x1_1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_1, 0); + arg->nor_y0_1 = val & 0x3fff; + arg->nor_y1_1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_1, 0); + arg->big_x0_1 = val & 0x3fff; + arg->big_x1_1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_1, 0); + arg->big_y0_1 = val & 0x3fff; + arg->big_y1_1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_2, 0); + arg->nor_x0_2 = val & 0x3fff; + arg->nor_x1_2 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_2, 0); + arg->nor_y0_2 = val & 0x3fff; + arg->nor_y1_2 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_2, 0); + arg->big_x0_2 = val & 0x3fff; + arg->big_x1_2 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_2, 0); + arg->big_y0_2 = val & 0x3fff; + arg->big_y1_2 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_3, 0); + arg->nor_x0_3 = val & 0x3fff; + arg->nor_x1_3 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_3, 0); + arg->nor_y0_3 = val & 0x3fff; + arg->nor_y1_3 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_3, 0); + arg->big_x0_3 = val & 0x3fff; + arg->big_x1_3 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_3, 0); + arg->big_y0_3 = val & 0x3fff; + arg->big_y1_3 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW_EXC_CTRL, 0); + arg->exc_wp_region0_excen = val & 0x3; + arg->exc_wp_region0_measen = !!(val & BIT(2)); + arg->exc_wp_region0_domain = !!(val & BIT(3)); + arg->exc_wp_region1_excen = (val >> 4) & 0x3; + arg->exc_wp_region1_measen = !!(val & BIT(6)); + arg->exc_wp_region1_domain = !!(val & BIT(7)); + arg->exc_wp_region2_excen = (val >> 8) & 0x3; + arg->exc_wp_region2_measen = !!(val & BIT(10)); + arg->exc_wp_region2_domain = !!(val & BIT(11)); + arg->exc_wp_region3_excen = (val >> 12) & 0x3; + arg->exc_wp_region3_measen = !!(val & BIT(14)); + arg->exc_wp_region3_domain = !!(val & BIT(15)); + arg->exc_wp_region4_excen = (val >> 16) & 0x3; + arg->exc_wp_region4_domain = !!(val & BIT(19)); + arg->exc_wp_region5_excen = (val >> 20) & 0x3; + arg->exc_wp_region5_domain = !!(val & BIT(23)); + arg->exc_wp_region6_excen = (val >> 24) & 0x3; + arg->exc_wp_region6_domain = !!(val & BIT(27)); + arg->multiwindow_en = !!(val & BIT(31)); + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW0_OFFS, 0); + arg->multiwindow0_h_offs = val & 0x1fff; + arg->multiwindow0_v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW0_SIZE, 0); + arg->multiwindow0_h_size = val & 0x1fff; + arg->multiwindow0_v_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW1_OFFS, 0); + arg->multiwindow1_h_offs = val & 0x1fff; + arg->multiwindow1_v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW1_SIZE, 0); + arg->multiwindow1_h_size = val & 0x1fff; + arg->multiwindow1_v_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW2_OFFS, 0); + arg->multiwindow2_h_offs = val & 0x1fff; + arg->multiwindow2_v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW2_SIZE, 0); + arg->multiwindow2_h_size = val & 0x1fff; + arg->multiwindow2_v_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW3_OFFS, 0); + arg->multiwindow3_h_offs = val & 0x1fff; + arg->multiwindow3_v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW3_SIZE, 0); + arg->multiwindow3_h_size = val & 0x1fff; + arg->multiwindow3_v_size = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION0_XU, 0); + arg->exc_wp_region0_xu0 = val & 0x3fff; + arg->exc_wp_region0_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION0_YV, 0); + arg->exc_wp_region0_yv0 = val & 0x3fff; + arg->exc_wp_region0_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION1_XU, 0); + arg->exc_wp_region1_xu0 = val & 0x3fff; + arg->exc_wp_region1_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION1_YV, 0); + arg->exc_wp_region1_yv0 = val & 0x3fff; + arg->exc_wp_region1_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION2_XU, 0); + arg->exc_wp_region2_xu0 = val & 0x3fff; + arg->exc_wp_region2_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION2_YV, 0); + arg->exc_wp_region2_yv0 = val & 0x3fff; + arg->exc_wp_region2_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION3_XU, 0); + arg->exc_wp_region3_xu0 = val & 0x3fff; + arg->exc_wp_region3_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION3_YV, 0); + arg->exc_wp_region3_yv0 = val & 0x3fff; + arg->exc_wp_region3_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION4_XU, 0); + arg->exc_wp_region4_xu0 = val & 0x3fff; + arg->exc_wp_region4_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION4_YV, 0); + arg->exc_wp_region4_yv0 = val & 0x3fff; + arg->exc_wp_region4_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION5_XU, 0); + arg->exc_wp_region5_xu0 = val & 0x3fff; + arg->exc_wp_region5_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION5_YV, 0); + arg->exc_wp_region5_yv0 = val & 0x3fff; + arg->exc_wp_region5_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION6_XU, 0); + arg->exc_wp_region6_xu0 = val & 0x3fff; + arg->exc_wp_region6_xu1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION6_YV, 0); + arg->exc_wp_region6_yv0 = val & 0x3fff; + arg->exc_wp_region6_yv1 = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP32_RAWAWB_EXC_WP_WEIGHT0_3, 0); + arg->exc_wp_region0_weight = val & 0x3f; + arg->exc_wp_region1_weight = (val >> 8) & 0x3f; + arg->exc_wp_region2_weight = (val >> 16) & 0x3f; + arg->exc_wp_region3_weight = (val >> 24) & 0x3f; + + val = isp3_param_read(params_vdev, ISP32_RAWAWB_EXC_WP_WEIGHT4_6, 0); + arg->exc_wp_region4_weight = val & 0x3f; + arg->exc_wp_region5_weight = (val >> 8) & 0x3f; + arg->exc_wp_region6_weight = (val >> 16) & 0x3f; + + memcpy(arg->wp_blk_wei_w, arg_rec->wp_blk_wei_w, ISP39_RAWAWB_WEIGHT_NUM); +} + +static void rkisp_get_params_rawae0(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_rawae_meas_cfg *arg = ¶ms->meas.rawae0; + const u32 ae_wnd_num[] = {1, 5, 15, 15}; + u32 addr = ISP3X_RAWAE_LITE_BASE, val; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RAWAE0; + arg->wnd_num = (val >> 1) & 0x3; + arg->wnd1_en = !!(val & BIT(4)); + arg->debug_en = !!(val & BIT(8)); + arg->bnr_be_sel = !!(val & BIT(9)); + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_OFFSET, 0); + arg->win0_h_offset = val & 0x1fff; + arg->win0_v_offset = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_BLK_SIZE, 0); + arg->win0_h_size = (val & 0x1fff) * ae_wnd_num[arg->wnd_num]; + arg->win0_v_size = ((val >> 16) & 0x1fff) * ae_wnd_num[arg->wnd_num]; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_OFFSET, 0); + arg->win1_h_offset = val & 0x1fff; + arg->win1_v_offset = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_SIZE, 0); + arg->win1_h_offset = (val & 0x1fff) - arg->win1_h_offset; + arg->win1_v_offset = ((val >> 16) & 0x1fff) - arg->win1_v_offset; + + val = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, 0); + arg->rawae_sel = (val >> 22) & 0x3; + arg->bnr2ae_sel = !!(val & BIT(30)); +} + +static void rkisp_get_params_rawae3(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_rawae_meas_cfg *arg = ¶ms->meas.rawae3; + const u32 ae_wnd_num[] = {1, 5, 15, 15}; + u32 addr = ISP3X_RAWAE_BIG1_BASE, val; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RAWAE3; + arg->wnd_num = (val >> 1) & 0x3; + arg->wnd1_en = !!(val & BIT(4)); + arg->debug_en = !!(val & BIT(8)); + arg->bnr_be_sel = !!(val & BIT(9)); + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_OFFSET, 0); + arg->win0_h_offset = val & 0x1fff; + arg->win0_v_offset = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_BLK_SIZE, 0); + arg->win0_h_size = (val & 0x1fff) * ae_wnd_num[arg->wnd_num]; + arg->win0_v_size = ((val >> 16) & 0x1fff) * ae_wnd_num[arg->wnd_num]; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_OFFSET, 0); + arg->win1_h_offset = val & 0x1fff; + arg->win1_v_offset = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_SIZE, 0); + arg->win1_h_size = (val & 0x1fff) - arg->win1_h_offset; + arg->win1_v_size = ((val >> 16) & 0x1fff) - arg->win1_v_offset; + + val = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, 0); + arg->rawae_sel = (val >> 16) & 0x3; + arg->bnr2ae_sel = !!(val & BIT(29)); +} + +static void rkisp_get_params_rawhist0(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_rawhist_meas_cfg *arg = ¶ms->meas.rawhist0; + struct isp35_rawhist_meas_cfg *arg_rec = ¶ms_vdev->isp35_params->meas.rawhist0; + const u32 hist_wnd_num[] = {5, 5, 15, 15}; + u32 addr = ISP3X_RAWHIST_LITE_BASE, val; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RAWHIST0; + arg->stepsize = (val >> 1) & 0x7; + arg->debug_en = !!(val & BIT(7)); + arg->mode = (val >> 8) & 0x7; + arg->waterline = (val >> 12) & 0xfff; + arg->data_sel = (val >> 24) & 0x7; + arg->wnd_num = (val >> 28) & 0x3; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_OFFS, 0); + arg->h_offset = val & 0x1fff; + arg->v_offset = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_SIZE, 0); + arg->h_size = (val & 0x1fff) * hist_wnd_num[arg->wnd_num]; + arg->v_size = ((val >> 16) & 0x1fff) * hist_wnd_num[arg->wnd_num]; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_RAW2Y_CC, 0); + arg->rcc = val & 0xff; + arg->gcc = (val >> 8) & 0xff; + arg->bcc = (val >> 16) & 0xff; + arg->off = (val >> 24) & 0xff; + + memcpy(arg->weight, arg_rec->weight, ISP35_RAWHIST_WEIGHT_NUM); +} + +static void rkisp_get_params_rawhist3(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_rawhist_meas_cfg *arg = ¶ms->meas.rawhist3; + struct isp35_rawhist_meas_cfg *arg_rec = ¶ms_vdev->isp35_params->meas.rawhist3; + const u32 hist_wnd_num[] = {5, 5, 15, 15}; + u32 addr = ISP3X_RAWHIST_BIG1_BASE, val; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RAWHIST3; + arg->stepsize = (val >> 1) & 0x7; + arg->debug_en = !!(val & BIT(7)); + arg->mode = (val >> 8) & 0x7; + arg->waterline = (val >> 12) & 0xfff; + arg->data_sel = (val >> 24) & 0x7; + arg->wnd_num = (val >> 28) & 0x3; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_OFFS, 0); + arg->h_offset = val & 0x1fff; + arg->v_offset = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_SIZE, 0); + arg->h_size = (val & 0x1fff) * hist_wnd_num[arg->wnd_num]; + arg->v_size = ((val >> 16) & 0x1fff) * hist_wnd_num[arg->wnd_num]; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_RAW2Y_CC, 0); + arg->rcc = val & 0xff; + arg->gcc = (val >> 8) & 0xff; + arg->bcc = (val >> 16) & 0xff; + arg->off = (val >> 24) & 0xff; + + memcpy(arg->weight, arg_rec->weight, ISP35_RAWHIST_WEIGHT_NUM); +} + +static void rkisp_get_params_bls(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_bls_cfg *arg = ¶ms->others.bls_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_BLS; + arg->enable_auto = !!(val & BIT(1)); + arg->en_windows = (val >> 2) & 0x3; + arg->bls1_en = !!(val & BIT(4)); + params->meas.rawawb.bls2_en = !!(val & BIT(5)); + + switch (params_vdev->raw_type) { + case RAW_BGGR: + val = isp3_param_read(params_vdev, ISP3X_BLS_D_FIXED, 0); + arg->fixed_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_C_FIXED, 0); + arg->fixed_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_B_FIXED, 0); + arg->fixed_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_A_FIXED, 0); + arg->fixed_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP3X_BLS1_D_FIXED, 0); + arg->bls1_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_C_FIXED, 0); + arg->bls1_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_B_FIXED, 0); + arg->bls1_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_A_FIXED, 0); + arg->bls1_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP32_BLS2_D_FIXED, 0); + params->meas.rawawb.bls2_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_C_FIXED, 0); + params->meas.rawawb.bls2_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_B_FIXED, 0); + params->meas.rawawb.bls2_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_A_FIXED, 0); + params->meas.rawawb.bls2_val.b = (val & 0x1fff); + break; + case RAW_GBRG: + val = isp3_param_read(params_vdev, ISP3X_BLS_C_FIXED, 0); + arg->fixed_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_D_FIXED, 0); + arg->fixed_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_A_FIXED, 0); + arg->fixed_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_B_FIXED, 0); + arg->fixed_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP3X_BLS1_C_FIXED, 0); + arg->bls1_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_D_FIXED, 0); + arg->bls1_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_A_FIXED, 0); + arg->bls1_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_B_FIXED, 0); + arg->bls1_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP32_BLS2_C_FIXED, 0); + params->meas.rawawb.bls2_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_D_FIXED, 0); + params->meas.rawawb.bls2_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_A_FIXED, 0); + params->meas.rawawb.bls2_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_B_FIXED, 0); + params->meas.rawawb.bls2_val.b = (val & 0x1fff); + break; + case RAW_GRBG: + val = isp3_param_read(params_vdev, ISP3X_BLS_B_FIXED, 0); + arg->fixed_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_A_FIXED, 0); + arg->fixed_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_D_FIXED, 0); + arg->fixed_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_C_FIXED, 0); + arg->fixed_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP3X_BLS1_B_FIXED, 0); + arg->bls1_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_A_FIXED, 0); + arg->bls1_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_D_FIXED, 0); + arg->bls1_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_C_FIXED, 0); + arg->bls1_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP32_BLS2_B_FIXED, 0); + params->meas.rawawb.bls2_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_A_FIXED, 0); + params->meas.rawawb.bls2_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_D_FIXED, 0); + params->meas.rawawb.bls2_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_C_FIXED, 0); + params->meas.rawawb.bls2_val.b = (val & 0x1fff); + break; + case RAW_RGGB: + default: + val = isp3_param_read(params_vdev, ISP3X_BLS_A_FIXED, 0); + arg->fixed_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_B_FIXED, 0); + arg->fixed_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_C_FIXED, 0); + arg->fixed_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS_D_FIXED, 0); + arg->fixed_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP3X_BLS1_A_FIXED, 0); + arg->bls1_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_B_FIXED, 0); + arg->bls1_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_C_FIXED, 0); + arg->bls1_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP3X_BLS1_D_FIXED, 0); + arg->bls1_val.b = (val & 0x1fff); + + val = isp3_param_read(params_vdev, ISP32_BLS2_A_FIXED, 0); + params->meas.rawawb.bls2_val.r = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_B_FIXED, 0); + params->meas.rawawb.bls2_val.gr = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_C_FIXED, 0); + params->meas.rawawb.bls2_val.gb = (val & 0x1fff); + val = isp3_param_read(params_vdev, ISP32_BLS2_D_FIXED, 0); + params->meas.rawawb.bls2_val.b = (val & 0x1fff); + } + + val = isp3_param_read(params_vdev, ISP3X_BLS_SAMPLES, 0); + arg->bls_samples = val & 0x1f; + + val = isp3_param_read(params_vdev, ISP3X_BLS_H1_START, 0); + arg->bls_window1.h_offs = val & 0x3fff; + val = isp3_param_read(params_vdev, ISP3X_BLS_H1_STOP, 0); + arg->bls_window1.h_size = (val - arg->bls_window1.h_offs) & 0x3fff; + val = isp3_param_read(params_vdev, ISP3X_BLS_V1_START, 0); + arg->bls_window1.v_offs = val & 0x3fff; + val = isp3_param_read(params_vdev, ISP3X_BLS_V1_STOP, 0); + arg->bls_window1.v_size = (val - arg->bls_window1.v_offs) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP3X_BLS_H2_START, 0); + arg->bls_window2.h_offs = val & 0x3fff; + val = isp3_param_read(params_vdev, ISP3X_BLS_H2_STOP, 0); + arg->bls_window2.h_size = (val - arg->bls_window2.h_offs) & 0x3fff; + val = isp3_param_read(params_vdev, ISP3X_BLS_V2_START, 0); + arg->bls_window2.v_offs = val & 0x3fff; + val = isp3_param_read(params_vdev, ISP3X_BLS_V2_STOP, 0); + arg->bls_window2.v_size = (val - arg->bls_window2.v_offs) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP32_BLS_ISP_OB_OFFSET, 0); + arg->isp_ob_offset = val & 0x1ff; + arg->isp_ob_offset1 = (val >> 16) & 0x1ff; + val = isp3_param_read(params_vdev, ISP32_BLS_ISP_OB_PREDGAIN, 0); + arg->isp_ob_predgain = val & 0xffff; + val = isp3_param_read(params_vdev, ISP32_BLS_ISP_OB_MAX, 0); + arg->isp_ob_max = val & 0xfffff; +} + +static void rkisp_get_params_dpcc(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp39_dpcc_cfg *arg = ¶ms->others.dpcc_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_MODE, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_DPCC; + arg->grayscale_mode = !!(val & BIT(1)); + arg->stage1_enable = !!(val & BIT(2)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_OUTPUT_MODE, 0); + arg->stage1_incl_green_center = !!(val & BIT(0)); + arg->stage1_incl_rb_center = !!(val & BIT(1)); + arg->stage1_g_3x3 = !!(val & BIT(2)); + arg->stage1_rb_3x3 = !!(val & BIT(3)); + arg->sw_dpcc_output_sel = !!(val & BIT(4)); + arg->sw_rk_out_sel = (val >> 5) & 0x3; + arg->border_bypass_mode = !!(val & BIT(8)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_SET_USE, 0); + arg->stage1_use_set_1 = !!(val & BIT(0)); + arg->stage1_use_set_2 = !!(val & BIT(1)); + arg->stage1_use_set_3 = !!(val & BIT(2)); + arg->stage1_use_fix_set = !!(val & BIT(3)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_METHODS_SET_1, 0); + arg->pg_green1_enable = !!(val & BIT(0)); + arg->lc_green1_enable = !!(val & BIT(1)); + arg->ro_green1_enable = !!(val & BIT(2)); + arg->rnd_green1_enable = !!(val & BIT(3)); + arg->rg_green1_enable = !!(val & BIT(4)); + arg->sw_rk_green1_en = !!(val & BIT(5)); + arg->pg_red_blue1_enable = !!(val & BIT(8)); + arg->lc_red_blue1_enable = !!(val & BIT(9)); + arg->ro_red_blue1_enable = !!(val & BIT(10)); + arg->rnd_red_blue1_enable = !!(val & BIT(11)); + arg->rg_red_blue1_enable = !!(val & BIT(12)); + arg->sw_rk_red_blue1_en = !!(val & BIT(13)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_METHODS_SET_2, 0); + arg->pg_green2_enable = !!(val & BIT(0)); + arg->lc_green2_enable = !!(val & BIT(1)); + arg->ro_green2_enable = !!(val & BIT(2)); + arg->rnd_green2_enable = !!(val & BIT(3)); + arg->rg_green2_enable = !!(val & BIT(4)); + arg->sw_rk_green2_en = !!(val & BIT(5)); + arg->pg_red_blue2_enable = !!(val & BIT(8)); + arg->lc_red_blue2_enable = !!(val & BIT(9)); + arg->ro_red_blue2_enable = !!(val & BIT(10)); + arg->rnd_red_blue2_enable = !!(val & BIT(11)); + arg->rg_red_blue2_enable = !!(val & BIT(12)); + arg->sw_rk_red_blue2_en = !!(val & BIT(13)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_METHODS_SET_3, 0); + arg->pg_green3_enable = !!(val & BIT(0)); + arg->lc_green3_enable = !!(val & BIT(1)); + arg->ro_green3_enable = !!(val & BIT(2)); + arg->rnd_green3_enable = !!(val & BIT(3)); + arg->rg_green3_enable = !!(val & BIT(4)); + arg->sw_rk_green3_en = !!(val & BIT(5)); + arg->pg_red_blue3_enable = !!(val & BIT(8)); + arg->lc_red_blue3_enable = !!(val & BIT(9)); + arg->ro_red_blue3_enable = !!(val & BIT(10)); + arg->rnd_red_blue3_enable = !!(val & BIT(11)); + arg->rg_red_blue3_enable = !!(val & BIT(12)); + arg->sw_rk_red_blue3_en = !!(val & BIT(13)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_LINE_THRESH_1, 0); + arg->line_thr_1_g = val & 0xff; + arg->line_thr_1_rb = (val >> 8) & 0xff; + arg->sw_mindis1_g = (val >> 16) & 0xff; + arg->sw_mindis1_rb = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_LINE_MAD_FAC_1, 0); + arg->line_mad_fac_1_g = val & 0xff; + arg->line_mad_fac_1_rb = (val >> 8) & 0xff; + arg->sw_dis_scale_max1 = (val >> 16) & 0xff; + arg->sw_dis_scale_min1 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PG_FAC_1, 0); + arg->pg_fac_1_g = val & 0xff; + arg->pg_fac_1_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RND_THRESH_1, 0); + arg->rnd_thr_1_g = val & 0xff; + arg->rnd_thr_1_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RG_FAC_1, 0); + arg->rg_fac_1_g = val & 0xff; + arg->rg_fac_1_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_LINE_THRESH_2, 0); + arg->line_thr_2_g = val & 0xff; + arg->line_thr_2_rb = (val >> 8) & 0xff; + arg->sw_mindis2_g = (val >> 16) & 0xff; + arg->sw_mindis2_rb = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_LINE_MAD_FAC_2, 0); + arg->line_mad_fac_2_g = val & 0xff; + arg->line_mad_fac_2_rb = (val >> 8) & 0xff; + arg->sw_dis_scale_max2 = (val >> 16) & 0xff; + arg->sw_dis_scale_min2 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PG_FAC_2, 0); + arg->pg_fac_2_g = val & 0xff; + arg->pg_fac_2_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RND_THRESH_2, 0); + arg->rnd_thr_2_g = val & 0xff; + arg->rnd_thr_2_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RG_FAC_2, 0); + arg->rg_fac_2_g = val & 0xff; + arg->rg_fac_2_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_LINE_THRESH_3, 0); + arg->line_thr_3_g = val & 0xff; + arg->line_thr_3_rb = (val >> 8) & 0xff; + arg->sw_mindis3_g = (val >> 16) & 0xff; + arg->sw_mindis3_rb = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_LINE_MAD_FAC_3, 0); + arg->line_mad_fac_3_g = val & 0xff; + arg->line_mad_fac_3_rb = (val >> 8) & 0xff; + arg->sw_dis_scale_max3 = (val >> 16) & 0xff; + arg->sw_dis_scale_min3 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PG_FAC_3, 0); + arg->pg_fac_3_g = val & 0xff; + arg->pg_fac_3_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RND_THRESH_3, 0); + arg->rnd_thr_3_g = val & 0xff; + arg->rnd_thr_3_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RG_FAC_3, 0); + arg->rg_fac_3_g = val & 0xff; + arg->rg_fac_3_rb = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RO_LIMITS, 0); + arg->ro_lim_1_g = val & 0x3; + arg->ro_lim_1_rb = (val >> 2) & 0x3; + arg->ro_lim_2_g = (val >> 4) & 0x3; + arg->ro_lim_2_rb = (val >> 6) & 0x3; + arg->ro_lim_3_g = (val >> 8) & 0x3; + arg->ro_lim_3_rb = (val >> 10) & 0x3; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_RND_OFFS, 0); + arg->rnd_offs_1_g = val & 0x3; + arg->rnd_offs_1_rb = (val >> 2) & 0x3; + arg->rnd_offs_2_g = (val >> 4) & 0x3; + arg->rnd_offs_2_rb = (val >> 6) & 0x3; + arg->rnd_offs_3_g = (val >> 8) & 0x3; + arg->rnd_offs_3_rb = (val >> 10) & 0x3; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PDAF_EN, 0); + arg->sw_pdaf_en = !!(val & BIT(0)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PDAF_POINT_EN, 0); + for (i = 0; i < ISP35_DPCC_PDAF_POINT_NUM; i++) + arg->pdaf_point_en[i] = !!(val & BIT(i)); + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PDAF_OFFSET, 0); + arg->pdaf_offsetx = val & 0xffff; + arg->pdaf_offsety = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PDAF_WRAP, 0); + arg->pdaf_wrapx = val & 0xffff; + arg->pdaf_wrapy = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP_DPCC0_PDAF_SCOPE, 0); + arg->pdaf_wrapx_num = val & 0xffff; + arg->pdaf_wrapy_num = (val >> 16) & 0xffff; + + for (i = 0; i < ISP35_DPCC_PDAF_POINT_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PDAF_POINT_0 + 4 * i, 0); + arg->point[2 * i].x = val & 0xff; + arg->point[2 * i].y = (val >> 8) & 0xff; + arg->point[2 * i + 1].x = (val >> 16) & 0xff; + arg->point[2 * i + 1].y = (val >> 24) & 0xff; + } + + val = isp3_param_read(params_vdev, ISP3X_DPCC0_PDAF_FORWARD_MED, 0); + arg->pdaf_forward_med = !!(val & BIT(0)); +} + +static void rkisp_get_params_lsc(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp3x_lsc_cfg *arg = ¶ms->others.lsc_cfg; + struct isp3x_lsc_cfg *arg_rec = ¶ms_vdev->isp35_params->others.lsc_cfg; + u32 val, i; + + val = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_LSC; + arg->sector_16x16 = !!(val & BIT(2)); + + for (i = 0; i < ISP35_LSC_SIZE_TBL_SIZE / 4; i++) { + val = isp3_param_read(params_vdev, ISP3X_LSC_XSIZE_01 + i * 4, 0); + arg->x_size_tbl[i * 2] = val & 0xffff; + arg->x_size_tbl[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_XSIZE_89 + i * 4, 0); + arg->x_size_tbl[i * 2 + 8] = val & 0xffff; + arg->x_size_tbl[i * 2 + 9] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_XGRAD_01 + i * 4, 0); + arg->x_grad_tbl[i * 2] = val & 0xffff; + arg->x_grad_tbl[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_XGRAD_89 + i * 4, 0); + arg->x_grad_tbl[i * 2 + 8] = val & 0xffff; + arg->x_grad_tbl[i * 2 + 9] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_YSIZE_01 + i * 4, 0); + arg->y_size_tbl[i * 2] = val & 0xffff; + arg->y_size_tbl[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_YSIZE_89 + i * 4, 0); + arg->y_size_tbl[i * 2 + 8] = val & 0xffff; + arg->y_size_tbl[i * 2 + 9] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_YGRAD_01 + i * 4, 0); + arg->y_grad_tbl[i * 2] = val & 0xffff; + arg->y_grad_tbl[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_LSC_YGRAD_89 + i * 4, 0); + arg->y_grad_tbl[i * 2 + 8] = val & 0xffff; + arg->y_grad_tbl[i * 2 + 9] = (val >> 16) & 0xffff; + } + memcpy(arg->r_data_tbl, arg_rec->r_data_tbl, ISP3X_LSC_DATA_TBL_SIZE); + memcpy(arg->gr_data_tbl, arg_rec->gr_data_tbl, ISP3X_LSC_DATA_TBL_SIZE); + memcpy(arg->gb_data_tbl, arg_rec->gb_data_tbl, ISP3X_LSC_DATA_TBL_SIZE); + memcpy(arg->b_data_tbl, arg_rec->b_data_tbl, ISP3X_LSC_DATA_TBL_SIZE); +} + +static void rkisp_get_params_awbgain(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp32_awb_gain_cfg *arg = ¶ms->others.awb_gain_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_ISP_CTRL0, 0); + if (!(val & CIF_ISP_CTRL_ISP_AWB_ENA)) + return; + params->module_ens |= ISP35_MODULE_AWB_GAIN; + + val = isp3_param_read(params_vdev, ISP3X_ISP_AWB_GAIN0_G, 0); + arg->gain0_green_b = val & 0xffff; + arg->gain0_green_r = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_ISP_AWB_GAIN0_RB, 0); + arg->gain0_blue = val & 0xffff; + arg->gain0_red = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_ISP_AWB_GAIN1_G, 0); + arg->gain1_green_b = val & 0xffff; + arg->gain1_green_r = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_ISP_AWB_GAIN1_RB, 0); + arg->gain1_blue = val & 0xffff; + arg->gain1_red = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_ISP_AWB_GAIN2_G, 0); + arg->gain2_green_b = val & 0xffff; + arg->gain2_green_r = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_ISP_AWB_GAIN2_RB, 0); + arg->gain2_blue = val & 0xffff; + arg->gain2_red = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP32_ISP_AWB1_GAIN_G, 0); + arg->awb1_gain_gb = val & 0xffff; + arg->awb1_gain_gr = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP32_ISP_AWB1_GAIN_RB, 0); + arg->awb1_gain_b = val & 0xffff; + arg->awb1_gain_r = (val >> 16) & 0xffff; +} + +static void rkisp_get_params_gic(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp33_gic_cfg *arg = ¶ms->others.gic_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_GIC_CONTROL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_GIC; + arg->bypass_en = !!(val & BIT(1)); + arg->pro_mode = !!(val & BIT(2)); + arg->manualnoisecurve_en = !!(val & BIT(3)); + arg->manualnoisethred_en = !!(val & BIT(4)); + arg->gain_bypass_en = !!(val & BIT(5)); + + val = isp3_param_read(params_vdev, ISP33_GIC_MEDFLT_PARA, 0); + arg->medflt_minthred = val & 0xf; + arg->medflt_maxthred = (val >> 4) & 0xf; + arg->medflt_ratio = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_MEDFLTUV_PARA, 0); + arg->medfltuv_minthred = val & 0xf; + arg->medfltuv_maxthred = (val >> 4) & 0xf; + arg->medfltuv_ratio = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_NOISE_SCALE, 0); + arg->noisecurve_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_GIC_BILAT_PARA1, 0); + arg->bffltwgt_offset = val & 0xffff; + arg->bffltwgt_scale = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_BILAT_PARA2, 0); + arg->bfflt_ratio = val & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_DISWGT_COEFF, 0); + arg->bfflt_coeff0 = val & 0xff; + arg->bfflt_coeff1 = (val >> 8) & 0xff; + arg->bfflt_coeff2 = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_GIC_SIGMA_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_GIC_SIGMA_Y0 + 4 * i, 0); + arg->bfflt_vsigma_y[2 * i] = val & 0xffff; + arg->bfflt_vsigma_y[2 * i + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP33_GIC_SIGMA_Y8, 0); + arg->bfflt_vsigma_y[2 * i] = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_GIC_LUMA_DX, 0); + for (i = 0; i < ISP35_GIC_LUMA_DX_NUM; i++) + arg->luma_dx[i] = (val >> (i * 4)) & 0xf; + + for (i = 0; i < ISP35_GIC_THRED_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_GIC_THRED_Y0 + i * 4, 0); + arg->thred_y[i * 2] = val & 0xffff; + arg->thred_y[i * 2 + 1] = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_GIC_MIN_THRED_Y0 + i * 4, 0); + arg->minthred_y[i * 2] = val & 0xffff; + arg->minthred_y[i * 2 + 1] = (val >> 16) & 0xffff; + } + + val = isp3_param_read(params_vdev, ISP33_GIC_THRED_SCALE, 0); + arg->autonoisethred_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_GIC_LOFLTGR_COEFF, 0); + arg->lofltgr_coeff0 = val & 0xff; + arg->lofltgr_coeff1 = (val >> 8) & 0xff; + arg->lofltgr_coeff2 = (val >> 16) & 0xff; + arg->lofltgr_coeff3 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_LOFLTGB_COEFF, 0); + arg->lofltgb_coeff0 = val & 0xff; + arg->lofltgb_coeff1 = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_SUM_LOFLT_INV, 0); + arg->sumlofltcoeff_inv = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_GIC_LOFLTTHRED_COEFF, 0); + arg->lofltthred_coeff0 = val & 0xff; + arg->lofltthred_coeff1 = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_GAIN, 0); + arg->global_gain = val & 0x3ff; + arg->globalgain_alpha = (val >> 12) & 0xf; + arg->globalgain_scale = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_GIC_GAIN_SLOPE, 0); + arg->gain_offset = val & 0xffff; + arg->gain_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_GIC_GAIN_THRED, 0); + arg->gainadjflt_minthred = val & 0xffff; + arg->gainadjflt_maxthred = (val >> 16) & 0xffff; +} + +static void rkisp_get_params_debayer(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_debayer_cfg *arg = ¶ms->others.debayer_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_DEBAYER_CONTROL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_DEBAYER; + arg->bypass = !!(val & BIT(1)); + arg->g_out_flt_en = !!(val & BIT(4)); + arg->cnt_flt_en = !!(val & BIT(8)); + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_LUMA_DX, 0); + arg->luma_dx[0] = val & 0xf; + arg->luma_dx[1] = (val >> 4) & 0xf; + arg->luma_dx[2] = (val >> 8) & 0xf; + arg->luma_dx[3] = (val >> 12) & 0xf; + arg->luma_dx[4] = (val >> 16) & 0xf; + arg->luma_dx[5] = (val >> 20) & 0xf; + arg->luma_dx[6] = (val >> 24) & 0xf; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_INTERP, 0); + arg->g_interp_clip_en = !!(val & BIT(0)); + arg->hi_texture_thred = (val >> 4) & 0xf; + arg->hi_drct_thred = (val >> 8) & 0xf; + arg->lo_drct_thred = (val >> 12) & 0xf; + arg->drct_method_thred = (val >> 16) & 0xff; + arg->g_interp_sharp_strg_max_limit = (val >> 24) & 0x3f; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_INTERP_FILTER1, 0); + arg->lo_drct_flt_coeff1 = val & 0x1f; + arg->lo_drct_flt_coeff2 = (val >> 8) & 0x1f; + arg->lo_drct_flt_coeff3 = (val >> 16) & 0x1f; + arg->lo_drct_flt_coeff4 = (val >> 24) & 0x1f; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_INTERP_FILTER2, 0); + arg->hi_drct_flt_coeff1 = val & 0x1f; + arg->hi_drct_flt_coeff2 = (val >> 8) & 0x1f; + arg->hi_drct_flt_coeff3 = (val >> 16) & 0x1f; + arg->hi_drct_flt_coeff4 = (val >> 24) & 0x1f; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_INTERP_OFFSET_ALPHA, 0); + arg->g_interp_sharp_strg_offset = val & 0xfff; + arg->grad_lo_flt_alpha = (val >> 16) & 0x7f; + + for (i = 0; i < ISP35_DEBAYER_DRCT_OFFSET_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_INTERP_DRCT_OFFSET0 + i * 4, 0); + arg->drct_offset[i * 2] = val & 0xffff; + arg->drct_offset[i * 2 + 1] = (val >> 16) & 0xffff; + } + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_FILTER_MODE_OFFSET, 0); + arg->gflt_mode = !!(val & BIT(0)); + arg->gflt_ratio = (val >> 4) & 0x7ff; + arg->gflt_offset = (val >> 16) & 0x7ff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_FILTER_FILTER, 0); + arg->gflt_coe0 = val & 0xff; + arg->gflt_coe1 = (val >> 8) & 0xff; + arg->gflt_coe2 = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_DEBAYER_VSIGMA_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP39_DEBAYER_G_FILTER_VSIGMA0 + i * 4, 0); + arg->gflt_vsigma[i * 2] = val & 0xffff; + arg->gflt_vsigma[i * 2 + 1] = (val >> 16) & 0xffff; + } + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_GUIDE_GAUS, 0); + arg->cnr_lo_guide_lpf_coe0 = val & 0xff; + arg->cnr_lo_guide_lpf_coe1 = (val >> 8) & 0xff; + arg->cnr_lo_guide_lpf_coe2 = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_CE_GAUS, 0); + arg->cnr_pre_flt_coe0 = val & 0xff; + arg->cnr_pre_flt_coe1 = (val >> 8) & 0xff; + arg->cnr_pre_flt_coe2 = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_ALPHA_GAUS, 0); + arg->cnr_alpha_lpf_coe0 = val & 0xff; + arg->cnr_alpha_lpf_coe1 = (val >> 8) & 0xff; + arg->cnr_alpha_lpf_coe2 = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_LOG_OFFSET, 0); + arg->cnr_log_grad_offset = val & 0x1fff; + arg->cnr_log_guide_offset = (val >> 16) & 0xfff; + arg->cnr_trans_en = !!(val & BIT(31)); + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_ALPHA, 0); + arg->cnr_moire_alpha_offset = val & 0xfff; + arg->cnr_moire_alpha_scale = (val >> 12) & 0xfffff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_EDGE, 0); + arg->cnr_edge_alpha_offset = val & 0xfff; + arg->cnr_edge_alpha_scale = (val >> 12) & 0xfffff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_IIR_0, 0); + arg->cnr_lo_flt_strg_inv = val & 0xff; + arg->cnr_lo_flt_strg_shift = (val >> 8) & 0x3f; + arg->cnr_lo_flt_wgt_slope = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_IIR_1, 0); + arg->cnr_lo_flt_wgt_max_limit = val & 0x7f; + arg->cnr_lo_flt_wgt_min_thred = (val >> 8) & 0x3f; + + val = isp3_param_read(params_vdev, ISP39_DEBAYER_C_FILTER_BF, 0); + arg->cnr_hi_flt_vsigma = val & 0xffff; + arg->cnr_hi_flt_wgt_min_limit = (val >> 16) & 0x7f; + arg->cnr_hi_flt_cur_wgt = (val >> 24) & 0x7f; +} + +static void rkisp_get_params_ccm(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp33_ccm_cfg *arg = ¶ms->others.ccm_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_CCM_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_CCM; + arg->highy_adjust_dis = !!(val & BIT(1)); + arg->enh_adj_en = !!(val & BIT(2)); + arg->asym_adj_en = !!(val & BIT(3)); + arg->sat_decay_en = !!(val & BIT(4)); + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF0_R, 0); + arg->coeff0_r = val & 0xffff; + arg->coeff1_r = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF1_R, 0); + arg->coeff2_r = val & 0xffff; + arg->offset_r = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF0_G, 0); + arg->coeff0_g = val & 0xffff; + arg->coeff1_g = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF1_G, 0); + arg->coeff2_g = val & 0xffff; + arg->offset_g = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF0_B, 0); + arg->coeff0_b = val & 0xffff; + arg->coeff1_b = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF1_B, 0); + arg->coeff2_b = val & 0xffff; + arg->offset_b = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF0_Y, 0); + arg->coeff0_y = val & 0xffff; + arg->coeff1_y = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_CCM_COEFF1_Y, 0); + arg->coeff2_y = val & 0xffff; + + for (i = 0; i < ISP35_CCM_CURVE_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_CCM_ALP_Y0 + 4 * i, 0); + arg->alp_y[2 * i] = val & 0xffff; + arg->alp_y[2 * i + 1] = (val >> 16) & 0xffff; + } + + val = isp3_param_read(params_vdev, ISP3X_CCM_BOUND_BIT, 0); + arg->bound_bit = val & 0xf; + arg->right_bit = (val >> 4) & 0xf; + + val = isp3_param_read(params_vdev, ISP32_CCM_ENHANCE0, 0); + arg->color_coef0_r2y = val & 0x7ff; + arg->color_coef1_g2y = (val >> 16) & 0x7ff; + + val = isp3_param_read(params_vdev, ISP32_CCM_ENHANCE1, 0); + arg->color_coef2_b2y = val & 0x7ff; + arg->color_enh_rat_max = (val >> 16) & 0x3fff; + + val = isp3_param_read(params_vdev, ISP39_CCM_HF_THD, 0); + arg->hf_low = val & 0xff; + arg->hf_up = (val >> 8) & 0xff; + arg->hf_scale = (val >> 16) & 0x3fff; + + for (i = 0; i < ISP35_CCM_HF_FACTOR_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_CCM_HF_FACTOR0 + i * 4, 0); + arg->hf_factor[i * 2] = val & 0xffff; + arg->hf_factor[i * 2 + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP33_CCM_HF_FACTOR8 + i * 4, 0); + arg->hf_factor[i * 2] = val & 0xffff; +} + +static void rkisp_get_params_gammaout(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp3x_gammaout_cfg *arg = ¶ms->others.gammaout_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_GAMMA_OUT_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_GOC; + arg->equ_segm = !!(val & BIT(1)); + arg->finalx4_dense_en = !!(val & BIT(2)); + + val = isp3_param_read(params_vdev, ISP3X_GAMMA_OUT_OFFSET, 0); + arg->offset = val & 0xffff; + + for (i = 0; i < ISP35_GAMMA_OUT_MAX_SAMPLES / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_GAMMA_OUT_Y0 + i * 4, 0); + arg->gamma_y[2 * i] = val & 0xffff; + arg->gamma_y[2 * i + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP3X_GAMMA_OUT_Y0 + i * 4, 0); + arg->gamma_y[2 * i] = val & 0xffff; +} + +static void rkisp_get_params_cproc(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp2x_cproc_cfg *arg = ¶ms->others.cproc_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_CPROC_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_CPROC; + arg->y_out_range = !!(val & BIT(1)); + arg->y_in_range = !!(val & BIT(2)); + arg->c_out_range = !!(val & BIT(3)); + + val = isp3_param_read(params_vdev, ISP3X_CPROC_CONTRAST, 0); + arg->contrast = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_CPROC_HUE, 0); + arg->hue = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_CPROC_SATURATION, 0); + arg->sat = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_CPROC_BRIGHTNESS, 0); + arg->brightness = val & 0xff; +} + +static void rkisp_get_params_drc(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_drc_cfg *arg = ¶ms->others.drc_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_DRC_CTRL0, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_DRC; + arg->bypass_en = !!(val & BIT(1)); + arg->cmps_byp_en = !!(val & BIT(2)); + arg->gainx32_en = !!(val & BIT(3)); + + val = isp3_param_read(params_vdev, ISP3X_DRC_CTRL1, 0); + arg->gain_idx_luma_scale = val & 0x3fff; + arg->comps_idx_luma_scale = (val >> 14) & 0x1fff; + arg->log_transform_offset_bits = (val >> 28) & 0xf; + + val = isp3_param_read(params_vdev, ISP3X_DRC_LPRATIO, 0); + arg->lo_detail_ratio = val & 0xfff; + arg->hi_detail_ratio = (val >> 12) & 0xfff; + arg->adj_gain_idx_luma_scale = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT0, 0); + arg->bifilt_wgt_offset = val & 0xff; + arg->thumb_thred_neg = (val >> 8) & 0x1ff; + arg->thumb_thred_en = !!(val & BIT(23)); + arg->bifilt_cur_pixel_wgt = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT1, 0); + arg->cmps_offset_bits = val & 0xf; + arg->cmps_mode = !!(val & BIT(4)); + arg->filt_luma_soft_thred = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT2, 0); + arg->thumb_max_limit = val & 0xfff; + arg->thumb_scale = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT3, 0); + arg->hi_range_inv_sigma = val & 0x3ff; + arg->lo_range_inv_sigma = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT4, 0); + arg->bifilt_wgt = val & 0x1f; + arg->bifilt_hi_wgt = (val >> 8) & 0xff; + arg->bifilt_soft_thred = (val >> 16) & 0x7ff; + arg->bifilt_soft_thred_en = !!(val & BIT(31)); + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_DRC_GAIN_Y0 + 4 * i, 0); + arg->gain_y[2 * i] = val & 0xffff; + arg->gain_y[2 * i + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP3X_DRC_GAIN_Y0 + 4 * i, 0); + arg->gain_y[2 * i] = val & 0xffff; + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_DRC_COMPRES_Y0 + 4 * i, 0); + arg->compres_y[2 * i] = val & 0xffff; + arg->compres_y[2 * i + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP3X_DRC_COMPRES_Y0 + 4 * i, 0); + arg->compres_y[2 * i] = val & 0xffff; + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP3X_DRC_SCALE_Y0 + 4 * i, 0); + arg->scale_y[2 * i] = val & 0xffff; + arg->scale_y[2 * i + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP3X_DRC_SCALE_Y0 + 4 * i, 0); + arg->scale_y[2 * i] = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_DRC_IIRWG_GAIN, 0); + arg->comps_gain_min_limit = val & 0xffff; + + for (i = 0; i < ISP35_DRC_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP39_DRC_SFTHD_Y0 + 4 * i, 0); + arg->sfthd_y[2 * i] = val & 0xffff; + arg->sfthd_y[2 * i + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP39_DRC_SFTHD_Y0 + 4 * i, 0); + arg->sfthd_y[2 * i] = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP35_DRC_LUMA_MIX, 0); + arg->max_luma_wgt = val & 0xff; + arg->mid_luma_wgt = (val >> 8) & 0xff; + arg->min_luma_wgt = (val >> 16) & 0xff; +} + +static void rkisp_get_params_hdrmge(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_hdrmge_cfg *arg = ¶ms->others.hdrmge_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_HDRMGE; + arg->short_base_en = !!(val & BIT(1)); + arg->frame_mode = (val >> 2) & 0x3; + arg->dbg_mode = (val >> 4) & 0x3; + arg->channel_detection_en = !!(val & BIT(6)); + arg->s_base_mode = !!(val & BIT(7)); + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_GAIN0, 0); + arg->short_gain = val & 0xffff; + arg->short_inv_gain = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_GAIN1, 0); + arg->medium_gain = val & 0xffff; + arg->medium_inv_gain = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_GAIN2, 0); + arg->long_gain = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_LIGHTZ, 0); + arg->ms_diff_scale = val & 0xff; + arg->ms_diff_offset = (val >> 8) & 0xff; + arg->lm_diff_scale = (val >> 16) & 0xff; + arg->lm_diff_offset = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_MS_DIFF, 0); + arg->ms_abs_diff_scale = val & 0x7ff; + arg->ms_abs_diff_thred_min_limit = (val >> 12) & 0x3ff; + arg->ms_adb_diff_thred_max_limit = (val >> 22) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_LM_DIFF, 0); + arg->lm_abs_diff_scale = val & 0x7ff; + arg->lm_abs_diff_thred_min_limit = (val >> 12) & 0x3ff; + arg->lm_abs_diff_thred_max_limit = (val >> 22) & 0x3ff; + + for (i = 0; i < ISP35_HDRMGE_WGT_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_DIFF_Y0 + 4 * i, 0); + arg->ms_luma_diff2wgt[i] = val & 0xffff; + arg->lm_luma_diff2wgt[i] = (val >> 16) & 0xffff; + } + + for (i = 0; i < ISP35_HDRMGE_WGT_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_OVER_Y0 + 4 * i, 0); + arg->luma2wgt[i] = val & 0x3ff; + arg->ms_raw_diff2wgt[i] = (val >> 10) & 0x3ff; + arg->lm_raw_diff2wgt[i] = (val >> 20) & 0x3ff; + } + + val = isp3_param_read(params_vdev, ISP32_HDRMGE_EACH_GAIN, 0); + arg->channel_detn_short_gain = val & 0xffff; + arg->channel_detn_medium_gain = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP35_HDRMGE_FORCE_LONG0, 0); + arg->mid_luma_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP35_HDRMGE_FORCE_LONG1, 0); + arg->mid_luma_thred_max_limit = val & 0xffff; + arg->mid_luma_thred_min_limit = (val >> 16) & 0xffff; +} + +static void rkisp_get_params_ldch(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp32_ldch_cfg *arg = ¶ms->others.ldch_cfg; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_LDCH_STS, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_LDCH; + arg->frm_end_dis = !!(val & BIT(1)); + arg->sample_avr_en = !!(val & BIT(3)); + arg->bic_mode_en = !!(val & BIT(4)); + arg->force_map_en = !!(val & BIT(6)); + arg->map13p3_en = !!(val & BIT(7)); + + for (i = 0; i < ISP35_LDCH_BIC_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP32_LDCH_BIC_TABLE0 + i * 4, 0); + arg->bicubic[i * 4] = val & 0xff; + arg->bicubic[i * 4 + 1] = (val >> 8) & 0xff; + arg->bicubic[i * 4 + 2] = (val >> 16) & 0xff; + arg->bicubic[i * 4 + 3] = (val >> 24) & 0xff; + } + + val = isp3_param_read(params_vdev, ISP3X_MI_LUT_LDCH_RD_H_WSIZE, 0); + arg->hsize = val & 0xfff; + val = isp3_param_read(params_vdev, ISP3X_MI_LUT_LDCH_RD_V_SIZE, 0); + arg->vsize = val & 0xffff; + + val = priv->buf_ldch_idx[0]; + arg->buf_fd = priv->buf_ldch[0][val].dma_fd; +} + +static void rkisp_get_params_bay3d(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct isp35_bay3d_cfg *arg = ¶ms->others.bay3d_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CTRL0, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_BAY3D; + arg->bypass_en = !!(val & BIT(1)); + arg->iir_wr_src = !!(val & BIT(3)); + arg->out_use_pre_mode = (val >> 5) & 0x7; + arg->motion_est_en = !!(val & BIT(8)); + arg->iir_rw_fmt = (val >> 13) & 0x3; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CTRL1, 0); + arg->transf_bypass_en = !!(val & BIT(0)); + arg->tnrsigma_curve_double_en = !!(val & BIT(1)); + arg->md_large_lo_use_mode = !!(val & BIT(2)); + arg->md_large_lo_min_filter_bypass_en = !!(val & BIT(3)); + arg->md_large_lo_gauss_filter_bypass_en = !!(val & BIT(4)); + arg->md_large_lo_md_wgt_bypass_en = !!(val & BIT(5)); + arg->pre_pix_out_mode = !!(val & BIT(6)); + arg->motion_detect_bypass_en = !!(val & BIT(7)); + arg->lpf_hi_bypass_en = !!(val & BIT(8)); + arg->lo_diff_vfilt_bypass_en = !!(val & BIT(9)); + arg->lpf_lo_bypass_en = !!(val & BIT(10)); + arg->lo_wgt_hfilt_en = !!(val & BIT(11)); + arg->lo_diff_hfilt_en = !!(val & BIT(12)); + arg->sig_hfilt_en = !!(val & BIT(13)); + arg->lo_detection_bypass_en = !!(val & BIT(15)); + arg->lo_mge_wgt_mode = (val >> 16) & 0x3; + arg->pre_spnr_out_en = !!(val & BIT(20)); + arg->md_only_lo_en = !!(val & BIT(21)); + arg->cur_spnr_out_en = !!(val & BIT(22)); + arg->md_wgt_out_en = !!(val & BIT(25)); + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CTRL2, 0); + arg->cur_spnr_filter_bypass_en = !!(val & BIT(0)); + arg->pre_spnr_hi_filter_gic_en = !!(val & BIT(2)); + arg->pre_spnr_hi_filter_gic_enhance_en = !!(val & BIT(3)); + arg->spnr_presigma_use_en = !!(val & BIT(4)); + arg->pre_spnr_lo_filter_bypass_en = !!(val & BIT(5)); + arg->pre_spnr_hi_filter_bypass_en = !!(val & BIT(6)); + arg->pre_spnr_sigma_curve_double_en = !!(val & BIT(7)); + arg->pre_spnr_hi_guide_filter_bypass_en = !!(val & BIT(8)); + arg->pre_spnr_sigma_idx_filt_bypass_en = !!(val & BIT(9)); + arg->pre_spnr_sigma_idx_filt_mode = !!(val & BIT(10)); + arg->pre_spnr_hi_noise_ctrl_en = !!(val & BIT(11)); + arg->pre_spnr_hi_filter_wgt_mode = !!(val & BIT(12)); + arg->pre_spnr_lo_filter_wgt_mode = !!(val & BIT(13)); + arg->pre_spnr_hi_filter_rb_wgt_mode = !!(val & BIT(14)); + arg->pre_spnr_lo_filter_rb_wgt_mode = !!(val & BIT(15)); + arg->pre_hi_gic_lp_en = !!(val & BIT(20)); + arg->pre_hi_bf_lp_en = !!(val & BIT(21)); + arg->pre_lo_avg_lp_en = !!(val & BIT(22)); + arg->pre_spnr_dpc_flt_en = !!(val & BIT(23)); + arg->pre_spnr_dpc_nr_bal_mode = !!(val & BIT(24)); + arg->pre_spnr_dpc_flt_mode = !!(val & BIT(25)); + arg->pre_spnr_dpc_flt_prewgt_en = !!(val & BIT(26)); + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CTRL3, 0); + arg->transf_mode = !!(val & BIT(0)); + arg->wgt_cal_mode = !!(val & BIT(1)); + arg->mge_wgt_ds_mode = !!(val & BIT(2)); + arg->kalman_wgt_ds_mode = (val >> 3) & 0x3; + arg->mge_wgt_hdr_sht_thred = (val >> 16) & 0x3f; + arg->sigma_calc_mge_wgt_hdr_sht_thred = (val >> 24) & 0x3f; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_TRANS0, 0); + arg->transf_mode_offset = val & 0x1fff; + arg->transf_mode_scale = (val >> 14) & 0x3; + arg->itransf_mode_offset = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_TRANS1, 0); + arg->transf_data_max_limit = val; + + val = isp3_param_read(params_vdev, ISP35_BAY3D_PREHI_SIGSCL, 0); + arg->pre_spnr_sigma_ctrl_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP35_BAY3D_PREHI_SIGOF, 0); + arg->pre_spnr_hi_guide_out_wgt = val & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CURHISPW0, 0); + arg->cur_spnr_filter_coeff[0] = val & 0xff; + arg->cur_spnr_filter_coeff[1] = (val >> 8) & 0xff; + arg->cur_spnr_filter_coeff[2] = (val >> 16) & 0xff; + val = isp3_param_read(params_vdev, ISP33_BAY3D_CURHISPW1, 0); + arg->cur_spnr_filter_coeff[3] = val & 0xff; + arg->cur_spnr_filter_coeff[4] = (val >> 8) & 0xff; + arg->cur_spnr_filter_coeff[5] = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_BAY3D_XY_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_BAY3D_IIRSX0 + i * 4, 0); + arg->pre_spnr_luma2sigma_x[i * 2] = val & 0xffff; + arg->pre_spnr_luma2sigma_x[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP33_BAY3D_IIRSY0 + i * 4, 0); + arg->pre_spnr_luma2sigma_y[i * 2] = val & 0xffff; + arg->pre_spnr_luma2sigma_y[i * 2 + 1] = (val >> 16) & 0xffff; + } + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHI_SIGSCL, 0); + arg->pre_spnr_hi_sigma_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHI_WSCL, 0); + arg->pre_spnr_hi_wgt_calc_scale = val & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHIWMM, 0); + arg->pre_spnr_hi_filter_wgt_min_limit = val & 0xff; + arg->pre_spnr_hi_wgt_calc_offset = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHISIGOF, 0); + arg->pre_spnr_hi_filter_out_wgt = val & 0xff; + arg->pre_spnr_sigma_offset = (val >> 16) & 0xff; + arg->pre_spnr_sigma_hdr_sht_offset = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHISIGSCL, 0); + arg->pre_spnr_sigma_scale = val & 0xffff; + arg->pre_spnr_sigma_hdr_sht_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHISPW0, 0); + arg->pre_spnr_hi_filter_coeff[0] = val & 0xff; + arg->pre_spnr_hi_filter_coeff[1] = (val >> 8) & 0xff; + arg->pre_spnr_hi_filter_coeff[2] = (val >> 16) & 0xff; + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHISPW1, 0); + arg->pre_spnr_hi_filter_coeff[3] = val & 0xff; + arg->pre_spnr_hi_filter_coeff[4] = (val >> 8) & 0xff; + arg->pre_spnr_hi_filter_coeff[5] = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PRELOSIGCSL, 0); + arg->pre_spnr_lo_sigma_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PRELOSIGOF, 0); + arg->pre_spnr_lo_wgt_calc_offset = val & 0xff; + arg->pre_spnr_lo_wgt_calc_scale = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PREHI_NRCT, 0); + arg->pre_spnr_hi_noise_ctrl_scale = val & 0xffff; + arg->pre_spnr_hi_noise_ctrl_offset = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_BAY3D_TNRSIG_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_BAY3D_TNRSX0 + i * 4, 0); + arg->tnr_luma2sigma_x[i * 2] = val & 0xffff; + arg->tnr_luma2sigma_x[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP33_BAY3D_TNRSY0 + i * 4, 0); + arg->tnr_luma2sigma_y[i * 2] = val & 0xffff; + arg->tnr_luma2sigma_y[i * 2 + 1] = (val >> 16) & 0xffff; + } + + for (i = 0; i < ISP35_BAY3D_LPF_COEFF_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_BAY3D_HIWD0 + i * 4, 0); + arg->lpf_hi_coeff[i * 3] = val & 0x3ff; + arg->lpf_hi_coeff[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->lpf_hi_coeff[i * 3 + 2] = (val >> 20) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_BAY3D_LOWD0 + i * 4, 0); + arg->lpf_lo_coeff[i * 3] = val & 0x3ff; + arg->lpf_lo_coeff[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->lpf_lo_coeff[i * 3 + 2] = (val >> 20) & 0x3ff; + } + + val = isp3_param_read(params_vdev, ISP33_BAY3D_GF3, 0); + arg->sigma_idx_filt_coeff[0] = val & 0xff; + arg->sigma_idx_filt_coeff[1] = (val >> 8) & 0xff; + arg->sigma_idx_filt_coeff[2] = (val >> 16) & 0xff; + arg->sigma_idx_filt_coeff[3] = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_GF4, 0); + arg->sigma_idx_filt_coeff[4] = val & 0xff; + arg->sigma_idx_filt_coeff[5] = (val >> 8) & 0xff; + arg->lo_wgt_cal_first_line_sigma_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_VIIR, 0); + arg->lo_diff_vfilt_wgt = val & 0x1f; + arg->lo_wgt_vfilt_wgt = (val >> 5) & 0x1f; + arg->sig_first_line_scale = (val >> 16) & 0x3f; + arg->lo_diff_first_line_scale = (val >> 22) & 0x3f; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_LFSCL, 0); + arg->lo_wgt_cal_offset = val & 0xffff; + arg->lo_wgt_cal_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_LFSCLTH, 0); + arg->lo_wgt_cal_max_limit = val & 0xffff; + arg->mode0_base_ratio = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_DSWGTSCL, 0); + arg->lo_diff_wgt_cal_offset = val & 0xffff; + arg->lo_diff_wgt_cal_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTLASTSCL, 0); + arg->lo_mge_pre_wgt_offset = val & 0xffff; + arg->lo_mge_pre_wgt_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTSCL0, 0); + arg->mode0_lo_wgt_scale = val & 0xffff; + arg->mode0_lo_wgt_hdr_sht_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTSCL1, 0); + arg->mode1_lo_wgt_scale = val & 0xffff; + arg->mode1_lo_wgt_hdr_sht_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTSCL2, 0); + arg->mode1_wgt_scale = val & 0xffff; + arg->mode1_wgt_hdr_sht_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTOFF, 0); + arg->mode1_lo_wgt_offset = val & 0xffff; + arg->mode1_lo_wgt_hdr_sht_offset = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGT1OFF, 0); + arg->auto_sigma_count_wgt_thred = val & 0x3ff; + arg->mode1_wgt_min_limit = (val >> 10) & 0x3ff; + arg->mode1_wgt_offset = (val >> 20) & 0xfff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_SIGORG, 0); + arg->tnr_out_sigma_sq = val; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTLO_L, 0); + arg->lo_wgt_clip_min_limit = val & 0xffff; + arg->lo_wgt_clip_hdr_sht_min_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTLO_H, 0); + arg->lo_wgt_clip_max_limit = val & 0xffff; + arg->lo_wgt_clip_hdr_sht_max_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_STH_SCL, 0); + arg->lo_pre_gg_soft_thresh_scale = val & 0xffff; + arg->lo_pre_rb_soft_thresh_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_STH_LIMIT, 0); + arg->lo_pre_soft_thresh_max_limit = val & 0xffff; + arg->lo_pre_soft_thresh_min_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_HIKEEP, 0); + arg->cur_spnr_hi_wgt_min_limit = val & 0xff; + arg->pre_spnr_hi_wgt_min_limit = (val >> 8) & 0xff; + arg->motion_est_lo_wgt_thred = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PIXMAX, 0); + arg->pix_max_limit = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_SIGNUMTH, 0); + arg->sigma_num_th = val; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_MONR, 0); + arg->out_use_hi_noise_bal_nr_strg = val & 0x7ff; + arg->out_use_md_noise_bal_nr_strg = (val >> 11) & 0x7ff; + arg->gain_out_max_limit = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_SIGSCL, 0); + arg->sigma_scale = val & 0xffff; + arg->sigma_hdr_sht_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_DSOFF, 0); + arg->lo_wgt_vfilt_offset = val & 0x3ff; + arg->lo_diff_vfilt_offset = (val >> 10) & 0xfff; + arg->lo_wgt_cal_first_line_vfilt_wgt = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_DSSCL, 0); + arg->lo_wgt_vfilt_scale = val & 0xff; + arg->lo_diff_vfilt_scale_bit = (val >> 8) & 0xff; + arg->lo_diff_vfilt_scale = (val >> 16) & 0xff; + arg->lo_diff_first_line_vfilt_wgt = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_ME0, 0); + arg->motion_est_up_mvx_cost_offset = val & 0xffff; + arg->motion_est_up_mvx_cost_scale = (val >> 16) & 0x7ff; + arg->motion_est_sad_vert_wgt0 = (val >> 28) & 0x3; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_ME1, 0); + arg->motion_est_up_left_mvx_cost_offset = val & 0x16; + arg->motion_est_up_left_mvx_cost_scale = (val >> 16) & 0x7ff; + arg->motion_est_sad_vert_wgt1 = (val >> 28) & 0x3; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_ME2, 0); + arg->motion_est_up_right_mvx_cost_offset = val & 0xffff; + arg->motion_est_up_right_mvx_cost_scale = (val >> 16) & 0x7ff; + arg->motion_est_sad_vert_wgt2 = (val >> 28) & 0x3; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTMAX, 0); + arg->lo_wgt_clip_motion_max_limit = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGT1MAX, 0); + arg->mode1_wgt_max_limit = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_WGTM0, 0); + arg->mode0_wgt_out_max_limit = val & 0xffff; + arg->mode0_wgt_out_offset = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PRELOWGT, 0); + arg->pre_spnr_lo_val_wgt_out_wgt = val & 0xff; + arg->pre_spnr_lo_filter_out_wgt = (val >> 8) & 0xff; + arg->pre_spnr_lo_filter_wgt_min = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP35_BAY3D_LOCOEF0, 0); + arg->lo_wgt_hflt_coeff2 = val & 0x7; + arg->lo_wgt_hflt_coeff1 = (val >> 4) & 0xf; + arg->lo_wgt_hflt_coeff0 = (val >> 8) & 0x1f; + arg->sig_hflt_coeff2 = (val >> 16) & 0x7; + arg->sig_hflt_coeff1 = (val >> 20) & 0xf; + arg->sig_hflt_coeff0 = (val >> 24) & 0x1f; + val = isp3_param_read(params_vdev, ISP35_BAY3D_LOCOEF1, 0); + arg->lo_dif_hflt_coeff2 = val & 0x7; + arg->lo_dif_hflt_coeff1 = (val >> 4) & 0xf; + arg->lo_dif_hflt_coeff0 = (val >> 8) & 0x1f; + + val = isp3_param_read(params_vdev, ISP35_BAY3D_DPC0, 0); + arg->pre_spnr_dpc_bright_str = val & 0x3; + arg->pre_spnr_dpc_dark_str = (val >> 2) & 0x3; + arg->pre_spnr_dpc_str = (val >> 3) & 0x7; + arg->pre_spnr_dpc_wk_scale = (val >> 8) & 0xff; + arg->pre_spnr_dpc_wk_offset = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP35_BAY3D_DPC1, 0); + arg->pre_spnr_dpc_nr_bal_str = val & 0xffff; + arg->pre_spnr_dpc_soft_thr_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_PRELOWGT, 0); + arg->pre_spnr_lo_val_wgt_out_wgt = val & 0xff; + arg->pre_spnr_lo_filter_out_wgt = (val >> 8) & 0xff; + arg->pre_spnr_lo_filter_wgt_min = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_MIDBIG0, 0); + arg->md_large_lo_md_wgt_offset = val & 0xff; + arg->md_large_lo_md_wgt_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_MIDBIG1, 0); + arg->md_large_lo_wgt_cut_offset = val & 0xffff; + arg->md_large_lo_wgt_add_offset = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_MIDBIG2, 0); + arg->md_large_lo_wgt_scale = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP35_BAY3D_MONROFF, 0); + arg->out_use_hi_noise_bal_nr_off = val & 0xfff; + arg->out_use_md_noise_bal_nr_off = (val >> 16) & 0xfff; + + val = isp3_param_read(params_vdev, ISP35_B3DLDC_CTRL, 0); + arg->btnr_ldc_en = !!(val & BIT(0)); + arg->b3dldcv_map13p3_en = !!(val & BIT(7)); + arg->b3dldcv_force_map_en = !!(val & BIT(8)); + + val = isp3_param_read(params_vdev, ISP35_B3DLDC_ADR_STS, 0); + arg->b3dldch_en = !!(val & BIT(0)); + arg->b3dldch_map13p3_en = !!(val & BIT(6)); + arg->b3dldch_force_map_en = !!(val & BIT(7)); + + val = isp3_param_read(params_vdev, ISP35_B3DLDC_EXTBOUND1, 0); + arg->btnr_ldc_wrap_ext_bound_offset = val & 0xffff; + arg->btnr_ldcltp_mode = !!(val & BIT(16)); + + val = priv->buf_b3dldc_idx[0]; + arg->lut_buf_fd = priv->buf_b3dldc[0][val].dma_fd; +} + +static void rkisp_get_params_ynr(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_ynr_cfg *arg = ¶ms->others.ynr_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_YNR_GLOBAL_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_YNR; + arg->hi_spnr_bypass = !!(val & BIT(1)); + arg->mi_spnr_bypass = !!(val & BIT(2)); + arg->lo_spnr_bypass = !!(val & BIT(3)); + arg->rnr_en = !!(val & BIT(4)); + arg->tex2lo_strg_en = !!(val & BIT(5)); + arg->hi_lp_en = !!(val & BIT(6)); + arg->dsfilt_bypass = !!(val & BIT(7)); + arg->tex2wgt_en = !!(val & BIT(8)); + + val = isp3_param_read(params_vdev, ISP33_YNR_GAIN_CTRL, 0); + arg->global_set_gain = val & 0x3ff; + arg->gain_merge_alpha = (val >> 12) & 0xf; + arg->local_gain_scale = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_YNR_ADJ_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_YNR_GAIN_ADJ_0_2 + i * 4, 0); + arg->lo_spnr_gain2strg[i * 3] = val & 0x1ff; + arg->lo_spnr_gain2strg[i * 3 + 1] = (val >> 10) & 0x1ff; + arg->lo_spnr_gain2strg[i * 3 + 2] = (val >> 20) & 0x1ff; + } + + val = isp3_param_read(params_vdev, ISP33_YNR_RNR_MAX_R, 0); + arg->rnr_max_radius = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_YNR_RNR_CENTER_COOR, 0); + arg->rnr_center_h = val & 0xffff; + arg->rnr_center_v = (val >> 16) & 0xffff; + + for (i = 0; i < ISP35_YNR_XY_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_YNR_RNR_STRENGTH03 + i * 4, 0); + arg->radius2strg[i * 4] = val & 0xff; + arg->radius2strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->radius2strg[i * 4 + 2] = (val >> 16) & 0xff; + arg->radius2strg[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_YNR_RNR_STRENGTH16, 0); + arg->radius2strg[i * 4] = val & 0xff; + + for (i = 0; i < ISP35_YNR_XY_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_YNR_SGM_DX_0_1 + i * 4, 0); + arg->luma2sima_x[i * 2] = val & 0xffff; + arg->luma2sima_x[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP33_YNR_SGM_Y_0_1 + i * 4, 0); + arg->luma2sima_y[i * 2] = val & 0xffff; + arg->luma2sima_y[i * 2 + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP33_YNR_SGM_DX_16, 0); + arg->luma2sima_x[i * 2] = val & 0xffff; + val = isp3_param_read(params_vdev, ISP33_YNR_SGM_Y_16, 0); + arg->luma2sima_y[i * 2] = val & 0xffff; + + for (i = 0; i < ISP35_YNR_TEX2WGT_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP35_YNR_MI_TEX2WGT_SCALE_0_1_2 + i * 4, 0); + arg->mi_spnr_tex2wgt_scale[i * 3] = val & 0xff; + arg->mi_spnr_tex2wgt_scale[i * 3 + 1] = (val >> 10) & 0xff; + arg->mi_spnr_tex2wgt_scale[i * 3 + 2] = (val >> 20) & 0xff; + val = isp3_param_read(params_vdev, ISP35_YNR_LO_TEX2WGT_SCALE_0_1_2 + i * 4, 0); + arg->lo_spnr_tex2wgt_scale[i * 3] = val & 0xff; + arg->lo_spnr_tex2wgt_scale[i * 3 + 1] = (val >> 10) & 0xff; + arg->lo_spnr_tex2wgt_scale[i * 3 + 2] = (val >> 20) & 0xff; + } + + val = isp3_param_read(params_vdev, ISP33_YNR_HI_SIGMA_GAIN, 0); + arg->hi_spnr_sigma_min_limit = val & 0x7ff; + arg->hi_spnr_local_gain_alpha = (val >> 11) & 0x1f; + arg->hi_spnr_strg = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP33_YNR_HI_GAUS_COE, 0); + arg->hi_spnr_filt_coeff[0] = val & 0x3f; + arg->hi_spnr_filt_coeff[1] = (val >> 6) & 0x3f; + arg->hi_spnr_filt_coeff[2] = (val >> 12) & 0x3f; + arg->hi_spnr_filt_coeff[3] = (val >> 18) & 0x3f; + + val = isp3_param_read(params_vdev, ISP33_YNR_HI_WEIGHT, 0); + arg->hi_spnr_filt_wgt_offset = val & 0x3ff; + arg->hi_spnr_filt_center_wgt = (val >> 10) & 0x1fff; + + val = isp3_param_read(params_vdev, ISP33_YNR_HI_GAUS1_COE_0_2, 0); + arg->hi_spnr_filt1_coeff[0] = val & 0x1ff; + arg->hi_spnr_filt1_coeff[1] = (val >> 10) & 0x1ff; + arg->hi_spnr_filt1_coeff[2] = (val >> 20) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP33_YNR_HI_GAUS1_COE_3_5, 0); + arg->hi_spnr_filt1_coeff[3] = val & 0x1ff; + arg->hi_spnr_filt1_coeff[4] = (val >> 10) & 0x1ff; + arg->hi_spnr_filt1_coeff[5] = (val >> 20) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP33_YNR_HI_TEXT, 0); + arg->hi_spnr_filt1_tex_thred = val & 0x7ff; + arg->hi_spnr_filt1_tex_scale = (val >> 12) & 0x3ff; + arg->hi_spnr_filt1_wgt_alpha = (val >> 22) & 0x1ff; + + val = isp3_param_read(params_vdev, ISP33_YNR_MI_GAUS_COE, 0); + arg->mi_spnr_filt_coeff0 = val & 0xff; + arg->mi_spnr_filt_coeff1 = (val >> 10) & 0xff; + arg->mi_spnr_filt_coeff2 = (val >> 20) & 0xff; + val = isp3_param_read(params_vdev, ISP35_YNR_MI_GAUS_COE1, 0); + arg->mi_spnr_filt_coeff3 = val & 0xff; + arg->mi_spnr_filt_coeff4 = (val >> 10) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_YNR_MI_STRG_DETAIL, 0); + arg->mi_spnr_strg = val & 0xffff; + arg->mi_spnr_soft_thred_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_YNR_MI_WEIGHT, 0); + arg->mi_spnr_wgt = val & 0xff; + arg->mi_spnr_filt_center_wgt = (val >> 10) & 0x7ff; + arg->mi_ehance_scale_en = !!(val & BIT(23)); + arg->mi_ehance_scale = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP35_YNR_DSIIR_COE, 0); + arg->dsfilt_diff_offset = val & 0x3ff; + arg->dsfilt_center_wgt = (val >> 10) & 0x7ff; + arg->dsfilt_strg = (val >> 21) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP33_YNR_LO_STRG_DETAIL, 0); + arg->lo_spnr_strg = val & 0xffff; + arg->lo_spnr_soft_thred_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_YNR_LO_LIMIT_SCALE, 0); + arg->lo_spnr_thumb_thred_scale = val & 0x3ff; + arg->tex2lo_strg_mantissa = (val >> 12) & 0x7ff; + arg->tex2lo_strg_exponent = (val >> 24) & 0xf; + + val = isp3_param_read(params_vdev, ISP33_YNR_LO_WEIGHT, 0); + arg->lo_spnr_wgt = val & 0xff; + arg->lo_spnr_filt_center_wgt = (val >> 10) & 0x1fff; + arg->lo_enhance_scale = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_YNR_LO_TEXT_THRED, 0); + arg->tex2lo_strg_upper_thred = val & 0x3ff; + arg->tex2lo_strg_lower_thred = (val >> 12) & 0x3ff; + + for (i = 0; i < ISP35_YNR_ADJ_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_YNR_FUSION_WEIT_ADJ_0_3 + i * 4, 0); + arg->lo_gain2wgt[i * 4] = val & 0xff; + arg->lo_gain2wgt[i * 4 + 1] = (val >> 8) & 0xff; + arg->lo_gain2wgt[i * 4 + 2] = (val >> 16) & 0xff; + arg->lo_gain2wgt[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_YNR_FUSION_WEIT_ADJ_8, 0); + arg->lo_gain2wgt[i * 4] = val & 0xff; +} + +static void rkisp_get_params_cnr(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_cnr_cfg *arg = ¶ms->others.cnr_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_CNR_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_CNR; + arg->exgain_bypass = !!(val & BIT(1)); + arg->yuv422_mode = !!(val & BIT(2)); + arg->thumb_mode = (val >> 4) & 0x3; + arg->uv_dis = !!(val & BIT(6)); + arg->hiflt_wgt0_mode = !!(val & BIT(8)); + arg->local_alpha_dis = !!(val & BIT(11)); + arg->loflt_coeff = (val >> 12) & 0x3f; + arg->hsv_alpha_en = !!(val & BIT(18)); + + val = isp3_param_read(params_vdev, ISP3X_CNR_EXGAIN, 0); + arg->global_gain = val & 0x3ff; + arg->global_gain_alpha = (val >> 12) & 0xf; + arg->local_gain_scale = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP32_CNR_THUMB1, 0); + arg->lobfflt_vsigma_uv = val & 0xffff; + arg->lobfflt_vsigma_y = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP32_CNR_THUMB_BF_RATIO, 0); + arg->lobfflt_alpha = val & 0x7ff; + + val = isp3_param_read(params_vdev, ISP32_CNR_LBF_WEITD, 0); + arg->thumb_bf_coeff0 = val & 0xff; + arg->thumb_bf_coeff1 = (val >> 8) & 0xff; + arg->thumb_bf_coeff2 = (val >> 16) & 0xff; + arg->thumb_bf_coeff3 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP32_CNR_IIR_PARA1, 0); + arg->loflt_uv_gain = val & 0xf; + arg->loflt_vsigma = (val >> 4) & 0xff; + arg->exp_x_shift_bit = (val >> 12) & 0x3f; + arg->loflt_wgt_slope = (val >> 20) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP32_CNR_IIR_PARA2, 0); + arg->loflt_wgt_min_thred = val & 0x3f; + arg->loflt_wgt_max_limit = (val >> 8) & 0x7f; + + val = isp3_param_read(params_vdev, ISP32_CNR_GAUS_COE1, 0); + arg->gaus_flt_coeff[0] = val & 0xff; + arg->gaus_flt_coeff[1] = (val >> 8) & 0xff; + arg->gaus_flt_coeff[2] = (val >> 16) & 0xff; + arg->gaus_flt_coeff[3] = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP32_CNR_GAUS_COE2, 0); + arg->gaus_flt_coeff[4] = val & 0xff; + arg->gaus_flt_coeff[5] = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP32_CNR_GAUS_RATIO, 0); + arg->gaus_flt_alpha = val & 0x7ff; + arg->hiflt_wgt_min_limit = (val >> 12) & 0xff; + arg->hiflt_alpha = (val >> 20) & 0x7ff; + + val = isp3_param_read(params_vdev, ISP32_CNR_BF_PARA1, 0); + arg->hiflt_uv_gain = val & 0x7f; + arg->hiflt_global_vsigma = (val >> 8) & 0x3fff; + arg->hiflt_cur_wgt = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP32_CNR_BF_PARA2, 0); + arg->adj_offset = val & 0x1ff; + arg->adj_scale = (val >> 16) & 0x7fff; + + for (i = 0; i < ISP35_CNR_SIGMA_Y_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP32_CNR_SIGMA0 + i * 4, 0); + arg->sgm_ratio[i * 4] = val & 0xff; + arg->sgm_ratio[i * 4 + 1] = (val >> 8) & 0xff; + arg->sgm_ratio[i * 4 + 2] = (val >> 16) & 0xff; + arg->sgm_ratio[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP32_CNR_SIGMA0 + i * 4, 0); + arg->sgm_ratio[i * 4] = val & 0xff; + arg->bf_merge_max_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP32_CNR_IIR_GLOBAL_GAIN, 0); + arg->loflt_global_sgm_ratio = val & 0xff; + arg->loflt_global_sgm_ratio_alpha = (val >> 8) & 0xff; + arg->bf_alpha_max_limit = (val >> 16) & 0xffff; + + for (i = 0; i < ISP35_CNR_WGT_SIGMA_Y_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP39_CNR_WGT_SIGMA0 + i * 4, 0); + arg->cur_wgt[i * 4] = val & 0xff; + arg->cur_wgt[i * 4 + 1] = (val >> 8) & 0xff; + arg->cur_wgt[i * 4 + 2] = (val >> 16) & 0xff; + arg->cur_wgt[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP39_CNR_WGT_SIGMA0 + i * 4, 0); + arg->cur_wgt[i * 4] = val & 0xff; + + for (i = 0; i < ISP35_CNR_GAUS_SIGMAR_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP39_CNR_GAUS_X_SIGMAR0 + i * 4, 0); + arg->hiflt_vsigma_idx[i * 3] = val & 0x3ff; + arg->hiflt_vsigma_idx[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->hiflt_vsigma_idx[i * 3 + 2] = (val >> 20) & 0x3ff; + } + val = isp3_param_read(params_vdev, ISP39_CNR_GAUS_X_SIGMAR0 + i * 4, 0); + arg->hiflt_vsigma_idx[i * 3] = val & 0x3ff; + arg->hiflt_vsigma_idx[i * 3 + 1] = (val >> 20) & 0x3ff; + + for (i = 0; i < ISP35_CNR_GAUS_SIGMAR_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP39_CNR_GAUS_Y_SIGMAR0 + i * 4, 0); + arg->hiflt_vsigma[i * 2] = val & 0xffff; + arg->hiflt_vsigma[i * 2 + 1] = (val >> 16) & 0xffff; + } + + for (i = 0; i < ISP35_CNR_WGT_SIGMA_Y_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP35_CNR_IIR_SIGMAR0 + i * 4, 0); + arg->lo_flt_vsigma[i * 4] = val & 0xff; + arg->lo_flt_vsigma[i * 4 + 1] = (val >> 8) & 0xff; + arg->lo_flt_vsigma[i * 4 + 2] = (val >> 16) & 0xff; + arg->lo_flt_vsigma[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP35_CNR_IIR_SIGMAR3, 0); + arg->lo_flt_vsigma[i * 4] = val & 0xff; + + for (i = 0; i < ISP35_CNR_CURVE_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP35_CNR_HSV_CURVE0 + i * 4, 0); + arg->hsv_adj_alpha_table[i * 4] = val & 0xff; + arg->hsv_adj_alpha_table[i * 4 + 1] = (val >> 8) & 0xff; + arg->hsv_adj_alpha_table[i * 4 + 2] = (val >> 16) & 0xff; + arg->hsv_adj_alpha_table[i * 4 + 3] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP35_CNR_SAT_CURVE0 + i * 4, 0); + arg->sat_adj_alpha_table[i * 4] = val & 0xff; + arg->sat_adj_alpha_table[i * 4 + 1] = (val >> 8) & 0xff; + arg->sat_adj_alpha_table[i * 4 + 2] = (val >> 16) & 0xff; + arg->sat_adj_alpha_table[i * 4 + 3] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP35_CNR_GAIN_ADJ_CURVE0 + i * 4, 0); + arg->gain_adj_alpha_table[i * 4] = val & 0xff; + arg->gain_adj_alpha_table[i * 4 + 1] = (val >> 8) & 0xff; + arg->gain_adj_alpha_table[i * 4 + 2] = (val >> 16) & 0xff; + arg->gain_adj_alpha_table[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP35_CNR_HSV_CURVE2, 0); + arg->hsv_adj_alpha_table[i * 4] = val & 0xff; + arg->hsv_adj_alpha_table[i * 4 + 1] = (val >> 8) & 0xff; + val = isp3_param_read(params_vdev, ISP35_CNR_SAT_CURVE2, 0); + arg->sat_adj_alpha_table[i * 4] = val & 0xff; + arg->sat_adj_alpha_table[i * 4 + 1] = (val >> 8) & 0xff; + val = isp3_param_read(params_vdev, ISP35_CNR_GAIN_ADJ_CURVE2, 0); + arg->gain_adj_alpha_table[i * 4] = val & 0xff; + arg->gain_adj_alpha_table[i * 4 + 1] = (val >> 8) & 0xff; +} + +static void rkisp_get_params_sharp(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_sharp_cfg *arg = ¶ms->others.sharp_cfg; + struct isp35_sharp_cfg *arg_rec = ¶ms_vdev->isp35_params->others.sharp_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_SHARP_EN, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_SHARP; + arg->bypass = !!(val & BIT(1)); + arg->local_gain_bypass = !!(val & BIT(2)); + arg->tex_est_mode = !!(val & BIT(3)); + arg->max_min_flt_mode = !!(val & BIT(4)); + arg->detail_fusion_wgt_mode = !!(val & BIT(5)); + arg->noise_calc_mode = !!(val & BIT(6)); + arg->radius_step_mode = !!(val & BIT(7)); + arg->noise_curve_mode = !!(val & BIT(8)); + arg->gain_wgt_mode = !!(val & BIT(9)); + arg->detail_lp_en = !!(val & BIT(10)); + arg->debug_mode = (val >> 12) & 0x7; + + val = isp3_param_read(params_vdev, ISP33_SHARP_TEXTURE0, 0); + arg->fst_noise_scale = val & 0xffff; + arg->fst_sigma_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_TEXTURE1, 0); + arg->fst_sigma_offset = val & 0xffff; + arg->fst_wgt_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_TEXTURE2, 0); + arg->tex_wgt_mode = (val >> 8) & 0x3; + arg->noise_est_alpha = (val >> 12) & 0x3f; + + val = isp3_param_read(params_vdev, ISP33_SHARP_TEXTURE3, 0); + arg->sec_noise_scale = val & 0xffff; + arg->sec_sigma_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_TEXTURE4, 0); + arg->sec_sigma_offset = val & 0xffff; + arg->sec_wgt_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_HPF_KERNEL0, 0); + arg->img_hpf_coeff[0] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP33_SHARP_HPF_KERNEL1, 0); + arg->img_hpf_coeff[1] = val & 0xff; + arg->img_hpf_coeff[2] = (val >> 8) & 0xff; + arg->img_hpf_coeff[3] = (val >> 16) & 0xff; + arg->img_hpf_coeff[4] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP33_SHARP_TEXFLT_KERNEL, 0); + arg->img_hpf_coeff[5] = val & 0xff; + arg->texWgt_flt_coeff0 = (val >> 8) & 0xff; + arg->texWgt_flt_coeff1 = (val >> 16) & 0xff; + arg->texWgt_flt_coeff2 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL0, 0); + arg->detail_in_alpha = val & 0xff; + arg->pre_bifilt_slope_fix = (val >> 8) & 0x7ff; + arg->pre_bifilt_alpha = (val >> 20) & 0x3f; + arg->fusion_wgt_min_limit = !!(val & BIT(28)); + arg->fusion_wgt_max_limit = !!(val & BIT(29)); + + val = isp3_param_read(params_vdev, ISP33_SHARP_LUMA_DX, 0); + for (i = 0; i < ISP35_SHARP_X_NUM; i++) + arg->luma_dx[i] = (val >> (i * 4)) & 0xf; + + for (i = 0; i < ISP35_SHARP_Y_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_PBF_VSIGMA0 + i * 4, 0); + arg->pre_bifilt_vsigma_inv[i * 2] = val & 0xffff; + arg->pre_bifilt_vsigma_inv[i * 2 + 1] = (val >> 16) & 0xffff; + } + + val = isp3_param_read(params_vdev, ISP33_SHARP_PBF_KERNEL, 0); + arg->pre_bifilt_coeff0 = val & 0x3f; + arg->pre_bifilt_coeff1 = (val >> 8) & 0x3f; + arg->pre_bifilt_coeff2 = (val >> 16) & 0x3f; + + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_KERNEL0, 0); + arg->hi_detail_lpf_coeff[0] = val & 0xff; + arg->hi_detail_lpf_coeff[1] = (val >> 8) & 0xff; + arg->hi_detail_lpf_coeff[2] = (val >> 16) & 0xff; + arg->hi_detail_lpf_coeff[3] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_KERNEL1, 0); + arg->hi_detail_lpf_coeff[4] = val & 0xff; + arg->hi_detail_lpf_coeff[5] = (val >> 8) & 0xff; + arg->mi_detail_lpf_coeff[0] = (val >> 16) & 0xff; + arg->mi_detail_lpf_coeff[1] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_KERNEL2, 0); + arg->mi_detail_lpf_coeff[2] = val & 0xff; + arg->mi_detail_lpf_coeff[3] = (val >> 8) & 0xff; + arg->mi_detail_lpf_coeff[4] = (val >> 16) & 0xff; + arg->mi_detail_lpf_coeff[5] = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GAIN, 0); + arg->global_gain = val & 0xffff; + arg->gain_merge_alpha = (val >> 16) & 0xff; + arg->local_gain_scale = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GAIN_ADJ0, 0); + arg->edge_gain_max_limit = val & 0xff; + arg->edge_gain_min_limit = (val >> 8) & 0xff; + arg->detail_gain_max_limit = (val >> 16) & 0xff; + arg->detail_gain_min_limit = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GAIN_ADJ1, 0); + arg->hitex_gain_max_limit = val & 0xff; + arg->hitex_gain_min_limit = (val >> 8) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GAIN_ADJ2, 0); + arg->edge_gain_slope = val & 0xff; + arg->detail_gain_slope = (val >> 8) & 0xff; + arg->hitex_gain_slope = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GAIN_ADJ3, 0); + arg->edge_gain_offset = val & 0x3ff; + arg->detail_gain_offset = (val >> 10) & 0x3ff; + arg->hitex_gain_offset = (val >> 20) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GAIN_ADJ4, 0); + arg->edge_gain_sigma = val & 0xffff; + arg->detail_gain_sigma = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE0, 0); + arg->pos_edge_wgt_scale = val & 0xffff; + arg->neg_edge_wgt_scale = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE1, 0); + arg->pos_edge_strg = val & 0xff; + arg->neg_edge_strg = (val >> 8) & 0xff; + arg->overshoot_alpha = (val >> 16) & 0xff; + arg->undershoot_alpha = (val >> 24) & 0xff; + + for (i = 0; i < ISP35_SHARP_EDGE_KERNEL_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE_KERNEL0 + i * 4, 0); + arg->edge_bpf_coeff[i * 4] = val & 0xff; + arg->edge_bpf_coeff[i * 4 + 1] = (val >> 8) & 0xff; + arg->edge_bpf_coeff[i * 4 + 2] = (val >> 16) & 0xff; + arg->edge_bpf_coeff[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE_KERNEL2, 0); + arg->edge_bpf_coeff[i * 4] = val & 0xff; + arg->edge_bpf_coeff[i * 4 + 1] = (val >> 8) & 0xff; + + for (i = 0; i < ISP35_SHARP_EDGE_WGT_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE_WGT_VAL0 + i * 4, 0); + arg->edge_wgt_val[i * 3] = val & 0x3ff; + arg->edge_wgt_val[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->edge_wgt_val[i * 3 + 2] = (val >> 20) & 0x3ff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE_WGT_VAL5, 0); + arg->edge_wgt_val[i * 3] = val & 0x3ff; + arg->edge_wgt_val[i * 3 + 1] = (val >> 10) & 0x3ff; + + for (i = 0; i < ISP35_SHARP_LUMA_STRG_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_LUMA_ADJ_STRG0 + i * 4, 0); + arg->luma2strg[i * 4] = val & 0xff; + arg->luma2strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->luma2strg[i * 4 + 2] = (val >> 16) & 0xff; + arg->luma2strg[i * 4 + 3] = (val >> 24) & 0xff; + } + + val = isp3_param_read(params_vdev, ISP33_SHARP_CENTER, 0); + arg->center_x = val & 0xffff; + arg->center_y = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_OUT_LIMIT, 0); + arg->flat_max_limit = val & 0xffff; + arg->edge_min_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_TEX_X_INV_FIX0, 0); + arg->tex_x_inv_fix0 = val; + val = isp3_param_read(params_vdev, ISP33_SHARP_TEX_X_INV_FIX1, 0); + arg->tex_x_inv_fix1 = val; + val = isp3_param_read(params_vdev, ISP33_SHARP_TEX_X_INV_FIX2, 0); + arg->tex_x_inv_fix2 = val; + + val = isp3_param_read(params_vdev, ISP33_SHARP_LOCAL_STRG1, 0); + arg->tex2loss_tex_in_hinr_strg[0] = (val >> 10) & 0x3ff; + arg->tex2loss_tex_in_hinr_strg[1] = (val >> 20) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_SHARP_LOCAL_STRG2, 0); + arg->tex2loss_tex_in_hinr_strg[2] = val & 0x3ff; + arg->tex2loss_tex_in_hinr_strg[3] = (val >> 10) & 0x3ff; + + for (i = 0; i < ISP35_SHARP_CONTRAST_STRG_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_SCALE_TAB0 + i * 4, 0); + arg->contrast2pos_strg[i * 4] = val & 0xff; + arg->contrast2pos_strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->contrast2pos_strg[i * 4 + 2] = (val >> 16) & 0xff; + arg->contrast2pos_strg[i * 4 + 3] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_SCALE_TAB3 + i * 4, 0); + arg->contrast2neg_strg[i * 4] = val & 0xff; + arg->contrast2neg_strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->contrast2neg_strg[i * 4 + 2] = (val >> 16) & 0xff; + arg->contrast2neg_strg[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_SCALE_TAB2, 0); + arg->contrast2pos_strg[i * 4] = val & 0xff; + arg->pos_detail_strg = (val >> 8) & 0xff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_SCALE_TAB5, 0); + arg->contrast2neg_strg[i * 4] = val & 0xff; + arg->neg_detail_strg = (val >> 8) & 0xff; + + for (i = 0; i < ISP35_SHARP_TEX_CLIP_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_TEX_CLIP0 + i * 4, 0); + arg->tex2detail_pos_clip[i * 3] = val & 0x3ff; + arg->tex2detail_pos_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->tex2detail_pos_clip[i * 3 + 2] = (val >> 20) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_TEX_CLIP3 + i * 4, 0); + arg->tex2detail_neg_clip[i * 3] = val & 0x3ff; + arg->tex2detail_neg_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->tex2detail_neg_clip[i * 3 + 2] = (val >> 20) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_SHARP_GRAIN_TEX_CLIP0 + i * 4, 0); + arg->tex2grain_pos_clip[i * 3] = val & 0x3ff; + arg->tex2grain_pos_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->tex2grain_pos_clip[i * 3 + 2] = (val >> 20) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_SHARP_GRAIN_TEX_CLIP3 + i * 4, 0); + arg->tex2grain_neg_clip[i * 3] = val & 0x3ff; + arg->tex2grain_neg_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->tex2grain_neg_clip[i * 3 + 2] = (val >> 20) & 0x3ff; + } + + for (i = 0; i < ISP35_SHARP_LUM_CLIP_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_LUMA_CLIP0 + i * 4, 0); + arg->luma2detail_pos_clip[i * 3] = val & 0x3ff; + arg->luma2detail_pos_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->luma2detail_pos_clip[i * 3 + 2] = (val >> 20) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_LUMA_CLIP3 + i * 4, 0); + arg->luma2detail_neg_clip[i * 3] = val & 0x3ff; + arg->luma2detail_neg_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->luma2detail_neg_clip[i * 3 + 2] = (val >> 20) & 0x3ff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_LUMA_CLIP2, 0); + arg->luma2detail_pos_clip[i * 3] = val & 0x3ff; + arg->luma2detail_pos_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + val = isp3_param_read(params_vdev, ISP33_SHARP_DETAIL_LUMA_CLIP5, 0); + arg->luma2detail_neg_clip[i * 3] = val & 0x3ff; + arg->luma2detail_neg_clip[i * 3 + 1] = (val >> 10) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_GRAIN_STRG, 0); + arg->grain_strg = val & 0xff; + + for (i = 0; i < ISP35_SHARP_HUE_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_HUE_ADJ_TAB0 + i * 4, 0); + arg->hue2strg[i * 3] = val & 0x3ff; + arg->hue2strg[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->hue2strg[i * 3 + 2] = (val >> 20) & 0x3ff; + } + + for (i = 0; i < ISP35_SHARP_DISATANCE_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_DISATANCE_ADJ0 + i * 4, 0); + arg->distance2strg[i * 4] = val & 0xff; + arg->distance2strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->distance2strg[i * 4 + 2] = (val >> 16) & 0xff; + arg->distance2strg[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_DISATANCE_ADJ2, 0); + arg->distance2strg[i * 4] = val & 0xff; + arg->distance2strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->distance2strg[i * 4 + 2] = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_SHARP_TEX_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP35_SHARP_TEX2DETAIL_STRG0 + i * 4, 0); + arg->tex2detail_strg[i * 3] = val & 0x3ff; + arg->tex2detail_strg[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->tex2detail_strg[i * 3 + 2] = (val >> 20) & 0x3ff; + } + + for (i = 0; i < ISP35_SHARP_TEX_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_NOISE_SIGMA0 + i * 4, 0); + arg->hi_tex_threshold[i * 2] = val & 0xffff; + arg->hi_tex_threshold[i * 2 + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_NOISE_SIGMA4, 0); + arg->hi_tex_threshold[i * 2] = val & 0xffff; + + for (i = 0; i < ISP35_SHARP_TEX_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP35_SHARP_TEX2MFDETAIL_STRG0 + i * 4, 0); + arg->tex2mf_detail_strg[i * 3] = val & 0x3ff; + arg->tex2mf_detail_strg[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->tex2mf_detail_strg[i * 3 + 2] = (val >> 20) & 0x3ff; + } + + val = isp3_param_read(params_vdev, ISP33_SHARP_LOSSTEXINHINR_STRG, 0); + arg->loss_tex_in_hinr_strg = val & 0xff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_NOISE_CLIP, 0); + arg->noise_clip_min_limit = val & 0xffff; + arg->noise_clip_max_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP35_SHARP_EDGEWGTFLT_KERNEL, 0); + arg->edge_wgt_flt_coeff0 = val & 0xff; + arg->edge_wgt_flt_coeff1 = (val >> 8) & 0xff; + arg->edge_wgt_flt_coeff2 = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP35_SHARP_EDGE_GLOBAL_CLIP, 0); + arg->edge_glb_clip_thred = val & 0x3ff; + arg->pos_edge_clip = (val >> 10) & 0x3ff; + arg->neg_edge_clip = (val >> 20) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP35_SHARP_MFDETAIL, 0); + arg->mf_detail_data_alpha = val & 0xff; + arg->pos_mf_detail_strg = (val >> 8) & 0xff; + arg->neg_mf_detail_strg = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP35_SHARP_MFDETAIL_CLIP, 0); + arg->mf_detail_pos_clip = val & 0x3ff; + arg->sharp_mf_detail_neg_clip = (val >> 10) & 0x3ff; + + for (i = 0; i < ISP35_SHARP_SATURATION_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP35_SHARP_SATURATION_STRG0 + i * 4, 0); + arg->staturation2strg[i * 4] = val & 0xff; + arg->staturation2strg[i * 4 + 1] = (val >> 8) & 0xff; + arg->staturation2strg[i * 4 + 2] = (val >> 16) & 0xff; + arg->staturation2strg[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP35_SHARP_SATURATION_STRG2, 0); + arg->staturation2strg[i * 4] = val & 0x1f; + arg->lo_saturation_strg = (val >> 8) & 0x3ff; + + memcpy(arg->noise_curve_ext, arg_rec->noise_curve_ext, sizeof(arg->noise_curve_ext)); + arg->noise_count_thred_ratio = arg_rec->noise_count_thred_ratio; + arg->noise_clip_scale = arg_rec->noise_clip_scale; +} + +static void rkisp_get_params_cac(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp33_cac_cfg *arg = ¶ms->others.cac_cfg; + struct isp33_cac_cfg *arg_rec = ¶ms_vdev->isp33_params->others.cac_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_CAC_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_CAC; + arg->bypass_en = !!(val & BIT(1)); + arg->edge_detect_en = !!(val & BIT(2)); + arg->neg_clip0_en = !!(val & BIT(3)); + arg->wgt_color_en = !!(val & BIT(5)); + + val = isp3_param_read(params_vdev, ISP3X_CAC_PSF_PARA, 0); + arg->psf_table_fix_bit = val & 0xff; + + val = isp3_param_read(params_vdev, ISP33_CAC_HIGH_DIRECT, 0); + arg->hi_drct_ratio = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_CAC_OVER_EXPO0, 0); + arg->over_expo_thred = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_OVER_EXPO1, 0); + arg->over_expo_adj = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_FLAT, 0); + arg->flat_thred = val & 0xff; + arg->flat_offset = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_CAC_GAUSS_COEFF, 0); + arg->chroma_lo_flt_coeff0 = val & 0x7; + arg->chroma_lo_flt_coeff1 = (val >> 4) & 0x7; + arg->color_lo_flt_coeff0 = (val >> 8) & 0x7; + arg->color_lo_flt_coeff1 = (val >> 12) & 0x7; + + val = isp3_param_read(params_vdev, ISP33_CAC_RATIO, 0); + arg->search_range_ratio = val & 0xffff; + arg->residual_chroma_ratio = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_COLOR_B, 0); + arg->wgt_color_b_min_thred = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_COLOR_R, 0); + arg->wgt_color_r_min_thred = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_COLOR_SLOPE_B, 0); + arg->wgt_color_b_slope = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_COLOR_SLOPE_R, 0); + arg->wgt_color_r_slope = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_COLOR_LUMA0, 0); + arg->wgt_color_min_luma = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_COLOR_LUMA1, 0); + arg->wgt_color_luma_slope = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_OVER_EXPO0, 0); + arg->wgt_over_expo_min_thred = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_OVER_EXPO1, 0); + arg->wgt_over_expo_slope = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_CONTRAST0, 0); + arg->wgt_contrast_min_thred = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_CONTRAST1, 0); + arg->wgt_contrast_slope = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_CONTRAST2, 0); + arg->wgt_contrast_offset = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_DARK_AREA0, 0); + arg->wgt_dark_thed = val; + + val = isp3_param_read(params_vdev, ISP33_CAC_WGT_DARK_AREA1, 0); + arg->wgt_dark_slope = val; + + memcpy(arg->psf_b_ker, arg_rec->psf_b_ker, sizeof(arg->psf_b_ker)); + memcpy(arg->psf_r_ker, arg_rec->psf_r_ker, sizeof(arg->psf_r_ker)); +} + +static void rkisp_get_params_gain(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp3x_gain_cfg *arg = ¶ms->others.gain_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_GAIN_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_GAIN; + + val = isp3_param_read(params_vdev, ISP3X_GAIN_G0, 0); + arg->g0 = val & 0x3ffff; + + val = isp3_param_read(params_vdev, ISP3X_GAIN_G1_G2, 0); + arg->g1 = val & 0xffff; + arg->g2 = (val >> 16) & 0xffff; +} + +static void rkisp_get_params_csm(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp21_csm_cfg *arg = ¶ms->others.csm_cfg; + u32 i, val; + + for (i = 0; i < ISP35_CSM_COEFF_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_ISP_CC_COEFF_0 + i * 4, 0); + if (i == 0) { + arg->csm_c_offset = (val >> 16) & 0xff; + arg->csm_y_offset = (val >> 24) & 0x3f; + } + arg->csm_coeff[i] = val & 0x1ff; + } +} + +static void rkisp_get_params_cgc(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp21_cgc_cfg *arg = ¶ms->others.cgc_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_ISP_CTRL0, 0); + arg->yuv_limit = !!(val & ISP3X_SW_CGC_YUV_LIMIT); + arg->ratio_en = !!(val & ISP3X_SW_CGC_RATIO_EN); +} + +static void rkisp_get_params_ie(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_IMG_EFF_CTRL, 0); + + if (val & ISP35_MODULE_EN) + params->module_ens |= ISP35_MODULE_IE; +} + +static void rkisp_get_params_enh(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp33_enh_cfg *arg = ¶ms->others.enh_cfg; + struct isp33_enh_cfg *arg_rec = ¶ms_vdev->isp35_params->others.enh_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP33_ENH_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_ENH; + arg->bypass = !!(val & BIT(1)); + arg->blf3_bypass = !!(val & BIT(2)); + + val = isp3_param_read(params_vdev, ISP33_ENH_IIR_FLT, 0); + arg->iir_inv_sigma = val & 0xffff; + arg->iir_soft_thed = (val >> 16) & 0xff; + arg->iir_cur_wgt = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_ENH_BILAT_FLT3X3, 0); + arg->blf3_inv_sigma = val & 0x1ff; + arg->blf3_cur_wgt = (val >> 16) & 0x1ff; + arg->blf3_thumb_cur_wgt = (val >> 28) & 0xf; + + val = isp3_param_read(params_vdev, ISP33_ENH_BILAT_FLT5X5, 0); + arg->blf5_inv_sigma = val & 0xffff; + arg->blf5_cur_wgt = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_ENH_GLOBAL_STRG, 0); + arg->global_strg = val & 0xffff; + + for (i = 0; i < ISP35_ENH_LUMA_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_ENH_LUMA_LUT0 + i * 4, 0); + arg->lum2strg[i * 2] = val & 0xffff; + arg->lum2strg[i * 2 + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP33_ENH_LUMA_LUT8, 0); + arg->lum2strg[i * 2] = val & 0xffff; + + for (i = 0; i < ISP35_ENH_DETAIL_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP33_ENH_DETAIL_IDX0 + i * 4, 0); + arg->detail2strg_idx[i * 3] = val & 0x3ff; + arg->detail2strg_idx[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->detail2strg_idx[i * 3 + 2] = (val >> 20) & 0x3ff; + } + val = isp3_param_read(params_vdev, ISP33_ENH_DETAIL_IDX2, 0); + arg->detail2strg_idx[i * 3] = val & 0x3ff; + arg->detail2strg_idx[i * 3 + 1] = (val >> 10) & 0x7ff; + + val = isp3_param_read(params_vdev, ISP33_ENH_DETAIL_POWER, 0); + arg->detail2strg_power0 = val & 0xf; + arg->detail2strg_power1 = (val >> 4) & 0xf; + arg->detail2strg_power2 = (val >> 8) & 0xf; + arg->detail2strg_power3 = (val >> 12) & 0xf; + arg->detail2strg_power4 = (val >> 16) & 0xf; + arg->detail2strg_power5 = (val >> 20) & 0xf; + arg->detail2strg_power6 = (val >> 24) & 0xf; + + for (i = 0; i < ISP35_ENH_DETAIL_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_ENH_DETAIL_VALUE0 + i * 4, 0); + arg->detail2strg_val[i * 2] = val & 0xffff; + arg->detail2strg_val[i * 2 + 1] = (val >> 16) & 0xffff; + } + arg->pre_wet_frame_cnt0 = arg_rec->pre_wet_frame_cnt0; + arg->pre_wet_frame_cnt1 = arg_rec->pre_wet_frame_cnt1; + memcpy(arg->iir, arg_rec->iir, sizeof(arg->iir)); +} + +static void rkisp_get_params_hist(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp33_hist_cfg *arg = ¶ms->others.hist_cfg; + struct isp33_hist_cfg *arg_rec = ¶ms_vdev->isp35_params->others.hist_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP33_HIST_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_HIST; + arg->bypass = !!(val & BIT(1)); + arg->mem_mode = !!(val & BIT(4)); + + val = isp3_param_read(params_vdev, ISP33_HIST_HF_STAT, 0); + arg->count_scale = val & 0xff; + arg->count_offset = (val >> 8) & 0xff; + arg->count_min_limit = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_HIST_MAP0, 0); + arg->merge_alpha = val & 0xffff; + arg->user_set = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_HIST_MAP1, 0); + arg->map_count_scale = val & 0xffff; + arg->gain_ref_wgt = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP33_HIST_IIR, 0); + arg->flt_inv_sigma = val & 0xffff; + arg->flt_cur_wgt = (val >> 16) & 0xff; + + for (i = 0; i < ISP35_HIST_ALPHA_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_HIST_POS_ALPHA0 + i * 4, 0); + arg->pos_alpha[i * 4] = val & 0xff; + arg->pos_alpha[i * 4 + 1] = (val >> 8) & 0xff; + arg->pos_alpha[i * 4 + 2] = (val >> 16) & 0xff; + arg->pos_alpha[i * 4 + 3] = (val >> 24) & 0xff; + val = isp3_param_read(params_vdev, ISP33_HIST_NEG_ALPHA0 + i * 4, 0); + arg->neg_alpha[i * 4] = val & 0xff; + arg->neg_alpha[i * 4 + 1] = (val >> 8) & 0xff; + arg->neg_alpha[i * 4 + 2] = (val >> 16) & 0xff; + arg->neg_alpha[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_HIST_POS_ALPHA4, 0); + arg->pos_alpha[i * 4] = val & 0xff; + val = isp3_param_read(params_vdev, ISP33_HIST_NEG_ALPHA4, 0); + arg->neg_alpha[i * 4] = val & 0xff; + + val = isp3_param_read(params_vdev, ISP33_HIST_UV_SCL, 0); + arg->saturate_scale = val & 0xff; + + arg->stab_frame_cnt0 = arg_rec->stab_frame_cnt0; + arg->stab_frame_cnt1 = arg_rec->stab_frame_cnt1; + memcpy(arg->iir, arg_rec->iir, sizeof(arg->iir)); +} + +static void rkisp_get_params_hsv(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp35_hsv_cfg *arg = ¶ms->others.hsv_cfg; + struct isp35_hsv_cfg *arg_rec = ¶ms_vdev->isp35_params->others.hsv_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_3DLUT_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_HSV; + arg->hsv_1dlut0_en = !!(val & BIT(1)); + arg->hsv_1dlut1_en = !!(val & BIT(2)); + arg->hsv_2dlut0_en = !!(val & BIT(3)); + arg->hsv_2dlut1_en = !!(val & BIT(4)); + arg->hsv_2dlut2_en = !!(val & BIT(8)); + arg->hsv_2dlut12_cfg = !!(val & BIT(6)); + + val = isp3_param_read(params_vdev, ISP35_HSV_MODE_CTRL, 0); + arg->hsv_1dlut0_idx_mode = val & 0x3; + arg->hsv_1dlut1_idx_mode = (val >> 2) & 0x3; + arg->hsv_2dlut0_idx_mode = (val >> 4) & 0x3; + arg->hsv_2dlut1_idx_mode = (val >> 6) & 0x3; + arg->hsv_2dlut2_idx_mode = (val >> 8) & 0x3; + arg->hsv_1dlut0_item_mode = (val >> 10) & 0x7; + arg->hsv_1dlut1_item_mode = (val >> 13) & 0x7; + arg->hsv_2dlut0_item_mode = (val >> 16) & 0x3; + arg->hsv_2dlut1_item_mode = (val >> 18) & 0x3; + arg->hsv_2dlut2_item_mode = (val >> 20) & 0x3; + + memcpy(arg->lut0_1d, arg_rec->lut0_1d, sizeof(arg->lut0_1d)); + memcpy(arg->lut1_1d, arg_rec->lut1_1d, sizeof(arg->lut1_1d)); + memcpy(arg->lut0_2d, arg_rec->lut0_2d, sizeof(arg->lut0_2d)); + memcpy(arg->lut1_2d, arg_rec->lut1_2d, sizeof(arg->lut1_2d)); + memcpy(arg->lut2_2d, arg_rec->lut2_2d, sizeof(arg->lut2_2d)); +} + +static void rkisp_get_params_rgbir(struct rkisp_isp_params_vdev *params_vdev, + struct isp35_isp_params_cfg *params) +{ + struct isp39_rgbir_cfg *arg = ¶ms->others.rgbir_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP39_RGBIR_CTRL, 0); + if (!(val & ISP35_MODULE_EN)) + return; + params->module_ens |= ISP35_MODULE_RGBIR; + + val = isp3_param_read(params_vdev, ISP39_RGBIR_THETA, 0); + arg->coe_theta = val & 0xfff; + + val = isp3_param_read(params_vdev, ISP39_RGBIR_DELTA, 0); + arg->coe_delta = val & 0x3fff; + + for (i = 0; i < ISP35_RGBIR_SCALE_NUM; i++) { + val = isp3_param_read(params_vdev, ISP39_RGBIR_SCALE0 + i * 4, 0); + arg->scale[i] = val & 0x1ff; + } + + for (i = 0; i < ISP35_RGBIR_LUMA_POINT_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP39_RGBIR_LUMA_POINT0 + i * 4, 0); + arg->luma_point[i * 3] = val & 0x3ff; + arg->luma_point[i * 3 + 1] = (val >> 10) & 0x3ff; + arg->luma_point[i * 3 + 2] = (val >> 20) & 0x3ff; + } + val = isp3_param_read(params_vdev, ISP39_RGBIR_LUMA_POINT0 + i * 4, 0); + arg->luma_point[i * 3] = val & 0x3ff; + arg->luma_point[i * 3 + 1] = (val >> 10) & 0x7ff; + + for (i = 0; i < ISP35_RGBIR_SCALE_MAP_NUM / 3; i++) { + val = isp3_param_read(params_vdev, ISP39_RGBIR_SCALE_MAP0 + i * 4, 0); + arg->scale_map[i * 3] = val & 0x1ff; + arg->scale_map[i * 3 + 1] = (val >> 9) & 0x1ff; + arg->scale_map[i * 3 + 2] = (val >> 18) & 0x1ff; + } + val = isp3_param_read(params_vdev, ISP39_RGBIR_SCALE_MAP0 + i * 4, 0); + arg->scale_map[i * 3] = val & 0x1ff; + arg->scale_map[i * 3 + 1] = (val >> 9) & 0x1ff; +} + +int rkisp_get_params_v35(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + struct isp35_isp_params_cfg *params = arg; + + if (!params) + return -EINVAL; + memset(params, 0, sizeof(struct isp35_isp_params_cfg)); + rkisp_get_params_rawaf(params_vdev, params); + rkisp_get_params_rawawb(params_vdev, params); + rkisp_get_params_rawae0(params_vdev, params); + rkisp_get_params_rawae3(params_vdev, params); + rkisp_get_params_rawhist0(params_vdev, params); + rkisp_get_params_rawhist3(params_vdev, params); + + rkisp_get_params_bls(params_vdev, params); + rkisp_get_params_dpcc(params_vdev, params); + rkisp_get_params_lsc(params_vdev, params); + rkisp_get_params_awbgain(params_vdev, params); + rkisp_get_params_gic(params_vdev, params); + rkisp_get_params_debayer(params_vdev, params); + rkisp_get_params_ccm(params_vdev, params); + rkisp_get_params_gammaout(params_vdev, params); + rkisp_get_params_cproc(params_vdev, params); + rkisp_get_params_drc(params_vdev, params); + rkisp_get_params_hdrmge(params_vdev, params); + rkisp_get_params_ldch(params_vdev, params); + rkisp_get_params_bay3d(params_vdev, params); + rkisp_get_params_ynr(params_vdev, params); + rkisp_get_params_cnr(params_vdev, params); + rkisp_get_params_sharp(params_vdev, params); + rkisp_get_params_gain(params_vdev, params); + rkisp_get_params_csm(params_vdev, params); + rkisp_get_params_cgc(params_vdev, params); + rkisp_get_params_ie(params_vdev, params); + rkisp_get_params_enh(params_vdev, params); + rkisp_get_params_hist(params_vdev, params); + rkisp_get_params_hsv(params_vdev, params); + rkisp_get_params_cac(params_vdev, params); + rkisp_get_params_rgbir(params_vdev, params); + return 0; +} +#endif diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.h b/drivers/media/platform/rockchip/isp/isp_params_v35.h new file mode 100644 index 000000000000..3ee884225c94 --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ + +#ifndef _RKISP_ISP_PARAM_V35_H +#define _RKISP_ISP_PARAM_V35_H + +#include "isp_params.h" + +#define ISP35_RAWHISTBIG_ROW_NUM 15 +#define ISP35_RAWHISTBIG_COLUMN_NUM 15 +#define ISP35_RAWHISTBIG_WEIGHT_REG_SIZE \ + (ISP35_RAWHISTBIG_ROW_NUM * ISP35_RAWHISTBIG_COLUMN_NUM) + +struct rkisp_isp_params_vdev; +struct rkisp_isp_params_val_v35 { + struct rkisp_dummy_buffer buf_ldch[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_ldch_idx[ISP_UNITE_MAX]; + struct rkisp_dummy_buffer buf_b3dldc[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_b3dldc_idx[ISP_UNITE_MAX]; + u32 b3dldc_hsize; + u32 b3dldch_vsize; + u32 b3dldcv_vsize; + struct rkisp_dummy_buffer buf_info[RKISP_INFO2DDR_BUF_MAX]; + u32 buf_info_owner; + u32 buf_info_cnt; + int buf_info_idx; + + struct rkisp_dummy_buffer buf_aiawb[RKISP_BUFFER_MAX]; + u32 buf_aiawb_cnt; + int buf_aiawb_idx; + + struct rkisp_dummy_buffer buf_3dnr_wgt; + struct rkisp_dummy_buffer buf_3dnr_iir; + struct rkisp_dummy_buffer buf_3dnr_ds; + struct rkisp_dummy_buffer buf_gain; + u32 bay3d_iir_stride; + u32 bay3d_ds_size; + u32 bay3d_iir_size; + u32 bay3d_wgt_size; + u32 gain_size; + + u32 hist_blk_num; + u32 enh_row; + u32 enh_col; +}; + +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) +int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev); +void rkisp_uninit_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev); +#else +static inline int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) { return -EINVAL; } +static inline void rkisp_uninit_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) {} +#endif +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35_DBG) +int rkisp_get_params_v35(struct rkisp_isp_params_vdev *params_vdev, void *arg); +#else +static inline int rkisp_get_params_v35(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + pr_err("enable CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35_DBG in kernel config\n"); + return -EINVAL; +} +#endif + +#endif /* _RKISP_ISP_PARAM_V35_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_pdaf.c b/drivers/media/platform/rockchip/isp/isp_pdaf.c index 144335550a36..fdf4219cfe93 100644 --- a/drivers/media/platform/rockchip/isp/isp_pdaf.c +++ b/drivers/media/platform/rockchip/isp/isp_pdaf.c @@ -243,6 +243,8 @@ static int rkisp_pdaf_start_streaming(struct vb2_queue *vq, unsigned int count) v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s cnt:%d\n", __func__, count); val = pdaf_vdev->fmt.plane_fmt[0].bytesperline; + if (dev->isp_ver == ISP_V35) + val = 512; rkisp_write(dev, ISP39_W3A_CTRL1, val, false); pdaf_vdev->streaming = true; tasklet_enable(&pdaf_vdev->buf_done_tasklet); @@ -303,11 +305,14 @@ static void rkisp_pdaf_buf_done_task(unsigned long arg) void rkisp_pdaf_update_buf(struct rkisp_device *dev) { - struct rkisp_pdaf_vdev *pdaf_vdev = &dev->pdaf_vdev; + struct rkisp_pdaf_vdev *pdaf_vdev = dev->pdaf_vdev; struct rkisp_buffer *buf = NULL; unsigned long flags = 0; u32 val; + if (!pdaf_vdev) + return; + spin_lock_irqsave(&pdaf_vdev->vbq_lock, flags); if (!pdaf_vdev->next_buf && !list_empty(&pdaf_vdev->buf_queue)) { buf = list_first_entry(&pdaf_vdev->buf_queue, @@ -333,11 +338,15 @@ void rkisp_pdaf_update_buf(struct rkisp_device *dev) void rkisp_pdaf_isr(struct rkisp_device *dev) { - struct rkisp_pdaf_vdev *pdaf_vdev = &dev->pdaf_vdev; + struct rkisp_pdaf_vdev *pdaf_vdev = dev->pdaf_vdev; struct rkisp_buffer *buf = NULL; unsigned long flags = 0; - u32 w3a_ris = rkisp_read(dev, ISP39_W3A_INT_STAT, true); + u32 w3a_ris; + if (!pdaf_vdev) + return; + + w3a_ris = rkisp_read(dev, ISP39_W3A_INT_STAT, true); if (w3a_ris & ISP39_W3A_INT_PDAF_OVF) { v4l2_err(&dev->v4l2_dev, "pdaf overflow 0x%x\n", w3a_ris); rkisp_write(dev, ISP39_W3A_INT_STAT, ISP39_W3A_INT_PDAF_OVF, true); @@ -387,16 +396,22 @@ void rkisp_pdaf_isr(struct rkisp_device *dev) int rkisp_register_pdaf_vdev(struct rkisp_device *dev) { - struct rkisp_pdaf_vdev *pdaf_vdev = &dev->pdaf_vdev; - struct rkisp_vdev_node *node = &pdaf_vdev->vnode; - struct video_device *vdev = &node->vdev; + struct rkisp_pdaf_vdev *pdaf_vdev; + struct rkisp_vdev_node *node; + struct video_device *vdev; struct media_entity *source, *sink; int ret; - if (dev->isp_ver != ISP_V39) + if (dev->isp_ver != ISP_V39 && dev->isp_ver != ISP_V35) return 0; - + pdaf_vdev = kzalloc(sizeof(struct rkisp_pdaf_vdev), GFP_KERNEL); + if (!pdaf_vdev) + return -ENOMEM; pdaf_vdev->dev = dev; + dev->pdaf_vdev = pdaf_vdev; + + node = &pdaf_vdev->vnode; + vdev = &node->vdev; INIT_LIST_HEAD(&pdaf_vdev->buf_queue); spin_lock_init(&pdaf_vdev->vbq_lock); mutex_init(&pdaf_vdev->api_lock); @@ -419,6 +434,8 @@ int rkisp_register_pdaf_vdev(struct rkisp_device *dev) if (ret < 0) { v4l2_err(vdev->v4l2_dev, "could not register Video for Linux device\n"); + kfree(pdaf_vdev); + dev->pdaf_vdev = NULL; return ret; } @@ -440,18 +457,25 @@ int rkisp_register_pdaf_vdev(struct rkisp_device *dev) return 0; unreg: video_unregister_device(vdev); + kfree(pdaf_vdev); + dev->pdaf_vdev = NULL; return ret; } void rkisp_unregister_pdaf_vdev(struct rkisp_device *dev) { - struct rkisp_pdaf_vdev *pdaf_vdev = &dev->pdaf_vdev; - struct rkisp_vdev_node *node = &pdaf_vdev->vnode; - struct video_device *vdev = &node->vdev; + struct rkisp_pdaf_vdev *pdaf_vdev; + struct rkisp_vdev_node *node; + struct video_device *vdev; - if (dev->isp_ver != ISP_V39) + if (!dev->pdaf_vdev) return; + pdaf_vdev = dev->pdaf_vdev; + node = &pdaf_vdev->vnode; + vdev = &node->vdev; tasklet_kill(&pdaf_vdev->buf_done_tasklet); media_entity_cleanup(&vdev->entity); video_unregister_device(vdev); + kfree(pdaf_vdev); + dev->pdaf_vdev = NULL; } diff --git a/drivers/media/platform/rockchip/isp/isp_pdaf.h b/drivers/media/platform/rockchip/isp/isp_pdaf.h index 9e8f60e317de..27bb39afb4e9 100644 --- a/drivers/media/platform/rockchip/isp/isp_pdaf.h +++ b/drivers/media/platform/rockchip/isp/isp_pdaf.h @@ -25,7 +25,7 @@ struct rkisp_pdaf_vdev { bool stopping; }; -#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) void rkisp_pdaf_update_buf(struct rkisp_device *dev); void rkisp_pdaf_isr(struct rkisp_device *dev); int rkisp_register_pdaf_vdev(struct rkisp_device *dev); diff --git a/drivers/media/platform/rockchip/isp/isp_rockit.c b/drivers/media/platform/rockchip/isp/isp_rockit.c index 6221342f6399..865c40b18a1b 100644 --- a/drivers/media/platform/rockchip/isp/isp_rockit.c +++ b/drivers/media/platform/rockchip/isp/isp_rockit.c @@ -315,7 +315,7 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd, struct rkisp_buf rockit_cfg->frame.u64PTS = ns; rockit_cfg->frame.u32TimeRef = seq; - if (dev->isp_ver == ISP_V33) + if (dev->isp_ver == ISP_V33 || dev->isp_ver == ISP_V35) rockit_cfg->frame.ispEncCnt = ISP33_ISP2ENC_FRM_CNT(rkisp_read(dev, ISP3X_ISP_DEBUG1, true)); } diff --git a/drivers/media/platform/rockchip/isp/isp_sditf.c b/drivers/media/platform/rockchip/isp/isp_sditf.c index e6ebe02dce86..f4a2e1af5530 100644 --- a/drivers/media/platform/rockchip/isp/isp_sditf.c +++ b/drivers/media/platform/rockchip/isp/isp_sditf.c @@ -91,6 +91,8 @@ void rkisp_sditf_reset_notify_vpss(struct rkisp_device *dev) { struct rkisp_sditf_device *sditf = dev->sditf_dev; + if (!sditf || !sditf->is_on || !sditf->remote_sd) + return; v4l2_info(&dev->v4l2_dev, "%s\n", __func__); v4l2_subdev_call(sditf->remote_sd, core, ioctl, RKISP_VPSS_RESET_NOTIFY_VPSS, NULL); } diff --git a/drivers/media/platform/rockchip/isp/isp_sditf.h b/drivers/media/platform/rockchip/isp/isp_sditf.h index 5aae87fb4887..b9b6c7bc78e7 100644 --- a/drivers/media/platform/rockchip/isp/isp_sditf.h +++ b/drivers/media/platform/rockchip/isp/isp_sditf.h @@ -18,7 +18,7 @@ struct rkisp_sditf_device { bool is_on; }; -#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) extern struct platform_driver rkisp_sditf_drv; void rkisp_sditf_sof(struct rkisp_device *dev, u32 irq); void rkisp_sditf_reset_notify_vpss(struct rkisp_device *dev); diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index c110fd672e83..170a3a4e0e60 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -16,6 +16,7 @@ #include "isp_stats_v32.h" #include "isp_stats_v39.h" #include "isp_stats_v33.h" +#include "isp_stats_v35.h" #define STATS_NAME DRIVER_NAME "-statistics" #define RKISP_ISP_STATS_REQ_BUFS_MIN 2 @@ -155,7 +156,7 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) unsigned long flags = 0; stats_buf->vaddr[0] = vb2_plane_vaddr(vb, 0); - if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33) { + if (dev->isp_ver == ISP_V32 || dev->isp_ver >= ISP_V33) { struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); stats_buf->buff_addr[0] = sg_dma_address(sgt->sgl); @@ -166,35 +167,10 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) vb->vb2_queue->mem_ops->prepare(vb->planes[0].mem_priv); } spin_lock_irqsave(&stats_dev->rd_lock, flags); - if (dev->isp_ver == ISP_V32 && dev->is_pre_on) { - struct rkisp32_isp_stat_buffer *buf = stats_dev->stats_buf[0].vaddr; - - if (dev->isp_state & ISP_START && stats_buf->vaddr[0] && - buf && !buf->frame_id && buf->meas_type) { - dev_info(dev->dev, - "tb stat seq:%d meas_type:0x%x\n", - buf->frame_id, buf->meas_type); - memcpy(stats_buf->vaddr[0], buf, size); - buf->meas_type = 0; - vb2_set_plane_payload(vb, 0, size); - vbuf->sequence = buf->frame_id; + if (dev->is_pre_on && stats_dev->ops->stats_tb) { + if (stats_dev->ops->stats_tb(stats_dev, stats_buf) == 0) { spin_unlock_irqrestore(&stats_dev->rd_lock, flags); - vb2_buffer_done(vb, VB2_BUF_STATE_DONE); - return; - } - } else if (dev->isp_ver == ISP_V33 && dev->is_pre_on) { - struct rkisp33_stat_buffer *buf = stats_dev->stats_buf[0].vaddr; - - if (dev->isp_state & ISP_START && stats_buf->vaddr[0] && - buf && !buf->frame_id && buf->meas_type) { - dev_info(dev->dev, - "tb stat seq:%d meas_type:0x%x\n", - buf->frame_id, buf->meas_type); - memcpy(stats_buf->vaddr[0], buf, size); - buf->meas_type = 0; vb2_set_plane_payload(vb, 0, size); - vbuf->sequence = buf->frame_id; - spin_unlock_irqrestore(&stats_dev->rd_lock, flags); vb2_buffer_done(vb, VB2_BUF_STATE_DONE); return; } @@ -280,8 +256,7 @@ static int rkisp_stats_init_vb2_queue(struct vb2_queue *q, q->drv_priv = stats_vdev; q->ops = &rkisp_stats_vb2_ops; if (stats_vdev->dev->isp_ver == ISP_V32 || - stats_vdev->dev->isp_ver == ISP_V39 || - stats_vdev->dev->isp_ver == ISP_V33) { + stats_vdev->dev->isp_ver >= ISP_V33) { q->mem_ops = stats_vdev->dev->hw_dev->mem_ops; if (stats_vdev->dev->hw_dev->is_dma_contig) q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS; @@ -336,6 +311,8 @@ static void rkisp_init_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_init_stats_vdev_v39(stats_vdev); else if (dev->isp_ver == ISP_V33) rkisp_init_stats_vdev_v33(stats_vdev); + else if (dev->isp_ver == ISP_V35) + rkisp_init_stats_vdev_v35(stats_vdev); } static void rkisp_uninit_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) @@ -356,6 +333,8 @@ static void rkisp_uninit_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_uninit_stats_vdev_v39(stats_vdev); else if (dev->isp_ver == ISP_V33) rkisp_uninit_stats_vdev_v33(stats_vdev); + else if (dev->isp_ver == ISP_V35) + rkisp_uninit_stats_vdev_v35(stats_vdev); } void rkisp_stats_rdbk_enable(struct rkisp_isp_stats_vdev *stats_vdev, bool en) @@ -366,28 +345,14 @@ void rkisp_stats_rdbk_enable(struct rkisp_isp_stats_vdev *stats_vdev, bool en) void rkisp_stats_first_ddr_config(struct rkisp_isp_stats_vdev *stats_vdev) { - if (stats_vdev->dev->isp_ver == ISP_V20) - rkisp_stats_first_ddr_config_v2x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V21) - rkisp_stats_first_ddr_config_v21(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V30) - rkisp_stats_first_ddr_config_v3x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V32) - rkisp_stats_first_ddr_config_v32(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V39) - rkisp_stats_first_ddr_config_v39(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V33) - rkisp_stats_first_ddr_config_v33(stats_vdev); + if (stats_vdev->ops->first_ddr_cfg) + stats_vdev->ops->first_ddr_cfg(stats_vdev); } void rkisp_stats_next_ddr_config(struct rkisp_isp_stats_vdev *stats_vdev) { - if (stats_vdev->dev->isp_ver == ISP_V32) - rkisp_stats_next_ddr_config_v32(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V39) - rkisp_stats_next_ddr_config_v39(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V33) - rkisp_stats_next_ddr_config_v33(stats_vdev); + if (stats_vdev->ops->next_ddr_cfg) + stats_vdev->ops->next_ddr_cfg(stats_vdev); } void rkisp_stats_isr(struct rkisp_isp_stats_vdev *stats_vdev, diff --git a/drivers/media/platform/rockchip/isp/isp_stats.h b/drivers/media/platform/rockchip/isp/isp_stats.h index 4ccf8b827410..962e8c073f8d 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.h +++ b/drivers/media/platform/rockchip/isp/isp_stats.h @@ -35,6 +35,9 @@ struct rkisp_isp_stats_ops { struct rkisp_isp_readout_work *meas_work); void (*rdbk_enable)(struct rkisp_isp_stats_vdev *stats_vdev, bool en); void (*get_stat_size)(struct rkisp_isp_stats_vdev *stats_vdev, unsigned int sizes[]); + void (*first_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev); + void (*next_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev); + int (*stats_tb)(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_buffer *stats_buf); }; /* diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v21.c b/drivers/media/platform/rockchip/isp/isp_stats_v21.c index 343e0da58a52..4f5acf9a4ed3 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v21.c @@ -1133,14 +1133,8 @@ rkisp_get_stat_size_v21(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } -static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { - .isr_hdl = rkisp_stats_isr_v21, - .send_meas = rkisp_stats_send_meas_v21, - .rdbk_enable = rkisp_stats_rdbk_enable_v21, - .get_stat_size = rkisp_get_stat_size_v21, -}; - -void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) { stats_vdev->rd_stats_from_ddr = false; stats_vdev->priv_ops = &rkisp_stats_reg_ops_v21; @@ -1161,6 +1155,14 @@ void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) } } +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v21, + .send_meas = rkisp_stats_send_meas_v21, + .rdbk_enable = rkisp_stats_rdbk_enable_v21, + .get_stat_size = rkisp_get_stat_size_v21, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v21, +}; + void rkisp_init_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev) { int mult = stats_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v21.h b/drivers/media/platform/rockchip/isp/isp_stats_v21.h index 6fccd014db2b..bc51ad051cbc 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v21.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v21.h @@ -40,11 +40,9 @@ struct rkisp_stats_v21_ops { }; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V21) -void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_init_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_uninit_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev); #else -static inline void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_init_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_uninit_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev) {} #endif diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c index 408aa2950f20..a6d7e8ef328b 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c @@ -1467,14 +1467,8 @@ rkisp_get_stat_size_v2x(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } -static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { - .isr_hdl = rkisp_stats_isr_v2x, - .send_meas = rkisp_stats_send_meas_v2x, - .rdbk_enable = rkisp_stats_rdbk_enable_v2x, - .get_stat_size = rkisp_get_stat_size_v2x, -}; - -void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) { bool reg_withstream = false; struct v4l2_subdev *sd = v4l2_get_subdev_hostdata(&stats_vdev->dev->br_dev.sd); @@ -1499,6 +1493,14 @@ void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) } } +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v2x, + .send_meas = rkisp_stats_send_meas_v2x, + .rdbk_enable = rkisp_stats_rdbk_enable_v2x, + .get_stat_size = rkisp_get_stat_size_v2x, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v2x, +}; + void rkisp_init_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev) { stats_vdev->ops = &rkisp_isp_stats_ops_tbl; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v2x.h b/drivers/media/platform/rockchip/isp/isp_stats_v2x.h index 37d7988f7013..1d6c8d7d4f39 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v2x.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v2x.h @@ -58,11 +58,9 @@ struct rkisp_stats_v2x_ops { }; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V20) -void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_init_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_uninit_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev); #else -static inline void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_init_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_uninit_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev) {} #endif diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/drivers/media/platform/rockchip/isp/isp_stats_v32.c index d373c7156cee..db56055f82de 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.c @@ -1088,14 +1088,29 @@ rkisp_get_stat_size_v32(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } -static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { - .isr_hdl = rkisp_stats_isr_v32, - .send_meas = rkisp_stats_send_meas_v32, - .rdbk_enable = rkisp_stats_rdbk_enable_v32, - .get_stat_size = rkisp_get_stat_size_v32, -}; +static int +rkisp_stats_tb_v32(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp_buffer *stats_buf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp32_isp_stat_buffer *buf = stats_vdev->stats_buf[0].vaddr; + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + int ret = -EINVAL; -void rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) + if (dev->isp_state & ISP_START && stats_buf->vaddr[0] && + buf && !buf->frame_id && buf->meas_type) { + dev_info(dev->dev, "tb stat seq:%d meas_type:0x%x\n", + buf->frame_id, buf->meas_type); + memcpy(stats_buf->vaddr[0], buf, size); + stats_buf->vb.sequence = buf->frame_id; + buf->meas_type = 0; + ret = 0; + } + return ret; +} + +static void +rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; u32 size = 0, div = dev->unite_div; @@ -1119,7 +1134,8 @@ void rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) } } -void rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_hw_dev *hw = stats_vdev->dev->hw_dev; @@ -1130,6 +1146,16 @@ void rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_stats_update_buf(stats_vdev); } +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v32, + .send_meas = rkisp_stats_send_meas_v32, + .rdbk_enable = rkisp_stats_rdbk_enable_v32, + .get_stat_size = rkisp_get_stat_size_v32, + .stats_tb = rkisp_stats_tb_v32, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v32, + .next_ddr_cfg = rkisp_stats_next_ddr_config_v32, +}; + void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) { if (stats_vdev->dev->isp_ver == ISP_V32) { diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.h b/drivers/media/platform/rockchip/isp/isp_stats_v32.h index b598c8734478..b6a4f6419a3d 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.h @@ -40,13 +40,9 @@ struct rkisp_stats_ops_v32 { }; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) -void rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev); -void rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_uninit_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev); #else -static inline void rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) {} -static inline void rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_uninit_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) {} #endif diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v33.c b/drivers/media/platform/rockchip/isp/isp_stats_v33.c index 19ff836b064b..887f90f7d487 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v33.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v33.c @@ -504,13 +504,29 @@ rkisp_get_stat_size_v33(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } -static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { - .isr_hdl = rkisp_stats_isr_v33, - .send_meas = rkisp_stats_send_meas_v33, - .get_stat_size = rkisp_get_stat_size_v33, -}; +static int +rkisp_stats_tb_v33(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp_buffer *stats_buf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp33_stat_buffer *buf = stats_vdev->stats_buf[0].vaddr; + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + int ret = -EINVAL; -void rkisp_stats_first_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) + if (dev->isp_state & ISP_START && stats_buf->vaddr[0] && + buf && !buf->frame_id && buf->meas_type) { + dev_info(dev->dev, "tb stat seq:%d meas_type:0x%x\n", + buf->frame_id, buf->meas_type); + memcpy(stats_buf->vaddr[0], buf, size); + stats_buf->vb.sequence = buf->frame_id; + buf->meas_type = 0; + ret = 0; + } + return ret; +} + +static void +rkisp_stats_first_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; u32 val, size = 0, div = dev->unite_div; @@ -539,7 +555,8 @@ void rkisp_stats_first_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) } } -void rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; struct rkisp_hw_dev *hw = dev->hw_dev; @@ -551,6 +568,15 @@ void rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_stats_update_buf(stats_vdev); } +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v33, + .send_meas = rkisp_stats_send_meas_v33, + .get_stat_size = rkisp_get_stat_size_v33, + .stats_tb = rkisp_stats_tb_v33, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v33, + .next_ddr_cfg = rkisp_stats_next_ddr_config_v33, +}; + void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev) { stats_vdev->ops = &rkisp_isp_stats_ops_tbl; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v33.h b/drivers/media/platform/rockchip/isp/isp_stats_v33.h index 6360e0abf76e..31c3d5c94daf 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v33.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v33.h @@ -12,13 +12,9 @@ struct rkisp_isp_stats_vdev; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) -void rkisp_stats_first_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev); -void rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_uninit_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev); #else -static inline void rkisp_stats_first_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) {} -static inline void rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_uninit_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev) {} #endif diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v35.c b/drivers/media/platform/rockchip/isp/isp_stats_v35.c new file mode 100644 index 000000000000..a3937c9b98c8 --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_stats_v35.c @@ -0,0 +1,636 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ + +#include +#include +#include +#include +#include +#include +#include "dev.h" +#include "regs.h" +#include "common.h" +#include "isp_stats.h" +#include "isp_stats_v35.h" +#include "isp_params_v35.h" + +#define ISP35_3A_MEAS_DONE BIT(31) + +static void isp3_module_done(struct rkisp_isp_stats_vdev *stats_vdev, u32 reg, u32 value) +{ + void __iomem *base = stats_vdev->dev->hw_dev->base_addr; + + writel(value, base + reg); +} + +static u32 isp3_stats_read(struct rkisp_isp_stats_vdev *stats_vdev, u32 addr) +{ + return rkisp_read(stats_vdev->dev, addr, true); +} + +static void isp3_stats_write(struct rkisp_isp_stats_vdev *stats_vdev, + u32 addr, u32 value) +{ + rkisp_write(stats_vdev->dev, addr, value, true); +} + +static int +rkisp_stats_get_sharp_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct isp33_sharp_stat *sharp; + u32 i, val; + + if (!pbuf) + return 0; + + val = isp3_stats_read(stats_vdev, ISP3X_SHARP_EN); + if (val & 0x1) { + sharp = &pbuf->stat.sharp; + for (i = 0; i < ISP35_SHARP_NOISE_CURVE_NUM / 2; i++) { + val = isp3_stats_read(stats_vdev, ISP33_SHARP_NOISE_CURVE0 + i * 4); + sharp->noise_curve[i * 2] = val & 0x7ff; + sharp->noise_curve[i * 2 + 1] = (val >> 16) & 0x7ff; + } + val = isp3_stats_read(stats_vdev, ISP33_SHARP_NOISE_CURVE8); + sharp->noise_curve[i * 2] = val & 0x7ff; + pbuf->meas_type |= ISP35_STAT_SHARP; + } + return 0; +} + +static int +rkisp_stats_get_bay3d_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct isp33_bay3d_stat *bay3d; + u32 i, val; + + if (!pbuf) + return 0; + val = isp3_stats_read(stats_vdev, ISP33_BAY3D_CTRL0); + if (val & 0x1) { + bay3d = &pbuf->stat.bay3d; + val = isp3_stats_read(stats_vdev, ISP33_BAY3D_TNRSUM); + bay3d->sigma_num = val; + for (i = 0; i < ISP35_BAY3D_TNRSIG_NUM / 2; i++) { + val = isp3_stats_read(stats_vdev, ISP33_BAY3D_TNRYO0 + i * 4); + bay3d->sigma_y[i * 2] = val & 0xfff; + bay3d->sigma_y[i * 2 + 1] = (val >> 16) & 0xfff; + } + pbuf->meas_type |= ISP35_STAT_BAY3D; + } + return 0; +} + +static int +rkisp_stats_get_hist_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_vdev *params = &dev->params_vdev; + struct rkisp_isp_params_val_v35 *priv_val = params->priv_val; + struct isp35_isp_params_cfg *params_rec = params->isp35_params + dev->unite_index; + struct isp33_hist_cfg *arg_rec = ¶ms_rec->others.hist_cfg; + struct isp33_hist_stat *hist; + int val, i, j, timeout; + + val = isp3_stats_read(stats_vdev, ISP33_HIST_CTRL); + if (val & 0x1) { + val = isp3_stats_read(stats_vdev, ISP33_HIST_STAB); + arg_rec->stab_frame_cnt0 = val & 0xf; + arg_rec->stab_frame_cnt1 = (val & 0xf0) >> 4; + for (i = 0; i < priv_val->hist_blk_num; i++) { + val = ISP33_IIR_RD_ID(i) | ISP33_IIR_RD_P; + isp3_stats_write(stats_vdev, ISP33_HIST_RW, val); + timeout = 5; + while (timeout--) { + val = isp3_stats_read(stats_vdev, ISP33_HIST_RW); + if (val & ISP33_IIR_RDATA_VAL) + break; + udelay(2); + } + if (timeout < 0) { + v4l2_warn(&dev->v4l2_dev, "%s hist read:%d timeout\n", __func__, i); + return 0; + } + for (j = 0; j < ISP35_HIST_IIR_NUM / 2; j++) { + val = isp3_stats_read(stats_vdev, ISP33_HIST_IIR0 + 4 * j); + arg_rec->iir[i][2 * j] = val & 0x3FF; + arg_rec->iir[i][2 * j + 1] = val >> 16; + } + } + if (dev->is_frm_rd) + arg_rec->iir_wr = true; + if (pbuf) { + hist = &pbuf->stat.hist; + memcpy(hist->iir, arg_rec->iir, sizeof(hist->iir)); + pbuf->meas_type |= ISP35_STAT_HIST; + } + } + return 0; +} + +static int +rkisp_stats_get_enh_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_vdev *params = &dev->params_vdev; + struct rkisp_isp_params_val_v35 *priv_val = params->priv_val; + struct isp35_isp_params_cfg *params_rec = params->isp35_params + dev->unite_index; + struct isp33_enh_cfg *arg_rec = ¶ms_rec->others.enh_cfg; + struct isp33_enh_stat *enh; + int val, i, j, timeout; + + val = isp3_stats_read(stats_vdev, ISP33_ENH_CTRL); + if (val & 0x1) { + val = isp3_stats_read(stats_vdev, ISP33_ENH_PRE_FRAME); + arg_rec->pre_wet_frame_cnt0 = val & 0xf; + arg_rec->pre_wet_frame_cnt1 = (val & 0xf0) >> 4; + for (i = 0; i < priv_val->enh_row; i++) { + val = ISP33_IIR_RD_ID(i) | ISP33_IIR_RD_P; + isp3_stats_write(stats_vdev, ISP33_ENH_IIR_RW, val); + timeout = 5; + while (timeout--) { + val = isp3_stats_read(stats_vdev, ISP33_ENH_IIR_RW); + if (val & ISP33_IIR_RDATA_VAL) + break; + udelay(2); + } + if (timeout < 0) { + v4l2_warn(&dev->v4l2_dev, "%s enh read:%d timeout\n", __func__, i); + return 0; + } + for (j = 0; j < priv_val->enh_col / 4; j++) { + val = isp3_stats_read(stats_vdev, ISP33_ENH_IIR0 + 4 * j); + arg_rec->iir[i][4 * j] = val & 0xFF; + arg_rec->iir[i][4 * j + 1] = (val & 0xff00) >> 8; + arg_rec->iir[i][4 * j + 2] = (val & 0xff0000) >> 16; + arg_rec->iir[i][4 * j + 3] = (val & 0xff000000) >> 24; + } + } + if (dev->is_frm_rd) + arg_rec->iir_wr = true; + if (pbuf) { + enh = &pbuf->stat.enh; + memcpy(enh->iir, arg_rec->iir, sizeof(enh->iir)); + pbuf->meas_type |= ISP35_STAT_ENH; + } + } + return 0; +} + +static int +rkisp_stats_update_buf(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_buffer *buf; + unsigned long flags = 0; + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize / dev->unite_div; + u32 val, addr = 0, offset = 0; + int i, ret = 0; + + spin_lock_irqsave(&stats_vdev->rd_lock, flags); + if (!stats_vdev->nxt_buf && !list_empty(&stats_vdev->stat)) { + buf = list_first_entry(&stats_vdev->stat, + struct rkisp_buffer, queue); + list_del(&buf->queue); + stats_vdev->nxt_buf = buf; + } + spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); + + if (stats_vdev->nxt_buf) { + addr = stats_vdev->nxt_buf->buff_addr[0]; + if (!dev->hw_dev->is_single) { + stats_vdev->cur_buf = stats_vdev->nxt_buf; + stats_vdev->nxt_buf = NULL; + } + } else if (stats_vdev->stats_buf[0].mem_priv) { + addr = stats_vdev->stats_buf[0].dma_addr; + } else { + ret = -EINVAL; + } + + if (addr) { + for (i = 0; i < dev->unite_div; i++) { + val = addr + i * size; + + rkisp_idx_write(dev, ISP39_W3A_AEBIG_ADDR, val, i, false); + + offset = sizeof(struct isp33_rawae_stat) + + sizeof(struct isp33_rawhist_stat); + val += offset; + rkisp_idx_write(dev, ISP39_W3A_AE0_ADDR, val, i, false); + + val += offset; + rkisp_idx_write(dev, ISP39_W3A_AF_ADDR, val, i, false); + + offset = sizeof(struct isp39_rawaf_stat); + val += offset; + rkisp_idx_write(dev, ISP39_W3A_AWB_ADDR, val, i, false); + } + v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, + "%s BASE:0x%x SHD AEBIG:0x%x AE0:0x%x AF:0x%x AWB:0x%x\n", + __func__, addr, + isp3_stats_read(stats_vdev, ISP39_W3A_AEBIG_ADDR_SHD), + isp3_stats_read(stats_vdev, ISP39_W3A_AE0_ADDR_SHD), + isp3_stats_read(stats_vdev, ISP39_W3A_AF_ADDR_SHD), + isp3_stats_read(stats_vdev, ISP39_W3A_AWB_ADDR_SHD)); + } + return ret; +} + +static void +rkisp_stats_get_aiawb_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev; + struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; + u32 ctrl = rkisp_read(dev, ISP35_AIAWB_CTRL0, false); + u32 buf_idx, val; + + if (!pbuf || !(ctrl & ISP35_AIAWB_EN) || !priv_val->buf_aiawb_cnt) + return; + pbuf->meas_type |= ISP35_STAT_AIAWB; + buf_idx = priv_val->buf_aiawb_idx; + pbuf->stat.buf_aiawb_index = priv_val->buf_aiawb[buf_idx].index; + buf_idx = (buf_idx + 1) % priv_val->buf_aiawb_cnt; + val = priv_val->buf_aiawb[buf_idx].dma_addr; + rkisp_write(dev, ISP35_AIAWB_WR_BASE, val, false); + rkisp_write(dev, ISP35_AIAWB_CTRL0, ctrl | ISP35_AIAWB_SELF_UPD, false); + priv_val->buf_aiawb_idx = buf_idx; +} + +static void +rkisp_stats_get_awbsync_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct isp35_awbsync_stat *awbsync; + u32 ctrl = isp3_stats_read(stats_vdev, ISP35_AWBSYNC_CTRL); + u64 msb, lsb; + int i; + + if (!(ctrl & ISP35_3A_MEAS_DONE)) { + v4l2_dbg(1, rkisp_debug, &stats_vdev->dev->v4l2_dev, + "%s fail, ctrl:0x%x\n", __func__, ctrl); + return; + } + if (!pbuf) + goto out; + awbsync = &pbuf->stat.awbsync; + for (i = 0; i < ISP35_AWBSYNC_WIN_MAX; i++) { + msb = isp3_stats_read(stats_vdev, ISP35_AWBSYNC_WIN0_SUMP + i * 0x10); + awbsync->sump[i] = msb & 0x3ffffff; + lsb = isp3_stats_read(stats_vdev, ISP35_AWBSYNC_WIN0_SUMR + i * 0x10); + awbsync->sumr[i] = lsb | ((msb & 0xc0000000) << 2); + lsb = isp3_stats_read(stats_vdev, ISP35_AWBSYNC_WIN0_SUMG + i * 0x10); + awbsync->sumg[i] = lsb | ((msb & 0x30000000) << 4); + lsb = isp3_stats_read(stats_vdev, ISP35_AWBSYNC_WIN0_SUMB + i * 0x10); + awbsync->sumg[i] = lsb | ((msb & 0xc000000) << 6); + } + pbuf->meas_type |= ISP35_STAT_AWBSYNC; +out: + isp3_module_done(stats_vdev, ISP35_AWBSYNC_CTRL, ctrl); +} + +static void +rkisp_stats_info2ddr(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp35_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_val_v35 *priv_val; + struct rkisp_dummy_buffer *buf; + int idx, buf_fd = -1; + u32 reg = 0, ctrl, mask; + + if (dev->is_aiisp_en) + return; + + priv_val = dev->params_vdev.priv_val; + if (!priv_val->buf_info_owner && priv_val->buf_info_idx >= 0) { + priv_val->buf_info_idx = -1; + rkisp_clear_bits(dev, ISP3X_GAIN_CTRL, ISP3X_GAIN_2DDR_EN, false); + rkisp_clear_bits(dev, ISP3X_RAWAWB_CTRL, ISP32_RAWAWB_2DDR_PATH_EN, false); + return; + } + + if (priv_val->buf_info_owner == RKISP_INFO2DRR_OWNER_GAIN) { + reg = ISP3X_GAIN_CTRL; + ctrl = ISP3X_GAIN_2DDR_EN; + mask = ISP3X_GAIN_2DDR_EN; + } else { + reg = ISP3X_RAWAWB_CTRL; + ctrl = ISP32_RAWAWB_2DDR_PATH_EN; + mask = ISP32_RAWAWB_2DDR_PATH_EN | ISP32_RAWAWB_2DDR_PATH_DS; + } + + idx = priv_val->buf_info_idx; + if (idx >= 0) { + buf = &priv_val->buf_info[idx]; + rkisp_finish_buffer(dev, buf); + v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, + "%s data:0x%x 0x%x:0x%x\n", __func__, + *(u32 *)buf->vaddr, reg, rkisp_read(dev, reg, true)); + if (*(u32 *)buf->vaddr != RKISP_INFO2DDR_BUF_INIT && pbuf && + (reg != ISP3X_RAWAWB_CTRL || + !(rkisp_read(dev, reg, true) & ISP32_RAWAWB_2DDR_PATH_ERR))) { + pbuf->stat.info2ddr.buf_fd = buf->dma_fd; + pbuf->stat.info2ddr.owner = priv_val->buf_info_owner; + pbuf->meas_type |= ISP35_STAT_INFO2DDR; + buf_fd = buf->dma_fd; + } else if (reg == ISP3X_RAWAWB_CTRL && + rkisp_read(dev, reg, true) & ISP32_RAWAWB_2DDR_PATH_ERR) { + v4l2_warn(&dev->v4l2_dev, "rawawb2ddr path error idx:%d\n", idx); + } else { + u32 v0 = rkisp_read(dev, reg, false); + u32 v1 = rkisp_read_reg_cache(dev, reg); + + if ((v0 & mask) != (v1 & mask)) + rkisp_write(dev, reg, v0 | (v1 & mask), false); + } + + if (buf_fd == -1) + return; + } + /* get next unused buf to hw */ + for (idx = 0; idx < priv_val->buf_info_cnt; idx++) { + buf = &priv_val->buf_info[idx]; + if (*(u32 *)buf->vaddr == RKISP_INFO2DDR_BUF_INIT) + break; + } + + if (idx == priv_val->buf_info_cnt) { + rkisp_clear_bits(dev, reg, ctrl, false); + priv_val->buf_info_idx = -1; + } else { + buf = &priv_val->buf_info[idx]; + rkisp_write(dev, ISP3X_MI_GAIN_WR_BASE, buf->dma_addr, false); + if (dev->hw_dev->is_single) + rkisp_write(dev, ISP3X_MI_WR_CTRL2, ISP3X_GAINSELF_UPD, true); + if (priv_val->buf_info_idx < 0) + rkisp_set_bits(dev, reg, 0, ctrl, false); + priv_val->buf_info_idx = idx; + } +} + +static void +rkisp_stats_send_meas_v35(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp_isp_readout_work *meas_work) +{ + struct rkisp_isp_params_vdev *params_vdev = &stats_vdev->dev->params_vdev; + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_buffer *cur_buf = stats_vdev->cur_buf; + struct rkisp35_stat_buffer *cur_stat_buf = NULL; + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + u32 cur_frame_id = meas_work->frame_id; + bool is_dummy = false; + unsigned long flags = 0; + + if (!stats_vdev->rdbk_drop) { + if (!cur_buf && stats_vdev->stats_buf[0].mem_priv) { + rkisp_finish_buffer(stats_vdev->dev, &stats_vdev->stats_buf[0]); + cur_stat_buf = stats_vdev->stats_buf[0].vaddr; + cur_stat_buf->frame_id = cur_frame_id; + cur_stat_buf->params_id = params_vdev->cur_frame_id; + is_dummy = true; + } else if (cur_buf) { + cur_stat_buf = cur_buf->vaddr[0]; + cur_stat_buf->frame_id = cur_frame_id; + cur_stat_buf->params_id = params_vdev->cur_frame_id; + } + + /* buffer done when frame of right handle */ + if (dev->unite_div > ISP_UNITE_DIV1) { + if (dev->unite_index == ISP_UNITE_LEFT) { + cur_buf = NULL; + is_dummy = false; + } else if (cur_stat_buf) { + cur_stat_buf = (void *)cur_stat_buf + size / 2; + cur_stat_buf->frame_id = cur_frame_id; + cur_stat_buf->params_id = params_vdev->cur_frame_id; + } + } + + if (dev->unite_div < ISP_UNITE_DIV2 || dev->unite_index == ISP_UNITE_RIGHT) { + /* config buf for next frame */ + stats_vdev->cur_buf = NULL; + if (stats_vdev->nxt_buf) { + stats_vdev->cur_buf = stats_vdev->nxt_buf; + stats_vdev->nxt_buf = NULL; + } + rkisp_stats_update_buf(stats_vdev); + } + } else { + cur_buf = NULL; + } + + if (cur_stat_buf) { + cur_stat_buf->stat.buf_aiawb_index = -1; + cur_stat_buf->stat.info2ddr.buf_fd = -1; + cur_stat_buf->stat.info2ddr.owner = 0; + } + + if (meas_work->isp3a_ris & ISP3X_3A_RAWAWB && cur_stat_buf) + cur_stat_buf->meas_type |= ISP35_STAT_RAWAWB; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWAF && cur_stat_buf) + cur_stat_buf->meas_type |= ISP35_STAT_RAWAF; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG && cur_stat_buf) + cur_stat_buf->meas_type |= ISP35_STAT_RAWAE3; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_BIG && cur_stat_buf) + cur_stat_buf->meas_type |= ISP35_STAT_RAWHST3; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_CH0 && cur_stat_buf) + cur_stat_buf->meas_type |= ISP35_STAT_RAWAE0; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_CH0 && cur_stat_buf) + cur_stat_buf->meas_type |= ISP35_STAT_RAWHST0; + + if (meas_work->isp3a_ris & ISP35_AIAWB_DONE && cur_stat_buf) + rkisp_stats_get_aiawb_stats(stats_vdev, cur_stat_buf); + if (meas_work->isp3a_ris & ISP35_AWBSYNC_DONE && cur_stat_buf) + rkisp_stats_get_awbsync_stats(stats_vdev, cur_stat_buf); + + if (meas_work->isp_ris & ISP3X_FRAME) { + rkisp_stats_get_bay3d_stats(stats_vdev, cur_stat_buf); + rkisp_stats_get_sharp_stats(stats_vdev, cur_stat_buf); + rkisp_stats_get_enh_stats(stats_vdev, cur_stat_buf); + rkisp_stats_get_hist_stats(stats_vdev, cur_stat_buf); + } + + if (cur_stat_buf && (dev->is_first_double || dev->is_wait_aiq)) { + cur_stat_buf->meas_type |= ISP35_STAT_RTT_FST; + dev_info(dev->dev, "stats seq:%d meas_type:0x%x for fast\n", + cur_frame_id, cur_stat_buf->meas_type); + } + + if (is_dummy) { + spin_lock_irqsave(&stats_vdev->rd_lock, flags); + if (!list_empty(&stats_vdev->stat)) { + cur_buf = list_first_entry(&stats_vdev->stat, struct rkisp_buffer, queue); + list_del(&cur_buf->queue); + } + spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); + if (cur_buf) { + memcpy(cur_buf->vaddr[0], stats_vdev->stats_buf[0].vaddr, size); + cur_stat_buf = cur_buf->vaddr[0]; + } + } + if (cur_buf && cur_stat_buf) { + cur_stat_buf->frame_id = cur_frame_id; + cur_stat_buf->params_id = params_vdev->cur_frame_id; + cur_stat_buf->stat.info2ddr.buf_fd = -1; + cur_stat_buf->stat.info2ddr.owner = 0; + rkisp_stats_info2ddr(stats_vdev, cur_stat_buf); + + vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0, size); + cur_buf->vb.sequence = cur_frame_id; + cur_buf->vb.vb2_buf.timestamp = meas_work->timestamp; + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + } + v4l2_dbg(4, rkisp_debug, &stats_vdev->dev->v4l2_dev, + "%s seq:%d params_id:%d ris:0x%x buf:%p meas_type:0x%x aiawb(fd:%d 0x%x)\n", + __func__, cur_frame_id, params_vdev->cur_frame_id, meas_work->isp3a_ris, + cur_buf, !cur_stat_buf ? 0 : cur_stat_buf->meas_type, + !cur_stat_buf ? -1 : cur_stat_buf->stat.buf_aiawb_index, + isp3_stats_read(stats_vdev, ISP35_AIAWB_WR_BASE_SHD)); +} + +static void +rkisp_stats_isr_v35(struct rkisp_isp_stats_vdev *stats_vdev, + u32 isp_ris, u32 isp3a_ris) +{ + struct rkisp_isp_readout_work work; + u32 cur_frame_id, isp_mis_tmp = 0; + u32 temp_isp3a_ris; + + rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, NULL, true); + + temp_isp3a_ris = isp3_stats_read(stats_vdev, ISP3X_ISP_3A_RIS); + isp_mis_tmp = temp_isp3a_ris; + if (isp_mis_tmp) + isp3_stats_write(stats_vdev, ISP3X_ISP_3A_ICR, isp_mis_tmp); + + rkisp_pdaf_isr(stats_vdev->dev); + + if (isp_ris & ISP3X_FRAME) { + work.readout = RKISP_ISP_READOUT_MEAS; + work.frame_id = cur_frame_id; + work.isp_ris = isp_ris; + work.isp3a_ris = temp_isp3a_ris; + work.timestamp = ktime_get_ns(); + rkisp_stats_send_meas_v35(stats_vdev, &work); + } +} + +static void +rkisp_get_stat_size_v35(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + int mult = stats_vdev->dev->unite_div; + + sizes[0] = ALIGN(sizeof(struct rkisp35_stat_buffer), 16); + sizes[0] *= mult; + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + +static int +rkisp_stats_tb_v35(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp_buffer *stats_buf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp35_stat_buffer *buf = stats_vdev->stats_buf[0].vaddr; + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + int ret = -EINVAL; + + if (dev->isp_state & ISP_START && stats_buf->vaddr[0] && + buf && !buf->frame_id && buf->meas_type) { + dev_info(dev->dev, "tb stat seq:%d meas_type:0x%x\n", + buf->frame_id, buf->meas_type); + memcpy(stats_buf->vaddr[0], buf, size); + stats_buf->vb.sequence = buf->frame_id; + buf->meas_type = 0; + ret = 0; + } + return ret; +} + +static void +rkisp_stats_first_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_pdaf_vdev *pdaf_vdev = dev->pdaf_vdev; + u32 val, size = 0, div = dev->unite_div; + + if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) + return; + + rkisp_get_stat_size_v35(stats_vdev, &size); + stats_vdev->stats_buf[0].is_need_vaddr = true; + stats_vdev->stats_buf[0].size = size; + if (rkisp_alloc_buffer(dev, &stats_vdev->stats_buf[0])) + v4l2_warn(&dev->v4l2_dev, "stats alloc buf fail\n"); + else + memset(stats_vdev->stats_buf[0].vaddr, 0, size); + if (rkisp_stats_update_buf(stats_vdev) < 0) { + v4l2_err(&dev->v4l2_dev, "no stats buf to enable w3a\n"); + return; + } + if (dev->hw_dev->is_single) + rkisp_unite_set_bits(dev, ISP3X_SWS_CFG, 0, ISP3X_3A_DDR_WRITE_EN, false); + val = rkisp_read(dev, ISP39_W3A_CTRL0, false); + val |= ISP39_W3A_EN | ISP39_W3A_AUTO_CLR_EN | ISP39_W3A_FORCE_UPD; + if (pdaf_vdev && pdaf_vdev->streaming) { + val |= ISP39_W3A_PDAF_EN; + rkisp_pdaf_update_buf(dev); + if (pdaf_vdev->next_buf) { + pdaf_vdev->curr_buf = pdaf_vdev->next_buf; + pdaf_vdev->next_buf = NULL; + } + } + rkisp_unite_write(dev, ISP39_W3A_CTRL0, val, false); + rkisp_unite_write(dev, ISP39_W3A_WR_SIZE, size / div, false); + if (stats_vdev->nxt_buf) { + stats_vdev->cur_buf = stats_vdev->nxt_buf; + stats_vdev->nxt_buf = NULL; + } +} + +static void +rkisp_stats_next_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_hw_dev *hw = dev->hw_dev; + struct rkisp_pdaf_vdev *pdaf_vdev = dev->pdaf_vdev; + + if (!stats_vdev->streamon || dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) + return; + /* pingpong buf */ + if (hw->is_single) { + rkisp_stats_update_buf(stats_vdev); + if (pdaf_vdev && pdaf_vdev->streaming) + rkisp_pdaf_update_buf(dev); + } +} + +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v35, + .get_stat_size = rkisp_get_stat_size_v35, + .stats_tb = rkisp_stats_tb_v35, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v35, + .next_ddr_cfg = rkisp_stats_next_ddr_config_v35, +}; + +void rkisp_init_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev) +{ + stats_vdev->ops = &rkisp_isp_stats_ops_tbl; +} + +void rkisp_uninit_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev) +{ + +} diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v35.h b/drivers/media/platform/rockchip/isp/isp_stats_v35.h new file mode 100644 index 000000000000..6fa3cec4c40c --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_stats_v35.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ + +#ifndef _RKISP_STATS_V35_H +#define _RKISP_STATS_V35_H + +#define ISP35_RD_STATS_BUF_SIZE 0x10000 + +struct rkisp_isp_stats_vdev; + +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) +void rkisp_init_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev); +void rkisp_uninit_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev); +#else +static inline void rkisp_init_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev) {} +static inline void rkisp_uninit_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev) {} +#endif + +#endif /* _RKISP_STATS_V35_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v39.c b/drivers/media/platform/rockchip/isp/isp_stats_v39.c index 058be1da53a2..c420645761e4 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v39.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v39.c @@ -477,15 +477,11 @@ rkisp_get_stat_size_v39(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } -static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { - .isr_hdl = rkisp_stats_isr_v39, - .get_stat_size = rkisp_get_stat_size_v39, -}; - -void rkisp_stats_first_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_first_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; - struct rkisp_pdaf_vdev *pdaf_vdev = &dev->pdaf_vdev; + struct rkisp_pdaf_vdev *pdaf_vdev = dev->pdaf_vdev; u32 val, size = 0, div = dev->unite_div; if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) @@ -506,7 +502,7 @@ void rkisp_stats_first_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) val = ISP39_W3A_EN | ISP39_W3A_FORCE_UPD; if (!dev->is_aiisp_en || dev->is_aiisp_sync) val |= ISP39_W3A_AUTO_CLR_EN; - if (pdaf_vdev->streaming) { + if (pdaf_vdev && pdaf_vdev->streaming) { val |= ISP39_W3A_PDAF_EN; rkisp_pdaf_update_buf(dev); if (pdaf_vdev->next_buf) { @@ -522,11 +518,12 @@ void rkisp_stats_first_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) } } -void rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; struct rkisp_hw_dev *hw = dev->hw_dev; - struct rkisp_pdaf_vdev *pdaf_vdev = &dev->pdaf_vdev; + struct rkisp_pdaf_vdev *pdaf_vdev = dev->pdaf_vdev; if (!stats_vdev->streamon || dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) return; @@ -534,11 +531,18 @@ void rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) if (hw->is_single) { if (!dev->is_aiisp_en || dev->is_aiisp_sync) rkisp_stats_update_buf(stats_vdev); - if (pdaf_vdev->streaming) + if (pdaf_vdev && pdaf_vdev->streaming) rkisp_pdaf_update_buf(dev); } } +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v39, + .get_stat_size = rkisp_get_stat_size_v39, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v39, + .next_ddr_cfg = rkisp_stats_next_ddr_config_v39, +}; + void rkisp_init_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev) { stats_vdev->ops = &rkisp_isp_stats_ops_tbl; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v39.h b/drivers/media/platform/rockchip/isp/isp_stats_v39.h index 5590c7cbc5c3..570dfcd370dd 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v39.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v39.h @@ -14,13 +14,9 @@ struct rkisp_isp_stats_vdev; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) -void rkisp_stats_first_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev); -void rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_init_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_uninit_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev); #else -static inline void rkisp_stats_first_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) {} -static inline void rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_init_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_uninit_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev) {} #endif diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c index 812e9b1fac1a..7f162b2e0f48 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c @@ -1171,14 +1171,8 @@ rkisp_get_stat_size_v3x(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } -static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { - .isr_hdl = rkisp_stats_isr_v3x, - .send_meas = rkisp_stats_send_meas_v3x, - .rdbk_enable = rkisp_stats_rdbk_enable_v3x, - .get_stat_size = rkisp_get_stat_size_v3x, -}; - -void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) +static void +rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; int i, mult = dev->unite_div; @@ -1217,6 +1211,14 @@ err: dev_err(dev->dev, "alloc stats ddr buf fail\n"); } +static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { + .isr_hdl = rkisp_stats_isr_v3x, + .send_meas = rkisp_stats_send_meas_v3x, + .rdbk_enable = rkisp_stats_rdbk_enable_v3x, + .get_stat_size = rkisp_get_stat_size_v3x, + .first_ddr_cfg = rkisp_stats_first_ddr_config_v3x, +}; + void rkisp_init_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev) { stats_vdev->ops = &rkisp_isp_stats_ops_tbl; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v3x.h b/drivers/media/platform/rockchip/isp/isp_stats_v3x.h index 042f11c70a36..3c290147729a 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v3x.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v3x.h @@ -40,11 +40,9 @@ struct rkisp_stats_ops_v3x { }; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V30) -void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_init_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev); void rkisp_uninit_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev); #else -static inline void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_init_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev) {} static inline void rkisp_uninit_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev) {} #endif diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index 6b1f297aa958..b633a2cc39c7 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -13,6 +13,7 @@ #include "isp_params_v3x.h" #include "isp_params_v32.h" #include "isp_params_v33.h" +#include "isp_params_v35.h" #include "isp_params_v39.h" #ifdef CONFIG_PROC_FS @@ -1134,6 +1135,162 @@ static void isp33_show(struct rkisp_device *dev, struct seq_file *p) !!(val & BIT(3)), !!(val & BIT(2)), !!(val & BIT(1)), !!(val & BIT(0))); } +static void isp35_show(struct rkisp_device *dev, struct seq_file *p) +{ + struct rkisp_isp_params_val_v35 *priv = dev->params_vdev.priv_val; + u32 full_range_flg = CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA; + static const char * const effect[] = { "OFF", "BLACKWHITE" }; + u32 val, tmp; + + val = rkisp_read(dev, ISP3X_SWS_CFG, false); + tmp = rkisp_read(dev, ISP3X_SWS_CFG, true); + seq_printf(p, "%-10s %s wrap:%d isp2enc(path_en:%d pipe_en:%d hold:%d)\n", "ISP2ENC", + dev->cap_dev.wrap_line ? "online" : "offline", + dev->cap_dev.wrap_line, + !!(val & BIT(5)), !!(val & BIT(1)), !!(tmp & BIT(31))); + val = rkisp_read(dev, ISP3X_GIC_CONTROL, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d\n", "GIC", (val & 1) ? "ON" : "OFF", + val, !!(val & BIT(1))); + val = rkisp_read(dev, ISP3X_CAC_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d\n", "CAC", (val & (BIT(0) | BIT(31))) ? "ON" : "OFF", + val, !!(val & (BIT(1) | BIT(30)))); + val = rkisp_read(dev, ISP3X_ISP_CTRL0, false); + seq_printf(p, "%-10s %s(0x%x) (gain0:0x%08x 0x%08x gain1:0x%x 0x%x)\n", "AWBGAIN", + (val & BIT(7)) ? "ON" : "OFF", val, + rkisp_read(dev, ISP3X_ISP_AWB_GAIN0_G, false), + rkisp_read(dev, ISP3X_ISP_AWB_GAIN0_RB, false), + rkisp_read(dev, ISP32_ISP_AWB1_GAIN_G, false), + rkisp_read(dev, ISP32_ISP_AWB1_GAIN_RB, false)); + val = rkisp_read(dev, ISP3X_DPCC0_MODE, false); + seq_printf(p, "%-10s %s(0x%x)\n", "DPCC0", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_DPCC1_MODE, false); + seq_printf(p, "%-10s %s(0x%x)\n", "DPCC1", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_BLS_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "BLS", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_LSC_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "LSC", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_DEBAYER_CONTROL, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d\n", "DEBAYER", (val & (BIT(0) | BIT(29))) ? "ON" : "OFF", + val, !!(val & (BIT(1) | BIT(27)))); + val = rkisp_read(dev, ISP3X_CCM_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "CCM", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_GAMMA_OUT_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "GAMMA_OUT", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_CPROC_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "CPROC", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_IMG_EFF_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) (effect: %s)\n", "IE", + (val & 1) ? "ON" : "OFF", val, effect[!!val]); + val = rkisp_read(dev, ISP3X_DRC_CTRL0, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d lp_en:%d\n", "DRC", (val & 1) ? "ON" : "OFF", + val, !!(val & BIT(1)), !!(val & BIT(4))); + val = rkisp_read(dev, ISP3X_HDRMGE_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) wrap:%d\n", "HDRMGE", (val & 1) ? "ON" : "OFF", + val, dev->hdr_wrap_line); + val = rkisp_read(dev, ISP33_BAY3D_CTRL0, false); + tmp = rkisp_read(dev, ISP33_BAY3D_CTRL2, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d iir_rw_fmt:%d b3dldch:0x%x b3dldcv:0x%x\n" + "\t lp_en(me_off:%d gic:%d bf:%d avg:%d) size(iir:%d ds:%d wgt:%d)\n", + "BAY3D", (val & 1) ? "ON" : "OFF", val, !!(val & BIT(1)), (val >> 13) & 0x7, + rkisp_read(dev, ISP35_B3DLDC_ADR_STS, false), + rkisp_read(dev, ISP35_B3DLDC_CTRL, false), + !(val & BIT(8)), !!(tmp & BIT(20)), !!(tmp & BIT(21)), !!(tmp & BIT(22)), + priv->buf_3dnr_iir.size, priv->buf_3dnr_ds.size, priv->buf_3dnr_wgt.size); + val = rkisp_read(dev, ISP3X_YNR_GLOBAL_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) bypass(hi:%d mi:%d lo:%d) lp_en:%d\n", "YNR", + (val & 1) ? "ON" : "OFF", val, + !!(val & BIT(1)), !!(val & BIT(2)), !!(val & BIT(3)), !!(val & BIT(6))); + val = rkisp_read(dev, ISP3X_CNR_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "CNR", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_SHARP_EN, false); + seq_printf(p, "%-10s %s(0x%x) lp_en:%d\n", "SHARP", + (val & 1) ? "ON" : "OFF", val, !!(val & BIT(10))); + val = rkisp_read(dev, ISP33_ENH_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d lp_en:%d\n", "ENH", (val & 1) ? "ON" : "OFF", + val, !!(val & BIT(1)), !!(val & BIT(2))); + val = rkisp_read(dev, ISP33_HIST_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) bypass:%d\n", "HIST", (val & 1) ? "ON" : "OFF", + val, !!(val & BIT(1))); + val = rkisp_read(dev, ISP33_HSV_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "HSV", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_LDCH_STS, false); + seq_printf(p, "%-10s %s(0x%x)\n", "LDCH", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_ISP_CTRL0, false); + tmp = rkisp_read(dev, ISP3X_ISP_CC_COEFF_0, false); + seq_printf(p, "%-10s %s(0x%x), y_offs:0x%x c_offs:0x%x\n" + "\t coeff Y:0x%x 0x%x 0x%x CB:0x%x 0x%x 0x%x CR:0x%x 0x%x 0x%x\n", + "CSM", (val & full_range_flg) ? "FULL" : "LIMIT", val, + (tmp >> 24) & 0x3f, + (tmp >> 16) & 0xff ? (tmp >> 16) & 0xff : 128, + tmp & 0x1ff, + rkisp_read(dev, ISP3X_ISP_CC_COEFF_1, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_2, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_3, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_4, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_5, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_6, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_7, false), + rkisp_read(dev, ISP3X_ISP_CC_COEFF_8, false)); + val = rkisp_read(dev, ISP3X_GAIN_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "GAIN", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP32_BLS_ISP_OB_PREDGAIN, false); + tmp = rkisp_read(dev, ISP32_BLS_ISP_OB_OFFSET, false); + seq_printf(p, "%-10s %s pregdain:0x%x offset:0x%x offset1:%d max:0x%x\n", + "OB", val ? "ON" : "OFF", val, tmp & 0x1ff, (tmp >> 16) & 0x1ff, + rkisp_read(dev, ISP32_BLS_ISP_OB_MAX, false)); + val = rkisp_read(dev, ISP3X_RAWAE_LITE_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWAE0", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_RAWAE_BIG1_BASE, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWAE3", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_RAWHIST_LITE_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWHIST0", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_RAWHIST_BIG1_BASE, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWHIST3", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_RAWAF_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWAF", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_RAWAWB_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWAWB", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP35_AIAWB_CTRL0, false); + seq_printf(p, "%-10s %s(0x%x) idx:%d cnt:%d\n", "AIAWB", (val & 1) ? "ON" : "OFF", + val, priv->buf_aiawb_cnt, priv->buf_aiawb_idx); + val = rkisp_read(dev, ISP35_AWBSYNC_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "AWBSYNC", (val & 1) ? "ON" : "OFF", val); + val = rkisp_read(dev, ISP3X_ISP_DEBUG1, true); + seq_printf(p, "%-10s space full status group(0x%x) isp2enc_cnt:%d\n" + "\t ibuf2:0x%x ibuf1:0x%x ibuf0:0x%x\n" + "\t outfifo:0x%x lafifo:0x%x\n", + "DEBUG1", val, val & 0xff, + val >> 28, (val >> 24) & 0xf, (val >> 20) & 0xf, + (val >> 12) & 0xf, (val >> 8) & 0xf); + val = rkisp_read(dev, ISP3X_ISP_DEBUG2, true); + seq_printf(p, "%-10s 0x%x\n" + "\t bay3d_fifo_full iir:%d cur:%d\n" + "\t module outform vertical counter:%d, out frame counter:%d\n" + "\t isp output line counter:%d\n", + "DEBUG2", val, !!(val & BIT(31)), !!(val & BIT(30)), + (val >> 16) & 0x3fff, (val >> 14) & 0x3, val & 0x3fff); + val = rkisp_read(dev, ISP3X_ISP_DEBUG3, true); + seq_printf(p, "%-10s isp pipeline group (0x%x)\n" + "\t mge(%d %d) rawnr(%d %d) bay3d(%d %d) tmo(%d %d)\n" + "\t gic(%d %d) dbr(%d %d) debayer(%d %d) dhaz(%d %d)\n" + "\t lut3d(%d %d) ldch(%d %d) ynr(%d %d) shp(%d %d)\n" + "\t cgc(%d %d) cac(%d %d) isp_out(%d %d) isp_in(%d %d)\n", + "DEBUG3", val, + !!(val & BIT(31)), !!(val & BIT(30)), !!(val & BIT(29)), !!(val & BIT(28)), + !!(val & BIT(27)), !!(val & BIT(26)), !!(val & BIT(25)), !!(val & BIT(24)), + !!(val & BIT(23)), !!(val & BIT(22)), !!(val & BIT(21)), !!(val & BIT(20)), + !!(val & BIT(19)), !!(val & BIT(18)), !!(val & BIT(17)), !!(val & BIT(16)), + !!(val & BIT(15)), !!(val & BIT(14)), !!(val & BIT(13)), !!(val & BIT(12)), + !!(val & BIT(11)), !!(val & BIT(10)), !!(val & BIT(9)), !!(val & BIT(8)), + !!(val & BIT(7)), !!(val & BIT(6)), !!(val & BIT(5)), !!(val & BIT(4)), + !!(val & BIT(3)), !!(val & BIT(2)), !!(val & BIT(1)), !!(val & BIT(0))); + val = rkisp_read(dev, ISP32_ISP_DEBUG4, true); + seq_printf(p, "%-10s isp pipeline group (0x%x)\n" + "\t expd(%d %d) ynr(%d %d)\n", + "DEBUG4", val, + !!(val & BIT(3)), !!(val & BIT(2)), !!(val & BIT(1)), !!(val & BIT(0))); +} + static int isp_show(struct seq_file *p, void *v) { struct rkisp_device *dev = p->private; @@ -1264,6 +1421,10 @@ static int isp_show(struct seq_file *p, void *v) if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33)) isp33_show(dev, p); break; + case ISP_V35: + if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35)) + isp35_show(dev, p); + break; default: break; } diff --git a/drivers/media/platform/rockchip/isp/regs.c b/drivers/media/platform/rockchip/isp/regs.c index 9326d7e3baad..744853926b68 100644 --- a/drivers/media/platform/rockchip/isp/regs.c +++ b/drivers/media/platform/rockchip/isp/regs.c @@ -482,7 +482,7 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y, struct rkisp_device *dev = stream->ispdev; int i = 0; - if (dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33 || + if (dev->isp_ver >= ISP_V33 || (dev->isp_ver == ISP_V32_L && stream->id == RKISP_STREAM_SP)) { set_bilinear_scale(stream, in_y, in_c, out_y, out_c, async); return; @@ -508,8 +508,7 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y, void rkisp_disable_rsz(struct rkisp_stream *stream, bool async) { rkisp_unite_write(stream->ispdev, stream->config->rsz.ctrl, 0, false); - if (stream->ispdev->isp_ver == ISP_V39 || - stream->ispdev->isp_ver == ISP_V33 || + if (stream->ispdev->isp_ver >= ISP_V33 || (stream->ispdev->isp_ver == ISP_V32_L && stream->id == RKISP_STREAM_SP)) return; update_rsz_shadow(stream, async); diff --git a/drivers/media/platform/rockchip/isp/regs_v3x.h b/drivers/media/platform/rockchip/isp/regs_v3x.h index a2817e6f8ad2..a8c6be021fff 100644 --- a/drivers/media/platform/rockchip/isp/regs_v3x.h +++ b/drivers/media/platform/rockchip/isp/regs_v3x.h @@ -532,6 +532,22 @@ #define ISP39_LDCV_OUT_SIZE (ISP39_LDCV_BASE + 0x0003c) #define ISP39_LDCV_WR_C_ADDR (ISP39_LDCV_BASE + 0x00040) +#define ISP35_AI_BASE 0x00001200 +#define ISP35_AI_CTRL (ISP35_AI_BASE + 0x00000) +#define ISP35_AI_SIGMA_Y0 (ISP35_AI_BASE + 0x00010) +#define ISP35_AI_SIGMA_Y16 (ISP35_AI_BASE + 0x00050) +#define ISP35_AI_PRE_NL_WR_BASE (ISP35_AI_BASE + 0x00054) +#define ISP35_AI_PRE_NL_WR_STRIDE (ISP35_AI_BASE + 0x00058) +#define ISP35_AI_PRE_GAIN_WR_BASE (ISP35_AI_BASE + 0x0005c) +#define ISP35_AI_PRE_GAIN_WR_STRIDE (ISP35_AI_BASE + 0x00060) +#define ISP35_AI_PRE_NL_PRE (ISP35_AI_BASE + 0x00064) +#define ISP35_AI_PRE_GAIN_PARA (ISP35_AI_BASE + 0x00068) +#define ISP35_AI_PRE_SIGMA_CURVE0 (ISP35_AI_BASE + 0x0006c) +#define ISP35_AI_PRE_SIGMA_CURVE10 (ISP35_AI_BASE + 0x00094) +#define ISP35_AI_PRE_NOISE0 (ISP35_AI_BASE + 0x00098) +#define ISP35_AI_PRE_NOISE1 (ISP35_AI_BASE + 0x0009c) +#define ISP35_AI_PRE_NOISE2 (ISP35_AI_BASE + 0x000A0) + #define ISP3X_MI_BASE 0x00001400 #define ISP3X_MI_WR_CTRL (ISP3X_MI_BASE + 0x00000) #define ISP3X_MI_WR_INIT (ISP3X_MI_BASE + 0x00004) @@ -760,6 +776,16 @@ #define ISP32L_FRM_BUF_WR_BASE (ISP3X_MI_BASE + 0x00650) #define ISP32L_FRM_BUF_WR_SIZE (ISP3X_MI_BASE + 0x00654) #define ISP32L_FRM_BUF_RD_BASE (ISP3X_MI_BASE + 0x00658) +#define ISP35_B3DLDCH_RD_BASE (ISP3X_MI_BASE + 0x00600) +#define ISP35_B3DLDCH_RD_LENGTH (ISP3X_MI_BASE + 0x00604) +#define ISP35_B3DLDCH_RD_HWSIZE (ISP3X_MI_BASE + 0x00608) +#define ISP35_B3DLDCH_RD_VSIZE (ISP3X_MI_BASE + 0x0060c) +#define ISP35_B3DLDCH_RD_BASE_SHD (ISP3X_MI_BASE + 0x00620) +#define ISP35_B3DLDCV_RD_BASE_SHD (ISP3X_MI_BASE + 0x00628) +#define ISP35_B3DLDCV_RD_BASE (ISP3X_MI_BASE + 0x00630) +#define ISP35_B3DLDCV_RD_LENGTH (ISP3X_MI_BASE + 0x00634) +#define ISP35_B3DLDCV_RD_HWSIZE (ISP3X_MI_BASE + 0x00638) +#define ISP35_B3DLDCV_RD_VSIZE (ISP3X_MI_BASE + 0x0063C) #define ISP3X_MPFBC_BASE 0x000018C0 #define ISP3X_MPFBC_CTRL (ISP3X_MPFBC_BASE + 0x00000) @@ -1073,6 +1099,10 @@ #define ISP33_YNR_LO_TEXT_THRED (ISP3X_YNR_BASE + 0x000ec) #define ISP33_YNR_FUSION_WEIT_ADJ_0_3 (ISP3X_YNR_BASE + 0x000f0) #define ISP33_YNR_FUSION_WEIT_ADJ_8 (ISP3X_YNR_BASE + 0x000f8) +#define ISP35_YNR_MI_TEX2WGT_SCALE_0_1_2 (ISP3X_YNR_BASE + 0x00088) +#define ISP35_YNR_LO_TEX2WGT_SCALE_0_1_2 (ISP3X_YNR_BASE + 0x00094) +#define ISP35_YNR_MI_GAUS_COE1 (ISP3X_YNR_BASE + 0x000d0) +#define ISP35_YNR_DSIIR_COE (ISP3X_YNR_BASE + 0x000dc) #define ISP3X_CNR_BASE 0x00002800 #define ISP3X_CNR_CTRL (ISP3X_CNR_BASE + 0x00000) @@ -1116,6 +1146,14 @@ #define ISP39_CNR_GAUS_Y_SIGMAR1 (ISP3X_CNR_BASE + 0x00064) #define ISP39_CNR_GAUS_Y_SIGMAR2 (ISP3X_CNR_BASE + 0x00068) #define ISP39_CNR_GAUS_Y_SIGMAR3 (ISP3X_CNR_BASE + 0x0006c) +#define ISP35_CNR_IIR_SIGMAR0 (ISP3X_CNR_BASE + 0x00070) +#define ISP35_CNR_IIR_SIGMAR3 (ISP3X_CNR_BASE + 0x0007c) +#define ISP35_CNR_HSV_CURVE0 (ISP3X_CNR_BASE + 0x00080) +#define ISP35_CNR_HSV_CURVE2 (ISP3X_CNR_BASE + 0x00088) +#define ISP35_CNR_SAT_CURVE0 (ISP3X_CNR_BASE + 0x0008c) +#define ISP35_CNR_SAT_CURVE2 (ISP3X_CNR_BASE + 0x00094) +#define ISP35_CNR_GAIN_ADJ_CURVE0 (ISP3X_CNR_BASE + 0x00098) +#define ISP35_CNR_GAIN_ADJ_CURVE2 (ISP3X_CNR_BASE + 0x000a0) #define ISP3X_SHARP_BASE 0x00002900 #define ISP3X_SHARP_EN (ISP3X_SHARP_BASE + 0x00000) @@ -1259,6 +1297,16 @@ #define ISP33_SHARP_NOISE_CURVE0 (ISP3X_SHARP_BASE + 0x00170) #define ISP33_SHARP_NOISE_CURVE8 (ISP3X_SHARP_BASE + 0x00190) #define ISP33_SHARP_NOISE_CLIP (ISP3X_SHARP_BASE + 0x00194) +#define ISP35_SHARP_TEX2DETAIL_STRG0 (ISP3X_SHARP_BASE + 0x0013c) +#define ISP35_SHARP_TEX2DETAIL_STRG2 (ISP3X_SHARP_BASE + 0x00144) +#define ISP35_SHARP_TEX2MFDETAIL_STRG0 (ISP3X_SHARP_BASE + 0x0015c) +#define ISP35_SHARP_TEX2MFDETAIL_STRG2 (ISP3X_SHARP_BASE + 0x00164) +#define ISP35_SHARP_EDGEWGTFLT_KERNEL (ISP3X_SHARP_BASE + 0x00198) +#define ISP35_SHARP_EDGE_GLOBAL_CLIP (ISP3X_SHARP_BASE + 0x001a0) +#define ISP35_SHARP_MFDETAIL (ISP3X_SHARP_BASE + 0x001a4) +#define ISP35_SHARP_MFDETAIL_CLIP (ISP3X_SHARP_BASE + 0x001a8) +#define ISP35_SHARP_SATURATION_STRG0 (ISP3X_SHARP_BASE + 0x001ac) +#define ISP35_SHARP_SATURATION_STRG2 (ISP3X_SHARP_BASE + 0x001b4) #define ISP33_BAY3D_BASE 0x00002B00 #define ISP33_BAY3D_CTRL0 (ISP33_BAY3D_BASE + 0x00000) @@ -1323,6 +1371,13 @@ #define ISP33_BAY3D_MIDBIG2 (ISP33_BAY3D_BASE + 0x00288) #define ISP33_BAY3D_TNRSUM (ISP33_BAY3D_BASE + 0x002d4) #define ISP33_BAY3D_TNRYO0 (ISP33_BAY3D_BASE + 0x002d8) +#define ISP35_BAY3D_PREHI_SIGSCL (ISP33_BAY3D_BASE + 0x00058) +#define ISP35_BAY3D_PREHI_SIGOF (ISP33_BAY3D_BASE + 0x00068) +#define ISP35_BAY3D_LOCOEF0 (ISP33_BAY3D_BASE + 0x001f0) +#define ISP35_BAY3D_LOCOEF1 (ISP33_BAY3D_BASE + 0x001f4) +#define ISP35_BAY3D_DPC0 (ISP33_BAY3D_BASE + 0x001f8) +#define ISP35_BAY3D_DPC1 (ISP33_BAY3D_BASE + 0x001fc) +#define ISP35_BAY3D_MONROFF (ISP33_BAY3D_BASE + 0x0028c) #define ISP3X_BAY3D_BASE 0x00002C00 #define ISP3X_BAY3D_CTRL (ISP3X_BAY3D_BASE + 0x00000) @@ -1594,6 +1649,8 @@ #define ISP32_BLS_ISP_OB_OFFSET (ISP3X_BLS_BASE + 0x00068) #define ISP32_BLS_ISP_OB_PREDGAIN (ISP3X_BLS_BASE + 0x0006c) #define ISP32_BLS_ISP_OB_MAX (ISP3X_BLS_BASE + 0x00070) +#define ISP35_BLS3_AB_FIXED (ISP3X_BLS_BASE + 0x00074) +#define ISP35_BLS3_CD_FIXED (ISP3X_BLS_BASE + 0x00078) #define ISP39_EXPD_BASE 0x00003100 #define ISP39_EXPD_K15 (ISP39_EXPD_BASE + 0x00000) @@ -1902,6 +1959,8 @@ #define ISP3X_HDRMGE_OVER_Y15 (ISP3X_HDRMGE_BASE + 0x000ac) #define ISP3X_HDRMGE_OVER_Y16 (ISP3X_HDRMGE_BASE + 0x000b0) #define ISP32_HDRMGE_EACH_GAIN (ISP3X_HDRMGE_BASE + 0x000b4) +#define ISP35_HDRMGE_FORCE_LONG0 (ISP3X_HDRMGE_BASE + 0x000b8) +#define ISP35_HDRMGE_FORCE_LONG1 (ISP3X_HDRMGE_BASE + 0x000bc) #define ISP3X_DRC_BASE 0x00003900 #define ISP3X_DRC_CTRL0 (ISP3X_DRC_BASE + 0x00000) @@ -1956,6 +2015,7 @@ #define ISP39_DRC_SFTHD_Y6 (ISP3X_DRC_BASE + 0x000a8) #define ISP39_DRC_SFTHD_Y7 (ISP3X_DRC_BASE + 0x000ac) #define ISP39_DRC_SFTHD_Y8 (ISP3X_DRC_BASE + 0x000b0) +#define ISP35_DRC_LUMA_MIX (ISP3X_DRC_BASE + 0x000b4) #define ISP3X_BAYNR_BASE 0x00003A00 #define ISP3X_BAYNR_CTRL (ISP3X_BAYNR_BASE + 0x00000) @@ -2027,6 +2087,11 @@ #define ISP32_LDCH_BIC_TABLE7 (ISP3X_LDCH_BASE + 0x00020) #define ISP32_LDCH_BIC_TABLE8 (ISP3X_LDCH_BASE + 0x00024) #define ISP39_LDCH_OUT_SIZE (ISP3X_LDCH_BASE + 0x00028) +#define ISP35_B3DLDC_CTRL (ISP3X_LDCH_BASE + 0x00080) +#define ISP35_B3DLDC_WR_ADDR (ISP3X_LDCH_BASE + 0x000a8) +#define ISP35_B3DLDC_WR_STRIDE (ISP3X_LDCH_BASE + 0x000ac) +#define ISP35_B3DLDC_ADR_STS (ISP3X_LDCH_BASE + 0x000e0) +#define ISP35_B3DLDC_EXTBOUND1 (ISP3X_LDCH_BASE + 0x000e8) #define ISP3X_DHAZ_BASE 0x00003C00 #define ISP3X_DHAZ_CTRL (ISP3X_DHAZ_BASE + 0x00000) @@ -2220,6 +2285,36 @@ #define ISP33_HSV_UPDATE (ISP33_HSV_BASE + 0x00004) #define ISP33_HSV_1DLUT (ISP33_HSV_BASE + 0x00008) #define ISP33_HSV_2DLUT (ISP33_HSV_BASE + 0x0000c) +#define ISP35_HSV_MODE_CTRL (ISP33_HSV_BASE + 0x00004) +#define ISP35_HSV_1DLUT (ISP33_HSV_BASE + 0x0000c) +#define ISP35_HSV_2DLUT0 (ISP33_HSV_BASE + 0x00010) +#define ISP35_HSV_2DLUT1 (ISP33_HSV_BASE + 0x00014) +#define ISP35_HSV_2DLUT2 (ISP33_HSV_BASE + 0x00018) + +#define ISP35_AWBSYNC_BASE 0x00003E80 +#define ISP35_AWBSYNC_CTRL (ISP35_AWBSYNC_BASE + 0x00000) +#define ISP35_AWBSYNC_SCL (ISP35_AWBSYNC_BASE + 0x00004) +#define ISP35_AWBSYNC_SUMVAL_MIN (ISP35_AWBSYNC_BASE + 0x00008) +#define ISP35_AWBSYNC_SUMVAL_MAX (ISP35_AWBSYNC_BASE + 0x0000C) +#define ISP35_AWBSYNC_WIN0_OFFS (ISP35_AWBSYNC_BASE + 0x00010) +#define ISP35_AWBSYNC_WIN0_RD_COOR (ISP35_AWBSYNC_BASE + 0x00014) +#define ISP35_AWBSYNC_WIN1_OFFS (ISP35_AWBSYNC_BASE + 0x00018) +#define ISP35_AWBSYNC_WIN1_RD_COOR (ISP35_AWBSYNC_BASE + 0x0001C) +#define ISP35_AWBSYNC_WIN2_OFFS (ISP35_AWBSYNC_BASE + 0x00020) +#define ISP35_AWBSYNC_WIN2_RD_COOR (ISP35_AWBSYNC_BASE + 0x00024) +#define ISP35_AWBSYNC_WIN0_SUMR (ISP35_AWBSYNC_BASE + 0x00030) +#define ISP35_AWBSYNC_WIN0_SUMG (ISP35_AWBSYNC_BASE + 0x00034) +#define ISP35_AWBSYNC_WIN0_SUMB (ISP35_AWBSYNC_BASE + 0x00038) +#define ISP35_AWBSYNC_WIN0_SUMP (ISP35_AWBSYNC_BASE + 0x0003C) +#define ISP35_AWBSYNC_WIN1_SUMR (ISP35_AWBSYNC_BASE + 0x00040) +#define ISP35_AWBSYNC_WIN1_SUMG (ISP35_AWBSYNC_BASE + 0x00044) +#define ISP35_AWBSYNC_WIN1_SUMB (ISP35_AWBSYNC_BASE + 0x00048) +#define ISP35_AWBSYNC_WIN1_SUMP (ISP35_AWBSYNC_BASE + 0x0004C) +#define ISP35_AWBSYNC_WIN2_SUMR (ISP35_AWBSYNC_BASE + 0x00050) +#define ISP35_AWBSYNC_WIN2_SUMG (ISP35_AWBSYNC_BASE + 0x00054) +#define ISP35_AWBSYNC_WIN2_SUMB (ISP35_AWBSYNC_BASE + 0x00058) +#define ISP35_AWBSYNC_WIN2_SUMP (ISP35_AWBSYNC_BASE + 0x0005C) +#define ISP35_AWBSYNC_DBG0 (ISP35_AWBSYNC_BASE + 0x00060) #define ISP3X_GAIN_BASE 0x00003F00 #define ISP3X_GAIN_CTRL (ISP3X_GAIN_BASE + 0x00000) @@ -2666,6 +2761,22 @@ #define ISP33_RAWAWB_CCM_COEFF0_B (ISP3X_RAWAWB_BASE + 0x01d0) #define ISP33_RAWAWB_CCM_COEFF1_B (ISP3X_RAWAWB_BASE + 0x01d4) +#define ISP35_AIAWB_BASE 0x00005a00 +#define ISP35_AIAWB_CTRL0 (ISP35_AIAWB_BASE + 0x0000) +#define ISP35_AIAWB_CTRL1 (ISP35_AIAWB_BASE + 0x0004) +#define ISP35_AIAWB_WIN_OFFS (ISP35_AIAWB_BASE + 0x0008) +#define ISP35_AIAWB_WIN_SIZE (ISP35_AIAWB_BASE + 0x000c) +#define ISP35_AIAWB_FLT_COE0 (ISP35_AIAWB_BASE + 0x0010) +#define ISP35_AIAWB_FLT_COE1 (ISP35_AIAWB_BASE + 0x0014) +#define ISP35_AIAWB_WBGAIN_INV0 (ISP35_AIAWB_BASE + 0x0018) +#define ISP35_AIAWB_WBGAIN_INV1 (ISP35_AIAWB_BASE + 0x001c) +#define ISP35_AIAWB_MATRIX_SCALE (ISP35_AIAWB_BASE + 0x0020) +#define ISP35_AIAWB_MATRIX_ROT0 (ISP35_AIAWB_BASE + 0x0024) +#define ISP35_AIAWB_MATRIX_ROT1 (ISP35_AIAWB_BASE + 0x0028) +#define ISP35_AIAWB_WR_BASE (ISP35_AIAWB_BASE + 0x0030) +#define ISP35_AIAWB_WR_BASE_SHD (ISP35_AIAWB_BASE + 0x0034) +#define ISP35_AIAWB_WR_BASE_VIR (ISP35_AIAWB_BASE + 0x0038) + /* VI_ISP_PATH */ #define ISP3X_RAWAE3_SEL(x) (((x) & 3) << 16) #define ISP3X_RAWAF_SEL(x) (((x) & 3) << 18) @@ -2712,8 +2823,11 @@ #define ISP32_MIR_ENABLE BIT(5) #define ISP3X_SW_CGC_YUV_LIMIT BIT(28) #define ISP3X_SW_CGC_RATIO_EN BIT(29) +#define ISP35_ISP_CFG_UPD_FE BIT(31) /* ISP CTRL1 */ +#define ISP35_BAYER_UPD_FE_EN BIT(0) +#define ISP35_BAYER_PAT_FE(x) (((x) & 0x3) << 1) #define ISP39_YUVME_FST_FRAME BIT(18) #define ISP32_SHP_FST_FRAME BIT(19) #define ISP3X_YNR_FST_FRAME BIT(23) @@ -2781,11 +2895,15 @@ #define ISP3X_3A_RAWHIST_CH2 BIT(7) #define ISP3X_3A_RAWAF_SUM BIT(8) #define ISP3X_3A_RAWAF_LUM BIT(9) +#define ISP35_AWBSYNC_DONE BIT(9) #define ISP3X_3A_RAWAF BIT(10) #define ISP3X_3A_RAWAWB BIT(11) #define ISP3X_3A_DDR_DONE BIT(12) +#define ISP35_W3A_ERR BIT(13) +#define ISP35_AIAWB_DONE BIT(14) #define ISP3X_ISP_OUT_LINE(a) ((a) & 0x3fff) +#define ISP3X_ISP_OUT_FRM_CNT(a) (((a) >> 14) & 0x3) #define ISP33_ISP2ENC_FRM_CNT(a) ((a) & 0xff) @@ -2832,12 +2950,31 @@ #define ISP39_LDCV_OUTPUT_YUV422 BIT(3) #define ISP39_LDCV_OUTPUT_YUV420 GENMASK(3, 2) #define ISP39_LDCV_UV_SWAP BIT(4) -#define ISP39_LDCV_LUT_MODE(x) ((x & 0x3) << 24) +#define ISP39_LDCV_LUT_MODE(x) (((x) & 0x3) << 24) #define ISP39_LDCV_FORCE_UPD BIT(26) #define ISP39_LDCV_MAP_ERROR BIT(28) #define ISP39_LDCV_WORKING BIT(30) #define ISP39_LDCV_EN_SHD BIT(31) +/* AI */ +#define ISP35_AIISP_EN BIT(0) +#define ISP35_AIISP_ST BIT(1) +#define ISP35_AIISP_RAW12_MSB BIT(2) +#define ISP35_AIISP_HDR_EN BIT(3) +#define ISP35_AIISP_GIAN_MODE(x) (((x) & 0x3) << 4) +#define ISP35_NPU_CURVE_EN BIT(6) +#define ISP35_AIPRE_IIR_EN BIT(8) +#define ISP35_AIPRE_IIR2DDR_EN BIT(9) +#define ISP35_AIPRE_GAIN_EN BIT(10) +#define ISP35_AIPRE_GIAN2DDR_EN BIT(11) +#define ISP35_AIPRE_YRAW_SEL BIT(12) +#define ISP35_AIPRE_NL_DDR_MODE BIT(13) +#define ISP35_AIPRE_GAIN_BYPASS BIT(14) +#define ISP35_AIPRE_GAIN_MODE BIT(15) +#define ISP35_AIPRE_NARMAP_INV BIT(16) +#define ISP35_AIPRE_LUMA2GAIN_DIS BIT(17) +#define ISP35_AIPRE_ITS_FORCE_UPD BIT(24) + /* mi interrupt */ #define ISP3X_MI_MP_FRAME BIT(0) #define ISP3X_MI_SP_FRAME BIT(1) @@ -2913,6 +3050,8 @@ #define ISP32_MI_OUTPUT_YUV400 0 #define ISP32_MI_OUTPUT_YUV420 BIT(8) #define ISP32_MI_OUTPUT_YUV422 BIT(9) +#define ISP35_MI_MP_TILE BIT(12) +#define ISP35_MI_SP_TILE BIT(13) /* MI_WR_CTRL2_SHD */ #define ISP32_BP_EN_IN_SHD BIT(4) @@ -3019,6 +3158,8 @@ /* CSI2RX */ #define ISP3X_RXSELF_FORCE_UPD BIT(31) +#define ISP35_RXS_FORCE_UPD BIT(31) +#define ISP35_RX0_FORCE_UPD BIT(30) /* DEBAYER */ @@ -3041,6 +3182,7 @@ /* BLS */ #define ISP32_BLS_BLS2_EN BIT(5) +#define ISP35_BLS_BLS3_EN BIT(6) /* BAY3D */ #define ISP32_BAY3D_BWSAVING(a) (((a) & 0x1) << 13) @@ -3053,6 +3195,14 @@ #define ISP3X_LDCH_MAP_ERR BIT(29) #define ISP3X_LDCH_FORCE_UPD BIT(31) +#define ISP35_B3DLDC_EN BIT(0) +#define ISP35_B3DLDC_MAP_ERR BIT(12) +#define ISP35_B3DLDC_LUT_MODE(x) (((x) & 0x3) << 24) +#define ISP35_B3DLDC_FORCE_UPD BIT(26) + +#define ISP35_B3DLDHC_LUT_FRM_END BIT(8) +#define ISP35_B3DLDCH_MAP_ERR BIT(29) + /* DHAZ */ #define ISP3X_DHAZ_ENMUX BIT(0) #define ISP3X_DHAZ_DC_EN BIT(4) @@ -3115,6 +3265,12 @@ #define ISP3X_3DLUT_LUT_MODE(x) (((x) & 0x3) << 24) #define ISP3X_3DLUT_LUT_ERR BIT(29) +#define ISP35_HSV_FIX_RW_CONFLICT BIT(8) +#define ISP35_HSV_AHB_CFG_LUT_EN BIT(9) + +/* AWBSYNC */ +#define ISP35_AWBSYNC_FRM_PROT BIT(1) + /* DEBAYER */ /* LSC */ @@ -3133,6 +3289,9 @@ #define ISP39_W3A_PDAF2DDR_HOLD_DIS BIT(3) #define ISP39_W3A_AUTO_CLR_EN BIT(4) #define ISP39_W3A_CLK_GATING_DIS BIT(5) +#define ISP35_W3A_B3DNROUT_ILG_BYPASS BIT(8) +#define ISP35_W3A_RAWLSC_SEL BIT(9) +#define ISP35_W3A_FORCE_UPD_F BIT(30) #define ISP39_W3A_FORCE_UPD BIT(31) #define ISP39_W3A_INT_AEBIG BIT(0) @@ -3198,4 +3357,12 @@ #define ISP32_RAWAWB_2DDR_PATH_DS BIT(27) #define ISP32_RAWAWB_2DDR_PATH_ERR BIT(29) +#define ISP33_RAWAWB_WRAM_CLR BIT(31) + +/* AIAWB */ +#define ISP35_AIAWB_EN BIT(0) +#define ISP35_AIAWB_FRMEND_UPD_DIS BIT(28) +#define ISP35_AIAWB_SYS_UPD_DIS BIT(29) +#define ISP35_AIAWB_SELF_UPD BIT(30) + #endif /* _RKISP_REGS_V3X_H */ diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 66e87bbc3e37..253bfdfebb31 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -239,13 +239,18 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, max_h = dev->hw_dev->unite ? CIF_ISP_INPUT_H_MAX_V33_UNITE : CIF_ISP_INPUT_H_MAX_V33; break; + case ISP_V35: + max_w = CIF_ISP_INPUT_W_MAX_V35; + max_h = CIF_ISP_INPUT_H_MAX_V35; + break; default: max_w = CIF_ISP_INPUT_W_MAX; max_h = CIF_ISP_INPUT_H_MAX; } max_size = max_w * max_h; w = clamp_t(u32, src_w, CIF_ISP_INPUT_W_MIN, max_w); - max_h = max_size / w; + if (dev->isp_ver != ISP_V35) + max_h = max_size / w; h = clamp_t(u32, src_h, CIF_ISP_INPUT_H_MIN, max_h); if (dev->isp_ver >= ISP_V33) { @@ -628,12 +633,7 @@ static void rkisp_update_list_reg(struct rkisp_device *dev) /* sensor mode & index */ if (dev->isp_ver >= ISP_V21) { val = rkisp_read_reg_cache(dev, ISP_ACQ_H_OFFS); - if (hw->unite == ISP_UNITE_ONE && - dev->isp_ver == ISP_V33 && !dev->is_frm_rd && - dev->unite_index == ISP_UNITE_RIGHT) - index = 1; - else - index = dev->multi_index; + index = dev->multi_index; val |= ISP21_SENSOR_INDEX(index); if (dev->isp_ver >= ISP_V32_L) val |= ISP32L_SENSOR_MODE(dev->multi_mode); @@ -658,7 +658,7 @@ static void rkisp_update_list_reg(struct rkisp_device *dev) rkisp_update_regs(dev, ISP3X_CAC_PSF_PARA, ISP32_CAC_RO_CNT); rkisp_update_regs(dev, ISP_LSC_XGRAD_01, ISP3X_CAC_CTRL); rkisp_update_regs(dev, ISP39_W3A_CTRL1, ISP3X_RAWAWB_RAM_DATA_BASE); - rkisp_update_regs(dev, ISP32_CAC_RO_CNT, ISP39_W3A_CTRL0); + rkisp_update_regs(dev, ISP32_CAC_RO_CNT, ISP39_W3A_CTRL0 - 4); if (dev->isp_ver == ISP_V21) { val = rkisp_read(dev, MI_WR_CTRL2, false); rkisp_set_bits(dev, MI_WR_CTRL2, 0, val, true); @@ -666,11 +666,28 @@ static void rkisp_update_list_reg(struct rkisp_device *dev) } else { if (dev->isp_ver >= ISP_V32_L) rkisp_write(dev, ISP32_SELF_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); - if (dev->isp_ver == ISP_V33 || dev->isp_ver == ISP_V39) { + if (dev->isp_ver >= ISP_V33) { rkisp_write(dev, ISP39_MAIN_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); if (dev->isp_ver == ISP_V33) rkisp_write(dev, ISP33_BP_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); } + if (dev->isp_ver == ISP_V35) { + rkisp_update_regs(dev, ISP35_AIAWB_CTRL1, ISP35_AIAWB_WR_BASE_VIR); + val = rkisp_read(dev, ISP35_AIAWB_CTRL0, false); + if (val & ISP35_AIAWB_EN) { + val |= ISP35_AIAWB_SELF_UPD; + writel(val, hw->base_addr + ISP35_AIAWB_CTRL0); + } + if (rkisp_read(dev, ISP39_W3A_CTRL0, false) & ISP39_W3A_EN) { + val = rkisp_read(dev, ISP3X_SWS_CFG, false); + val |= ISP3X_3A_DDR_WRITE_EN; + writel(val, hw->base_addr + ISP3X_SWS_CFG); + } + } + if (dev->isp_ver >= ISP_V33) { + val = rkisp_read(dev, ISP39_W3A_CTRL0, false); + writel(val, hw->base_addr + ISP39_W3A_CTRL0); + } rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true); } v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, @@ -914,7 +931,7 @@ run_next: /* disable isp force update to read 3dlut * 3dlut auto update at frame end for single sensor */ - if (hw->is_single && is_upd && + if (hw->is_single && is_upd && hw->isp_ver < ISP_V33 && rkisp_read_reg_cache(dev, ISP_3DLUT_UPDATE) & 0x1) { rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 0, true); is_3dlut_upd = true; @@ -960,6 +977,13 @@ run_next: udelay(25); } + if (hw->isp_ver == ISP_V35) { + val = rkisp_read_reg_cache(dev, ISP3X_CSI2RX_RAW_RD_CTRL); + val |= ISP35_RXS_FORCE_UPD; + if (dev->rd_mode == HDR_RDBK_FRAME2) + val |= ISP35_RX0_FORCE_UPD; + writel(val, hw->base_addr + ISP3X_CSI2RX_RAW_RD_CTRL); + } val = rkisp_read(dev, CSI2RX_CTRL0, true); val &= ~SW_IBUF_OP_MODE(0xf); tmp = SW_IBUF_OP_MODE(dev->rd_mode); @@ -1445,7 +1469,7 @@ static void rkisp_config_ism(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, height / mult, false); if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32 || - dev->isp_ver == ISP_V33) + dev->isp_ver >= ISP_V33) return; /* IS(Image Stabilization) is always on, working as output crop */ @@ -1457,8 +1481,7 @@ static int rkisp_reset_handle(struct rkisp_device *dev) u32 val; dev_info(dev->dev, "%s enter\n", __func__); - if (dev->isp_ver == ISP_V39 && dev->sditf_dev && dev->sditf_dev->is_on) - rkisp_sditf_reset_notify_vpss(dev); + rkisp_sditf_reset_notify_vpss(dev); rkisp_hw_reg_save(dev->hw_dev); rkisp_soft_reset(dev->hw_dev, true); @@ -2919,6 +2942,9 @@ static void rkisp_isp_sd_try_crop(struct v4l2_subdev *sd, case ISP_V33: size = CIF_ISP_INPUT_W_MAX_V33 * CIF_ISP_INPUT_H_MAX_V33; break; + case ISP_V35: + size = CIF_ISP_INPUT_W_MAX_V35 * CIF_ISP_INPUT_H_MAX_V35; + break; case ISP_V39: size = CIF_ISP_INPUT_W_MAX_V39_UNITE * CIF_ISP_INPUT_H_MAX_V39_UNITE; size /= 2; @@ -3006,6 +3032,10 @@ static int rkisp_isp_sd_get_selection(struct v4l2_subdev *sd, max_h = dev->hw_dev->unite ? CIF_ISP_INPUT_H_MAX_V33_UNITE : CIF_ISP_INPUT_H_MAX_V33; break; + case ISP_V35: + max_w = CIF_ISP_INPUT_W_MAX_V35; + max_h = CIF_ISP_INPUT_H_MAX_V35; + break; case ISP_V39: max_w = dev->hw_dev->unite ? CIF_ISP_INPUT_W_MAX_V39_UNITE : CIF_ISP_INPUT_W_MAX_V39; @@ -3765,7 +3795,8 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, isp_dev->is_suspend_one_frame = false; if (vicap_mode->rdbk_mode < RKISP_VICAP_RDBK_AIQ) { - if (!hw->is_single && hw->isp_ver != ISP_V33) + if (!hw->is_single && + hw->isp_ver != ISP_V33 && hw->isp_ver != ISP_V35) return -EINVAL; /* switch to online mode for single sensor */ switch (rd_mode) { @@ -3802,13 +3833,15 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, rkisp_unite_write(isp_dev, CSI2RX_CTRL0, SW_IBUF_OP_MODE(isp_dev->rd_mode), true); mask = SW_MPIP_DROP_FRM_DIS; - if (isp_dev->isp_ver == ISP_V33) + if (isp_dev->isp_ver == ISP_V33 || isp_dev->isp_ver == ISP_V35) mask |= ISP33_SW_ISP2ENC_PATH_EN | ISP33_PP_ENC_PIPE_EN; if (IS_HDR_RDBK(isp_dev->rd_mode)) { val = SW_MPIP_DROP_FRM_DIS; - if (isp_dev->isp_ver == ISP_V33 && isp_dev->cap_dev.wrap_line) + if (isp_dev->cap_dev.wrap_line && + (isp_dev->isp_ver == ISP_V33 || isp_dev->isp_ver == ISP_V35)) val = ISP33_SW_ISP2ENC_PATH_EN | ISP33_PP_ENC_PIPE_EN; - } else if (isp_dev->isp_ver == ISP_V33 && isp_dev->cap_dev.wrap_line) { + } else if (isp_dev->cap_dev.wrap_line && + (isp_dev->isp_ver == ISP_V33 || isp_dev->isp_ver == ISP_V35)) { val = ISP33_SW_ISP2ENC_PATH_EN; } else { val = 0; @@ -4027,7 +4060,8 @@ static int rkisp_set_online_hdr_wrap(struct rkisp_device *dev, int *line) "hdr wrap no support for offline\n"); return -EINVAL; } - if (dev->isp_ver != ISP_V33 || dev->unite_div != ISP_UNITE_DIV1) { + if (dev->unite_div != ISP_UNITE_DIV1 || + (dev->isp_ver != ISP_V33 && dev->isp_ver != ISP_V35)) { v4l2_warn(&dev->v4l2_dev, "hdr wrap support for 1103b and no unite mode\n"); return -EINVAL; @@ -4142,8 +4176,6 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct rkisp_device *isp_dev = sd_to_isp_dev(sd); struct rkisp_thunderboot_resmem *resmem; - struct rkisp32_thunderboot_resmem_head *tb_head_v32; - struct rkisp33_thunderboot_resmem_head *tb_head_v33; struct rkisp_thunderboot_resmem_head *head; struct rkisp_thunderboot_shmem *shmem; struct isp2x_buf_idxfd *idxfd; @@ -4164,31 +4196,29 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) rkisp_get_info(isp_dev, arg); break; case RKISP_CMD_GET_TB_HEAD_V32: - if (isp_dev->tb_head.complete != RKISP_TB_OK || - (!isp_dev->is_rtt_suspend && !isp_dev->is_pre_on)) { - ret = -EINVAL; - break; - } - tb_head_v32 = arg; - memcpy(tb_head_v32, &isp_dev->tb_head, - sizeof(struct rkisp_thunderboot_resmem_head)); - memcpy(&tb_head_v32->cfg, isp_dev->params_vdev.isp32_params, - sizeof(struct isp32_isp_params_cfg)); - break; case RKISP_CMD_GET_TB_HEAD_V33: + case RKISP_CMD_GET_TB_HEAD: if (isp_dev->tb_head.complete != RKISP_TB_OK || (!isp_dev->is_rtt_suspend && !isp_dev->is_pre_on)) { ret = -EINVAL; break; } - tb_head_v33 = arg; - memcpy(tb_head_v33, &isp_dev->tb_head, + memcpy(arg, &isp_dev->tb_head, sizeof(struct rkisp_thunderboot_resmem_head)); - memcpy(&tb_head_v33->cfg, isp_dev->params_vdev.isp33_params, - sizeof(struct isp33_isp_params_cfg)); + if (cmd != RKISP_CMD_GET_TB_HEAD_V32 && cmd != RKISP_CMD_GET_TB_HEAD_V33) + break; + if (cmd == RKISP_CMD_GET_TB_HEAD_V32) + memcpy(arg + sizeof(struct rkisp_thunderboot_resmem_head), + isp_dev->params_vdev.isp32_params, + sizeof(struct isp32_isp_params_cfg)); + else + memcpy(arg + sizeof(struct rkisp_thunderboot_resmem_head), + isp_dev->params_vdev.isp33_params, + sizeof(struct isp33_isp_params_cfg)); break; case RKISP_CMD_SET_TB_HEAD_V32: case RKISP_CMD_SET_TB_HEAD_V33: + case RKISP_CMD_SET_TB_HEAD: memcpy(&isp_dev->tb_head, arg, sizeof(struct rkisp_thunderboot_resmem_head)); break; @@ -4325,6 +4355,9 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKISP_VICAP_CMD_SOF: ret = rkisp_vicap_sof(isp_dev, arg); break; + case RKISP_CMD_AIAWB_BUF: + ret = rkisp_params_get_aiawb_buffd(&isp_dev->params_vdev, arg); + break; default: ret = -ENOIOCTLCMD; } @@ -4435,6 +4468,11 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd, size = sizeof(struct rkisp_fpn_cfg); cp_f_us = true; break; + case RKISP_CMD_AIAWB_BUF: + size = sizeof(struct rkisp_aiawb_buffd); + cp_f_us = true; + cp_t_us = true; + break; default: return -ENOIOCTLCMD; } @@ -4636,6 +4674,8 @@ void rkisp_save_tb_info(struct rkisp_device *isp_dev) offset = size * isp_dev->dev_id; break; default: + size = sizeof(struct rkisp_thunderboot_resmem_head); + offset = size * isp_dev->dev_id; break; } @@ -4664,6 +4704,8 @@ void rkisp_save_tb_info(struct rkisp_device *isp_dev) tmp->cfg.module_en_update, tmp->cfg.module_ens, tmp->cfg.module_cfg_update); + } else { + head = resmem_va + offset; } if (param && (isp_dev->isp_state & ISP_STOP)) { params_vdev->ops->get_param_size(params_vdev, @@ -4691,8 +4733,7 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) if (!isp_dev->is_thunderboot) return; - if (params_vdev->is_first_cfg && - (isp_dev->isp_ver == ISP_V32 || isp_dev->isp_ver == ISP_V33)) + if (params_vdev->is_first_cfg) goto end; resmem_va = phys_to_virt(isp_dev->resmem_pa); @@ -4930,7 +4971,7 @@ void rkisp_isp_isr(unsigned int isp_mis, /* disabled frame end to read 3dlut for multi sensor * 3dlut will update at isp readback */ - if (!dev->hw_dev->is_single) { + if (!dev->hw_dev->is_single && dev->isp_ver < ISP_V33) { writel(0, hw->base_addr + ISP_3DLUT_UPDATE); if (hw->unite == ISP_UNITE_TWO) writel(0, hw->base_next_addr + ISP_3DLUT_UPDATE); diff --git a/drivers/media/platform/rockchip/isp/rkisp.h b/drivers/media/platform/rockchip/isp/rkisp.h index 60a12dc2b284..10628ac096dc 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.h +++ b/drivers/media/platform/rockchip/isp/rkisp.h @@ -71,6 +71,8 @@ #define CIF_ISP_INPUT_H_MAX_V33 1620 #define CIF_ISP_INPUT_W_MAX_V33_UNITE 3840 #define CIF_ISP_INPUT_H_MAX_V33_UNITE 2160 +#define CIF_ISP_INPUT_W_MAX_V35 4096 +#define CIF_ISP_INPUT_H_MAX_V35 3072 #define CIF_ISP_INPUT_W_MIN 272 #define CIF_ISP_INPUT_H_MIN 264 #define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX diff --git a/include/soc/rockchip/rockchip_rockit.h b/include/soc/rockchip/rockchip_rockit.h index 4f0ff242a7ad..f960615771ac 100644 --- a/include/soc/rockchip/rockchip_rockit.h +++ b/include/soc/rockchip/rockchip_rockit.h @@ -125,7 +125,9 @@ struct rockit_rkcif_cfg { int (*rkcif_rockit_mpibuf_done)(struct rockit_rkcif_cfg *rockit_cif_cfg); }; -#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) || \ +IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) || \ +IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) void *rkisp_rockit_function_register(void *function, int cmd); int rkisp_rockit_get_ispdev(char **name); diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index 8ebaca078367..9dce8dc2ed35 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -91,6 +91,15 @@ #define RKISP_CMD_INIT_BNR_BUF \ _IOWR('V', BASE_VIDIOC_PRIVATE + 26, struct rkisp_bnr_buf_info) + +#define RKISP_CMD_GET_TB_HEAD \ + _IOR('V', BASE_VIDIOC_PRIVATE + 27, struct rkisp_thunderboot_resmem_head) +#define RKISP_CMD_SET_TB_HEAD \ + _IOW('V', BASE_VIDIOC_PRIVATE + 28, struct rkisp_thunderboot_resmem_head) + +#define RKISP_CMD_AIAWB_BUF \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 29, struct rkisp_aiawb_buffd) + /****************ISP VIDEO IOCTL******************************/ #define RKISP_CMD_GET_CSI_MEMORY_MODE \ @@ -141,6 +150,7 @@ /* BASE_VIDIOC_PRIVATE + 115 for RKISP_CMD_GET_PARAMS_V39 */ /* BASE_VIDIOC_PRIVATE + 116 for RKISP_CMD_GET_PARAMS_V33 */ /* BASE_VIDIOC_PRIVATE + 117 for RKISP_CMD_SET_QUICK_STREAM */ +/* BASE_VIDIOC_PRIVATE + 119 for RKISP_CMD_GET_PARAMS_V35 */ /* frame information attach to image tail, see struct rkisp_frame_info * set this before VIDIOC_REQBUFS then VIDIOC_QUERYBUF to get buf size @@ -330,6 +340,21 @@ struct rkisp_buf_info { int buf_fd[RKISP_BUFFER_MAX]; } __attribute__ ((packed)); +enum rkisp_aiawb_ds { + RKISP_AIAWB_DS_4X4, + RKISP_AIAWB_DS_8X4, + RKISP_AIAWB_DS_8X8, + RKISP_AIAWB_DS_16X16, +}; + +/* struct rkisp_aiawb_buffd + * set aiawb buf count and get buf fd result + */ +struct rkisp_aiawb_buffd { + enum rkisp_aiawb_ds ds; + struct rkisp_buf_info info; +} __attribute__ ((packed)); + enum rkisp_isp_mode { /* frame input related */ RKISP_ISP_NORMAL = _BITUL(0), @@ -372,6 +397,7 @@ struct rkisp_meshbuf_size { struct isp2x_mesh_head { enum isp2x_mesh_buf_stat stat; __u32 data_oft; + __u32 data1_oft; } __attribute__ ((packed)); enum { diff --git a/include/uapi/linux/rk-isp35-config.h b/include/uapi/linux/rk-isp35-config.h new file mode 100644 index 000000000000..3e63aa605c5c --- /dev/null +++ b/include/uapi/linux/rk-isp35-config.h @@ -0,0 +1,1751 @@ +/* SPDX-License-Identifier: (GPL-2.0+ WITH Linux-syscall-note) OR MIT + * + * Rockchip ISP35 + * Copyright (C) 2025 Rockchip Electronics Co., Ltd. + */ + +#ifndef _UAPI_RK_ISP35_CONFIG_H +#define _UAPI_RK_ISP35_CONFIG_H + +#include +#include +#include + +#define RKISP_CMD_GET_PARAMS_V35 \ + _IOR('V', BASE_VIDIOC_PRIVATE + 119, struct isp35_isp_params_cfg) + +#define ISP35_MODULE_DPCC ISP3X_MODULE_DPCC +#define ISP35_MODULE_BLS ISP3X_MODULE_BLS +#define ISP35_MODULE_SDG ISP3X_MODULE_SDG +#define ISP35_MODULE_LSC ISP3X_MODULE_LSC +#define ISP35_MODULE_AWB_GAIN ISP3X_MODULE_AWB_GAIN +#define ISP35_MODULE_BDM ISP3X_MODULE_BDM +#define ISP35_MODULE_CCM ISP3X_MODULE_CCM +#define ISP35_MODULE_GOC ISP3X_MODULE_GOC +#define ISP35_MODULE_CPROC ISP3X_MODULE_CPROC +#define ISP35_MODULE_IE ISP3X_MODULE_IE +#define ISP35_MODULE_RAWAF ISP3X_MODULE_RAWAF +#define ISP35_MODULE_RAWAE0 ISP3X_MODULE_RAWAE0 +#define ISP35_MODULE_RAWAE1 ISP3X_MODULE_RAWAE1 +#define ISP35_MODULE_RAWAE2 ISP3X_MODULE_RAWAE2 +#define ISP35_MODULE_RAWAE3 ISP3X_MODULE_RAWAE3 +#define ISP35_MODULE_RAWAWB ISP3X_MODULE_RAWAWB +#define ISP35_MODULE_RAWHIST0 ISP3X_MODULE_RAWHIST0 +#define ISP35_MODULE_RAWHIST1 ISP3X_MODULE_RAWHIST1 +#define ISP35_MODULE_RAWHIST2 ISP3X_MODULE_RAWHIST2 +#define ISP35_MODULE_RAWHIST3 ISP3X_MODULE_RAWHIST3 +#define ISP35_MODULE_HDRMGE ISP3X_MODULE_HDRMGE +#define ISP35_MODULE_RAWNR ISP3X_MODULE_RAWNR +#define ISP35_MODULE_GIC ISP3X_MODULE_GIC +#define ISP35_MODULE_DHAZ ISP3X_MODULE_DHAZ +#define ISP35_MODULE_3DLUT ISP3X_MODULE_3DLUT +#define ISP35_MODULE_LDCH ISP3X_MODULE_LDCH +#define ISP35_MODULE_GAIN ISP3X_MODULE_GAIN +#define ISP35_MODULE_DEBAYER ISP3X_MODULE_DEBAYER +#define ISP35_MODULE_BAYNR ISP3X_MODULE_BAYNR +#define ISP35_MODULE_BAY3D ISP3X_MODULE_BAY3D +#define ISP35_MODULE_YNR ISP3X_MODULE_YNR +#define ISP35_MODULE_CNR ISP3X_MODULE_CNR +#define ISP35_MODULE_SHARP ISP3X_MODULE_SHARP +#define ISP35_MODULE_DRC ISP3X_MODULE_DRC +#define ISP35_MODULE_CAC ISP3X_MODULE_CAC +#define ISP35_MODULE_CSM ISP3X_MODULE_CSM +#define ISP35_MODULE_CGC ISP3X_MODULE_CGC +#define ISP35_MODULE_RGBIR ISP39_MODULE_RGBIR +#define ISP35_MODULE_HSV ISP33_MODULE_HSV +#define ISP35_MODULE_ENH ISP33_MODULE_ENH +#define ISP35_MODULE_HIST ISP33_MODULE_HIST +#define ISP35_MODULE_AI BIT_ULL(51) +#define ISP35_MODULE_AIAWB BIT_ULL(52) +#define ISP35_MODULE_AWBSYNC BIT_ULL(53) + +#define ISP35_MODULE_FORCE ISP3X_MODULE_FORCE + +/* Measurement types */ +#define ISP35_STAT_RAWAWB ISP3X_STAT_RAWAWB +#define ISP35_STAT_RAWAF ISP3X_STAT_RAWAF +#define ISP35_STAT_RAWAE0 ISP3X_STAT_RAWAE0 +#define ISP35_STAT_RAWAE3 ISP3X_STAT_RAWAE3 +#define ISP35_STAT_RAWHST0 ISP3X_STAT_RAWHST0 +#define ISP35_STAT_RAWHST3 ISP3X_STAT_RAWHST3 +#define ISP35_STAT_INFO2DDR ISP33_STAT_INFO2DDR +#define ISP35_STAT_BAY3D ISP33_STAT_BAY3D +#define ISP35_STAT_ENH ISP33_STAT_ENH +#define ISP35_STAT_HIST ISP33_STAT_HIST +#define ISP35_STAT_SHARP ISP33_STAT_SHARP +#define ISP35_STAT_AIAWB BIT(24) +#define ISP35_STAT_AWBSYNC BIT(25) +#define ISP35_STAT_RTT_FST ISP33_STAT_RTT_FST + +#define ISP35_MESH_BUF_NUM ISP3X_MESH_BUF_NUM + +#define ISP35_LSC_GRAD_TBL_SIZE ISP3X_LSC_GRAD_TBL_SIZE +#define ISP35_LSC_SIZE_TBL_SIZE ISP3X_LSC_SIZE_TBL_SIZE +#define ISP35_LSC_DATA_TBL_SIZE ISP3X_LSC_DATA_TBL_SIZE + +#define ISP35_DEGAMMA_CURVE_SIZE ISP3X_DEGAMMA_CURVE_SIZE + +#define ISP35_GAIN_IDX_NUM ISP3X_GAIN_IDX_NUM +#define ISP35_GAIN_LUT_NUM ISP3X_GAIN_LUT_NUM + +#define ISP35_RAWAWB_WEIGHT_NUM ISP3X_RAWAWB_WEIGHT_NUM +#define ISP35_RAWAWB_HSTBIN_NUM ISP3X_RAWAWB_HSTBIN_NUM +#define ISP35_RAWAWB_SUM_NUM 4 +#define ISP35_RAWAWB_EXCL_STAT_NUM 4 + +#define ISP35_RAWAEBIG_SUBWIN_NUM 2 + +#define ISP35_RAWHIST_WEIGHT_NUM 225 + +#define ISP35_RAWAF_CURVE_NUM ISP3X_RAWAF_CURVE_NUM +#define ISP35_RAWAF_HIIR_COE_NUM ISP3X_RAWAF_HIIR_COE_NUM +#define ISP35_RAWAF_VFIR_COE_NUM ISP3X_RAWAF_VFIR_COE_NUM +#define ISP35_RAWAF_WIN_NUM ISP3X_RAWAF_WIN_NUM +#define ISP35_RAWAF_LINE_NUM ISP3X_RAWAF_LINE_NUM +#define ISP35_RAWAF_GAMMA_NUM ISP3X_RAWAF_GAMMA_NUM +#define ISP35_RAWAF_SUMDATA_NUM ISP3X_RAWAF_SUMDATA_NUM +#define ISP35_RAWAF_VIIR_COE_NUM 3 +#define ISP35_RAWAF_GAUS_COE_NUM 9 + +#define ISP35_DPCC_PDAF_POINT_NUM ISP3X_DPCC_PDAF_POINT_NUM + +#define ISP35_HDRMGE_WGT_NUM 17 + +#define ISP35_GIC_SIGMA_Y_NUM ISP33_GIC_SIGMA_Y_NUM +#define ISP35_GIC_LUMA_DX_NUM ISP33_GIC_LUMA_DX_NUM +#define ISP35_GIC_THRED_Y_NUM ISP33_GIC_THRED_Y_NUM + +#define ISP35_CCM_CURVE_NUM 18 +#define ISP35_CCM_HF_FACTOR_NUM 17 + +#define ISP35_HSV_1DLUT_NUM ISP33_HSV_1DLUT_NUM +#define ISP35_HSV_2DLUT_ROW ISP33_HSV_2DLUT_ROW +#define ISP35_HSV_2DLUT_COL ISP33_HSV_2DLUT_COL + +#define ISP35_LDCH_BIC_NUM ISP33_LDCH_BIC_NUM + +#define ISP35_GAMMA_OUT_MAX_SAMPLES ISP3X_GAMMA_OUT_MAX_SAMPLES + +#define ISP35_ENH_LUMA_NUM ISP33_ENH_LUMA_NUM +#define ISP35_ENH_DETAIL_NUM ISP33_ENH_DETAIL_NUM +#define ISP35_ENH_IIR_ROW_MAX ISP33_ENH_IIR_ROW_MAX +#define ISP35_ENH_IIR_COL_MAX ISP33_ENH_IIR_COL_MAX + +#define ISP35_HIST_ALPHA_NUM ISP33_HIST_ALPHA_NUM +#define ISP35_HIST_THUMB_ROW_MAX ISP33_HIST_THUMB_ROW_MAX +#define ISP35_HIST_THUMB_COL_MAX ISP33_HIST_THUMB_COL_MAX +#define ISP35_HIST_IIR_NUM ISP33_HIST_IIR_NUM +#define ISP35_HIST_IIR_BLK_MAX ISP33_HIST_IIR_BLK_MAX + +#define ISP35_DRC_Y_NUM ISP3X_DRC_Y_NUM + +#define ISP35_CNR_SIGMA_Y_NUM ISP3X_CNR_SIGMA_Y_NUM +#define ISP35_CNR_GAUS_COE_NUM 6 +#define ISP35_CNR_GAUS_SIGMAR_NUM 8 +#define ISP35_CNR_WGT_SIGMA_Y_NUM 13 +#define ISP35_CNR_CURVE_NUM 10 + +#define ISP35_YNR_XY_NUM ISP3X_YNR_XY_NUM +#define ISP35_YNR_HI_GAUS1_COE_NUM ISP33_YNR_HI_GAUS1_COE_NUM +#define ISP35_YNR_ADJ_NUM ISP33_YNR_ADJ_NUM +#define ISP35_YNR_HI_GAUS_COE_NUM 4 +#define ISP35_YNR_TEX2WGT_NUM 9 + +#define ISP35_BAY3D_XY_NUM 16 +#define ISP35_BAY3D_TNRSIG_NUM 20 +#define ISP35_BAY3D_LPF_COEFF_NUM 9 +#define ISP35_BAY3D_FILT_COEFF_NUM 6 + +#define ISP35_AI_SIGMA_NUM 33 + +#define ISP35_SHARP_X_NUM ISP33_SHARP_X_NUM +#define ISP35_SHARP_Y_NUM ISP33_SHARP_Y_NUM +#define ISP35_SHARP_KERNEL_NUM ISP33_SHARP_KERNEL_NUM +#define ISP35_SHARP_EDGE_KERNEL_NUM ISP33_SHARP_EDGE_KERNEL_NUM +#define ISP35_SHARP_EDGE_WGT_NUM ISP33_SHARP_EDGE_WGT_NUM +#define ISP35_SHARP_LUMA_STRG_NUM ISP33_SHARP_LUMA_STRG_NUM +#define ISP35_SHARP_CONTRAST_STRG_NUM ISP33_SHARP_CONTRAST_STRG_NUM +#define ISP35_SHARP_TEX_CLIP_NUM ISP33_SHARP_TEX_CLIP_NUM +#define ISP35_SHARP_LUM_CLIP_NUM ISP33_SHARP_LUM_CLIP_NUM +#define ISP35_SHARP_HUE_NUM ISP33_SHARP_HUE_NUM +#define ISP35_SHARP_DISATANCE_NUM ISP33_SHARP_DISATANCE_NUM +#define ISP35_SHARP_TEX_NUM ISP33_SHARP_HITEX_NUM +#define ISP35_SHARP_NOISE_CURVE_NUM ISP33_SHARP_NOISE_CURVE_NUM +#define ISP35_SHARP_SATURATION_NUM 9 +#define ISP35_SHARP_LOCAL_STRG_NUM 4 + +#define ISP35_CAC_PSF_NUM ISP33_CAC_PSF_NUM + +#define ISP35_CSM_COEFF_NUM ISP3X_CSM_COEFF_NUM + +#define ISP35_DEBAYER_LUMA_NUM 7 +#define ISP35_DEBAYER_DRCT_OFFSET_NUM 8 +#define ISP35_DEBAYER_VSIGMA_NUM 8 + +#define ISP35_RGBIR_SCALE_NUM 4 +#define ISP35_RGBIR_LUMA_POINT_NUM 17 +#define ISP35_RGBIR_SCALE_MAP_NUM 17 + +#define ISP35_MEAN_BLK_X_NUM 15 +#define ISP35_MEAN_BLK_Y_NUM 15 + +#define ISP35_AIAWB_FLT_COE_NUM 5 + +#define ISP35_AWBSYNC_WIN_MAX 3 + +struct isp35_bls_cfg { + __u8 enable_auto; + __u8 en_windows; + __u8 bls1_en; + + __u8 bls_samples; + + struct isp2x_window bls_window1; + struct isp2x_window bls_window2; + struct isp2x_bls_fixed_val fixed_val; + struct isp2x_bls_fixed_val bls1_val; + + __u16 isp_ob_offset; + __u16 isp_ob_offset1; + __u16 isp_ob_predgain; + __u32 isp_ob_max; +} __attribute__ ((packed)); + +struct isp35_hdrmge_cfg { + /* CTRL */ + __u8 short_base_en; + __u8 frame_mode; + __u8 dbg_mode; + __u8 channel_detection_en; + __u8 s_base_mode; + /* GAIN0 */ + __u16 short_gain; + __u16 short_inv_gain; + /* GAIN1 */ + __u16 medium_gain; + __u16 medium_inv_gain; + /* GAIN2 */ + __u8 long_gain; + /* LIGHTZ */ + __u8 ms_diff_scale; + __u8 ms_diff_offset; + __u8 lm_diff_scale; + __u8 lm_diff_offset; + /* MS_DIFF */ + __u16 ms_abs_diff_scale; + __u16 ms_abs_diff_thred_min_limit; + __u16 ms_adb_diff_thred_max_limit; + /* LM_DIFF */ + __u16 lm_abs_diff_scale; + __u16 lm_abs_diff_thred_min_limit; + __u16 lm_abs_diff_thred_max_limit; + /* DIFF_Y */ + __u16 ms_luma_diff2wgt[ISP35_HDRMGE_WGT_NUM]; + __u16 lm_luma_diff2wgt[ISP35_HDRMGE_WGT_NUM]; + /* OVER_Y */ + __u16 luma2wgt[ISP35_HDRMGE_WGT_NUM]; + __u16 ms_raw_diff2wgt[ISP35_HDRMGE_WGT_NUM]; + __u16 lm_raw_diff2wgt[ISP35_HDRMGE_WGT_NUM]; + /* EACH_GAIN */ + __u16 channel_detn_short_gain; + __u16 channel_detn_medium_gain; + /* FORCE_LONG0 */ + __u16 mid_luma_scale; + /* FORCE_LONG1 */ + __u16 mid_luma_thred_max_limit; + __u16 mid_luma_thred_min_limit; +} __attribute__ ((packed)); + +struct isp35_hsv_cfg { + __u8 hsv_1dlut0_en; + __u8 hsv_1dlut1_en; + __u8 hsv_2dlut0_en; + __u8 hsv_2dlut1_en; + __u8 hsv_2dlut2_en; + __u8 hsv_2dlut12_cfg; + + __u8 hsv_1dlut0_idx_mode; + __u8 hsv_1dlut1_idx_mode; + __u8 hsv_2dlut0_idx_mode; + __u8 hsv_2dlut1_idx_mode; + __u8 hsv_2dlut2_idx_mode; + __u8 hsv_1dlut0_item_mode; + __u8 hsv_1dlut1_item_mode; + __u8 hsv_2dlut0_item_mode; + __u8 hsv_2dlut1_item_mode; + __u8 hsv_2dlut2_item_mode; + + __u16 lut0_1d[ISP35_HSV_1DLUT_NUM]; + __u16 lut1_1d[ISP35_HSV_1DLUT_NUM]; + __u16 lut0_2d[ISP35_HSV_2DLUT_ROW][ISP35_HSV_2DLUT_COL]; + __u16 lut1_2d[ISP35_HSV_2DLUT_ROW][ISP35_HSV_2DLUT_COL]; + __u16 lut2_2d[ISP35_HSV_2DLUT_ROW][ISP35_HSV_2DLUT_COL]; +} __attribute__ ((packed)); + +struct isp35_debayer_cfg { + /* CONTROL */ + __u8 bypass; + __u8 g_out_flt_en; + __u8 cnt_flt_en; + /* LUMA_DX */ + __u8 luma_dx[ISP35_DEBAYER_LUMA_NUM]; + /* G_INTERP */ + __u8 g_interp_clip_en; + __u8 hi_texture_thred; + __u8 hi_drct_thred; + __u8 lo_drct_thred; + __u8 drct_method_thred; + __u8 g_interp_sharp_strg_max_limit; + /* G_INTERP_FILTER1 */ + __s8 lo_drct_flt_coeff1; + __s8 lo_drct_flt_coeff2; + __s8 lo_drct_flt_coeff3; + __s8 lo_drct_flt_coeff4; + /* G_INTERP_FILTER2 */ + __s8 hi_drct_flt_coeff1; + __s8 hi_drct_flt_coeff2; + __s8 hi_drct_flt_coeff3; + __s8 hi_drct_flt_coeff4; + /* G_INTERP_OFFSET_ALPHA */ + __u16 g_interp_sharp_strg_offset; + __u8 grad_lo_flt_alpha; + /* G_INTERP_DRCT_OFFSET */ + __u16 drct_offset[ISP35_DEBAYER_DRCT_OFFSET_NUM]; + /* G_FILTER_MODE_OFFSET */ + __u8 gflt_mode; + __u16 gflt_ratio; + __u16 gflt_offset; + /* G_FILTER_FILTER */ + __s8 gflt_coe0; + __s8 gflt_coe1; + __s8 gflt_coe2; + /* G_FILTER_VSIGMA */ + __u16 gflt_vsigma[ISP35_DEBAYER_VSIGMA_NUM]; + /* C_FILTER_GUIDE_GAUS */ + __u8 cnr_lo_guide_lpf_coe0; + __u8 cnr_lo_guide_lpf_coe1; + __u8 cnr_lo_guide_lpf_coe2; + /* C_FILTER_CE_GAUS */ + __u8 cnr_pre_flt_coe0; + __u8 cnr_pre_flt_coe1; + __u8 cnr_pre_flt_coe2; + /* C_FILTER_ALPHA_GAUS */ + __u8 cnr_alpha_lpf_coe0; + __u8 cnr_alpha_lpf_coe1; + __u8 cnr_alpha_lpf_coe2; + /* C_FILTER_LOG_OFFSET */ + __u16 cnr_log_grad_offset; + __u16 cnr_log_guide_offset; + __u8 cnr_trans_en; + /* C_FILTER_ALPHA */ + __u16 cnr_moire_alpha_offset; + __u32 cnr_moire_alpha_scale; + /* C_FILTER_EDGE */ + __u16 cnr_edge_alpha_offset; + __u32 cnr_edge_alpha_scale; + /* C_FILTER_IIR_0 */ + __u8 cnr_lo_flt_strg_inv; + __u8 cnr_lo_flt_strg_shift; + __u16 cnr_lo_flt_wgt_slope; + /* C_FILTER_IIR_1 */ + __u8 cnr_lo_flt_wgt_max_limit; + __u8 cnr_lo_flt_wgt_min_thred; + /* C_FILTER_BF */ + __u16 cnr_hi_flt_vsigma; + __u8 cnr_hi_flt_wgt_min_limit; + __u8 cnr_hi_flt_cur_wgt; +} __attribute__ ((packed)); + +struct isp35_bay3d_cfg { + /* BAY3D_CTRL */ + __u8 bypass_en; + __u8 iir_wr_src; + __u8 out_use_pre_mode; + __u8 motion_est_en; + __u8 iir_rw_fmt; + /* BAY3D_CTRL1 */ + __u8 transf_bypass_en; + __u8 tnrsigma_curve_double_en; + __u8 md_large_lo_use_mode; + __u8 md_large_lo_min_filter_bypass_en; + __u8 md_large_lo_gauss_filter_bypass_en; + __u8 md_large_lo_md_wgt_bypass_en; + __u8 pre_pix_out_mode; + __u8 motion_detect_bypass_en; + __u8 lpf_hi_bypass_en; + __u8 lo_diff_vfilt_bypass_en; + __u8 lpf_lo_bypass_en; + __u8 lo_wgt_hfilt_en; + __u8 lo_diff_hfilt_en; + __u8 sig_hfilt_en; + __u8 lo_detection_bypass_en; + __u8 lo_mge_wgt_mode; + __u8 pre_spnr_out_en; + __u8 md_only_lo_en; + __u8 cur_spnr_out_en; + __u8 md_wgt_out_en; + /* BAY3D_CTRL2 */ + __u8 cur_spnr_filter_bypass_en; + __u8 pre_spnr_hi_filter_gic_en; + __u8 pre_spnr_hi_filter_gic_enhance_en; + __u8 spnr_presigma_use_en; + __u8 pre_spnr_lo_filter_bypass_en; + __u8 pre_spnr_hi_filter_bypass_en; + __u8 pre_spnr_sigma_curve_double_en; + __u8 pre_spnr_hi_guide_filter_bypass_en; + __u8 pre_spnr_sigma_idx_filt_bypass_en; + __u8 pre_spnr_sigma_idx_filt_mode; + __u8 pre_spnr_hi_noise_ctrl_en; + __u8 pre_spnr_hi_filter_wgt_mode; + __u8 pre_spnr_lo_filter_wgt_mode; + __u8 pre_spnr_hi_filter_rb_wgt_mode; + __u8 pre_spnr_lo_filter_rb_wgt_mode; + __u8 pre_hi_gic_lp_en; + __u8 pre_hi_bf_lp_en; + __u8 pre_lo_avg_lp_en; + __u8 pre_spnr_dpc_flt_en; + __u8 pre_spnr_dpc_nr_bal_mode; + __u8 pre_spnr_dpc_flt_mode; + __u8 pre_spnr_dpc_flt_prewgt_en; + /* BAY3D_CTRL3 */ + __u8 transf_mode; + __u8 wgt_cal_mode; + __u8 mge_wgt_ds_mode; + __u8 kalman_wgt_ds_mode; + __u8 mge_wgt_hdr_sht_thred; + __u8 sigma_calc_mge_wgt_hdr_sht_thred; + /* BAY3D_TRANS0 */ + __u16 transf_mode_offset; + __u8 transf_mode_scale; + __u16 itransf_mode_offset; + /* BAY3D_TRANS1 */ + __u32 transf_data_max_limit; + /* BAY3D_PREHI_SIGSCL */ + __u16 pre_spnr_sigma_ctrl_scale; + /* BAY3D_PREHI_SIGOF */ + __u8 pre_spnr_hi_guide_out_wgt; + /* BAY3D_CURHISPW */ + __u8 cur_spnr_filter_coeff[ISP35_BAY3D_FILT_COEFF_NUM]; + /* BAY3D_IIRSX */ + __u16 pre_spnr_luma2sigma_x[ISP35_BAY3D_XY_NUM]; + /* BAY3D_IIRSY */ + __u16 pre_spnr_luma2sigma_y[ISP35_BAY3D_XY_NUM]; + /* BAY3D_PREHI_SIGSCL */ + __u16 pre_spnr_hi_sigma_scale; + /* BAY3D_PREHI_WSCL */ + __u8 pre_spnr_hi_wgt_calc_scale; + /* BAY3D_PREHIWMM */ + __u8 pre_spnr_hi_filter_wgt_min_limit; + __u8 pre_spnr_hi_wgt_calc_offset; + /* BAY3D_PREHISIGOF */ + __u8 pre_spnr_hi_filter_out_wgt; + __u8 pre_spnr_sigma_offset; + __u8 pre_spnr_sigma_hdr_sht_offset; + /* BAY3D_PREHISIGSCL */ + __u16 pre_spnr_sigma_scale; + __u16 pre_spnr_sigma_hdr_sht_scale; + /* BAY3D_PREHISPW */ + __u8 pre_spnr_hi_filter_coeff[ISP35_BAY3D_FILT_COEFF_NUM]; + /* BAY3D_PRELOSIGCSL */ + __u16 pre_spnr_lo_sigma_scale; + /* BAY3D_PRELOSIGOF */ + __u8 pre_spnr_lo_wgt_calc_offset; + __u8 pre_spnr_lo_wgt_calc_scale; + /* BAY3D_PREHI_NRCT */ + __u16 pre_spnr_hi_noise_ctrl_scale; + __u8 pre_spnr_hi_noise_ctrl_offset; + /* BAY3D_TNRSX */ + __u16 tnr_luma2sigma_x[ISP35_BAY3D_TNRSIG_NUM]; + /* BAY3D_TNRSY */ + __u16 tnr_luma2sigma_y[ISP35_BAY3D_TNRSIG_NUM]; + /* BAY3D_HIWD */ + __u16 lpf_hi_coeff[ISP35_BAY3D_LPF_COEFF_NUM]; + /* BAY3D_LOWD */ + __u16 lpf_lo_coeff[ISP35_BAY3D_LPF_COEFF_NUM]; + /* BAY3D_GF */ + __u8 sigma_idx_filt_coeff[ISP35_BAY3D_FILT_COEFF_NUM]; + __u16 lo_wgt_cal_first_line_sigma_scale; + /* BAY3D_VIIR */ + __u8 lo_diff_vfilt_wgt; + __u8 lo_wgt_vfilt_wgt; + __u8 sig_first_line_scale; + __u8 lo_diff_first_line_scale; + /* BAY3D_LFSCL */ + __u16 lo_wgt_cal_offset; + __u16 lo_wgt_cal_scale; + /* BAY3D_LFSCLTH */ + __u16 lo_wgt_cal_max_limit; + __u16 mode0_base_ratio; + /* BAY3D_DSWGTSCL */ + __u16 lo_diff_wgt_cal_offset; + __u16 lo_diff_wgt_cal_scale; + /* BAY3D_WGTLASTSCL */ + __u16 lo_mge_pre_wgt_offset; + __u16 lo_mge_pre_wgt_scale; + /* BAY3D_WGTSCL0 */ + __u16 mode0_lo_wgt_scale; + __u16 mode0_lo_wgt_hdr_sht_scale; + /* BAY3D_WGTSCL1 */ + __u16 mode1_lo_wgt_scale; + __u16 mode1_lo_wgt_hdr_sht_scale; + /* BAY3D_WGTSCL2 */ + __u16 mode1_wgt_scale; + __u16 mode1_wgt_hdr_sht_scale; + /* BAY3D_WGTOFF */ + __u16 mode1_lo_wgt_offset; + __u16 mode1_lo_wgt_hdr_sht_offset; + /* BAY3D_WGT1OFF */ + __u16 auto_sigma_count_wgt_thred; + __u16 mode1_wgt_min_limit; + __u16 mode1_wgt_offset; + /* BAY3D_SIGORG */ + __u32 tnr_out_sigma_sq; + /* BAY3D_WGTLO_L */ + __u16 lo_wgt_clip_min_limit; + __u16 lo_wgt_clip_hdr_sht_min_limit; + /* BAY3D_WGTLO_H */ + __u16 lo_wgt_clip_max_limit; + __u16 lo_wgt_clip_hdr_sht_max_limit; + /* BAY3D_STH_SCL */ + __u16 lo_pre_gg_soft_thresh_scale; + __u16 lo_pre_rb_soft_thresh_scale; + /* BAY3D_STH_LIMIT */ + __u16 lo_pre_soft_thresh_max_limit; + __u16 lo_pre_soft_thresh_min_limit; + /* BAY3D_HIKEEP */ + __u8 cur_spnr_hi_wgt_min_limit; + __u8 pre_spnr_hi_wgt_min_limit; + __u16 motion_est_lo_wgt_thred; + /* BAY3D_PIXMAX */ + __u16 pix_max_limit; + /* BAY3D_SIGNUMTH */ + __u32 sigma_num_th; + /* BAY3D_MONR */ + __u16 out_use_hi_noise_bal_nr_strg; + __u16 out_use_md_noise_bal_nr_strg; + __u8 gain_out_max_limit; + /* BAY3D_SIGSCL */ + __u16 sigma_scale; + __u16 sigma_hdr_sht_scale; + /* BAY3D_DSOFF */ + __u16 lo_wgt_vfilt_offset; + __u16 lo_diff_vfilt_offset; + __u8 lo_wgt_cal_first_line_vfilt_wgt; + /* BAY3D_DSSCL */ + __u8 lo_wgt_vfilt_scale; + __u8 lo_diff_vfilt_scale_bit; + __u8 lo_diff_vfilt_scale; + __u8 lo_diff_first_line_vfilt_wgt; + /* BAY3D_ME0 */ + __u16 motion_est_up_mvx_cost_offset; + __u16 motion_est_up_mvx_cost_scale; + __u8 motion_est_sad_vert_wgt0; + /* BAY3D_ME1 */ + __u16 motion_est_up_left_mvx_cost_offset; + __u16 motion_est_up_left_mvx_cost_scale; + __u8 motion_est_sad_vert_wgt1; + /* BAY3D_ME2 */ + __u16 motion_est_up_right_mvx_cost_offset; + __u16 motion_est_up_right_mvx_cost_scale; + __u8 motion_est_sad_vert_wgt2; + /* BAY3D_WGTMAX */ + __u16 lo_wgt_clip_motion_max_limit; + /* BAY3D_WGT1MAX */ + __u16 mode1_wgt_max_limit; + /* BAY3D_WGTM0 */ + __u16 mode0_wgt_out_max_limit; + __u16 mode0_wgt_out_offset; + /* BAY3D_LOCOEF0 */ + __u8 lo_wgt_hflt_coeff2; + __u8 lo_wgt_hflt_coeff1; + __u8 lo_wgt_hflt_coeff0; + __u8 sig_hflt_coeff2; + __u8 sig_hflt_coeff1; + __u8 sig_hflt_coeff0; + /* BAY3D_LOCOEF1 */ + __u8 lo_dif_hflt_coeff2; + __u8 lo_dif_hflt_coeff1; + __u8 lo_dif_hflt_coeff0; + /* BAY3D_DPC0 */ + __u8 pre_spnr_dpc_bright_str; + __u8 pre_spnr_dpc_dark_str; + __u8 pre_spnr_dpc_str; + __u8 pre_spnr_dpc_wk_scale; + __u8 pre_spnr_dpc_wk_offset; + /* BAY3D_DPC1 */ + __u16 pre_spnr_dpc_nr_bal_str; + __u16 pre_spnr_dpc_soft_thr_scale; + /* BAY3D_PRELOWGT */ + __u8 pre_spnr_lo_val_wgt_out_wgt; + __u8 pre_spnr_lo_filter_out_wgt; + __u8 pre_spnr_lo_filter_wgt_min; + /* BAY3D_MIDBIG0 */ + __u8 md_large_lo_md_wgt_offset; + __u16 md_large_lo_md_wgt_scale; + /* BAY3D_MIDBIG1 */ + __u16 md_large_lo_wgt_cut_offset; + __u16 md_large_lo_wgt_add_offset; + /* BAY3D_MIDBIG2 */ + __u16 md_large_lo_wgt_scale; + /* BAY3D_MONROFF */ + __u16 out_use_hi_noise_bal_nr_off; + __u16 out_use_md_noise_bal_nr_off; + + /* B3DLDC_CTRL */ + __u8 btnr_ldc_en; + __u8 b3dldcv_map13p3_en; + __u8 b3dldcv_force_map_en; + /* B3DLDC_ADR_STS */ + __u8 b3dldch_en; + __u8 b3dldch_map13p3_en; + __u8 b3dldch_force_map_en; + /* B3DLDC_EXTBOUND1 */ + __u8 btnr_ldcltp_mode; + __u16 btnr_ldc_wrap_ext_bound_offset; + /* lut_ldch:offset data_oft; lut_ldcv:offset data1_oft */ + __s32 lut_buf_fd; +} __attribute__ ((packed)); + +struct isp35_ai_cfg { + /* CTRL */ + __u8 aiisp_raw12_msb; + __u8 aiisp_gain_mode; + __u8 aiisp_curve_en; + __u8 aipre_iir_en; + __u8 aipre_iir2ddr_en; + __u8 aipre_gain_en; + __u8 aipre_gain2ddr_en; + __u8 aipre_luma2gain_dis; + __u8 aipre_nl_ddr_mode; + __u8 aipre_yraw_sel; + __u8 aipre_gain_bypass; + __u8 aipre_gain_mode; + __u8 aipre_narmap_inv; + /* SIGMA_Y */ + __u16 aiisp_sigma_y[ISP35_AI_SIGMA_NUM]; + /* AIPRE_NL_PRE */ + __u8 aipre_scale; + __u8 aipre_zp; + __u16 aipre_black_lvl; + /* AIPRE_GAIN_PARA */ + __u8 aipre_gain_alpha; + __u8 aipre_global_gain; + __u16 aipre_gain_ratio; + /* AIPRE_SIGMA_CURVE */ + __u16 aipre_sigma_y[ISP35_AI_SIGMA_NUM]; + /* AIPRE_NOISE0 */ + __u8 aipre_noise_mot_offset; + __u8 aipre_noise_mot_gain; + __u16 aipre_noise_luma_offset; + /* AIPRE_NOISE1 */ + __u16 aipre_noise_luma_gain; + __u16 aipre_noise_luma_clip; + __u8 aipre_noise_luma_static; + /* AIPRE_NOISE2 */ + __u8 aipre_nar_manual; + __u8 aipre_nar_manual_alpha; +} __attribute__ ((packed)); + +struct isp35_ynr_cfg { + /* GLOBAL_CTRL */ + __u8 hi_spnr_bypass; + __u8 mi_spnr_bypass; + __u8 lo_spnr_bypass; + __u8 rnr_en; + __u8 tex2lo_strg_en; + __u8 hi_lp_en; + __u8 dsfilt_bypass; + __u8 tex2wgt_en; + /* GAIN_CTRL */ + __u16 global_set_gain; + __u8 gain_merge_alpha; + __u8 local_gain_scale; + /* GAIN_ADJ */ + __u16 lo_spnr_gain2strg[ISP35_YNR_ADJ_NUM]; + /* RNR_MAX_R */ + __u16 rnr_max_radius; + /* RNR_CENTER_COOR */ + __u16 rnr_center_h; + __u16 rnr_center_v; + /* RNR_STRENGTH */ + __u8 radius2strg[ISP35_YNR_XY_NUM]; + /* SGM_DX */ + __u16 luma2sima_x[ISP35_YNR_XY_NUM]; + /* SGM_Y */ + __u16 luma2sima_y[ISP35_YNR_XY_NUM]; + /* MI_TEX2WGT_SCALE */ + __u8 mi_spnr_tex2wgt_scale[ISP35_YNR_TEX2WGT_NUM]; + /* LO_TEX2WGT_SCALE */ + __u8 lo_spnr_tex2wgt_scale[ISP35_YNR_TEX2WGT_NUM]; + /* HI_SIGMA_GAIN */ + __u16 hi_spnr_sigma_min_limit; + __u8 hi_spnr_local_gain_alpha; + __u16 hi_spnr_strg; + /* HI_GAUS_COE */ + __u8 hi_spnr_filt_coeff[ISP35_YNR_HI_GAUS_COE_NUM]; + /* HI_WEIGHT */ + __u16 hi_spnr_filt_wgt_offset; + __u16 hi_spnr_filt_center_wgt; + /* HI_GAUS1_COE */ + __u16 hi_spnr_filt1_coeff[ISP35_YNR_HI_GAUS1_COE_NUM]; + /* HI_TEXT */ + __u16 hi_spnr_filt1_tex_thred; + __u16 hi_spnr_filt1_tex_scale; + __u16 hi_spnr_filt1_wgt_alpha; + /* MI_GAUS_COE */ + __u8 mi_spnr_filt_coeff0; + __u8 mi_spnr_filt_coeff1; + __u8 mi_spnr_filt_coeff2; + __u8 mi_spnr_filt_coeff3; + __u8 mi_spnr_filt_coeff4; + /* MI_STRG_DETAIL */ + __u16 mi_spnr_strg; + __u16 mi_spnr_soft_thred_scale; + /* MI_WEIGHT */ + __u8 mi_spnr_wgt; + __u8 mi_ehance_scale_en; + __u8 mi_ehance_scale; + __u16 mi_spnr_filt_center_wgt; + /* DSIIR_COE */ + __u16 dsfilt_diff_offset; + __u16 dsfilt_center_wgt; + __u16 dsfilt_strg; + /* LO_STRG_DETAIL */ + __u16 lo_spnr_strg; + __u16 lo_spnr_soft_thred_scale; + /* LO_LIMIT_SCALE */ + __u16 lo_spnr_thumb_thred_scale; + __u16 tex2lo_strg_mantissa; + __u8 tex2lo_strg_exponent; + /* LO_WEIGHT */ + __u8 lo_spnr_wgt; + __u16 lo_spnr_filt_center_wgt; + __u8 lo_enhance_scale; + /* LO_TEXT_THRED */ + __u16 tex2lo_strg_upper_thred; + __u16 tex2lo_strg_lower_thred; + /* FUSION_WEIT_ADJ */ + __u8 lo_gain2wgt[ISP35_YNR_ADJ_NUM]; +} __attribute__ ((packed)); + +struct isp35_cnr_cfg { + /* CNR_CTRL */ + __u8 exgain_bypass; + __u8 yuv422_mode; + __u8 thumb_mode; + __u8 uv_dis; + __u8 hiflt_wgt0_mode; + __u8 local_alpha_dis; + __u8 loflt_coeff; + __u8 hsv_alpha_en; + /* CNR_EXGAIN */ + __u16 global_gain; + __u8 global_gain_alpha; + __u8 local_gain_scale; + /* CNR_THUMB1 */ + __u16 lobfflt_vsigma_uv; + __u16 lobfflt_vsigma_y; + /* CNR_THUMB_BF_RATIO */ + __u16 lobfflt_alpha; + /* CNR_LBF_WEITD */ + __u8 thumb_bf_coeff0; + __u8 thumb_bf_coeff1; + __u8 thumb_bf_coeff2; + __u8 thumb_bf_coeff3; + /* CNR_IIR_PARA1 */ + __u8 loflt_uv_gain; + __u8 loflt_vsigma; + __u8 exp_x_shift_bit; + __u16 loflt_wgt_slope; + /* CNR_IIR_PARA2 */ + __u8 loflt_wgt_min_thred; + __u8 loflt_wgt_max_limit; + /* CNR_GAUS_COE */ + __u8 gaus_flt_coeff[ISP35_CNR_GAUS_COE_NUM]; + /* CNR_GAUS_RATIO */ + __u16 gaus_flt_alpha; + __u8 hiflt_wgt_min_limit; + __u16 hiflt_alpha; + /* CNR_BF_PARA1 */ + __u8 hiflt_uv_gain; + __u16 hiflt_global_vsigma; + __u8 hiflt_cur_wgt; + /* CNR_BF_PARA2 */ + __u16 adj_offset; + __u16 adj_scale; + /* CNR_SIGMA */ + __u8 sgm_ratio[ISP35_CNR_SIGMA_Y_NUM]; + __u16 bf_merge_max_limit; + /* CNR_IIR_GLOBAL_GAIN */ + __u8 loflt_global_sgm_ratio; + __u8 loflt_global_sgm_ratio_alpha; + __u16 bf_alpha_max_limit; + /* CNR_WGT_SIGMA */ + __u8 cur_wgt[ISP35_CNR_WGT_SIGMA_Y_NUM]; + /* GAUS_X_SIGMAR */ + __u16 hiflt_vsigma_idx[ISP35_CNR_GAUS_SIGMAR_NUM]; + /* GAUS_Y_SIGMAR */ + __u16 hiflt_vsigma[ISP35_CNR_GAUS_SIGMAR_NUM]; + /* IIR_SIGMAR */ + __u8 lo_flt_vsigma[ISP35_CNR_WGT_SIGMA_Y_NUM]; + /* HSV_CURVE */ + __u8 hsv_adj_alpha_table[ISP35_CNR_CURVE_NUM]; + /* SAT_CURVE */ + __u8 sat_adj_alpha_table[ISP35_CNR_CURVE_NUM]; + /* GAIN_ADJ_CURVE */ + __u8 gain_adj_alpha_table[ISP35_CNR_CURVE_NUM]; +} __attribute__ ((packed)); + +struct isp35_sharp_cfg { + /* ctrl */ + __u8 bypass; + __u8 local_gain_bypass; + __u8 tex_est_mode; + __u8 max_min_flt_mode; + __u8 detail_fusion_wgt_mode; + __u8 noise_calc_mode; + __u8 radius_step_mode; + __u8 noise_curve_mode; + __u8 gain_wgt_mode; + __u8 detail_lp_en; + __u8 debug_mode; + /* TEXTURE0 */ + __u16 fst_noise_scale; + __u16 fst_sigma_scale; + /* TEXTURE1 */ + __u16 fst_sigma_offset; + __u16 fst_wgt_scale; + /* TEXTURE2 */ + __u8 tex_wgt_mode; + __u8 noise_est_alpha; + /* TEXTURE3 */ + __u16 sec_noise_scale; + __u16 sec_sigma_scale; + /* TEXTURE4 */ + __u16 sec_sigma_offset; + __u16 sec_wgt_scale; + /* HPF_KERNEL */ + __u8 img_hpf_coeff[ISP35_SHARP_KERNEL_NUM]; + /* TEXFLT_KERNEL */ + __u8 texWgt_flt_coeff0; + __u8 texWgt_flt_coeff1; + __u8 texWgt_flt_coeff2; + /* DETAIL0 */ + __u8 detail_in_alpha; + __u8 pre_bifilt_alpha; + __u8 fusion_wgt_min_limit; + __u8 fusion_wgt_max_limit; + __u16 pre_bifilt_slope_fix; + /* LUMA_DX */ + __u8 luma_dx[ISP35_SHARP_X_NUM]; + /* PBF_VSIGMA */ + __u16 pre_bifilt_vsigma_inv[ISP35_SHARP_Y_NUM]; + /* PBF_KERNEL */ + __u8 pre_bifilt_coeff0; + __u8 pre_bifilt_coeff1; + __u8 pre_bifilt_coeff2; + /* DETAIL_KERNEL */ + __u8 hi_detail_lpf_coeff[ISP35_SHARP_KERNEL_NUM]; + __u8 mi_detail_lpf_coeff[ISP35_SHARP_KERNEL_NUM]; + /* GAIN */ + __u16 global_gain; + __u8 gain_merge_alpha; + __u8 local_gain_scale; + /* GAIN_ADJ0 */ + __u8 edge_gain_max_limit; + __u8 edge_gain_min_limit; + __u8 detail_gain_max_limit; + __u8 detail_gain_min_limit; + /* GAIN_ADJ1 */ + __u8 hitex_gain_max_limit; + __u8 hitex_gain_min_limit; + /* GAIN_ADJ2 */ + __u8 edge_gain_slope; + __u8 detail_gain_slope; + __u8 hitex_gain_slope; + /* GAIN_ADJ3 */ + __u16 edge_gain_offset; + __u16 detail_gain_offset; + __u16 hitex_gain_offset; + /* GAIN_ADJ4 */ + __u16 edge_gain_sigma; + __u16 detail_gain_sigma; + /* EDGE0 */ + __u16 pos_edge_wgt_scale; + __u16 neg_edge_wgt_scale; + /* EDGE1 */ + __u8 pos_edge_strg; + __u8 neg_edge_strg; + __u8 overshoot_alpha; + __u8 undershoot_alpha; + /* EDGE_KERNEL */ + __u8 edge_bpf_coeff[ISP35_SHARP_EDGE_KERNEL_NUM]; + /* EDGE_WGT_VAL */ + __u16 edge_wgt_val[ISP35_SHARP_EDGE_WGT_NUM]; + /* LUMA_ADJ_STRG */ + __u8 luma2strg[ISP35_SHARP_LUMA_STRG_NUM]; + /* CENTER */ + __u16 center_x; + __u16 center_y; + /* OUT_LIMIT */ + __u16 flat_max_limit; + __u16 edge_min_limit; + /* TEX_X_INV_FIX */ + __u32 tex_x_inv_fix0; + __u32 tex_x_inv_fix1; + __u32 tex_x_inv_fix2; + /* LOCAL_STRG */ + __u16 tex2loss_tex_in_hinr_strg[ISP35_SHARP_LOCAL_STRG_NUM]; + /* DETAIL_SCALE_TAB */ + __u8 contrast2pos_strg[ISP35_SHARP_CONTRAST_STRG_NUM]; + __u8 contrast2neg_strg[ISP35_SHARP_CONTRAST_STRG_NUM]; + __u8 pos_detail_strg; + __u8 neg_detail_strg; + /* DETAIL_TEX_CLIP */ + __u16 tex2detail_pos_clip[ISP35_SHARP_TEX_CLIP_NUM]; + __u16 tex2detail_neg_clip[ISP35_SHARP_TEX_CLIP_NUM]; + /* GRAIN_TEX_CLIP */ + __u16 tex2grain_pos_clip[ISP35_SHARP_TEX_CLIP_NUM]; + __u16 tex2grain_neg_clip[ISP35_SHARP_TEX_CLIP_NUM]; + /* DETAIL_LUMA_CLIP */ + __u16 luma2detail_pos_clip[ISP35_SHARP_LUM_CLIP_NUM]; + __u16 luma2detail_neg_clip[ISP35_SHARP_LUM_CLIP_NUM]; + /* GRAIN_STRG */ + __u8 grain_strg; + /* HUE_ADJ_TAB */ + __u16 hue2strg[ISP35_SHARP_HUE_NUM]; + /* DISATANCE_ADJ */ + __u8 distance2strg[ISP35_SHARP_DISATANCE_NUM]; + /* TEX2DETAIL_STRG */ + __u16 tex2detail_strg[ISP35_SHARP_TEX_NUM]; + /* NOISE_SIGMA */ + __u16 hi_tex_threshold[ISP35_SHARP_TEX_NUM]; + /* TEX2MFDETAIL_STRG */ + __u16 tex2mf_detail_strg[ISP35_SHARP_TEX_NUM]; + /* LOSSTEXINHINR_STRG */ + __u8 loss_tex_in_hinr_strg; + /* NOISE_CURVE */ + __u16 noise_curve_ext[ISP35_SHARP_NOISE_CURVE_NUM]; + __u8 noise_count_thred_ratio; + __u8 noise_clip_scale; + /* NOISE_CLIP */ + __u16 noise_clip_min_limit; + __u16 noise_clip_max_limit; + /* EDGEWGTFLT_KERNEL */ + __u8 edge_wgt_flt_coeff0; + __u8 edge_wgt_flt_coeff1; + __u8 edge_wgt_flt_coeff2; + /* EDGE_GLOBAL_CLIP */ + __u16 edge_glb_clip_thred; + __u16 pos_edge_clip; + __u16 neg_edge_clip; + /* MFDETAIL */ + __u8 mf_detail_data_alpha; + __u8 pos_mf_detail_strg; + __u8 neg_mf_detail_strg; + /* MFDETAIL_CLIP */ + __u16 mf_detail_pos_clip; + __u16 sharp_mf_detail_neg_clip; + /* SATURATION_STRG */ + __u8 staturation2strg[ISP35_SHARP_SATURATION_NUM]; + __u16 lo_saturation_strg; +} __attribute__ ((packed)); + +struct isp35_drc_cfg { + /* DRC_CTRL0 */ + __u8 bypass_en; + __u8 cmps_byp_en; + __u8 gainx32_en; + /* DRC_CTRL1 */ + __u16 gain_idx_luma_scale; + __u16 comps_idx_luma_scale; + __u8 log_transform_offset_bits; + /* DRC_LPRATIO */ + __u16 lo_detail_ratio; + __u16 hi_detail_ratio; + __u8 adj_gain_idx_luma_scale; + /* DRC_BILAT0 */ + __u8 bifilt_wgt_offset; + __u16 thumb_thred_neg; + __u8 thumb_thred_en; + __u8 bifilt_cur_pixel_wgt; + /* DRC_BILAT1 */ + __u8 cmps_offset_bits; + __u8 cmps_mode; + __u16 filt_luma_soft_thred; + /* DRC_BILAT2 */ + __u16 thumb_max_limit; + __u8 thumb_scale; + /* DRC_BILAT3 */ + __u16 hi_range_inv_sigma; + __u16 lo_range_inv_sigma; + /* DRC_BILAT4 */ + __u8 bifilt_wgt; + __u8 bifilt_hi_wgt; + __u16 bifilt_soft_thred; + __u8 bifilt_soft_thred_en; + /* DRC_GAIN_Y */ + __u16 gain_y[ISP35_DRC_Y_NUM]; + /* DRC_COMPRES_Y */ + __u16 compres_y[ISP35_DRC_Y_NUM]; + /* DRC_SCALE_Y */ + __u16 scale_y[ISP35_DRC_Y_NUM]; + /* IIRWG_GAIN */ + __u16 comps_gain_min_limit; + /* SFTHD_Y */ + __u16 sfthd_y[ISP35_DRC_Y_NUM]; + /* LUMA_MIX */ + __u8 max_luma_wgt; + __u8 mid_luma_wgt; + __u8 min_luma_wgt; +} __attribute__ ((packed)); + +struct isp35_rawawb_meas_cfg { + __u8 bls2_en; + + __u8 rawawb_sel; + __u8 bnr2awb_sel; + __u8 drc2awb_sel; + /* RAWAWB_CTRL */ + __u8 uv_en0; + __u8 xy_en0; + __u8 yuv3d_en0; + __u8 yuv3d_ls_idx0; + __u8 yuv3d_ls_idx1; + __u8 yuv3d_ls_idx2; + __u8 yuv3d_ls_idx3; + __u8 in_rshift_to_12bit_en; + __u8 in_overexposure_check_en; + __u8 wind_size; + __u8 rawlsc_bypass_en; + __u8 light_num; + __u8 uv_en1; + __u8 xy_en1; + __u8 yuv3d_en1; + __u8 low12bit_val; + /* RAWAWB_BLK_CTRL */ + __u8 blk_measure_enable; + __u8 blk_measure_mode; + __u8 blk_measure_xytype; + __u8 blk_rtdw_measure_en; + __u8 blk_measure_illu_idx; + __u8 ds16x8_mode_en; + __u8 blk_with_luma_wei_en; + __u8 ovexp_2ddr_dis; + __u8 bnr_be_sel; + __u16 in_overexposure_threshold; + /* RAWAWB_WIN_OFFS */ + __u16 h_offs; + __u16 v_offs; + /* RAWAWB_WIN_SIZE */ + __u16 h_size; + __u16 v_size; + /* RAWAWB_LIMIT_RG_MAX*/ + __u16 r_max; + __u16 g_max; + /* RAWAWB_LIMIT_BY_MAX */ + __u16 b_max; + __u16 y_max; + /* RAWAWB_LIMIT_RG_MIN */ + __u16 r_min; + __u16 g_min; + /* RAWAWB_LIMIT_BY_MIN */ + __u16 b_min; + __u16 y_min; + /* RAWAWB_WEIGHT_CURVE_CTRL */ + __u8 wp_luma_wei_en0; + __u8 wp_luma_wei_en1; + __u8 wp_blk_wei_en0; + __u8 wp_blk_wei_en1; + __u8 wp_hist_xytype; + /* RAWAWB_YWEIGHT_CURVE_XCOOR03 */ + __u8 wp_luma_weicurve_y0; + __u8 wp_luma_weicurve_y1; + __u8 wp_luma_weicurve_y2; + __u8 wp_luma_weicurve_y3; + /* RAWAWB_YWEIGHT_CURVE_XCOOR47 */ + __u8 wp_luma_weicurve_y4; + __u8 wp_luma_weicurve_y5; + __u8 wp_luma_weicurve_y6; + __u8 wp_luma_weicurve_y7; + /* RAWAWB_YWEIGHT_CURVE_XCOOR8 */ + __u8 wp_luma_weicurve_y8; + /* RAWAWB_YWEIGHT_CURVE_YCOOR03 */ + __u8 wp_luma_weicurve_w0; + __u8 wp_luma_weicurve_w1; + __u8 wp_luma_weicurve_w2; + __u8 wp_luma_weicurve_w3; + /* RAWAWB_YWEIGHT_CURVE_YCOOR47 */ + __u8 wp_luma_weicurve_w4; + __u8 wp_luma_weicurve_w5; + __u8 wp_luma_weicurve_w6; + __u8 wp_luma_weicurve_w7; + /* RAWAWB_YWEIGHT_CURVE_YCOOR8 */ + __u8 wp_luma_weicurve_w8; + __u16 pre_wbgain_inv_r; + /* RAWAWB_PRE_WBGAIN_INV */ + __u16 pre_wbgain_inv_g; + __u16 pre_wbgain_inv_b; + /* RAWAWB_UV_DETC_VERTEX0_0 */ + __u16 vertex0_u_0; + __u16 vertex0_v_0; + /* RAWAWB_UV_DETC_VERTEX1_0 */ + __u16 vertex1_u_0; + __u16 vertex1_v_0; + /* RAWAWB_UV_DETC_VERTEX2_0 */ + __u16 vertex2_u_0; + __u16 vertex2_v_0; + /* RAWAWB_UV_DETC_VERTEX3_0 */ + __u16 vertex3_u_0; + __u16 vertex3_v_0; + /* RAWAWB_UV_DETC_ISLOPE01_0 */ + __u32 islope01_0; + /* RAWAWB_UV_DETC_ISLOPE12_0 */ + __u32 islope12_0; + /* RAWAWB_UV_DETC_ISLOPE23_0 */ + __u32 islope23_0; + /* RAWAWB_UV_DETC_ISLOPE30_0 */ + __u32 islope30_0; + /* RAWAWB_UV_DETC_VERTEX0_1 */ + __u16 vertex0_u_1; + __u16 vertex0_v_1; + /* RAWAWB_UV_DETC_VERTEX1_1 */ + __u16 vertex1_u_1; + __u16 vertex1_v_1; + /* RAWAWB_UV_DETC_VERTEX2_1 */ + __u16 vertex2_u_1; + __u16 vertex2_v_1; + /* RAWAWB_UV_DETC_VERTEX3_1 */ + __u16 vertex3_u_1; + __u16 vertex3_v_1; + /* RAWAWB_UV_DETC_ISLOPE01_1 */ + __u32 islope01_1; + /* RAWAWB_UV_DETC_ISLOPE12_1 */ + __u32 islope12_1; + /* RAWAWB_UV_DETC_ISLOPE23_1 */ + __u32 islope23_1; + /* RAWAWB_UV_DETC_ISLOPE30_1 */ + __u32 islope30_1; + /* RAWAWB_UV_DETC_VERTEX0_2 */ + __u16 vertex0_u_2; + __u16 vertex0_v_2; + /* RAWAWB_UV_DETC_VERTEX1_2 */ + __u16 vertex1_u_2; + __u16 vertex1_v_2; + /* RAWAWB_UV_DETC_VERTEX2_2 */ + __u16 vertex2_u_2; + __u16 vertex2_v_2; + /* RAWAWB_UV_DETC_VERTEX3_2 */ + __u16 vertex3_u_2; + __u16 vertex3_v_2; + /* RAWAWB_UV_DETC_ISLOPE01_2 */ + __u32 islope01_2; + /* RAWAWB_UV_DETC_ISLOPE12_2 */ + __u32 islope12_2; + /* RAWAWB_UV_DETC_ISLOPE23_2 */ + __u32 islope23_2; + /* RAWAWB_UV_DETC_ISLOPE30_2 */ + __u32 islope30_2; + /* RAWAWB_UV_DETC_VERTEX0_3 */ + __u16 vertex0_u_3; + __u16 vertex0_v_3; + /* RAWAWB_UV_DETC_VERTEX1_3 */ + __u16 vertex1_u_3; + __u16 vertex1_v_3; + /* RAWAWB_UV_DETC_VERTEX2_3 */ + __u16 vertex2_u_3; + __u16 vertex2_v_3; + /* RAWAWB_UV_DETC_VERTEX3_3 */ + __u16 vertex3_u_3; + __u16 vertex3_v_3; + /* RAWAWB_UV_DETC_ISLOPE01_3 */ + __u32 islope01_3; + /* RAWAWB_UV_DETC_ISLOPE12_3 */ + __u32 islope12_3; + /* RAWAWB_UV_DETC_ISLOPE23_3 */ + __u32 islope23_3; + /* RAWAWB_UV_DETC_ISLOPE30_3 */ + __u32 islope30_3; + /* RAWAWB_YUV_RGB2ROTY_0 */ + __u16 rgb2ryuvmat0_y; + __u16 rgb2ryuvmat1_y; + /* RAWAWB_YUV_RGB2ROTY_1 */ + __u16 rgb2ryuvmat2_y; + __u16 rgb2ryuvofs_y; + /* RAWAWB_YUV_RGB2ROTU_0 */ + __u16 rgb2ryuvmat0_u; + __u16 rgb2ryuvmat1_u; + /* RAWAWB_YUV_RGB2ROTU_1 */ + __u16 rgb2ryuvmat2_u; + __u16 rgb2ryuvofs_u; + /* RAWAWB_YUV_RGB2ROTV_0 */ + __u16 rgb2ryuvmat0_v; + __u16 rgb2ryuvmat1_v; + /* RAWAWB_YUV_RGB2ROTV_1 */ + __u16 rgb2ryuvmat2_v; + __u16 rgb2ryuvofs_v; + /* RAWAWB_YUV_X_COOR_Y_0 */ + __u16 coor_x1_ls0_y; + __u16 vec_x21_ls0_y; + /* RAWAWB_YUV_X_COOR_U_0 */ + __u16 coor_x1_ls0_u; + __u16 vec_x21_ls0_u; + /* RAWAWB_YUV_X_COOR_V_0 */ + __u16 coor_x1_ls0_v; + __u16 vec_x21_ls0_v; + /* RAWAWB_YUV_X1X2_DIS_0 */ + __u8 dis_x1x2_ls0; + __u8 rotu0_ls0; + __u8 rotu1_ls0; + /* RAWAWB_YUV_INTERP_CURVE_UCOOR_0 */ + __u8 rotu2_ls0; + __u8 rotu3_ls0; + __u8 rotu4_ls0; + __u8 rotu5_ls0; + /* RAWAWB_YUV_INTERP_CURVE_TH0_0 */ + __u16 th0_ls0; + __u16 th1_ls0; + /* RAWAWB_YUV_INTERP_CURVE_TH1_0 */ + __u16 th2_ls0; + __u16 th3_ls0; + /* RAWAWB_YUV_INTERP_CURVE_TH2_0 */ + __u16 th4_ls0; + __u16 th5_ls0; + /* RAWAWB_YUV_X_COOR_Y_1 */ + __u16 coor_x1_ls1_y; + __u16 vec_x21_ls1_y; + /* RAWAWB_YUV_X_COOR_U_1 */ + __u16 coor_x1_ls1_u; + __u16 vec_x21_ls1_u; + /* RAWAWB_YUV_X_COOR_V_1 */ + __u16 coor_x1_ls1_v; + __u16 vec_x21_ls1_v; + /* RAWAWB_YUV_X1X2_DIS_1 */ + __u8 dis_x1x2_ls1; + __u8 rotu0_ls1; + __u8 rotu1_ls1; + /* YUV_INTERP_CURVE_UCOOR_1 */ + __u8 rotu2_ls1; + __u8 rotu3_ls1; + __u8 rotu4_ls1; + __u8 rotu5_ls1; + /* RAWAWB_YUV_INTERP_CURVE_TH0_1 */ + __u16 th0_ls1; + __u16 th1_ls1; + /* RAWAWB_YUV_INTERP_CURVE_TH1_1 */ + __u16 th2_ls1; + __u16 th3_ls1; + /* RAWAWB_YUV_INTERP_CURVE_TH2_1 */ + __u16 th4_ls1; + __u16 th5_ls1; + /* RAWAWB_YUV_X_COOR_Y_2 */ + __u16 coor_x1_ls2_y; + __u16 vec_x21_ls2_y; + /* RAWAWB_YUV_X_COOR_U_2 */ + __u16 coor_x1_ls2_u; + __u16 vec_x21_ls2_u; + /* RAWAWB_YUV_X_COOR_V_2 */ + __u16 coor_x1_ls2_v; + __u16 vec_x21_ls2_v; + /* RAWAWB_YUV_X1X2_DIS_2 */ + __u8 dis_x1x2_ls2; + __u8 rotu0_ls2; + __u8 rotu1_ls2; + /* YUV_INTERP_CURVE_UCOOR_2 */ + __u8 rotu2_ls2; + __u8 rotu3_ls2; + __u8 rotu4_ls2; + __u8 rotu5_ls2; + /* RAWAWB_YUV_INTERP_CURVE_TH0_2 */ + __u16 th0_ls2; + __u16 th1_ls2; + /* RAWAWB_YUV_INTERP_CURVE_TH1_2 */ + __u16 th2_ls2; + __u16 th3_ls2; + /* RAWAWB_YUV_INTERP_CURVE_TH2_2 */ + __u16 th4_ls2; + __u16 th5_ls2; + /* RAWAWB_YUV_X_COOR_Y_3 */ + __u16 coor_x1_ls3_y; + __u16 vec_x21_ls3_y; + /* RAWAWB_YUV_X_COOR_U_3 */ + __u16 coor_x1_ls3_u; + __u16 vec_x21_ls3_u; + /* RAWAWB_YUV_X_COOR_V_3 */ + __u16 coor_x1_ls3_v; + __u16 vec_x21_ls3_v; + /* RAWAWB_YUV_X1X2_DIS_3 */ + __u8 dis_x1x2_ls3; + __u8 rotu0_ls3; + __u8 rotu1_ls3; + /* RAWAWB_YUV_INTERP_CURVE_UCOOR_3 */ + __u8 rotu2_ls3; + __u8 rotu3_ls3; + __u8 rotu4_ls3; + __u8 rotu5_ls3; + /* RAWAWB_YUV_INTERP_CURVE_TH0_3 */ + __u16 th0_ls3; + __u16 th1_ls3; + /* RAWAWB_YUV_INTERP_CURVE_TH1_3 */ + __u16 th2_ls3; + __u16 th3_ls3; + /* RAWAWB_YUV_INTERP_CURVE_TH2_3 */ + __u16 th4_ls3; + __u16 th5_ls3; + /* CCM_COEFF0_R */ + __u16 ccm_coeff0_r; + __u16 ccm_coeff1_r; + /* CCM_COEFF1_R */ + __u16 ccm_coeff2_r; + /* CCM_COEFF0_G */ + __u16 ccm_coeff0_g; + __u16 ccm_coeff1_g; + /* CCM_COEFF1_G */ + __u16 ccm_coeff2_g; + /* CCM_COEFF0_B */ + __u16 ccm_coeff0_b; + __u16 ccm_coeff1_b; + /* CCM_COEFF1_B */ + __u16 ccm_coeff2_b; + /* RAWAWB_RGB2XY_WT01 */ + __u16 wt0; + __u16 wt1; + /* RAWAWB_RGB2XY_WT2 */ + __u16 wt2; + /* RAWAWB_RGB2XY0_MAT */ + __u16 mat0_x; + __u16 mat0_y; + /* RAWAWB_RGB2XY_MAT1_XY */ + __u16 mat1_x; + __u16 mat1_y; + /* RAWAWB_RGB2XY_MAT2_XY */ + __u16 mat2_x; + __u16 mat2_y; + /* RAWAWB_XY_DETC_NOR_X_0 */ + __u16 nor_x0_0; + __u16 nor_x1_0; + /* RAWAWB_XY_DETC_NOR_Y_0 */ + __u16 nor_y0_0; + __u16 nor_y1_0; + /* RAWAWB_XY_DETC_BIG_X_0 */ + __u16 big_x0_0; + __u16 big_x1_0; + /* RAWAWB_XY_DETC_BIG_Y_0 */ + __u16 big_y0_0; + __u16 big_y1_0; + /* RAWAWB_XY_DETC_NOR_X_1 */ + __u16 nor_x0_1; + __u16 nor_x1_1; + /* RAWAWB_XY_DETC_NOR_Y_1 */ + __u16 nor_y0_1; + __u16 nor_y1_1; + /* RAWAWB_XY_DETC_BIG_X_1 */ + __u16 big_x0_1; + __u16 big_x1_1; + /* RAWAWB_XY_DETC_BIG_Y_1 */ + __u16 big_y0_1; + __u16 big_y1_1; + /* RAWAWB_XY_DETC_NOR_X_2 */ + __u16 nor_x0_2; + __u16 nor_x1_2; + /* RAWAWB_XY_DETC_NOR_Y_2 */ + __u16 nor_y0_2; + __u16 nor_y1_2; + /* RAWAWB_XY_DETC_BIG_X_2 */ + __u16 big_x0_2; + __u16 big_x1_2; + /* RAWAWB_XY_DETC_BIG_Y_2 */ + __u16 big_y0_2; + __u16 big_y1_2; + /* RAWAWB_XY_DETC_NOR_X_3 */ + __u16 nor_x0_3; + __u16 nor_x1_3; + /* RAWAWB_XY_DETC_NOR_Y_3 */ + __u16 nor_y0_3; + __u16 nor_y1_3; + /* RAWAWB_XY_DETC_BIG_X_3 */ + __u16 big_x0_3; + __u16 big_x1_3; + /* RAWAWB_XY_DETC_BIG_Y_3 */ + __u16 big_y0_3; + __u16 big_y1_3; + /* RAWAWB_MULTIWINDOW_EXC_CTRL */ + __u8 exc_wp_region0_excen; + __u8 exc_wp_region0_measen; + __u8 exc_wp_region0_domain; + __u8 exc_wp_region1_excen; + __u8 exc_wp_region1_measen; + __u8 exc_wp_region1_domain; + __u8 exc_wp_region2_excen; + __u8 exc_wp_region2_measen; + __u8 exc_wp_region2_domain; + __u8 exc_wp_region3_excen; + __u8 exc_wp_region3_measen; + __u8 exc_wp_region3_domain; + __u8 exc_wp_region4_excen; + __u8 exc_wp_region4_domain; + __u8 exc_wp_region5_excen; + __u8 exc_wp_region5_domain; + __u8 exc_wp_region6_excen; + __u8 exc_wp_region6_domain; + __u8 multiwindow_en; + /* RAWAWB_MULTIWINDOW0_OFFS */ + __u16 multiwindow0_h_offs; + __u16 multiwindow0_v_offs; + /* RAWAWB_MULTIWINDOW0_SIZE */ + __u16 multiwindow0_h_size; + __u16 multiwindow0_v_size; + /* RAWAWB_MULTIWINDOW1_OFFS */ + __u16 multiwindow1_h_offs; + __u16 multiwindow1_v_offs; + /* RAWAWB_MULTIWINDOW1_OFFS */ + __u16 multiwindow1_h_size; + __u16 multiwindow1_v_size; + /* RAWAWB_MULTIWINDOW2_OFFS */ + __u16 multiwindow2_h_offs; + __u16 multiwindow2_v_offs; + /* RAWAWB_MULTIWINDOW2_SIZE */ + __u16 multiwindow2_h_size; + __u16 multiwindow2_v_size; + /* RAWAWB_MULTIWINDOW3_OFFS */ + __u16 multiwindow3_h_offs; + __u16 multiwindow3_v_offs; + /* RAWAWB_MULTIWINDOW3_SIZE */ + __u16 multiwindow3_h_size; + __u16 multiwindow3_v_size; + /* RAWAWB_EXC_WP_REGION0_XU */ + __u16 exc_wp_region0_xu0; + __u16 exc_wp_region0_xu1; + /* RAWAWB_EXC_WP_REGION0_YV */ + __u16 exc_wp_region0_yv0; + __u16 exc_wp_region0_yv1; + /* RAWAWB_EXC_WP_REGION1_XU */ + __u16 exc_wp_region1_xu0; + __u16 exc_wp_region1_xu1; + /* RAWAWB_EXC_WP_REGION1_YV */ + __u16 exc_wp_region1_yv0; + __u16 exc_wp_region1_yv1; + /* RAWAWB_EXC_WP_REGION2_XU */ + __u16 exc_wp_region2_xu0; + __u16 exc_wp_region2_xu1; + /* RAWAWB_EXC_WP_REGION2_YV */ + __u16 exc_wp_region2_yv0; + __u16 exc_wp_region2_yv1; + /* RAWAWB_EXC_WP_REGION3_XU */ + __u16 exc_wp_region3_xu0; + __u16 exc_wp_region3_xu1; + /* RAWAWB_EXC_WP_REGION3_YV */ + __u16 exc_wp_region3_yv0; + __u16 exc_wp_region3_yv1; + /* RAWAWB_EXC_WP_REGION4_XU */ + __u16 exc_wp_region4_xu0; + __u16 exc_wp_region4_xu1; + /* RAWAWB_EXC_WP_REGION4_YV */ + __u16 exc_wp_region4_yv0; + __u16 exc_wp_region4_yv1; + /* RAWAWB_EXC_WP_REGION5_XU */ + __u16 exc_wp_region5_xu0; + __u16 exc_wp_region5_xu1; + /* RAWAWB_EXC_WP_REGION5_YV */ + __u16 exc_wp_region5_yv0; + __u16 exc_wp_region5_yv1; + /* RAWAWB_EXC_WP_REGION6_XU */ + __u16 exc_wp_region6_xu0; + __u16 exc_wp_region6_xu1; + /* RAWAWB_EXC_WP_REGION6_YV */ + __u16 exc_wp_region6_yv0; + __u16 exc_wp_region6_yv1; + /* RAWAWB_EXC_WP_WEIGHT0_3 */ + __u8 exc_wp_region0_weight; + __u8 exc_wp_region1_weight; + __u8 exc_wp_region2_weight; + __u8 exc_wp_region3_weight; + /* RAWAWB_EXC_WP_WEIGHT4_6 */ + __u8 exc_wp_region4_weight; + __u8 exc_wp_region5_weight; + __u8 exc_wp_region6_weight; + /* RAWAWB_WRAM_DATA */ + __u8 wp_blk_wei_w[ISP35_RAWAWB_WEIGHT_NUM]; + + struct isp2x_bls_fixed_val bls2_val; +} __attribute__ ((packed)); + +struct isp35_aiawb_meas_cfg { + __u8 bls3_en; + /* CTRL0 */ + __u8 ds_mode_config_en; + __u8 ds_mode; + __u8 rgb2w_mode; + __u8 rawout_sel; + __u8 path_sel; + __u8 in_shift; + /* CTRL1 */ + __u8 exp1_check_en; + __u8 exp_thr; + __u16 saturation_hthr; + __u16 saturation_lthr; + /* WIN_OFFS */ + __u16 h_offs; + __u16 v_offs; + /* WIN_SIZE */ + __u16 h_size; + __u16 v_size; + /* FLT_COE */ + __s8 flt_coe[ISP35_AIAWB_FLT_COE_NUM]; + /* WBGAIN_INV0 */ + __u16 wbgain_inv_g; + __u16 wbgain_inv_b; + /* WBGAIN_INV1 */ + __u16 wbgain_inv_r; + __u16 expand; + /* MATRIX_SCALE */ + __u16 ms00; + __u16 ms01; + /* MATRIX_ROT0 */ + __u16 mr00; + __u16 mr01; + /* MATRIX_ROT1 */ + __u16 mr10; + __u16 mr11; + + struct isp2x_bls_fixed_val bls3_val; +} __attribute__ ((packed)); + +struct isp35_awbsync_meas_cfg { + /* CTRL */ + __u8 sumval_check_en; + __u8 sumval_mode; + /* SCL */ + __u16 scl_b; + __u16 scl_g; + __u16 scl_r; + /* SUMVAL_MIN */ + __u16 sumval_minb; + __u16 sumval_ming; + __u16 sumval_minr; + /* SUMVAL_MAX */ + __u16 sumval_maxb; + __u16 sumval_maxg; + __u16 sumval_maxr; + /* WINDOW0_OFFS */ + __u16 win0_h_offs; + __u16 win0_v_offs; + /* WINDOW0_RD_COOR */ + __u16 win0_r_coor; + __u16 win0_d_coor; + /* WINDOW1_OFFS */ + __u16 win1_h_offs; + __u16 win1_v_offs; + /* WINDOW1_RD_COOR */ + __u16 win1_r_coor; + __u16 win1_d_coor; + /* WINDOW2_OFFS */ + __u16 win2_h_offs; + __u16 win2_v_offs; + /* WINDOW2_RD_COOR */ + __u16 win2_r_coor; + __u16 win2_d_coor; +} __attribute__ ((packed)); + +struct isp35_rawaf_meas_cfg { + __u8 rawaf_sel; + __u8 num_afm_win; + __u8 bnr2af_sel; + + /* CTRL */ + __u8 gamma_en; + __u8 gaus_en; + __u8 hiir_en; + __u8 viir_en; + __u8 ldg_en; + __u8 h1_fv_mode; + __u8 h2_fv_mode; + __u8 v1_fv_mode; + __u8 v2_fv_mode; + __u8 ae_mode; + __u8 y_mode; + __u8 vldg_sel; + __u8 v_dnscl_mode; + __u8 from_ynr; + __u8 bnr_be_sel; + __u8 hiir_left_border_mode; + __u8 avg_ds_en; + __u8 avg_ds_mode; + __u8 h1_acc_mode; + __u8 h2_acc_mode; + __u8 v1_acc_mode; + __u8 v2_acc_mode; + + /* WINA_B */ + struct isp2x_window win[ISP39_RAWAF_WIN_NUM]; + + /* CTRL1 */ + __s16 bls_offset; + __u8 bls_en; + __u8 aehgl_en; + __u8 hldg_dilate_num; + __u8 tnrin_shift; + + /* HVIIR_VAR_SHIFT */ + __u8 h1iir_shift_wina; + __u8 h2iir_shift_wina; + __u8 v1iir_shift_wina; + __u8 v2iir_shift_wina; + __u8 h1iir_shift_winb; + __u8 h2iir_shift_winb; + __u8 v1iir_shift_winb; + __u8 v2iir_shift_winb; + + /* GAUS_COE */ + __s8 gaus_coe[ISP39_RAWAF_GAUS_COE_NUM]; + + /* GAMMA_Y */ + __u16 gamma_y[ISP39_RAWAF_GAMMA_NUM]; + /* HIIR_THRESH */ + __u16 h_fv_thresh; + __u16 v_fv_thresh; + struct isp3x_rawaf_curve curve_h[ISP39_RAWAF_CURVE_NUM]; + struct isp3x_rawaf_curve curve_v[ISP39_RAWAF_CURVE_NUM]; + __s16 h1iir1_coe[ISP39_RAWAF_HIIR_COE_NUM]; + __s16 h1iir2_coe[ISP39_RAWAF_HIIR_COE_NUM]; + __s16 h2iir1_coe[ISP39_RAWAF_HIIR_COE_NUM]; + __s16 h2iir2_coe[ISP39_RAWAF_HIIR_COE_NUM]; + __s16 v1iir_coe[ISP39_RAWAF_VIIR_COE_NUM]; + __s16 v2iir_coe[ISP39_RAWAF_VIIR_COE_NUM]; + __s16 v1fir_coe[ISP39_RAWAF_VFIR_COE_NUM]; + __s16 v2fir_coe[ISP39_RAWAF_VFIR_COE_NUM]; + /* HIGHLIT_THRESH */ + __u16 highlit_thresh; + + /* CORING_H */ + __u16 h_fv_limit; + __u16 h_fv_slope; + /* CORING_V */ + __u16 v_fv_limit; + __u16 v_fv_slope; +} __attribute__ ((packed)); + +struct isp35_rawae_meas_cfg { + __u8 rawae_sel; + __u8 bnr2ae_sel; + + __u8 wnd_num; + __u8 wnd1_en; + __u8 debug_en; + __u8 bnr_be_sel; + + __u16 win0_h_offset; + __u16 win0_v_offset; + __u16 win0_h_size; + __u16 win0_v_size; + __u16 win1_h_offset; + __u16 win1_v_offset; + __u16 win1_h_size; + __u16 win1_v_size; +} __attribute__ ((packed)); + +struct isp35_rawhist_meas_cfg { + __u8 stepsize; + __u8 debug_en; + __u8 mode; + __u8 data_sel; + __u8 wnd_num; + __u16 waterline; + + __u8 rcc; + __u8 gcc; + __u8 bcc; + __u8 off; + + __u16 h_offset; + __u16 v_offset; + __u16 h_size; + __u16 v_size; + + __u8 weight[ISP35_RAWHIST_WEIGHT_NUM]; +} __attribute__ ((packed)); + +struct isp35_isp_other_cfg { + struct isp39_rgbir_cfg rgbir_cfg; + struct isp35_bls_cfg bls_cfg; + struct isp32_awb_gain_cfg awb_gain_cfg; + struct isp39_dpcc_cfg dpcc_cfg; + struct isp35_hdrmge_cfg hdrmge_cfg; + struct isp3x_gain_cfg gain_cfg; + struct isp35_bay3d_cfg bay3d_cfg; + struct isp35_ai_cfg ai_cfg; + + struct isp33_cac_cfg cac_cfg; + struct isp3x_lsc_cfg lsc_cfg; + + struct isp35_debayer_cfg debayer_cfg; + struct isp35_drc_cfg drc_cfg; + struct isp33_ccm_cfg ccm_cfg; + struct isp3x_gammaout_cfg gammaout_cfg; + struct isp35_hsv_cfg hsv_cfg; + struct isp21_csm_cfg csm_cfg; + struct isp33_gic_cfg gic_cfg; + struct isp35_cnr_cfg cnr_cfg; + struct isp35_ynr_cfg ynr_cfg; + struct isp35_sharp_cfg sharp_cfg; + struct isp33_enh_cfg enh_cfg; + struct isp33_hist_cfg hist_cfg; + struct isp32_ldch_cfg ldch_cfg; + struct isp21_cgc_cfg cgc_cfg; + struct isp2x_cproc_cfg cproc_cfg; +} __attribute__ ((packed)); + +struct isp35_isp_meas_cfg { + struct isp35_rawae_meas_cfg rawae0; + struct isp35_rawhist_meas_cfg rawhist0; + struct isp35_rawae_meas_cfg rawae3; + struct isp35_rawhist_meas_cfg rawhist3; + struct isp35_rawawb_meas_cfg rawawb; + struct isp35_rawaf_meas_cfg rawaf; + struct isp35_aiawb_meas_cfg aiawb; + struct isp35_awbsync_meas_cfg awbsync; +} __attribute__ ((packed)); + +struct isp35_isp_params_cfg { + __u64 module_en_update; + __u64 module_ens; + __u64 module_cfg_update; + + __u32 frame_id; + struct isp35_isp_meas_cfg meas; + struct isp35_isp_other_cfg others; + struct sensor_exposure_cfg exposure; +} __attribute__ ((packed)); + +struct isp35_awbsync_stat { + __u64 sumr[ISP35_AWBSYNC_WIN_MAX]; + __u64 sumg[ISP35_AWBSYNC_WIN_MAX]; + __u64 sumb[ISP35_AWBSYNC_WIN_MAX]; + __u64 sump[ISP35_AWBSYNC_WIN_MAX]; +} __attribute__ ((packed)); + +struct isp35_stat { + /* mean to ddr */ + struct isp33_rawae_stat rawae3; + struct isp33_rawhist_stat rawhist3; + struct isp33_rawae_stat rawae0; + struct isp33_rawhist_stat rawhist0; + struct isp39_rawaf_stat rawaf; + struct isp33_rawawb_stat rawawb; + /* ahb read reg */ + struct isp33_bay3d_stat bay3d; + struct isp33_sharp_stat sharp; + struct isp33_enh_stat enh; + struct isp33_hist_stat hist; + struct isp35_awbsync_stat awbsync; + struct isp32_info2ddr_stat info2ddr; + int buf_aiawb_index; +} __attribute__ ((packed)); + +struct rkisp35_stat_buffer { + struct isp35_stat stat; + __u32 meas_type; + __u32 frame_id; + __u32 params_id; +} __attribute__ ((packed)); +#endif /* _UAPI_RK_ISP35_CONFIG_H */