media: rockchip: vicap support capture raw online with only one buffer

Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: I6e4be9633798c3c666dbc36221acbbf3d5df0c35
This commit is contained in:
Zefa Chen
2023-10-13 17:23:51 +08:00
committed by Tao Huang
parent af37f2152d
commit 534dc2d08b

View File

@@ -1614,25 +1614,29 @@ static int rkcif_assign_new_buffer_oneframe(struct rkcif_stream *stream,
return ret;
}
static void rkcif_rx_buffer_free(struct rkcif_stream *stream)
static struct v4l2_subdev *get_rkisp_sd(struct sditf_priv *priv)
{
struct media_pad *pad = NULL;
if (priv && priv->pads[0].entity->num_links) {
if (priv->is_combine_mode)
pad = media_entity_remote_pad(&priv->pads[1]);
else
pad = media_entity_remote_pad(&priv->pads[0]);
if (pad)
return media_entity_to_v4l2_subdev(pad->entity);
}
return NULL;
}
static void rkcif_rx_buffer_free(struct rkcif_stream *stream)
{
struct v4l2_subdev *sd;
struct rkisp_rx_buf *dbufs;
struct rkcif_device *dev = stream->cifdev;
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
pad = media_entity_remote_pad(&dev->sditf[0]->pads[0]);
} else {
return;
}
if (pad)
sd = media_entity_to_v4l2_subdev(pad->entity);
else
sd = get_rkisp_sd(dev->sditf[0]);
if (!sd)
return;
while (!list_empty(&stream->rx_buf_head_vicap)) {
@@ -1648,22 +1652,13 @@ static void rkcif_rx_buffer_free(struct rkcif_stream *stream)
static void rkcif_s_rx_buffer(struct rkcif_device *dev, struct rkisp_rx_buf *dbufs)
{
struct media_pad *pad = NULL;
struct v4l2_subdev *sd;
struct rkcif_rx_buffer *rx_buf = NULL;
if (dev->sditf[0]) {
if (dev->sditf[0]->is_combine_mode)
pad = media_entity_remote_pad(&dev->sditf[0]->pads[1]);
else
pad = media_entity_remote_pad(&dev->sditf[0]->pads[0]);
} else {
return;
}
if (pad)
sd = media_entity_to_v4l2_subdev(pad->entity);
else
sd = get_rkisp_sd(dev->sditf[0]);
if (!sd)
return;
if (dev->rdbk_debug &&
dbufs->sequence < 15) {
rx_buf = to_cif_rx_buf(dbufs);
@@ -2346,6 +2341,7 @@ static void rkcif_assign_new_buffer_init(struct rkcif_stream *stream,
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
struct csi_channel_info *channel = &dev->channels[channel_id];
stream->lack_buf_cnt = 0;
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
mbus_cfg->type == V4L2_MBUS_CCP2) {
@@ -2440,6 +2436,8 @@ static void rkcif_assign_new_buffer_init(struct rkcif_stream *stream,
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);
} else if (stream->curr_buf) {
stream->next_buf = stream->curr_buf;
}
}
@@ -2546,18 +2544,9 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
get_dvp_reg_index_of_frm1_uv_addr(channel_id);
}
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;
}
if (stream->to_stop_dma && (stream->dma_en & RKCIF_DMAEN_BY_ISP)) {
v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
goto stop_dma;
}
spin_lock_irqsave(&stream->vbq_lock, flags);
@@ -2603,9 +2592,9 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
}
}
}
} else if (!(stream->dma_en & RKCIF_DMAEN_BY_ISP)) {
} else {
buffer = NULL;
if (dummy_buf->vaddr) {
if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) && dummy_buf->vaddr) {
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
stream->curr_buf = NULL;
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
@@ -2616,12 +2605,11 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
stream->next_buf = NULL;
}
}
} else if (stream->curr_buf && stream->next_buf &&
stream->curr_buf != stream->next_buf) {
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
} else if (stream->curr_buf != stream->next_buf) {
if (stream->frame_phase == CIF_CSI_FRAME0_READY && stream->next_buf) {
stream->curr_buf = stream->next_buf;
buffer = stream->next_buf;
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY && stream->curr_buf) {
stream->next_buf = stream->curr_buf;
buffer = stream->curr_buf;
}
@@ -2688,66 +2676,6 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
if (dbufs)
rkcif_s_rx_buffer(dev, dbufs);
}
} else {
if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
buff_addr_y = stream->curr_buf_toisp->dummy.dma_addr;
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
rkcif_write_buff_addr_multi_dev_combine(stream,
frm_addr_y, 0,
buff_addr_y, 0, false);
else
rkcif_write_register(dev, frm_addr_y, buff_addr_y);
if (stream->frame_phase == CIF_CSI_FRAME0_READY &&
stream->next_buf)
dbuf = stream->next_buf->dbuf;
else if (stream->frame_phase == CIF_CSI_FRAME1_READY &&
stream->curr_buf)
dbuf = stream->curr_buf->dbuf;
if (dbuf) {
list_for_each_entry(dbufs, &stream->rx_buf_head_vicap, list)
if (dbufs->dbuf == dbuf)
break;
} else {
dbufs = &stream->curr_buf_toisp->dbufs;
}
if (dbufs)
rkcif_s_rx_buffer(dev, dbufs);
if (stream->curr_buf && stream->frame_phase == CIF_CSI_FRAME0_READY) {
stream->curr_buf = NULL;
if (stream->buf_replace_cnt)
stream->buf_replace_cnt--;
} else if (stream->next_buf && stream->frame_phase == CIF_CSI_FRAME1_READY) {
stream->next_buf = NULL;
if (stream->buf_replace_cnt)
stream->buf_replace_cnt--;
}
} else if (dummy_buf->vaddr) {
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
buff_addr_y = dummy_buf->dma_addr;
buff_addr_cbcr = dummy_buf->dma_addr;
rkcif_write_buff_addr_multi_dev_combine(stream,
frm_addr_y,
frm_addr_uv,
buff_addr_y,
buff_addr_cbcr,
true);
} else {
rkcif_write_register(dev, frm_addr_y, dummy_buf->dma_addr);
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
rkcif_write_register(dev, frm_addr_uv, dummy_buf->dma_addr);
}
dev->err_state |= (RKCIF_ERR_ID0_NOT_BUF << stream->id);
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]++;
}
}
spin_unlock_irqrestore(&stream->vbq_lock, flags);
return ret;
@@ -4600,7 +4528,8 @@ void rkcif_buf_queue(struct vb2_buffer *vb)
list_add_tail(&dbufs->list, &stream->rx_buf_head_vicap);
}
if (stream->cifdev->workmode == RKCIF_WORKMODE_PINGPONG &&
stream->lack_buf_cnt)
stream->lack_buf_cnt &&
stream->cur_stream_mode & RKCIF_STREAM_MODE_CAPTURE)
rkcif_check_buffer_update_pingpong(stream, stream->id);
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
"stream[%d] buf queue, index: %d, dma_addr 0x%x\n",
@@ -5073,13 +5002,13 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream,
list_add_tail(&stream->next_buf->queue, &stream->buf_head);
spin_unlock_irqrestore(&stream->vbq_lock, flags);
stream->curr_buf = NULL;
stream->next_buf = NULL;
if (dev->hdr.hdr_mode == HDR_X2 ||
dev->hdr.hdr_mode == HDR_X3)
rkcif_release_rdbk_buf(stream);
stream->curr_buf = NULL;
stream->next_buf = NULL;
rkcif_rx_buffer_free(stream);
list_for_each_entry(buf, &stream->buf_head, queue) {
v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev,
@@ -8486,7 +8415,7 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
v4l2_err(&dev->v4l2_dev,
"s/m/l frame err, timestamp s:%lld m:%lld l:%lld\n",
s_ts, m_ts, l_ts);
goto RDBK_FRM_UNMATCH;
return;
}
if ((m_ts - l_ts) > time || (s_ts - m_ts) > time) {
@@ -8507,7 +8436,7 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
v4l2_err(&dev->v4l2_dev,
"timestamp no match, s:%lld m:%lld l:%lld, fps:%d\n",
s_ts, m_ts, l_ts, fps);
goto RDBK_FRM_UNMATCH;
return;
}
}
dev->rdbk_buf[RDBK_M]->vb.sequence = dev->rdbk_buf[RDBK_L]->vb.sequence;
@@ -8536,7 +8465,7 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
v4l2_err(&dev->v4l2_dev, "lost medium frames\n");
if (!dev->rdbk_buf[RDBK_S])
v4l2_err(&dev->v4l2_dev, "lost short frames\n");
goto RDBK_FRM_UNMATCH;
return;
}
} else if (dev->hdr.hdr_mode == HDR_X2) {
if (dev->rdbk_buf[RDBK_L] && dev->rdbk_buf[RDBK_M]) {
@@ -8547,7 +8476,7 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
v4l2_err(&dev->v4l2_dev,
"s/l frame err, timestamp s:%lld l:%lld\n",
s_ts, l_ts);
goto RDBK_FRM_UNMATCH;
return;
}
if ((s_ts - l_ts) > time) {
@@ -8567,7 +8496,7 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
v4l2_err(&dev->v4l2_dev,
"timestamp no match, s:%lld l:%lld, fps:%d\n",
s_ts, l_ts, fps);
goto RDBK_FRM_UNMATCH;
return;
}
}
dev->rdbk_buf[RDBK_M]->vb.sequence = dev->rdbk_buf[RDBK_L]->vb.sequence;
@@ -8591,29 +8520,10 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
v4l2_err(&dev->v4l2_dev, "lost long frames\n");
if (!dev->rdbk_buf[RDBK_M])
v4l2_err(&dev->v4l2_dev, "lost short frames\n");
goto RDBK_FRM_UNMATCH;
return;
}
}
dev->rdbk_buf[RDBK_L] = NULL;
dev->rdbk_buf[RDBK_M] = NULL;
dev->rdbk_buf[RDBK_S] = NULL;
return;
RDBK_FRM_UNMATCH:
if (dev->rdbk_buf[RDBK_L]) {
dev->rdbk_buf[RDBK_L]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
rkcif_buf_queue(&dev->rdbk_buf[RDBK_L]->vb.vb2_buf);
}
if (dev->rdbk_buf[RDBK_M]) {
dev->rdbk_buf[RDBK_M]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
rkcif_buf_queue(&dev->rdbk_buf[RDBK_M]->vb.vb2_buf);
}
if (dev->rdbk_buf[RDBK_S]) {
dev->rdbk_buf[RDBK_S]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
rkcif_buf_queue(&dev->rdbk_buf[RDBK_S]->vb.vb2_buf);
}
dev->rdbk_buf[RDBK_L] = NULL;
dev->rdbk_buf[RDBK_M] = NULL;
dev->rdbk_buf[RDBK_S] = NULL;
@@ -8664,6 +8574,15 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
}
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED)
vb_done->sequence /= 2;
} else if (cif_dev->rdbk_buf[stream->id]) {
vb_done = &cif_dev->rdbk_buf[stream->id]->vb;
if (cif_dev->chip_id < CHIP_RK3588_CIF &&
cif_dev->active_sensor->mbus.type == V4L2_MBUS_BT656)
vb_done->vb2_buf.timestamp = stream->readout.fe_timestamp;
else
vb_done->vb2_buf.timestamp = stream->readout.fs_timestamp;
vb_done->sequence = stream->frame_idx - 1;
cif_dev->rdbk_buf[stream->id]->fe_timestamp = ktime_get_ns();
}
if (cif_dev->hdr.hdr_mode == NO_HDR || cif_dev->hdr.hdr_mode == HDR_COMPR) {
@@ -8687,7 +8606,7 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
if (cif_dev->is_start_hdr) {
spin_lock_irqsave(&cif_dev->hdr_lock, flags);
if (mipi_id == RKCIF_STREAM_MIPI_ID0) {
if (cif_dev->rdbk_buf[RDBK_L]) {
if (cif_dev->rdbk_buf[RDBK_L] && active_buf) {
v4l2_err(&cif_dev->v4l2_dev,
"multiple long data in %s frame,frm_idx:%d,state:0x%x\n",
cif_dev->hdr.hdr_mode == HDR_X2 ? "hdr_x2" : "hdr_x3",
@@ -8700,7 +8619,7 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
if (active_buf)
cif_dev->rdbk_buf[RDBK_L] = active_buf;
} else if (mipi_id == RKCIF_STREAM_MIPI_ID1) {
if (cif_dev->rdbk_buf[RDBK_M]) {
if (cif_dev->rdbk_buf[RDBK_M] && active_buf) {
v4l2_err(&cif_dev->v4l2_dev,
"multiple %s frame,frm_idx:%d,state:0x%x\n",
cif_dev->hdr.hdr_mode == HDR_X2 ? "short data in hdr_x2" : "medium data in hdr_x3",
@@ -8715,7 +8634,7 @@ static void rkcif_buf_done_prepare(struct rkcif_stream *stream,
if (cif_dev->hdr.hdr_mode == HDR_X2)
rkcif_rdbk_frame_end(stream);
} else if (mipi_id == RKCIF_STREAM_MIPI_ID2) {
if (cif_dev->rdbk_buf[RDBK_S]) {
if (cif_dev->rdbk_buf[RDBK_S] && active_buf) {
v4l2_err(&cif_dev->v4l2_dev,
"multiple %s frame, frm_idx:%d,state:0x%x\n",
cif_dev->hdr.hdr_mode == HDR_X2 ? "err short data in hdr_x3" : "short data in hdr_x3",
@@ -10797,7 +10716,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
}
spin_lock_irqsave(&stream->vbq_lock, flags);
if (!(stream->dma_en & RKCIF_DMAEN_BY_ISP) && stream->lack_buf_cnt == 2) {
if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) && 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);