media: rockchip: vicap support tool video capture raw with rdbk by isp

used in the case of thunderboot

Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: I94e21fe6c130dd52f08cf695a5f1e46d555d7399
This commit is contained in:
Zefa Chen
2023-06-27 09:53:45 +08:00
committed by Tao Huang
parent 48a7374baa
commit cedb72825d
5 changed files with 168 additions and 31 deletions

View File

@@ -1670,6 +1670,20 @@ static void rkcif_disable_skip_frame(struct rkcif_stream *stream)
stream->skip_info.skip_en = false;
}
static void rkcif_rdbk_with_tools(struct rkcif_stream *stream,
struct rkcif_rx_buffer *active_buf)
{
unsigned long flags;
spin_lock_irqsave(&stream->tools_vdev->vbq_lock, flags);
if (stream->tools_vdev->state == RKCIF_STATE_STREAMING) {
list_add_tail(&active_buf->list, &stream->tools_vdev->buf_done_head);
if (!work_busy(&stream->tools_vdev->work))
schedule_work(&stream->tools_vdev->work);
}
spin_unlock_irqrestore(&stream->tools_vdev->vbq_lock, flags);
}
static void rkcif_rdbk_frame_end_toisp(struct rkcif_stream *stream,
struct rkcif_rx_buffer *buffer)
{
@@ -1734,6 +1748,12 @@ static void rkcif_rdbk_frame_end_toisp(struct rkcif_stream *stream,
rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_L]->dbufs);
rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_M]->dbufs);
rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_S]->dbufs);
rkcif_rdbk_with_tools(&dev->stream[RDBK_L], dev->rdbk_rx_buf[RDBK_L]);
rkcif_rdbk_with_tools(&dev->stream[RDBK_M], dev->rdbk_rx_buf[RDBK_M]);
rkcif_rdbk_with_tools(&dev->stream[RDBK_S], dev->rdbk_rx_buf[RDBK_S]);
atomic_dec(&dev->stream[RDBK_L].buf_cnt);
atomic_dec(&dev->stream[RDBK_M].buf_cnt);
atomic_dec(&dev->stream[RDBK_S].buf_cnt);
dev->rdbk_rx_buf[RDBK_L] = NULL;
dev->rdbk_rx_buf[RDBK_M] = NULL;
dev->rdbk_rx_buf[RDBK_S] = NULL;
@@ -1772,6 +1792,10 @@ static void rkcif_rdbk_frame_end_toisp(struct rkcif_stream *stream,
dev->rdbk_rx_buf[RDBK_M]->dbufs.sequence = dev->rdbk_rx_buf[RDBK_L]->dbufs.sequence;
rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_L]->dbufs);
rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_M]->dbufs);
rkcif_rdbk_with_tools(&dev->stream[RDBK_L], dev->rdbk_rx_buf[RDBK_L]);
rkcif_rdbk_with_tools(&dev->stream[RDBK_M], dev->rdbk_rx_buf[RDBK_M]);
atomic_dec(&dev->stream[RDBK_L].buf_cnt);
atomic_dec(&dev->stream[RDBK_M].buf_cnt);
dev->rdbk_rx_buf[RDBK_L] = NULL;
dev->rdbk_rx_buf[RDBK_M] = NULL;
}
@@ -1889,14 +1913,18 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
active_buf->fe_timestamp = ktime_get_ns();
stream->last_frame_idx = stream->frame_idx;
if (dev->hdr.hdr_mode == NO_HDR)
if (dev->hdr.hdr_mode == NO_HDR) {
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
else
if (dev->is_support_tools && stream->tools_vdev)
rkcif_rdbk_with_tools(stream, active_buf);
atomic_dec(&stream->buf_cnt);
} else {
rkcif_rdbk_frame_end_toisp(stream, active_buf);
stream->buf_num_toisp--;
}
} else {
rkcif_s_rx_buffer(dev, &stream->next_buf_toisp->dbufs);
stream->buf_num_toisp--;
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
if (dev->is_support_tools && stream->tools_vdev)
rkcif_rdbk_with_tools(stream, active_buf);
}
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
if (stream->curr_buf_toisp == stream->next_buf_toisp)
@@ -1918,14 +1946,18 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
active_buf->fe_timestamp = ktime_get_ns();
stream->last_frame_idx = stream->frame_idx;
if (dev->hdr.hdr_mode == NO_HDR)
if (dev->hdr.hdr_mode == NO_HDR) {
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
else
if (dev->is_support_tools && stream->tools_vdev)
rkcif_rdbk_with_tools(stream, active_buf);
atomic_dec(&stream->buf_cnt);
} else {
rkcif_rdbk_frame_end_toisp(stream, active_buf);
stream->buf_num_toisp--;
}
} else {
rkcif_s_rx_buffer(dev, &stream->curr_buf_toisp->dbufs);
stream->buf_num_toisp--;
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
if (dev->is_support_tools && stream->tools_vdev)
rkcif_rdbk_with_tools(stream, active_buf);
}
}
if (stream->lack_buf_cnt)
@@ -1967,10 +1999,14 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
active_buf->fe_timestamp = ktime_get_ns();
stream->last_frame_idx = stream->frame_idx;
if (dev->hdr.hdr_mode == NO_HDR)
if (dev->hdr.hdr_mode == NO_HDR) {
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
else
if (dev->is_support_tools && stream->tools_vdev)
rkcif_rdbk_with_tools(stream, active_buf);
atomic_dec(&stream->buf_cnt);
} else {
rkcif_rdbk_frame_end_toisp(stream, active_buf);
}
} else {
if (stream->cifdev->rdbk_debug && dev->hw_dev->dummy_buf.vaddr)
v4l2_info(&stream->cifdev->v4l2_dev,
@@ -1978,6 +2014,8 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
stream->id,
stream->frame_idx - 1);
}
if (dev->is_support_tools && stream->tools_vdev && stream->curr_buf_toisp)
rkcif_rdbk_with_tools(stream, stream->curr_buf_toisp);
}
out_get_buf:
@@ -2091,7 +2129,6 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
stream->id,
stream->frame_idx - 1, frm_addr_y,
(u32)stream->curr_buf_toisp->dummy.dma_addr);
stream->buf_num_toisp--;
}
} else if (frame_phase == CIF_CSI_FRAME1_READY) {
active_buf = stream->next_buf_toisp;
@@ -2109,7 +2146,6 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
stream->id,
stream->frame_idx - 1, frm_addr_y,
(u32)stream->next_buf_toisp->dummy.dma_addr);
stream->buf_num_toisp--;
}
}
if (stream->lack_buf_cnt)
@@ -2439,7 +2475,6 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
}
if (dbufs)
rkcif_s_rx_buffer(dev, dbufs);
stream->buf_num_toisp--;
}
} else {
if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
@@ -2460,7 +2495,6 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
dbufs = &stream->curr_buf_toisp->dbufs;
}
rkcif_s_rx_buffer(dev, dbufs);
stream->buf_num_toisp--;
if (stream->curr_buf && stream->frame_phase == CIF_CSI_FRAME0_READY) {
stream->curr_buf = NULL;
if (stream->buf_replace_cnt)
@@ -2507,7 +2541,6 @@ stop_dma:
}
if (dbufs)
rkcif_s_rx_buffer(dev, dbufs);
stream->buf_num_toisp--;
if (stream->frame_phase == CIF_CSI_FRAME0_READY &&
stream->curr_buf) {
@@ -3955,7 +3988,7 @@ static int rkcif_queue_setup(struct vb2_queue *queue,
plane_fmt = &pixm->plane_fmt[i];
sizes[i] = plane_fmt->sizeimage / height * h;
}
stream->total_buf_num = *num_buffers;
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "%s count %d, size %d, extended(%d, %d)\n",
v4l2_type_names[queue->type], *num_buffers, sizes[0],
is_extended, extend_line->is_extended);
@@ -4230,6 +4263,8 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num)
rkcif_free_buffer(dev, &buf->dummy);
else
list_add_tail(&buf->list_free, &priv->buf_free_list);
atomic_dec(&stream->buf_cnt);
stream->total_buf_num--;
}
if (dev->is_thunderboot) {
@@ -4323,7 +4358,6 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && i == 0) {
buf->dbufs.is_first = true;
rkcif_s_rx_buffer(dev, &buf->dbufs);
stream->buf_num_toisp--;
}
i++;
if (!dev->is_thunderboot && i >= buf_num) {
@@ -4339,7 +4373,8 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
(u64)dummy->dma_addr, pixm->plane_fmt[0].sizeimage);
}
if (priv->buf_num) {
stream->buf_num_toisp = priv->buf_num;
stream->total_buf_num = priv->buf_num;
atomic_set(&stream->buf_cnt, priv->buf_num);
return 0;
} else {
return -EINVAL;
@@ -4665,7 +4700,7 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream,
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
}
stream->total_buf_num = 0;
atomic_set(&stream->buf_cnt, 0);
stream->lack_buf_cnt = 0;
stream->dma_en &= ~RKCIF_DMAEN_BY_VICAP;
@@ -8313,8 +8348,10 @@ static void rkcif_release_unnecessary_buf_for_online(struct rkcif_stream *stream
spin_lock_irqsave(&priv->cif_dev->buffree_lock, flags);
for (i = 0; i < priv->buf_num; i++) {
rx_buf = &stream->rx_buf[i];
if (rx_buf && (!rx_buf->dummy.is_free) && rx_buf != buf)
if (rx_buf && (!rx_buf->dummy.is_free) && rx_buf != buf) {
list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
stream->total_buf_num--;
}
}
spin_unlock_irqrestore(&priv->cif_dev->buffree_lock, flags);
schedule_work(&priv->buffree_work.work);
@@ -8384,11 +8421,13 @@ static void rkcif_line_wake_up_rdbk(struct rkcif_stream *stream, int mipi_id)
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
active_buf->fe_timestamp = ktime_get_ns();
stream->last_frame_idx = stream->frame_idx;
if (stream->cifdev->hdr.hdr_mode == NO_HDR)
if (stream->cifdev->hdr.hdr_mode == NO_HDR) {
rkcif_s_rx_buffer(stream->cifdev, &active_buf->dbufs);
else
if (stream->cifdev->is_support_tools && stream->tools_vdev)
rkcif_rdbk_with_tools(stream, active_buf);
} else {
rkcif_rdbk_frame_end_toisp(stream, active_buf);
stream->buf_num_toisp--;
}
}
}
}

View File

@@ -589,11 +589,8 @@ static int rkcif_tools_init_vb2_queue(struct vb2_queue *q,
return vb2_queue_init(q);
}
static void rkcif_tools_work(struct work_struct *work)
static void rkcif_tools_buf_done(struct rkcif_tools_vdev *tools_vdev)
{
struct rkcif_tools_vdev *tools_vdev = container_of(work,
struct rkcif_tools_vdev,
work);
struct rkcif_stream *stream = tools_vdev->stream;
struct rkcif_tools_buffer *tools_buf;
const struct cif_output_fmt *fmt = tools_vdev->tools_out_fmt;
@@ -700,6 +697,99 @@ retry_done_buf:
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
}
static void rkcif_tools_buf_done_rdbk(struct rkcif_tools_vdev *tools_vdev)
{
struct rkcif_stream *stream = tools_vdev->stream;
struct rkcif_device *dev = stream->cifdev;
const struct cif_output_fmt *fmt = tools_vdev->tools_out_fmt;
struct rkcif_rx_buffer *buf = NULL;
int i = 0;
unsigned long flags;
retry_done_rdbk_buf:
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
if (!list_empty(&tools_vdev->buf_done_head)) {
buf = list_first_entry(&tools_vdev->buf_done_head,
struct rkcif_rx_buffer, list);
if (buf)
list_del(&buf->list);
}
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
if (!buf) {
v4l2_err(&dev->v4l2_dev, "stream[%d] tools fail to get buf form list\n",
stream->id);
return;
}
if (tools_vdev->stopping) {
rkcif_tools_stop(tools_vdev);
tools_vdev->stopping = false;
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
while (!list_empty(&tools_vdev->buf_done_head)) {
buf = list_first_entry(&tools_vdev->buf_done_head,
struct rkcif_rx_buffer, list);
if (buf)
list_del(&buf->list);
}
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
wake_up(&tools_vdev->wq_stopped);
return;
}
if (!list_empty(&tools_vdev->buf_head)) {
tools_vdev->curr_buf = list_first_entry(&tools_vdev->buf_head,
struct rkcif_buffer, queue);
if (!tools_vdev->curr_buf || tools_vdev->state != RKCIF_STATE_STREAMING) {
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
if (!list_empty(&tools_vdev->buf_done_head)) {
spin_unlock_irqrestore(&stream->tools_vdev->vbq_lock, flags);
goto retry_done_rdbk_buf;
}
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
return;
}
list_del(&tools_vdev->curr_buf->queue);
/* Dequeue a filled buffer */
for (i = 0; i < fmt->mplanes; i++) {
u32 payload_size = tools_vdev->pixm.plane_fmt[i].sizeimage;
void *src = buf->dummy.vaddr;
void *dst = vb2_plane_vaddr(&tools_vdev->curr_buf->vb.vb2_buf, i);
if (!src || !dst)
break;
dma_sync_single_for_device(dev->dev,
buf->dummy.dma_addr,
buf->dummy.size,
DMA_FROM_DEVICE);
vb2_set_plane_payload(&tools_vdev->curr_buf->vb.vb2_buf, i,
payload_size);
memcpy(dst, src, payload_size);
}
tools_vdev->curr_buf->vb.sequence = buf->dbufs.sequence;
tools_vdev->curr_buf->vb.vb2_buf.timestamp = buf->dbufs.timestamp;
vb2_buffer_done(&tools_vdev->curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
tools_vdev->curr_buf = NULL;
}
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
if (!list_empty(&tools_vdev->buf_done_head)) {
spin_unlock_irqrestore(&stream->tools_vdev->vbq_lock, flags);
goto retry_done_rdbk_buf;
}
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
}
static void rkcif_tools_work(struct work_struct *work)
{
struct rkcif_tools_vdev *tools_vdev = container_of(work,
struct rkcif_tools_vdev,
work);
if (tools_vdev->stream->dma_en & RKCIF_DMAEN_BY_VICAP)
rkcif_tools_buf_done(tools_vdev);
else if (tools_vdev->stream->dma_en & RKCIF_DMAEN_BY_ISP)
rkcif_tools_buf_done_rdbk(tools_vdev);
}
void rkcif_init_tools_vdev(struct rkcif_device *cif_dev, u32 ch)
{
struct rkcif_tools_vdev *tools_vdev = &cif_dev->tools_vdev[ch];

View File

@@ -193,6 +193,7 @@ struct rkcif_buffer {
struct rkcif_tools_buffer {
struct vb2_v4l2_buffer *vb;
struct rkisp_rx_buf *dbufs;
struct list_head list;
u32 frame_idx;
u64 timestamp;
@@ -526,7 +527,7 @@ struct rkcif_stream {
unsigned int cur_stream_mode;
struct rkcif_rx_buffer rx_buf[RKISP_VICAP_BUF_CNT_MAX];
struct list_head rx_buf_head;
int buf_num_toisp;
int total_buf_num;
u64 line_int_cnt;
int lack_buf_cnt;
unsigned int buf_wake_up_cnt;

View File

@@ -376,6 +376,11 @@ static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f)
atomic_read(&dev->stream[1].buf_cnt),
atomic_read(&dev->stream[2].buf_cnt),
atomic_read(&dev->stream[3].buf_cnt));
seq_printf(f, "total buf_cnt: %d %d %d %d\n",
dev->stream[0].total_buf_num,
dev->stream[1].total_buf_num,
dev->stream[2].total_buf_num,
dev->stream[3].total_buf_num);
}
}

View File

@@ -781,8 +781,8 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
rx_buf = to_cif_rx_buf(dbufs);
spin_lock_irqsave(&stream->vbq_lock, flags);
stream->buf_num_toisp++;
stream->last_rx_buf_idx = dbufs->sequence + 1;
atomic_inc(&stream->buf_cnt);
if (!list_empty(&stream->rx_buf_head) &&
cif_dev->is_thunderboot &&
@@ -791,6 +791,8 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);
list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
spin_unlock_irqrestore(&cif_dev->buffree_lock, buffree_flags);
atomic_dec(&stream->buf_cnt);
stream->total_buf_num--;
schedule_work(&priv->buffree_work.work);
is_free = true;
}