From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 08:20:59 +0000 Subject: [PATCH] kernel_5.10 no rt --- 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