diff --git a/drivers/media/platform/rockchip/isp/Kconfig b/drivers/media/platform/rockchip/isp/Kconfig index a1a762136816..3c4303870179 100644 --- a/drivers/media/platform/rockchip/isp/Kconfig +++ b/drivers/media/platform/rockchip/isp/Kconfig @@ -50,6 +50,16 @@ config VIDEO_ROCKCHIP_ISP_VERSION_V39_DBG depends on VIDEO_ROCKCHIP_ISP_VERSION_V39 default n +config VIDEO_ROCKCHIP_ISP_VERSION_V33 + bool "isp33 for rv1103b" + depends on CPU_RV1103B + default y + +config VIDEO_ROCKCHIP_ISP_VERSION_V33_DBG + bool "isp33 params debug for rv1103b" + depends on VIDEO_ROCKCHIP_ISP_VERSION_V33 + 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 b66abd1e0cc8..202a30b2aa18 100644 --- a/drivers/media/platform/rockchip/isp/Makefile +++ b/drivers/media/platform/rockchip/isp/Makefile @@ -51,6 +51,12 @@ video_rkisp-$(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) += \ isp_pdaf.o \ isp_sditf.o +video_rkisp-$(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) += \ + capture_v33.o \ + isp_params_v33.o \ + isp_stats_v33.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 66d16c778239..24a6ad2fa8d2 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -372,6 +372,7 @@ void rkisp_stream_vir_cpy_image(struct work_struct *work) struct rkisp_buffer *src_buf = NULL; struct vb2_buffer *src_vb = NULL; struct rkisp_device *isp_dev = vir->ispdev; + struct rkisp_stream *src_stream = NULL; const struct vb2_mem_ops *g_ops = isp_dev->hw_dev->mem_ops; void *src = NULL, *dst = NULL, *mem = NULL; u32 payload_size = 0; @@ -420,14 +421,19 @@ void rkisp_stream_vir_cpy_image(struct work_struct *work) payload_size = vir->out_fmt.plane_fmt[i].sizeimage; dst = vb2_plane_vaddr(&vir->curr_buf->vb.vb2_buf, i); mem = src_vb->planes[i].mem_priv; - src = vb2_plane_vaddr(&src_buf->vb.vb2_buf, i); - + if (src_vb->memory) + src = vb2_plane_vaddr(&src_buf->vb.vb2_buf, i); + else + src = src_buf->vaddr[i]; if (!src || !dst) break; /* sync cache */ - if (mem) - g_ops->finish(mem); - + if (mem) { + if (src_vb->memory) + g_ops->finish(mem); + else + dma_sync_sgtable_for_cpu(isp_dev->hw_dev->dev, mem, DMA_BIDIRECTIONAL); + } vb2_set_plane_payload(&vir->curr_buf->vb.vb2_buf, i, payload_size); memcpy(dst, src, payload_size); } @@ -438,8 +444,15 @@ void rkisp_stream_vir_cpy_image(struct work_struct *work) vir->curr_buf = NULL; end: - if (src_buf) - vb2_buffer_done(&src_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + if (src_buf) { + if (src_buf->vb.vb2_buf.memory) { + vb2_buffer_done(&src_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + } else { + src_stream = &isp_dev->cap_dev.stream[vir->conn_id]; + if (src_stream) + rkisp_rockit_buf_done(src_stream, ROCKIT_DVBM_END, src_buf); + } + } src_buf = NULL; spin_lock_irqsave(&vir->vbq_lock, lock_flags); @@ -533,8 +546,10 @@ int rkisp_stream_frame_start(struct rkisp_device *dev, u32 isp_mis) struct rkisp_stream *stream; int i; - if (isp_mis) - rkisp_dvbm_event(dev, CIF_ISP_V_START); + /* frame start irq no handle for unite or multi-sensor online mode */ + if (!dev->hw_dev->is_single && isp_mis) + return 0; + rkisp_bridge_update_mi(dev, isp_mis); for (i = 0; i < RKISP_MAX_STREAM; i++) { @@ -972,6 +987,10 @@ int rkisp_fh_open(struct file *filp) if (!stream->ispdev->is_probe_end) return -EINVAL; + ret = rkisp_cond_poll_timeout(!stream->ispdev->is_thunderboot, + 5000, 1000 * USEC_PER_MSEC); + if (ret) + return ret; ret = v4l2_fh_open(filp); if (!ret) { @@ -1102,7 +1121,9 @@ static int rkisp_get_cmsk(struct rkisp_stream *stream, struct rkisp_cmsk_cfg *cf unsigned long lock_flags = 0; u32 i, win_en, mode; - if ((dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) || + if ((dev->isp_ver != ISP_V30 && + dev->isp_ver != ISP_V32 && + dev->isp_ver != ISP_V33) || stream->id == RKISP_STREAM_FBC || stream->id == RKISP_STREAM_MPDS || stream->id == RKISP_STREAM_BPDS) { @@ -1151,7 +1172,9 @@ static int rkisp_set_cmsk(struct rkisp_stream *stream, struct rkisp_cmsk_cfg *cf u32 align = (dev->isp_ver == ISP_V30) ? 8 : 2; bool warn = false; - if ((dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) || + if ((dev->isp_ver != ISP_V30 && + dev->isp_ver != ISP_V32 && + dev->isp_ver != ISP_V33) || stream->id == RKISP_STREAM_FBC || stream->id == RKISP_STREAM_MPDS || stream->id == RKISP_STREAM_BPDS) { @@ -1243,7 +1266,7 @@ static int rkisp_get_mirror_flip(struct rkisp_stream *stream, { struct rkisp_device *dev = stream->ispdev; - if (dev->isp_ver != ISP_V32) + if (dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) return -EINVAL; cfg->mirror = dev->cap_dev.is_mirror; @@ -1256,16 +1279,15 @@ static int rkisp_set_mirror_flip(struct rkisp_stream *stream, { struct rkisp_device *dev = stream->ispdev; - if (dev->isp_ver != ISP_V32) + if (dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) return -EINVAL; - if (dev->cap_dev.wrap_line) { - v4l2_warn(&dev->v4l2_dev, "wrap_line mode can not set the mirror"); - dev->cap_dev.is_mirror = 0; - } else { - dev->cap_dev.is_mirror = cfg->mirror; + if (dev->cap_dev.wrap_line && cfg->flip) { + cfg->flip = 0; + v4l2_warn(&dev->v4l2_dev, "no support flip for wrap mode\n"); } + dev->cap_dev.is_mirror = cfg->mirror; stream->is_flip = cfg->flip; stream->is_mf_upd = true; return 0; @@ -1275,7 +1297,8 @@ static int rkisp_get_wrap_line(struct rkisp_stream *stream, struct rkisp_wrap_in { struct rkisp_device *dev = stream->ispdev; - if (dev->isp_ver != ISP_V32 && stream->id != RKISP_STREAM_MP) + if (stream->id != RKISP_STREAM_MP && + dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) return -EINVAL; arg->width = dev->cap_dev.wrap_width; @@ -1299,7 +1322,7 @@ static int rkisp_set_fps(struct rkisp_stream *stream, int *fps) { struct rkisp_device *dev = stream->ispdev; - if (dev->isp_ver != ISP_V32) + if (dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) return -EINVAL; return rkisp_rockit_fps_set(fps, stream); @@ -1309,7 +1332,7 @@ static int rkisp_get_fps(struct rkisp_stream *stream, int *fps) { struct rkisp_device *dev = stream->ispdev; - if (dev->isp_ver != ISP_V32) + if (dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) return -EINVAL; return rkisp_rockit_fps_get(fps, stream); @@ -1781,7 +1804,7 @@ 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) + if (ispdev->isp_ver != ISP_V32 && ispdev->isp_ver != ISP_V33) return; mutex_lock(&ispdev->hw_dev->dev_lock); @@ -1799,8 +1822,7 @@ static void rkisp_stream_fast(struct work_struct *work) if (ispdev->hw_dev->dev_num > 1) ispdev->hw_dev->is_single = false; ispdev->is_pre_on = true; - ispdev->is_rdbk_auto = true; - ispdev->pipe.open(&ispdev->pipe, &stream->vnode.vdev.entity, true); + rkisp_csi_config_patch(ispdev, true); v4l2_subdev_call(sd, video, s_stream, true); } @@ -1927,6 +1949,8 @@ int rkisp_register_stream_vdevs(struct rkisp_device *dev) ret = rkisp_register_stream_v32(dev); } else if (dev->isp_ver == ISP_V39) { ret = rkisp_register_stream_v39(dev); + } else if (dev->isp_ver == ISP_V33) { + ret = rkisp_register_stream_v33(dev); } INIT_WORK(&cap_dev->fast_work, rkisp_stream_fast); @@ -1947,6 +1971,8 @@ void rkisp_unregister_stream_vdevs(struct rkisp_device *dev) rkisp_unregister_stream_v32(dev); else if (dev->isp_ver == ISP_V39) rkisp_unregister_stream_v39(dev); + else if (dev->isp_ver == ISP_V33) + rkisp_unregister_stream_v33(dev); } void rkisp_mi_isr(u32 mis_val, struct rkisp_device *dev) @@ -1963,6 +1989,8 @@ void rkisp_mi_isr(u32 mis_val, struct rkisp_device *dev) rkisp_mi_v32_isr(mis_val, dev); else if (dev->isp_ver == ISP_V39) rkisp_mi_v39_isr(mis_val, dev); + else if (dev->isp_ver == ISP_V33) + rkisp_mi_v33_isr(mis_val, dev); } void rkisp_mipi_v3x_isr(unsigned int phy, unsigned int packet, diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index 15561cb685a9..8d9bd68fcf1f 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -348,6 +348,12 @@ static const struct capture_fmt luma_fmts[] = { }, }; +static struct stream_config rkisp_luma_stream_config = { + .fmts = luma_fmts, + .fmt_size = ARRAY_SIZE(luma_fmts), + .frame_end_id = 0, +}; + static struct stream_config rkisp_sp_stream_config_lite = { /* constraints */ .max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L, @@ -410,12 +416,6 @@ static struct stream_config rkisp_sp_stream_config_lite = { }, }; -static struct stream_config rkisp_luma_stream_config = { - .fmts = luma_fmts, - .fmt_size = ARRAY_SIZE(luma_fmts), - .frame_end_id = 0, -}; - static struct stream_config rkisp_bp_stream_config = { .fmts = bp_fmts, .fmt_size = ARRAY_SIZE(bp_fmts), @@ -853,6 +853,7 @@ 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; @@ -867,7 +868,8 @@ static int sp_config_mi(struct rkisp_stream *stream) * NOTE: plane_fmt[0].sizeimage is total size of all planes for single * memory plane formats, so calculate the size explicitly. */ - val = stream->u.sp.y_stride; + 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); @@ -1287,7 +1289,6 @@ static int set_mirror_flip(struct rkisp_stream *stream) val = ISP32_MP_WR_V_FLIP; if (dev->cap_dev.wrap_line) { stream->is_flip = false; - v4l2_warn(&dev->v4l2_dev, "flip not support width wrap function\n"); return -EINVAL; } } @@ -1529,9 +1530,10 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) /* 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.dma_addr)) + !stream->dummy_buf.mem_priv && stream->dummy_buf.dma_addr)) { + set_mirror_flip(stream); return 0; - + } if (dev->cap_dev.is_done_early && (state == FRAME_IRQ || state == FRAME_WORK)) { /* skip mainpath wrap mode */ @@ -1586,19 +1588,18 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) stream->dbg.timestamp = ns; stream->dbg.id = i; - if (vb2_buf->memory) { - 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 { - rkisp_stream_buf_done(stream, buf); - } + 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 { - rkisp_rockit_buf_done(stream, ROCKIT_DVBM_END); + if (vb2_buf->memory) + rkisp_stream_buf_done(stream, buf); + else + rkisp_rockit_buf_done(stream, ROCKIT_DVBM_END, buf); } } @@ -1840,7 +1841,7 @@ static void rkisp_destroy_dummy_buf(struct rkisp_stream *stream) if (!dev->cap_dev.wrap_line || stream->id != RKISP_STREAM_MP) return; - rkisp_dvbm_deinit(); + rkisp_dvbm_deinit(dev); rkisp_free_buffer(dev, &stream->dummy_buf); stream->dummy_buf.dma_addr = 0; } @@ -1935,10 +1936,8 @@ end: mutex_unlock(&dev->hw_dev->dev_lock); if (dev->is_pre_on && stream->id == RKISP_STREAM_MP) { - dev->is_rdbk_auto = false; dev->is_pre_on = false; - v4l2_subdev_call(dev->active_sensor->sd, video, s_stream, false); - dev->pipe.close(&dev->pipe); + dev->params_vdev.first_cfg_params = false; v4l2_pipeline_pm_put(&stream->vnode.vdev.entity); } } @@ -2309,9 +2308,6 @@ void rkisp_unregister_stream_v32(struct rkisp_device *dev) stream = &cap_dev->stream[RKISP_STREAM_LUMA]; rkisp_unregister_stream_vdev(stream); rkisp_rockit_dev_deinit(); - } else { - stream = &cap_dev->stream[RKISP_STREAM_VIR]; - rkisp_unregister_stream_vdev(stream); } } @@ -2370,6 +2366,7 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) stream->dbg.delay = ns - dev->isp_sdev.frm_timestamp; stream->dbg.timestamp = ns; stream->dbg.id = seq; + set_mirror_flip(stream); } else { mi_frame_end(stream, FRAME_IRQ); } diff --git a/drivers/media/platform/rockchip/isp/capture_v33.c b/drivers/media/platform/rockchip/isp/capture_v33.c new file mode 100644 index 000000000000..2a3c3100360f --- /dev/null +++ b/drivers/media/platform/rockchip/isp/capture_v33.c @@ -0,0 +1,1972 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Rockchip Electronics Co., Ltd. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dev.h" +#include "regs.h" + +/* ISP33 + * |--mainpath----[wrap]--------->enc(or ddr) + * |->selfpath----------------->ddr + *output->|->bypasspath------------------->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, + }, +}; + +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 const struct capture_fmt bp_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_UYVY, + .fmt_type = FMT_YUV, + .bpp = { 16 }, + .cplanes = 1, + .mplanes = 1, + .write_format = ISP3X_BP_FORMAT_INT, + .output_format = ISP3X_BP_OUTPUT_YUV422, + }, { + .fourcc = V4L2_PIX_FMT_NV16, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .write_format = ISP3X_BP_FORMAT_SPLA, + .output_format = ISP3X_BP_OUTPUT_YUV422, + }, { + .fourcc = V4L2_PIX_FMT_NV12, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 1, + .write_format = ISP3X_BP_FORMAT_SPLA, + .output_format = ISP3X_BP_OUTPUT_YUV420, + }, { + .fourcc = V4L2_PIX_FMT_NV12M, + .fmt_type = FMT_YUV, + .bpp = { 8, 16 }, + .cplanes = 2, + .mplanes = 2, + .write_format = ISP3X_BP_FORMAT_SPLA, + .output_format = ISP3X_BP_OUTPUT_YUV420, + } +}; + +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_V33, + .max_rsz_height = CIF_ISP_INPUT_H_MAX_V33, + .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 struct stream_config rkisp_bp_stream_cfg = { + .fmts = bp_fmts, + .fmt_size = ARRAY_SIZE(bp_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 = ISP3X_MI_BP_FRAME, + .rsz = { + .ctrl = ISP33_BP_SCALE_CTRL, + .update = ISP33_BP_SCALE_UPDATE, + .src_size = ISP33_BP_SCALE_SRC_SIZE, + .dst_size = ISP33_BP_SCALE_DST_SIZE, + .scale_hy_offs_mi = ISP33_BP_SCALE_HY_OFFS_MI, + .scale_hc_offs_mi = ISP33_BP_SCALE_HC_OFFS_MI, + .scale_in_crop_offs = ISP33_BP_SCALE_IN_CROP_OFFSET, + .scale_hy_offs = ISP33_BP_SCALE_HY_OFFS, + .scale_hc_offs = ISP33_BP_SCALE_HC_OFFS, + .scale_hy_size = ISP33_BP_SCALE_HY_SIZE, + .scale_hc_size = ISP33_BP_SCALE_HC_SIZE, + .scale_hy = ISP33_BP_SCALE_HY_FAC, + .scale_hcr = ISP33_BP_SCALE_HC_FAC, + .scale_vy = ISP33_BP_SCALE_VY_FAC, + .scale_vc = ISP33_BP_SCALE_VC_FAC, + .scale_hy_shd = ISP33_BP_SCALE_HY_FAC_SHD, + .scale_hcr_shd = ISP33_BP_SCALE_HC_FAC_SHD, + .scale_vy_shd = ISP33_BP_SCALE_VY_FAC_SHD, + .scale_vc_shd = ISP33_BP_SCALE_VC_FAC_SHD, + .ctrl_shd = ISP33_BP_SCALE_CTRL_SHD, + }, + .dual_crop = { + .ctrl = ISP3X_DUAL_CROP_CTRL, + .yuvmode_mask = ISP3X_DUAL_CROP_FBC_MODE, + .h_offset = ISP3X_DUAL_CROP_FBC_H_OFFS, + .v_offset = ISP3X_DUAL_CROP_FBC_V_OFFS, + .h_size = ISP3X_DUAL_CROP_FBC_H_SIZE, + .v_size = ISP3X_DUAL_CROP_FBC_V_SIZE, + }, + .mi = { + .y_size_init = ISP3X_MI_BP_WR_Y_SIZE, + .cb_size_init = ISP3X_MI_BP_WR_CB_SIZE, + .y_base_ad_init = ISP3X_MI_BP_WR_Y_BASE, + .cb_base_ad_init = ISP3X_MI_BP_WR_CB_BASE, + .y_offs_cnt_init = ISP3X_MI_BP_WR_Y_OFFS_CNT, + .cb_offs_cnt_init = ISP3X_MI_BP_WR_CB_OFFS_CNT, + .y_base_ad_shd = ISP3X_MI_BP_WR_Y_BASE_SHD, + .y_pic_size = ISP3X_MI_BP_WR_Y_PIC_SIZE, + }, +}; + +static bool bp_is_stream_stopped(struct rkisp_stream *stream) +{ + u32 en = ISP32_BP_EN_OUT_SHD; + u32 reg = ISP32_MI_WR_CTRL2_SHD; + bool is_direct = true; + + if (!stream->ispdev->hw_dev->is_single) { + is_direct = false; + en = ISP3X_BP_ENABLE; + reg = ISP3X_MI_BP_WR_CTRL; + } + + return !(rkisp_read(stream->ispdev, reg, is_direct) & en); +} + +static void stream_self_update(struct rkisp_stream *stream) +{ + u32 mask = ISP3X_MPSELF_UPD | ISP3X_SPSELF_UPD | ISP3X_BPSELF_UPD; + u32 val; + + switch (stream->id) { + case RKISP_STREAM_MP: + val = ISP3X_MPSELF_UPD; + break; + case RKISP_STREAM_SP: + val = ISP3X_SPSELF_UPD; + break; + case RKISP_STREAM_BP: + val = ISP3X_BPSELF_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_BP: + ret = ISP_FRAME_BP; + 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_pix_format_mplane *output = &stream->out_fmt; + 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; + } + + /* bug if STREAM_BP with crop and scale */ + if (stream->id == RKISP_STREAM_BP && + (dcrop->left + dcrop->width < input_win->width) && + (dcrop->top + dcrop->height < input_win->height) && + (output->width != dcrop->width || output->height != dcrop->height)) { + v4l2_warn(&dev->v4l2_dev, + "bypasspath no support crop(%d,%d)%dx%d->scl:%dx%d, force disable crop\n", + dcrop->left, dcrop->top, dcrop->width, dcrop->height, + output->width, output->height); + dcrop->left = 0; + dcrop->top = 0; + dcrop->width = input_win->width; + dcrop->height = input_win->height; + if (dev->unite_div < ISP_UNITE_DIV2) { + rkisp_disable_dcrop(stream, async); + 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, val, mask; + 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; + } + + mask = ISP3X_RAWX_RD_BURST_MASK | ISP3X_RAWX_WR_BURST_MASK | ISP3X_RAWX_WR_GROP_MASK; + val = ISP3X_MI_NEW_WR_BURST_DIS | ISP3X_RAWX_RD_BURST_LEN(2) | + ISP3X_RAWX_WR_BURST_LEN(1) | ISP3X_RAWX_WR_GROP_MODE(3); + rkisp_unite_set_bits(dev, ISP3X_MI_RD_CTRL2, mask, val, false); + 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; + val /= DIV_ROUND_UP(fmt->bpp[0], 8); + 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) + 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 int bp_config_mi(struct rkisp_stream *stream) +{ + struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; + struct capture_fmt *fmt = &stream->out_isp_fmt; + struct rkisp_device *dev = stream->ispdev; + u32 val, mask; + + /* + * 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_BP_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); + + mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_BP_YUV_MODE; + val = rkisp_read_reg_cache(dev, ISP3X_MPFBC_CTRL) & ~mask; + + if (out_fmt->pixelformat == V4L2_PIX_FMT_NV12 || + out_fmt->pixelformat == V4L2_PIX_FMT_NV12M) + val |= ISP3X_SEPERATE_YUV_CFG; + else + val |= ISP3X_SEPERATE_YUV_CFG | ISP3X_BP_YUV_MODE; + rkisp_unite_write(dev, ISP3X_MPFBC_CTRL, val, false); + val = CIF_MI_CTRL_INIT_BASE_EN | CIF_MI_CTRL_INIT_OFFSET_EN; + rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, 0, 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); + return 0; +} + +static void mp_enable_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + struct capture_fmt *isp_fmt = &stream->out_isp_fmt; + u32 mask = CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE; + u32 val = CIF_MI_CTRL_MP_ENABLE; + + if (isp_fmt->fmt_type == FMT_BAYER) + val = CIF_MI_CTRL_RAW_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 bp_enable_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + + u32 val = stream->out_isp_fmt.write_format | + stream->out_isp_fmt.output_format | + ISP3X_BP_ENABLE | ISP3X_BP_AUTO_UPD; + + rkisp_unite_write(dev, ISP3X_MI_BP_WR_CTRL, 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) +{ + struct rkisp_device *dev = stream->ispdev; + + rkisp_unite_clear_bits(dev, ISP3X_MI_WR_CTRL, CIF_MI_CTRL_SP_ENABLE, false); +} + +static void bp_disable_mi(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + + rkisp_unite_clear_bits(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_BP_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; + bool is_cr_cfg = false; + + if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) + is_cr_cfg = true; + + 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); + + if (is_cr_cfg) { + 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); + + if (is_cr_cfg) { + 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 (dev->unite_div == ISP_UNITE_DIV4) { + /* left bottom of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += (out_fmt->plane_fmt[0].bytesperline * out_fmt->height / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += (out_fmt->plane_fmt[1].sizeimage / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + + if (is_cr_cfg) { + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += (out_fmt->plane_fmt[2].sizeimage / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + } + /* right bottom of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += (out_fmt->plane_fmt[0].bytesperline * out_fmt->height / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += (out_fmt->plane_fmt[1].sizeimage / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); + + if (is_cr_cfg) { + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += (out_fmt->plane_fmt[2].sizeimage / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, 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); + if (is_cr_cfg) { + 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 set_mirror_flip(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + u32 tmp, val = 0; + + if (!stream->is_mf_upd) + return 0; + + stream->is_mf_upd = false; + if (dev->cap_dev.is_mirror) + rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL0, 0, ISP32_MIR_ENABLE, false); + else + rkisp_unite_clear_bits(dev, ISP3X_ISP_CTRL0, ISP32_MIR_ENABLE, false); + + switch (stream->id) { + case RKISP_STREAM_SP: + val = ISP32_SP_WR_V_FLIP; + break; + case RKISP_STREAM_BP: + val = ISP32_BP_WR_V_FLIP; + break; + default: + val = ISP32_MP_WR_V_FLIP; + if (dev->cap_dev.wrap_line) { + stream->is_flip = false; + return -EINVAL; + } + } + + tmp = rkisp_read_reg_cache(dev, ISP32_MI_WR_VFLIP_CTRL); + if (stream->is_flip) + rkisp_unite_write(dev, ISP32_MI_WR_VFLIP_CTRL, tmp | val, false); + else + rkisp_unite_write(dev, ISP32_MI_WR_VFLIP_CTRL, tmp & ~val, false); + return 0; +} + +static int mp_set_wrap(struct rkisp_stream *stream, int line) +{ + struct rkisp_device *dev = stream->ispdev; + int ret = 0; + + dev->cap_dev.wrap_line = line; + if (dev->is_pre_on && + stream->streaming && + !stream->dummy_buf.mem_priv) { + ret = rkisp_create_dummy_buf(stream); + if (ret) + return ret; + rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, + ISP33_SW_ISP2ENC_PATH_EN | ISP33_PP_ENC_PIPE_EN, false); + stream->ops->config_mi(stream); + if (stream->is_pause) { + stream->ops->enable_mi(stream); + if (!ISP3X_ISP_OUT_LINE(rkisp_read(dev, ISP3X_ISP_DEBUG2, true))) + stream_self_update(stream); + stream->is_pause = false; + } + } + return ret; +} + +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 struct streams_ops rkisp_bp_streams_ops = { + .config_mi = bp_config_mi, + .enable_mi = bp_enable_mi, + .disable_mi = bp_disable_mi, + .is_stream_stopped = bp_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.dma_addr)) { + set_mirror_flip(stream); + 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 { + buf = stream->curr_buf; + } + + 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; + buf->vb.vb2_buf.timestamp = ns; + ns = rkisp_time_get_ns(dev); + stream->dbg.interval = ns - stream->dbg.timestamp; + stream->dbg.delay = ns - dev->isp_sdev.frm_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; + set_mirror_flip(stream); + spin_lock_irqsave(&stream->vbq_lock, lock_flags); + 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 || + stream->id == RKISP_STREAM_BP) { + 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->dma_addr) { + 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.dma_addr && + 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; + if (dev->hw_dev->unite) + stream->config->max_rsz_width *= 2; + break; + case RKISP_STREAM_BP: + strscpy(vdev->name, BP_VDEV_NAME, sizeof(vdev->name)); + stream->ops = &rkisp_bp_streams_ops; + stream->config = &rkisp_bp_stream_cfg; + if (dev->hw_dev->unite) + stream->config->max_rsz_width *= 2; + 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; + if (dev->hw_dev->unite) { + stream->config->max_rsz_width = CIF_ISP_INPUT_W_MAX_V33_UNITE; + stream->config->max_rsz_height = CIF_ISP_INPUT_H_MAX_V33_UNITE; + } + } + + 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_v33(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_BP); + if (ret < 0) + goto err_free_sp; + + ret = rkisp_stream_init(dev, RKISP_STREAM_VIR); + if (ret < 0) + goto err_free_bp; + + rkisp_dvbm_get(dev); + rkisp_rockit_dev_init(dev); + + return 0; +err_free_bp: + rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_BP]); +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_v33(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_BP]; + 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_v33_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_MAX_STREAM; ++i) { + stream = &dev->cap_dev.stream[i]; + + if (!(mis_val & CIF_MI_FRAME(stream)) || + stream->id == RKISP_STREAM_VIR) + 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); + rkisp_dmarx_get_frame(dev, &seq, NULL, NULL, true); + stream->dbg.interval = ns - stream->dbg.timestamp; + stream->dbg.delay = ns - dev->isp_sdev.frm_timestamp; + stream->dbg.timestamp = ns; + stream->dbg.id = seq; + set_mirror_flip(stream); + } 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); + } + if (mis_val & ISP3X_MI_BP_FRAME) { + stream = &dev->cap_dev.stream[RKISP_STREAM_BP]; + if (!stream->streaming) + dev->irq_ends_mask &= ~ISP_FRAME_BP; + rkisp_check_idle(dev, ISP_FRAME_BP); + } +} diff --git a/drivers/media/platform/rockchip/isp/capture_v3x.h b/drivers/media/platform/rockchip/isp/capture_v3x.h index 07bc5b1c53fb..be9860dc1ae1 100644 --- a/drivers/media/platform/rockchip/isp/capture_v3x.h +++ b/drivers/media/platform/rockchip/isp/capture_v3x.h @@ -24,7 +24,23 @@ static inline void rkisp_mi_v30_isr(u32 mis_val, struct rkisp_device *dev) {} int rkisp_register_stream_v32(struct rkisp_device *dev); void rkisp_unregister_stream_v32(struct rkisp_device *dev); void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev); +#else +static inline int rkisp_register_stream_v32(struct rkisp_device *dev) { return -EINVAL; } +static inline void rkisp_unregister_stream_v32(struct rkisp_device *dev) {} +static inline void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) {} +#endif +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) +int rkisp_register_stream_v33(struct rkisp_device *dev); +void rkisp_unregister_stream_v33(struct rkisp_device *dev); +void rkisp_mi_v33_isr(u32 mis_val, struct rkisp_device *dev); +#else +static inline int rkisp_register_stream_v33(struct rkisp_device *dev) { return -EINVAL; } +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) 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); @@ -32,12 +48,8 @@ void rkisp_rockit_dev_deinit(void); void rkisp_rockit_frame_start(struct rkisp_device *dev); int rkisp_rockit_fps_set(int *dst_fps, struct rkisp_stream *stream); int rkisp_rockit_fps_get(int *dst_fps, struct rkisp_stream *stream); -int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd); +int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd, struct rkisp_buffer *curr_buf); #else -static inline int rkisp_register_stream_v32(struct rkisp_device *dev) { return -EINVAL; } -static inline void rkisp_unregister_stream_v32(struct rkisp_device *dev) {} -static inline void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) {} - static inline void rkisp_rockit_buf_state_clear(struct rkisp_stream *stream) { return; } static inline int rkisp_rockit_buf_free(struct rkisp_stream *stream) { return -EINVAL; } static inline void rkisp_rockit_dev_init(struct rkisp_device *dev) { return; } @@ -45,7 +57,8 @@ static inline void rkisp_rockit_dev_deinit(void) {} static inline void rkisp_rockit_frame_start(struct rkisp_device *dev) {} static inline int rkisp_rockit_fps_set(int *dst_fps, struct rkisp_stream *stream) { return -EINVAL; } static inline int rkisp_rockit_fps_get(int *dst_fps, struct rkisp_stream *stream) { return -EINVAL; } -static inline int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) { return -EINVAL; } +static inline int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd, + struct rkisp_buffer *curr_buf) { return -EINVAL; } #endif #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39) @@ -63,12 +76,12 @@ static inline void rkisp_stream_ldc_end_v39(struct rkisp_device *dev) {} #if IS_ENABLED(CONFIG_ROCKCHIP_DVBM) int rkisp_dvbm_get(struct rkisp_device *dev); int rkisp_dvbm_init(struct rkisp_stream *stream); -void rkisp_dvbm_deinit(void); +void rkisp_dvbm_deinit(struct rkisp_device *dev); int rkisp_dvbm_event(struct rkisp_device *dev, u32 event); #else static inline int rkisp_dvbm_get(struct rkisp_device *dev) { return -EINVAL; } static inline int rkisp_dvbm_init(struct rkisp_stream *stream) { return -EINVAL; } -static inline void rkisp_dvbm_deinit(void) {} +static inline void rkisp_dvbm_deinit(struct rkisp_device *dev) {} static inline int rkisp_dvbm_event(struct rkisp_device *dev, u32 event) { return -EINVAL; } #endif diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index 31fe49bd32f1..84fba4017ff9 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -227,8 +227,6 @@ int rkisp_buf_get_fd(struct rkisp_device *dev, if (!buf || !buf->mem_priv) return -EINVAL; - if (try_fd && buf->is_need_dmafd) - return 0; if (try_fd) { buf->is_need_dbuf = true; buf->is_need_dmafd = true; @@ -532,7 +530,7 @@ u64 rkisp_time_get_ns(struct rkisp_device *dev) { u64 ns; - if (dev->isp_ver == ISP_V32) + if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) ns = ktime_get_boottime_ns(); else ns = ktime_get_ns(); diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index c7acd5030972..f77364e922ed 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -146,6 +146,7 @@ extern bool rkisp_irq_dbg; extern bool rkisp_buf_dbg; extern u64 rkisp_debug_reg; extern unsigned int rkisp_vicap_buf[DEV_MAX]; +extern unsigned int rkisp_hdr_wrap_line[DEV_MAX]; extern struct platform_driver rkisp_plat_drv; static inline diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index 9b6915882cb4..6b045b5d9960 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -524,7 +524,7 @@ int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg) return v4l2_subdev_call(sd, core, ioctl, RKMODULE_GET_HDR_CFG, cfg); } -int rkisp_csi_config_patch(struct rkisp_device *dev) +int rkisp_csi_config_patch(struct rkisp_device *dev, bool is_pre_cfg) { int val = 0, ret = 0; struct v4l2_subdev *mipi_sensor; @@ -541,7 +541,8 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) ret = rkisp_csi_get_hdr_cfg(dev, &hdr_cfg); if (dev->isp_inp & INP_CIF) { struct rkisp_vicap_mode mode; - int buf_cnt = 0; + struct rkisp_init_buf init_buf = { 0 }; + u32 op_mode; memset(&mode, 0, sizeof(mode)); mode.name = dev->name; @@ -563,46 +564,79 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) if (dev->isp_inp == INP_CIF && dev->isp_ver > ISP_V21) { /* read back mode default if more sensor link to isp */ - if (!dev->hw_dev->is_single) + if (!dev->hw_dev->is_single && !dev->is_m_online) dev->is_rdbk_auto = true; - mode.rdbk_mode = dev->is_rdbk_auto ? RKISP_VICAP_RDBK_AUTO : RKISP_VICAP_ONLINE; + if (dev->is_m_online && dev->unite_div == ISP_UNITE_DIV2) + mode.rdbk_mode = RKISP_VICAP_ONLINE_UNITE; + else if (dev->is_m_online) + mode.rdbk_mode = RKISP_VICAP_ONLINE_MULTI; + else if (dev->is_rdbk_auto) + mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO; + else + mode.rdbk_mode = RKISP_VICAP_ONLINE; } else { mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ; } + /* vicap pre capture raw for thunderboot mode */ + if (is_pre_cfg) + mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO; + mode.dev_id = dev->dev_id; v4l2_subdev_call(mipi_sensor, core, ioctl, RKISP_VICAP_CMD_MODE, &mode); dev->vicap_in = mode.input; + + op_mode = dev->hdr.op_mode; /* vicap direct to isp */ - if (dev->isp_ver >= ISP_V30 && !mode.rdbk_mode) { - switch (dev->hdr.op_mode) { + if (dev->isp_ver >= ISP_V30 && + mode.rdbk_mode <= RKISP_VICAP_ONLINE_UNITE) { + switch (op_mode) { case HDR_RDBK_FRAME3: - dev->hdr.op_mode = HDR_LINEX3_DDR; + op_mode = HDR_LINEX3_DDR; break; case HDR_RDBK_FRAME2: - dev->hdr.op_mode = HDR_LINEX2_DDR; + op_mode = HDR_LINEX2_DDR; break; default: - dev->hdr.op_mode = HDR_NORMAL; + op_mode = HDR_NORMAL; + dev->hdr_wrap_line = 0; } - if (dev->hdr.op_mode != HDR_NORMAL) { - buf_cnt = 1; + if (op_mode != HDR_NORMAL || + mode.rdbk_mode == RKISP_VICAP_ONLINE_UNITE) { + init_buf.buf_cnt = 1; + init_buf.hdr_wrap_line = dev->hdr_wrap_line; } } else if (mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) { + dev->hdr_wrap_line = 0; if (dev->vicap_buf_cnt) - buf_cnt = dev->vicap_buf_cnt; + init_buf.buf_cnt = dev->vicap_buf_cnt; else - buf_cnt = RKISP_VICAP_BUF_CNT; + init_buf.buf_cnt = RKISP_VICAP_BUF_CNT; } - if (buf_cnt) + if (init_buf.buf_cnt) { + if (!dev->is_pre_on || is_pre_cfg) + dev->rd_mode = op_mode; v4l2_subdev_call(mipi_sensor, core, ioctl, - RKISP_VICAP_CMD_INIT_BUF, &buf_cnt); + 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) { + val = ISP33_SW_ISP2ENC_PATH_EN | ISP33_PP_ENC_PIPE_EN; + rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, val, false); + } + return 0; + } + dev->hdr.op_mode = op_mode; } else { dev->hdr.op_mode = hdr_cfg.hdr_mode; } - if (!dev->hw_dev->is_mi_update) + if (dev->isp_ver < ISP_V30) { + if (!dev->hw_dev->is_mi_update) + rkisp_unite_write(dev, CSI2RX_CTRL0, + SW_IBUF_OP_MODE(dev->hdr.op_mode), true); + } else { rkisp_unite_write(dev, CSI2RX_CTRL0, - SW_IBUF_OP_MODE(dev->hdr.op_mode), true); - + SW_IBUF_OP_MODE(dev->hdr.op_mode), false); + } /* hdr merge */ switch (dev->hdr.op_mode) { case HDR_RDBK_FRAME2: @@ -633,11 +667,18 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, val, true); } + val = 0; if (IS_HDR_RDBK(dev->hdr.op_mode)) - rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS, true); - + val |= SW_MPIP_DROP_FRM_DIS; + if (dev->isp_ver == ISP_V33 && dev->cap_dev.wrap_line) { + val |= ISP33_SW_ISP2ENC_PATH_EN; + if (IS_HDR_RDBK(dev->hdr.op_mode)) + val |= ISP33_PP_ENC_PIPE_EN; + } if (dev->isp_ver >= ISP_V30) - rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP3X_SW_ACK_FRM_PRO_DIS, true); + val |= ISP3X_SW_ACK_FRM_PRO_DIS; + if (val) + rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, val, false); /* line counter from isp out, default from mp out */ if (dev->isp_ver == ISP_V32_L || dev->isp_ver == ISP_V39) rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP32L_ISP2ENC_CNT_MUX, true); diff --git a/drivers/media/platform/rockchip/isp/csi.h b/drivers/media/platform/rockchip/isp/csi.h index 9fbdc35b4405..8e059c5414e7 100644 --- a/drivers/media/platform/rockchip/isp/csi.h +++ b/drivers/media/platform/rockchip/isp/csi.h @@ -78,7 +78,7 @@ int rkisp_register_csi_subdev(struct rkisp_device *dev, struct v4l2_device *v4l2_dev); void rkisp_unregister_csi_subdev(struct rkisp_device *dev); int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg); -int rkisp_csi_config_patch(struct rkisp_device *dev); +int rkisp_csi_config_patch(struct rkisp_device *dev, bool is_pre_cfg); void rkisp_csi_sof(struct rkisp_device *dev, u8 id); void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev, struct v4l2_subdev **sensor_sd, u32 function); diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 49999b58ea87..c72cfc41c0eb 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -79,6 +79,10 @@ static bool rkisp_clk_dbg; module_param_named(clk_dbg, rkisp_clk_dbg, bool, 0644); MODULE_PARM_DESC(clk_dbg, "rkisp clk set by user"); +static bool rkisp_m_online[DEV_MAX]; +module_param_array_named(m_online, rkisp_m_online, bool, NULL, 0644); +MODULE_PARM_DESC(m_online, "rkisp multi sensor online mode"); + static char rkisp_version[RKISP_VERNO_LEN]; module_param_string(version, rkisp_version, RKISP_VERNO_LEN, 0444); MODULE_PARM_DESC(version, "version number"); @@ -99,6 +103,10 @@ unsigned int rkisp_vicap_buf[DEV_MAX]; module_param_array_named(vicap_raw_buf, rkisp_vicap_buf, uint, NULL, 0644); MODULE_PARM_DESC(vicap_raw_buf, "rkisp and vicap auto readback mode raw buf count"); +unsigned int rkisp_hdr_wrap_line[DEV_MAX]; +module_param_array_named(hdr_wrap_line, rkisp_hdr_wrap_line, uint, NULL, 0644); +MODULE_PARM_DESC(hdr_wrap_line, "rkisp and vicap online hdr wrap line"); + static DEFINE_MUTEX(rkisp_dev_mutex); static LIST_HEAD(rkisp_device_list); @@ -269,7 +277,7 @@ end: if (hw_dev->unite == ISP_UNITE_TWO) rkisp_set_clk_rate(hw_dev->clks[5], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL); /* aclk equal to core clk */ - if (dev->isp_ver == ISP_V32) + if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) rkisp_set_clk_rate(hw_dev->clks[1], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL); dev_info(hw_dev->dev, "set isp clk = %luHz\n", clk_get_rate(hw_dev->clks[0])); @@ -289,6 +297,7 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, if (atomic_inc_return(&p->power_cnt) > 1) return 0; + dev->hdr_wrap_line = 0; if (hw->is_assigned_clk) rkisp_clk_dbg = true; if (!(dev->isp_inp & (INP_RAWRD0 | INP_RAWRD2))) { @@ -298,6 +307,14 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, if (rkisp_vicap_buf[dev->dev_id] > RKISP_VICAP_BUF_CNT_MAX) 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) + dev->is_m_online = false; + if (hw->isp_ver == ISP_V33) { + 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]; + } } dev->cap_dev.wait_line = rkisp_wait_line; @@ -316,7 +333,7 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, dev->hw_dev->monitor.is_en = rkisp_monitor; if (dev->isp_inp & (INP_CSI | INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF)) - rkisp_csi_config_patch(dev); + rkisp_csi_config_patch(dev, false); return 0; err: atomic_dec(&p->power_cnt); @@ -335,6 +352,7 @@ static int rkisp_pipeline_close(struct rkisp_pipeline *p) if (dev->hw_dev->is_runing && (dev->isp_ver >= ISP_V30) && !rkisp_clk_dbg) dev->hw_dev->is_dvfs = true; dev->is_rdbk_auto = false; + dev->is_m_online = false; return 0; } @@ -358,12 +376,17 @@ static int rkisp_pipeline_set_stream(struct rkisp_pipeline *p, bool on) ret = v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, true); if (ret < 0) goto err; + if (dev->is_m_online && !dev->is_pre_on && + atomic_read(&dev->hw_dev->refcnt) == 1) { + i = 1; + v4l2_subdev_call(p->subdevs[0], core, ioctl, RKISP_VICAP_CMD_HW_LINK, &i); + } /* phy -> sensor */ for (i = 0; i < p->num_subdevs; ++i) { if (((dev->vicap_in.merge_num > 1) && (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR)) || - (dev->isp_inp & INP_CIF && IS_HDR_RDBK(dev->rd_mode) && - (!dev->is_rdbk_auto))) + ((dev->isp_inp & (INP_CIF | INP_RAWRD2)) == (INP_CIF | INP_RAWRD2)) || + dev->is_pre_on) continue; ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on); if (on && ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) @@ -384,8 +407,7 @@ static int rkisp_pipeline_set_stream(struct rkisp_pipeline *p, bool on) for (i = p->num_subdevs - 1; i >= 0; --i) { if (((dev->vicap_in.merge_num > 1) && (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR)) || - (dev->isp_inp & INP_CIF && IS_HDR_RDBK(dev->rd_mode) && - (!dev->is_rdbk_auto))) + ((dev->isp_inp & (INP_CIF | INP_RAWRD2)) == (INP_CIF | INP_RAWRD2))) continue; v4l2_subdev_call(p->subdevs[i], video, s_stream, on); } @@ -569,6 +591,9 @@ static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init) } if (dev->isp_ver == ISP_V39) rkisp_set_stream_def_fmt(dev, RKISP_STREAM_LDC, width, height, V4L2_PIX_FMT_NV12); + if (dev->isp_ver == ISP_V33) + rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP, + width, height, V4L2_PIX_FMT_NV12); return 0; } @@ -1082,12 +1107,13 @@ static int rkisp_pm_prepare(struct device *dev) return 0; } -static void rkisp_pm_complete(struct device *dev) +static int rkisp_resume(struct device *dev) { struct rkisp_device *isp_dev = dev_get_drvdata(dev); struct rkisp_hw_dev *hw = isp_dev->hw_dev; struct rkisp_pipeline *p = &isp_dev->pipe; struct rkisp_stream *stream; + struct rkisp_device *isp_tmp; int i, on = 1, rd_mode = isp_dev->rd_mode; u32 val; @@ -1100,7 +1126,7 @@ static void rkisp_pm_complete(struct device *dev) if (mipi_sensor) v4l2_subdev_call(mipi_sensor, core, s_power, 1); } - return; + return 0; } if (isp_dev->is_rtt_suspend) { @@ -1182,21 +1208,66 @@ static void rkisp_pm_complete(struct device *dev) if (isp_dev->is_first_double) stream->skip_frame = 1; } - if (hw->cur_dev_id == isp_dev->dev_id) + if (hw->cur_dev_id == isp_dev->dev_id) { + if (atomic_read(&hw->refcnt) == 2) { + /* isp0 online, isp1 offline, isp0 to running first */ + isp_tmp = hw->isp[!isp_dev->dev_id]; + if (isp_dev->dev_id && !(IS_HDR_RDBK(isp_tmp->rd_mode))) + hw->is_idle = false; + } rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL); - + } if (rkisp_link_sensor(isp_dev->isp_inp)) { for (i = 0; i < p->num_subdevs; i++) v4l2_subdev_call(p->subdevs[i], core, s_power, 1); for (i = 0; i < p->num_subdevs; i++) v4l2_subdev_call(p->subdevs[i], video, s_stream, on); - } else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) { + } else if (isp_dev->isp_inp & INP_CIF && !IS_HDR_RDBK(isp_dev->rd_mode)) { + if (!hw->is_single) { + int on = 1; + + if (atomic_read(&hw->refcnt) == 2) { + /* isp0 and isp1 online, isp1 to running first */ + isp_tmp = hw->isp[!isp_dev->dev_id]; + if (!IS_HDR_RDBK(isp_tmp->rd_mode) && !isp_dev->dev_id) + on = 0; + } else if (isp_dev->unite_div == ISP_UNITE_DIV2) { + isp_dev->unite_index = ISP_UNITE_LEFT; + isp_dev->params_vdev.rdbk_times = 2; + } + if (on) { + hw->cur_dev_id = isp_dev->dev_id; + hw->is_idle = false; + rkisp_online_update_reg(isp_dev, false, true); + rkisp_vicap_hw_link(isp_dev, on); + } + } v4l2_subdev_call(p->subdevs[0], core, ioctl, RKISP_VICAP_CMD_QUICK_STREAM, &on); } + return 0; +} + +static int rkisp_pm_resume(struct device *dev) +{ + struct rkisp_device *isp_dev = dev_get_drvdata(dev); + + if (isp_dev->isp_ver == ISP_V33) + return rkisp_resume(dev); + return 0; +} + +static void rkisp_pm_complete(struct device *dev) +{ + struct rkisp_device *isp_dev = dev_get_drvdata(dev); + + if (isp_dev->isp_ver == ISP_V33) + return; + rkisp_resume(dev); } static const struct dev_pm_ops rkisp_plat_pm_ops = { .prepare = rkisp_pm_prepare, + .resume = rkisp_pm_resume, .complete = rkisp_pm_complete, SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL) }; diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index 1670cec2488c..7aae9ef06a63 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -296,6 +296,7 @@ struct rkisp_device { bool is_hw_link; bool is_bigmode; bool is_rdbk_auto; + bool is_m_online; bool is_pre_on; bool is_first_double; bool is_probe_end; @@ -305,8 +306,12 @@ struct rkisp_device { bool is_suspend_one_frame; bool is_aiisp_en; bool is_aiisp_upd; + bool is_frm_rd; + bool is_multi_one_sync; + bool is_wait_aiq; struct rkisp_vicap_input vicap_in; + u32 hdr_wrap_line; u8 multi_mode; u8 multi_index; @@ -315,6 +320,9 @@ struct rkisp_device { u8 unite_div; }; +void rkisp_vicap_hw_link(struct rkisp_device *dev, int on); +void rkisp_online_update_reg(struct rkisp_device *dev, bool is_init, bool is_reset); + static inline void rkisp_unite_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) { diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index 22691b78f289..df42ee814161 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -482,6 +482,8 @@ static int dmarx_frame_end(struct rkisp_stream *stream) { struct rkisp_buffer *buf = NULL; unsigned long lock_flags = 0; + u32 val, reg; + int on = 1; spin_lock_irqsave(&stream->vbq_lock, lock_flags); if (stream->curr_buf) { @@ -518,14 +520,31 @@ static int dmarx_frame_end(struct rkisp_stream *stream) dev->rd_mode = HDR_NORMAL; } dev->hdr.op_mode = dev->rd_mode; - rkisp_unite_write(dev, CSI2RX_CTRL0, - SW_IBUF_OP_MODE(dev->hdr.op_mode), true); - rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, - 0, ISP21_MIPI_DROP_FRM, true); - rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, CIF_ISP_FRAME_IN, true); + val = SW_IBUF_OP_MODE(dev->hdr.op_mode); + rkisp_unite_write(dev, CSI2RX_CTRL0, val, false); + val = ISP21_MIPI_DROP_FRM; + rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, val, false); + rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, CIF_ISP_FRAME_IN, false); + if (dev->isp_ver == ISP_V33) { + val = ISP33_PP_ENC_PIPE_EN; + rkisp_unite_clear_bits(dev, CTRL_SWS_CFG, val, false); + if (dev->hdr_wrap_line) { + val = stream->out_fmt.plane_fmt[0].bytesperline * dev->hdr_wrap_line; + rkisp_unite_write(dev, ISP32_MI_RAW0_RD_SIZE, val, false); + } + if (dev->unite_div == ISP_UNITE_DIV2) { + mi_raw_length(stream); + reg = stream->config->mi.y_base_ad_init; + rkisp_unite_write(dev, reg, rx_buf->dma, false); + dev->unite_index = ISP_UNITE_LEFT; + dev->params_vdev.rdbk_times = 2; + } + } dev_info(dev->dev, "switch online seq:%d mode:0x%x\n", rx_buf->sequence, dev->rd_mode); + if (dev->hw_dev->is_single) + v4l2_subdev_call(sd, core, ioctl, RKISP_VICAP_CMD_HW_LINK, &on); } rx_buf->runtime_us = dev->isp_sdev.dbg.interval / 1000; v4l2_subdev_call(sd, video, s_rx_buffer, rx_buf, NULL); diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index afc9dbdfce41..cf7668b3a028 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -128,6 +128,22 @@ static void default_sw_reg_flag(struct rkisp_device *dev) 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, + }; u32 i, j, *flag, *reg, size; switch (dev->isp_ver) { @@ -152,6 +168,10 @@ static void default_sw_reg_flag(struct rkisp_device *dev) reg = v39_reg; size = ARRAY_SIZE(v39_reg); break; + case ISP_V33: + reg = v33_reg; + size = ARRAY_SIZE(v33_reg); + break; default: return; } @@ -351,7 +371,7 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) ISP_RAWHIST_LITE_BASE, ISP_RAWHIST_BIG1_BASE, ISP_RAWHIST_BIG2_BASE, ISP_RAWHIST_BIG3_BASE, ISP_RAWAF_BASE, ISP_RAWAWB_BASE, ISP_LDCH_BASE, - ISP3X_CAC_BASE, + ISP3X_CAC_BASE, ISP33_BAY3D_CTRL0, ISP33_ENH_CTRL }; struct backup_reg backup[] = { { @@ -454,11 +474,15 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) for (j = 0; j < RKISP_ISP_SW_REG_SIZE; j += 4) { /* skip table RAM */ if ((j > ISP3X_LSC_CTRL && j < ISP3X_LSC_XGRAD_01) || - (j > ISP32_CAC_OFFSET && j < ISP3X_CAC_RO_CNT) || + (j > ISP32_CAC_OFFSET && j < ISP3X_CAC_RO_CNT && dev->isp_ver != ISP_V33) || (j > ISP3X_3DLUT_UPDATE && j < ISP3X_GAIN_BASE) || (j == 0x4840 || j == 0x4a80 || j == 0x4b40 || j == 0x5660) || (dev->isp_ver == ISP_V39 && - (j > ISP39_DHAZ_HIST_IIR0 && j < ISP39_DHAZ_LINE_CNT))) + (j > ISP39_DHAZ_HIST_IIR0 && j < ISP39_DHAZ_LINE_CNT)) || + (dev->isp_ver == ISP_V33 && + ((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)))) continue; /* skip mmu range */ if (dev->isp_ver < ISP_V30 && @@ -492,25 +516,27 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) } writel(val, base + backup[j].base); } - if (dev->isp_ver == ISP_V32) { + if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) { reg = reg_buf + ISP32_MI_WR_CTRL2_SHD; reg1 = reg_buf + ISP3X_MI_BP_WR_CTRL; - if ((*reg & ISP32_BP_EN_IN_SHD) != (*reg1 & ISP3X_BP_ENABLE)) { - val = *reg & ISP32_BP_EN_IN_SHD; - val |= *reg1 & ~ISP3X_BP_ENABLE; + if (!!(*reg & ISP32_BP_EN_IN_SHD) != !!(*reg1 & ISP3X_BP_ENABLE)) { + val = !!(*reg & ISP32_BP_EN_IN_SHD); + val |= (*reg1 & ~ISP3X_BP_ENABLE); writel(val, base + ISP3X_MI_BP_WR_CTRL); } - reg1 = reg_buf + ISP32_MI_MPDS_WR_CTRL; - if ((*reg & ISP32_MPDS_EN_IN_SHD) != (*reg1 & ISP32_DS_ENABLE)) { - val = *reg & ISP32_MPDS_EN_IN_SHD; - val |= *reg1 & ~ISP32_DS_ENABLE; - writel(val, base + ISP32_MI_MPDS_WR_CTRL); - } - reg1 = reg_buf + ISP32_MI_BPDS_WR_CTRL; - if ((*reg & ISP32_BPDS_EN_IN_SHD) != (*reg1 & ISP32_DS_ENABLE)) { - val = *reg & ISP32_BPDS_EN_IN_SHD; - val |= *reg1 & ~ISP32_DS_ENABLE; - writel(val, base + ISP32_MI_BPDS_WR_CTRL); + if (dev->isp_ver == ISP_V32) { + reg1 = reg_buf + ISP32_MI_MPDS_WR_CTRL; + if (!!(*reg & ISP32_MPDS_EN_IN_SHD) != !!(*reg1 & ISP32_DS_ENABLE)) { + val = !!(*reg & ISP32_MPDS_EN_IN_SHD); + val |= (*reg1 & ~ISP32_DS_ENABLE); + writel(val, base + ISP32_MI_MPDS_WR_CTRL); + } + reg1 = reg_buf + ISP32_MI_BPDS_WR_CTRL; + if (!!(*reg & ISP32_BPDS_EN_IN_SHD) != !!(*reg1 & ISP32_DS_ENABLE)) { + val = !!(*reg & ISP32_BPDS_EN_IN_SHD); + val |= (*reg1 & ~ISP32_DS_ENABLE); + writel(val, base + ISP32_MI_BPDS_WR_CTRL); + } } } @@ -520,7 +546,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) + if (dev->isp_ver == ISP_V32_L || dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33) writel(ISP32_SCALE_FORCE_UPD | ISP32_SCALE_GEN_UPD, base + ISP32_SELF_SCALE_UPDATE); else @@ -528,28 +554,35 @@ 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) + if (dev->isp_ver == ISP_V39 || dev->isp_ver == ISP_V33) writel(ISP32_SCALE_FORCE_UPD | ISP32_SCALE_GEN_UPD, base + ISP39_MAIN_SCALE_UPDATE); else writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL); } reg = reg_buf + ISP32_BP_RESIZE_CTRL; - if (*reg & 0xf) - writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + ISP32_BP_RESIZE_CTRL); + if (*reg & 0xf) { + if (dev->isp_ver == ISP_V33) + writel(ISP32_SCALE_FORCE_UPD | ISP32_SCALE_GEN_UPD, + base + ISP33_BP_SCALE_UPDATE); + else + writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + ISP32_BP_RESIZE_CTRL); + } /* update mi and isp, base_reg will update to shd_reg */ writel(CIF_MI_INIT_SOFT_UPD, base + MI_WR_INIT); /* config base_reg */ for (j = 0; j < ARRAY_SIZE(backup); j++) writel(backup[j].val, base + backup[j].base); - if (dev->isp_ver == ISP_V32) { + if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) { reg = reg_buf + ISP3X_MI_BP_WR_CTRL; writel(*reg, base + ISP3X_MI_BP_WR_CTRL); - reg = reg_buf + ISP32_MI_MPDS_WR_CTRL; - writel(*reg, base + ISP32_MI_MPDS_WR_CTRL); - reg = reg_buf + ISP32_MI_BPDS_WR_CTRL; - writel(*reg, base + ISP32_MI_BPDS_WR_CTRL); + if (dev->isp_ver == ISP_V32) { + reg = reg_buf + ISP32_MI_MPDS_WR_CTRL; + writel(*reg, base + ISP32_MI_MPDS_WR_CTRL); + reg = reg_buf + ISP32_MI_BPDS_WR_CTRL; + writel(*reg, base + ISP32_MI_BPDS_WR_CTRL); + } } /* base_reg = shd_reg, write is base but read is shd */ val = rkisp_read_reg_cache(isp, ISP_MPFBC_HEAD_PTR); @@ -557,7 +590,7 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) val = rkisp_read_reg_cache(isp, MI_SWS_3A_WR_BASE); writel(val, base + MI_SWS_3A_WR_BASE); /* force for cac to read lut */ - if (dev->isp_ver >= ISP_V33) { + if (dev->isp_ver == ISP_V39) { val = rkisp_read_reg_cache(isp, ISP3X_CAC_BASE); writel(val, base + ISP3X_CAC_BASE); } @@ -584,6 +617,17 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) 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 */ + 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); } reg = reg_buf + ISP_CTRL; @@ -594,17 +638,19 @@ 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) { + if (dev->isp_ver == ISP_V39 || 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_AF_ADDR; - writel(*reg, dev->base_addr + ISP39_W3A_AF_ADDR); reg = reg_buf + ISP39_W3A_AWB_ADDR; writel(*reg, dev->base_addr + ISP39_W3A_AWB_ADDR); - reg = reg_buf + ISP39_W3A_PDAF_ADDR; - writel(*reg, dev->base_addr + ISP39_W3A_PDAF_ADDR); + if (dev->isp_ver == ISP_V39) { + reg = reg_buf + ISP39_W3A_AF_ADDR; + writel(*reg, dev->base_addr + ISP39_W3A_AF_ADDR); + reg = reg_buf + ISP39_W3A_PDAF_ADDR; + writel(*reg, dev->base_addr + ISP39_W3A_PDAF_ADDR); + } } } } @@ -805,6 +851,17 @@ static struct isp_irqs_data rv1126_isp_irqs[] = { {"mipi_irq", mipi_irq_hdl} }; +static const struct isp_match_data rv1103b_isp_match_data = { + .clks = rv1106_isp_clks, + .num_clks = ARRAY_SIZE(rv1106_isp_clks), + .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), + .unite = false, +}; + static const struct isp_match_data rv1106_isp_match_data = { .clks = rv1106_isp_clks, .num_clks = ARRAY_SIZE(rv1106_isp_clks), @@ -910,6 +967,12 @@ static const struct of_device_id rkisp_hw_of_match[] = { .data = &rk3588_isp_unite_match_data, }, #endif +#ifdef CONFIG_CPU_RV1103B + { + .compatible = "rockchip,rv1103b-rkisp", + .data = &rv1103b_isp_match_data, + }, +#endif #ifdef CONFIG_CPU_RV1106 { .compatible = "rockchip,rv1106-rkisp", @@ -1023,6 +1086,30 @@ void rkisp_soft_reset(struct rkisp_hw_dev *dev, bool is_secure) writel(ISP39_W3A_PDAF2DDR_HOLD_DIS | ISP39_W3A_3A_HOLD_DIS, dev->base_addr + ISP39_W3A_CTRL0); writel(0, dev->base_addr + ISP39_VI3A_CTRL0); + } else if (dev->isp_ver == ISP_V33) { + 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, + dev->base_addr + ISP39_W3A_CTRL0); + writel(0, dev->base_addr + ISP39_LDCH_OUT_SIZE); + /* debayer reg default */ + writel(0x09aa9988, dev->base_addr + ISP3X_DEBAYER_G_INTERP); + writel(0, dev->base_addr + ISP3X_DEBAYER_G_INTERP_FILTER1); + writel(0, dev->base_addr + ISP3X_DEBAYER_G_INTERP_FILTER2); + writel(0x040d6381, dev->base_addr + ISP3X_DEBAYER_OFFSET); + writel(0x041c021e, dev->base_addr + ISP3X_DEBAYER_C_FILTER); + writel(0x041e021f, dev->base_addr + ISP32_DEBAYER_C_FILTER_GUIDE_GAUS); + writel(0x40400004, dev->base_addr + ISP32_DEBAYER_C_FILTER_CE_GAUS); + writel(0x00100010, dev->base_addr + ISP32_DEBAYER_C_FILTER_ALPHA_GAUS); + writel(0x00100010, dev->base_addr + ISP32_DEBAYER_C_FILTER_LOG_OFFSET); + writel(0x00100010, dev->base_addr + ISP32_DEBAYER_C_FILTER_ALPHA); + writel(0x00100010, dev->base_addr + ISP32_DEBAYER_C_FILTER_EDGE); + writel(0x00014001, dev->base_addr + ISP39_DEBAYER_G_FILTER_MODE_OFFSET); + writel(0x000a1018, dev->base_addr + ISP39_DEBAYER_G_FILTER_FILTER); + writel(0x08000800, dev->base_addr + ISP39_DEBAYER_G_FILTER_VSIGMA0); + 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); } } @@ -1031,7 +1118,8 @@ static void isp_config_clk(struct rkisp_hw_dev *dev, int on) u32 val = !on ? 0 : CIF_ICCL_ISP_CLK | CIF_ICCL_CP_CLK | CIF_ICCL_MRSZ_CLK | CIF_ICCL_SRSZ_CLK | CIF_ICCL_JPEG_CLK | CIF_ICCL_MI_CLK | - CIF_ICCL_IE_CLK | CIF_ICCL_MIPI_CLK | CIF_ICCL_DCROP_CLK; + CIF_ICCL_IE_CLK | CIF_ICCL_MIPI_CLK | CIF_ICCL_DCROP_CLK | + CIF_ICCL_SIMP_CLK | CIF_ICCL_SMIA_CLK; if ((dev->isp_ver == ISP_V20 || dev->isp_ver >= ISP_V30) && on) val |= ICCL_MPFBC_CLK; @@ -1477,7 +1565,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) } static const struct dev_pm_ops rkisp_hw_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL) }; diff --git a/drivers/media/platform/rockchip/isp/isp_dvbm.c b/drivers/media/platform/rockchip/isp/isp_dvbm.c index fe597add1f64..4b0967e81f43 100644 --- a/drivers/media/platform/rockchip/isp/isp_dvbm.c +++ b/drivers/media/platform/rockchip/isp/isp_dvbm.c @@ -17,7 +17,7 @@ int rkisp_dvbm_get(struct rkisp_device *dev) int ret = -EINVAL; g_dvbm = NULL; - if (dev->isp_ver != ISP_V32) + if (dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33) goto end; if (!np_dvbm || !of_device_is_available(np_dvbm)) { @@ -61,10 +61,13 @@ int rkisp_dvbm_init(struct rkisp_stream *stream) return 0; } -void rkisp_dvbm_deinit(void) +void rkisp_dvbm_deinit(struct rkisp_device *dev) { - if (g_dvbm) - rk_dvbm_unlink(g_dvbm); + if (!g_dvbm || !dev) { + pr_err("g_dvbm %p or devv %p is NULL\n", g_dvbm, dev); + return; + } + rk_dvbm_unlink(g_dvbm); } int rkisp_dvbm_event(struct rkisp_device *dev, u32 event) @@ -72,8 +75,8 @@ int rkisp_dvbm_event(struct rkisp_device *dev, u32 event) enum dvbm_cmd cmd; u32 seq; - if (!g_dvbm || dev->isp_ver != ISP_V32 || - !dev->cap_dev.wrap_line) + if (!g_dvbm || !dev->cap_dev.wrap_line || + (dev->isp_ver != ISP_V32 && dev->isp_ver != ISP_V33)) return -EINVAL; rkisp_dmarx_get_frame(dev, &seq, NULL, NULL, true); diff --git a/drivers/media/platform/rockchip/isp/isp_external.h b/drivers/media/platform/rockchip/isp/isp_external.h index 6d4907483830..480329bb2c9c 100644 --- a/drivers/media/platform/rockchip/isp/isp_external.h +++ b/drivers/media/platform/rockchip/isp/isp_external.h @@ -4,11 +4,13 @@ #ifndef _RKISP_EXTERNAL_H #define _RKISP_EXTERNAL_H +#include + #define RKISP_VICAP_CMD_MODE \ _IOWR('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_vicap_mode) #define RKISP_VICAP_CMD_INIT_BUF \ - _IOW('V', BASE_VIDIOC_PRIVATE + 1, int) + _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct rkisp_init_buf) #define RKISP_VICAP_CMD_RX_BUFFER_FREE \ _IOW('V', BASE_VIDIOC_PRIVATE + 2, struct rkisp_rx_buf) @@ -22,17 +24,30 @@ #define RKISP_VICAP_CMD_SET_STREAM \ _IOW('V', BASE_VIDIOC_PRIVATE + 5, int) +#define RKISP_VICAP_CMD_HW_LINK \ + _IOW('V', BASE_VIDIOC_PRIVATE + 6, int) + #define RKISP_VICAP_BUF_CNT 3 #define RKISP_VICAP_BUF_CNT_MAX 8 #define RKISP_RX_BUF_POOL_MAX (RKISP_VICAP_BUF_CNT_MAX * 3) +#define rkisp_cond_poll_timeout(cond, sleep_us, timeout_us) \ +({ \ + int __val; \ + read_poll_timeout((int), __val, cond, sleep_us, timeout_us, false, 0); \ +}) + struct rkisp_vicap_input { u8 merge_num; u8 index; + u8 multi_sync; }; enum rkisp_vicap_link { RKISP_VICAP_ONLINE, + RKISP_VICAP_ONLINE_ONE_FRAME, + RKISP_VICAP_ONLINE_MULTI, + RKISP_VICAP_ONLINE_UNITE, RKISP_VICAP_RDBK_AIQ, RKISP_VICAP_RDBK_AUTO, RKISP_VICAP_RDBK_AUTO_ONE_FRAME, @@ -43,6 +58,12 @@ struct rkisp_vicap_mode { enum rkisp_vicap_link rdbk_mode; struct rkisp_vicap_input input; + int dev_id; +}; + +struct rkisp_init_buf { + u32 buf_cnt; + u32 hdr_wrap_line; }; enum rx_buf_type { diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 4181c27acc6c..60909b9cf495 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -15,6 +15,7 @@ #include "isp_params_v3x.h" #include "isp_params_v32.h" #include "isp_params_v39.h" +#include "isp_params_v33.h" #include "regs.h" #define PARAMS_NAME DRIVER_NAME "-input-params" @@ -99,6 +100,8 @@ static int rkisp_get_params(struct rkisp_isp_params_vdev *params_vdev, void *arg if (params_vdev->dev->isp_ver == ISP_V39) 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); return ret; } @@ -113,6 +116,7 @@ static long rkisp_params_ioctl_default(struct file *file, void *fh, ret = rkisp_expander_config(params->dev, arg, true); break; case RKISP_CMD_GET_PARAMS_V39: + case RKISP_CMD_GET_PARAMS_V33: ret = rkisp_get_params(params, arg); break; default: @@ -216,7 +220,13 @@ static void rkisp_params_vb2_buf_queue(struct vb2_buffer *vb) list_add_tail(¶ms_buf->queue, ¶ms_vdev->params); spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); - if (params_vdev->dev->is_first_double) { + if (dev->is_wait_aiq) { + dev_info(dev->dev, "sync params for rtt\n"); + dev->is_wait_aiq = false; + dev->skip_frame = 0; + rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL); + } + if (dev->is_first_double) { struct isp32_isp_params_cfg *params = params_buf->vaddr[0]; struct rkisp_buffer *buf; @@ -232,9 +242,18 @@ static void rkisp_params_vb2_buf_queue(struct vb2_buffer *vb) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); - dev_info(params_vdev->dev->dev, - "first params:%d for rtt resume\n", params->frame_id); - params_vdev->dev->is_first_double = false; + dev_info(dev->dev, "params seq:%d for rtt\n", params->frame_id); + dev->is_first_double = false; + if (dev->isp_ver == ISP_V33) { + dev->skip_frame = 1; + dev->is_wait_aiq = true; + } + dev->sw_rd_cnt = 0; + if (dev->hw_dev->unite == ISP_UNITE_ONE) { + dev->unite_index = ISP_UNITE_LEFT; + dev->sw_rd_cnt += dev->hw_dev->is_multi_overflow ? 3 : 1; + } + params_vdev->rdbk_times = dev->sw_rd_cnt + 1; rkisp_trigger_read_back(params_vdev->dev, false, false, false); } } @@ -275,6 +294,7 @@ static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq) params_vdev->rdbk_times = 0; if (!(dev->isp_state & ISP_START)) rkisp_params_stream_stop(params_vdev); + dev->fpn_cfg.en = 0; if (dev->fpn_cfg.buf) { vfree(dev->fpn_cfg.buf); @@ -318,6 +338,10 @@ static int rkisp_params_fh_open(struct file *filp) if (!params->dev->is_probe_end) return -EINVAL; + ret = rkisp_cond_poll_timeout(!params->dev->is_thunderboot, + 5000, 1000 * USEC_PER_MSEC); + if (ret) + return ret; ret = v4l2_fh_open(filp); if (!ret) { @@ -386,21 +410,23 @@ rkisp_params_init_vb2_queue(struct vb2_queue *q, static int rkisp_init_params_vdev(struct rkisp_isp_params_vdev *params_vdev) { - int ret; + struct rkisp_device *dev = params_vdev->dev; + int ret = -EINVAL; - if (params_vdev->dev->isp_ver <= ISP_V13) + if (dev->isp_ver <= ISP_V13) ret = rkisp_init_params_vdev_v1x(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V21) + else if (dev->isp_ver == ISP_V21) ret = rkisp_init_params_vdev_v21(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V20) + else if (dev->isp_ver == ISP_V20) ret = rkisp_init_params_vdev_v2x(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V30) + else if (dev->isp_ver == ISP_V30) ret = rkisp_init_params_vdev_v3x(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V32 || - params_vdev->dev->isp_ver == ISP_V32_L) + else if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L) ret = rkisp_init_params_vdev_v32(params_vdev); - else + else if (dev->isp_ver == ISP_V39) ret = rkisp_init_params_vdev_v39(params_vdev); + else if (dev->isp_ver == ISP_V33) + ret = rkisp_init_params_vdev_v33(params_vdev); params_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS; return ret; @@ -408,19 +434,22 @@ static int rkisp_init_params_vdev(struct rkisp_isp_params_vdev *params_vdev) static void rkisp_uninit_params_vdev(struct rkisp_isp_params_vdev *params_vdev) { - if (params_vdev->dev->isp_ver <= ISP_V13) + struct rkisp_device *dev = params_vdev->dev; + + if (dev->isp_ver <= ISP_V13) rkisp_uninit_params_vdev_v1x(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V21) + else if (dev->isp_ver == ISP_V21) rkisp_uninit_params_vdev_v21(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V20) + else if (dev->isp_ver == ISP_V20) rkisp_uninit_params_vdev_v2x(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V30) + else if (dev->isp_ver == ISP_V30) rkisp_uninit_params_vdev_v3x(params_vdev); - else if (params_vdev->dev->isp_ver == ISP_V32 || - params_vdev->dev->isp_ver == ISP_V32_L) + else if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L) rkisp_uninit_params_vdev_v32(params_vdev); - else + else if (dev->isp_ver == ISP_V39) rkisp_uninit_params_vdev_v39(params_vdev); + else if (dev->isp_ver == ISP_V33) + rkisp_uninit_params_vdev_v33(params_vdev); } void rkisp_params_cfg(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id) diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index fe31b627259a..94990abb4afe 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "common.h" @@ -66,6 +67,7 @@ struct rkisp_isp_params_vdev { struct isp3x_isp_params_cfg *isp3x_params; struct isp32_isp_params_cfg *isp32_params; struct isp39_isp_params_cfg *isp39_params; + struct isp33_isp_params_cfg *isp33_params; }; struct v4l2_format vdev_fmt; bool streamon; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index 26ddc6d86c29..3dc134c30fac 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -4985,7 +4985,18 @@ rkisp_params_first_cfg_v32(struct rkisp_isp_params_vdev *params_vdev) static void rkisp_save_first_param_v32(struct rkisp_isp_params_vdev *params_vdev, void *param) { - memcpy(params_vdev->isp32_params, param, params_vdev->vdev_fmt.fmt.meta.buffersize); + u32 size; + + if (!params_vdev->dev->is_rtt_first) { + size = params_vdev->vdev_fmt.fmt.meta.buffersize; + memcpy(params_vdev->isp32_params, param, size); + } else { + /* left and right params for unit fast case */ + size = sizeof(struct isp32_isp_params_cfg); + memcpy(params_vdev->isp32_params, param, size); + if (params_vdev->dev->unite_div == ISP_UNITE_DIV2) + memcpy(params_vdev->isp32_params + 1, param, size); + } rkisp_alloc_internal_buf(params_vdev, params_vdev->isp32_params); } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v33.c b/drivers/media/platform/rockchip/isp/isp_params_v33.c new file mode 100644 index 000000000000..8523bc03023d --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_params_v33.c @@ -0,0 +1,7222 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Rockchip Electronics Co., Ltd. */ + +#include +#include +#include +#include +#include "dev.h" +#include "regs.h" +#include "isp_params_v33.h" + +#define ISP33_MODULE_EN BIT(0) +#define ISP33_SELF_FORCE_UPD BIT(31) + +static inline void +isp3_param_write_direct(struct rkisp_isp_params_vdev *params_vdev, + u32 value, u32 addr) +{ + rkisp_write(params_vdev->dev, addr, value, true); +} + +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 < ISP32_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 < ISP32_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 isp32_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); + + isp3_param_write(params_vdev, arg->isp_ob_offset, 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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 & ISP33_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 rkisp_device *dev = params_vdev->dev; + struct isp33_isp_params_cfg *params_rec = params_vdev->isp33_params + id; + u32 data, ctrl; + int i; + + for (i = 0; i < ISP33_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 &= ISP33_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 & ISP33_MODULE_EN)) + return; + + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 isp33_debayer_cfg *arg, u32 id) +{ + u32 val; + int i; + + val = isp3_param_read(params_vdev, ISP3X_DEBAYER_CONTROL, id); + val &= ISP_DEBAYER_EN; + + val |= !!arg->g_out_flt_en << 4 | !!arg->bypass << 1; + isp3_param_write(params_vdev, val, ISP3X_DEBAYER_CONTROL, id); + + val = (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, val, ISP39_DEBAYER_LUMA_DX, id); + + val = !!arg->g_interp_clip_en << 0 | + (arg->hi_texture_thred & 0xf) << 4 | + (arg->hi_drct_thred & 0xf) << 8 | + (arg->lo_drct_thred & 0xf) << 12 | + arg->drct_method_thred << 16 | + arg->g_interp_sharp_strg_max_limit << 24; + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_INTERP, id); + + val = (arg->lo_drct_flt_coeff1 & 0x1f) | + (arg->lo_drct_flt_coeff2 & 0x1f) << 8 | + (arg->lo_drct_flt_coeff3 & 0x1f) << 16 | + (arg->lo_drct_flt_coeff4 & 0x1f) << 24; + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_INTERP_FILTER1, id); + + val = (arg->hi_drct_flt_coeff1 & 0x1f) | + (arg->hi_drct_flt_coeff2 & 0x1f) << 8 | + (arg->hi_drct_flt_coeff3 & 0x1f) << 16 | + (arg->hi_drct_flt_coeff4 & 0x1f) << 24; + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_INTERP_FILTER2, id); + + val = arg->g_interp_sharp_strg_offset | arg->grad_lo_flt_alpha << 16; + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_INTERP_OFFSET_ALPHA, id); + + for (i = 0; i < ISP33_DEBAYER_DRCT_OFFSET_NUM / 2; i++) { + val = ISP_PACK_2SHORT(arg->drct_offset[i * 2], arg->drct_offset[i * 2 + 1]); + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_INTERP_DRCT_OFFSET0 + i * 4, id); + } + + val = !!arg->gflt_mode << 0 | (arg->gflt_ratio & 0x7ff) << 4 | + arg->gflt_offset << 16; + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_FILTER_MODE_OFFSET, id); + + val = ISP_PACK_4BYTE(arg->gflt_coe0, arg->gflt_coe1, arg->gflt_coe2, 0); + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_FILTER_FILTER, id); + + for (i = 0; i < ISP33_DEBAYER_VSIGMA_NUM / 2; i++) { + val = ISP_PACK_2SHORT(arg->gflt_vsigma[i * 2], arg->gflt_vsigma[i * 2 + 1]); + isp3_param_write(params_vdev, val, ISP39_DEBAYER_G_FILTER_VSIGMA0 + i * 4, 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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 < ISP33_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 < ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 < ISP32_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) + val = ISP33_MODULE_EN; + else + val = 0; + isp3_param_write(params_vdev, val, ISP3X_IMG_EFF_CTRL, id); +} + +static void +isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawaebig_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 i, 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); + + if (arg->subwin_en[0]) + value |= ISP3X_RAWAE_BIG_WND1_EN; + if (arg->subwin_en[1]) + value |= ISP3X_RAWAE_BIG_WND2_EN; + if (arg->subwin_en[2]) + value |= ISP3X_RAWAE_BIG_WND3_EN; + if (arg->subwin_en[3]) + value |= ISP3X_RAWAE_BIG_WND4_EN; + isp3_param_write(params_vdev, value, addr + ISP3X_RAWAE_BIG_CTRL, id); + + h_offs = arg->win.h_offs & ~0x1; + v_offs = arg->win.v_offs & ~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->win.h_size; + v_size = arg->win.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); + + for (i = 0; i < ISP33_RAWAEBIG_SUBWIN_NUM; i++) { + h_offs = arg->subwin[i].h_offs & ~0x1; + v_offs = arg->subwin[i].v_offs & ~0x1; + isp3_param_write(params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), + addr + ISP3X_RAWAE_BIG_WND1_OFFSET + 8 * i, id); + + v_size = arg->subwin[i].v_size; + h_size = arg->subwin[i].h_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 + 8 * i, 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); + if (arg->rawae_sel & ISP33_BNR2AEBIG_SEL_EN) + value |= BIT(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); + if (arg->rawae_sel & ISP33_BNR2AE0_SEL_EN) + value |= BIT(30); + isp3_param_write(params_vdev, value, ISP3X_VI_ISP_PATH, id); + } +} + +static void +isp_rawaebig_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 isp2x_rawaebig_meas_cfg *arg, u32 id) +{ + isp_rawaebig_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_rawaebig_enable(params_vdev, en, ISP3X_RAWAE_LITE_BASE, id); +} + +static void +isp_rawae3_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawaebig_meas_cfg *arg, u32 id) +{ + isp_rawaebig_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_rawaebig_enable(params_vdev, en, ISP3X_RAWAE_BIG1_BASE, id); +} + +static void +isp_rawawb_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_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 & ISP33_MODULE_EN)) + return; + + isp3_param_write_direct(params_vdev, 0, ISP3X_RAWAWB_WRAM_CTRL); + for (i = 0; i < ISP33_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 isp33_rawawb_meas_cfg *arg, u32 id) +{ + struct rkisp_device *dev = params_vdev->dev; + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; + struct isp33_isp_params_cfg *params_rec = params_vdev->isp33_params + id; + struct isp33_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->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); + + 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, ISP33_RAWAWB_WEIGHT_NUM); + + /* avoid to override the old enable value */ + value = isp3_param_read_cache(params_vdev, ISP3X_RAWAWB_CTRL, id); + value &= (ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_SELF_FORCE_UPD); + isp3_param_write(params_vdev, val, ISP3X_RAWAWB_CTRL, id); +} + +static void +isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawhistbig_cfg *arg, + u32 addr, bool is_check, u32 id) +{ + u32 i, j, wnd_num_idx, value; + u8 weight15x15[ISP33_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 * ISP33_RAWHISTBIG_ROW_NUM + j] = + arg->weight[i * hist_wnd_num[wnd_num_idx] + j]; + } + } + + for (i = 0; i < (ISP33_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_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawhistbig_cfg *arg, u32 addr, u32 id) +{ + struct isp33_isp_params_cfg *params_rec = params_vdev->isp33_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 isp2x_rawhistbig_cfg *arg_rec; + u32 hist_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 */ + hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id); + hist_ctrl &= ISP3X_RAWHIST_EN; + hist_ctrl = hist_ctrl | + ISP3X_RAWHIST_MODE(arg->mode) | + ISP3X_RAWHIST_WND_NUM(arg->wnd_num) | + ISP3X_RAWHIST_STEPSIZE(arg->stepsize) | + ISP3X_RAWHIST_DATASEL(arg->data_sel) | + ISP3X_RAWHIST_WATERLINE(arg->waterline); + isp3_param_write(params_vdev, hist_ctrl, addr + ISP3X_RAWHIST_BIG_CTRL, id); + + h_offs = arg->win.h_offs & ~0x1; + v_offs = arg->win.v_offs & ~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->win.h_size; + v_size = arg->win.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_rawhstbig_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_rawhstbig_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 & ISP33_MODULE_EN)) + return; + val &= ~(ISP33_SELF_FORCE_UPD | ISP33_MODULE_EN); + if (en) + val |= ISP33_MODULE_EN; + isp3_param_write(params_vdev, val, addr + ISP3X_RAWHIST_BIG_CTRL, id); +} + +static void +isp_rawhst0_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawhistbig_cfg *arg, u32 id) +{ + isp_rawhstbig_config(params_vdev, arg, ISP3X_RAWHIST_LITE_BASE, id); +} + +static void +isp_rawhst0_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + isp_rawhstbig_enable(params_vdev, en, ISP3X_RAWHIST_LITE_BASE, id); +} + +static void +isp_rawhst3_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawhistbig_cfg *arg, u32 id) +{ + isp_rawhstbig_config(params_vdev, arg, ISP3X_RAWHIST_BIG1_BASE, id); +} + +static void +isp_rawhst3_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + isp_rawhstbig_enable(params_vdev, en, ISP3X_RAWHIST_BIG1_BASE, id); +} + +static void +isp_hdrmge_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_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->gain0, arg->gain0_inv); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_GAIN0, id); + + value = ISP_PACK_2SHORT(arg->gain1, arg->gain1_inv); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_GAIN1, id); + + value = arg->gain2; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_GAIN2, id); + + value = isp3_param_read_cache(params_vdev, ISP3X_HDRMGE_CTRL, id); + if (arg->s_base) + value |= BIT(1); + else + value &= ~BIT(1); + if (arg->each_raw_en) + value |= BIT(6); + else + value &= ~BIT(6); + 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_dif_0p8, arg->ms_diff_0p15, + arg->lm_dif_0p9, arg->lm_dif_0p15); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_LIGHTZ, id); + value = (arg->ms_scl & 0x7ff) | + (arg->ms_thd0 & 0x3ff) << 12 | + (arg->ms_thd1 & 0x3ff) << 22; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_MS_DIFF, id); + value = (arg->lm_scl & 0x7ff) | + (arg->lm_thd0 & 0x3ff) << 12 | + (arg->lm_thd1 & 0x3ff) << 22; + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_LM_DIFF, id); + + for (i = 0; i < ISP32_HDRMGE_L_CURVE_NUM; i++) { + value = ISP_PACK_2SHORT(arg->curve.curve_0[i], arg->curve.curve_1[i]); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_DIFF_Y0 + 4 * i, id); + } + + for (i = 0; i < ISP32_HDRMGE_E_CURVE_NUM; i++) { + value = (arg->l_raw1[i] & 0x3ff) << 20 | + (arg->l_raw0[i] & 0x3ff) << 10 | + (arg->e_y[i] & 0x3ff); + isp3_param_write(params_vdev, value, ISP3X_HDRMGE_OVER_Y0 + 4 * i, id); + } + + value = ISP_PACK_2SHORT(arg->each_raw_gain0, arg->each_raw_gain1); + isp3_param_write(params_vdev, value, ISP32_HDRMGE_EACH_GAIN, id); + } +} + +static void +isp_hdrmge_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ +} + +static void +isp_hdrdrc_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_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 &= ISP33_MODULE_EN; + ctrl |= !!arg->bypass_en << 1 | + !!arg->cmps_byp_en << 2 | + !!arg->gainx32_en << 3 | + !!arg->bf_lp_en << 4; + 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 & ISP33_MODULE_EN)) + dev_warn(params_vdev->dev->dev, "drc cmps_byp_en=1 but hdr\n"); + + if (type == RKISP_PARAMS_IMD) + return; + + value = (arg->offset_pow2 & 0xF) << 28 | + (arg->compres_scl & 0x1FFF) << 14 | + (arg->position & 0x03FFF); + isp3_param_write(params_vdev, value, ISP3X_DRC_CTRL1, id); + + value = arg->delta_scalein << 24 | + (arg->hpdetail_ratio & 0xFFF) << 12 | + (arg->lpdetail_ratio & 0xFFF); + isp3_param_write(params_vdev, value, ISP3X_DRC_LPRATIO, id); + + value = arg->bilat_wt_off | (arg->thumb_thd_neg & 0x1ff) << 8 | + !!arg->thumb_thd_enable << 23 | arg->weicur_pix << 24; + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT0, id); + + value = (arg->cmps_offset_bits_int & 0xf) | + !!arg->cmps_fixbit_mode << 4 | + arg->drc_gas_t << 16; + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT1, id); + + value = arg->thumb_clip | arg->thumb_scale << 16; + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT2, id); + + value = ISP_PACK_2SHORT(arg->range_sgm_inv0, arg->range_sgm_inv1); + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT3, id); + + value = arg->weig_bilat | arg->weight_8x8thumb << 8 | + (arg->bilat_soft_thd & 0x7ff) << 16 | + !!arg->enable_soft_thd << 31; + isp3_param_write(params_vdev, value, ISP39_DRC_BILAT4, id); + + for (i = 0; i < ISP33_DRC_Y_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->gain_y[i * 2], arg->gain_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP3X_DRC_GAIN_Y0 + i * 4, id); + value = ISP_PACK_2SHORT(arg->compres_y[i * 2], arg->compres_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP3X_DRC_COMPRES_Y0 + i * 4, id); + value = ISP_PACK_2SHORT(arg->scale_y[i * 2], arg->scale_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP3X_DRC_SCALE_Y0 + i * 4, id); + value = ISP_PACK_2SHORT(arg->sfthd_y[i * 2], arg->sfthd_y[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP39_DRC_SFTHD_Y0 + i * 4, id); + } + value = arg->gain_y[i * 2]; + isp3_param_write(params_vdev, value, ISP3X_DRC_GAIN_Y8, id); + value = arg->compres_y[i * 2]; + isp3_param_write(params_vdev, value, ISP3X_DRC_COMPRES_Y8, id); + value = arg->scale_y[i * 2]; + isp3_param_write(params_vdev, value, ISP3X_DRC_SCALE_Y8, id); + value = arg->sfthd_y[i * 2]; + isp3_param_write(params_vdev, value, ISP39_DRC_SFTHD_Y8, id); + + value = arg->min_ogain; + isp3_param_write(params_vdev, value, ISP3X_DRC_IIRWG_GAIN, id); +} + +static void +isp_hdrdrc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_DRC_CTRL0, id); + + if (en == !!(val & ISP33_MODULE_EN)) + return; + if (en) { + val |= ISP33_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP3X_ADRC_FST_FRAME, id); + } else { + val &= ~(ISP33_MODULE_EN | ISP33_SELF_FORCE_UPD); + } + isp3_param_write(params_vdev, val, 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 &= ISP33_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 < ISP33_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 < ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) { + val |= ISP33_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP33_GIC_FST_FRAME, id); + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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_v33 *priv_val = params_vdev->priv_val; + u32 i, j, val, ctrl = isp3_param_read(params_vdev, ISP33_ENH_CTRL, id); + + if (is_check && (!(ctrl & ISP33_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_val->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_val->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 isp33_isp_params_cfg *params_rec = params_vdev->isp33_params + id; + struct isp33_enh_cfg *arg_rec = ¶ms_rec->others.enh_cfg; + struct rkisp_isp_params_val_v33 *priv_val = 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_val->enh_col = ALIGN((w + 127) / 128, 4); + if (priv_val->enh_col > ISP33_ENH_IIR_COL_MAX) + priv_val->enh_col = ISP33_ENH_IIR_COL_MAX; + priv_val->enh_row = (h + 128) / 129; + if (priv_val->enh_row > ISP33_ENH_IIR_ROW_MAX) + priv_val->enh_row = ISP33_ENH_IIR_ROW_MAX; + het_aliquant = h % 3; + + ctrl = isp3_param_read(params_vdev, ISP33_ENH_CTRL, id); + ctrl &= ISP33_MODULE_EN; + ctrl |= !!arg->bypass << 1 | + !!arg->blf3_bypass << 2 | + (het_aliquant & 0x3) << 4 | + (priv_val->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 < ISP33_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 < ISP33_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 < ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) { + val |= ISP33_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP33_ENH_FST_FRAME, id); + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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_v33 *priv_val = params_vdev->priv_val; + u32 i, j, val, ctrl = isp3_param_read(params_vdev, ISP33_HIST_CTRL, id); + + if (is_check && (!(ctrl & ISP33_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_val->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 < ISP33_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 isp33_isp_params_cfg *params_rec = params_vdev->isp33_params + id; + struct isp33_hist_cfg *arg_rec = ¶ms_rec->others.hist_cfg; + struct rkisp_isp_params_val_v33 *priv_val = 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 &= ISP33_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 < ISP33_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_val->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 & ISP33_MODULE_EN)) + return; + if (en) { + val |= ISP33_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP33_YHIST_FST_FRAME, id); + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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 isp33_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 & ISP33_MODULE_EN)) + return; + + for (i = 0; i < ISP33_HSV_1DLUT_NUM; i++) { + val = ISP_PACK_2SHORT(arg->lut0_1d[i], arg->lut1_1d[i]); + isp3_param_write_direct(params_vdev, val, ISP33_HSV_1DLUT); + } + for (i = 0; i < ISP33_HSV_2DLUT_ROW; i++) { + for (j = 0; j < ISP33_HSV_2DLUT_COL - 1; j += 2) { + val = ISP_PACK_2SHORT(arg->lut_2d[i][j], arg->lut_2d[i][j + 1]); + isp3_param_write_direct(params_vdev, val, ISP33_HSV_2DLUT); + } + val = arg->lut_2d[i][ISP33_HSV_2DLUT_COL - 1]; + isp3_param_write_direct(params_vdev, val, ISP33_HSV_2DLUT); + } +} + +static void +isp_hsv_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_hsv_cfg *arg, u32 id) +{ + struct rkisp_device *dev = params_vdev->dev; + struct isp33_isp_params_cfg *params_rec = params_vdev->isp33_params + id; + u32 val = isp3_param_read(params_vdev, ISP3X_3DLUT_CTRL, id); + + val &= ISP33_MODULE_EN; + val |= !!arg->hsv_1dlut0_en << 1 | + !!arg->hsv_1dlut1_en << 2 | + !!arg->hsv_2dlut_en << 3 | + (arg->hsv_1dlut0_idx_mode & 0x3) << 4 | + (arg->hsv_1dlut1_idx_mode & 0x3) << 6 | + (arg->hsv_2dlut_idx_mode & 0x3) << 8 | + (arg->hsv_1dlut0_item_mode & 0x7) << 10 | + (arg->hsv_1dlut1_item_mode & 0x7) << 13 | + (arg->hsv_2dlut_item_mode & 0x3) << 16; + isp3_param_write(params_vdev, val, ISP3X_3DLUT_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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_v33 *priv_val = 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 &= ISP33_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 < ISP33_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 < ISP33_MESH_BUF_NUM; i++) { + if (!priv_val->buf_ldch[id][i].mem_priv) + continue; + if (arg->buf_fd == priv_val->buf_ldch[id][i].dma_fd) + break; + } + if (i == ISP33_MESH_BUF_NUM) { + dev_err(dev->dev, "cannot find ldch buf fd(%d)\n", arg->buf_fd); + return; + } + + if (!priv_val->buf_ldch[id][i].vaddr) { + dev_err(dev->dev, "no ldch buffer allocated\n"); + return; + } + + buf_idx = priv_val->buf_ldch_idx[id]; + head = (struct isp2x_mesh_head *)priv_val->buf_ldch[id][buf_idx].vaddr; + head->stat = MESH_BUF_INIT; + + buf_idx = i; + head = (struct isp2x_mesh_head *)priv_val->buf_ldch[id][buf_idx].vaddr; + head->stat = MESH_BUF_CHIPINUSE; + priv_val->buf_ldch_idx[id] = buf_idx; + rkisp_prepare_buffer(dev, &priv_val->buf_ldch[id][buf_idx]); + value = priv_val->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_v33 *priv_val = 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 & ISP33_MODULE_EN)) + return; + if (en) { + buf_idx = priv_val->buf_ldch_idx[id]; + if (!priv_val->buf_ldch[id][buf_idx].vaddr) { + dev_err(dev->dev, "no ldch buffer allocated\n"); + return; + } + val |= ISP33_MODULE_EN; + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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 isp33_ynr_cfg *arg, u32 id) +{ + u32 i, value; + + value = isp3_param_read(params_vdev, ISP3X_YNR_GLOBAL_CTRL, id); + value &= ISP33_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; + 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 < ISP33_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 < ISP33_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 < ISP33_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); + + 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 | + (arg->hi_spnr_filt_coeff[4] & 0x3f) << 24; + 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 & 0x1ff) | + (arg->mi_spnr_filt_coeff1 & 0x1ff) << 10 | + (arg->mi_spnr_filt_coeff2 & 0x1ff) << 20; + isp3_param_write(params_vdev, value, ISP33_YNR_MI_GAUS_COE, 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 = 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; + 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 < ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) { + val |= ISP33_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP3X_YNR_FST_FRAME, id); + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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 isp33_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 &= ISP33_MODULE_EN; + + ctrl |= (arg->loflt_coeff & 0x3f) << 12 | + !!arg->local_alpha_dis << 11 | + !!arg->hiflt_wgt0_mode << 8 | + (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 & ISP33_MODULE_EN && !(gain_ctrl & ISP33_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 < ISP33_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 << 8 | + arg->bf_alpha_max_limit << 16; + isp3_param_write(params_vdev, value, ISP32_CNR_IIR_GLOBAL_GAIN, id); + + for (i = 0; i < ISP33_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 < ISP33_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 < ISP33_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); + } +} + +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 & ISP33_MODULE_EN)) + return; + if (en) { + val |= ISP33_MODULE_EN; + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, + ISP3X_CNR_FST_FRAME, id); + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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 isp33_sharp_cfg *arg, u32 id, bool direct) +{ + struct rkisp_device *dev = params_vdev->dev; + u32 i, value; + + for (i = 0; i < ISP33_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 isp33_sharp_cfg *arg, u32 id) +{ + struct isp33_isp_params_cfg *params_rec = params_vdev->isp33_params + id; + u32 i, value; + + value = isp3_param_read(params_vdev, ISP3X_SHARP_EN, id); + value &= ISP33_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->detail_fusion_slope_fix; + isp3_param_write(params_vdev, value, ISP33_SHARP_DETAIL1, 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 < ISP33_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 < ISP33_SHARP_EDGE_KERNEL_NUM / 4; i++) { + value = ISP_PACK_4BYTE(arg->edge_lpf_coeff[i * 4], + arg->edge_lpf_coeff[i * 4 + 1], + arg->edge_lpf_coeff[i * 4 + 2], + arg->edge_lpf_coeff[i * 4 + 3]); + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE_KERNEL0 + i * 4, id); + } + value = ISP_PACK_4BYTE(arg->edge_lpf_coeff[i * 4], arg->edge_lpf_coeff[i * 4 + 1], 0, 0); + isp3_param_write(params_vdev, value, ISP33_SHARP_EDGE_KERNEL2, id); + + for (i = 0; i < ISP33_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 < ISP33_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->tex2detail_strg[0] & 0x3ff) | + (arg->tex2detail_strg[1] & 0x3ff) << 10 | + (arg->tex2detail_strg[2] & 0x3ff) << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_LOCAL_STRG0, id); + value = (arg->tex2detail_strg[3] & 0x3ff) | + (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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_SHARP_HITEX_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); + + value = arg->loss_tex_in_hinr_strg; + isp3_param_write(params_vdev, value, ISP33_SHARP_LOSSTEXINHINR_STRG, id); + + for (i = 0; i < ISP33_SHARP_NOISE_CURVE_NUM / 2; i++) { + value = ISP_PACK_2SHORT(arg->noise_curve_ext[i * 2], + arg->noise_curve_ext[i * 2 + 1]); + isp3_param_write(params_vdev, value, ISP33_SHARP_NOISE_CURVE0 + i * 4, id); + } + value = (arg->noise_curve_ext[i * 2] & 0x7ff) | + arg->noise_count_thred_ratio << 12 | + arg->noise_clip_scale << 20; + isp3_param_write(params_vdev, value, ISP33_SHARP_NOISE_CURVE8, 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); + + /* 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 & ISP33_MODULE_EN)) + return; + if (en) { + isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, ISP32_SHP_FST_FRAME, id); + val |= ISP33_MODULE_EN; + } else { + val &= ~(ISP33_MODULE_EN | ISP33_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 isp33_bay3d_cfg *arg, u32 id) +{ + u32 i, value, ctrl; + + 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 &= ISP33_MODULE_EN; + + ctrl |= !!arg->motion_est_en << 8 | + (arg->out_use_pre_mode & 0x7) << 5 | + !!arg->iirsparse_en << 2 | + !!arg->bypass_en << 1; + isp3_param_write(params_vdev, ctrl, ISP33_BAY3D_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_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->wgt_last_mode & 0x3) << 3 | + !!arg->ww_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 << 15 | + (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_sig_ctrl_scl; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CURHI_SIGSCL, id); + + value = arg->pre_hi_guide_out_wgt; + isp3_param_write(params_vdev, value, ISP33_BAY3D_CURHI_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 < ISP33_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; + 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_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 < ISP33_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 < ISP33_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_hi_noise_bal_nr_strg & 0x3fffff); + 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 = 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); + + if (params_vdev->dev->hw_dev->is_single && ctrl & ISP33_MODULE_EN) + isp3_param_write(params_vdev, ctrl | ISP33_SELF_FORCE_UPD, ISP33_BAY3D_CTRL0, id); +} + +static void +isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + struct rkisp_isp_params_val_v33 *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 & ISP33_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); + isp3_param_write(params_vdev, value, ISP39_AIISP_RD_BASE, id); + if (priv_val->buf_gain.mem_priv) { + value = priv_val->gain_size; + isp3_param_write(params_vdev, value, ISP3X_MI_GAIN_WR_SIZE, id); + isp3_param_write(params_vdev, value, ISP32_MI_RAW0_RD_SIZE, id); + value = priv_val->buf_gain.dma_addr + value * id; + isp3_param_write(params_vdev, value, ISP3X_MI_GAIN_WR_BASE, id); + isp3_param_write(params_vdev, value, ISP3X_MI_RAW0_RD_BASE, id); + + value = isp3_param_read_cache(params_vdev, ISP3X_GAIN_CTRL, id); + value |= ISP3X_GAIN_2DDR_MODE(1) | ISP3X_GAIN_2DDR_EN; + isp3_param_write(params_vdev, value, ISP3X_GAIN_CTRL, 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 |= ISP33_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 &= ~(ISP33_MODULE_EN | ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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->isp33_params->others.cac_cfg; + u32 i, val, ctrl; + + ctrl = isp3_param_read(params_vdev, ISP3X_CAC_CTRL, id); + ctrl &= ISP33_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 < ISP33_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 & ISP33_MODULE_EN)) + return; + if (en) + val |= ISP33_MODULE_EN; + else + val &= ~(ISP33_MODULE_EN | ISP33_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 < ISP32_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); + } +} + +struct rkisp_isp_params_ops_v33 isp_params_ops_v33 = { + .dpcc_config = isp_dpcc_config, + .dpcc_enable = isp_dpcc_enable, + .bls_config = isp_bls_config, + .bls_enable = isp_bls_enable, + .lsc_config = isp_lsc_config, + .lsc_enable = isp_lsc_enable, + .awbgain_config = isp_awbgain_config, + .awbgain_enable = isp_awbgain_enable, + .debayer_config = isp_debayer_config, + .debayer_enable = isp_debayer_enable, + .ccm_config = isp_ccm_config, + .ccm_enable = isp_ccm_enable, + .goc_config = isp_goc_config, + .goc_enable = isp_goc_enable, + .csm_config = isp_csm_config, + .cproc_config = isp_cproc_config, + .cproc_enable = isp_cproc_enable, + .ie_enable = isp_ie_enable, + .rawae0_config = isp_rawae0_config, + .rawae0_enable = isp_rawae0_enable, + .rawae3_config = isp_rawae3_config, + .rawae3_enable = isp_rawae3_enable, + .rawawb_config = isp_rawawb_config, + .rawawb_enable = isp_rawawb_enable, + .rawhst0_config = isp_rawhst0_config, + .rawhst0_enable = isp_rawhst0_enable, + .rawhst3_config = isp_rawhst3_config, + .rawhst3_enable = isp_rawhst3_enable, + .hdrmge_config = isp_hdrmge_config, + .hdrmge_enable = isp_hdrmge_enable, + .hdrdrc_config = isp_hdrdrc_config, + .hdrdrc_enable = isp_hdrdrc_enable, + .gic_config = isp_gic_config, + .gic_enable = isp_gic_enable, + .enh_config = isp_enh_config, + .enh_enable = isp_enh_enable, + .hist_config = isp_hist_config, + .hist_enable = isp_hist_enable, + .hsv_config = isp_hsv_config, + .hsv_enable = isp_hsv_enable, + .ldch_config = isp_ldch_config, + .ldch_enable = isp_ldch_enable, + .ynr_config = isp_ynr_config, + .ynr_enable = isp_ynr_enable, + .cnr_config = isp_cnr_config, + .cnr_enable = isp_cnr_enable, + .sharp_config = isp_sharp_config, + .sharp_enable = isp_sharp_enable, + .bay3d_config = isp_bay3d_config, + .bay3d_enable = isp_bay3d_enable, + .gain_config = isp_gain_config, + .gain_enable = isp_gain_enable, + .cac_config = isp_cac_config, + .cac_enable = isp_cac_enable, + .cgc_config = isp_cgc_config, +}; + +static __maybe_unused +void __isp_isr_other_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + struct rkisp_isp_params_ops_v33 *ops = params_vdev->priv_ops; + u64 module_cfg_update = new_params->module_cfg_update; + + if (type == RKISP_PARAMS_SHD) { + if ((module_cfg_update & ISP33_MODULE_HDRMGE)) + ops->hdrmge_config(params_vdev, &new_params->others.hdrmge_cfg, type, id); + + if ((module_cfg_update & ISP33_MODULE_DRC)) + ops->hdrdrc_config(params_vdev, &new_params->others.drc_cfg, type, id); + return; + } + + 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 & ISP33_MODULE_DPCC) + ops->dpcc_config(params_vdev, &new_params->others.dpcc_cfg, id); + + if (module_cfg_update & ISP33_MODULE_BLS) + ops->bls_config(params_vdev, &new_params->others.bls_cfg, id); + + if (module_cfg_update & ISP33_MODULE_AWB_GAIN) + ops->awbgain_config(params_vdev, &new_params->others.awb_gain_cfg, id); + + if (module_cfg_update & ISP33_MODULE_DEBAYER) + ops->debayer_config(params_vdev, &new_params->others.debayer_cfg, id); + + if (module_cfg_update & ISP33_MODULE_CCM) + ops->ccm_config(params_vdev, &new_params->others.ccm_cfg, id); + + if (module_cfg_update & ISP33_MODULE_GOC) + ops->goc_config(params_vdev, &new_params->others.gammaout_cfg, id); + + /* range csm->cgc->cproc->ie */ + if (module_cfg_update & ISP33_MODULE_CSM) + ops->csm_config(params_vdev, &new_params->others.csm_cfg, id); + + if (module_cfg_update & ISP33_MODULE_CGC) + ops->cgc_config(params_vdev, &new_params->others.cgc_cfg, id); + + if (module_cfg_update & ISP33_MODULE_CPROC) + ops->cproc_config(params_vdev, &new_params->others.cproc_cfg, id); + + if (module_cfg_update & ISP33_MODULE_HDRMGE) + ops->hdrmge_config(params_vdev, &new_params->others.hdrmge_cfg, type, id); + + if (module_cfg_update & ISP33_MODULE_DRC) + ops->hdrdrc_config(params_vdev, &new_params->others.drc_cfg, type, id); + + if (module_cfg_update & ISP33_MODULE_GIC) + ops->gic_config(params_vdev, &new_params->others.gic_cfg, id); + + if (module_cfg_update & ISP33_MODULE_ENH) + ops->enh_config(params_vdev, &new_params->others.enh_cfg, id); + + if (module_cfg_update & ISP33_MODULE_HIST) + ops->hist_config(params_vdev, &new_params->others.hist_cfg, id); + + if (module_cfg_update & ISP33_MODULE_LDCH) + ops->ldch_config(params_vdev, &new_params->others.ldch_cfg, id); + + if (module_cfg_update & ISP33_MODULE_YNR) + ops->ynr_config(params_vdev, &new_params->others.ynr_cfg, id); + + if (module_cfg_update & ISP33_MODULE_CNR) + ops->cnr_config(params_vdev, &new_params->others.cnr_cfg, id); + + if (module_cfg_update & ISP33_MODULE_SHARP) + ops->sharp_config(params_vdev, &new_params->others.sharp_cfg, id); + + if (module_cfg_update & ISP33_MODULE_BAY3D) + ops->bay3d_config(params_vdev, &new_params->others.bay3d_cfg, id); + + if (module_cfg_update & ISP33_MODULE_GAIN) + ops->gain_config(params_vdev, &new_params->others.gain_cfg, id); + + if (module_cfg_update & ISP33_MODULE_LSC) + ops->lsc_config(params_vdev, &new_params->others.lsc_cfg, id); + + if (module_cfg_update & ISP33_MODULE_CAC) + ops->cac_config(params_vdev, &new_params->others.cac_cfg, id); + + if (module_cfg_update & ISP33_MODULE_HSV) + ops->hsv_config(params_vdev, &new_params->others.hsv_cfg, id); +} + +static __maybe_unused +void __isp_isr_other_en(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + struct rkisp_isp_params_val_v33 *priv_val = params_vdev->priv_val; + struct rkisp_isp_params_ops_v33 *ops = params_vdev->priv_ops; + u64 module_en_update = new_params->module_en_update; + u64 mask, module_ens = new_params->module_ens; + u32 gain_ctrl, cnr_ctrl, val; + + if (type == RKISP_PARAMS_SHD) + return; + + mask = ISP33_MODULE_YNR | ISP33_MODULE_CNR | ISP33_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 & ISP33_MODULE_DPCC) + ops->dpcc_enable(params_vdev, !!(module_ens & ISP33_MODULE_DPCC), id); + + if (module_en_update & ISP33_MODULE_BLS) + ops->bls_enable(params_vdev, !!(module_ens & ISP33_MODULE_BLS), id); + + if (module_en_update & ISP33_MODULE_LSC) + ops->lsc_enable(params_vdev, !!(module_ens & ISP33_MODULE_LSC), id); + + if (module_en_update & ISP33_MODULE_AWB_GAIN) + ops->awbgain_enable(params_vdev, !!(module_ens & ISP33_MODULE_AWB_GAIN), id); + + if (module_en_update & ISP33_MODULE_DEBAYER) + ops->debayer_enable(params_vdev, !!(module_ens & ISP33_MODULE_DEBAYER), id); + + if (module_en_update & ISP33_MODULE_CCM) + ops->ccm_enable(params_vdev, !!(module_ens & ISP33_MODULE_CCM), id); + + if (module_en_update & ISP33_MODULE_GOC) + ops->goc_enable(params_vdev, !!(module_ens & ISP33_MODULE_GOC), id); + + if (module_en_update & ISP33_MODULE_CPROC) + ops->cproc_enable(params_vdev, !!(module_ens & ISP33_MODULE_CPROC), id); + + if (module_en_update & ISP33_MODULE_IE) + ops->ie_enable(params_vdev, !!(module_ens & ISP33_MODULE_IE), id); + + if (module_en_update & ISP33_MODULE_HDRMGE) + ops->hdrmge_enable(params_vdev, !!(module_ens & ISP33_MODULE_HDRMGE), id); + + if (module_en_update & ISP33_MODULE_DRC) + ops->hdrdrc_enable(params_vdev, !!(module_ens & ISP33_MODULE_DRC), id); + + if (module_en_update & ISP33_MODULE_GIC) + ops->gic_enable(params_vdev, !!(module_ens & ISP33_MODULE_GIC), id); + + if (module_en_update & ISP33_MODULE_ENH) + ops->enh_enable(params_vdev, !!(module_ens & ISP33_MODULE_ENH), id); + + if (module_en_update & ISP33_MODULE_HIST) + ops->hist_enable(params_vdev, !!(module_ens & ISP33_MODULE_HIST), id); + + if (module_en_update & ISP33_MODULE_HSV) + ops->hsv_enable(params_vdev, !!(module_ens & ISP33_MODULE_HSV), id); + + if (module_en_update & ISP33_MODULE_LDCH) + ops->ldch_enable(params_vdev, !!(module_ens & ISP33_MODULE_LDCH), id); + + if (module_en_update & ISP33_MODULE_YNR) + ops->ynr_enable(params_vdev, !!(module_ens & ISP33_MODULE_YNR), id); + + if (module_en_update & ISP33_MODULE_CNR) + ops->cnr_enable(params_vdev, !!(module_ens & ISP33_MODULE_CNR), id); + + if (module_en_update & ISP33_MODULE_SHARP) + ops->sharp_enable(params_vdev, !!(module_ens & ISP33_MODULE_SHARP), id); + + if (module_en_update & ISP33_MODULE_BAY3D) + ops->bay3d_enable(params_vdev, !!(module_ens & ISP33_MODULE_BAY3D), id); + + if (module_en_update & ISP33_MODULE_CAC) + ops->cac_enable(params_vdev, !!(module_ens & ISP33_MODULE_CAC), id); + + if (module_en_update & ISP33_MODULE_GAIN || + ((priv_val->buf_info_owner == RKISP_INFO2DRR_OWNER_GAIN) && + !(isp3_param_read(params_vdev, ISP3X_GAIN_CTRL, id) & ISP3X_GAIN_2DDR_EN))) + ops->gain_enable(params_vdev, !!(module_ens & ISP33_MODULE_GAIN), 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 & ISP33_MODULE_EN) && cnr_ctrl & ISP33_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 isp33_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + struct rkisp_isp_params_ops_v33 *ops = params_vdev->priv_ops; + u64 module_cfg_update = new_params->module_cfg_update; + + params_vdev->cur_frame_id = new_params->frame_id; + if (type == RKISP_PARAMS_SHD) + return; + + 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 & ISP33_MODULE_RAWAE0) + ops->rawae0_config(params_vdev, &new_params->meas.rawae0, id); + + if (module_cfg_update & ISP33_MODULE_RAWAE3) + ops->rawae3_config(params_vdev, &new_params->meas.rawae3, id); + + if (module_cfg_update & ISP33_MODULE_RAWHIST0) + ops->rawhst0_config(params_vdev, &new_params->meas.rawhist0, id); + + if (module_cfg_update & ISP33_MODULE_RAWHIST3) + ops->rawhst3_config(params_vdev, &new_params->meas.rawhist3, id); + + if (module_cfg_update & ISP33_MODULE_RAWAWB) + ops->rawawb_config(params_vdev, &new_params->meas.rawawb, id); +} + +static __maybe_unused +void __isp_isr_meas_en(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *new_params, + enum rkisp_params_type type, u32 id) +{ + struct rkisp_isp_params_ops_v33 *ops = params_vdev->priv_ops; + u64 module_en_update = new_params->module_en_update; + u64 module_ens = new_params->module_ens; + + if (type == RKISP_PARAMS_SHD) + return; + + 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 & ISP33_MODULE_RAWAE0) + ops->rawae0_enable(params_vdev, !!(module_ens & ISP33_MODULE_RAWAE0), id); + + if (module_en_update & ISP33_MODULE_RAWAE3) + ops->rawae3_enable(params_vdev, !!(module_ens & ISP33_MODULE_RAWAE3), id); + + if (module_en_update & ISP33_MODULE_RAWHIST0) + ops->rawhst0_enable(params_vdev, !!(module_ens & ISP33_MODULE_RAWHIST0), id); + + if (module_en_update & ISP33_MODULE_RAWHIST3) + ops->rawhst3_enable(params_vdev, !!(module_ens & ISP33_MODULE_RAWHIST3), id); + + if (module_en_update & ISP33_MODULE_RAWAWB) + ops->rawawb_enable(params_vdev, !!(module_ens & ISP33_MODULE_RAWAWB), id); +} + +static +void rkisp_params_cfgsram_v33(struct rkisp_isp_params_vdev *params_vdev, bool is_reset) +{ + u32 id = params_vdev->dev->unite_index; + struct isp33_isp_params_cfg *params = params_vdev->isp33_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_rawhstbig_cfg_sram(params_vdev, ¶ms->meas.rawhist0, + ISP3X_RAWHIST_LITE_BASE, true, id); + isp_rawhstbig_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 isp33_isp_params_cfg *new_params) +{ + struct rkisp_isp_params_val_v33 *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 & ISP33_MODULE_BAY3D) && + (module_ens & ISP33_MODULE_BAY3D)) { + bool iirsparse_en = !!new_params->others.bay3d_cfg.iirsparse_en; + u32 w = ALIGN(isp_sdev->in_crop.width, 16); + u32 h = isp_sdev->in_crop.height; + u32 hsize, vsize, val; + bool is_alloc; + + if (dev->unite_div > ISP_UNITE_DIV1) + w = ALIGN(isp_sdev->in_crop.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); + if (dev->unite_div == ISP_UNITE_DIV4) + h = isp_sdev->in_crop.height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + + if (!iirsparse_en) { + hsize = w * 3 / 2 + w / 4; + vsize = h / 2; + } else { + hsize = w; + vsize = h; + } + val = ALIGN(hsize * vsize * 2, 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; + } + } + + hsize = (w * 36 / 8 + 31) / 32 * 4; + vsize = (h + 7) / 8; + val = ALIGN(hsize * vsize, 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; + } + } + + hsize = (((w + 31) / 32 + 1) / 2 * 2 + 3) / 4 * 4; + vsize = (h + 31) / 32; + val = ALIGN(hsize * vsize, 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; + } + } + + val = ALIGN(w * h / 4, 16); + priv_val->gain_size = val; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; + is_alloc = dev->is_aiisp_en ? true : false; + if (priv_val->buf_gain.mem_priv) { + if (val > priv_val->buf_gain.size) + rkisp_free_buffer(dev, &priv_val->buf_gain); + else + is_alloc = false; + } + if (is_alloc) { + priv_val->buf_gain.size = val; + if (ret) { + rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); + rkisp_free_buffer(dev, &priv_val->buf_3dnr_wgt); + dev_err(dev->dev, "alloc gain buf fail:%d\n", ret); + goto err_3dnr; + } + } + } + + return 0; +err_3dnr: + return ret; +} + +static bool +rkisp_params_check_bigmode_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev; + + dev->multi_index = 0; + dev->multi_mode = 0; + if (!hw->is_single) { + dev->is_frm_rd = true; + dev->multi_index = dev->dev_id; + } + + return dev->is_bigmode = false; +} + +/* Not called when the camera active, thus not isr protection. */ +static void +rkisp_params_first_cfg_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + struct isp33_isp_params_cfg *params = params_vdev->isp33_params; + struct rkisp_device *dev = params_vdev->dev; + int i; + + rkisp_params_check_bigmode_v33(params_vdev); + spin_lock(¶ms_vdev->config_lock); + 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(¶ms_vdev->config_lock); + + 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_v33(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->isp33_params, param, size); + } else { + /* left and right params for unit fast case */ + size = sizeof(struct isp33_isp_params_cfg); + memcpy(params_vdev->isp33_params, param, size); + if (params_vdev->dev->unite_div == ISP_UNITE_DIV2) + memcpy(params_vdev->isp33_params + 1, param, size); + } + rkisp_alloc_internal_buf(params_vdev, params_vdev->isp33_params); +} + +static void rkisp_clear_first_param_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + u32 mult = params_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; + u32 size = sizeof(struct isp33_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_v33 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + int i; + + if (!priv_val) + return; + + switch (module_id) { + case ISP33_MODULE_LDCH: + buf = priv_val->buf_ldch[id]; + break; + default: + return; + } + + for (i = 0; i < ISP32_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_v33 *priv_val = 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_val) { + dev_err(dev, "priv_val is NULL\n"); + return -EINVAL; + } + + switch (meshsize->module_id) { + case ISP33_MODULE_LDCH: + priv_val->buf_ldch_idx[id] = 0; + buf = priv_val->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; + default: + return -EINVAL; + } + + if (buf_cnt <= 0 || buf_cnt > ISP33_MESH_BUF_NUM) + buf_cnt = ISP33_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); + } + buf++; + } + + return 0; +err: + rkisp_deinit_mesh_buf(params_vdev, meshsize->module_id, id); + return -ENOMEM; +} + +static void +rkisp_get_param_size_v33(struct rkisp_isp_params_vdev *params_vdev, + unsigned int sizes[]) +{ + u32 mult = params_vdev->dev->unite_div; + + sizes[0] = sizeof(struct isp33_isp_params_cfg) * mult; + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + +static void +rkisp_params_get_meshbuf_inf_v33(struct rkisp_isp_params_vdev *params_vdev, + void *meshbuf_inf) +{ + struct rkisp_isp_params_val_v33 *priv_val = 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 ISP33_MODULE_LDCH: + priv_val->buf_ldch_idx[id] = 0; + buf = priv_val->buf_ldch[id]; + break; + default: + return; + } + + for (i = 0; i < ISP33_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_v33(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_v33(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_v33(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + struct rkisp_isp_params_val_v33 *priv_val = 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_val->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_val->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_val->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_val->buf_info_idx = 0; + priv_val->buf_info_cnt = cfg->buf_cnt; + priv_val->buf_info_owner = cfg->owner; + + cfg->wsize = wsize; + cfg->vsize = vsize; + return 0; +err: + for (i -= 1; i >= 0; i--) { + buf = &priv_val->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_v33(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v33 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v33.ds_fd = buf->dma_fd; + bay3dbuf->u.v33.ds_size = buf->size; + + buf = &priv_val->buf_gain; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v33.gain_fd = buf->dma_fd; + bay3dbuf->u.v33.gain_size = buf->size; +} + +static void +rkisp_params_stream_stop_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v33 *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]); + 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_v33(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, ISP33_MODULE_LDCH, id); +} + +/* Not called when the camera active, thus not isr protection. */ +static void +rkisp_params_disable_isp_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + int i; + + params_vdev->isp33_params->module_ens = 0; + params_vdev->isp33_params->module_en_update = ~ISP33_MODULE_FORCE; + + for (i = 0; i < params_vdev->dev->unite_div; i++) { + __isp_isr_other_en(params_vdev, params_vdev->isp33_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params_vdev->isp33_params, RKISP_PARAMS_ALL, i); + } +} + +static void +module_data_abandon(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params, u32 id) +{ + struct rkisp_isp_params_val_v33 *priv_val = params_vdev->priv_val; + struct isp2x_mesh_head *mesh_head; + int i; + + if (params->module_cfg_update & ISP33_MODULE_LDCH) { + const struct isp32_ldch_cfg *arg = ¶ms->others.ldch_cfg; + + for (i = 0; i < ISP32_MESH_BUF_NUM; i++) { + if (priv_val->buf_ldch[id][i].vaddr && + arg->buf_fd == priv_val->buf_ldch[id][i].dma_fd) { + mesh_head = priv_val->buf_ldch[id][i].vaddr; + mesh_head->stat = MESH_BUF_CHIPINUSE; + break; + } + } + } +} + +static void +rkisp_params_cfg_v33(struct rkisp_isp_params_vdev *params_vdev, + u32 frame_id, enum rkisp_params_type type) +{ + struct rkisp_device *dev = params_vdev->dev; + struct isp33_isp_params_cfg *new_params = NULL; + struct rkisp_buffer *cur_buf = params_vdev->cur_buf; + int i; + + spin_lock(¶ms_vdev->config_lock); + if (!params_vdev->streamon) + goto unlock; + + /* get buffer by frame_id */ + while (!list_empty(¶ms_vdev->params) && !cur_buf) { + cur_buf = list_first_entry(¶ms_vdev->params, + struct rkisp_buffer, queue); + + new_params = (struct isp33_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 & ISP33_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 & ISP33_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; + + new_params = (struct isp33_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 (type != RKISP_PARAMS_IMD) + new_params->module_cfg_update = 0; + new_params++; + } + if (type != RKISP_PARAMS_IMD) { + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + cur_buf = NULL; + } + +unlock: + params_vdev->cur_buf = cur_buf; + spin_unlock(¶ms_vdev->config_lock); +} + +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_ADRC_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_v33(struct rkisp_isp_params_vdev *params_vdev, + u32 isp_mis) +{ + struct rkisp_device *dev = params_vdev->dev; + u32 cur_frame_id; + + 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 (!params_vdev->cur_buf) + return; + + if (IS_HDR_RDBK(dev->rd_mode) && !params_vdev->rdbk_times) { + rkisp_params_cfg_v33(params_vdev, cur_frame_id, RKISP_PARAMS_SHD); + 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_v33(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_v33, + .clear_first_param = rkisp_clear_first_param_v33, + .get_param_size = rkisp_get_param_size_v33, + .first_cfg = rkisp_params_first_cfg_v33, + .disable_isp = rkisp_params_disable_isp_v33, + .isr_hdl = rkisp_params_isr_v33, + .param_cfg = rkisp_params_cfg_v33, + .param_cfgsram = rkisp_params_cfgsram_v33, + .get_meshbuf_inf = rkisp_params_get_meshbuf_inf_v33, + .set_meshbuf_size = rkisp_params_set_meshbuf_size_v33, + .free_meshbuf = rkisp_params_free_meshbuf_v33, + .stream_stop = rkisp_params_stream_stop_v33, + .fop_release = rkisp_params_fop_release_v33, + .check_bigmode = rkisp_params_check_bigmode_v33, + .info2ddr_cfg = rkisp_params_info2ddr_cfg_v33, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v33, +}; + +int rkisp_init_params_vdev_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v33 *priv_val; + int size; + + priv_val = kzalloc(sizeof(*priv_val), GFP_KERNEL); + if (!priv_val) + return -ENOMEM; + + size = sizeof(struct isp33_isp_params_cfg); + if (params_vdev->dev->hw_dev->unite) + size *= ISP_UNITE_MAX; + params_vdev->isp33_params = vmalloc(size); + if (!params_vdev->isp33_params) { + kfree(priv_val); + return -ENOMEM; + } + + params_vdev->priv_val = (void *)priv_val; + params_vdev->ops = &rkisp_isp_params_ops_tbl; + params_vdev->priv_ops = &isp_params_ops_v33; + rkisp_clear_first_param_v33(params_vdev); + priv_val->buf_info_owner = 0; + priv_val->buf_info_cnt = 0; + priv_val->buf_info_idx = -1; + return 0; +} + +void rkisp_uninit_params_vdev_v33(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v33 *priv_val = params_vdev->priv_val; + + if (params_vdev->isp33_params) + vfree(params_vdev->isp33_params); + kfree(priv_val); + params_vdev->priv_val = NULL; +} + +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33_DBG) +static void rkisp_get_params_rawawb(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp33_rawawb_meas_cfg *arg = ¶ms->meas.rawawb; + struct isp33_rawawb_meas_cfg *arg_rec = ¶ms_vdev->isp33_params->meas.rawawb; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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->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, 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 & 0xffff; + arg->wt1 = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_WT2, 0); + arg->wt2 = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_MAT0_XY, 0); + arg->mat0_x = val & 0xffff; + arg->mat0_y = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_MAT1_XY, 0); + arg->mat1_x = val & 0xffff; + arg->mat1_y = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_RGB2XY_MAT2_XY, 0); + arg->mat2_x = val & 0xffff; + arg->mat2_y = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_0, 0); + arg->nor_x0_0 = val & 0xffff; + arg->nor_x1_0 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_0, 0); + arg->nor_y0_0 = val & 0xffff; + arg->nor_y1_0 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_0, 0); + arg->big_x0_0 = val & 0xffff; + arg->big_x1_0 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_0, 0); + arg->big_y0_0 = val & 0xffff; + arg->big_y1_0 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_1, 0); + arg->nor_x0_1 = val & 0xffff; + arg->nor_x1_1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_1, 0); + arg->nor_y0_1 = val & 0xffff; + arg->nor_y1_1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_1, 0); + arg->big_x0_1 = val & 0xffff; + arg->big_x1_1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_1, 0); + arg->big_y0_1 = val & 0xffff; + arg->big_y1_1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_2, 0); + arg->nor_x0_2 = val & 0xffff; + arg->nor_x1_2 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_2, 0); + arg->nor_y0_2 = val & 0xffff; + arg->nor_y1_2 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_2, 0); + arg->big_x0_2 = val & 0xffff; + arg->big_x1_2 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_2, 0); + arg->big_y0_2 = val & 0xffff; + arg->big_y1_2 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_X_3, 0); + arg->nor_x0_3 = val & 0xffff; + arg->nor_x1_3 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_NOR_Y_3, 0); + arg->nor_y0_3 = val & 0xffff; + arg->nor_y1_3 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_X_3, 0); + arg->big_x0_3 = val & 0xffff; + arg->big_x1_3 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_XY_DETC_BIG_Y_3, 0); + arg->big_y0_3 = val & 0xffff; + arg->big_y1_3 = (val >> 16) & 0xffff; + + 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 & 0xffff; + arg->multiwindow0_v_offs = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW0_SIZE, 0); + arg->multiwindow0_h_size = val & 0xffff; + arg->multiwindow0_v_size = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW1_OFFS, 0); + arg->multiwindow1_h_offs = val & 0xffff; + arg->multiwindow1_v_offs = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW1_SIZE, 0); + arg->multiwindow1_h_size = val & 0xffff; + arg->multiwindow1_v_size = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW2_OFFS, 0); + arg->multiwindow2_h_offs = val & 0xffff; + arg->multiwindow2_v_offs = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW2_SIZE, 0); + arg->multiwindow2_h_size = val & 0xffff; + arg->multiwindow2_v_size = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW3_OFFS, 0); + arg->multiwindow3_h_offs = val & 0xffff; + arg->multiwindow3_v_offs = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_MULTIWINDOW3_SIZE, 0); + arg->multiwindow3_h_size = val & 0xffff; + arg->multiwindow3_v_size = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION0_XU, 0); + arg->exc_wp_region0_xu0 = val & 0xffff; + arg->exc_wp_region0_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION0_YV, 0); + arg->exc_wp_region0_yv0 = val & 0xffff; + arg->exc_wp_region0_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION1_XU, 0); + arg->exc_wp_region1_xu0 = val & 0xffff; + arg->exc_wp_region1_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION1_YV, 0); + arg->exc_wp_region1_yv0 = val & 0xffff; + arg->exc_wp_region1_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION2_XU, 0); + arg->exc_wp_region2_xu0 = val & 0xffff; + arg->exc_wp_region2_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION2_YV, 0); + arg->exc_wp_region2_yv0 = val & 0xffff; + arg->exc_wp_region2_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION3_XU, 0); + arg->exc_wp_region3_xu0 = val & 0xffff; + arg->exc_wp_region3_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION3_YV, 0); + arg->exc_wp_region3_yv0 = val & 0xffff; + arg->exc_wp_region3_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION4_XU, 0); + arg->exc_wp_region4_xu0 = val & 0xffff; + arg->exc_wp_region4_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION4_YV, 0); + arg->exc_wp_region4_yv0 = val & 0xffff; + arg->exc_wp_region4_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION5_XU, 0); + arg->exc_wp_region5_xu0 = val & 0xffff; + arg->exc_wp_region5_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION5_YV, 0); + arg->exc_wp_region5_yv0 = val & 0xffff; + arg->exc_wp_region5_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION6_XU, 0); + arg->exc_wp_region6_xu0 = val & 0xffff; + arg->exc_wp_region6_xu1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_RAWAWB_EXC_WP_REGION6_YV, 0); + arg->exc_wp_region6_yv0 = val & 0xffff; + arg->exc_wp_region6_yv1 = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP32_RAWAWB_EXC_WP_WEIGHT0_3, 0); + arg->exc_wp_region0_weight = val & 0xff; + arg->exc_wp_region1_weight = (val >> 8) & 0xff; + arg->exc_wp_region2_weight = (val >> 16) & 0xff; + arg->exc_wp_region3_weight = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP32_RAWAWB_EXC_WP_WEIGHT4_6, 0); + arg->exc_wp_region4_weight = val & 0xff; + arg->exc_wp_region5_weight = (val >> 8) & 0xff; + arg->exc_wp_region6_weight = (val >> 16) & 0xff; + + memcpy(arg->wp_blk_wei_w, arg_rec->wp_blk_wei_w, sizeof(arg->wp_blk_wei_w)); +} + + +static void rkisp_get_params_rawae0(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp2x_rawaebig_meas_cfg *arg = ¶ms->meas.rawae0; + const u32 ae_wnd_num[] = {1, 5, 15, 15}; + u32 addr = ISP3X_RAWAE_LITE_BASE, i, val; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_RAWAE0; + arg->wnd_num = (val >> 1) & 0x3; + arg->subwin_en[0] = !!(val & BIT(4)); + arg->subwin_en[1] = !!(val & BIT(5)); + arg->subwin_en[2] = !!(val & BIT(6)); + arg->subwin_en[3] = !!(val & BIT(7)); + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_OFFSET, 0); + arg->win.h_offs = val & 0x1fff; + arg->win.v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_BLK_SIZE, 0); + arg->win.h_size = (val & 0x1fff) * ae_wnd_num[arg->wnd_num]; + arg->win.v_size = ((val >> 16) & 0x1fff) * ae_wnd_num[arg->wnd_num]; + + for (i = 0; i < ISP39_RAWAEBIG_SUBWIN_NUM; i++) { + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_OFFSET + 8 * i, 0); + arg->subwin[i].h_offs = val & 0x1fff; + arg->subwin[i].v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_SIZE + 8 * i, 0); + arg->subwin[i].h_size = (val & 0x1fff) - arg->subwin[i].h_offs; + arg->subwin[i].v_size = ((val >> 16) & 0x1fff) - arg->subwin[i].v_offs; + } + + val = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, 0); + arg->rawae_sel = (val >> 22) & 0x3; + if (val & BIT(30)) + arg->rawae_sel |= ISP33_BNR2AE0_SEL_EN; +} + +static void rkisp_get_params_rawae3(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp2x_rawaebig_meas_cfg *arg = ¶ms->meas.rawae3; + const u32 ae_wnd_num[] = {1, 5, 15, 15}; + u32 addr = ISP3X_RAWAE_BIG1_BASE, i, val; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_RAWAE3; + arg->wnd_num = (val >> 1) & 0x3; + arg->subwin_en[0] = !!(val & BIT(4)); + arg->subwin_en[1] = !!(val & BIT(5)); + arg->subwin_en[2] = !!(val & BIT(6)); + arg->subwin_en[3] = !!(val & BIT(7)); + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_OFFSET, 0); + arg->win.h_offs = val & 0x1fff; + arg->win.v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_BLK_SIZE, 0); + arg->win.h_size = (val & 0x1fff) * ae_wnd_num[arg->wnd_num]; + arg->win.v_size = ((val >> 16) & 0x1fff) * ae_wnd_num[arg->wnd_num]; + + for (i = 0; i < ISP39_RAWAEBIG_SUBWIN_NUM; i++) { + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_OFFSET + 8 * i, 0); + arg->subwin[i].h_offs = val & 0x1fff; + arg->subwin[i].v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWAE_BIG_WND1_SIZE + 8 * i, 0); + arg->subwin[i].h_size = (val & 0x1fff) - arg->subwin[i].h_offs; + arg->subwin[i].v_size = ((val >> 16) & 0x1fff) - arg->subwin[i].v_offs; + } + + val = isp3_param_read(params_vdev, ISP3X_VI_ISP_PATH, 0); + arg->rawae_sel = (val >> 16) & 0x3; + if (val & BIT(29)) + arg->rawae_sel |= ISP33_BNR2AEBIG_SEL_EN; +} + +static void rkisp_get_params_rawhist0(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp2x_rawhistbig_cfg *arg = ¶ms->meas.rawhist0; + struct isp2x_rawhistbig_cfg *arg_rec = ¶ms_vdev->isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_RAWHIST0; + arg->stepsize = (val >> 1) & 0x7; + 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->win.h_offs = val & 0x1fff; + arg->win.v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_SIZE, 0); + arg->win.h_size = (val & 0x1fff) * hist_wnd_num[arg->wnd_num]; + arg->win.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, sizeof(arg->weight)); +} + +static void rkisp_get_params_rawhist3(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp2x_rawhistbig_cfg *arg = ¶ms->meas.rawhist3; + struct isp2x_rawhistbig_cfg *arg_rec = ¶ms_vdev->isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_RAWHIST3; + arg->stepsize = (val >> 1) & 0x7; + 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->win.h_offs = val & 0x1fff; + arg->win.v_offs = (val >> 16) & 0x1fff; + + val = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_SIZE, 0); + arg->win.h_size = (val & 0x1fff) * hist_wnd_num[arg->wnd_num]; + arg->win.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, sizeof(arg->weight)); +} + +static void rkisp_get_params_bls(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp32_bls_cfg *arg = ¶ms->others.bls_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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; + 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 isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP39_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 < ISP39_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 isp33_isp_params_cfg *params) +{ + struct isp3x_lsc_cfg *arg = ¶ms->others.lsc_cfg; + struct isp3x_lsc_cfg *arg_rec = ¶ms_vdev->isp33_params->others.lsc_cfg; + u32 val, i; + + val = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_LSC; + arg->sector_16x16 = !!(val & BIT(2)); + + for (i = 0; i < ISP39_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, sizeof(arg->r_data_tbl)); + memcpy(arg->gr_data_tbl, arg_rec->gr_data_tbl, sizeof(arg->gr_data_tbl)); + memcpy(arg->gb_data_tbl, arg_rec->gb_data_tbl, sizeof(arg->gb_data_tbl)); + memcpy(arg->b_data_tbl, arg_rec->b_data_tbl, sizeof(arg->b_data_tbl)); +} + +static void rkisp_get_params_awbgain(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_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 |= ISP33_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 isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP33_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 < ISP33_GIC_LUMA_DX_NUM; i++) + arg->luma_dx[i] = (val >> (i * 4)) & 0xf; + + for (i = 0; i < ISP33_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 isp33_isp_params_cfg *params) +{ + struct isp33_debayer_cfg *arg = ¶ms->others.debayer_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_DEBAYER_CONTROL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_DEBAYER; + arg->bypass = !!(val & BIT(1)); + arg->g_out_flt_en = !!(val & BIT(4)); + + 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) & 0xff; + + 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) & 0xff; + + for (i = 0; i < ISP33_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 < ISP33_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; + } +} + +static void rkisp_get_params_ccm(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP33_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, ISP33_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 < ISP33_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_goc(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP39_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 isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 isp33_isp_params_cfg *params) +{ + struct isp33_drc_cfg *arg = ¶ms->others.drc_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_DRC_CTRL0, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_DRC; + arg->bypass_en = !!(val & BIT(1)); + arg->cmps_byp_en = !!(val & BIT(2)); + arg->gainx32_en = !!(val & BIT(3)); + arg->bf_lp_en = !!(val & BIT(4)); + arg->raw_dly_dis = !!(val & BIT(29)); + + val = isp3_param_read(params_vdev, ISP3X_DRC_CTRL1, 0); + arg->position = val & 0x3fff; + arg->compres_scl = (val >> 14) & 0x1fff; + arg->offset_pow2 = (val >> 28) & 0xf; + + val = isp3_param_read(params_vdev, ISP3X_DRC_LPRATIO, 0); + arg->lpdetail_ratio = val & 0xfff; + arg->hpdetail_ratio = (val >> 12) & 0xfff; + arg->delta_scalein = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT0, 0); + arg->bilat_wt_off = val & 0xff; + arg->thumb_thd_neg = (val >> 8) & 0x1ff; + arg->thumb_thd_enable = !!(val & BIT(23)); + arg->weicur_pix = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT1, 0); + arg->cmps_offset_bits_int = val & 0xf; + arg->cmps_fixbit_mode = !!(val & BIT(4)); + arg->drc_gas_t = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT2, 0); + arg->thumb_clip = val & 0xfff; + arg->thumb_scale = (val >> 16) & 0xff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT3, 0); + arg->range_sgm_inv0 = val & 0x3ff; + arg->range_sgm_inv1 = (val >> 16) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP39_DRC_BILAT4, 0); + arg->weig_bilat = val & 0x1f; + arg->weight_8x8thumb = (val >> 8) & 0xff; + arg->bilat_soft_thd = (val >> 16) & 0x7ff; + arg->enable_soft_thd = !!(val & BIT(31)); + + for (i = 0; i < ISP33_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_COMPRES_Y0 + i * 4, 0); + arg->compres_y[i * 2] = val & 0xffff; + arg->compres_y[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_DRC_SCALE_Y0 + i * 4, 0); + arg->scale_y[i * 2] = val & 0xffff; + arg->scale_y[i * 2 + 1] = (val >> 16) & 0xffff; + val = isp3_param_read(params_vdev, ISP39_DRC_SFTHD_Y0 + i * 4, 0); + arg->sfthd_y[i * 2] = val & 0xffff; + arg->sfthd_y[i * 2 + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP3X_DRC_GAIN_Y8, 0); + arg->gain_y[2 * i] = val & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_DRC_COMPRES_Y8, 0); + arg->compres_y[i * 2] = val & 0xffff; + val = isp3_param_read(params_vdev, ISP3X_DRC_SCALE_Y8, 0); + arg->scale_y[i * 2] = val & 0xffff; + val = isp3_param_read(params_vdev, ISP39_DRC_SFTHD_Y8, 0); + arg->sfthd_y[i * 2] = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_DRC_IIRWG_GAIN, 0); + arg->min_ogain = val & 0xffff; +} + +static void rkisp_get_params_hdrmge(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp32_hdrmge_cfg *arg = ¶ms->others.hdrmge_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_HDRMGE; + arg->s_base = !!(val & BIT(1)); + arg->mode = (val >> 2) & 0x3; + arg->dbg_mode = (val >> 4) & 0x3; + arg->each_raw_en = !!(val & BIT(6)); + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_GAIN0, 0); + arg->gain0 = val & 0xffff; + arg->gain0_inv = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_GAIN1, 0); + arg->gain1 = val & 0xffff; + arg->gain1_inv = (val >> 16) & 0xffff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_GAIN2, 0); + arg->gain2 = val & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_LIGHTZ, 0); + arg->ms_dif_0p8 = val & 0xff; + arg->ms_diff_0p15 = (val >> 8) & 0xff; + arg->lm_dif_0p9 = (val >> 16) & 0xff; + arg->lm_dif_0p15 = (val >> 24) & 0xff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_MS_DIFF, 0); + arg->ms_scl = val & 0x7ff; + arg->ms_thd0 = (val >> 12) & 0x3ff; + arg->ms_thd1 = (val >> 22) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_LM_DIFF, 0); + arg->lm_scl = val & 0x7ff; + arg->lm_thd0 = (val >> 12) & 0x3ff; + arg->lm_thd1 = (val >> 22) & 0x3ff; + + for (i = 0; i < ISP33_HDRMGE_L_CURVE_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_DIFF_Y0 + 4 * i, 0); + arg->curve.curve_0[i] = val & 0xffff; + arg->curve.curve_1[i] = (val >> 16) & 0xffff; + } + + for (i = 0; i < ISP33_HDRMGE_E_CURVE_NUM; i++) { + val = isp3_param_read(params_vdev, ISP3X_HDRMGE_OVER_Y0 + 4 * i, 0); + arg->e_y[i] = val & 0x3ff; + arg->l_raw0[i] = (val >> 10) & 0x3ff; + arg->l_raw1[i] = (val >> 20) & 0x3ff; + } + + val = isp3_param_read(params_vdev, ISP32_HDRMGE_EACH_GAIN, 0); + arg->each_raw_gain0 = val & 0xffff; + arg->each_raw_gain1 = (val >> 16) & 0xffff; +} + +static void rkisp_get_params_ldch(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp32_ldch_cfg *arg = ¶ms->others.ldch_cfg; + struct rkisp_isp_params_val_v33 *priv_val = params_vdev->priv_val; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_LDCH_STS, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP33_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_val->buf_ldch_idx[0]; + arg->buf_fd = priv_val->buf_ldch[0][val].dma_fd; +} + +static void rkisp_get_params_bay3d(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp33_bay3d_cfg *arg = ¶ms->others.bay3d_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_BAY3D_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_BAY3D; + arg->bypass_en = !!(val & BIT(1)); + arg->iirsparse_en = !!(val & BIT(2)); + arg->out_use_pre_mode = (val >> 5) & 0x7; + arg->motion_est_en = !!(val & BIT(8)); + + 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)); + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CTRL3, 0); + arg->transf_mode = !!(val & BIT(0)); + arg->wgt_cal_mode = !!(val & BIT(1)); + arg->ww_mode = !!(val & BIT(2)); + arg->wgt_last_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 & BIT(15)); + 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, ISP33_BAY3D_CURHI_SIGSCL, 0); + arg->pre_sig_ctrl_scl = val & 0xffff; + + val = isp3_param_read(params_vdev, ISP33_BAY3D_CURHI_SIGOF, 0); + arg->pre_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 < ISP33_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; + + 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_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_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 < ISP33_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 < ISP33_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 & 0x3fffff; + 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, 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; +} + +static void rkisp_get_params_ynr(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp33_ynr_cfg *arg = ¶ms->others.ynr_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_YNR_GLOBAL_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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)); + + 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 < ISP33_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 < ISP33_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 < ISP33_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; + + 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; + arg->hi_spnr_filt_coeff[4] = (val >> 24) & 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 & 0x1ff; + arg->mi_spnr_filt_coeff1 = (val >> 10) & 0x1ff; + arg->mi_spnr_filt_coeff2 = (val >> 20) & 0x1ff; + + 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, 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; + + 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 < ISP33_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 isp33_isp_params_cfg *params) +{ + struct isp33_cnr_cfg *arg = ¶ms->others.cnr_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_CNR_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_CNR; + arg->exgain_bypass = !!(val & BIT(1)); + arg->yuv422_mode = !!(val & BIT(2)); + arg->thumb_mode = (val >> 4) & 0x3; + arg->hiflt_wgt0_mode = !!(val & BIT(8)); + arg->local_alpha_dis = !!(val & BIT(11)); + arg->loflt_coeff = (val >> 12) & 0x3f; + + 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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_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; + } +} + +static void rkisp_get_params_sharp(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp33_sharp_cfg *arg = ¶ms->others.sharp_cfg; + struct isp33_sharp_cfg *arg_rec = ¶ms_vdev->isp33_params->others.sharp_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP3X_SHARP_EN, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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_DETAIL1, 0); + arg->detail_fusion_slope_fix = val; + + val = isp3_param_read(params_vdev, ISP33_SHARP_LUMA_DX, 0); + for (i = 0; i < ISP33_SHARP_X_NUM; i++) + arg->luma_dx[i] = (val >> (i * 4)) & 0xf; + + for (i = 0; i < ISP33_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 < ISP33_SHARP_EDGE_KERNEL_NUM / 4; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE_KERNEL0 + i * 4, 0); + arg->edge_lpf_coeff[i * 4] = val & 0xff; + arg->edge_lpf_coeff[i * 4 + 1] = (val >> 8) & 0xff; + arg->edge_lpf_coeff[i * 4 + 2] = (val >> 16) & 0xff; + arg->edge_lpf_coeff[i * 4 + 3] = (val >> 24) & 0xff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_EDGE_KERNEL2, 0); + arg->edge_lpf_coeff[i * 4] = val & 0xff; + arg->edge_lpf_coeff[i * 4 + 1] = (val >> 8) & 0xff; + + for (i = 0; i < ISP33_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 < ISP33_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_STRG0, 0); + arg->tex2detail_strg[0] = val & 0x3ff; + arg->tex2detail_strg[1] = (val >> 10) & 0x3ff; + arg->tex2detail_strg[2] = (val >> 20) & 0x3ff; + + val = isp3_param_read(params_vdev, ISP33_SHARP_LOCAL_STRG1, 0); + arg->tex2detail_strg[3] = val & 0x3ff; + 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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_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 < ISP33_SHARP_HITEX_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; + + val = isp3_param_read(params_vdev, ISP33_SHARP_LOSSTEXINHINR_STRG, 0); + arg->loss_tex_in_hinr_strg = val & 0xff; + + for (i = 0; i < ISP33_SHARP_NOISE_CURVE_NUM / 2; i++) { + val = isp3_param_read(params_vdev, ISP33_SHARP_NOISE_CURVE0 + i * 4, 0); + arg->noise_curve_ext[i * 2] = val & 0xffff; + arg->noise_curve_ext[i * 2 + 1] = (val >> 16) & 0xffff; + } + val = isp3_param_read(params_vdev, ISP33_SHARP_NOISE_CURVE8, 0); + arg->noise_curve_ext[i * 2] = val & 0x7ff; + arg->noise_count_thred_ratio = (val >> 12) & 0xff; + arg->noise_clip_scale = (val >> 20) & 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; + + 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 isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 isp33_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 & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 isp33_isp_params_cfg *params) +{ + struct isp21_csm_cfg *arg = ¶ms->others.csm_cfg; + u32 i, val; + + for (i = 0; i < ISP33_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 isp33_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 isp33_isp_params_cfg *params) +{ + u32 val = isp3_param_read(params_vdev, ISP3X_IMG_EFF_CTRL, 0); + + if (val & ISP33_MODULE_EN) + params->module_ens |= ISP33_MODULE_IE; +} + +static void rkisp_get_params_enh(struct rkisp_isp_params_vdev *params_vdev, + struct isp33_isp_params_cfg *params) +{ + struct isp33_enh_cfg *arg = ¶ms->others.enh_cfg; + struct isp33_enh_cfg *arg_rec = ¶ms_vdev->isp33_params->others.enh_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP33_ENH_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP33_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 < ISP33_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 < ISP33_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 isp33_isp_params_cfg *params) +{ + struct isp33_hist_cfg *arg = ¶ms->others.hist_cfg; + struct isp33_hist_cfg *arg_rec = ¶ms_vdev->isp33_params->others.hist_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP33_HIST_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_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 < ISP33_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 isp33_isp_params_cfg *params) +{ + struct isp33_hsv_cfg *arg = ¶ms->others.hsv_cfg; + struct isp33_hsv_cfg *arg_rec = ¶ms_vdev->isp33_params->others.hsv_cfg; + u32 val; + + val = isp3_param_read(params_vdev, ISP3X_3DLUT_CTRL, 0); + if (!(val & ISP33_MODULE_EN)) + return; + params->module_ens |= ISP33_MODULE_HSV; + arg->hsv_1dlut0_en = !!(val & BIT(1)); + arg->hsv_1dlut1_en = !!(val & BIT(2)); + arg->hsv_2dlut_en = !!(val & BIT(3)); + arg->hsv_1dlut0_idx_mode = (val >> 4) & 0x3; + arg->hsv_1dlut1_idx_mode = (val >> 6) & 0x3; + arg->hsv_2dlut_idx_mode = (val >> 8) & 0x3; + arg->hsv_1dlut0_item_mode = (val >> 10) & 0x7; + arg->hsv_1dlut1_item_mode = (val >> 13) & 0x7; + arg->hsv_2dlut_item_mode = (val >> 16) & 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->lut_2d, arg_rec->lut_2d, sizeof(arg->lut_2d)); +} + +int rkisp_get_params_v33(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + struct isp33_isp_params_cfg *params = arg; + + if (!params) + return -EINVAL; + memset(params, 0, sizeof(struct isp33_isp_params_cfg)); + + 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_goc(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); + return 0; +} +#endif diff --git a/drivers/media/platform/rockchip/isp/isp_params_v33.h b/drivers/media/platform/rockchip/isp/isp_params_v33.h new file mode 100644 index 000000000000..25b94e900ece --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_params_v33.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2024 Rockchip Electronics Co., Ltd. */ + +#ifndef _RKISP_ISP_PARAM_V33_H +#define _RKISP_ISP_PARAM_V33_H + +#include "common.h" +#include "isp_params.h" + +#define ISP33_RAWHISTBIG_ROW_NUM 15 +#define ISP33_RAWHISTBIG_COLUMN_NUM 15 +#define ISP33_RAWHISTBIG_WEIGHT_REG_SIZE \ + (ISP33_RAWHISTBIG_ROW_NUM * ISP33_RAWHISTBIG_COLUMN_NUM) + +struct rkisp_isp_params_vdev; +struct rkisp_isp_params_ops_v33 { + void (*dpcc_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp39_dpcc_cfg *arg, u32 id); + void (*dpcc_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*bls_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_bls_cfg *arg, u32 id); + void (*bls_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*lsc_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_lsc_cfg *arg, u32 id); + void (*lsc_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*awbgain_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_awb_gain_cfg *arg, u32 id); + void (*awbgain_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*debayer_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_debayer_cfg *arg, u32 id); + void (*debayer_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*ccm_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_ccm_cfg *arg, u32 id); + void (*ccm_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*goc_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_gammaout_cfg *arg, u32 id); + void (*goc_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*cproc_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_cproc_cfg *arg, u32 id); + void (*cproc_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*ie_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*rawae0_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawaebig_meas_cfg *arg, u32 id); + void (*rawae0_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*rawae3_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawaebig_meas_cfg *arg, u32 id); + void (*rawae3_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*rawawb_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_rawawb_meas_cfg *arg, u32 id); + void (*rawawb_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*rawhst0_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawhistbig_cfg *arg, u32 id); + void (*rawhst0_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*rawhst3_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp2x_rawhistbig_cfg *arg, u32 id); + void (*rawhst3_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*hdrdrc_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_drc_cfg *arg, + enum rkisp_params_type type, u32 id); + void (*hdrdrc_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*hdrmge_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_hdrmge_cfg *arg, + enum rkisp_params_type type, u32 id); + void (*hdrmge_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*gic_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_gic_cfg *arg, u32 id); + void (*gic_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*enh_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_enh_cfg *arg, u32 id); + void (*enh_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*hist_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_hist_cfg *arg, u32 id); + void (*hist_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*hsv_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_hsv_cfg *arg, u32 id); + void (*hsv_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*ldch_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp32_ldch_cfg *arg, u32 id); + void (*ldch_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*ynr_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_ynr_cfg *arg, u32 id); + void (*ynr_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*cnr_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_cnr_cfg *arg, u32 id); + void (*cnr_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*sharp_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_sharp_cfg *arg, u32 id); + void (*sharp_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*bay3d_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_bay3d_cfg *arg, u32 id); + void (*bay3d_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*gain_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp3x_gain_cfg *arg, u32 id); + void (*gain_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*cac_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp33_cac_cfg *arg, u32 id); + void (*cac_enable)(struct rkisp_isp_params_vdev *params_vdev, + bool en, u32 id); + void (*csm_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp21_csm_cfg *arg, u32 id); + void (*cgc_config)(struct rkisp_isp_params_vdev *params_vdev, + const struct isp21_cgc_cfg *arg, u32 id); +}; + +struct rkisp_isp_params_val_v33 { + 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_info[RKISP_INFO2DDR_BUF_MAX]; + u32 buf_info_owner; + u32 buf_info_cnt; + int buf_info_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_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_V33) +int rkisp_init_params_vdev_v33(struct rkisp_isp_params_vdev *params_vdev); +void rkisp_uninit_params_vdev_v33(struct rkisp_isp_params_vdev *params_vdev); +#else +static inline int rkisp_init_params_vdev_v33(struct rkisp_isp_params_vdev *params_vdev) { return -EINVAL; } +static inline void rkisp_uninit_params_vdev_v33(struct rkisp_isp_params_vdev *params_vdev) {} +#endif +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33_DBG) +int rkisp_get_params_v33(struct rkisp_isp_params_vdev *params_vdev, void *arg); +#else +static inline int rkisp_get_params_v33(struct rkisp_isp_params_vdev *params_vdev, void *arg) +{ + pr_err("enable CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33_DBG in kernel config\n"); + return -EINVAL; +} +#endif + +#endif /* _RKISP_ISP_PARAM_V33_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_rockit.c b/drivers/media/platform/rockchip/isp/isp_rockit.c index d4ce12bdc404..57f9d8b374b9 100644 --- a/drivers/media/platform/rockchip/isp/isp_rockit.c +++ b/drivers/media/platform/rockchip/isp/isp_rockit.c @@ -22,6 +22,7 @@ struct rkisp_rockit_buffer { struct list_head queue; int buf_id; u32 buff_addr; + void *vaddr; }; static struct rkisp_stream *rkisp_rockit_get_stream(struct rockit_cfg *input_rockit_cfg) @@ -52,6 +53,10 @@ static struct rkisp_stream *rkisp_rockit_get_stream(struct rockit_cfg *input_roc return NULL; } + if (ispdev->isp_ver == ISP_V33 && + (input_rockit_cfg->nick_id == 3 || input_rockit_cfg->nick_id == 4)) + return NULL; + switch (input_rockit_cfg->nick_id) { case 0: stream = &ispdev->cap_dev.stream[RKISP_STREAM_MP]; @@ -117,6 +122,7 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) if (input_rockit_cfg->is_alloc) { struct dma_buf_attachment *dba; struct sg_table *sgt; + struct iosys_map map; for (i = 0; i < ROCKIT_BUF_NUM_MAX; i++) { if (!stream_cfg->buff_id[i] && !stream_cfg->rkisp_buff[i]) { @@ -147,6 +153,15 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) stream_cfg->buff_id[i] = 0; return PTR_ERR(sgt); } + isprk_buf->vaddr = NULL; + if (dma_buf_vmap(input_rockit_cfg->buf, &map) == 0) + isprk_buf->vaddr = map.vaddr; + if (rkisp_buf_dbg) { + u64 *data = isprk_buf->vaddr; + + if (data) + *data = RKISP_DATA_CHECK; + } isprk_buf->buff_addr = sg_dma_address(sgt->sgl); get_dma_buf(input_rockit_cfg->buf); isprk_buf->mpi_buf = input_rockit_cfg->mpibuf; @@ -154,9 +169,6 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) isprk_buf->dba = dba; isprk_buf->sgt = sgt; stream_cfg->rkisp_buff[i] = isprk_buf; - - for (i = 0; i < stream->out_isp_fmt.mplanes; i++) - isprk_buf->isp_buf.buff_addr[i] = isprk_buf->buff_addr; } if (ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) { @@ -193,13 +205,36 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) } if (stream->out_isp_fmt.mplanes == 1) { - for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) { - height = stream->out_fmt.height; - bytesperline = stream->out_fmt.plane_fmt[i].bytesperline; - offset = (i == 0) ? bytesperline * height : - stream->out_fmt.plane_fmt[i].sizeimage; - isprk_buf->isp_buf.buff_addr[i + 1] = - isprk_buf->isp_buf.buff_addr[i] + offset; + u32 y_offs = input_rockit_cfg->y_offset; + u32 u_offs = input_rockit_cfg->u_offset; + u32 vir_w = input_rockit_cfg->vir_width; + u32 dma_addr = isprk_buf->buff_addr; + + if (vir_w) + stream->out_fmt.plane_fmt[0].bytesperline = vir_w; + else + vir_w = stream->out_fmt.plane_fmt[0].bytesperline; + height = stream->out_fmt.height; + if (u_offs) { + offset = u_offs; + if (stream->out_isp_fmt.output_format == ISP32_MI_OUTPUT_YUV420) + stream->out_fmt.plane_fmt[1].sizeimage = vir_w * height / 2; + else + stream->out_fmt.plane_fmt[1].sizeimage = vir_w * height; + stream->out_fmt.plane_fmt[0].sizeimage = vir_w * height + + stream->out_fmt.plane_fmt[1].sizeimage; + } else { + offset = vir_w * height; + } + isprk_buf->isp_buf.buff_addr[0] = dma_addr + y_offs; + isprk_buf->isp_buf.buff_addr[1] = dma_addr + offset; + isprk_buf->isp_buf.vaddr[0] = NULL; + isprk_buf->isp_buf.vaddr[1] = NULL; + isprk_buf->isp_buf.vb.vb2_buf.planes[0].mem_priv = NULL; + if (isprk_buf->vaddr) { + isprk_buf->isp_buf.vaddr[0] = isprk_buf->vaddr + y_offs; + isprk_buf->isp_buf.vaddr[1] = isprk_buf->vaddr + offset; + isprk_buf->isp_buf.vb.vb2_buf.planes[0].mem_priv = isprk_buf->sgt; } } @@ -214,7 +249,7 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) return 0; } -int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) +int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd, struct rkisp_buffer *curr_buf) { struct rkisp_device *dev = stream->ispdev; struct rkisp_rockit_buffer *isprk_buf = NULL; @@ -230,24 +265,36 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) stream_cfg = &rockit_cfg->rkisp_dev_cfg[dev_id].rkisp_stream_cfg[stream->id]; if (cmd == ROCKIT_DVBM_END) { isprk_buf = - container_of(stream->curr_buf, struct rkisp_rockit_buffer, isp_buf); + container_of(curr_buf, struct rkisp_rockit_buffer, isp_buf); rockit_cfg->mpibuf = isprk_buf->mpi_buf; - rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp; + rockit_cfg->frame.u64PTS = curr_buf->vb.vb2_buf.timestamp; - rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence; + rockit_cfg->frame.u32TimeRef = curr_buf->vb.sequence; v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, - "%s stream:%d seq:%d buf:0x%x done\n", - __func__, stream->id, - stream->curr_buf->vb.sequence, - stream->curr_buf->buff_addr[0]); + "stream:%d seq:%d rockit buf done:0x%x\n", + stream->id, + curr_buf->vb.sequence, + curr_buf->buff_addr[0]); + if (rkisp_buf_dbg) { + u64 *data = isprk_buf->vaddr; + + if (data && *data == RKISP_DATA_CHECK) + v4l2_info(&dev->v4l2_dev, + "rockit seq:%d data no update:%llx %llx\n", + curr_buf->vb.sequence, + *data, *(data + 1)); + } } else { if (stream->ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) { - if (dev->is_first_double || stream_cfg->is_discard || - stream->ops->is_stream_stopped(stream)) + if (dev->skip_frame || stream_cfg->is_discard || + stream->skip_frame || stream->ops->is_stream_stopped(stream)) { + if (stream->skip_frame) + stream->skip_frame--; return 0; + } } else if (stream_cfg->dst_fps) { if (!stream_cfg->is_discard && !stream->curr_buf) { rockit_cfg->is_qbuf = true; @@ -267,6 +314,9 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) rockit_cfg->frame.u64PTS = ns; rockit_cfg->frame.u32TimeRef = seq; + if (dev->isp_ver == ISP_V33) + rockit_cfg->frame.ispEncCnt = + ISP33_ISP2ENC_FRM_CNT(rkisp_read(dev, ISP3X_ISP_DEBUG1, true)); } rockit_cfg->is_color = !rkisp_read(dev, ISP3X_IMG_EFF_CTRL, true); @@ -309,8 +359,12 @@ int rkisp_rockit_pause_stream(struct rockit_cfg *input_rockit_cfg) return -EINVAL; } - rockit_isp_ops.rkisp_stream_stop(stream); + v4l2_dbg(1, rkisp_debug, &stream->ispdev->v4l2_dev, + "%s stream:%d\n", __func__, stream->id); + rockit_isp_ops.rkisp_stream_stop(stream); + if (stream->ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) + rkisp_dvbm_deinit(stream->ispdev); return 0; } EXPORT_SYMBOL(rkisp_rockit_pause_stream); @@ -320,7 +374,7 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg, { struct rkisp_stream *stream = NULL; struct rkisp_buffer *isp_buf, *buf_temp; - int offset, i, ret; + int offset, ret; unsigned long lock_flags = 0; u32 reg, val, bytesperline; @@ -330,6 +384,11 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg, pr_err("the stream is NULL"); return -EINVAL; } + + v4l2_dbg(1, rkisp_debug, &stream->ispdev->v4l2_dev, + "%s stream:%d %dx%d wrap:%d\n", + __func__, stream->id, width, height, wrap_line); + stream->ispdev->cap_dev.wrap_line = wrap_line; stream->out_fmt.width = width; stream->out_fmt.height = height; @@ -364,14 +423,33 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg, stream->next_buf = NULL; } list_for_each_entry_safe(isp_buf, buf_temp, &stream->buf_queue, queue) { + struct rkisp_rockit_buffer *isprk_buf = + container_of(isp_buf, struct rkisp_rockit_buffer, isp_buf); + if (stream->out_isp_fmt.mplanes == 1) { - for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) { - height = stream->out_fmt.height; - bytesperline = stream->out_fmt.plane_fmt[i].bytesperline; - offset = (i == 0) ? bytesperline * height : - stream->out_fmt.plane_fmt[i].sizeimage; - isp_buf->buff_addr[i + 1] = isp_buf->buff_addr[i] + offset; + u32 y_offs = input_rockit_cfg->y_offset; + u32 u_offs = input_rockit_cfg->u_offset; + u32 vir_w = input_rockit_cfg->vir_width; + u32 dma_addr = isprk_buf->buff_addr; + + if (vir_w) + stream->out_fmt.plane_fmt[0].bytesperline = vir_w; + else + vir_w = stream->out_fmt.plane_fmt[0].bytesperline; + height = stream->out_fmt.height; + if (u_offs) { + offset = u_offs; + if (stream->out_isp_fmt.output_format == ISP32_MI_OUTPUT_YUV420) + stream->out_fmt.plane_fmt[1].sizeimage = vir_w * height / 2; + else + stream->out_fmt.plane_fmt[1].sizeimage = vir_w * height; + stream->out_fmt.plane_fmt[0].sizeimage = vir_w * height + + stream->out_fmt.plane_fmt[1].sizeimage; + } else { + offset = vir_w * height; } + isp_buf->buff_addr[0] = dma_addr + y_offs; + isp_buf->buff_addr[1] = dma_addr + offset; } } spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); @@ -392,12 +470,15 @@ int rkisp_rockit_resume_stream(struct rockit_cfg *input_rockit_cfg) return -EINVAL; } - stream->streaming = true; + v4l2_dbg(1, rkisp_debug, &stream->ispdev->v4l2_dev, + "%s stream:%d\n", __func__, stream->id); + ret = rockit_isp_ops.rkisp_stream_start(stream); if (ret < 0) { pr_err("stream id %d start failed\n", stream->id); return -EINVAL; } + stream->skip_frame = 2; if (stream->ispdev->isp_state == ISP_STOP) { stream->ispdev->isp_state = ISP_START; rkisp_rdbk_trigger_event(stream->ispdev, T_CMD_QUEUE, NULL); @@ -507,6 +588,12 @@ int rkisp_rockit_buf_free(struct rkisp_stream *stream) if (stream_cfg->rkisp_buff[i]) { isprk_buf = (struct rkisp_rockit_buffer *)stream_cfg->rkisp_buff[i]; if (isprk_buf->dba) { + if (isprk_buf->vaddr) { + struct iosys_map map = IOSYS_MAP_INIT_VADDR(isprk_buf->vaddr); + + dma_buf_vunmap(isprk_buf->dmabuf, &map); + isprk_buf->vaddr = NULL; + } if (isprk_buf->sgt) { dma_buf_unmap_attachment(isprk_buf->dba, isprk_buf->sgt, @@ -695,7 +782,7 @@ void rkisp_rockit_frame_start(struct rkisp_device *dev) stream = &dev->cap_dev.stream[i]; if (!stream->streaming) continue; - rkisp_rockit_buf_done(stream, ROCKIT_DVBM_START); + rkisp_rockit_buf_done(stream, ROCKIT_DVBM_START, stream->curr_buf); rkisp_rockit_ctrl_fps(stream); } } diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index fcd3cc86512a..f5a316326fce 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -15,6 +15,7 @@ #include "isp_stats_v3x.h" #include "isp_stats_v32.h" #include "isp_stats_v39.h" +#include "isp_stats_v33.h" #define STATS_NAME DRIVER_NAME "-statistics" #define RKISP_ISP_STATS_REQ_BUFS_MIN 2 @@ -91,6 +92,10 @@ static int rkisp_stats_fh_open(struct file *filp) if (!stats->dev->is_probe_end) return -EINVAL; + ret = rkisp_cond_poll_timeout(!stats->dev->is_thunderboot, + 5000, 1000 * USEC_PER_MSEC); + if (ret) + return ret; ret = v4l2_fh_open(filp); if (!ret) { @@ -150,7 +155,7 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) unsigned long flags; stats_buf->vaddr[0] = vb2_plane_vaddr(vb, 0); - if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V39) { + if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V39 || 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); @@ -164,6 +169,22 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) 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; + 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, @@ -259,7 +280,8 @@ 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_V39 || + 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; @@ -293,41 +315,47 @@ static void rkisp_stats_readout_task(unsigned long data) static void rkisp_init_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) { + struct rkisp_device *dev = stats_vdev->dev; + stats_vdev->rd_buf_idx = 0; stats_vdev->wr_buf_idx = 0; memset(stats_vdev->stats_buf, 0, sizeof(stats_vdev->stats_buf)); stats_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_STAT_3A; - if (stats_vdev->dev->isp_ver <= ISP_V13) + if (dev->isp_ver <= ISP_V13) rkisp_init_stats_vdev_v1x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V21) + else if (dev->isp_ver == ISP_V21) rkisp_init_stats_vdev_v21(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V20) + else if (dev->isp_ver == ISP_V20) rkisp_init_stats_vdev_v2x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V30) + else if (dev->isp_ver == ISP_V30) rkisp_init_stats_vdev_v3x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V32 || - stats_vdev->dev->isp_ver == ISP_V32_L) + else if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L) rkisp_init_stats_vdev_v32(stats_vdev); - else + else if (dev->isp_ver == ISP_V39) rkisp_init_stats_vdev_v39(stats_vdev); + else if (dev->isp_ver == ISP_V33) + rkisp_init_stats_vdev_v33(stats_vdev); } static void rkisp_uninit_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) { - if (stats_vdev->dev->isp_ver <= ISP_V13) + struct rkisp_device *dev = stats_vdev->dev; + + if (dev->isp_ver <= ISP_V13) rkisp_uninit_stats_vdev_v1x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V21) + else if (dev->isp_ver == ISP_V21) rkisp_uninit_stats_vdev_v21(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V20) + else if (dev->isp_ver == ISP_V20) rkisp_uninit_stats_vdev_v2x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V30) + else if (dev->isp_ver == ISP_V30) rkisp_uninit_stats_vdev_v3x(stats_vdev); - else if (stats_vdev->dev->isp_ver == ISP_V32 || - stats_vdev->dev->isp_ver == ISP_V32_L) + else if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L) rkisp_uninit_stats_vdev_v32(stats_vdev); - else + else if (dev->isp_ver == ISP_V39) rkisp_uninit_stats_vdev_v39(stats_vdev); + else if (dev->isp_ver == ISP_V33) + rkisp_uninit_stats_vdev_v33(stats_vdev); } void rkisp_stats_rdbk_enable(struct rkisp_isp_stats_vdev *stats_vdev, bool en) @@ -348,6 +376,8 @@ void rkisp_stats_first_ddr_config(struct rkisp_isp_stats_vdev *stats_vdev) 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); } void rkisp_stats_next_ddr_config(struct rkisp_isp_stats_vdev *stats_vdev) @@ -356,6 +386,8 @@ void rkisp_stats_next_ddr_config(struct rkisp_isp_stats_vdev *stats_vdev) 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); } void rkisp_stats_isr(struct rkisp_isp_stats_vdev *stats_vdev, diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/drivers/media/platform/rockchip/isp/isp_stats_v32.c index b1d2e8fc830e..e1633147afcf 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.c @@ -548,7 +548,6 @@ rkisp_stats_send_meas(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_isp_readout_work *meas_work) { struct rkisp_device *dev = stats_vdev->dev; - struct rkisp_hw_dev *hw = dev->hw_dev; struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev; struct rkisp_buffer *cur_buf = stats_vdev->cur_buf; struct rkisp32_isp_stat_buffer *cur_stat_buf = NULL; @@ -573,7 +572,7 @@ rkisp_stats_send_meas(struct rkisp_isp_stats_vdev *stats_vdev, } /* buffer done when frame of right handle */ - if (hw->unite == ISP_UNITE_ONE) { + if (dev->unite_div > ISP_UNITE_DIV1) { if (dev->unite_index == ISP_UNITE_LEFT) { cur_buf = NULL; is_dummy = false; @@ -584,7 +583,7 @@ rkisp_stats_send_meas(struct rkisp_isp_stats_vdev *stats_vdev, } } - if (hw->unite != ISP_UNITE_ONE || dev->unite_index == ISP_UNITE_RIGHT) { + 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) { diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v33.c b/drivers/media/platform/rockchip/isp/isp_stats_v33.c new file mode 100644 index 000000000000..15dc07cdb7fe --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_stats_v33.c @@ -0,0 +1,562 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 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_v33.h" +#include "isp_params_v33.h" + +#define ISP33_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 rkisp33_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 < ISP33_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 |= ISP33_STAT_SHARP; + } + return 0; +} + +static int +rkisp_stats_get_bay3d_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp33_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 < ISP33_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 |= ISP33_STAT_BAY3D; + } + return 0; +} + +static int +rkisp_stats_get_hist_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp33_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_vdev *params = &dev->params_vdev; + struct rkisp_isp_params_val_v33 *priv_val = params->priv_val; + struct isp33_isp_params_cfg *params_rec = params->isp33_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 < ISP33_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 |= ISP33_STAT_HIST; + } + } + return 0; +} + +static int +rkisp_stats_get_enh_stats(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp33_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_vdev *params = &dev->params_vdev; + struct rkisp_isp_params_val_v33 *priv_val = params->priv_val; + struct isp33_isp_params_cfg *params_rec = params->isp33_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) { + enh = &pbuf->stat.enh; + 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 |= ISP33_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; + 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_AWB_ADDR, val, i, false); + } + v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, + "%s BASE:0x%x SHD AEBIG:0x%x AE0: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_AWB_ADDR_SHD)); + } + return ret; +} + +static void +rkisp_stats_info2ddr(struct rkisp_isp_stats_vdev *stats_vdev, + struct rkisp33_stat_buffer *pbuf) +{ + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_isp_params_val_v33 *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 |= ISP33_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_v33(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 rkisp33_stat_buffer *cur_stat_buf = NULL; + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + u32 val, w3a_int, cur_frame_id = meas_work->frame_id; + bool is_dummy = false; + unsigned long flags; + + w3a_int = isp3_stats_read(stats_vdev, ISP39_W3A_INT_STAT); + if (w3a_int) + isp3_stats_write(stats_vdev, ISP39_W3A_INT_STAT, w3a_int); + + 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 (w3a_int & ISP39_W3A_INT_ERR_MASK) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWAE_BIG1_BASE); + if (val & ISP33_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAE_BIG1_BASE, val); + + val = isp3_stats_read(stats_vdev, ISP3X_RAWAE_LITE_BASE); + if (val & ISP33_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAE_LITE_BASE, val); + + val = isp3_stats_read(stats_vdev, ISP3X_RAWHIST_BIG1_BASE); + if (val & ISP33_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWHIST_BIG1_BASE, val); + + val = isp3_stats_read(stats_vdev, ISP3X_RAWHIST_LITE_BASE); + if (val & ISP33_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWHIST_LITE_BASE, val); + + val = isp3_stats_read(stats_vdev, ISP3X_RAWAWB_BASE); + if (val & ISP33_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAWB_BASE, val); + + v4l2_warn(&dev->v4l2_dev, + "id:%d stats seq:%d error:0x%x overflow(aebig:%d ae0:%d awb:%d wcfifo(wr:%d rd:%d))\n", + dev->unite_index, cur_frame_id, w3a_int, + !!(w3a_int & ISP39_W3A_INT_AEBIG_OVF), + !!(w3a_int & ISP39_W3A_INT_AE0_OVF), + !!(w3a_int & ISP39_W3A_INT_AWB_OVF), + !!(w3a_int & ISP39_W3A_INT_WCFIFO_WR_ERR), + !!(w3a_int & ISP39_W3A_INT_WCFIFO_RD_ERR)); + } else { + if (meas_work->isp3a_ris & ISP3X_3A_RAWAWB && cur_stat_buf) + cur_stat_buf->meas_type |= ISP33_STAT_RAWAWB; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG && cur_stat_buf) + cur_stat_buf->meas_type |= ISP33_STAT_RAWAE3; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_BIG && cur_stat_buf) + cur_stat_buf->meas_type |= ISP33_STAT_RAWHST3; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_CH0 && cur_stat_buf) + cur_stat_buf->meas_type |= ISP33_STAT_RAWAE0; + + if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_CH0 && cur_stat_buf) + cur_stat_buf->meas_type |= ISP33_STAT_RAWHST0; + } + 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 |= ISP33_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\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); +} + +static void +rkisp_stats_isr_v33(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); + + isp_mis_tmp &= isp3_stats_read(stats_vdev, ISP3X_ISP_3A_MIS); + if (isp_mis_tmp) + v4l2_err(stats_vdev->vnode.vdev.v4l2_dev, + "isp3A icr 3A info err: 0x%x 0x%x\n", + isp_mis_tmp, isp3a_ris); + } + + 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_v33(stats_vdev, &work); + } +} + +static void +rkisp_get_stat_size_v33(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + int mult = stats_vdev->dev->unite_div; + + sizes[0] = ALIGN(sizeof(struct rkisp33_stat_buffer), 16); + sizes[0] *= mult; + 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, +}; + +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; + + if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) + return; + + rkisp_get_stat_size_v33(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; + } + rkisp_unite_set_bits(dev, ISP3X_SWS_CFG, 0, ISP3X_3A_DDR_WRITE_EN, false); + val = ISP39_W3A_EN | ISP39_W3A_AUTO_CLR_EN | ISP39_W3A_FORCE_UPD; + 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; + } +} + +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; + + 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); +} + +void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev) +{ + stats_vdev->ops = &rkisp_isp_stats_ops_tbl; +} + +void rkisp_uninit_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev) +{ + +} diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v33.h b/drivers/media/platform/rockchip/isp/isp_stats_v33.h new file mode 100644 index 000000000000..6360e0abf76e --- /dev/null +++ b/drivers/media/platform/rockchip/isp/isp_stats_v33.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2024 Rockchip Electronics Co., Ltd. */ + +#ifndef _RKISP_STATS_V33_H +#define _RKISP_STATS_V33_H + +#include +#include +#include +#include "common.h" + +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 + +#endif /* _RKISP_ISP_STATS_V33_H */ diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index 94c983bd475f..d52e406d0fd8 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -12,6 +12,7 @@ #include "regs_v2x.h" #include "isp_params_v3x.h" #include "isp_params_v32.h" +#include "isp_params_v33.h" #include "isp_params_v39.h" #ifdef CONFIG_PROC_FS @@ -980,6 +981,157 @@ static void isp39_show(struct rkisp_device *dev, struct seq_file *p) !!(val & BIT(3)), !!(val & BIT(2)), !!(val & BIT(1)), !!(val & BIT(0))); } +static void isp33_show(struct rkisp_device *dev, struct seq_file *p) +{ + struct rkisp_isp_params_val_v33 *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))); + tmp = rkisp_read(dev, ISP32_MI_WR_VFLIP_CTRL, false); + val = rkisp_read(dev, ISP3X_ISP_CTRL0, false); + seq_printf(p, "%-10s mirror:%d flip(mp:%d sp:%d bp:%d)\n", + "MIR_FLIP", !!(val & BIT(5)), + !!(tmp & BIT(0)), !!(tmp & BIT(1)), !!(tmp & BIT(2))); + 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_CMSK_CTRL0, false); + seq_printf(p, "%-10s %s(0x%x)\n", "CMSK", (val & 1) ? "ON" : "OFF", val); + 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 sparse:%d 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 & BIT(2)), !(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, ISP3X_RAWAWB_CTRL, false); + seq_printf(p, "%-10s %s(0x%x)\n", "RAWAWB", (val & 1) ? "ON" : "OFF", val); + 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, ISP32_BLS_ISP_OB_PREDGAIN, false); + seq_printf(p, "%-10s %s(0x%x)\n", "OB", val ? "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; @@ -1106,6 +1258,10 @@ static int isp_show(struct seq_file *p, void *v) if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V39)) isp39_show(dev, p); break; + case ISP_V33: + if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33)) + isp33_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 854ccd2ae84d..6263bd18469c 100644 --- a/drivers/media/platform/rockchip/isp/regs.c +++ b/drivers/media/platform/rockchip/isp/regs.c @@ -462,7 +462,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 || + if (dev->isp_ver == ISP_V39 || 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; @@ -489,6 +489,7 @@ 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 || (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_v2x.h b/drivers/media/platform/rockchip/isp/regs_v2x.h index 12dfdbad8449..fa2efa10708c 100644 --- a/drivers/media/platform/rockchip/isp/regs_v2x.h +++ b/drivers/media/platform/rockchip/isp/regs_v2x.h @@ -2678,13 +2678,21 @@ static inline void raw_rd_ctrl(void __iomem *base, u32 val) static inline void mi_raw_length(struct rkisp_stream *stream) { bool is_direct = true; + u32 bytesperline = stream->out_fmt.plane_fmt[0].bytesperline; if (stream->config->mi.length == MI_RAW0_RD_LENGTH || stream->config->mi.length == MI_RAW1_RD_LENGTH || - stream->config->mi.length == MI_RAW2_RD_LENGTH) + stream->config->mi.length == MI_RAW2_RD_LENGTH) { is_direct = false; - rkisp_unite_write(stream->ispdev, stream->config->mi.length, - stream->out_fmt.plane_fmt[0].bytesperline, is_direct); + if (stream->ispdev->isp_ver == ISP_V33 && + !IS_HDR_RDBK(stream->ispdev->rd_mode) && + stream->config->mi.length == MI_RAW2_RD_LENGTH && + stream->ispdev->unite_div == ISP_UNITE_DIV2) { + bytesperline = stream->out_fmt.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + bytesperline = ALIGN(bytesperline * stream->out_isp_fmt.bpp[0] / 8, 256); + } + } + rkisp_unite_write(stream->ispdev, stream->config->mi.length, bytesperline, is_direct); if (stream->ispdev->isp_ver == ISP_V21 || stream->ispdev->isp_ver == ISP_V30) rkisp_unite_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); } diff --git a/drivers/media/platform/rockchip/isp/regs_v3x.h b/drivers/media/platform/rockchip/isp/regs_v3x.h index ebd4a2202fac..93d4f3056033 100644 --- a/drivers/media/platform/rockchip/isp/regs_v3x.h +++ b/drivers/media/platform/rockchip/isp/regs_v3x.h @@ -235,6 +235,9 @@ #define ISP39_HF_FACTOR6 (ISP3X_CCM_BASE + 0x00070) #define ISP39_HF_FACTOR7 (ISP3X_CCM_BASE + 0x00074) #define ISP39_HF_FACTOR8 (ISP3X_CCM_BASE + 0x00078) +#define ISP33_CCM_HF_THD (ISP3X_CCM_BASE + 0x00054) +#define ISP33_CCM_HF_FACTOR0 (ISP3X_CCM_BASE + 0x00058) +#define ISP33_CCM_HF_FACTOR8 (ISP3X_CCM_BASE + 0x00078) #define ISP3X_CPROC_BASE 0x00000800 #define ISP3X_CPROC_CTRL (ISP3X_CPROC_BASE + 0x00000) @@ -404,6 +407,40 @@ #define ISP32_BP_RESIZE_HC_OFFS_MI_SHD (ISP32_BP_RESIZE_BASE + 0x00074) #define ISP32_BP_RESIZE_IN_CROP_OFFSET (ISP32_BP_RESIZE_BASE + 0x00078) +#define ISP33_BP_SCALE_BASE 0x00000E00 +#define ISP33_BP_SCALE_CTRL (ISP33_BP_SCALE_BASE + 0x0000) +#define ISP33_BP_SCALE_UPDATE (ISP33_BP_SCALE_BASE + 0x0004) +#define ISP33_BP_SCALE_SRC_SIZE (ISP33_BP_SCALE_BASE + 0x0008) +#define ISP33_BP_SCALE_DST_SIZE (ISP33_BP_SCALE_BASE + 0x000c) +#define ISP33_BP_SCALE_HY_FAC (ISP33_BP_SCALE_BASE + 0x0010) +#define ISP33_BP_SCALE_HC_FAC (ISP33_BP_SCALE_BASE + 0x0014) +#define ISP33_BP_SCALE_VY_FAC (ISP33_BP_SCALE_BASE + 0x0018) +#define ISP33_BP_SCALE_VC_FAC (ISP33_BP_SCALE_BASE + 0x001c) +#define ISP33_BP_SCALE_HY_OFFS (ISP33_BP_SCALE_BASE + 0x0020) +#define ISP33_BP_SCALE_HC_OFFS (ISP33_BP_SCALE_BASE + 0x0024) +#define ISP33_BP_SCALE_VY_OFFS (ISP33_BP_SCALE_BASE + 0x0028) +#define ISP33_BP_SCALE_HY_SIZE (ISP33_BP_SCALE_BASE + 0x0040) +#define ISP33_BP_SCALE_HC_SIZE (ISP33_BP_SCALE_BASE + 0x0044) +#define ISP33_BP_SCALE_HY_OFFS_MI (ISP33_BP_SCALE_BASE + 0x0048) +#define ISP33_BP_SCALE_HC_OFFS_MI (ISP33_BP_SCALE_BASE + 0x004c) +#define ISP33_BP_SCALE_IN_CROP_OFFSET (ISP33_BP_SCALE_BASE + 0x0050) +#define ISP33_BP_SCALE_CTRL_SHD (ISP33_BP_SCALE_BASE + 0x0080) +#define ISP33_BP_SCALE_SRC_SIZE_SHD (ISP33_BP_SCALE_BASE + 0x0088) +#define ISP33_BP_SCALE_DST_SIZE_SHD (ISP33_BP_SCALE_BASE + 0x008c) +#define ISP33_BP_SCALE_HY_FAC_SHD (ISP33_BP_SCALE_BASE + 0x0090) +#define ISP33_BP_SCALE_HC_FAC_SHD (ISP33_BP_SCALE_BASE + 0x0094) +#define ISP33_BP_SCALE_VY_FAC_SHD (ISP33_BP_SCALE_BASE + 0x0098) +#define ISP33_BP_SCALE_VC_FAC_SHD (ISP33_BP_SCALE_BASE + 0x009c) +#define ISP33_BP_SCALE_HY_OFFS_SHD (ISP33_BP_SCALE_BASE + 0x00a0) +#define ISP33_BP_SCALE_HC_OFFS_SHD (ISP33_BP_SCALE_BASE + 0x00a4) +#define ISP33_BP_SCALE_VY_OFFS_SHD (ISP33_BP_SCALE_BASE + 0x00a8) +#define ISP33_BP_SCALE_VC_OFFS_SHD (ISP33_BP_SCALE_BASE + 0x00ac) +#define ISP33_BP_SCALE_HY_SIZE_SHD (ISP33_BP_SCALE_BASE + 0x00c0) +#define ISP33_BP_SCALE_HC_SIZE_SHD (ISP33_BP_SCALE_BASE + 0x00c4) +#define ISP33_BP_SCALE_HY_OFFS_MI_SHD (ISP33_BP_SCALE_BASE + 0x00c8) +#define ISP33_BP_SCALE_HC_OFFS_MI_SHD (ISP33_BP_SCALE_BASE + 0x00cc) +#define ISP33_BP_SCALE_IN_CROP_OFFSET_SHD (ISP33_BP_SCALE_BASE + 0x00d0) + #define ISP3X_SELF_RESIZE_BASE 0x00001000 #define ISP3X_SELF_RESIZE_CTRL (ISP3X_SELF_RESIZE_BASE + 0x00000) #define ISP3X_SELF_RESIZE_SCALE_HY (ISP3X_SELF_RESIZE_BASE + 0x00004) @@ -900,6 +937,31 @@ #define ISP32_CAC_EXPO_ADJ_B (ISP3X_CAC_BASE + 0x00088) #define ISP32_CAC_EXPO_ADJ_R (ISP3X_CAC_BASE + 0x0008c) #define ISP32_CAC_RO_CNT (ISP3X_CAC_BASE + 0x000fc) +#define ISP33_CAC_HIGH_DIRECT (ISP3X_CAC_BASE + 0x00008) +#define ISP33_CAC_OVER_EXPO0 (ISP3X_CAC_BASE + 0x0000c) +#define ISP33_CAC_OVER_EXPO1 (ISP3X_CAC_BASE + 0x00010) +#define ISP33_CAC_FLAT (ISP3X_CAC_BASE + 0x00014) +#define ISP33_CAC_GAUSS_COEFF (ISP3X_CAC_BASE + 0x00018) +#define ISP33_CAC_RATIO (ISP3X_CAC_BASE + 0x0001c) +#define ISP33_CAC_WGT_COLOR_B (ISP3X_CAC_BASE + 0x00020) +#define ISP33_CAC_WGT_COLOR_R (ISP3X_CAC_BASE + 0x00024) +#define ISP33_CAC_WGT_COLOR_SLOPE_B (ISP3X_CAC_BASE + 0x00028) +#define ISP33_CAC_WGT_COLOR_SLOPE_R (ISP3X_CAC_BASE + 0x0002c) +#define ISP33_CAC_WGT_COLOR_LUMA0 (ISP3X_CAC_BASE + 0x00030) +#define ISP33_CAC_WGT_COLOR_LUMA1 (ISP3X_CAC_BASE + 0x00034) +#define ISP33_CAC_WGT_OVER_EXPO0 (ISP3X_CAC_BASE + 0x00038) +#define ISP33_CAC_WGT_OVER_EXPO1 (ISP3X_CAC_BASE + 0x0003c) +#define ISP33_CAC_WGT_CONTRAST0 (ISP3X_CAC_BASE + 0x00040) +#define ISP33_CAC_WGT_CONTRAST1 (ISP3X_CAC_BASE + 0x00044) +#define ISP33_CAC_WGT_CONTRAST2 (ISP3X_CAC_BASE + 0x00048) +#define ISP33_CAC_WGT_DARK_AREA0 (ISP3X_CAC_BASE + 0x0004c) +#define ISP33_CAC_WGT_DARK_AREA1 (ISP3X_CAC_BASE + 0x00050) +#define ISP33_CAC_PSF_B0 (ISP3X_CAC_BASE + 0x00054) +#define ISP33_CAC_PSF_B2 (ISP3X_CAC_BASE + 0x0005c) +#define ISP33_CAC_PSF_R0 (ISP3X_CAC_BASE + 0x00060) +#define ISP33_CAC_PSF_R2 (ISP3X_CAC_BASE + 0x00068) +#define ISP33_CAC_RO_CNT (ISP3X_CAC_BASE + 0x000f8) +#define ISP33_CAC_DEBUG (ISP3X_CAC_BASE + 0x000fc) #define ISP3X_YNR_BASE 0x00002700 #define ISP3X_YNR_GLOBAL_CTRL (ISP3X_YNR_BASE + 0x00000) @@ -986,6 +1048,31 @@ #define ISP39_YNR_NLM_COE (ISP3X_YNR_BASE + 0x000f4) #define ISP39_YNR_NLM_WEIGHT (ISP3X_YNR_BASE + 0x000f8) #define ISP39_YNR_NLM_NR_WEIGHT (ISP3X_YNR_BASE + 0x000fc) +#define ISP33_YNR_GAIN_CTRL (ISP3X_YNR_BASE + 0x00010) +#define ISP33_YNR_GAIN_ADJ_0_2 (ISP3X_YNR_BASE + 0x00014) +#define ISP33_YNR_RNR_MAX_R (ISP3X_YNR_BASE + 0x00020) +#define ISP33_YNR_RNR_CENTER_COOR (ISP3X_YNR_BASE + 0x00024) +#define ISP33_YNR_RNR_STRENGTH03 (ISP3X_YNR_BASE + 0x00028) +#define ISP33_YNR_RNR_STRENGTH16 (ISP3X_YNR_BASE + 0x00038) +#define ISP33_YNR_SGM_DX_0_1 (ISP3X_YNR_BASE + 0x00040) +#define ISP33_YNR_SGM_DX_16 (ISP3X_YNR_BASE + 0x00060) +#define ISP33_YNR_SGM_Y_0_1 (ISP3X_YNR_BASE + 0x00064) +#define ISP33_YNR_SGM_Y_16 (ISP3X_YNR_BASE + 0x00084) +#define ISP33_YNR_HI_SIGMA_GAIN (ISP3X_YNR_BASE + 0x000a0) +#define ISP33_YNR_HI_GAUS_COE (ISP3X_YNR_BASE + 0x000a4) +#define ISP33_YNR_HI_WEIGHT (ISP3X_YNR_BASE + 0x000a8) +#define ISP33_YNR_HI_GAUS1_COE_0_2 (ISP3X_YNR_BASE + 0x000ac) +#define ISP33_YNR_HI_GAUS1_COE_3_5 (ISP3X_YNR_BASE + 0x000b0) +#define ISP33_YNR_HI_TEXT (ISP3X_YNR_BASE + 0x000b4) +#define ISP33_YNR_MI_GAUS_COE (ISP3X_YNR_BASE + 0x000c0) +#define ISP33_YNR_MI_STRG_DETAIL (ISP3X_YNR_BASE + 0x000c4) +#define ISP33_YNR_MI_WEIGHT (ISP3X_YNR_BASE + 0x000c8) +#define ISP33_YNR_LO_STRG_DETAIL (ISP3X_YNR_BASE + 0x000e0) +#define ISP33_YNR_LO_LIMIT_SCALE (ISP3X_YNR_BASE + 0x000e4) +#define ISP33_YNR_LO_WEIGHT (ISP3X_YNR_BASE + 0x000e8) +#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 ISP3X_CNR_BASE 0x00002800 #define ISP3X_CNR_CTRL (ISP3X_CNR_BASE + 0x00000) @@ -1101,6 +1188,141 @@ #define ISP39_SHARP_DETAIL_STRG_LUT6 (ISP3X_SHARP_BASE + 0x000dc) #define ISP39_SHARP_DETAIL_STRG_LUT7 (ISP3X_SHARP_BASE + 0x000e0) #define ISP39_SHARP_DETAIL_STRG_LUT8 (ISP3X_SHARP_BASE + 0x000e4) +#define ISP33_SHARP_TEXTURE0 (ISP3X_SHARP_BASE + 0x00004) +#define ISP33_SHARP_TEXTURE1 (ISP3X_SHARP_BASE + 0x00008) +#define ISP33_SHARP_TEXTURE2 (ISP3X_SHARP_BASE + 0x0000c) +#define ISP33_SHARP_TEXTURE3 (ISP3X_SHARP_BASE + 0x00010) +#define ISP33_SHARP_TEXTURE4 (ISP3X_SHARP_BASE + 0x00014) +#define ISP33_SHARP_HPF_KERNEL0 (ISP3X_SHARP_BASE + 0x00018) +#define ISP33_SHARP_HPF_KERNEL1 (ISP3X_SHARP_BASE + 0x0001c) +#define ISP33_SHARP_TEXFLT_KERNEL (ISP3X_SHARP_BASE + 0x00020) +#define ISP33_SHARP_DETAIL0 (ISP3X_SHARP_BASE + 0x00024) +#define ISP33_SHARP_DETAIL1 (ISP3X_SHARP_BASE + 0x00028) +#define ISP33_SHARP_LUMA_DX (ISP3X_SHARP_BASE + 0x0002c) +#define ISP33_SHARP_PBF_VSIGMA0 (ISP3X_SHARP_BASE + 0x00030) +#define ISP33_SHARP_PBF_KERNEL (ISP3X_SHARP_BASE + 0x00040) +#define ISP33_SHARP_DETAIL_KERNEL0 (ISP3X_SHARP_BASE + 0x00044) +#define ISP33_SHARP_DETAIL_KERNEL1 (ISP3X_SHARP_BASE + 0x00048) +#define ISP33_SHARP_DETAIL_KERNEL2 (ISP3X_SHARP_BASE + 0x0004c) +#define ISP33_SHARP_GAIN (ISP3X_SHARP_BASE + 0x00050) +#define ISP33_SHARP_GAIN_ADJ0 (ISP3X_SHARP_BASE + 0x00054) +#define ISP33_SHARP_GAIN_ADJ1 (ISP3X_SHARP_BASE + 0x00058) +#define ISP33_SHARP_GAIN_ADJ2 (ISP3X_SHARP_BASE + 0x0005c) +#define ISP33_SHARP_GAIN_ADJ3 (ISP3X_SHARP_BASE + 0x00060) +#define ISP33_SHARP_GAIN_ADJ4 (ISP3X_SHARP_BASE + 0x00064) +#define ISP33_SHARP_EDGE0 (ISP3X_SHARP_BASE + 0x00068) +#define ISP33_SHARP_EDGE1 (ISP3X_SHARP_BASE + 0x0006c) +#define ISP33_SHARP_EDGE_KERNEL0 (ISP3X_SHARP_BASE + 0x00070) +#define ISP33_SHARP_EDGE_KERNEL2 (ISP3X_SHARP_BASE + 0x00078) +#define ISP33_SHARP_EDGE_WGT_VAL0 (ISP3X_SHARP_BASE + 0x0007c) +#define ISP33_SHARP_EDGE_WGT_VAL5 (ISP3X_SHARP_BASE + 0x00090) +#define ISP33_SHARP_LUMA_ADJ_STRG0 (ISP3X_SHARP_BASE + 0x00094) +#define ISP33_SHARP_CENTER (ISP3X_SHARP_BASE + 0x0009c) +#define ISP33_SHARP_OUT_LIMIT (ISP3X_SHARP_BASE + 0x000a0) +#define ISP33_SHARP_TEX_X_INV_FIX0 (ISP3X_SHARP_BASE + 0x000a4) +#define ISP33_SHARP_TEX_X_INV_FIX1 (ISP3X_SHARP_BASE + 0x000a8) +#define ISP33_SHARP_TEX_X_INV_FIX2 (ISP3X_SHARP_BASE + 0x000ac) +#define ISP33_SHARP_LOCAL_STRG0 (ISP3X_SHARP_BASE + 0x000b0) +#define ISP33_SHARP_LOCAL_STRG1 (ISP3X_SHARP_BASE + 0x000b4) +#define ISP33_SHARP_LOCAL_STRG2 (ISP3X_SHARP_BASE + 0x000b8) +#define ISP33_SHARP_DETAIL_SCALE_TAB0 (ISP3X_SHARP_BASE + 0x000c0) +#define ISP33_SHARP_DETAIL_SCALE_TAB1 (ISP3X_SHARP_BASE + 0x000c4) +#define ISP33_SHARP_DETAIL_SCALE_TAB2 (ISP3X_SHARP_BASE + 0x000c8) +#define ISP33_SHARP_DETAIL_SCALE_TAB3 (ISP3X_SHARP_BASE + 0x000cc) +#define ISP33_SHARP_DETAIL_SCALE_TAB4 (ISP3X_SHARP_BASE + 0x000d0) +#define ISP33_SHARP_DETAIL_SCALE_TAB5 (ISP3X_SHARP_BASE + 0x000d4) +#define ISP33_SHARP_DETAIL_TEX_CLIP0 (ISP3X_SHARP_BASE + 0x000d8) +#define ISP33_SHARP_DETAIL_TEX_CLIP1 (ISP3X_SHARP_BASE + 0x000dc) +#define ISP33_SHARP_DETAIL_TEX_CLIP2 (ISP3X_SHARP_BASE + 0x000e0) +#define ISP33_SHARP_DETAIL_TEX_CLIP3 (ISP3X_SHARP_BASE + 0x000e4) +#define ISP33_SHARP_DETAIL_TEX_CLIP4 (ISP3X_SHARP_BASE + 0x000e8) +#define ISP33_SHARP_DETAIL_TEX_CLIP5 (ISP3X_SHARP_BASE + 0x000ec) +#define ISP33_SHARP_GRAIN_TEX_CLIP0 (ISP3X_SHARP_BASE + 0x000f0) +#define ISP33_SHARP_GRAIN_TEX_CLIP1 (ISP3X_SHARP_BASE + 0x000f4) +#define ISP33_SHARP_GRAIN_TEX_CLIP2 (ISP3X_SHARP_BASE + 0x000f8) +#define ISP33_SHARP_GRAIN_TEX_CLIP3 (ISP3X_SHARP_BASE + 0x000fc) +#define ISP33_SHARP_GRAIN_TEX_CLIP4 (ISP3X_SHARP_BASE + 0x00100) +#define ISP33_SHARP_GRAIN_TEX_CLIP5 (ISP3X_SHARP_BASE + 0x00104) +#define ISP33_SHARP_DETAIL_LUMA_CLIP0 (ISP3X_SHARP_BASE + 0x00108) +#define ISP33_SHARP_DETAIL_LUMA_CLIP1 (ISP3X_SHARP_BASE + 0x0010c) +#define ISP33_SHARP_DETAIL_LUMA_CLIP2 (ISP3X_SHARP_BASE + 0x00110) +#define ISP33_SHARP_DETAIL_LUMA_CLIP3 (ISP3X_SHARP_BASE + 0x00114) +#define ISP33_SHARP_DETAIL_LUMA_CLIP4 (ISP3X_SHARP_BASE + 0x00118) +#define ISP33_SHARP_DETAIL_LUMA_CLIP5 (ISP3X_SHARP_BASE + 0x0011c) +#define ISP33_SHARP_GRAIN_STRG (ISP3X_SHARP_BASE + 0x00120) +#define ISP33_SHARP_HUE_ADJ_TAB0 (ISP3X_SHARP_BASE + 0x00124) +#define ISP33_SHARP_DISATANCE_ADJ0 (ISP3X_SHARP_BASE + 0x00130) +#define ISP33_SHARP_DISATANCE_ADJ2 (ISP3X_SHARP_BASE + 0x00138) +#define ISP33_SHARP_NOISE_SIGMA0 (ISP3X_SHARP_BASE + 0x00148) +#define ISP33_SHARP_NOISE_SIGMA4 (ISP3X_SHARP_BASE + 0x00158) +#define ISP33_SHARP_LOSSTEXINHINR_STRG (ISP3X_SHARP_BASE + 0x0016c) +#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 ISP33_BAY3D_BASE 0x00002B00 +#define ISP33_BAY3D_CTRL0 (ISP33_BAY3D_BASE + 0x00000) +#define ISP33_BAY3D_CTRL1 (ISP33_BAY3D_BASE + 0x00004) +#define ISP33_BAY3D_CTRL2 (ISP33_BAY3D_BASE + 0x00008) +#define ISP33_BAY3D_CTRL3 (ISP33_BAY3D_BASE + 0x0000c) +#define ISP33_BAY3D_TRANS0 (ISP33_BAY3D_BASE + 0x00010) +#define ISP33_BAY3D_TRANS1 (ISP33_BAY3D_BASE + 0x00014) +#define ISP33_BAY3D_CURHI_SIGSCL (ISP33_BAY3D_BASE + 0x00058) +#define ISP33_BAY3D_CURHI_SIGOF (ISP33_BAY3D_BASE + 0x00068) +#define ISP33_BAY3D_CURHISPW0 (ISP33_BAY3D_BASE + 0x00070) +#define ISP33_BAY3D_CURHISPW1 (ISP33_BAY3D_BASE + 0x00074) +#define ISP33_BAY3D_IIRSX0 (ISP33_BAY3D_BASE + 0x00084) +#define ISP33_BAY3D_IIRSY0 (ISP33_BAY3D_BASE + 0x000a4) +#define ISP33_BAY3D_PREHI_SIGSCL (ISP33_BAY3D_BASE + 0x000c4) +#define ISP33_BAY3D_PREHI_WSCL (ISP33_BAY3D_BASE + 0x000c8) +#define ISP33_BAY3D_PREHIWMM (ISP33_BAY3D_BASE + 0x000cc) +#define ISP33_BAY3D_PREHISIGOF (ISP33_BAY3D_BASE + 0x000d4) +#define ISP33_BAY3D_PREHISIGSCL (ISP33_BAY3D_BASE + 0x000d8) +#define ISP33_BAY3D_PREHISPW0 (ISP33_BAY3D_BASE + 0x000dc) +#define ISP33_BAY3D_PREHISPW1 (ISP33_BAY3D_BASE + 0x000e0) +#define ISP33_BAY3D_PRELOSIGCSL (ISP33_BAY3D_BASE + 0x000e4) +#define ISP33_BAY3D_PRELOSIGOF (ISP33_BAY3D_BASE + 0x000e8) +#define ISP33_BAY3D_PREHI_NRCT (ISP33_BAY3D_BASE + 0x000f0) +#define ISP33_BAY3D_TNRSX0 (ISP33_BAY3D_BASE + 0x00100) +#define ISP33_BAY3D_TNRSY0 (ISP33_BAY3D_BASE + 0x00128) +#define ISP33_BAY3D_HIWD0 (ISP33_BAY3D_BASE + 0x00150) +#define ISP33_BAY3D_LOWD0 (ISP33_BAY3D_BASE + 0x0015c) +#define ISP33_BAY3D_GF3 (ISP33_BAY3D_BASE + 0x00168) +#define ISP33_BAY3D_GF4 (ISP33_BAY3D_BASE + 0x0016c) +#define ISP33_BAY3D_VIIR (ISP33_BAY3D_BASE + 0x00170) +#define ISP33_BAY3D_LFSCL (ISP33_BAY3D_BASE + 0x00174) +#define ISP33_BAY3D_LFSCLTH (ISP33_BAY3D_BASE + 0x00178) +#define ISP33_BAY3D_DSWGTSCL (ISP33_BAY3D_BASE + 0x0017c) +#define ISP33_BAY3D_WGTLASTSCL (ISP33_BAY3D_BASE + 0x00180) +#define ISP33_BAY3D_WGTSCL0 (ISP33_BAY3D_BASE + 0x00184) +#define ISP33_BAY3D_WGTSCL1 (ISP33_BAY3D_BASE + 0x00188) +#define ISP33_BAY3D_WGTSCL2 (ISP33_BAY3D_BASE + 0x0018c) +#define ISP33_BAY3D_WGTOFF (ISP33_BAY3D_BASE + 0x00190) +#define ISP33_BAY3D_WGT1OFF (ISP33_BAY3D_BASE + 0x00194) +#define ISP33_BAY3D_SIGORG (ISP33_BAY3D_BASE + 0x00198) +#define ISP33_BAY3D_WGTLO_L (ISP33_BAY3D_BASE + 0x0019c) +#define ISP33_BAY3D_WGTLO_H (ISP33_BAY3D_BASE + 0x001a0) +#define ISP33_BAY3D_STH_SCL (ISP33_BAY3D_BASE + 0x001a4) +#define ISP33_BAY3D_STH_LIMIT (ISP33_BAY3D_BASE + 0x001a8) +#define ISP33_BAY3D_HIKEEP (ISP33_BAY3D_BASE + 0x001ac) +#define ISP33_BAY3D_PIXMAX (ISP33_BAY3D_BASE + 0x001b0) +#define ISP33_BAY3D_SIGNUMTH (ISP33_BAY3D_BASE + 0x001b4) +#define ISP33_BAY3D_MONR (ISP33_BAY3D_BASE + 0x001b8) +#define ISP33_BAY3D_SIGSCL (ISP33_BAY3D_BASE + 0x001bc) +#define ISP33_BAY3D_DSOFF (ISP33_BAY3D_BASE + 0x001d0) +#define ISP33_BAY3D_DSSCL (ISP33_BAY3D_BASE + 0x001d4) +#define ISP33_BAY3D_ME0 (ISP33_BAY3D_BASE + 0x001d8) +#define ISP33_BAY3D_ME1 (ISP33_BAY3D_BASE + 0x001dc) +#define ISP33_BAY3D_ME2 (ISP33_BAY3D_BASE + 0x001e0) +#define ISP33_BAY3D_WGTMAX (ISP33_BAY3D_BASE + 0x001e4) +#define ISP33_BAY3D_WGT1MAX (ISP33_BAY3D_BASE + 0x001e8) +#define ISP33_BAY3D_WGTM0 (ISP33_BAY3D_BASE + 0x001ec) +#define ISP33_BAY3D_PRELOWGT (ISP33_BAY3D_BASE + 0x0020c) +#define ISP33_BAY3D_MIDBIG0 (ISP33_BAY3D_BASE + 0x00280) +#define ISP33_BAY3D_MIDBIG1 (ISP33_BAY3D_BASE + 0x00284) +#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 ISP3X_BAY3D_BASE 0x00002C00 #define ISP3X_BAY3D_CTRL (ISP3X_BAY3D_BASE + 0x00000) @@ -1322,6 +1544,25 @@ #define ISP3X_GIC_SIGMA_VALUE5 (ISP3X_GIC_BASE + 0x00034) #define ISP3X_GIC_SIGMA_VALUE6 (ISP3X_GIC_BASE + 0x00038) #define ISP3X_GIC_SIGMA_VALUE7 (ISP3X_GIC_BASE + 0x0003c) +#define ISP33_GIC_MEDFLT_PARA (ISP3X_GIC_BASE + 0x00004) +#define ISP33_GIC_MEDFLTUV_PARA (ISP3X_GIC_BASE + 0x00008) +#define ISP33_GIC_NOISE_SCALE (ISP3X_GIC_BASE + 0x0000c) +#define ISP33_GIC_BILAT_PARA1 (ISP3X_GIC_BASE + 0x00010) +#define ISP33_GIC_BILAT_PARA2 (ISP3X_GIC_BASE + 0x00014) +#define ISP33_GIC_DISWGT_COEFF (ISP3X_GIC_BASE + 0x00018) +#define ISP33_GIC_SIGMA_Y0 (ISP3X_GIC_BASE + 0x00020) +#define ISP33_GIC_SIGMA_Y8 (ISP3X_GIC_BASE + 0x00040) +#define ISP33_GIC_LUMA_DX (ISP3X_GIC_BASE + 0x00044) +#define ISP33_GIC_THRED_Y0 (ISP3X_GIC_BASE + 0x00050) +#define ISP33_GIC_MIN_THRED_Y0 (ISP3X_GIC_BASE + 0x00060) +#define ISP33_GIC_THRED_SCALE (ISP3X_GIC_BASE + 0x00070) +#define ISP33_GIC_LOFLTGR_COEFF (ISP3X_GIC_BASE + 0x00074) +#define ISP33_GIC_LOFLTGB_COEFF (ISP3X_GIC_BASE + 0x00078) +#define ISP33_GIC_SUM_LOFLT_INV (ISP3X_GIC_BASE + 0x0007c) +#define ISP33_GIC_LOFLTTHRED_COEFF (ISP3X_GIC_BASE + 0x00080) +#define ISP33_GIC_GAIN (ISP3X_GIC_BASE + 0x00090) +#define ISP33_GIC_GAIN_SLOPE (ISP3X_GIC_BASE + 0x00094) +#define ISP33_GIC_GAIN_THRED (ISP3X_GIC_BASE + 0x00098) #define ISP3X_BLS_BASE 0x00003000 #define ISP3X_BLS_CTRL (ISP3X_BLS_BASE + 0x00000) @@ -1756,6 +1997,24 @@ #define ISP32_BAYNR_GAINX1213 (ISP3X_BAYNR_BASE + 0x00090) #define ISP32_BAYNR_GAINX1415 (ISP3X_BAYNR_BASE + 0x00094) +#define ISP33_ENH_BASE 0x00003A00 +#define ISP33_ENH_CTRL (ISP33_ENH_BASE + 0x00000) +#define ISP33_ENH_IIR_FLT (ISP33_ENH_BASE + 0x00004) +#define ISP33_ENH_BILAT_FLT3X3 (ISP33_ENH_BASE + 0x00008) +#define ISP33_ENH_BILAT_FLT5X5 (ISP33_ENH_BASE + 0x0000c) +#define ISP33_ENH_GLOBAL_STRG (ISP33_ENH_BASE + 0x00010) +#define ISP33_ENH_LUMA_LUT0 (ISP33_ENH_BASE + 0x00014) +#define ISP33_ENH_LUMA_LUT8 (ISP33_ENH_BASE + 0x00034) +#define ISP33_ENH_DETAIL_IDX0 (ISP33_ENH_BASE + 0x00038) +#define ISP33_ENH_DETAIL_IDX2 (ISP33_ENH_BASE + 0x00040) +#define ISP33_ENH_DETAIL_POWER (ISP33_ENH_BASE + 0x00044) +#define ISP33_ENH_DETAIL_VALUE0 (ISP33_ENH_BASE + 0x00048) +#define ISP33_ENH_PRE_FRAME (ISP33_ENH_BASE + 0x0007c) +#define ISP33_ENH_IIR0 (ISP33_ENH_BASE + 0x00080) +#define ISP33_ENH_IIR9 (ISP33_ENH_BASE + 0x000a4) +#define ISP33_ENH_IIR_RW (ISP33_ENH_BASE + 0x000a8) +#define ISP33_ENH_ERR_FLAG (ISP33_ENH_BASE + 0x000fc) + #define ISP3X_LDCH_BASE 0x00003B00 #define ISP3X_LDCH_STS (ISP3X_LDCH_BASE + 0x00000) #define ISP32_LDCH_BIC_TABLE0 (ISP3X_LDCH_BASE + 0x00004) @@ -1934,10 +2193,34 @@ #define ISP39_DHAZ_ADP_RD1 (ISP3X_DHAZ_BASE + 0x00188) #define ISP39_DHAZ_LINE_CNT (ISP3X_DHAZ_BASE + 0x0018c) +#define ISP33_HIST_BASE 0x00003C00 +#define ISP33_HIST_CTRL (ISP33_HIST_BASE + 0x00000) +#define ISP33_HIST_HF_STAT (ISP33_HIST_BASE + 0x00004) +#define ISP33_HIST_BLOCK_SIZE (ISP33_HIST_BASE + 0x00008) +#define ISP33_HIST_THUMB_SIZE (ISP33_HIST_BASE + 0x0000c) +#define ISP33_HIST_MAP0 (ISP33_HIST_BASE + 0x00010) +#define ISP33_HIST_MAP1 (ISP33_HIST_BASE + 0x00014) +#define ISP33_HIST_IIR (ISP33_HIST_BASE + 0x00018) +#define ISP33_HIST_POS_ALPHA0 (ISP33_HIST_BASE + 0x0001c) +#define ISP33_HIST_POS_ALPHA4 (ISP33_HIST_BASE + 0x0002c) +#define ISP33_HIST_NEG_ALPHA0 (ISP33_HIST_BASE + 0x00030) +#define ISP33_HIST_NEG_ALPHA4 (ISP33_HIST_BASE + 0x00040) +#define ISP33_HIST_IIR0 (ISP33_HIST_BASE + 0x00080) +#define ISP33_HIST_RW (ISP33_HIST_BASE + 0x000a0) +#define ISP33_HIST_STAB (ISP33_HIST_BASE + 0x000a4) +#define ISP33_HIST_UV_SCL (ISP33_HIST_BASE + 0x000a8) +#define ISP33_HIST_ERR_FLAG (ISP33_HIST_BASE + 0x000fc) + #define ISP3X_3DLUT_BASE 0x00003E00 #define ISP3X_3DLUT_CTRL (ISP3X_3DLUT_BASE + 0x00000) #define ISP3X_3DLUT_UPDATE (ISP3X_3DLUT_BASE + 0x00004) +#define ISP33_HSV_BASE 0x00003E00 +#define ISP33_HSV_CTRL (ISP33_HSV_BASE + 0x00000) +#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 ISP3X_GAIN_BASE 0x00003F00 #define ISP3X_GAIN_CTRL (ISP3X_GAIN_BASE + 0x00000) #define ISP3X_GAIN_G0 (ISP3X_GAIN_BASE + 0x00004) @@ -2376,6 +2659,12 @@ #define ISP32L_RAWAWB_WIN_WEIGHT_2 (ISP3X_RAWAWB_BASE + 0x0668) #define ISP32L_RAWAWB_WIN_WEIGHT_3 (ISP3X_RAWAWB_BASE + 0x066c) #define ISP32L_RAWAWB_WIN_WEIGHT_4 (ISP3X_RAWAWB_BASE + 0x0670) +#define ISP33_RAWAWB_CCM_COEFF0_R (ISP3X_RAWAWB_BASE + 0x01c0) +#define ISP33_RAWAWB_CCM_COEFF1_R (ISP3X_RAWAWB_BASE + 0x01c4) +#define ISP33_RAWAWB_CCM_COEFF0_G (ISP3X_RAWAWB_BASE + 0x01c8) +#define ISP33_RAWAWB_CCM_COEFF1_G (ISP3X_RAWAWB_BASE + 0x01cc) +#define ISP33_RAWAWB_CCM_COEFF0_B (ISP3X_RAWAWB_BASE + 0x01d0) +#define ISP33_RAWAWB_CCM_COEFF1_B (ISP3X_RAWAWB_BASE + 0x01d4) /* VI_ISP_PATH */ #define ISP3X_RAWAE3_SEL(x) (((x) & 3) << 16) @@ -2396,7 +2685,9 @@ /* SWS_CFG */ #define ISP32L_ISP2ENC_CNT_MUX BIT(0) +#define ISP33_PP_ENC_PIPE_EN BIT(1) #define ISP3X_SW_ACK_FRM_PRO_DIS BIT(3) +#define ISP33_SW_ISP2ENC_PATH_EN BIT(5) #define ISP3X_3A_DDR_WRITE_EN BIT(24) #define ISP3X_SW_MIPI2ISP_FIFO_DIS BIT(25) #define ISP3X_SW_3D_DBR_START_MODE BIT(26) @@ -2413,7 +2704,7 @@ #define ISP3X_SW_CMSK_FORCE_UPD BIT(31) -#define ISP3X_SW_CMSK_ORDER_MODE BIT(1) +#define ISP3X_SW_CMSK_ORDER_MODE BIT(6) #define ISP3X_SW_CMSK_YUV(x, y, z) (((x) & 0xff) | ((y) & 0xff) << 8 | ((z) & 0xff) << 16) @@ -2433,6 +2724,10 @@ #define ISP3X_BIGMODE_FORCE_EN BIT(28) #define ISP3X_BIGMODE_MANUAL BIT(29) +#define ISP33_GIC_FST_FRAME BIT(22) +#define ISP33_ENH_FST_FRAME BIT(24) +#define ISP33_YHIST_FST_FRAME BIT(25) + /* ISP ACQ_H_OFFS */ #define ISP3X_SENSOR_MODE(x) (((x) & 3) << 30) #define ISP3X_SENSOR_INDEX(x) (((x) & 3) << 28) @@ -2492,6 +2787,8 @@ #define ISP3X_ISP_OUT_LINE(a) ((a) & 0x3fff) +#define ISP33_ISP2ENC_FRM_CNT(a) ((a) & 0xff) + #define ISP32_YNR_LUMA_RDBK_ST BIT(0) #define ISP32_YNR_LUMA_RDBK_OFFS(a) (((a) & 0x3fff) << 16) #define ISP32_YNR_LUMA_RDBK_RDY BIT(31) @@ -2599,8 +2896,17 @@ #define ISP3X_DBR_ST BIT(31) /* MI_RD_CTRL2 */ +#define ISP3X_RAWX_RD_BURST_MASK GENMASK(23, 22) +#define ISP3X_RAWX_WR_BURST_MASK GENMASK(21, 20) +#define ISP3X_RAWX_RD_GROP_MASK GENMASK(19, 18) +#define ISP3X_RAWX_WR_GROP_MASK GENMASK(17, 16) #define ISP39_AIISP_ST BIT(8) #define ISP39_AIISP_EN BIT(9) +#define ISP3X_RAWX_WR_GROP_MODE(x) (((x) & 0x3) << 16) +#define ISP3X_RAWX_RD_GROP_MODE(x) (((x) & 0x3) << 18) +#define ISP3X_RAWX_WR_BURST_LEN(x) (((x) & 0x3) << 20) +#define ISP3X_RAWX_RD_BURST_LEN(x) (((x) & 0x3) << 22) +#define ISP3X_MI_NEW_WR_BURST_DIS BIT(31) /* WR_OUTPUT_FORMAT */ #define ISP32_MI_OUTPUT_MASK GENMASK(10, 8) @@ -2763,6 +3069,12 @@ #define ISP39_DHAZ_IIR_WR_ID(x) (((x) & 0xff) << 16) #define ISP39_DHAZ_IIR_WR_CLEAR BIT(24) +#define ISP33_IIR_RD_ID(x) ((x) & 0x3f) +#define ISP33_IIR_RD_P BIT(8) +#define ISP33_IIR_RDATA_VAL BIT(9) +#define ISP33_IIR_WR_ID(x) (((x) & 0x3f) << 16) +#define ISP33_IIR_WR_CLEAR BIT(24) + /* HDRTMO */ /* HDRDRC */ diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 256643755b71..07e88580a073 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -189,6 +189,7 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, u32 src_w = dev->isp_sdev.in_frm.width; u32 src_h = dev->isp_sdev.in_frm.height; u32 dest_w, dest_h, w, h, max_size, max_h, max_w; + u32 w_align = 16, h_align = 8; int ret = 0; if (!crop) @@ -232,6 +233,12 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, max_h = dev->hw_dev->unite ? CIF_ISP_INPUT_H_MAX_V39_UNITE : CIF_ISP_INPUT_H_MAX_V39; break; + case ISP_V33: + max_w = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V33_UNITE : CIF_ISP_INPUT_W_MAX_V33; + max_h = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V33_UNITE : CIF_ISP_INPUT_H_MAX_V33; + break; default: max_w = CIF_ISP_INPUT_W_MAX; max_h = CIF_ISP_INPUT_H_MAX; @@ -241,6 +248,11 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, max_h = max_size / w; h = clamp_t(u32, src_h, CIF_ISP_INPUT_H_MIN, max_h); + if (dev->isp_ver >= ISP_V33) { + w_align = 4; + h_align = 4; + } + if (dev->active_sensor) sensor = dev->active_sensor->sd; if (sensor) { @@ -288,13 +300,13 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, crop->height = clamp_t(u32, crop->height, CIF_ISP_INPUT_H_MIN, h - crop->top); if ((code & RKISP_MEDIA_BUS_FMT_MASK) == RKISP_MEDIA_BUS_FMT_BAYER && - (ALIGN_DOWN(crop->width, 16) != crop->width || - ALIGN_DOWN(crop->height, 8) != crop->height)) + (ALIGN_DOWN(crop->width, w_align) != crop->width || + ALIGN_DOWN(crop->height, h_align) != crop->height)) v4l2_warn(&dev->v4l2_dev, - "Note: bayer raw need width 16 align, height 8 align!\n" + "Note: bayer raw need width %d align, height %d align!\n" "suggest (%d,%d)/%dx%d, specical requirements, Ignore!\n", - ALIGN_DOWN(crop->left, 4), crop->top, - ALIGN_DOWN(crop->width, 16), ALIGN_DOWN(crop->height, 8)); + w_align, h_align, ALIGN_DOWN(crop->left, 4), crop->top, + ALIGN_DOWN(crop->width, w_align), ALIGN_DOWN(crop->height, h_align)); return 0; } @@ -312,8 +324,8 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, * height 8 align * width and height no exceeding the max limit */ - dest_w = ALIGN_DOWN(w, 16); - dest_h = ALIGN_DOWN(h, 8); + dest_w = ALIGN_DOWN(w, w_align); + dest_h = ALIGN_DOWN(h, h_align); /* try to center of crop *4 align to no change bayer raw format @@ -538,7 +550,7 @@ static void rkisp_dvfs(struct rkisp_device *dev) if (hw->unite == ISP_UNITE_TWO) rkisp_set_clk_rate(hw->clks[5], hw->clk_rate_tbl[i].clk_rate * 1000000UL); /* aclk equal to core clk */ - if (dev->isp_ver == ISP_V32) + if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) rkisp_set_clk_rate(hw->clks[1], hw->clk_rate_tbl[i].clk_rate * 1000000UL); dev_info(hw->dev, "set isp clk = %luHz\n", clk_get_rate(hw->clks[0])); } @@ -583,6 +595,128 @@ static void rkisp_multi_overflow_hdl(struct rkisp_device *dev, bool on) rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true); } +static void rkisp_update_list_reg(struct rkisp_device *dev) +{ + struct rkisp_hw_dev *hw = dev->hw_dev; + u32 val = 0, index = 0; + + /* multi sensor need to reset isp resize mode if scale up */ + if (rkisp_read(dev, ISP3X_MAIN_RESIZE_CTRL, true) & 0xf0) + val |= BIT(3); + if (dev->isp_ver != ISP_V32_L && + rkisp_read(dev, ISP3X_SELF_RESIZE_CTRL, true) & 0xf0) + val |= BIT(4); + if (rkisp_read(dev, ISP32_BP_RESIZE_CTRL, true) & 0xf0) + val |= BIT(12); + if (val) { + writel(val, hw->base_addr + CIF_IRCL); + writel(0, hw->base_addr + CIF_IRCL); + } + + /* 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; + val |= ISP21_SENSOR_INDEX(index); + if (dev->isp_ver >= ISP_V32_L) + val |= ISP32L_SENSOR_MODE(dev->multi_mode); + else + val |= ISP21_SENSOR_MODE(dev->multi_mode); + writel(val, hw->base_addr + ISP_ACQ_H_OFFS); + if (hw->unite == ISP_UNITE_TWO) + writel(val, hw->base_next_addr + ISP_ACQ_H_OFFS); + } + rkisp_update_regs(dev, CTRL_VI_ISP_PATH, SUPER_IMP_COLOR_CR); + rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, ISP3X_DUAL_CROP_FBC_V_SIZE); + if (hw->isp_ver != ISP_V30) + rkisp_update_regs(dev, ISP_ACQ_PROP, ISP_ACQ_PROP); + rkisp_update_regs(dev, ISP_ACQ_V_OFFS, DUAL_CROP_CTRL); + rkisp_update_regs(dev, ISP39_LDCV_BIC_TABLE0, MI_WR_CTRL); + rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, ISP39_LDCV_CTRL); + rkisp_update_regs(dev, ISP32_BP_RESIZE_SCALE_HY, SELF_RESIZE_CTRL); + rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, ISP32_BP_RESIZE_CTRL); + rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, MAIN_RESIZE_CTRL); + rkisp_update_regs(dev, MI_RD_CTRL2, ISP_LSC_CTRL); + rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_WR_CTRL2 - 4); + 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); + if (dev->isp_ver == ISP_V21) { + val = rkisp_read(dev, MI_WR_CTRL2, false); + rkisp_set_bits(dev, MI_WR_CTRL2, 0, val, true); + rkisp_write(dev, MI_WR_INIT, ISP21_SP_FORCE_UPD | ISP21_MP_FORCE_UPD, true); + } 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) { + 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); + } + rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true); + } + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, + "sensor mode:%d index:%d | 0x%x\n", + dev->multi_mode, index, rkisp_read(dev, ISP_ACQ_H_OFFS, true)); +} + +void rkisp_online_update_reg(struct rkisp_device *dev, bool is_init, bool is_reset) +{ + u32 val; + + if (!is_init && dev->unite_index == ISP_UNITE_LEFT) + rkisp_stream_frame_start(dev, 0); + rkisp_update_list_reg(dev); + rkisp_params_cfgsram(&dev->params_vdev, true, is_reset); + val = rkisp_read(dev, ISP_CTRL, false); + val |= CIF_ISP_CTRL_ISP_CFG_UPD; + writel(val, dev->hw_dev->base_addr + ISP_CTRL); + if (!IS_HDR_RDBK(dev->rd_mode)) { + val = dev->rd_mode; + rkisp_write(dev, CSI2RX_CTRL0, SW_IBUF_OP_MODE(val), true); + } +} + +static void rkisp_check_mi_ends_mask(struct rkisp_device *dev) +{ + /* if output stream enable, wait it end */ + u32 val = rkisp_read(dev, CIF_MI_CTRL_SHD, true); + + if (val & CIF_MI_CTRL_SHD_MP_OUT_ENABLED) + dev->irq_ends_mask |= ISP_FRAME_MP; + else + dev->irq_ends_mask &= ~ISP_FRAME_MP; + if (val & CIF_MI_CTRL_SHD_SP_OUT_ENABLED) + dev->irq_ends_mask |= ISP_FRAME_SP; + else + dev->irq_ends_mask &= ~ISP_FRAME_SP; + if ((dev->isp_ver == ISP_V20 && + rkisp_read(dev, ISP_MPFBC_CTRL, true) & SW_MPFBC_EN) || + (dev->isp_ver == ISP_V30 && + rkisp_read(dev, ISP3X_MPFBC_CTRL, true) & ISP3X_MPFBC_EN_SHD)) + dev->irq_ends_mask |= ISP_FRAME_MPFBC; + else + dev->irq_ends_mask &= ~ISP_FRAME_MPFBC; + if ((dev->isp_ver == ISP_V30 && + rkisp_read(dev, ISP3X_MI_BP_WR_CTRL, true) & ISP3X_BP_ENABLE) || + ((dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V33) && + rkisp_read(dev, ISP32_MI_WR_CTRL2_SHD, true) & ISP32_BP_EN_OUT_SHD)) + dev->irq_ends_mask |= ISP_FRAME_BP; + else + dev->irq_ends_mask &= ~ISP_FRAME_BP; + if (dev->isp_ver == ISP_V39 && + rkisp_read(dev, ISP39_LDCV_CTRL, true) & ISP39_LDCV_EN_SHD) + dev->irq_ends_mask |= ISP_FRAME_LDC; + else + dev->irq_ends_mask &= ~ISP_FRAME_LDC; +} + /* * for hdr read back mode, rawrd read back data * this will update rawrd base addr to shadow. @@ -665,62 +799,11 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo rkisp_sditf_sof(dev, 0); if (!hw->is_single) { - /* multi sensor need to reset isp resize mode if scale up */ - val = 0; - if (rkisp_read(dev, ISP3X_MAIN_RESIZE_CTRL, true) & 0xf0) - val |= BIT(3); - if (dev->isp_ver != ISP_V32_L && - rkisp_read(dev, ISP3X_SELF_RESIZE_CTRL, true) & 0xf0) - val |= BIT(4); - if (rkisp_read(dev, ISP32_BP_RESIZE_CTRL, true) & 0xf0) - val |= BIT(12); - if (val) { - writel(val, hw->base_addr + CIF_IRCL); - writel(0, hw->base_addr + CIF_IRCL); - } - - /* sensor mode & index */ - if (dev->isp_ver >= ISP_V21) { - val = rkisp_read_reg_cache(dev, ISP_ACQ_H_OFFS); - val |= ISP21_SENSOR_INDEX(dev->multi_index); - if (dev->isp_ver >= ISP_V32_L) - val |= ISP32L_SENSOR_MODE(dev->multi_mode); - else - val |= ISP21_SENSOR_MODE(dev->multi_mode); - writel(val, hw->base_addr + ISP_ACQ_H_OFFS); - if (hw->unite == ISP_UNITE_TWO) - writel(val, hw->base_next_addr + ISP_ACQ_H_OFFS); - } - rkisp_update_regs(dev, CTRL_VI_ISP_PATH, SUPER_IMP_COLOR_CR); - rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, ISP3X_DUAL_CROP_FBC_V_SIZE); - rkisp_update_regs(dev, ISP_ACQ_V_OFFS, DUAL_CROP_CTRL); - rkisp_update_regs(dev, ISP39_LDCV_BIC_TABLE0, MI_WR_CTRL); - rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, ISP39_LDCV_CTRL); - rkisp_update_regs(dev, ISP32_BP_RESIZE_SCALE_HY, SELF_RESIZE_CTRL); - rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, ISP32_BP_RESIZE_CTRL); - rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, MAIN_RESIZE_CTRL); - rkisp_update_regs(dev, MI_RD_CTRL2, ISP_LSC_CTRL); - rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_WR_CTRL2 - 4); - rkisp_update_regs(dev, ISP39_W3A_CTRL1, ISP3X_RAWAWB_RAM_DATA_BASE); - rkisp_update_regs(dev, ISP_LSC_XGRAD_01, ISP39_W3A_CTRL0); + rkisp_update_list_reg(dev); if (dev->isp_ver == ISP_V20 && (rkisp_read(dev, ISP_DHAZ_CTRL, false) & ISP_DHAZ_ENMUX || - rkisp_read(dev, ISP_HDRTMO_CTRL, false) & ISP_HDRTMO_EN)) { + rkisp_read(dev, ISP_HDRTMO_CTRL, false) & ISP_HDRTMO_EN)) dma2frm += (dma2frm ? 0 : 1); - } else if (dev->isp_ver == ISP_V21) { - val = rkisp_read(dev, MI_WR_CTRL2, false); - rkisp_set_bits(dev, MI_WR_CTRL2, 0, val, true); - rkisp_write(dev, MI_WR_INIT, ISP21_SP_FORCE_UPD | ISP21_MP_FORCE_UPD, true); - } else { - if (dev->isp_ver == ISP_V32_L || dev->isp_ver == ISP_V39) - rkisp_write(dev, ISP32_SELF_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); - if (dev->isp_ver == ISP_V39) - rkisp_write(dev, ISP39_MAIN_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); - rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true); - } - v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, - "sensor mode:%d index:%d | 0x%x\n", - dev->multi_mode, dev->multi_index, rkisp_read(dev, ISP_ACQ_H_OFFS, true)); is_upd = true; } @@ -848,35 +931,7 @@ run_next: if (is_3dlut_upd) rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 1, true); - /* if output stream enable, wait it end */ - val = rkisp_read(dev, CIF_MI_CTRL_SHD, true); - if (val & CIF_MI_CTRL_SHD_MP_OUT_ENABLED) - dev->irq_ends_mask |= ISP_FRAME_MP; - else - dev->irq_ends_mask &= ~ISP_FRAME_MP; - if (val & CIF_MI_CTRL_SHD_SP_OUT_ENABLED) - dev->irq_ends_mask |= ISP_FRAME_SP; - else - dev->irq_ends_mask &= ~ISP_FRAME_SP; - if ((dev->isp_ver == ISP_V20 && - rkisp_read(dev, ISP_MPFBC_CTRL, true) & SW_MPFBC_EN) || - (dev->isp_ver == ISP_V30 && - rkisp_read(dev, ISP3X_MPFBC_CTRL, true) & ISP3X_MPFBC_EN_SHD)) - dev->irq_ends_mask |= ISP_FRAME_MPFBC; - else - dev->irq_ends_mask &= ~ISP_FRAME_MPFBC; - if ((dev->isp_ver == ISP_V30 && - rkisp_read(dev, ISP3X_MI_BP_WR_CTRL, true) & ISP3X_BP_ENABLE) || - (dev->isp_ver == ISP_V32 && - rkisp_read(dev, ISP32_MI_WR_CTRL2_SHD, true) & ISP32_BP_EN_OUT_SHD)) - dev->irq_ends_mask |= ISP_FRAME_BP; - else - dev->irq_ends_mask &= ~ISP_FRAME_BP; - if (dev->isp_ver == ISP_V39 && - rkisp_read(dev, ISP39_LDCV_CTRL, true) & ISP39_LDCV_EN_SHD) - dev->irq_ends_mask |= ISP_FRAME_LDC; - else - dev->irq_ends_mask &= ~ISP_FRAME_LDC; + rkisp_check_mi_ends_mask(dev); if (hw->is_frm_buf) { val = ISP32L_WR_FRM_BUF_EN | ISP32L_RD_FRM_BUF_EN | @@ -940,6 +995,13 @@ static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current) } } +void rkisp_vicap_hw_link(struct rkisp_device *dev, int on) +{ + struct v4l2_subdev *sd = dev->active_sensor->sd; + + v4l2_subdev_call(sd, core, ioctl, RKISP_VICAP_CMD_HW_LINK, &on); +} + static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) { struct rkisp_hw_dev *hw = dev->hw_dev; @@ -961,7 +1023,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) if (hw->unite == ISP_UNITE_ONE) { if (hw->is_multi_overflow && dev->sw_rd_cnt < 2) isp->unite_index = ISP_UNITE_RIGHT; - else if (hw->is_frm_buf) + else if (!hw->is_multi_overflow) isp->unite_index++; if (!hw->is_multi_overflow || (dev->sw_rd_cnt & 0x1)) is_try = false; @@ -970,6 +1032,21 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) } hw->is_idle = true; hw->pre_dev_id = dev->dev_id; + /* fast unite offline switch to online */ + if (dev->unite_div > ISP_UNITE_DIV1 && !IS_HDR_RDBK(dev->rd_mode)) + isp = dev; + else + isp = hw->isp[!dev->dev_id]; + if (isp && + isp->isp_state & ISP_START && + !IS_HDR_RDBK(isp->rd_mode)) { + hw->is_idle = false; + hw->cur_dev_id = isp->dev_id; + spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); + rkisp_online_update_reg(isp, false, false); + rkisp_vicap_hw_link(isp, true); + return; + } } if (hw->is_shutdown) hw->is_idle = false; @@ -977,8 +1054,6 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) goto end; if (hw->monitor.state & ISP_MIPI_ERROR && hw->monitor.is_en) goto end; - if (!IS_HDR_RDBK(dev->rd_mode)) - goto end; if (dev->is_suspend) { if (dev->suspend_sync) complete(&dev->pm_cmpl); @@ -1041,7 +1116,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) isp->sw_rd_cnt *= 2; isp->sw_rd_cnt += 1; } - } else if (hw->is_frm_buf) { + } else { isp->sw_rd_cnt += (isp->unite_div - 1); } /* first frame handle twice for thunderboot @@ -1112,12 +1187,74 @@ static void rkisp_rdbk_work(struct work_struct *work) rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL); } +static void rkisp_multi_online_switch(struct rkisp_device *dev) +{ + struct rkisp_hw_dev *hw = dev->hw_dev; + struct rkisp_device *isp = NULL; + int val = 0, id = dev->dev_id; + unsigned long lock_flags = 0; + bool is_switch = false; + bool to_online = false; + bool is_to_off = true; + + dev->irq_ends = 0; + if (dev->unite_div == ISP_UNITE_DIV2) { + if (dev->unite_index == ISP_UNITE_LEFT) { + rkisp_vicap_hw_link(dev, false); + dev->unite_index = ISP_UNITE_RIGHT; + rkisp_online_update_reg(dev, false, false); + val = dev->rd_mode == HDR_NORMAL ? HDR_RDBK_FRAME1 : HDR_RDBK_FRAME2; + rkisp_write(dev, CSI2RX_CTRL0, SW_IBUF_OP_MODE(val) | SW_CSI2RX_EN, true); + return; + } + is_to_off = false; + dev->unite_index = ISP_UNITE_LEFT; + dev->params_vdev.rdbk_times = 2; + } + + isp = hw->isp[!id]; + if (isp && isp->isp_state & ISP_START) { + if (!IS_HDR_RDBK(isp->rd_mode)) { + is_switch = true; + to_online = true; + } else { + val = 0; + rkisp_rdbk_trigger_event(isp, T_CMD_LEN, &val); + if (val || dev->is_multi_one_sync || dev->vicap_in.multi_sync) { + is_switch = true; + if (dev->is_multi_one_sync) + dev->is_multi_one_sync = false; + } + } + } + if (is_to_off) + rkisp_vicap_hw_link(dev, false); + if (!is_switch) { + rkisp_online_update_reg(dev, false, false); + rkisp_vicap_hw_link(dev, true); + } else { + if (to_online) { + spin_lock_irqsave(&hw->rdbk_lock, lock_flags); + hw->cur_dev_id = isp->dev_id; + spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); + rkisp_online_update_reg(isp, false, false); + rkisp_vicap_hw_link(isp, true); + } else { + spin_lock_irqsave(&hw->rdbk_lock, lock_flags); + hw->is_idle = true; + spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); + rkisp_rdbk_trigger_event(isp, T_CMD_QUEUE, NULL); + } + } +} + void rkisp_check_idle(struct rkisp_device *dev, u32 irq) { + struct rkisp_hw_dev *hw = dev->hw_dev; unsigned long lock_flags = 0; u32 val = 0; - if (!IS_HDR_RDBK(dev->rd_mode)) + if (hw->is_single && !IS_HDR_RDBK(dev->rd_mode)) return; spin_lock_irqsave(&dev->hw_dev->rdbk_lock, lock_flags); @@ -1137,6 +1274,10 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq) } spin_unlock_irqrestore(&dev->hw_dev->rdbk_lock, lock_flags); + /* two virtual isp online frame end switch to other isp */ + if (!hw->is_single && !IS_HDR_RDBK(dev->rd_mode)) + rkisp_multi_online_switch(dev); + if (dev->sw_rd_cnt) goto end; @@ -1167,6 +1308,9 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq) } } + if (!IS_HDR_RDBK(dev->rd_mode)) + return; + val = 0; switch (dev->rd_mode) { case HDR_RDBK_FRAME3://for rd1 rd0 rd2 @@ -1183,6 +1327,9 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq) end: dev->irq_ends = 0; + if (dev->is_wait_aiq && + (dev->unite_div < ISP_UNITE_DIV2 || dev->unite_index == ISP_UNITE_RIGHT)) + return; if (dev->hw_dev->is_dvfs) schedule_work(&dev->rdbk_work); else @@ -1232,7 +1379,8 @@ static void rkisp_config_ism(struct rkisp_device *dev) mult = 2; rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, height / mult, false); - if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) + if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32 || + dev->isp_ver == ISP_V33) return; /* IS(Image Stabilization) is always on, working as output crop */ @@ -1266,6 +1414,14 @@ static int rkisp_reset_handle(struct rkisp_device *dev) rkisp_trigger_read_back(dev, 1, 0, true); else rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, NULL); + } else if (!dev->hw_dev->is_single) { + if (dev->unite_div == ISP_UNITE_DIV2) { + dev->unite_index = ISP_UNITE_LEFT; + dev->params_vdev.rdbk_times = 2; + } + rkisp_online_update_reg(dev, false, true); + val = 1; + rkisp_vicap_hw_link(dev, val); } dev_info(dev->dev, "%s exit\n", __func__); return 0; @@ -1645,7 +1801,8 @@ static void rkisp_config_cmsk(struct rkisp_device *dev) unsigned long lock_flags = 0; struct rkisp_cmsk_cfg cfg; - if (dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) + if (dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32 && + dev->isp_ver != ISP_V33) return; spin_lock_irqsave(&dev->cmsk_lock, lock_flags); @@ -1817,6 +1974,7 @@ static int rkisp_config_isp(struct rkisp_device *dev) rkisp_config_color_space(dev); rkisp_params_first_cfg(&dev->params_vdev, in_fmt, dev->isp_sdev.quantization); + rkisp_stats_first_ddr_config(&dev->stats_vdev); } if (!dev->hw_dev->is_single && atomic_read(&dev->hw_dev->refcnt) <= 1) { rkisp_update_regs(dev, CIF_ISP_ACQ_H_OFFS, CIF_ISP_ACQ_V_SIZE); @@ -2147,15 +2305,18 @@ static int rkisp_isp_stop(struct rkisp_device *dev) hw->is_mi_update = false; hw->pre_dev_id = -1; end: + dev->is_frm_rd = false; dev->irq_ends_mask = 0; dev->hdr.op_mode = 0; dev->sw_rd_cnt = 0; dev->stats_vdev.rdbk_drop = false; + dev->is_multi_one_sync = false; rkisp_set_state(&dev->isp_state, ISP_STOP); if (dev->isp_ver >= ISP_V20) kfifo_reset(&dev->rdbk_kfifo); - if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) + if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32 || + dev->isp_ver == ISP_V33) memset(&dev->cmsk_cfg, 0, sizeof(dev->cmsk_cfg)); if (dev->emd_vc <= CIF_ISP_ADD_DATA_VC_MAX) { for (i = 0; i < RKISP_EMDDATA_FIFO_MAX; i++) @@ -2173,9 +2334,6 @@ end: static int rkisp_isp_start(struct rkisp_device *dev) { struct rkisp_hw_dev *hw = dev->hw_dev; - struct rkisp_sensor_info *sensor = dev->active_sensor; - void __iomem *base = dev->base_addr; - bool is_direct = true; u32 val; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, @@ -2203,32 +2361,15 @@ static int rkisp_isp_start(struct rkisp_device *dev) } } - /* Activate MIPI */ - if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { - if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { - /* clear interrupts state */ - readl(base + CIF_ISP_CSI0_ERR1); - readl(base + CIF_ISP_CSI0_ERR2); - readl(base + CIF_ISP_CSI0_ERR3); - /* csi2host enable */ - writel(1, base + CIF_ISP_CSI0_CTRL0); - } else if (dev->isp_ver < ISP_V12) { - val = readl(base + CIF_MIPI_CTRL); - writel(val | CIF_MIPI_CTRL_OUTPUT_ENA, - base + CIF_MIPI_CTRL); - } - } /* Activate ISP */ val = rkisp_read_reg_cache(dev, CIF_ISP_CTRL); val |= CIF_ISP_CTRL_ISP_CFG_UPD | CIF_ISP_CTRL_ISP_ENABLE | CIF_ISP_CTRL_ISP_INFORM_ENABLE | CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT; if (dev->isp_ver == ISP_V20) val |= NOC_HURRY_PRIORITY(2) | NOC_HURRY_W_MODE(2) | NOC_HURRY_R_MODE(1); - if (atomic_read(&hw->refcnt) > 1) - is_direct = false; - else + if (atomic_read(&hw->refcnt) == 1) hw->cur_dev_id = dev->dev_id; - rkisp_unite_write(dev, CIF_ISP_CTRL, val, is_direct); + rkisp_unite_write(dev, CIF_ISP_CTRL, val, false); rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); dev->isp_err_cnt = 0; @@ -2238,7 +2379,8 @@ static int rkisp_isp_start(struct rkisp_device *dev) v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s MI_CTRL 0x%08x ISP_CTRL 0x%08x\n", __func__, - readl(base + CIF_MI_CTRL), readl(base + CIF_ISP_CTRL)); + rkisp_read(dev, CIF_MI_CTRL, false), + rkisp_read(dev, CIF_ISP_CTRL, false)); if (hw->monitor.is_en && atomic_read(&hw->refcnt) < 2) { hw->monitor.retry = 0; @@ -2702,6 +2844,9 @@ static void rkisp_isp_sd_try_crop(struct v4l2_subdev *sd, case ISP_V32_L: size = CIF_ISP_INPUT_W_MAX_V32_L * CIF_ISP_INPUT_H_MAX_V32_L; break; + case ISP_V33: + size = CIF_ISP_INPUT_W_MAX_V33 * CIF_ISP_INPUT_H_MAX_V33; + break; case ISP_V39: size = CIF_ISP_INPUT_W_MAX_V39_UNITE * CIF_ISP_INPUT_H_MAX_V39_UNITE; size /= 2; @@ -2783,6 +2928,12 @@ static int rkisp_isp_sd_get_selection(struct v4l2_subdev *sd, max_h = dev->hw_dev->unite ? CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; break; + case ISP_V33: + max_w = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V33_UNITE : CIF_ISP_INPUT_W_MAX_V33; + max_h = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V33_UNITE : CIF_ISP_INPUT_H_MAX_V33; + break; case ISP_V39: max_w = dev->hw_dev->unite ? CIF_ISP_INPUT_W_MAX_V39_UNITE : CIF_ISP_INPUT_W_MAX_V39; @@ -2947,7 +3098,6 @@ static void rkisp_global_update_mi(struct rkisp_device *dev) struct rkisp_stream *stream; int i; - rkisp_stats_first_ddr_config(&dev->stats_vdev); if (dev->hw_dev->is_mi_update) return; @@ -3012,6 +3162,16 @@ static int rkisp_isp_sd_s_stream(struct v4l2_subdev *sd, int on) rkisp_config_cif(isp_dev); rkisp_isp_start(isp_dev); + if (!hw_dev->is_single && + !IS_HDR_RDBK(isp_dev->rd_mode) && + atomic_read(&hw_dev->refcnt) == 1) { + if (isp_dev->unite_div == ISP_UNITE_DIV2) { + isp_dev->unite_index = ISP_UNITE_LEFT; + isp_dev->params_vdev.rdbk_times = 2; + } + rkisp_online_update_reg(isp_dev, true, false); + hw_dev->is_idle = false; + } rkisp_global_update_mi(isp_dev); isp_dev->isp_state = ISP_START | ISP_FRAME_END; rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL); @@ -3052,8 +3212,9 @@ static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, u32 val = pool->buf.buff_addr[RKISP_PLANE_Y]; u32 reg = stream->config->mi.y_base_ad_init; - rkisp_write(dev, reg, val, false); - if (dev->hw_dev->unite == ISP_UNITE_TWO) { + rkisp_unite_write(dev, reg, val, false); + if (dev->hw_dev->unite == ISP_UNITE_TWO || + (dev->unite_div == ISP_UNITE_DIV2 && stream->id == RKISP_STREAM_RAWRD0)) { u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; if (stream->memory) @@ -3234,6 +3395,12 @@ end: stream->memory = SW_CSI_RAW_WR_SIMG_MODE; rkisp_dmarx_set_fmt(stream, stream->out_fmt); stream->ops->config_mi(stream); + if (dev->hdr_wrap_line && stream->id != RKISP_STREAM_RAWRD2) { + u32 size = dev->hdr_wrap_line * + stream->out_fmt.plane_fmt[0].bytesperline; + + rkisp_unite_write(dev, ISP32_MI_RAW0_RD_SIZE, size, false); + } dbufs->is_first = false; } v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, @@ -3429,6 +3596,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity, if (dev->isp_inp & rawrd) { dev->dmarx_dev.trigger = T_MANUAL; dev->is_rdbk_auto = false; + dev->is_m_online = false; } else { dev->dmarx_dev.trigger = T_AUTO; } @@ -3442,6 +3610,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity, /* read back mode only */ if (dev->isp_ver < ISP_V30 || !dev->hw_dev->is_single) mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ; + mode.dev_id = dev->dev_id; v4l2_subdev_call(remote, core, ioctl, RKISP_VICAP_CMD_MODE, &mode); dev->vicap_in = mode.input; @@ -3566,10 +3735,11 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, { struct rkisp_hw_dev *hw = isp_dev->hw_dev; int rd_mode = isp_dev->rd_mode; + u32 val, mask; isp_dev->is_suspend_one_frame = false; - if (vicap_mode->rdbk_mode == RKISP_VICAP_ONLINE) { - if (!hw->is_single) + if (vicap_mode->rdbk_mode < RKISP_VICAP_RDBK_AIQ) { + if (!hw->is_single && hw->isp_ver != ISP_V33) return -EINVAL; /* switch to online mode for single sensor */ switch (rd_mode) { @@ -3582,8 +3752,10 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, default: isp_dev->rd_mode = HDR_NORMAL; } - } else if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO || - vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) { + if (!hw->is_single && !IS_HDR_RDBK(rd_mode) && + vicap_mode->rdbk_mode == RKISP_VICAP_ONLINE_ONE_FRAME) + isp_dev->is_multi_one_sync = true; + } else { /* switch to readback mode */ switch (rd_mode) { case HDR_LINEX3_DDR: @@ -3595,21 +3767,27 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, default: isp_dev->rd_mode = HDR_RDBK_FRAME1; } - if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) + if (hw->isp_ver == ISP_V32 && + vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) isp_dev->is_suspend_one_frame = true; - } else { - return -EINVAL; } isp_dev->hdr.op_mode = isp_dev->rd_mode; if (rd_mode != isp_dev->rd_mode && hw->cur_dev_id == isp_dev->dev_id) { rkisp_unite_write(isp_dev, CSI2RX_CTRL0, SW_IBUF_OP_MODE(isp_dev->rd_mode), true); - if (IS_HDR_RDBK(isp_dev->rd_mode)) - rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, 0, - SW_MPIP_DROP_FRM_DIS, true); - else - rkisp_unite_clear_bits(isp_dev, CTRL_SWS_CFG, - SW_MPIP_DROP_FRM_DIS, true); + mask = SW_MPIP_DROP_FRM_DIS; + if (isp_dev->isp_ver == ISP_V33) + 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) + 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) { + val = ISP33_SW_ISP2ENC_PATH_EN; + } else { + val = 0; + } + rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, mask, val, true); } return 0; } @@ -3771,6 +3949,29 @@ static int rkisp_get_offline_raw_buf_cnt(struct rkisp_device *dev, int *cnt) return 0; } +static int rkisp_set_online_hdr_wrap(struct rkisp_device *dev, int *line) +{ + if (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD2)) { + v4l2_warn(&dev->v4l2_dev, + "hdr wrap no support for offline\n"); + return -EINVAL; + } + if (dev->isp_ver != ISP_V33 || dev->unite_div != ISP_UNITE_DIV1) { + v4l2_warn(&dev->v4l2_dev, + "hdr wrap support for 1103b and no unite mode\n"); + return -EINVAL; + } + dev->hdr_wrap_line = *line; + rkisp_hdr_wrap_line[dev->dev_id] = *line; + return 0; +} + +static int rkisp_get_online_hdr_wrap(struct rkisp_device *dev, int *line) +{ + *line = dev->hdr_wrap_line; + return 0; +} + static void rkisp_config_fpn(struct rkisp_device *dev) { struct rkisp_fpn_cfg *cfg = &dev->fpn_cfg; @@ -3854,6 +4055,7 @@ 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; @@ -3886,9 +4088,21 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) 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: + 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, + sizeof(struct rkisp_thunderboot_resmem_head)); + memcpy(&tb_head_v33->cfg, isp_dev->params_vdev.isp33_params, + sizeof(struct isp33_isp_params_cfg)); + break; case RKISP_CMD_SET_TB_HEAD_V32: - tb_head_v32 = arg; - memcpy(&isp_dev->tb_head, tb_head_v32, + case RKISP_CMD_SET_TB_HEAD_V33: + memcpy(&isp_dev->tb_head, arg, sizeof(struct rkisp_thunderboot_resmem_head)); break; case RKISP_CMD_GET_SHARED_BUF: @@ -4008,6 +4222,12 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKISP_CMD_GET_OFFLINE_RAW_BUFCNT: ret = rkisp_get_offline_raw_buf_cnt(isp_dev, arg); break; + case RKISP_CMD_SET_ONLINE_HDR_WRAP_LINE: + ret = rkisp_set_online_hdr_wrap(isp_dev, arg); + break; + case RKISP_CMD_GET_ONLINE_HDR_WRAP_LINE: + ret = rkisp_get_online_hdr_wrap(isp_dev, arg); + break; case RKISP_CMD_SET_FPN: ret = rkisp_set_fpn(isp_dev, arg); break; @@ -4101,10 +4321,12 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd, cp_t_us = true; break; case RKISP_CMD_SET_OFFLINE_RAW_BUFCNT: + case RKISP_CMD_SET_ONLINE_HDR_WRAP_LINE: size = sizeof(int); cp_f_us = true; break; case RKISP_CMD_GET_OFFLINE_RAW_BUFCNT: + case RKISP_CMD_GET_ONLINE_HDR_WRAP_LINE: size = sizeof(int); cp_t_us = true; break; @@ -4300,6 +4522,10 @@ void rkisp_save_tb_info(struct rkisp_device *isp_dev) size = sizeof(struct rkisp32_thunderboot_resmem_head); offset = size * isp_dev->dev_id; break; + case ISP_V33: + size = sizeof(struct rkisp33_thunderboot_resmem_head); + offset = size * isp_dev->dev_id; + break; default: break; } @@ -4312,6 +4538,16 @@ void rkisp_save_tb_info(struct rkisp_device *isp_dev) if (isp_dev->isp_ver == ISP_V32) { struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset; + param = &tmp->cfg; + head = &tmp->head; + v4l2_info(&isp_dev->v4l2_dev, + "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n", + tmp->cfg.module_en_update, + tmp->cfg.module_ens, + tmp->cfg.module_cfg_update); + } else if (isp_dev->isp_ver == ISP_V33) { + struct rkisp33_thunderboot_resmem_head *tmp = resmem_va + offset; + param = &tmp->cfg; head = &tmp->head; v4l2_info(&isp_dev->v4l2_dev, @@ -4320,8 +4556,11 @@ void rkisp_save_tb_info(struct rkisp_device *isp_dev) tmp->cfg.module_ens, tmp->cfg.module_cfg_update); } - if (param && (isp_dev->isp_state & ISP_STOP)) + if (param && (isp_dev->isp_state & ISP_STOP)) { + params_vdev->ops->get_param_size(params_vdev, + ¶ms_vdev->vdev_fmt.fmt.meta.buffersize); params_vdev->ops->save_first_param(params_vdev, param); + } } else if (size > isp_dev->resmem_size) { v4l2_err(&isp_dev->v4l2_dev, "resmem size:%zu no enough for head:%d\n", @@ -4343,7 +4582,8 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) if (!isp_dev->is_thunderboot) return; - if (isp_dev->isp_ver == ISP_V32 && params_vdev->is_first_cfg) + if (params_vdev->is_first_cfg && + (isp_dev->isp_ver == ISP_V32 || isp_dev->isp_ver == ISP_V33)) goto end; resmem_va = phys_to_virt(isp_dev->resmem_pa); @@ -4352,9 +4592,11 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) sizeof(struct rkisp_thunderboot_resmem_head), DMA_FROM_DEVICE); - shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 400 * USEC_PER_MSEC); - if (head->complete != RKISP_TB_OK) { - v4l2_err(&isp_dev->v4l2_dev, "wait thunderboot over timeout\n"); + shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 1000 * USEC_PER_MSEC); + if (head->complete == RKISP_TB_RUN) { + v4l2_err(&isp_dev->v4l2_dev, "wait thunderboot over timeout, tb still running\n"); + } else if (head->complete == RKISP_TB_NG) { + v4l2_err(&isp_dev->v4l2_dev, "thunderboot result error"); } else { int i, timeout = 50; @@ -4395,15 +4637,26 @@ end: } if (hw->is_thunderboot) { - rkisp_register_irq(hw); + if (head->complete != RKISP_TB_RUN) { + rkisp_register_irq(hw); + rkisp_tb_unprotect_clk(); + } rkisp_tb_set_state(tb_state); - rkisp_tb_unprotect_clk(); hw->is_thunderboot = false; } - isp_dev->is_thunderboot = false; + if (head->complete != RKISP_TB_RUN) + isp_dev->is_thunderboot = false; } #endif +static void rkisp_dvbm_start_event(struct rkisp_device *dev) +{ + struct rkisp_stream *stream = &dev->cap_dev.stream[0]; + + if (stream->streaming && !stream->ops->is_stream_stopped(stream)) + rkisp_dvbm_event(dev, CIF_ISP_V_START); +} + /**************** Interrupter Handler ****************/ void rkisp_mipi_isr(unsigned int mis, struct rkisp_device *dev) @@ -4562,6 +4815,7 @@ void rkisp_isp_isr(unsigned int isp_mis, complete(&dev->hw_dev->monitor.cmpl); } + rkisp_dvbm_start_event(dev); if (IS_HDR_RDBK(dev->hdr.op_mode)) { /* disabled frame end to read 3dlut for multi sensor * 3dlut will update at isp readback @@ -4573,6 +4827,10 @@ void rkisp_isp_isr(unsigned int isp_mis, } rkisp_stats_rdbk_enable(&dev->stats_vdev, true); goto vs_skip; + } else if (!hw->is_single) { + rkisp_check_mi_ends_mask(dev); + if (dev->unite_index == ISP_UNITE_RIGHT) + goto vs_skip; } if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { /* 0 = ODD 1 = EVEN */ @@ -4742,7 +5000,7 @@ vs_skip: } if (isp_mis & CIF_ISP_FRAME) { - if (dev->hw_dev->isp_ver == ISP_V32) { + if (dev->isp_ver == ISP_V32) { struct rkisp_stream *s = &dev->cap_dev.stream[RKISP_STREAM_LUMA]; s->ops->frame_end(s, FRAME_IRQ); diff --git a/drivers/media/platform/rockchip/isp/rkisp.h b/drivers/media/platform/rockchip/isp/rkisp.h index f024403f091b..39ac5d9988ba 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.h +++ b/drivers/media/platform/rockchip/isp/rkisp.h @@ -67,8 +67,12 @@ #define CIF_ISP_INPUT_H_MAX_V39 3504 #define CIF_ISP_INPUT_W_MAX_V39_UNITE 8192 #define CIF_ISP_INPUT_H_MAX_V39_UNITE 6144 +#define CIF_ISP_INPUT_W_MAX_V33 2880 +#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_MIN 272 -#define CIF_ISP_INPUT_H_MIN 272 +#define CIF_ISP_INPUT_H_MIN 264 #define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX #define CIF_ISP_OUTPUT_H_MAX CIF_ISP_INPUT_H_MAX #define CIF_ISP_OUTPUT_W_MIN CIF_ISP_INPUT_W_MIN diff --git a/include/soc/rockchip/rockchip_rockit.h b/include/soc/rockchip/rockchip_rockit.h index 760a864d24bc..f19436949644 100644 --- a/include/soc/rockchip/rockchip_rockit.h +++ b/include/soc/rockchip/rockchip_rockit.h @@ -55,6 +55,7 @@ struct ISP_VIDEO_FRAMES { u64 u64PrivateData; u32 u32FrameFlag; /* FRAME_FLAG_E, can be OR operation. */ + u8 ispEncCnt; }; struct rkisp_dev_cfg { @@ -75,6 +76,10 @@ struct rockit_cfg { int isp_num; u32 nick_id; u32 event; + u32 y_offset; + u32 u_offset; + u32 v_offset; + u32 vir_width; void *node; void *mpibuf; void *vvi_dev[ROCKIT_ISP_NUM_MAX]; @@ -120,7 +125,7 @@ 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) +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) || IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V33) 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 841790be482e..dfc86991a78a 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -80,6 +80,12 @@ #define RKISP_CMD_GET_OFFLINE_RAW_BUFCNT \ _IOR('V', BASE_VIDIOC_PRIVATE + 22, int) +#define RKISP_CMD_SET_ONLINE_HDR_WRAP_LINE \ + _IOW('V', BASE_VIDIOC_PRIVATE + 23, int) + +#define RKISP_CMD_GET_ONLINE_HDR_WRAP_LINE \ + _IOR('V', BASE_VIDIOC_PRIVATE + 24, int) + #define RKISP_CMD_SET_FPN \ _IOW('V', BASE_VIDIOC_PRIVATE + 25, struct rkisp_fpn_cfg) @@ -411,6 +417,12 @@ struct rkisp_bay3dbuf_info { int ds_fd; int ds_size; } v32; + struct { + int ds_fd; + int ds_size; + int gain_fd; + int gain_size; + } v33; struct { int gain_fd; int gain_size; @@ -430,7 +442,7 @@ struct rkisp_bay3dbuf_info { * RKISP_CMSK_WIN_MAX_V30 for rk3588 support 8 windows, and * support for mainpath and selfpath output stream channel. * - * RKISP_CMSK_WIN_MAX for rv1106 support 12 windows, and + * RKISP_CMSK_WIN_MAX for rv1106/rv1103b support 12 windows, and * support for mainpath selfpath and bypasspath output stream channel. * * mode: 0:mosaic mode, 1:cover mode @@ -2077,6 +2089,8 @@ enum { RKISP_RTT_MODE_ONE_FRAME, }; +#define MAX_PRE_BUF_NUM (4) + /** * struct rkisp_thunderboot_resmem_head */ @@ -2097,8 +2111,12 @@ struct rkisp_thunderboot_resmem_head { __u32 exp_time_reg[3]; __u32 exp_gain_reg[3]; __u32 exp_isp_dgain[3]; + __u32 dcg_mode[3]; __u32 nr_buf_size; __u32 share_mem_size; + __u32 pre_buf_num; + __u32 pre_buf_addr[MAX_PRE_BUF_NUM]; + __u32 pre_buf_timestamp[MAX_PRE_BUF_NUM]; } __attribute__ ((packed)); /** diff --git a/include/uapi/linux/rk-isp33-config.h b/include/uapi/linux/rk-isp33-config.h new file mode 100644 index 000000000000..1d0ca828d57f --- /dev/null +++ b/include/uapi/linux/rk-isp33-config.h @@ -0,0 +1,1476 @@ +/* SPDX-License-Identifier: (GPL-2.0+ WITH Linux-syscall-note) OR MIT + * + * Rockchip ISP33 + * Copyright (C) 2024 Rockchip Electronics Co., Ltd. + */ + +#ifndef _UAPI_RK_ISP33_CONFIG_H +#define _UAPI_RK_ISP33_CONFIG_H + +#include +#include +#include + +#define RKISP_CMD_GET_TB_HEAD_V33 \ + _IOR('V', BASE_VIDIOC_PRIVATE + 19, struct rkisp33_thunderboot_resmem_head) + +#define RKISP_CMD_SET_TB_HEAD_V33 \ + _IOW('V', BASE_VIDIOC_PRIVATE + 20, struct rkisp33_thunderboot_resmem_head) + +#define RKISP_CMD_GET_PARAMS_V33 \ + _IOR('V', BASE_VIDIOC_PRIVATE + 116, struct isp33_isp_params_cfg) + +#define ISP33_MODULE_DPCC ISP3X_MODULE_DPCC +#define ISP33_MODULE_BLS ISP3X_MODULE_BLS +#define ISP33_MODULE_LSC ISP3X_MODULE_LSC +#define ISP33_MODULE_AWB_GAIN ISP3X_MODULE_AWB_GAIN +#define ISP33_MODULE_CCM ISP3X_MODULE_CCM +#define ISP33_MODULE_GOC ISP3X_MODULE_GOC +#define ISP33_MODULE_CPROC ISP3X_MODULE_CPROC +#define ISP33_MODULE_IE ISP3X_MODULE_IE +#define ISP33_MODULE_RAWAE0 ISP3X_MODULE_RAWAE0 +#define ISP33_MODULE_RAWAE3 ISP3X_MODULE_RAWAE3 +#define ISP33_MODULE_RAWAWB ISP3X_MODULE_RAWAWB +#define ISP33_MODULE_RAWHIST0 ISP3X_MODULE_RAWHIST0 +#define ISP33_MODULE_RAWHIST3 ISP3X_MODULE_RAWHIST3 +#define ISP33_MODULE_HDRMGE ISP3X_MODULE_HDRMGE +#define ISP33_MODULE_GIC ISP3X_MODULE_GIC +#define ISP33_MODULE_LDCH ISP3X_MODULE_LDCH +#define ISP33_MODULE_GAIN ISP3X_MODULE_GAIN +#define ISP33_MODULE_DEBAYER ISP3X_MODULE_DEBAYER +#define ISP33_MODULE_BAY3D ISP3X_MODULE_BAY3D +#define ISP33_MODULE_YNR ISP3X_MODULE_YNR +#define ISP33_MODULE_CNR ISP3X_MODULE_CNR +#define ISP33_MODULE_SHARP ISP3X_MODULE_SHARP +#define ISP33_MODULE_DRC ISP3X_MODULE_DRC +#define ISP33_MODULE_CAC ISP3X_MODULE_CAC +#define ISP33_MODULE_CSM ISP3X_MODULE_CSM +#define ISP33_MODULE_CGC ISP3X_MODULE_CGC +#define ISP33_MODULE_HSV BIT_ULL(48) +#define ISP33_MODULE_ENH BIT_ULL(49) +#define ISP33_MODULE_HIST BIT_ULL(50) + +#define ISP33_MODULE_FORCE ISP3X_MODULE_FORCE + +/* Measurement types */ +#define ISP33_STAT_RAWAWB ISP3X_STAT_RAWAWB +#define ISP33_STAT_RAWAE0 ISP3X_STAT_RAWAE0 +#define ISP33_STAT_RAWAE3 ISP3X_STAT_RAWAE3 +#define ISP33_STAT_RAWHST0 ISP3X_STAT_RAWHST0 +#define ISP33_STAT_RAWHST3 ISP3X_STAT_RAWHST3 +#define ISP33_STAT_INFO2DDR ISP32_STAT_INFO2DDR +#define ISP33_STAT_BAY3D BIT(20) +#define ISP33_STAT_ENH BIT(21) +#define ISP33_STAT_HIST BIT(22) +#define ISP33_STAT_SHARP BIT(23) +#define ISP33_STAT_RTT_FST ISP32_STAT_RTT_FST + +#define ISP33_MESH_BUF_NUM ISP3X_MESH_BUF_NUM + +#define ISP33_LSC_GRAD_TBL_SIZE ISP3X_LSC_GRAD_TBL_SIZE +#define ISP33_LSC_SIZE_TBL_SIZE ISP3X_LSC_SIZE_TBL_SIZE +#define ISP33_LSC_DATA_TBL_SIZE ISP3X_LSC_DATA_TBL_SIZE + +#define ISP33_DEGAMMA_CURVE_SIZE ISP3X_DEGAMMA_CURVE_SIZE + +#define ISP33_GAIN_IDX_NUM ISP3X_GAIN_IDX_NUM +#define ISP33_GAIN_LUT_NUM ISP3X_GAIN_LUT_NUM + +#define ISP33_RAWAWB_WEIGHT_NUM ISP3X_RAWAWB_WEIGHT_NUM +#define ISP33_RAWAWB_HSTBIN_NUM ISP3X_RAWAWB_HSTBIN_NUM +#define ISP33_RAWAWB_SUM_NUM 4 +#define ISP33_RAWAWB_EXCL_STAT_NUM 4 + +#define ISP33_RAWAEBIG_SUBWIN_NUM 2 + +#define ISP33_RAWHISTBIG_SUBWIN_NUM ISP3X_RAWHISTBIG_SUBWIN_NUM +#define ISP33_RAWHISTLITE_SUBWIN_NUM ISP3X_RAWHISTLITE_SUBWIN_NUM +#define ISP33_HIST_BIN_N_MAX ISP3X_HIST_BIN_N_MAX + +#define ISP33_DPCC_PDAF_POINT_NUM ISP3X_DPCC_PDAF_POINT_NUM + +#define ISP33_HDRMGE_L_CURVE_NUM ISP3X_HDRMGE_L_CURVE_NUM +#define ISP33_HDRMGE_E_CURVE_NUM ISP3X_HDRMGE_E_CURVE_NUM + +#define ISP33_GIC_SIGMA_Y_NUM 17 +#define ISP33_GIC_LUMA_DX_NUM 7 +#define ISP33_GIC_THRED_Y_NUM 8 + +#define ISP33_CCM_CURVE_NUM 18 +#define ISP33_CCM_HF_FACTOR_NUM 17 + +#define ISP33_HSV_1DLUT_NUM 65 +#define ISP33_HSV_2DLUT_ROW 17 +#define ISP33_HSV_2DLUT_COL 17 + +#define ISP33_LDCH_BIC_NUM ISP32_LDCH_BIC_NUM + +#define ISP33_GAMMA_OUT_MAX_SAMPLES ISP3X_GAMMA_OUT_MAX_SAMPLES + +#define ISP33_ENH_LUMA_NUM 17 +#define ISP33_ENH_DETAIL_NUM 8 +#define ISP33_ENH_IIR_ROW_MAX 18 +#define ISP33_ENH_IIR_COL_MAX 24 + +#define ISP33_HIST_ALPHA_NUM 17 +#define ISP33_HIST_THUMB_ROW_MAX 8 +#define ISP33_HIST_THUMB_COL_MAX 10 +#define ISP33_HIST_IIR_NUM 16 +#define ISP33_HIST_IIR_BLK_MAX (ISP33_HIST_THUMB_ROW_MAX * ISP33_HIST_THUMB_COL_MAX) + +#define ISP33_DRC_Y_NUM ISP3X_DRC_Y_NUM + +#define ISP33_CNR_SIGMA_Y_NUM ISP3X_CNR_SIGMA_Y_NUM +#define ISP33_CNR_GAUS_COE_NUM 6 +#define ISP33_CNR_GAUS_SIGMAR_NUM 8 +#define ISP33_CNR_WGT_SIGMA_Y_NUM 13 + +#define ISP33_YNR_XY_NUM ISP3X_YNR_XY_NUM +#define ISP33_YNR_HI_GAUS_COE_NUM 5 +#define ISP33_YNR_HI_GAUS1_COE_NUM 6 +#define ISP33_YNR_ADJ_NUM 9 + +#define ISP33_BAY3D_XY_NUM 16 +#define ISP33_BAY3D_TNRSIG_NUM 20 +#define ISP33_BAY3D_LPF_COEFF_NUM 9 +#define ISP33_BAY3D_FILT_COEFF_NUM 6 + +#define ISP33_SHARP_X_NUM 7 +#define ISP33_SHARP_Y_NUM 8 +#define ISP33_SHARP_KERNEL_NUM 6 +#define ISP33_SHARP_EDGE_KERNEL_NUM 10 +#define ISP33_SHARP_EDGE_WGT_NUM 17 +#define ISP33_SHARP_LUMA_STRG_NUM 8 +#define ISP33_SHARP_LOCAL_STRG_NUM 4 +#define ISP33_SHARP_CONTRAST_STRG_NUM 9 +#define ISP33_SHARP_TEX_CLIP_NUM 9 +#define ISP33_SHARP_LUM_CLIP_NUM 8 +#define ISP33_SHARP_HUE_NUM 9 +#define ISP33_SHARP_DISATANCE_NUM 11 +#define ISP33_SHARP_HITEX_NUM 9 +#define ISP33_SHARP_NOISE_CURVE_NUM 17 + +#define ISP33_CAC_PSF_NUM 11 + +#define ISP33_CSM_COEFF_NUM ISP3X_CSM_COEFF_NUM + +#define ISP33_DEBAYER_LUMA_NUM 7 +#define ISP33_DEBAYER_DRCT_OFFSET_NUM 8 +#define ISP33_DEBAYER_VSIGMA_NUM 8 + +#define ISP33_MEAN_BLK_X_NUM 15 +#define ISP33_MEAN_BLK_Y_NUM 15 + +#define ISP33_BNR2AEBIG_SEL_EN 0x10 +#define ISP33_BNR2AE0_SEL_EN 0x20 + +struct isp33_hsv_cfg { + __u8 hsv_1dlut0_en; + __u8 hsv_1dlut1_en; + __u8 hsv_2dlut_en; + __u8 hsv_1dlut0_idx_mode; + __u8 hsv_1dlut1_idx_mode; + __u8 hsv_2dlut_idx_mode; + __u8 hsv_1dlut0_item_mode; + __u8 hsv_1dlut1_item_mode; + __u8 hsv_2dlut_item_mode; + + __u16 lut0_1d[ISP33_HSV_1DLUT_NUM]; + __u16 lut1_1d[ISP33_HSV_1DLUT_NUM]; + __u16 lut_2d[ISP33_HSV_2DLUT_ROW][ISP33_HSV_2DLUT_COL]; +} __attribute__ ((packed)); + +struct isp33_gic_cfg { + /* CTRL */ + __u8 bypass_en; + __u8 pro_mode; + __u8 manualnoisecurve_en; + __u8 manualnoisethred_en; + __u8 gain_bypass_en; + /* MEDFLT_PARA */ + __u8 medflt_minthred; + __u8 medflt_maxthred; + __u8 medflt_ratio; + /* MEDFLTUV_PARA */ + __u8 medfltuv_minthred; + __u8 medfltuv_maxthred; + __u8 medfltuv_ratio; + /* NOISE_SCALE */ + __u16 noisecurve_scale; + /* BILAT_PARA1 */ + __u16 bffltwgt_offset; + __u8 bffltwgt_scale; + /* BILAT_PARA2 */ + __u8 bfflt_ratio; + /* DISWGT_COEFF */ + __u8 bfflt_coeff0; + __u8 bfflt_coeff1; + __u8 bfflt_coeff2; + /* SIGMA_Y */ + __u16 bfflt_vsigma_y[ISP33_GIC_SIGMA_Y_NUM]; + /* LUMA_DX */ + __u8 luma_dx[ISP33_GIC_LUMA_DX_NUM]; + /* THRED_Y */ + __u16 thred_y[ISP33_GIC_THRED_Y_NUM]; + /* MIN_THRED_Y */ + __u16 minthred_y[ISP33_GIC_THRED_Y_NUM]; + /* THRED_SCALE */ + __u16 autonoisethred_scale; + /* LOFLTGR_COEFF */ + __u8 lofltgr_coeff0; + __u8 lofltgr_coeff1; + __u8 lofltgr_coeff2; + __u8 lofltgr_coeff3; + /* LOFLTGB_COEFF */ + __u8 lofltgb_coeff0; + __u8 lofltgb_coeff1; + /* SUM_LOFLT_INV */ + __u16 sumlofltcoeff_inv; + /* LOFLTTHRED_COEFF */ + __u8 lofltthred_coeff0; + __u8 lofltthred_coeff1; + /* GAIN */ + __u8 globalgain_alpha; + __u8 globalgain_scale; + __u16 global_gain; + /* GAIN_SLOPE */ + __u16 gain_offset; + __u16 gain_scale; + /* GAIN_THRED */ + __u16 gainadjflt_minthred; + __u16 gainadjflt_maxthred; +} __attribute__ ((packed)); + +struct isp33_cac_cfg { + /* CTRL */ + __u8 bypass_en; + __u8 edge_detect_en; + __u8 neg_clip0_en; + __u8 wgt_color_en; + /* PSF_PARA */ + __u8 psf_table_fix_bit; + /* HIGH_DIRECT */ + __u16 hi_drct_ratio; + /* OVER_EXPO0 */ + __u32 over_expo_thred; + /* OVER_EXP01 */ + __u32 over_expo_adj; + /* FLAT */ + __u8 flat_thred; + __u16 flat_offset; + /* GAUSS_COEFF */ + __u8 chroma_lo_flt_coeff0; + __u8 chroma_lo_flt_coeff1; + __u8 color_lo_flt_coeff0; + __u8 color_lo_flt_coeff1; + /* RATIO */ + __u16 search_range_ratio; + __u16 residual_chroma_ratio; + /* WGT_COLOR_B */ + __u32 wgt_color_b_min_thred; + /* WGT_COLOR_R */ + __u32 wgt_color_r_min_thred; + /* WGT_COLOR_SLOPE_B */ + __u32 wgt_color_b_slope; + /* WGT_COLOR_SLOPE_R */ + __u32 wgt_color_r_slope; + /* WGT_COLOR_LUMA0 */ + __u32 wgt_color_min_luma; + /* WGT_COLOR_LUMA1 */ + __u32 wgt_color_luma_slope; + /* WGT_OVER_EXPO0 */ + __u32 wgt_over_expo_min_thred; + /* WGT_OVER_EXPO1 */ + __u32 wgt_over_expo_slope; + /* WGT_CONTRAST0 */ + __u32 wgt_contrast_min_thred; + /* WGT_CONTRAST1 */ + __u32 wgt_contrast_slope; + /* WGT_CONTRAST2 */ + __u32 wgt_contrast_offset; + /* WGT_DARK_AREA0 */ + __u32 wgt_dark_thed; + /* WGT_DARK_AREA1 */ + __u32 wgt_dark_slope; + /* PSF_B */ + __u8 psf_b_ker[ISP33_CAC_PSF_NUM]; + /* PSF_R */ + __u8 psf_r_ker[ISP33_CAC_PSF_NUM]; +} __attribute__ ((packed)); + +struct isp33_ccm_cfg { + /* CTRL */ + __u8 highy_adjust_dis; + __u8 enh_adj_en; + __u8 asym_adj_en; + __u8 sat_decay_en; + /* COEFF0_R */ + __s16 coeff0_r; + __s16 coeff1_r; + /* COEFF1_R */ + __s16 coeff2_r; + __s16 offset_r; + /* COEFF0_G */ + __s16 coeff0_g; + __s16 coeff1_g; + /* COEFF1_G */ + __s16 coeff2_g; + __s16 offset_g; + /* COEFF0_B */ + __s16 coeff0_b; + __s16 coeff1_b; + /* COEFF1_B */ + __s16 coeff2_b; + __s16 offset_b; + /* COEFF0_Y */ + __u16 coeff0_y; + __u16 coeff1_y; + /* COEFF1_Y */ + __u16 coeff2_y; + /* ALP_Y */ + __u16 alp_y[ISP33_CCM_CURVE_NUM]; + /* BOUND_BIT */ + __u8 bound_bit; + __u8 right_bit; + /* ENHANCE0 */ + __u16 color_coef0_r2y; + __u16 color_coef1_g2y; + /* ENHANCE1 */ + __u16 color_coef2_b2y; + __u16 color_enh_rat_max; + /* HF_THD */ + __u8 hf_low; + __u8 hf_up; + __u16 hf_scale; + /* HF_FACTOR */ + __u16 hf_factor[ISP33_CCM_HF_FACTOR_NUM]; +} __attribute__ ((packed)); + +struct isp33_debayer_cfg { + /* CONTROL */ + __u8 bypass; + __u8 g_out_flt_en; + /* LUMA_DX */ + __u8 luma_dx[ISP33_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[ISP33_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[ISP33_DEBAYER_VSIGMA_NUM]; +} __attribute__ ((packed)); + +struct isp33_bay3d_cfg { + /* BAY3D_CTRL0 */ + __u8 bypass_en; + __u8 iirsparse_en; + __u8 out_use_pre_mode; + __u8 motion_est_en; + /* 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; + /* BAY3D_CTRL3 */ + __u8 transf_mode; + __u8 wgt_cal_mode; + __u8 ww_mode; + __u8 wgt_last_mode; + __u8 mge_wgt_hdr_sht_thred; + __u8 sigma_calc_mge_wgt_hdr_sht_thred; + /* BAY3D_TRANS0 */ + __u8 transf_mode_scale; + __u16 transf_mode_offset; + __u16 itransf_mode_offset; + /* BAY3D_TRANS1 */ + __u32 transf_data_max_limit; + /* BAY3D_CURHI_SIGSCL */ + __u16 pre_sig_ctrl_scl; + /* BAY3D_CURHI_SIGOF */ + __u8 pre_hi_guide_out_wgt; + /* BAY3D_CURHISPW */ + __u8 cur_spnr_filter_coeff[ISP33_BAY3D_FILT_COEFF_NUM]; + /* BAY3D_IIRSX */ + __u16 pre_spnr_luma2sigma_x[ISP33_BAY3D_XY_NUM]; + /* BAY3D_IIRSY */ + __u16 pre_spnr_luma2sigma_y[ISP33_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; + /* 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[ISP33_BAY3D_FILT_COEFF_NUM]; + /* BAY3D_PRELOSIGCSL */ + __u16 pre_spnr_lo_sigma_scale; + /* BAY3D_PRELOSIGOF */ + __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[ISP33_BAY3D_TNRSIG_NUM]; + /* BAY3D_TNRSY */ + __u16 tnr_luma2sigma_y[ISP33_BAY3D_TNRSIG_NUM]; + /* BAY3D_HIWD */ + __u16 lpf_hi_coeff[ISP33_BAY3D_LPF_COEFF_NUM]; + /* BAY3D_LOWD */ + __u16 lpf_lo_coeff[ISP33_BAY3D_LPF_COEFF_NUM]; + /* BAY3D_GF */ + __u8 sigma_idx_filt_coeff[ISP33_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 */ + __u32 out_use_hi_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_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; +} __attribute__ ((packed)); + +struct isp33_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; + /* GAIN_CTRL */ + __u16 global_set_gain; + __u8 gain_merge_alpha; + __u8 local_gain_scale; + /* GAIN_ADJ */ + __u16 lo_spnr_gain2strg[ISP33_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[ISP33_YNR_XY_NUM]; + /* SGM_DX */ + __u16 luma2sima_x[ISP33_YNR_XY_NUM]; + /* SGM_Y */ + __u16 luma2sima_y[ISP33_YNR_XY_NUM]; + /* HI_SIGMA_GAIN */ + __u16 hi_spnr_sigma_min_limit; + __u16 hi_spnr_strg; + __u8 hi_spnr_local_gain_alpha; + /* HI_GAUS_COE */ + __u8 hi_spnr_filt_coeff[ISP33_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[ISP33_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 */ + __u16 mi_spnr_filt_coeff0; + __u16 mi_spnr_filt_coeff1; + __u16 mi_spnr_filt_coeff2; + /* 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; + /* 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; + /* LO_TEXT_THRED */ + __u16 tex2lo_strg_upper_thred; + __u16 tex2lo_strg_lower_thred; + /* FUSION_WEIT_ADJ */ + __u8 lo_gain2wgt[ISP33_YNR_ADJ_NUM]; +} __attribute__ ((packed)); + +struct isp33_cnr_cfg { + /* CNR_CTRL */ + __u8 exgain_bypass; + __u8 yuv422_mode; + __u8 thumb_mode; + __u8 hiflt_wgt0_mode; + __u8 local_alpha_dis; + __u8 loflt_coeff; + /* 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[ISP33_CNR_GAUS_COE_NUM]; + /* CNR_GAUS_RATIO */ + __u8 hiflt_wgt_min_limit; + __u16 gaus_flt_alpha; + __u16 hiflt_alpha; + /* CNR_BF_PARA1 */ + __u8 hiflt_uv_gain; + __u8 hiflt_cur_wgt; + __u16 hiflt_global_vsigma; + /* CNR_BF_PARA2 */ + __u16 adj_offset; + __u16 adj_scale; + /* CNR_SIGMA */ + __u8 sgm_ratio[ISP33_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[ISP33_CNR_WGT_SIGMA_Y_NUM]; + /* GAUS_X_SIGMAR */ + __u16 hiflt_vsigma_idx[ISP33_CNR_GAUS_SIGMAR_NUM]; + /* GAUS_Y_SIGMAR */ + __u16 hiflt_vsigma[ISP33_CNR_GAUS_SIGMAR_NUM]; +} __attribute__ ((packed)); + +struct isp33_sharp_cfg { + /* SHARP_EN */ + __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[ISP33_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; + /* DETAIL1 */ + __u32 detail_fusion_slope_fix; + /* LUMA_DX */ + __u8 luma_dx[ISP33_SHARP_X_NUM]; + /* PBF_VSIGMA */ + __u16 pre_bifilt_vsigma_inv[ISP33_SHARP_Y_NUM]; + /* PBF_KERNEL */ + __u8 pre_bifilt_coeff0; + __u8 pre_bifilt_coeff1; + __u8 pre_bifilt_coeff2; + /* DETAIL_KERNEL */ + __u8 hi_detail_lpf_coeff[ISP33_SHARP_KERNEL_NUM]; + __u8 mi_detail_lpf_coeff[ISP33_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_lpf_coeff[ISP33_SHARP_EDGE_KERNEL_NUM]; + /* EDGE_WGT_VAL */ + __u16 edge_wgt_val[ISP33_SHARP_EDGE_WGT_NUM]; + /* LUMA_ADJ_STRG */ + __u8 luma2strg[ISP33_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 tex2detail_strg[ISP33_SHARP_LOCAL_STRG_NUM]; + __u16 tex2loss_tex_in_hinr_strg[ISP33_SHARP_LOCAL_STRG_NUM]; + /* DETAIL_SCALE_TAB */ + __u8 contrast2pos_strg[ISP33_SHARP_CONTRAST_STRG_NUM]; + __u8 contrast2neg_strg[ISP33_SHARP_CONTRAST_STRG_NUM]; + __u8 pos_detail_strg; + __u8 neg_detail_strg; + /* DETAIL_TEX_CLIP */ + __u16 tex2detail_pos_clip[ISP33_SHARP_TEX_CLIP_NUM]; + __u16 tex2detail_neg_clip[ISP33_SHARP_TEX_CLIP_NUM]; + /* GRAIN_TEX_CLIP */ + __u16 tex2grain_pos_clip[ISP33_SHARP_TEX_CLIP_NUM]; + __u16 tex2grain_neg_clip[ISP33_SHARP_TEX_CLIP_NUM]; + /* DETAIL_LUMA_CLIP */ + __u16 luma2detail_pos_clip[ISP33_SHARP_LUM_CLIP_NUM]; + __u16 luma2detail_neg_clip[ISP33_SHARP_LUM_CLIP_NUM]; + /* GRAIN_STRG */ + __u8 grain_strg; + /* HUE_ADJ_TAB */ + __u16 hue2strg[ISP33_SHARP_HUE_NUM]; + /* DISATANCE_ADJ */ + __u8 distance2strg[ISP33_SHARP_DISATANCE_NUM]; + /* NOISE_SIGMA */ + __u16 hi_tex_threshold[ISP33_SHARP_HITEX_NUM]; + /* LOSSTEXINHINR_STRG */ + __u8 loss_tex_in_hinr_strg; + /* NOISE_CURVE */ + __u16 noise_curve_ext[ISP33_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; +} __attribute__ ((packed)); + +struct isp33_enh_cfg { + /* CTRL */ + __u8 bypass; + __u8 blf3_bypass; + /* IIR_FLT */ + __u16 iir_inv_sigma; + __u8 iir_soft_thed; + __u8 iir_cur_wgt; + /* BILAT_FLT3X3 */ + __u16 blf3_inv_sigma; + __u16 blf3_cur_wgt; + __u8 blf3_thumb_cur_wgt; + /* BILAT_FLT5X5 */ + __u8 blf5_cur_wgt; + __u16 blf5_inv_sigma; + /* GLOBAL_STRG */ + __u16 global_strg; + /* LUMA_LUT */ + __u16 lum2strg[ISP33_ENH_LUMA_NUM]; + /* DETAIL_IDX */ + __u16 detail2strg_idx[ISP33_ENH_DETAIL_NUM]; + /* DETAIL_POWER */ + __u8 detail2strg_power0; + __u8 detail2strg_power1; + __u8 detail2strg_power2; + __u8 detail2strg_power3; + __u8 detail2strg_power4; + __u8 detail2strg_power5; + __u8 detail2strg_power6; + /* DETAIL_VALUE */ + __u16 detail2strg_val[ISP33_ENH_DETAIL_NUM]; + /* PRE_FRAME */ + __u8 pre_wet_frame_cnt0; + __u8 pre_wet_frame_cnt1; + /* IIR */ + __u8 iir_wr; + __u8 iir[ISP33_ENH_IIR_ROW_MAX][ISP33_ENH_IIR_COL_MAX]; +} __attribute__ ((packed)); + +struct isp33_hist_cfg { + /* CTRL */ + __u8 bypass; + __u8 mem_mode; + /* HF_STAT */ + __u8 count_scale; + __u8 count_offset; + __u16 count_min_limit; + /* BLOCK_SIZE */ + __u16 blk_het; + __u16 blk_wid; + /* THUMB_SIZE */ + __u8 thumb_row; + __u8 thumb_col; + /* MAP0 */ + __u16 merge_alpha; + __u16 user_set; + /* MAP1 */ + __u16 map_count_scale; + __u8 gain_ref_wgt; + /* IIR */ + __u8 flt_cur_wgt; + __u16 flt_inv_sigma; + /* POS_ALPHA */ + __u8 pos_alpha[ISP33_HIST_ALPHA_NUM]; + /* NEG_ALPHA */ + __u8 neg_alpha[ISP33_HIST_ALPHA_NUM]; + /* STAB */ + __u8 stab_frame_cnt0; + __u8 stab_frame_cnt1; + /* UV_SCL */ + __u8 saturate_scale; + /* HIST_IIR */ + __u16 iir_wr; + __u16 iir[ISP33_HIST_IIR_BLK_MAX][ISP33_HIST_IIR_NUM]; +} __attribute__ ((packed)); + +struct isp33_drc_cfg { + /* CTRL0 */ + __u8 bypass_en; + __u8 cmps_byp_en; + __u8 gainx32_en; + __u8 bf_lp_en; + __u8 raw_dly_dis; + /* CTRL1 */ + __u16 position; + __u16 compres_scl; + __u8 offset_pow2; + /* LPRATIO */ + __u16 lpdetail_ratio; + __u16 hpdetail_ratio; + __u8 delta_scalein; + /* BILAT0 */ + __u8 bilat_wt_off; + __u16 thumb_thd_neg; + __u8 thumb_thd_enable; + __u8 weicur_pix; + /* BILAT1 */ + __u8 cmps_offset_bits_int; + __u8 cmps_fixbit_mode; + __u16 drc_gas_t; + /* BILAT2 */ + __u16 thumb_clip; + __u8 thumb_scale; + /* BILAT3 */ + __u16 range_sgm_inv0; + __u16 range_sgm_inv1; + /* BILAT4 */ + __u8 weig_bilat; + __u8 weight_8x8thumb; + __u8 enable_soft_thd; + __u16 bilat_soft_thd; + /* GAIN_Y */ + __u16 gain_y[ISP33_DRC_Y_NUM]; + /* COMPRES_Y */ + __u16 compres_y[ISP33_DRC_Y_NUM]; + /* SCALE_Y */ + __u16 scale_y[ISP33_DRC_Y_NUM]; + /* IIRWG_GAIN */ + __u16 min_ogain; + /* SFTHD_Y */ + __u16 sfthd_y[ISP33_DRC_Y_NUM]; +} __attribute__ ((packed)); + +struct isp33_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; + __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; + /* 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[ISP33_RAWAWB_WEIGHT_NUM]; + + struct isp2x_bls_fixed_val bls2_val; +} __attribute__ ((packed)); + +struct isp33_isp_other_cfg { + struct isp32_bls_cfg bls_cfg; + struct isp39_dpcc_cfg dpcc_cfg; + struct isp3x_lsc_cfg lsc_cfg; + struct isp32_awb_gain_cfg awb_gain_cfg; + struct isp33_gic_cfg gic_cfg; + struct isp33_debayer_cfg debayer_cfg; + struct isp33_ccm_cfg ccm_cfg; + struct isp3x_gammaout_cfg gammaout_cfg; + struct isp2x_cproc_cfg cproc_cfg; + struct isp33_drc_cfg drc_cfg; + struct isp32_hdrmge_cfg hdrmge_cfg; + struct isp33_enh_cfg enh_cfg; + struct isp33_hist_cfg hist_cfg; + struct isp33_hsv_cfg hsv_cfg; + struct isp32_ldch_cfg ldch_cfg; + struct isp33_bay3d_cfg bay3d_cfg; + struct isp33_ynr_cfg ynr_cfg; + struct isp33_cnr_cfg cnr_cfg; + struct isp33_sharp_cfg sharp_cfg; + struct isp33_cac_cfg cac_cfg; + struct isp3x_gain_cfg gain_cfg; + struct isp21_csm_cfg csm_cfg; + struct isp21_cgc_cfg cgc_cfg; +} __attribute__ ((packed)); + +struct isp33_isp_meas_cfg { + struct isp33_rawawb_meas_cfg rawawb; + struct isp2x_rawaebig_meas_cfg rawae0; + struct isp2x_rawaebig_meas_cfg rawae3; + struct isp2x_rawhistbig_cfg rawhist0; + struct isp2x_rawhistbig_cfg rawhist3; +} __attribute__ ((packed)); + +struct isp33_isp_params_cfg { + __u64 module_en_update; + __u64 module_ens; + __u64 module_cfg_update; + + __u32 frame_id; + struct isp33_isp_meas_cfg meas; + struct isp33_isp_other_cfg others; +} __attribute__ ((packed)); + +struct rkisp33_thunderboot_resmem_head { + struct rkisp_thunderboot_resmem_head head; + struct isp33_isp_params_cfg cfg; +} __attribute__ ((packed)); + +struct isp33_sharp_stat { + __u16 noise_curve[ISP33_SHARP_NOISE_CURVE_NUM]; +} __attribute__ ((packed)); + +struct isp33_bay3d_stat { + __u32 sigma_num; + __u16 sigma_y[ISP33_BAY3D_TNRSIG_NUM]; +} __attribute__ ((packed)); + +struct isp33_enh_stat { + __u8 iir[ISP33_ENH_IIR_ROW_MAX][ISP33_ENH_IIR_COL_MAX]; +} __attribute__ ((packed)); + +struct isp33_hist_stat { + __u16 iir[ISP33_HIST_IIR_BLK_MAX][ISP33_HIST_IIR_NUM]; +} __attribute__ ((packed)); + +struct isp33_rawae_mean_lum { + __u32 g:12; + __u32 b:10; + __u32 r:10; +} __attribute__ ((packed)); + +struct isp33_rawae_mean_line { + /* line: 15 word + one unuse */ + struct isp33_rawae_mean_lum blk_x[ISP33_MEAN_BLK_X_NUM]; + __u32 reserved; +} __attribute__ ((packed)); + +struct isp33_rawae_stat { + struct isp33_rawae_mean_line blk_y[ISP33_MEAN_BLK_Y_NUM]; + __u32 wnd1_sumg; + __u32 wnd1_sumb; + __u32 wnd1_sumr; + __u32 reserved0; + __u32 wnd2_sumg; + __u32 wnd2_sumb; + __u32 wnd2_sumr; + __u32 reserved1; +} __attribute__ ((packed)); + +struct isp33_rawhist_stat { + __u32 bin[ISP33_HIST_BIN_N_MAX]; +} __attribute__ ((packed)); + +struct isp33_rawawb_mean_ramdata { + __u64 b:18; + __u64 g:18; + __u64 r:18; + __u64 wp:10; +} __attribute__ ((packed)); + +struct isp33_rawawb_mean_ramdata_line { + struct isp33_rawawb_mean_ramdata ramdata_blk_x[ISP33_MEAN_BLK_X_NUM]; + __u32 reserved[2]; +} __attribute__ ((packed)); + +struct isp33_rawawb_mean_sum { + __u32 rgain_nor; + __u32 bgain_nor; + __u32 wp_num_nor; + __u32 wp_num2; + + __u32 rgain_big; + __u32 bgain_big; + __u32 wp_num_big; + __u32 reserved; +} __attribute__ ((packed)); + +struct isp33_rawawb_mean_sum_exc { + __u32 rgain_exc; + __u32 bgain_exc; + __u32 wp_num_exc; + __u32 reserved; +} __attribute__ ((packed)); + +struct isp33_rawawb_stat { + struct isp33_rawawb_mean_ramdata_line ramdata_blk_y[ISP33_MEAN_BLK_Y_NUM]; + struct isp33_rawawb_mean_sum sum[ISP33_RAWAWB_SUM_NUM]; + __u16 yhist[ISP33_RAWAWB_HSTBIN_NUM]; + struct isp33_rawawb_mean_sum_exc sum_exc[ISP33_RAWAWB_EXCL_STAT_NUM]; +} __attribute__ ((packed)); + +struct isp33_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 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 isp32_info2ddr_stat info2ddr; +} __attribute__ ((packed)); + +struct rkisp33_stat_buffer { + struct isp33_stat stat; + __u32 meas_type; + __u32 frame_id; + __u32 params_id; +} __attribute__ ((packed)); +#endif /* _UAPI_RK_ISP33_CONFIG_H */