diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 19c374f73dc8..c1b4e8545111 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -2158,14 +2158,19 @@ 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])) + 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) + 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 + } else { + v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__); return -EINVAL; + } } spin_lock_irqsave(&stream->vbq_lock, flags); @@ -2236,6 +2241,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, if (stream->lack_buf_cnt < 2) stream->lack_buf_cnt++; } else { + stream->curr_buf = NULL; + stream->next_buf = NULL; if (stream->lack_buf_cnt < 2) stream->lack_buf_cnt++; } @@ -2314,6 +2321,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream, dev->irq_stats.not_active_buf_cnt[stream->id]++; } else { ret = -EINVAL; + stream->curr_buf = NULL; + stream->next_buf = NULL; dev->err_state |= (RKCIF_ERR_ID0_NOT_BUF << stream->id); dev->irq_stats.not_active_buf_cnt[stream->id]++; } @@ -3804,9 +3813,12 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus; struct rkcif_buffer *buffer = NULL; struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf; - u32 frm_addr_y, frm_addr_uv; + u32 frm_addr_y = 0, frm_addr_uv = 0; + u32 frm0_addr_y = 0, frm0_addr_uv = 0; + u32 frm1_addr_y = 0, frm1_addr_uv = 0; unsigned long flags; int frame_phase = 0; + bool is_dual_update_buf = false; spin_lock_irqsave(&stream->vbq_lock, flags); if (stream->state == RKCIF_STATE_STREAMING && @@ -3815,29 +3827,31 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, (!dummy_buf->vaddr)) || stream->curr_buf == NULL || stream->next_buf == NULL)) { - if (!stream->dma_en) - frame_phase = CIF_CSI_FRAME0_READY; - else - frame_phase = stream->frame_phase_cache; + frame_phase = stream->frame_phase_cache; if (!stream->is_line_wake_up || (stream->is_line_wake_up && stream->frame_idx < 2)) { if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY || mbus_cfg->type == V4L2_MBUS_CSI2_CPHY || mbus_cfg->type == V4L2_MBUS_CCP2) { - frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ? - get_reg_index_of_frm0_y_addr(channel_id) : - get_reg_index_of_frm1_y_addr(channel_id); - frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ? - get_reg_index_of_frm0_uv_addr(channel_id) : - get_reg_index_of_frm1_uv_addr(channel_id); + frm0_addr_y = get_reg_index_of_frm0_y_addr(channel_id); + frm1_addr_y = get_reg_index_of_frm1_y_addr(channel_id); + frm0_addr_uv = get_reg_index_of_frm0_uv_addr(channel_id); + frm1_addr_uv = get_reg_index_of_frm1_uv_addr(channel_id); } else { - frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ? - get_dvp_reg_index_of_frm0_y_addr(channel_id) : - get_dvp_reg_index_of_frm1_y_addr(channel_id); - frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ? - get_dvp_reg_index_of_frm0_uv_addr(channel_id) : - get_dvp_reg_index_of_frm1_uv_addr(channel_id); + frm0_addr_y = get_dvp_reg_index_of_frm0_y_addr(channel_id); + frm1_addr_y = get_dvp_reg_index_of_frm1_y_addr(channel_id); + frm0_addr_uv = get_dvp_reg_index_of_frm0_uv_addr(channel_id); + frm1_addr_uv = get_dvp_reg_index_of_frm1_uv_addr(channel_id); } + if (frame_phase & CIF_CSI_FRAME0_READY) { + frm_addr_y = frm0_addr_y; + frm_addr_uv = frm0_addr_uv; + } else { + frm_addr_y = frm1_addr_y; + frm_addr_uv = frm1_addr_uv; + } + if (!stream->dma_en && stream->curr_buf == NULL && stream->next_buf == NULL) + is_dual_update_buf = true; if (!list_empty(&stream->buf_head)) { if (frame_phase == CIF_CSI_FRAME0_READY) { stream->curr_buf = list_first_entry(&stream->buf_head, @@ -3846,6 +3860,8 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, list_del(&stream->curr_buf->queue); buffer = stream->curr_buf; } + if (buffer && is_dual_update_buf) + stream->next_buf = buffer; } else if (frame_phase == CIF_CSI_FRAME1_READY) { if (stream->next_buf == NULL && stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) { @@ -3857,17 +3873,37 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, list_del(&stream->next_buf->queue); buffer = stream->next_buf; } + if (buffer && is_dual_update_buf) + stream->curr_buf = buffer; } } + } else { + v4l2_info(&dev->v4l2_dev, "%s %d\n", __func__, __LINE__); } if (buffer) { - rkcif_write_register(dev, frm_addr_y, - buffer->buff_addr[RKCIF_PLANE_Y]); - if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW) - rkcif_write_register(dev, frm_addr_uv, - buffer->buff_addr[RKCIF_PLANE_CBCR]); + if (is_dual_update_buf) { + rkcif_write_register(dev, frm0_addr_y, + buffer->buff_addr[RKCIF_PLANE_Y]); + if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW) + rkcif_write_register(dev, frm0_addr_uv, + buffer->buff_addr[RKCIF_PLANE_CBCR]); + rkcif_write_register(dev, frm1_addr_y, + buffer->buff_addr[RKCIF_PLANE_Y]); + if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW) + rkcif_write_register(dev, frm1_addr_uv, + buffer->buff_addr[RKCIF_PLANE_CBCR]); + } else { + rkcif_write_register(dev, frm_addr_y, + buffer->buff_addr[RKCIF_PLANE_Y]); + if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW) + rkcif_write_register(dev, frm_addr_uv, + buffer->buff_addr[RKCIF_PLANE_CBCR]); + } } } else { + v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev, + "%s %d, is_wake_up %d, frame_idx %d\n", + __func__, __LINE__, stream->is_line_wake_up, stream->frame_idx); if (stream->curr_buf == stream->next_buf) { if (stream->frame_phase_cache == CIF_CSI_FRAME0_READY) { stream->curr_buf = list_first_entry(&stream->buf_head, @@ -3894,10 +3930,20 @@ static void rkcif_check_buffer_update_pingpong(struct rkcif_stream *stream, wake_up(&stream->wq_stopped); } else { stream->to_en_dma = RKCIF_DMAEN_BY_VICAP; + v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev, + "%s stream[%d] start dma capture, frame cnt %d\n", + __func__, stream->id, stream->frame_idx); } + } else { + v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev, + "%s %d, dma_en 0x%x, frame cnt %d\n", + __func__, __LINE__, stream->dma_en, stream->frame_idx); } 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); } spin_unlock_irqrestore(&stream->vbq_lock, flags); if (stream->to_en_dma) @@ -8166,11 +8212,11 @@ static void rkcif_update_stream(struct rkcif_device *cif_dev, ret = rkcif_assign_new_buffer_pingpong(stream, RKCIF_YUV_ADDR_STATE_UPDATE, mipi_id); - if (ret && cif_dev->chip_id != CHIP_RV1106_CIF) + if (ret && cif_dev->chip_id < CHIP_RK3588_CIF) return; } else { ret = rkcif_update_new_buffer_wake_up_mode(stream); - if (ret && cif_dev->chip_id != CHIP_RV1106_CIF) + if (ret && cif_dev->chip_id < CHIP_RK3588_CIF) return; } if (!stream->is_line_wake_up && stream->dma_en & RKCIF_DMAEN_BY_VICAP)