From adf004e7c8f9c2e75799b47da1e59c45d27bc302 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 26 May 2023 11:25:34 +0800 Subject: [PATCH] media: rockchip: vicap fixes issue of hdr raw capture Signed-off-by: Zefa Chen Change-Id: Icdd4cf79ea8c239df3d3e45b1572a4d59f4f7950 --- drivers/media/platform/rockchip/cif/capture.c | 58 +++++++++++++------ drivers/media/platform/rockchip/cif/dev.h | 1 + .../media/platform/rockchip/cif/subdev-itf.c | 3 +- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index bbd2731382ee..983d6750bb5e 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -1615,7 +1615,7 @@ static void rkcif_rx_buffer_free(struct rkcif_stream *stream) struct rkisp_rx_buf *dbufs; struct rkcif_device *dev = stream->cifdev; - if (dev->sditf[0] && dev->sditf[0]->num_sensors != 0) { + if (dev->sditf[0] && dev->sditf[0]->sd.entity.num_links) { if (dev->sditf[0]->is_combine_mode) pad = media_entity_remote_pad(&dev->sditf[0]->pads[1]); else @@ -2325,6 +2325,8 @@ static void rkcif_assign_new_buffer_init(struct rkcif_stream *stream, stream->curr_buf = list_first_entry(&stream->buf_head, struct rkcif_buffer, queue); + v4l2_dbg(4, rkcif_debug, &dev->v4l2_dev, "%s %d, stream[%d] buf idx %d\n", + __func__, __LINE__, stream->id, stream->curr_buf->vb.vb2_buf.index); list_del(&stream->curr_buf->queue); } } @@ -2393,6 +2395,8 @@ static void rkcif_assign_new_buffer_init(struct rkcif_stream *stream, if (!list_empty(&stream->buf_head)) { stream->next_buf = list_first_entry(&stream->buf_head, struct rkcif_buffer, queue); + v4l2_dbg(4, rkcif_debug, &dev->v4l2_dev, "%s %d, stream[%d] buf idx %d\n", + __func__, __LINE__, stream->id, stream->next_buf->vb.vb2_buf.index); list_del(&stream->next_buf->queue); } } @@ -2500,16 +2504,15 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, get_dvp_reg_index_of_frm1_uv_addr(channel_id); } - if (dev->hdr.hdr_mode != NO_HDR && stream->id != 0 && (!dev->rdbk_buf[RDBK_L])) { - v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__); - return -EINVAL; - } - if (stream->to_stop_dma) { if (stream->dma_en & RKCIF_DMAEN_BY_ISP) { v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__); goto stop_dma; } else { + if (stream->frame_phase == CIF_CSI_FRAME0_READY) + stream->curr_buf = NULL; + else + stream->next_buf = NULL; v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__); return -EINVAL; } @@ -2532,8 +2535,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, list_del(&stream->curr_buf->queue); buffer = stream->curr_buf; v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, - "stream[%d] update curr_buf 0x%x\n", - stream->id, buffer->buff_addr[0]); + "stream[%d] update curr_buf 0x%x, buf idx %d\n", + stream->id, buffer->buff_addr[0], stream->curr_buf->vb.vb2_buf.index); } } else if (stream->frame_phase == CIF_CSI_FRAME1_READY) { if (!stream->next_buf) @@ -2553,8 +2556,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, list_del(&stream->next_buf->queue); buffer = stream->next_buf; v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, - "stream[%d] update next_buf 0x%x\n", - stream->id, buffer->buff_addr[0]); + "stream[%d] update next_buf 0x%x, buf idx %d\n", + stream->id, buffer->buff_addr[0], stream->next_buf->vb.vb2_buf.index); } } } @@ -2734,11 +2737,9 @@ stop_dma: if (stream->frame_phase == CIF_CSI_FRAME0_READY && stream->curr_buf) { - list_add_tail(&stream->curr_buf->queue, &stream->buf_head); stream->curr_buf = NULL; } else if (stream->frame_phase == CIF_CSI_FRAME1_READY && stream->next_buf) { - list_add_tail(&stream->next_buf->queue, &stream->buf_head); stream->next_buf = NULL; } stream->buf_replace_cnt--; @@ -4419,11 +4420,17 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, if (stream->frame_phase_cache == CIF_CSI_FRAME0_READY) { stream->curr_buf = list_first_entry(&stream->buf_head, struct rkcif_buffer, queue); + v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, + "%s %d, stream[%d] buf idx %d\n", + __func__, __LINE__, stream->id, stream->curr_buf->vb.vb2_buf.index); if (stream->curr_buf) list_del(&stream->curr_buf->queue); } else if (stream->frame_phase_cache == CIF_CSI_FRAME1_READY) { stream->next_buf = list_first_entry(&stream->buf_head, struct rkcif_buffer, queue); + v4l2_dbg(4, rkcif_debug, &dev->v4l2_dev, + "%s %d, stream[%d] buf idx %d\n", + __func__, __LINE__, stream->id, stream->next_buf->vb.vb2_buf.index); if (stream->next_buf) list_del(&stream->next_buf->queue); } @@ -4452,6 +4459,7 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, } if (stream->lack_buf_cnt) stream->lack_buf_cnt--; + } else { v4l2_info(&dev->v4l2_dev, "%s %d, state %d, curr_buf %p, next_buf %p\n", __func__, __LINE__, stream->state, stream->curr_buf, stream->next_buf); @@ -4994,14 +5002,16 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream, } else if (mode == RKCIF_STREAM_MODE_CAPTURE && stream->dma_en & RKCIF_DMAEN_BY_VICAP) { //only stop dma stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP; + stream->is_wait_dma_stop = true; wait_event_timeout(stream->wq_stopped, - stream->to_stop_dma != RKCIF_DMAEN_BY_VICAP, + !stream->is_wait_dma_stop, msecs_to_jiffies(1000)); } else if (mode == RKCIF_STREAM_MODE_TOISP && stream->dma_en & RKCIF_DMAEN_BY_VICAP) { //only stop dma stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; + stream->is_wait_dma_stop = true; wait_event_timeout(stream->wq_stopped, - stream->to_stop_dma != RKCIF_DMAEN_BY_ISP, + !stream->is_wait_dma_stop, msecs_to_jiffies(1000)); } if ((mode & RKCIF_STREAM_MODE_CAPTURE) == RKCIF_STREAM_MODE_CAPTURE) { @@ -6594,6 +6604,7 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id) stream->is_high_align = false; stream->is_finish_stop_dma = false; + stream->is_wait_dma_stop = false; if (dev->chip_id == CHIP_RV1126_CIF || dev->chip_id == CHIP_RV1126_CIF_LITE) @@ -9893,6 +9904,11 @@ static int rkcif_stop_dma_capture(struct rkcif_stream *stream) rkcif_write_register(cif_dev, CIF_REG_DVP_CTRL, val); } stream->to_stop_dma = 0; + v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev, + "stream[%d] replace_cnt %d, y_addr 0x%x, 0x%x\n", + stream->id, stream->buf_replace_cnt, + rkcif_read_register(cif_dev, get_reg_index_of_frm0_y_addr(stream->id)), + rkcif_read_register(cif_dev, get_reg_index_of_frm1_y_addr(stream->id))); return 0; } @@ -10430,7 +10446,12 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) stream->frame_idx - 1, stream->frame_phase, ktime_get_ns()); - + if (stream->is_finish_stop_dma && stream->is_wait_dma_stop) { + stream->is_wait_dma_stop = false; + wake_up(&stream->wq_stopped); + stream->is_finish_stop_dma = false; + continue; + } if (stream->crop_dyn_en) rkcif_dynamic_crop(stream); @@ -10469,11 +10490,10 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) } spin_lock_irqsave(&stream->vbq_lock, flags); - if (stream->is_finish_stop_dma) { - wake_up(&stream->wq_stopped); - stream->is_finish_stop_dma = false; - } if (!(stream->dma_en & RKCIF_DMAEN_BY_ISP) && stream->lack_buf_cnt == 2) { + v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev, + "stream[%d] to stop dma, lack_buf_cnt %d\n", + stream->id, stream->lack_buf_cnt); stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP; rkcif_stop_dma_capture(stream); } diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index b5d4c0315e8c..d995f58ef99f 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -556,6 +556,7 @@ struct rkcif_stream { bool is_in_vblank; bool is_change_toisp; bool is_stop_capture; + bool is_wait_dma_stop; }; struct rkcif_lvds_subdev { diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 3df42731f17d..01aefd4e5988 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -806,7 +806,8 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd, return -EINVAL; rx_buf = to_cif_rx_buf(dbufs); - + v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n", + (u32)rx_buf->dummy.dma_addr); spin_lock_irqsave(&stream->vbq_lock, flags); stream->last_rx_buf_idx = dbufs->sequence + 1; atomic_inc(&stream->buf_cnt);