From e4423ba4ce7634e3714c2a5e67312d99a0dab2a6 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Thu, 23 Feb 2023 11:54:06 +0800 Subject: [PATCH] media: rockchip: isp: support buf early done Change-Id: Icfa088b48105089c4a77aeeebd6b8358d1e90bef Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/capture.c | 22 +++- drivers/media/platform/rockchip/isp/capture.h | 5 +- .../media/platform/rockchip/isp/capture_v1x.c | 10 +- .../media/platform/rockchip/isp/capture_v20.c | 20 ++-- .../media/platform/rockchip/isp/capture_v21.c | 16 +-- .../media/platform/rockchip/isp/capture_v30.c | 54 ++++++---- .../media/platform/rockchip/isp/capture_v32.c | 101 ++++++++++-------- drivers/media/platform/rockchip/isp/dev.h | 1 + .../platform/rockchip/isp/isp_params_v3x.c | 8 -- .../platform/rockchip/isp/isp_stats_v3x.c | 7 +- drivers/media/platform/rockchip/isp/rkisp.c | 45 +++++++- 11 files changed, 185 insertions(+), 104 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index 115fb85eb5e6..cbb45aa8da42 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -166,7 +166,7 @@ int hdr_update_dmatx_buf(struct rkisp_device *dev) for (i = RKISP_STREAM_DMATX0; i <= RKISP_STREAM_DMATX2; i++) { dmatx = &dev->cap_dev.stream[i]; if (dmatx->ops && dmatx->ops->frame_end) - dmatx->ops->frame_end(dmatx); + dmatx->ops->frame_end(dmatx, FRAME_INIT); } if (dev->dmarx_dev.trigger) @@ -455,6 +455,26 @@ int rkisp_stream_frame_start(struct rkisp_device *dev, u32 isp_mis) return 0; } +void rkisp_stream_buf_done_early(struct rkisp_device *dev) +{ + struct rkisp_stream *stream; + int i; + + if (!dev->cap_dev.is_done_early) + return; + + for (i = 0; i < RKISP_MAX_STREAM; i++) { + if (i == RKISP_STREAM_VIR || i == RKISP_STREAM_LUMA || + i == RKISP_STREAM_DMATX0 || i == RKISP_STREAM_DMATX1 || + i == RKISP_STREAM_DMATX2 || i == RKISP_STREAM_DMATX3) + continue; + stream = &dev->cap_dev.stream[i]; + if (stream->streaming && !stream->stopping && + stream->ops && stream->ops->frame_end) + stream->ops->frame_end(stream, FRAME_WORK); + } +} + struct stream_config rkisp_mp_stream_config = { /* constraints */ .max_rsz_width = STREAM_MAX_MP_RSZ_OUTPUT_WIDTH, diff --git a/drivers/media/platform/rockchip/isp/capture.h b/drivers/media/platform/rockchip/isp/capture.h index 04e90d628311..b76c075d90fc 100644 --- a/drivers/media/platform/rockchip/isp/capture.h +++ b/drivers/media/platform/rockchip/isp/capture.h @@ -219,7 +219,7 @@ struct streams_ops { void (*set_data_path)(struct rkisp_stream *stream); bool (*is_stream_stopped)(struct rkisp_stream *stream); void (*update_mi)(struct rkisp_stream *stream); - int (*frame_end)(struct rkisp_stream *stream); + int (*frame_end)(struct rkisp_stream *stream, u32 state); int (*frame_start)(struct rkisp_stream *stream, u32 mis); int (*set_wrap)(struct rkisp_stream *stream, int line); }; @@ -280,7 +280,7 @@ struct rkisp_stream { bool is_pause; bool is_crop_upd; bool is_using_resmem; - bool is_tb_s_info; + bool frame_early; wait_queue_head_t done; unsigned int burst; atomic_t sequence; @@ -322,6 +322,7 @@ extern struct stream_config rkisp_mp_stream_config; extern struct stream_config rkisp_sp_stream_config; extern struct rockit_isp_ops rockit_isp_ops; +void rkisp_stream_buf_done_early(struct rkisp_device *dev); void rkisp_stream_buf_done(struct rkisp_stream *stream, struct rkisp_buffer *buf); void rkisp_unregister_stream_vdev(struct rkisp_stream *stream); diff --git a/drivers/media/platform/rockchip/isp/capture_v1x.c b/drivers/media/platform/rockchip/isp/capture_v1x.c index 3c1df5e5273d..a9026e2a2ee6 100644 --- a/drivers/media/platform/rockchip/isp/capture_v1x.c +++ b/drivers/media/platform/rockchip/isp/capture_v1x.c @@ -15,7 +15,7 @@ #define CIF_ISP_REQ_BUFS_MIN 0 -static int mi_frame_end(struct rkisp_stream *stream); +static int mi_frame_end(struct rkisp_stream *stream, u32 state); static void rkisp_buf_queue(struct vb2_buffer *vb); static int rkisp_create_dummy_buf(struct rkisp_stream *stream); @@ -517,7 +517,7 @@ static int mp_config_mi(struct rkisp_stream *stream) mp_mi_ctrl_autoupdate_en(base); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -594,7 +594,7 @@ static int sp_config_mi(struct rkisp_stream *stream) sp_mi_ctrl_autoupdate_en(base); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -708,7 +708,7 @@ static struct streams_ops rkisp_sp_streams_ops = { * 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) +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; @@ -1262,7 +1262,7 @@ void rkisp_mi_v1x_isr(u32 mis_val, struct rkisp_device *dev) wake_up(&stream->done); } } else { - mi_frame_end(stream); + mi_frame_end(stream, FRAME_IRQ); } } } diff --git a/drivers/media/platform/rockchip/isp/capture_v20.c b/drivers/media/platform/rockchip/isp/capture_v20.c index ec766d08d807..209298197978 100644 --- a/drivers/media/platform/rockchip/isp/capture_v20.c +++ b/drivers/media/platform/rockchip/isp/capture_v20.c @@ -15,7 +15,7 @@ #define CIF_ISP_REQ_BUFS_MIN 0 -static int mi_frame_end(struct rkisp_stream *stream); +static int mi_frame_end(struct rkisp_stream *stream, u32 state); static void rkisp_buf_queue(struct vb2_buffer *vb); static const struct capture_fmt mp_fmts[] = { @@ -761,7 +761,7 @@ static int mp_config_mi(struct rkisp_stream *stream) mp_mi_ctrl_autoupdate_en(base); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -848,7 +848,7 @@ static int sp_config_mi(struct rkisp_stream *stream) sp_mi_ctrl_autoupdate_en(base); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -884,7 +884,7 @@ static int dmatx3_config_mi(struct rkisp_stream *stream) stream->memory | SW_CSI_RAW_WR_EN_ORG); mi_set_y_size(stream, in_size); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW3_WR_AUTOUPD); mi_raw_length(stream); @@ -930,7 +930,7 @@ static int dmatx2_config_mi(struct rkisp_stream *stream) val |= SW_CSI_RAW_WR_EN_ORG; raw_wr_ctrl(stream, val); mi_set_y_size(stream, in_size); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW2_WR_AUTOUPD); mi_raw_length(stream); @@ -974,7 +974,7 @@ static int dmatx1_config_mi(struct rkisp_stream *stream) val |= SW_CSI_RAW_WR_EN_ORG; raw_wr_ctrl(stream, val); mi_set_y_size(stream, in_size); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW1_WR_AUTOUPD); mi_raw_length(stream); @@ -1022,7 +1022,7 @@ static int dmatx0_config_mi(struct rkisp_stream *stream) val |= SW_CSI_RAW_WR_EN_ORG; raw_wr_ctrl(dmatx, val); mi_set_y_size(dmatx, in_size); - mi_frame_end(dmatx); + mi_frame_end(dmatx, FRAME_INIT); mi_frame_end_int_enable(dmatx); mi_wr_ctrl2(base, SW_RAW0_WR_AUTOUPD); mi_raw_length(stream); @@ -1353,7 +1353,7 @@ RDBK_FRM_UNMATCH: * 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) +static int mi_frame_end(struct rkisp_stream *stream, u32 state) { struct rkisp_device *dev = stream->ispdev; struct rkisp_capture_device *cap = &dev->cap_dev; @@ -2168,7 +2168,7 @@ void rkisp_stop_spstream(struct rkisp_stream *stream) void rkisp_update_spstream_buf(struct rkisp_stream *stream) { if (stream->id == RKISP_STREAM_SP && stream->out_isp_fmt.fmt_type == FMT_FBCGAIN) - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); } /**************** Interrupter Handler ****************/ @@ -2222,7 +2222,7 @@ void rkisp_mi_v20_isr(u32 mis_val, struct rkisp_device *dev) end_tx2 = false; } } else { - mi_frame_end(stream); + mi_frame_end(stream, FRAME_IRQ); if (dev->dmarx_dev.trigger == T_AUTO && ((dev->hdr.op_mode == HDR_RDBK_FRAME1 && end_tx2) || (dev->hdr.op_mode == HDR_RDBK_FRAME2 && end_tx2 && end_tx0) || diff --git a/drivers/media/platform/rockchip/isp/capture_v21.c b/drivers/media/platform/rockchip/isp/capture_v21.c index 75eff1643ee7..79836510f56e 100644 --- a/drivers/media/platform/rockchip/isp/capture_v21.c +++ b/drivers/media/platform/rockchip/isp/capture_v21.c @@ -15,7 +15,7 @@ #define CIF_ISP_REQ_BUFS_MIN 0 -static int mi_frame_end(struct rkisp_stream *stream); +static int mi_frame_end(struct rkisp_stream *stream, u32 state); static void rkisp_buf_queue(struct vb2_buffer *vb); static const struct capture_fmt mp_fmts[] = { @@ -720,7 +720,7 @@ static int mp_config_mi(struct rkisp_stream *stream) stream->out_isp_fmt.write_format, false); mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -794,7 +794,7 @@ static int sp_config_mi(struct rkisp_stream *stream) CIF_MI_SP_AUTOUPDATE_ENABLE, false); mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -823,7 +823,7 @@ static int dmatx3_config_mi(struct rkisp_stream *stream) stream->out_fmt.height); raw_wr_set_pic_offs(stream, 0); mi_set_y_size(stream, in_size); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW3_WR_AUTOUPD); mi_raw_length(stream); @@ -869,7 +869,7 @@ static int dmatx2_config_mi(struct rkisp_stream *stream) stream->out_fmt.height); raw_wr_set_pic_offs(stream, 0); mi_set_y_size(stream, in_size); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW1_WR_AUTOUPD); mi_raw_length(stream); @@ -915,7 +915,7 @@ static int dmatx0_config_mi(struct rkisp_stream *stream) stream->out_fmt.height); raw_wr_set_pic_offs(stream, 0); mi_set_y_size(stream, in_size); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW0_WR_AUTOUPD); mi_raw_length(stream); @@ -1197,7 +1197,7 @@ RDBK_FRM_UNMATCH: * 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) +static int mi_frame_end(struct rkisp_stream *stream, u32 state) { struct rkisp_device *dev = stream->ispdev; struct rkisp_capture_device *cap = &dev->cap_dev; @@ -1940,7 +1940,7 @@ void rkisp_mi_v21_isr(u32 mis_val, struct rkisp_device *dev) end_tx2 = false; } } else { - mi_frame_end(stream); + mi_frame_end(stream, FRAME_IRQ); if (dev->dmarx_dev.trigger == T_AUTO && ((dev->hdr.op_mode == HDR_RDBK_FRAME1 && end_tx2) || (dev->hdr.op_mode == HDR_RDBK_FRAME2 && end_tx2 && end_tx0))) { diff --git a/drivers/media/platform/rockchip/isp/capture_v30.c b/drivers/media/platform/rockchip/isp/capture_v30.c index 56564a3f9bac..c3ef571ff2e9 100644 --- a/drivers/media/platform/rockchip/isp/capture_v30.c +++ b/drivers/media/platform/rockchip/isp/capture_v30.c @@ -15,7 +15,7 @@ #define CIF_ISP_REQ_BUFS_MIN 0 -static int mi_frame_end(struct rkisp_stream *stream); +static int mi_frame_end(struct rkisp_stream *stream, u32 state); static int mi_frame_start(struct rkisp_stream *stream, u32 mis); static const struct capture_fmt mp_fmts[] = { @@ -521,7 +521,7 @@ static int mp_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -614,7 +614,7 @@ static int sp_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -642,7 +642,7 @@ static int fbc_config_mi(struct rkisp_stream *stream) false, is_unite); mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -685,7 +685,7 @@ static int bp_config_mi(struct rkisp_stream *stream) rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, 0, val, false, is_unite); mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); return 0; } @@ -951,19 +951,37 @@ static int mi_frame_start(struct rkisp_stream *stream, u32 mis) * 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) +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; + struct rkisp_buffer *buf = NULL; unsigned long lock_flags = 0; int i = 0; if (stream->id == RKISP_STREAM_VIR) return 0; - if (stream->curr_buf) { + if (dev->cap_dev.is_done_early && + (state == FRAME_IRQ || state == FRAME_WORK)) { + 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 rkisp_stream *vir = &dev->cap_dev.stream[RKISP_STREAM_VIR]; - struct vb2_buffer *vb2_buf = &stream->curr_buf->vb.vb2_buf; + struct vb2_buffer *vb2_buf = &buf->vb.vb2_buf; u64 ns = 0; /* Dequeue a filled buffer */ @@ -974,7 +992,7 @@ static int mi_frame_end(struct rkisp_stream *stream) } rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true); - stream->curr_buf->vb.sequence = i; + buf->vb.sequence = i; if (!ns) ns = ktime_get_ns(); vb2_buf->timestamp = ns; @@ -982,34 +1000,34 @@ static int mi_frame_end(struct rkisp_stream *stream) ns = ktime_get_ns(); stream->dbg.interval = ns - stream->dbg.timestamp; stream->dbg.timestamp = ns; - stream->dbg.id = stream->curr_buf->vb.sequence; + stream->dbg.id = buf->vb.sequence; stream->dbg.delay = ns - dev->isp_sdev.frm_timestamp; if (vir->streaming && vir->conn_id == stream->id) { spin_lock_irqsave(&vir->vbq_lock, lock_flags); - list_add_tail(&stream->curr_buf->queue, + 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, stream->curr_buf); + rkisp_stream_buf_done(stream, buf); } - - stream->curr_buf = NULL; } +end: + if (state == FRAME_WORK) + return 0; + spin_lock_irqsave(&stream->vbq_lock, lock_flags); stream->curr_buf = stream->next_buf; stream->next_buf = NULL; - spin_lock_irqsave(&stream->vbq_lock, lock_flags); 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); } - spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); - stream->ops->update_mi(stream); + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); return 0; } @@ -1711,7 +1729,7 @@ void rkisp_mi_v30_isr(u32 mis_val, struct rkisp_device *dev) wake_up(&stream->done); } } else { - mi_frame_end(stream); + mi_frame_end(stream, FRAME_IRQ); } } diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index 2e460ca70fde..519dc05105e3 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -27,7 +27,7 @@ #define CIF_ISP_REQ_BUFS_MIN 0 -static int mi_frame_end(struct rkisp_stream *stream); +static int mi_frame_end(struct rkisp_stream *stream, u32 state); static int mi_frame_start(struct rkisp_stream *stream, u32 mis); static int rkisp_create_dummy_buf(struct rkisp_stream *stream); @@ -752,7 +752,7 @@ static int mp_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); rkisp_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); rkisp_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); @@ -843,7 +843,7 @@ static int sp_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); rkisp_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); rkisp_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); @@ -886,7 +886,7 @@ static int bp_config_mi(struct rkisp_stream *stream) rkisp_set_bits(dev, ISP3X_MI_WR_CTRL, 0, val, false); mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); rkisp_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); rkisp_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); @@ -916,7 +916,7 @@ static int ds_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); - mi_frame_end(stream); + mi_frame_end(stream, FRAME_INIT); rkisp_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); rkisp_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); @@ -1098,7 +1098,6 @@ static void update_mi(struct rkisp_stream *stream) if (dev->tb_addr_idx < dev->tb_stream_info.buf_max - 1) dev->tb_addr_idx++; - stream->is_tb_s_info = true; } else if (!stream->is_pause) { stream->is_pause = true; stream->ops->disable_mi(stream); @@ -1220,7 +1219,7 @@ end: } } -static int luma_frame_end(struct rkisp_stream *stream) +static int luma_frame_end(struct rkisp_stream *stream, u32 state) { struct rkisp_device *dev = stream->ispdev; u32 val; @@ -1364,27 +1363,47 @@ static int mi_frame_start(struct rkisp_stream *stream, u32 mis) * 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) +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; if (stream->id == RKISP_STREAM_VIR) return 0; - set_mirror_flip(stream); + 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 (stream->curr_buf) { - struct vb2_buffer *vb2_buf = &stream->curr_buf->vb.vb2_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) { spin_lock_irqsave(&stream->vbq_lock, lock_flags); - list_add_tail(&stream->curr_buf->queue, &stream->buf_queue); + list_add_tail(&buf->queue, &stream->buf_queue); spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); - goto next; + goto end; } for (i = 0; i < isp_fmt->mplanes; i++) { @@ -1393,22 +1412,37 @@ static int mi_frame_end(struct rkisp_stream *stream) vb2_set_plane_payload(vb2_buf, i, payload_size); } + rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true); + if (!ns) + ns = ktime_get_ns(); + buf->vb.sequence = i; + buf->vb.vb2_buf.timestamp = ns; + ns = ktime_get_ns(); + 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 (vb2_buf->memory) { if (vir->streaming && vir->conn_id == stream->id) { spin_lock_irqsave(&vir->vbq_lock, lock_flags); - list_add_tail(&stream->curr_buf->queue, + 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, stream->curr_buf); + rkisp_stream_buf_done(stream, buf); } } else { rkisp_rockit_buf_done(stream, ROCKIT_DVBM_END); } } -next: + +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; @@ -2221,31 +2255,6 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) if (i == RKISP_STREAM_MP) rkisp_dvbm_event(dev, CIF_MI_MP_FRAME); - rkisp_dmarx_get_frame(dev, &seq, NULL, &ns, true); - if (!ns) - ns = ktime_get_ns(); - if (stream->curr_buf) { - stream->curr_buf->vb.sequence = seq; - stream->curr_buf->vb.vb2_buf.timestamp = ns; - - ns = ktime_get_ns(); - stream->dbg.interval = ns - stream->dbg.timestamp; - stream->dbg.delay = ns - dev->isp_sdev.frm_timestamp; - stream->dbg.timestamp = ns; - stream->dbg.id = seq; - } - if (stream->is_tb_s_info) { - struct rkisp_tb_stream_info *tb_info = &dev->tb_stream_info; - u32 idx; - - if (tb_info->buf_cnt < tb_info->buf_max) - tb_info->buf_cnt++; - idx = tb_info->buf_cnt - 1; - dev->tb_stream_info.buf[idx].sequence = seq; - dev->tb_stream_info.buf[idx].timestamp = ns; - stream->is_tb_s_info = false; - } - if (stream->stopping) { /* * Make sure stream is actually stopped, whose state @@ -2265,9 +2274,15 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) stream->streaming = false; wake_up(&stream->done); } + } else if (stream->id == RKISP_STREAM_MP && dev->cap_dev.wrap_line) { + ns = ktime_get_ns(); + 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; } else { - if (stream->id != RKISP_STREAM_MP || !dev->cap_dev.wrap_line) - mi_frame_end(stream); + mi_frame_end(stream, FRAME_IRQ); } } diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index 37b52d159c49..29af28c86b6c 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -253,5 +253,6 @@ struct rkisp_device { u8 multi_mode; u8 multi_index; + u8 rawaf_irq_cnt; }; #endif diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 31d24dcb1672..87db6aa87554 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -1061,14 +1061,6 @@ isp_rawaf_config(struct rkisp_isp_params_vdev *params_vdev, ISP3X_RAWAF_SIZE_WINA + i * 8, id); } - var = 0; - for (i = 0; i < ISP3X_RAWAF_LINE_NUM; i++) { - if (arg->line_en[i]) - var |= ISP3X_RAWAF_INTLINE0_EN << i; - var |= ISP3X_RAWAF_INELINE0(arg->line_num[i]) << 4 * i; - } - isp3_param_write(params_vdev, var, ISP3X_RAWAF_INT_LINE, id); - var = isp3_param_read(params_vdev, ISP3X_RAWAF_THRES, id); var &= ~0xFFFF; var |= arg->afm_thres; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c index 3b72a1c339f0..7b21a80b038b 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c @@ -1005,12 +1005,10 @@ rkisp_stats_send_meas_v3x(struct rkisp_isp_stats_vdev *stats_vdev, v4l2_warn(stats_vdev->vnode.vdev.v4l2_dev, "ISP3X_3A_RAWAF_SUM\n"); + ops->get_rawaf_meas(stats_vdev, cur_stat_buf, 0); if (meas_work->isp3a_ris & ISP3X_3A_RAWAWB) ret |= ops->get_rawawb_meas(stats_vdev, cur_stat_buf, 0); - if (meas_work->isp3a_ris & ISP3X_3A_RAWAF) - ret |= ops->get_rawaf_meas(stats_vdev, cur_stat_buf, 0); - if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG) ret |= ops->get_rawae3_meas(stats_vdev, cur_stat_buf, 0); @@ -1046,10 +1044,9 @@ rkisp_stats_send_meas_v3x(struct rkisp_isp_stats_vdev *stats_vdev, cur_stat_buf++; cur_stat_buf->frame_id = cur_frame_id; } + ops->get_rawaf_meas(stats_vdev, cur_stat_buf, 1); if (meas_work->isp3a_ris & ISP3X_3A_RAWAWB) ret |= ops->get_rawawb_meas(stats_vdev, cur_stat_buf, 1); - if (meas_work->isp3a_ris & ISP3X_3A_RAWAF) - ret |= ops->get_rawaf_meas(stats_vdev, cur_stat_buf, 1); if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG) ret |= ops->get_rawae3_meas(stats_vdev, cur_stat_buf, 1); if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_BIG) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 44173416fa60..485f3346d35e 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -2126,6 +2126,30 @@ static int rkisp_isp_start(struct rkisp_device *dev) atomic_read(&dev->hw_dev->refcnt), dev->hw_dev->dev_link_num); + dev->cap_dev.is_done_early = false; + if (dev->cap_dev.wait_line >= dev->isp_sdev.out_crop.height) + dev->cap_dev.wait_line = 0; + if (dev->cap_dev.wait_line) { + dev->cap_dev.is_done_early = true; + if (dev->isp_ver >= ISP_V32) { + val = dev->cap_dev.wait_line; + rkisp_write(dev, ISP32_ISP_IRQ_CFG0, val << 16, false); + rkisp_set_bits(dev, CIF_ISP_IMSC, 0, ISP3X_OUT_FRM_HALF, false); + } else { + /* using AF 15x15 block */ + val = dev->isp_sdev.out_crop.height / 15; + val = dev->cap_dev.wait_line / val; + val = ISP3X_RAWAF_INELINE0(val) | ISP3X_RAWAF_INTLINE0_EN; + rkisp_unite_write(dev, ISP3X_RAWAF_INT_LINE, + val, false, dev->hw_dev->is_unite); + rkisp_unite_set_bits(dev, ISP_ISP3A_IMSC, 0, + ISP2X_3A_RAWAF, false, dev->hw_dev->is_unite); + rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, + ISP2X_LSC_LUT_ERR, false, dev->hw_dev->is_unite); + dev->rawaf_irq_cnt = 0; + } + } + /* Activate MIPI */ if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { @@ -2817,7 +2841,7 @@ static void rkisp_global_update_mi(struct rkisp_device *dev) stream->id == RKISP_STREAM_LUMA) continue; if (stream->streaming && !stream->curr_buf) - stream->ops->frame_end(stream); + stream->ops->frame_end(stream, FRAME_INIT); } } rkisp_stats_next_ddr_config(&dev->stats_vdev); @@ -3968,7 +3992,7 @@ void rkisp_isp_isr(unsigned int isp_mis, ISP2X_3A_RAWHIST_BIG | ISP2X_3A_RAWHIST_CH0 | ISP2X_3A_RAWHIST_CH1 | ISP2X_3A_RAWHIST_CH2 | ISP2X_3A_RAWAF_SUM | ISP2X_3A_RAWAF_LUM | - ISP2X_3A_RAWAF | ISP2X_3A_RAWAWB; + ISP2X_3A_RAWAWB; bool sof_event_later = false; /* @@ -4085,6 +4109,16 @@ vs_skip: } } + if (isp3a_mis & ISP2X_3A_RAWAF) { + writel(ISP3X_3A_RAWAF, base + ISP3X_ISP_3A_ICR); + /* 3a irq will with lsc_lut_err irq if isp version below isp32 */ + if (isp_mis & ISP2X_LSC_LUT_ERR) + isp_mis &= ~ISP2X_LSC_LUT_ERR; + if (dev->rawaf_irq_cnt == 0) + rkisp_stream_buf_done_early(dev); + dev->rawaf_irq_cnt++; + } + if (isp_mis & ISP2X_LSC_LUT_ERR) { writel(ISP2X_LSC_LUT_ERR, base + CIF_ISP_ICR); @@ -4108,6 +4142,7 @@ vs_skip: /* frame was completely put out */ if (isp_mis & CIF_ISP_FRAME) { + dev->rawaf_irq_cnt = 0; if (!dev->is_pre_on || !IS_HDR_RDBK(dev->rd_mode)) dev->isp_sdev.dbg.interval = ktime_get_ns() - dev->isp_sdev.dbg.timestamp; @@ -4164,7 +4199,7 @@ vs_skip: if (dev->hw_dev->isp_ver == ISP_V32) { struct rkisp_stream *s = &dev->cap_dev.stream[RKISP_STREAM_LUMA]; - s->ops->frame_end(s); + s->ops->frame_end(s, FRAME_IRQ); } if (dev->procfs.is_fe_wait) { dev->procfs.is_fe_wait = false; @@ -4177,7 +4212,8 @@ vs_skip: * lot of register writes. Do those only one per frame. * Do the updates in the order of the processing flow. */ - rkisp_params_isr(&dev->params_vdev, isp_mis); + if (isp_mis & (CIF_ISP_V_START | CIF_ISP_FRAME)) + rkisp_params_isr(&dev->params_vdev, isp_mis); /* cur frame end and next frame start irq togeter */ if (dev->vs_irq < 0 && sof_event_later) { @@ -4193,6 +4229,7 @@ vs_skip: if (isp_mis & ISP3X_OUT_FRM_HALF) { writel(ISP3X_OUT_FRM_HALF, base + CIF_ISP_ICR); rkisp_dvbm_event(dev, ISP3X_OUT_FRM_HALF); + rkisp_stream_buf_done_early(dev); } if (isp_mis & ISP3X_OUT_FRM_END) { writel(ISP3X_OUT_FRM_END, base + CIF_ISP_ICR);