media: rockchip: isp: fast stream from vpss for isp35

Change-Id: Ie0a6cc46aebedb85bc0d885108ebc3873027c4a4
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2025-02-28 16:44:18 +08:00
committed by Tao Huang
parent 502d08b106
commit 310f380783
4 changed files with 81 additions and 60 deletions

View File

@@ -1310,13 +1310,12 @@ static void rkisp_stop_streaming(struct vb2_queue *queue)
atomic_dec(&dev->cap_dev.refcnt);
tasklet_disable(&stream->buf_done_tasklet);
end:
mutex_unlock(&dev->hw_dev->dev_lock);
if (dev->is_pre_on && stream->id == RKISP_STREAM_MP) {
if (dev->is_pre_on && !atomic_read(&dev->cap_dev.refcnt)) {
dev->is_pre_on = false;
dev->params_vdev.first_cfg_params = false;
v4l2_pipeline_pm_put(&stream->vnode.vdev.entity);
}
mutex_unlock(&dev->hw_dev->dev_lock);
}
static int rkisp_stream_start(struct rkisp_stream *stream)

View File

@@ -478,12 +478,59 @@ static struct streams_ops rkisp2_dmarx_streams_ops = {
.update_mi = update_rawrd,
};
static void dmarx_buf_to_vicap(struct rkisp_stream *stream, struct rkisp_buffer *buf)
{
struct rkisp_device *dev = stream->ispdev;
struct v4l2_subdev *sd = dev->active_sensor->sd;
struct rkisp_rx_buf *rx_buf = buf->other;
u32 val, reg;
int on = 1;
if (rx_buf->is_switch && stream->id == RKISP_STREAM_RAWRD2) {
switch (dev->rd_mode) {
case HDR_RDBK_FRAME3:
dev->rd_mode = HDR_LINEX3_DDR;
break;
case HDR_RDBK_FRAME2:
dev->rd_mode = HDR_LINEX2_DDR;
break;
default:
dev->rd_mode = HDR_NORMAL;
}
dev->hdr.op_mode = dev->rd_mode;
val = SW_IBUF_OP_MODE(dev->hdr.op_mode);
rkisp_unite_write(dev, CSI2RX_CTRL0, val, false);
val = ISP21_MIPI_DROP_FRM;
rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, val, false);
rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, CIF_ISP_FRAME_IN, false);
if (dev->isp_ver == ISP_V33) {
val = ISP33_PP_ENC_PIPE_EN;
rkisp_unite_clear_bits(dev, CTRL_SWS_CFG, val, false);
if (dev->hdr_wrap_line) {
val = stream->out_fmt.plane_fmt[0].bytesperline * dev->hdr_wrap_line;
rkisp_unite_write(dev, ISP32_MI_RAW0_RD_SIZE, val, false);
}
if (dev->unite_div == ISP_UNITE_DIV2) {
mi_raw_length(stream);
reg = stream->config->mi.y_base_ad_init;
rkisp_unite_write(dev, reg, rx_buf->dma, false);
dev->unite_index = ISP_UNITE_LEFT;
dev->params_vdev.rdbk_times = 2;
}
}
dev_info(dev->dev, "switch online seq:%d mode:0x%x refcnt:%d\n",
rx_buf->sequence, dev->rd_mode, atomic_read(&dev->hw_dev->refcnt));
if (dev->hw_dev->is_single)
v4l2_subdev_call(sd, core, ioctl, RKISP_VICAP_CMD_HW_LINK, &on);
}
rx_buf->runtime_us = dev->isp_sdev.dbg.interval / 1000;
v4l2_subdev_call(sd, video, s_rx_buffer, rx_buf, NULL);
}
static int dmarx_frame_end(struct rkisp_stream *stream)
{
struct rkisp_buffer *buf = NULL;
unsigned long lock_flags = 0;
u32 val, reg;
int on = 1;
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
if (stream->curr_buf) {
@@ -503,54 +550,10 @@ static int dmarx_frame_end(struct rkisp_stream *stream)
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
if (buf) {
if (buf->other) {
struct rkisp_device *dev = stream->ispdev;
struct v4l2_subdev *sd = dev->active_sensor->sd;
struct rkisp_rx_buf *rx_buf = buf->other;
if (rx_buf->is_switch && stream->id == RKISP_STREAM_RAWRD2) {
switch (dev->rd_mode) {
case HDR_RDBK_FRAME3:
dev->rd_mode = HDR_LINEX3_DDR;
break;
case HDR_RDBK_FRAME2:
dev->rd_mode = HDR_LINEX2_DDR;
break;
default:
dev->rd_mode = HDR_NORMAL;
}
dev->hdr.op_mode = dev->rd_mode;
val = SW_IBUF_OP_MODE(dev->hdr.op_mode);
rkisp_unite_write(dev, CSI2RX_CTRL0, val, false);
val = ISP21_MIPI_DROP_FRM;
rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, val, false);
rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, CIF_ISP_FRAME_IN, false);
if (dev->isp_ver == ISP_V33) {
val = ISP33_PP_ENC_PIPE_EN;
rkisp_unite_clear_bits(dev, CTRL_SWS_CFG, val, false);
if (dev->hdr_wrap_line) {
val = stream->out_fmt.plane_fmt[0].bytesperline * dev->hdr_wrap_line;
rkisp_unite_write(dev, ISP32_MI_RAW0_RD_SIZE, val, false);
}
if (dev->unite_div == ISP_UNITE_DIV2) {
mi_raw_length(stream);
reg = stream->config->mi.y_base_ad_init;
rkisp_unite_write(dev, reg, rx_buf->dma, false);
dev->unite_index = ISP_UNITE_LEFT;
dev->params_vdev.rdbk_times = 2;
}
}
dev_info(dev->dev,
"switch online seq:%d mode:0x%x\n",
rx_buf->sequence, dev->rd_mode);
if (dev->hw_dev->is_single)
v4l2_subdev_call(sd, core, ioctl, RKISP_VICAP_CMD_HW_LINK, &on);
}
rx_buf->runtime_us = dev->isp_sdev.dbg.interval / 1000;
v4l2_subdev_call(sd, video, s_rx_buffer, rx_buf, NULL);
} else {
if (buf->other)
dmarx_buf_to_vicap(stream, buf);
else
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
}
return 0;
}

View File

@@ -34,18 +34,27 @@ static int rkisp_sditf_s_stream(struct v4l2_subdev *sd, int on)
struct rkisp_device *dev = sditf->isp;
struct rkisp_hw_dev *hw = dev->hw_dev;
struct rkisp_isp_subdev *isp_sdev = &dev->isp_sdev;
struct rkisp_stream *stream = &dev->cap_dev.stream[RKISP_STREAM_LDC];
struct rkisp_stream *stream;
int ret = 0;
if (stream->linked) {
v4l2_err(sd, "isp to vpss online no support for ldcpath link\n");
return -EINVAL;
if (dev->isp_ver == ISP_V39) {
stream = &dev->cap_dev.stream[RKISP_STREAM_LDC];
if (stream->linked) {
v4l2_err(sd, "isp to vpss online no support for ldcpath link\n");
return -EINVAL;
}
}
v4l2_dbg(1, rkisp_debug, sd, "%s %d\n", __func__, on);
mutex_lock(&hw->dev_lock);
if (on) {
if (dev->is_pre_on &&
!dev->hw_dev->is_single &&
!atomic_read(&dev->hw_dev->refcnt) &&
!atomic_read(&dev->cap_dev.refcnt))
rkisp_hw_enum_isp_size(dev->hw_dev);
atomic_inc(&dev->cap_dev.refcnt);
ret = dev->pipe.open(&dev->pipe, &isp_sdev->sd.entity, true);
if (ret < 0)
@@ -65,6 +74,12 @@ pipe_close:
refcnt_dec:
atomic_dec(&dev->cap_dev.refcnt);
unlock:
if (dev->is_pre_on && !atomic_read(&dev->cap_dev.refcnt)) {
dev->is_pre_on = false;
dev->params_vdev.first_cfg_params = false;
stream = &dev->cap_dev.stream[0];
v4l2_pipeline_pm_put(&stream->vnode.vdev.entity);
}
mutex_unlock(&hw->dev_lock);
return ret;
}

View File

@@ -1103,8 +1103,12 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
}
hw->is_idle = true;
hw->pre_dev_id = dev->dev_id;
/* fast unite offline switch to online */
if (dev->unite_div > ISP_UNITE_DIV1 && !IS_HDR_RDBK(dev->rd_mode))
/* fast offline switch to online for multi sensor or unite mode
* one isp running first and switch to online, then other isp running
*/
if (!IS_HDR_RDBK(dev->rd_mode) && !hw->is_single &&
(dev->unite_div > ISP_UNITE_DIV1 || atomic_read(&hw->refcnt) == 1))
isp = dev;
else
isp = hw->isp[!dev->dev_id];
@@ -3373,9 +3377,9 @@ static int rkisp_rx_qbuf(struct rkisp_device *dev,
}
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
"%s rd_mode:%d seq:%d dma:0x%x\n",
"%s rd_mode:%d seq:%d dma:0x%x timestamp:%lld\n",
__func__, dev->rd_mode, dbufs->sequence,
pool->buf.buff_addr[RKISP_PLANE_Y]);
pool->buf.buff_addr[RKISP_PLANE_Y], dbufs->timestamp);
if (!IS_HDR_RDBK(dev->rd_mode)) {
rkisp_rx_qbuf_online(stream, pool);