From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
kernel/drivers/media/platform/rockchip/cif/capture.c | 960 +++++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 723 insertions(+), 237 deletions(-)
diff --git a/kernel/drivers/media/platform/rockchip/cif/capture.c b/kernel/drivers/media/platform/rockchip/cif/capture.c
index 0a557bd..983d675 100644
--- a/kernel/drivers/media/platform/rockchip/cif/capture.c
+++ b/kernel/drivers/media/platform/rockchip/cif/capture.c
@@ -847,11 +847,13 @@
}
const struct
-cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd, struct v4l2_rect *rect,
+cif_input_fmt *rkcif_get_input_fmt(struct rkcif_device *dev, struct v4l2_rect *rect,
u32 pad_id, struct csi_channel_info *csi_info)
{
struct v4l2_subdev_format fmt;
+ struct v4l2_subdev *sd = dev->terminal_sensor.sd;
struct rkmodule_channel_info ch_info = {0};
+ struct rkmodule_capture_info capture_info;
int ret;
u32 i;
@@ -909,7 +911,26 @@
rect->top = 0;
rect->width = fmt.format.width;
rect->height = fmt.format.height;
-
+ ret = v4l2_subdev_call(sd,
+ core, ioctl,
+ RKMODULE_GET_CAPTURE_MODE,
+ &capture_info);
+ if (!ret) {
+ if (capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
+ dev->hw_dev->is_rk3588s2) {
+ for (i = 0; i < capture_info.multi_dev.dev_num; i++) {
+ if (capture_info.multi_dev.dev_idx[i] == 0)
+ capture_info.multi_dev.dev_idx[i] = 2;
+ else if (capture_info.multi_dev.dev_idx[i] == 2)
+ capture_info.multi_dev.dev_idx[i] = 4;
+ else if (capture_info.multi_dev.dev_idx[i] == 3)
+ capture_info.multi_dev.dev_idx[i] = 5;
+ }
+ }
+ csi_info->capture_info = capture_info;
+ } else {
+ csi_info->capture_info.mode = RKMODULE_CAPTURE_MODE_NONE;
+ }
for (i = 0; i < ARRAY_SIZE(in_fmts); i++)
if (fmt.format.code == in_fmts[i].mbus_code &&
fmt.format.field == in_fmts[i].field)
@@ -1594,7 +1615,7 @@
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
@@ -1670,6 +1691,20 @@
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 +1769,12 @@
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 +1813,10 @@
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;
}
@@ -1783,14 +1828,51 @@
spin_unlock_irqrestore(&dev->hdr_lock, flags);
}
+static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream,
+ u32 frm_addr_y, u32 frm_addr_uv,
+ u32 buff_addr_y, u32 buff_addr_cbcr,
+ bool is_dummy_buf)
+{
+ struct rkcif_device *dev = stream->cifdev;
+ struct rkmodule_capture_info *capture_info = &dev->channels[stream->id].capture_info;
+ u32 addr_y, addr_cbcr;
+ int addr_offset = 0;
+ int i = 0;
+ int tmp_host_index = dev->csi_host_idx;
+
+ for (i = 0; i < capture_info->multi_dev.dev_num; i++) {
+ if (is_dummy_buf) {
+ addr_y = buff_addr_y;
+ } else {
+ addr_offset = dev->channels[stream->id].left_virtual_width;
+ addr_y = buff_addr_y + addr_offset * i;
+ }
+ dev->csi_host_idx = capture_info->multi_dev.dev_idx[i];
+ rkcif_write_register(dev, frm_addr_y, addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW &&
+ frm_addr_uv && buff_addr_cbcr) {
+ if (is_dummy_buf) {
+ addr_cbcr = buff_addr_cbcr;
+ } else {
+ addr_offset = dev->channels[stream->id].left_virtual_width;
+ addr_cbcr = buff_addr_cbcr + addr_offset * i;
+ }
+ rkcif_write_register(dev, frm_addr_uv, addr_cbcr);
+ }
+ }
+ dev->csi_host_idx = tmp_host_index;
+}
+
static void rkcif_assign_new_buffer_init_toisp(struct rkcif_stream *stream,
int channel_id)
{
struct rkcif_device *dev = stream->cifdev;
struct rkcif_rx_buffer *rx_buf;
struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus;
+ struct rkmodule_capture_info *capture_info = &dev->channels[channel_id].capture_info;
u32 frm0_addr_y;
u32 frm1_addr_y;
+ u32 buff_addr_y;
unsigned long flags;
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
@@ -1817,9 +1899,15 @@
}
}
- if (stream->curr_buf_toisp)
- rkcif_write_register(dev, frm0_addr_y,
- stream->curr_buf_toisp->dummy.dma_addr);
+ if (stream->curr_buf_toisp) {
+ buff_addr_y = stream->curr_buf_toisp->dummy.dma_addr;
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream, frm0_addr_y, 0,
+ buff_addr_y, 0, false);
+ } else {
+ rkcif_write_register(dev, frm0_addr_y, buff_addr_y);
+ }
+ }
if (!stream->next_buf_toisp) {
if (!list_empty(&stream->rx_buf_head)) {
@@ -1836,9 +1924,15 @@
}
}
- if (stream->next_buf_toisp)
- rkcif_write_register(dev, frm1_addr_y,
- stream->next_buf_toisp->dummy.dma_addr);
+ if (stream->next_buf_toisp) {
+ buff_addr_y = stream->next_buf_toisp->dummy.dma_addr;
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream, frm1_addr_y, 0,
+ buff_addr_y, 0, false);
+ } else {
+ rkcif_write_register(dev, frm1_addr_y, buff_addr_y);
+ }
+ }
spin_unlock_irqrestore(&stream->vbq_lock, flags);
stream->buf_owner = RKCIF_DMAEN_BY_ISP;
@@ -1849,10 +1943,11 @@
{
struct rkcif_device *dev = stream->cifdev;
struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus;
+ struct rkmodule_capture_info *capture_info = &dev->channels[channel_id].capture_info;
struct rkcif_rx_buffer *buffer = NULL;
struct rkcif_rx_buffer *active_buf = NULL;
struct sditf_priv *priv = dev->sditf[0];
- u32 frm_addr_y;
+ u32 frm_addr_y, buff_addr_y;
unsigned long flags;
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
@@ -1889,14 +1984,18 @@
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 +2017,18 @@
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 +2070,14 @@
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,13 +2085,20 @@
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:
stream->frame_phase_cache = stream->frame_phase;
if (buffer) {
- rkcif_write_register(dev, frm_addr_y,
- buffer->dummy.dma_addr);
+ buff_addr_y = buffer->dummy.dma_addr;
+ if (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 (dev->rdbk_debug > 1 &&
stream->frame_idx < 15)
v4l2_info(&dev->v4l2_dev,
@@ -1994,8 +2108,13 @@
frm_addr_y, (u32)buffer->dummy.dma_addr);
} else if (dev->hw_dev->dummy_buf.vaddr && priv &&
priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
- rkcif_write_register(dev, frm_addr_y,
- dev->hw_dev->dummy_buf.dma_addr);
+ buff_addr_y = dev->hw_dev->dummy_buf.dma_addr;
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream, frm_addr_y, 0,
+ buff_addr_y, 0, true);
+ } else {
+ rkcif_write_register(dev, frm_addr_y, buff_addr_y);
+ }
}
spin_unlock_irqrestore(&stream->vbq_lock, flags);
return 0;
@@ -2018,8 +2137,9 @@
struct rkcif_device *dev = stream->cifdev;
struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus;
struct rkcif_rx_buffer *buffer = NULL;
+ struct rkmodule_capture_info *capture_info = &dev->channels[stream->id].capture_info;
struct rkcif_rx_buffer *active_buf = NULL;
- u32 frm_addr_y;
+ u32 frm_addr_y, buff_addr_y;
u32 vblank = 0;
u32 vblank_ns = 0;
u64 cur_time = 0;
@@ -2082,8 +2202,15 @@
if (buffer) {
list_del(&buffer->list);
stream->curr_buf_toisp = buffer;
- rkcif_write_register(dev, frm_addr_y,
- stream->curr_buf_toisp->dummy.dma_addr);
+ buff_addr_y = stream->curr_buf_toisp->dummy.dma_addr;
+ if (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 (dev->rdbk_debug > 1 &&
stream->frame_idx < 15)
v4l2_info(&dev->v4l2_dev,
@@ -2091,7 +2218,6 @@
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;
@@ -2100,8 +2226,15 @@
if (buffer) {
list_del(&buffer->list);
stream->next_buf_toisp = buffer;
- rkcif_write_register(dev, frm_addr_y,
- stream->next_buf_toisp->dummy.dma_addr);
+ buff_addr_y = stream->next_buf_toisp->dummy.dma_addr;
+ if (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 (dev->rdbk_debug > 1 &&
stream->frame_idx < 15)
v4l2_info(&dev->v4l2_dev,
@@ -2109,7 +2242,6 @@
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)
@@ -2150,8 +2282,13 @@
stream->next_buf_toisp = stream->curr_buf_toisp;
else
stream->curr_buf_toisp = stream->next_buf_toisp;
- rkcif_write_register(dev, frm_addr_y,
- stream->curr_buf_toisp->dummy.dma_addr);
+ buff_addr_y = stream->curr_buf_toisp->dummy.dma_addr;
+ if (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);
+ }
}
}
@@ -2162,6 +2299,7 @@
struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus;
u32 frm0_addr_y, frm0_addr_uv;
u32 frm1_addr_y, frm1_addr_uv;
+ u32 buff_addr_y, buff_addr_cbcr;
unsigned long flags;
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
struct csi_channel_info *channel = &dev->channels[channel_id];
@@ -2187,21 +2325,45 @@
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);
}
}
if (stream->curr_buf) {
- rkcif_write_register(dev, frm0_addr_y,
- stream->curr_buf->buff_addr[RKCIF_PLANE_Y]);
- if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
- rkcif_write_register(dev, frm0_addr_uv,
- stream->curr_buf->buff_addr[RKCIF_PLANE_CBCR]);
+ buff_addr_y = stream->curr_buf->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = stream->curr_buf->buff_addr[RKCIF_PLANE_CBCR];
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm0_addr_y,
+ frm0_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm0_addr_y,
+ stream->curr_buf->buff_addr[RKCIF_PLANE_Y]);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm0_addr_uv,
+ stream->curr_buf->buff_addr[RKCIF_PLANE_CBCR]);
+ }
} else {
if (dummy_buf->vaddr) {
- rkcif_write_register(dev, frm0_addr_y, dummy_buf->dma_addr);
- if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
- rkcif_write_register(dev, frm0_addr_uv, dummy_buf->dma_addr);
+ buff_addr_y = dummy_buf->dma_addr;
+ buff_addr_cbcr = dummy_buf->dma_addr;
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm0_addr_y,
+ frm0_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ true);
+ } else {
+ rkcif_write_register(dev, frm0_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm0_addr_uv, buff_addr_cbcr);
+ }
} else {
if (stream->lack_buf_cnt < 2)
stream->lack_buf_cnt++;
@@ -2211,43 +2373,69 @@
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
stream->next_buf = stream->curr_buf;
if (stream->next_buf) {
- rkcif_write_register(dev, frm1_addr_y,
- stream->next_buf->buff_addr[RKCIF_PLANE_Y] + (channel->virtual_width / 2));
- if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
- rkcif_write_register(dev, frm1_addr_uv,
- stream->next_buf->buff_addr[RKCIF_PLANE_CBCR] + (channel->virtual_width / 2));
+ buff_addr_y = stream->next_buf->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = stream->next_buf->buff_addr[RKCIF_PLANE_CBCR];
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm1_addr_y,
+ frm1_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm1_addr_y,
+ buff_addr_y + (channel->virtual_width / 2));
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm1_addr_uv,
+ buff_addr_cbcr + (channel->virtual_width / 2));
+ }
}
} else {
if (!stream->next_buf) {
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);
}
}
- if (stream->next_buf) {
- rkcif_write_register(dev, frm1_addr_y,
- stream->next_buf->buff_addr[RKCIF_PLANE_Y]);
- if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
- rkcif_write_register(dev, frm1_addr_uv,
- stream->next_buf->buff_addr[RKCIF_PLANE_CBCR]);
- } else {
- if (dummy_buf->vaddr) {
+ if (!stream->next_buf && dummy_buf->vaddr) {
+ buff_addr_y = dummy_buf->dma_addr;
+ buff_addr_cbcr = dummy_buf->dma_addr;
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm1_addr_y,
+ frm1_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ true);
+ } else {
rkcif_write_register(dev, frm1_addr_y, dummy_buf->dma_addr);
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
rkcif_write_register(dev, frm1_addr_uv, dummy_buf->dma_addr);
+ }
+
+ } else if (!stream->next_buf && stream->curr_buf) {
+ stream->next_buf = stream->curr_buf;
+ if (stream->lack_buf_cnt < 2)
+ stream->lack_buf_cnt++;
+ }
+ if (stream->next_buf) {
+ buff_addr_y = stream->next_buf->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = stream->next_buf->buff_addr[RKCIF_PLANE_CBCR];
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm1_addr_y,
+ frm1_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
} else {
- if (stream->curr_buf) {
- stream->next_buf = stream->curr_buf;
- rkcif_write_register(dev, frm1_addr_y,
- stream->next_buf->buff_addr[RKCIF_PLANE_Y]);
- if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
- rkcif_write_register(dev, frm1_addr_uv,
- stream->next_buf->buff_addr[RKCIF_PLANE_CBCR]);
- }
- if (stream->lack_buf_cnt < 2)
- stream->lack_buf_cnt++;
+ rkcif_write_register(dev, frm1_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm1_addr_uv, buff_addr_cbcr);
}
}
}
@@ -2295,6 +2483,7 @@
struct rkisp_rx_buf *dbufs = NULL;
struct dma_buf *dbuf = NULL;
int ret = 0;
+ u32 buff_addr_y, buff_addr_cbcr;
unsigned long flags;
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
@@ -2315,16 +2504,15 @@
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;
}
@@ -2347,8 +2535,8 @@
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)
@@ -2368,8 +2556,8 @@
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);
}
}
}
@@ -2407,19 +2595,37 @@
stream->frame_phase_cache = stream->frame_phase;
if (buffer) {
+ buff_addr_y = buffer->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = buffer->buff_addr[RKCIF_PLANE_CBCR];
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED &&
stream->frame_phase == CIF_CSI_FRAME1_READY) {
- rkcif_write_register(dev, frm_addr_y,
- buffer->buff_addr[RKCIF_PLANE_Y] + (channel->virtual_width / 2));
- if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
- rkcif_write_register(dev, frm_addr_uv,
- buffer->buff_addr[RKCIF_PLANE_CBCR] + (channel->virtual_width / 2));
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm_addr_y,
+ frm_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm_addr_y,
+ buff_addr_y + (channel->virtual_width / 2));
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm_addr_uv,
+ buff_addr_cbcr + (channel->virtual_width / 2));
+ }
} 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]);
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm_addr_y,
+ frm_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm_addr_uv, buff_addr_cbcr);
+ }
}
if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
if (stream->buf_replace_cnt < 2)
@@ -2439,12 +2645,16 @@
}
if (dbufs)
rkcif_s_rx_buffer(dev, dbufs);
- stream->buf_num_toisp--;
}
} else {
if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
- rkcif_write_register(dev, frm_addr_y,
- stream->curr_buf_toisp->dummy.dma_addr);
+ 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;
@@ -2460,7 +2670,6 @@
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)
@@ -2471,11 +2680,24 @@
stream->buf_replace_cnt--;
}
} else if (dummy_buf->vaddr) {
- 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);
+
+ 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;
@@ -2489,8 +2711,13 @@
stop_dma:
if (stream->buf_replace_cnt) {
spin_lock_irqsave(&stream->vbq_lock, flags);
- rkcif_write_register(dev, frm_addr_y,
- stream->curr_buf_toisp->dummy.dma_addr);
+ 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;
@@ -2507,15 +2734,12 @@
}
if (dbufs)
rkcif_s_rx_buffer(dev, dbufs);
- stream->buf_num_toisp--;
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--;
@@ -2587,8 +2811,10 @@
struct rkcif_device *dev = stream->cifdev;
struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
struct v4l2_mbus_config *mbus_cfg = &dev->active_sensor->mbus;
+ struct rkmodule_capture_info *capture_info = &dev->channels[stream->id].capture_info;
struct rkcif_buffer *buffer = NULL;
u32 frm_addr_y, frm_addr_uv;
+ u32 buff_addr_y, buff_addr_cbcr;
int channel_id = stream->id;
int ret = 0;
unsigned long flags;
@@ -2619,16 +2845,35 @@
}
spin_unlock_irqrestore(&stream->vbq_lock, flags);
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]);
+ buff_addr_y = buffer->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = buffer->buff_addr[RKCIF_PLANE_CBCR];
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream, frm_addr_y,
+ frm_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm_addr_uv, buff_addr_cbcr);
+ }
} else {
if (dummy_buf->vaddr) {
- 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);
+ buff_addr_y = dummy_buf->dma_addr;
+ buff_addr_cbcr = dummy_buf->dma_addr;
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ 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, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev, frm_addr_uv, buff_addr_cbcr);
+ }
} else {
if (dev->chip_id < CHIP_RK3588_CIF)
ret = -EINVAL;
@@ -3163,6 +3408,7 @@
struct csi_channel_info *channel)
{
struct rkcif_device *dev = stream->cifdev;
+ struct sditf_priv *priv = dev->sditf[0];
const struct cif_output_fmt *fmt;
u32 fourcc;
int vc = dev->channels[stream->id].vc;
@@ -3187,7 +3433,7 @@
channel->crop_st_x = stream->crop[CROP_SRC_ACT].left;
channel->crop_st_y = stream->crop[CROP_SRC_ACT].top;
- if (dev->sditf_cnt > 1 && dev->sditf_cnt <= RKCIF_MAX_SDITF)
+ if (priv && priv->is_combine_mode && dev->sditf_cnt <= RKCIF_MAX_SDITF)
channel->crop_st_y *= dev->sditf_cnt;
channel->width = stream->crop[CROP_SRC_ACT].width;
channel->height = stream->crop[CROP_SRC_ACT].height;
@@ -3197,7 +3443,7 @@
channel->crop_en = 0;
}
- if (dev->sditf_cnt > 1 && dev->sditf_cnt <= RKCIF_MAX_SDITF)
+ if (priv && priv->is_combine_mode && dev->sditf_cnt <= RKCIF_MAX_SDITF)
channel->height *= dev->sditf_cnt;
fmt = rkcif_find_output_fmt(stream, stream->pixm.pixelformat);
@@ -3207,6 +3453,8 @@
return -EINVAL;
}
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
+ channel->width /= channel->capture_info.multi_dev.dev_num;
/*
* for mipi or lvds, when enable compact, the virtual width of raw10/raw12
* needs aligned with :ALIGN(bits_per_pixel * width / 8, 8), if enable 16bit mode
@@ -3216,9 +3464,19 @@
if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact &&
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888 &&
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB565) {
- channel->virtual_width = ALIGN(channel->width * fmt->raw_bpp / 8, 256);
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ channel->virtual_width = ALIGN(channel->width * 2 * fmt->raw_bpp / 8, 256);
+ channel->left_virtual_width = channel->width * fmt->raw_bpp / 8;
+ } else {
+ channel->virtual_width = ALIGN(channel->width * fmt->raw_bpp / 8, 256);
+ }
} else {
- channel->virtual_width = ALIGN(channel->width * fmt->bpp[0] / 8, 8);
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ channel->virtual_width = ALIGN(channel->width * 2 * fmt->bpp[0] / 8, 8);
+ channel->left_virtual_width = ALIGN(channel->width * fmt->bpp[0] / 8, 8);
+ } else {
+ channel->virtual_width = ALIGN(channel->width * fmt->bpp[0] / 8, 8);
+ }
}
if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888 || channel->fmt_val == CSI_WRDDR_TYPE_RGB565)
@@ -3237,6 +3495,8 @@
channel->width *= 2;
}
channel->virtual_width *= 2;
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
+ channel->left_virtual_width *= 2;
}
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
channel->virtual_width *= 2;
@@ -3585,15 +3845,18 @@
/*config reg for rk3588*/
static int rkcif_csi_channel_set_v1(struct rkcif_stream *stream,
- struct csi_channel_info *channel,
- enum v4l2_mbus_type mbus_type, unsigned int mode)
+ struct csi_channel_info *channel,
+ enum v4l2_mbus_type mbus_type, unsigned int mode,
+ int index)
{
unsigned int val = 0x0;
struct rkcif_device *dev = stream->cifdev;
struct rkcif_stream *detect_stream = &dev->stream[0];
struct sditf_priv *priv = dev->sditf[0];
+ struct rkmodule_capture_info *capture_info = &channel->capture_info;
unsigned int wait_line = 0x3fff;
unsigned int dma_en = 0;
+ int offset = 0;
if (channel->id >= 4)
return -EINVAL;
@@ -3609,21 +3872,28 @@
CSI_DMA_END_INTSTAT(channel->id) |
CSI_LINE_INTSTAT_V1(channel->id)));
- rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
- CSI_START_INTEN(channel->id));
+ if (!(capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
+ index < capture_info->multi_dev.dev_num - 1)) {
- if (priv && priv->mode.rdbk_mode && detect_stream->is_line_wake_up) {
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
- CSI_LINE_INTEN_RK3588(channel->id));
- wait_line = dev->wait_line;
- }
- rkcif_write_register(dev, CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1,
- wait_line << 16 | wait_line);
- rkcif_write_register(dev, CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3,
- wait_line << 16 | wait_line);
+ CSI_START_INTEN(channel->id));
- rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
- CSI_DMA_END_INTEN(channel->id));
+ if (priv && priv->mode.rdbk_mode && detect_stream->is_line_wake_up) {
+ rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
+ CSI_LINE_INTEN_RK3588(channel->id));
+ wait_line = dev->wait_line;
+ }
+ rkcif_write_register(dev, CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1,
+ wait_line << 16 | wait_line);
+ rkcif_write_register(dev, CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3,
+ wait_line << 16 | wait_line);
+
+ rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
+ CSI_DMA_END_INTEN(channel->id));
+
+ rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
+ CSI_ALL_ERROR_INTEN_V1);
+ }
if (stream->cifdev->id_use_cnt == 0) {
val = CIF_MIPI_LVDS_SW_PRESS_VALUE_RK3588(0x3) |
CIF_MIPI_LVDS_SW_PRESS_ENABLE |
@@ -3637,24 +3907,25 @@
else
val |= CIF_MIPI_LVDS_SW_SEL_LVDS_RV1106;
rkcif_write_register(dev, CIF_REG_MIPI_LVDS_CTRL, val);
-
- rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
- CSI_ALL_ERROR_INTEN_V1);
}
#if IS_ENABLED(CONFIG_CPU_RV1106)
if (channel->id == 1)
rv1106_sdmmc_get_lock();
#endif
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
+ priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE &&
+ (dev->hdr.hdr_mode == NO_HDR ||
+ (dev->hdr.hdr_mode == HDR_X2 && stream->id == 1) ||
+ (dev->hdr.hdr_mode == HDR_X3 && stream->id == 2)))
+ offset = channel->capture_info.multi_dev.pixel_offset;
+
rkcif_write_register(dev, get_reg_index_of_id_ctrl1(channel->id),
- channel->width | (channel->height << 16));
+ (channel->width + offset) | (channel->height << 16));
#if IS_ENABLED(CONFIG_CPU_RV1106)
if (channel->id == 1)
rv1106_sdmmc_put_lock();
#endif
-
- rkcif_write_register(dev, get_reg_index_of_frm0_y_vlw(channel->id),
- channel->virtual_width);
if (channel->crop_en)
rkcif_write_register(dev, get_reg_index_of_id_crop_start(channel->id),
@@ -3673,6 +3944,17 @@
rkcif_assign_new_buffer_pingpong_rockit(stream,
RKCIF_YUV_ADDR_STATE_INIT,
channel->id);
+
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
+ index == (capture_info->multi_dev.dev_num - 1) &&
+ priv && priv->mode.rdbk_mode != RKISP_VICAP_ONLINE)
+ rkcif_write_register(dev, get_reg_index_of_id_crop_start(channel->id),
+ channel->crop_st_y << 16 |
+ (channel->crop_st_x + capture_info->multi_dev.pixel_offset));
+
+ rkcif_write_register(dev, get_reg_index_of_frm0_y_vlw(channel->id),
+ channel->virtual_width);
+
if (stream->lack_buf_cnt == 2)
stream->dma_en = 0;
@@ -3735,7 +4017,24 @@
}
if (dev->chip_id >= CHIP_RV1106_CIF)
rkcif_modify_frame_skip_config(stream);
- stream->cifdev->id_use_cnt++;
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ if (index == (capture_info->multi_dev.dev_num - 1))
+ stream->cifdev->id_use_cnt++;
+ } else {
+ stream->cifdev->id_use_cnt++;
+ }
+ if (!(capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
+ index < capture_info->multi_dev.dev_num - 1)) {
+ if (mode == RKCIF_STREAM_MODE_CAPTURE)
+ rkcif_assign_new_buffer_pingpong(stream,
+ RKCIF_YUV_ADDR_STATE_INIT,
+ channel->id);
+ else if (mode == RKCIF_STREAM_MODE_TOISP ||
+ mode == RKCIF_STREAM_MODE_TOISP_RDBK)
+ rkcif_assign_new_buffer_pingpong_toisp(stream,
+ RKCIF_YUV_ADDR_STATE_INIT,
+ channel->id);
+ }
return 0;
}
@@ -3747,6 +4046,7 @@
enum v4l2_mbus_type mbus_type = active_sensor->mbus.type;
struct csi_channel_info *channel;
u32 ret = 0;
+ int i;
if (stream->state < RKCIF_STATE_STREAMING) {
stream->frame_idx = 0;
@@ -3785,10 +4085,18 @@
} else if (mode == RKCIF_STREAM_MODE_ROCKIT) {
stream->dma_en |= RKCIF_DMAEN_BY_ROCKIT;
}
- if (stream->cifdev->chip_id < CHIP_RK3588_CIF)
+ if (stream->cifdev->chip_id < CHIP_RK3588_CIF) {
rkcif_csi_channel_set(stream, channel, mbus_type);
- else
- rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode);
+ } else {
+ if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ for (i = 0; i < channel->capture_info.multi_dev.dev_num; i++) {
+ dev->csi_host_idx = channel->capture_info.multi_dev.dev_idx[i];
+ rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode, i);
+ }
+ } else {
+ rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode, 0);
+ }
+ }
} else {
if (stream->cifdev->chip_id >= CHIP_RK3588_CIF) {
if (mode == RKCIF_STREAM_MODE_CAPTURE) {
@@ -3828,7 +4136,9 @@
struct v4l2_mbus_config *mbus_cfg = &cif_dev->active_sensor->mbus;
u32 val;
int id;
+ int i = 0;
+ stream->cifdev->id_use_cnt--;
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
mbus_cfg->type == V4L2_MBUS_CCP2) {
@@ -3840,7 +4150,14 @@
else
val &= ~LVDS_ENABLE_CAPTURE;
- rkcif_write_register(cif_dev, get_reg_index_of_id_ctrl0(id), val);
+ if (cif_dev->channels[id].capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ for (i = 0; i < cif_dev->channels[id].capture_info.multi_dev.dev_num; i++) {
+ cif_dev->csi_host_idx = cif_dev->channels[id].capture_info.multi_dev.dev_idx[i];
+ rkcif_write_register(cif_dev, get_reg_index_of_id_ctrl0(id), val);
+ }
+ } else {
+ rkcif_write_register(cif_dev, get_reg_index_of_id_ctrl0(id), val);
+ }
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT,
CSI_START_INTSTAT(id) |
@@ -3859,8 +4176,16 @@
if (stream->cifdev->id_use_cnt == 0) {
rkcif_write_register_and(cif_dev, CIF_REG_MIPI_LVDS_INTEN,
~CSI_ALL_ERROR_INTEN_V1);
- rkcif_write_register_and(cif_dev, CIF_REG_MIPI_LVDS_CTRL,
- ~CSI_ENABLE_CAPTURE);
+ if (cif_dev->channels[id].capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ for (i = 0; i < cif_dev->channels[id].capture_info.multi_dev.dev_num; i++) {
+ cif_dev->csi_host_idx = cif_dev->channels[id].capture_info.multi_dev.dev_idx[i];
+ rkcif_write_register_and(cif_dev, CIF_REG_MIPI_LVDS_CTRL,
+ ~CSI_ENABLE_CAPTURE);
+ }
+ } else {
+ rkcif_write_register_and(cif_dev, CIF_REG_MIPI_LVDS_CTRL,
+ ~CSI_ENABLE_CAPTURE);
+ }
}
}
@@ -3876,7 +4201,6 @@
rkcif_config_dvp_pin(cif_dev, false);
}
}
- stream->cifdev->id_use_cnt--;
stream->state = RKCIF_STATE_READY;
stream->dma_en = 0;
}
@@ -3955,7 +4279,7 @@
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);
@@ -3973,6 +4297,8 @@
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;
+ u32 buff_addr_y = 0, buff_addr_cbcr = 0;
+ struct rkmodule_capture_info *capture_info = &dev->channels[channel_id].capture_info;
unsigned long flags;
int frame_phase = 0;
bool is_dual_update_buf = false;
@@ -4039,22 +4365,51 @@
}
if (buffer) {
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]);
+ buff_addr_y = buffer->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = buffer->buff_addr[RKCIF_PLANE_CBCR];
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm0_addr_y,
+ frm0_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm1_addr_y,
+ frm1_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm0_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev,
+ frm0_addr_uv,
+ buff_addr_cbcr);
+ rkcif_write_register(dev, frm1_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev,
+ frm1_addr_uv,
+ buff_addr_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]);
+
+ buff_addr_y = buffer->buff_addr[RKCIF_PLANE_Y];
+ buff_addr_cbcr = buffer->buff_addr[RKCIF_PLANE_CBCR];
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ rkcif_write_buff_addr_multi_dev_combine(stream,
+ frm_addr_y,
+ frm_addr_uv,
+ buff_addr_y,
+ buff_addr_cbcr,
+ false);
+ } else {
+ rkcif_write_register(dev, frm_addr_y, buff_addr_y);
+ if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
+ rkcif_write_register(dev,
+ frm_addr_uv,
+ buff_addr_cbcr);
+ }
}
}
} else {
@@ -4065,11 +4420,17 @@
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);
}
@@ -4098,6 +4459,7 @@
}
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);
@@ -4200,6 +4562,7 @@
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
"stream[%d] buf queue, index: %d, dma_addr 0x%x\n",
stream->id, vb->index, cifbuf->buff_addr[0]);
+ atomic_inc(&stream->buf_cnt);
}
void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num)
@@ -4229,6 +4592,8 @@
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) {
@@ -4322,7 +4687,6 @@
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) {
@@ -4338,7 +4702,8 @@
(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;
@@ -4352,6 +4717,7 @@
struct rkcif_dummy_buffer *dummy_buf = &hw->dummy_buf;
struct rkcif_device *tmp_dev = NULL;
struct v4l2_subdev_frame_interval_enum fie;
+ struct v4l2_subdev_format fmt;
u32 max_size = 0;
u32 size = 0;
int ret = 0;
@@ -4386,6 +4752,21 @@
continue;
}
}
+
+ if (max_size == 0 && dev->terminal_sensor.sd) {
+ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(dev->terminal_sensor.sd,
+ pad, get_fmt, NULL, &fmt);
+ if (!ret) {
+ if (fmt.format.code == MEDIA_BUS_FMT_RGB888_1X24)
+ size = fmt.format.width * fmt.format.height * 3;
+ else
+ size = fmt.format.width * fmt.format.height * 2;
+ if (size > max_size)
+ max_size = size;
+ }
+ }
+
dummy_buf->size = max_size;
dummy_buf->is_need_vaddr = true;
@@ -4621,14 +5002,16 @@
} 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) {
@@ -4664,6 +5047,8 @@
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;
}
@@ -4704,10 +5089,12 @@
dev->wait_line = 0;
stream->is_line_wake_up = false;
}
- tasklet_disable(&stream->vb_done_tasklet);
+ if (can_reset && hw_dev->dummy_buf.vaddr)
+ rkcif_destroy_dummy_buf(stream);
}
- if (can_reset && hw_dev->dummy_buf.vaddr)
- rkcif_destroy_dummy_buf(stream);
+ if (mode == RKCIF_STREAM_MODE_CAPTURE)
+ tasklet_disable(&stream->vb_done_tasklet);
+
stream->cur_stream_mode &= ~mode;
INIT_LIST_HEAD(&stream->vb_done_list);
v4l2_info(&dev->v4l2_dev, "stream[%d] stopping finished, dma_en 0x%x\n", stream->id, stream->dma_en);
@@ -4981,6 +5368,7 @@
stream->crop_mask |= CROP_SRC_SENSOR_MASK;
dev->terminal_sensor.selection = input_sel;
} else {
+ stream->crop_mask &= ~CROP_SRC_SENSOR_MASK;
dev->terminal_sensor.selection.r = dev->terminal_sensor.raw_rect;
}
}
@@ -5001,8 +5389,10 @@
stream->crop[CROP_SRC_ACT].top = stream->crop[CROP_SRC_USR].top +
stream->crop[CROP_SRC_SENSOR].top;
}
- } else {
+ } else if (stream->crop_mask & CROP_SRC_SENSOR_MASK) {
stream->crop[CROP_SRC_ACT] = stream->crop[CROP_SRC_SENSOR];
+ } else {
+ stream->crop[CROP_SRC_ACT] = dev->terminal_sensor.raw_rect;
}
}
@@ -5018,9 +5408,9 @@
struct v4l2_rect input, *crop;
if (dev->terminal_sensor.sd) {
- stream->cif_fmt_in = get_input_fmt(dev->terminal_sensor.sd,
- &input, stream->id,
- &dev->channels[stream->id]);
+ stream->cif_fmt_in = rkcif_get_input_fmt(dev,
+ &input, stream->id,
+ &dev->channels[stream->id]);
if (!stream->cif_fmt_in) {
v4l2_err(v4l2_dev, "Input fmt is invalid\n");
return -EINVAL;
@@ -5562,6 +5952,7 @@
{
struct rkcif_hw *hw = cifdev->hw_dev;
struct rkcif_device *dev;
+ struct sditf_priv *priv;
int i = 0, j = 0;
int ret = 0;
int count = 0;
@@ -5610,12 +6001,12 @@
else
sync_cfg.group = 0;
}
+ cifdev->sync_cfg = sync_cfg;
if (sync_cfg.type == NO_SYNC_MODE ||
hw->sync_config[sync_cfg.group].is_attach) {
mutex_unlock(&hw->dev_lock);
return;
}
- cifdev->sync_cfg = sync_cfg;
sync_config = &hw->sync_config[sync_cfg.group];
memset(sync_config, 0, sizeof(struct rkcif_multi_sync_config));
@@ -5639,26 +6030,31 @@
else
sync_cfg.group = 0;
} else {
- for (j = 0; j < dev->sditf_cnt; j++) {
- ret |= v4l2_subdev_call(dev->sditf[j]->sensor_sd,
- core, ioctl,
- RKMODULE_GET_SYNC_MODE,
- &sync_type);
- if (!ret && sync_type)
- break;
+ priv = dev->sditf[0];
+ if (priv && priv->is_combine_mode && dev->sditf_cnt <= RKCIF_MAX_SDITF) {
+ for (j = 0; j < dev->sditf_cnt; j++) {
+ ret |= v4l2_subdev_call(dev->sditf[j]->sensor_sd,
+ core, ioctl,
+ RKMODULE_GET_SYNC_MODE,
+ &sync_type);
+ if (!ret && sync_type) {
+ priv = dev->sditf[j];
+ break;
+ }
+ }
+ if (!ret)
+ sync_cfg.type = sync_type;
+ else
+ sync_cfg.type = NO_SYNC_MODE;
+ ret = v4l2_subdev_call(priv->sensor_sd,
+ core, ioctl,
+ RKMODULE_GET_GROUP_ID,
+ &sync_group);
+ if (!ret && sync_group < RKCIF_MAX_GROUP)
+ sync_cfg.group = sync_group;
+ else
+ sync_cfg.group = 0;
}
- if (!ret)
- sync_cfg.type = sync_type;
- else
- sync_cfg.type = NO_SYNC_MODE;
- ret = v4l2_subdev_call(dev->sditf[j]->sensor_sd,
- core, ioctl,
- RKMODULE_GET_GROUP_ID,
- &sync_group);
- if (!ret && sync_group < RKCIF_MAX_GROUP)
- sync_cfg.group = sync_group;
- else
- sync_cfg.group = 0;
}
if (sync_cfg.group == cifdev->sync_cfg.group) {
if (sync_cfg.type == EXTERNAL_MASTER_MODE) {
@@ -5681,6 +6077,11 @@
sync_config->sync_mask |= BIT(dev->csi_host_idx);
}
dev->sync_cfg = sync_cfg;
+ } else {
+ ret = v4l2_subdev_call(dev->terminal_sensor.sd,
+ core, ioctl,
+ RKMODULE_GET_SYNC_MODE,
+ &sync_type);
}
}
if (sync_config->int_master.count == 1) {
@@ -5714,15 +6115,18 @@
struct rkcif_hw *hw_dev = dev->hw_dev;
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
struct rkcif_sensor_info *sensor_info = dev->active_sensor;
- struct rkcif_sensor_info *terminal_sensor = &dev->terminal_sensor;
+ struct rkcif_sensor_info *terminal_sensor = NULL;
struct rkmodule_hdr_cfg hdr_cfg;
+ struct rkcif_csi_info csi_info = {0};
int rkmodule_stream_seq = RKMODULE_START_STREAM_DEFAULT;
int ret;
+ int i = 0;
v4l2_info(&dev->v4l2_dev, "stream[%d] start streaming\n", stream->id);
rkcif_attach_sync_mode(dev);
mutex_lock(&dev->stream_lock);
+
if ((stream->cur_stream_mode & RKCIF_STREAM_MODE_CAPTURE) == mode) {
ret = -EBUSY;
v4l2_err(v4l2_dev, "stream in busy state\n");
@@ -5735,7 +6139,7 @@
else
stream->is_line_inten = false;
- if (dev->active_sensor) {
+ if (!dev->active_sensor) {
ret = rkcif_update_sensor_info(stream);
if (ret < 0) {
v4l2_err(v4l2_dev,
@@ -5744,7 +6148,7 @@
goto out;
}
}
-
+ terminal_sensor = &dev->terminal_sensor;
if (terminal_sensor->sd) {
ret = v4l2_subdev_call(terminal_sensor->sd,
core, ioctl,
@@ -5775,6 +6179,39 @@
goto destroy_buf;
mutex_lock(&hw_dev->dev_lock);
+ if (atomic_read(&dev->pipe.stream_cnt) == 0 &&
+ dev->active_sensor &&
+ (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
+ dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY ||
+ dev->active_sensor->mbus.type == V4L2_MBUS_CCP2)) {
+ if (dev->channels[0].capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
+ csi_info.csi_num = dev->channels[0].capture_info.multi_dev.dev_num;
+ if (csi_info.csi_num > RKCIF_MAX_CSI_NUM) {
+ v4l2_err(v4l2_dev,
+ "csi num %d, max %d\n",
+ csi_info.csi_num, RKCIF_MAX_CSI_NUM);
+ goto out;
+ }
+ for (i = 0; i < csi_info.csi_num; i++) {
+ csi_info.csi_idx[i] = dev->channels[0].capture_info.multi_dev.dev_idx[i];
+ if (dev->hw_dev->is_rk3588s2)
+ v4l2_info(v4l2_dev, "rk3588s2 combine mode attach to mipi%d\n",
+ csi_info.csi_idx[i]);
+ }
+ } else {
+ csi_info.csi_num = 1;
+ dev->csi_host_idx = dev->csi_host_idx_def;
+ csi_info.csi_idx[0] = dev->csi_host_idx;
+ }
+ ret = v4l2_subdev_call(dev->active_sensor->sd,
+ core, ioctl,
+ RKCIF_CMD_SET_CSI_IDX,
+ &csi_info);
+ if (ret)
+ v4l2_err(&dev->v4l2_dev, "set csi idx %d fail\n", dev->csi_host_idx);
+
+ }
+
if (((dev->active_sensor && dev->active_sensor->mbus.type == V4L2_MBUS_BT656) ||
dev->is_use_dummybuf) &&
(!dev->hw_dev->dummy_buf.vaddr) &&
@@ -5788,8 +6225,10 @@
}
mutex_unlock(&hw_dev->dev_lock);
- if (stream->cur_stream_mode == RKCIF_STREAM_MODE_NONE) {
+ if (mode == RKCIF_STREAM_MODE_CAPTURE)
tasklet_enable(&stream->vb_done_tasklet);
+
+ if (stream->cur_stream_mode == RKCIF_STREAM_MODE_NONE) {
ret = dev->pipe.open(&dev->pipe, &node->vdev.entity, true);
if (ret < 0) {
v4l2_err(v4l2_dev, "open cif pipeline failed %d\n",
@@ -5807,7 +6246,7 @@
rkmodule_stream_seq == RKMODULE_START_STREAM_FRONT) {
ret = dev->pipe.set_stream(&dev->pipe, true);
if (ret < 0)
- goto runtime_put;
+ goto destroy_buf;
}
}
if (dev->chip_id >= CHIP_RK1808_CIF) {
@@ -5823,7 +6262,7 @@
}
if (ret < 0)
- goto runtime_put;
+ goto destroy_buf;
if (stream->cur_stream_mode == RKCIF_STREAM_MODE_NONE) {
ret = media_pipeline_start(&node->vdev.entity, &dev->pipe.pipe);
@@ -5869,15 +6308,19 @@
rkcif_stream_stop(stream);
pipe_stream_off:
dev->pipe.set_stream(&dev->pipe, false);
-runtime_put:
- pm_runtime_put_sync(dev->dev);
+
destroy_buf:
- if (stream->next_buf)
- vb2_buffer_done(&stream->next_buf->vb.vb2_buf,
- VB2_BUF_STATE_QUEUED);
+ if (mode == RKCIF_STREAM_MODE_CAPTURE)
+ tasklet_disable(&stream->vb_done_tasklet);
if (stream->curr_buf)
- vb2_buffer_done(&stream->curr_buf->vb.vb2_buf,
- VB2_BUF_STATE_QUEUED);
+ list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
+ if (stream->next_buf &&
+ stream->next_buf != stream->curr_buf)
+ list_add_tail(&stream->next_buf->queue, &stream->buf_head);
+
+ stream->curr_buf = NULL;
+ stream->next_buf = NULL;
+ atomic_set(&stream->buf_cnt, 0);
while (!list_empty(&stream->buf_head)) {
struct rkcif_buffer *buf;
@@ -5942,6 +6385,7 @@
bool try)
{
struct rkcif_device *dev = stream->cifdev;
+ struct sditf_priv *priv = dev->sditf[0];
const struct cif_output_fmt *fmt;
const struct cif_input_fmt *cif_fmt_in = NULL;
struct v4l2_rect input_rect;
@@ -5949,6 +6393,7 @@
u32 xsubs = 1, ysubs = 1, i;
struct rkmodule_hdr_cfg hdr_cfg;
struct rkcif_extend_info *extend_line = &stream->extend_line;
+ struct csi_channel_info *channel_info = &dev->channels[stream->id];
int ret;
for (i = 0; i < RKCIF_MAX_PLANE; i++)
@@ -5962,9 +6407,9 @@
input_rect.height = RKCIF_DEFAULT_HEIGHT;
if (dev->terminal_sensor.sd) {
- cif_fmt_in = get_input_fmt(dev->terminal_sensor.sd,
- &input_rect, stream->id,
- &dev->channels[stream->id]);
+ cif_fmt_in = rkcif_get_input_fmt(dev,
+ &input_rect, stream->id,
+ channel_info);
stream->cif_fmt_in = cif_fmt_in;
} else {
v4l2_err(&stream->cifdev->v4l2_dev,
@@ -6006,8 +6451,9 @@
planes = fmt->cplanes ? fmt->cplanes : fmt->mplanes;
- if (cif_fmt_in && (cif_fmt_in->mbus_code == MEDIA_BUS_FMT_SPD_2X8 ||
- cif_fmt_in->mbus_code == MEDIA_BUS_FMT_EBD_1X8))
+ if (cif_fmt_in &&
+ (cif_fmt_in->mbus_code == MEDIA_BUS_FMT_SPD_2X8 ||
+ cif_fmt_in->mbus_code == MEDIA_BUS_FMT_EBD_1X8))
stream->crop_enable = false;
for (i = 0; i < planes; i++) {
@@ -6032,7 +6478,7 @@
}
}
- if (dev->sditf_cnt > 1 && dev->sditf_cnt <= RKCIF_MAX_SDITF)
+ if (priv && priv->is_combine_mode && dev->sditf_cnt <= RKCIF_MAX_SDITF)
height *= dev->sditf_cnt;
extend_line->pixm.height = height + RKMODULE_EXTEND_LINE;
@@ -6042,8 +6488,9 @@
* to optimize reading and writing of ddr, aliged with 256.
*/
if (fmt->fmt_type == CIF_FMT_TYPE_RAW &&
- (stream->cif_fmt_in->mbus_code == MEDIA_BUS_FMT_EBD_1X8 ||
- stream->cif_fmt_in->mbus_code == MEDIA_BUS_FMT_SPD_2X8)) {
+ cif_fmt_in &&
+ (cif_fmt_in->mbus_code == MEDIA_BUS_FMT_EBD_1X8 ||
+ cif_fmt_in->mbus_code == MEDIA_BUS_FMT_SPD_2X8)) {
stream->is_compact = false;
}
@@ -6157,6 +6604,7 @@
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)
@@ -6184,6 +6632,7 @@
stream->buf_owner = 0;
stream->buf_replace_cnt = 0;
stream->is_stop_capture = false;
+ atomic_set(&stream->buf_cnt, 0);
}
static int rkcif_fh_open(struct file *filp)
@@ -6329,9 +6778,9 @@
input_rect.height = RKCIF_DEFAULT_HEIGHT;
if (dev->terminal_sensor.sd)
- get_input_fmt(dev->terminal_sensor.sd,
- &input_rect, stream->id,
- &csi_info);
+ rkcif_get_input_fmt(dev,
+ &input_rect, stream->id,
+ &csi_info);
if (dev->hw_dev->adapt_to_usbcamerahal) {
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
@@ -6410,7 +6859,7 @@
return -EINVAL;
if (dev->terminal_sensor.sd) {
- cif_fmt_in = get_input_fmt(dev->terminal_sensor.sd,
+ cif_fmt_in = rkcif_get_input_fmt(dev,
&input_rect, stream->id,
&dev->channels[stream->id]);
stream->cif_fmt_in = cif_fmt_in;
@@ -6796,8 +7245,8 @@
break;
case RKCIF_CMD_SET_CSI_MEMORY_MODE:
if (dev->terminal_sensor.sd) {
- in_fmt = get_input_fmt(dev->terminal_sensor.sd,
- &rect, 0, &csi_info);
+ in_fmt = rkcif_get_input_fmt(dev,
+ &rect, 0, &csi_info);
if (in_fmt == NULL) {
v4l2_err(&dev->v4l2_dev, "can't get sensor input format\n");
return -EINVAL;
@@ -6876,6 +7325,7 @@
v4l2_dbg(2, rkcif_debug, &stream->cifdev->v4l2_dev,
"stream[%d] vb done, index: %d, sequence %d\n", stream->id,
vb_done->vb2_buf.index, vb_done->sequence);
+ atomic_dec(&stream->buf_cnt);
}
static void rkcif_tasklet_handle(unsigned long data)
@@ -8147,7 +8597,11 @@
if (active_buf) {
vb_done = &active_buf->vb;
- vb_done->vb2_buf.timestamp = stream->readout.fs_timestamp;
+ 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;
active_buf->fe_timestamp = ktime_get_ns();
if (stream->is_line_wake_up) {
@@ -8308,8 +8762,10 @@
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);
@@ -8379,11 +8835,13 @@
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--;
+ }
}
}
}
@@ -8455,8 +8913,8 @@
if (!stream->is_line_wake_up) {
ret = rkcif_assign_new_buffer_pingpong(stream,
- RKCIF_YUV_ADDR_STATE_UPDATE,
- mipi_id);
+ RKCIF_YUV_ADDR_STATE_UPDATE,
+ mipi_id);
if (ret && cif_dev->chip_id < CHIP_RK3588_CIF)
return;
} else {
@@ -8464,6 +8922,10 @@
if (ret && cif_dev->chip_id < CHIP_RK3588_CIF)
return;
}
+ if (cif_dev->chip_id < CHIP_RK3588_CIF &&
+ cif_dev->active_sensor->mbus.type == V4L2_MBUS_BT656 &&
+ stream->id != 0)
+ stream->frame_idx++;
if (!stream->is_line_wake_up && stream->dma_en & RKCIF_DMAEN_BY_VICAP)
rkcif_buf_done_prepare(stream, active_buf, mipi_id, 0);
@@ -8590,6 +9052,7 @@
struct rkcif_sensor_info *terminal_sensor = &cif_dev->terminal_sensor;
struct rkcif_resume_info *resume_info = &cif_dev->reset_work.resume_info;
struct rkcif_timer *timer = &cif_dev->reset_watchdog_timer;
+ struct sditf_priv *priv = cif_dev->sditf[0];
int i, j, ret = 0;
u32 on, sof_cnt;
int capture_mode = 0;
@@ -8658,10 +9121,12 @@
__func__, on ? "on" : "off", p->subdevs[i]->name);
}
- for (i = 0; i < cif_dev->sditf_cnt; i++) {
- if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd)
- ret = v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, core, ioctl,
- RKMODULE_SET_QUICK_STREAM, &on);
+ if (priv && priv->is_combine_mode && cif_dev->sditf_cnt <= RKCIF_MAX_SDITF) {
+ for (i = 0; i < cif_dev->sditf_cnt; i++) {
+ if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd)
+ ret = v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, core, ioctl,
+ RKMODULE_SET_QUICK_STREAM, &on);
+ }
}
rockchip_clear_system_status(SYS_STATUS_CIF0);
@@ -8756,10 +9221,12 @@
p->subdevs[i]->name);
}
- for (i = 0; i < cif_dev->sditf_cnt; i++) {
- if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd)
- v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, core, ioctl,
- RKMODULE_SET_QUICK_STREAM, &on);
+ if (priv && priv->is_combine_mode && cif_dev->sditf_cnt <= RKCIF_MAX_SDITF) {
+ for (i = 0; i < cif_dev->sditf_cnt; i++) {
+ if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd)
+ v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, core, ioctl,
+ RKMODULE_SET_QUICK_STREAM, &on);
+ }
}
if (cif_dev->chip_id < CHIP_RK3588_CIF)
@@ -9437,6 +9904,11 @@
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;
}
@@ -9616,15 +10088,16 @@
sync_config = &hw->sync_config[cif_dev->sync_cfg.group];
sync_config->sync_code |= BIT(cif_dev->csi_host_idx);
- if (sync_config->sync_code != sync_config->sync_mask)
- return -EINVAL;
-
v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev,
- "sync code 0x%x, mask 0x%x, update 0x%x, cache 0x%x\n",
+ "sync code 0x%x, mask 0x%x, update 0x%x, cache 0x%x, timestamp %llu\n",
sync_config->sync_code,
sync_config->sync_mask,
sync_config->update_code,
- sync_config->update_cache);
+ sync_config->update_cache,
+ detect_stream->readout.fs_timestamp);
+
+ if (sync_config->sync_code != sync_config->sync_mask)
+ return -EINVAL;
for (i = 0; i < sync_config->dev_cnt; i++) {
if (sync_config->mode == RKCIF_MASTER_MASTER) {
@@ -9973,7 +10446,12 @@
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);
@@ -9982,11 +10460,20 @@
is_update = true;
else
is_update = rkcif_check_buffer_prepare(stream);
+ v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
+ "dma capture by vicap, is_updata %d, group mode %d, dma_en %d\n",
+ is_update, cif_dev->sync_cfg.type, stream->dma_en);
if (is_update)
rkcif_update_stream(cif_dev, stream, mipi_id);
} else if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
+ v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
+ "dma capture by isp, dma_en 0x%x\n",
+ stream->dma_en);
rkcif_update_stream_toisp(cif_dev, stream, mipi_id);
} else if (stream->dma_en & RKCIF_DMAEN_BY_ROCKIT) {
+ v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
+ "dma capture by rockit, dma_en 0x%x\n",
+ stream->dma_en);
rkcif_update_stream_rockit(cif_dev, stream, mipi_id);
}
@@ -10003,11 +10490,10 @@
}
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);
}
--
Gitblit v1.6.2