diff --git a/drivers/media/platform/rockchip/isp/capture_v35.c b/drivers/media/platform/rockchip/isp/capture_v35.c index 32e71077b0c4..f7f7ec6b373a 100644 --- a/drivers/media/platform/rockchip/isp/capture_v35.c +++ b/drivers/media/platform/rockchip/isp/capture_v35.c @@ -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) diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index eba6f71e08e8..1282c7bf33b8 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -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; } diff --git a/drivers/media/platform/rockchip/isp/isp_sditf.c b/drivers/media/platform/rockchip/isp/isp_sditf.c index f4a2e1af5530..eb60fbc4e3a4 100644 --- a/drivers/media/platform/rockchip/isp/isp_sditf.c +++ b/drivers/media/platform/rockchip/isp/isp_sditf.c @@ -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; } diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 43031116397d..10dce9b38656 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -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);