diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index 51e4b750ef7a..05de8743b707 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -752,7 +752,8 @@ static int mp_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); /* set up first buffer */ - mi_frame_end(stream, FRAME_INIT); + if (dev->cap_dev.wrap_line && stream->dummy_buf.mem_priv) + mi_frame_end(stream, FRAME_INIT); rkisp_unite_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); rkisp_unite_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); @@ -1704,17 +1705,19 @@ static int rkisp_create_dummy_buf(struct rkisp_stream *stream) { struct rkisp_device *dev = stream->ispdev; struct rkisp_dummy_buffer *buf = &stream->dummy_buf; - int ret; + int ret = 0; /* mainpath for warp default */ if (!dev->cap_dev.wrap_line || stream->id != RKISP_STREAM_MP) return 0; - buf->size = dev->cap_dev.wrap_width * dev->cap_dev.wrap_line * 2; - if (stream->out_isp_fmt.output_format == ISP32_MI_OUTPUT_YUV420) - buf->size = buf->size - buf->size / 4; - buf->is_need_dbuf = true; - ret = rkisp_alloc_buffer(stream->ispdev, buf); + if (!buf->dma_addr) { + buf->size = dev->cap_dev.wrap_width * dev->cap_dev.wrap_line * 2; + if (stream->out_isp_fmt.output_format == ISP32_MI_OUTPUT_YUV420) + buf->size = buf->size - buf->size / 4; + buf->is_need_dbuf = true; + ret = rkisp_alloc_buffer(stream->ispdev, buf); + } if (ret == 0) { ret = rkisp_dvbm_init(stream); if (ret < 0) @@ -1732,6 +1735,7 @@ static void rkisp_destroy_dummy_buf(struct rkisp_stream *stream) return; rkisp_dvbm_deinit(); rkisp_free_buffer(dev, &stream->dummy_buf); + stream->dummy_buf.dma_addr = 0; } static void destroy_buf_queue(struct rkisp_stream *stream, @@ -2039,7 +2043,7 @@ rkisp_start_streaming(struct vb2_queue *queue, unsigned int count) goto buffer_done; if (dev->isp_ver == ISP_V32 && - count == 0 && !stream->dummy_buf.mem_priv && + count == 0 && !stream->dummy_buf.dma_addr && list_empty(&stream->buf_queue)) { v4l2_err(v4l2_dev, "no buf for %s\n", node->vdev.name); ret = -EINVAL; diff --git a/drivers/media/platform/rockchip/isp/isp_rockit.c b/drivers/media/platform/rockchip/isp/isp_rockit.c index 6ff581044af9..c8682492aaaf 100644 --- a/drivers/media/platform/rockchip/isp/isp_rockit.c +++ b/drivers/media/platform/rockchip/isp/isp_rockit.c @@ -90,6 +90,7 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) void *mem = NULL; struct sg_table *sg_tbl; unsigned long lock_flags = 0; + u32 reg, val, bytesperline; if (!input_rockit_cfg) return -EINVAL; @@ -175,6 +176,20 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) isprk_buf->isp_buf.buff_addr[i] = isprk_buf->buff_addr; } + if (ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP && isprk_buf) { + val = isprk_buf->buff_addr; + reg = stream->config->mi.y_base_ad_init; + rkisp_write(ispdev, reg, val, false); + + bytesperline = stream->out_fmt.plane_fmt[0].bytesperline; + val += bytesperline * ispdev->cap_dev.wrap_line; + reg = stream->config->mi.cb_base_ad_init; + rkisp_write(ispdev, reg, val, false); + stream->dummy_buf.dma_addr = isprk_buf->buff_addr; + v4l2_info(&ispdev->v4l2_dev, "rockit wrap buf:0x%x\n", isprk_buf->buff_addr); + return -EINVAL; + } + if (stream_cfg->is_discard && stream->streaming) return -EINVAL; @@ -195,8 +210,8 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) if (stream->out_isp_fmt.mplanes == 1) { for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) { height = stream->out_fmt.height; - offset = (i == 0) ? - stream->out_fmt.plane_fmt[i].bytesperline * height : + bytesperline = stream->out_fmt.plane_fmt[i].bytesperline; + offset = (i == 0) ? bytesperline * height : stream->out_fmt.plane_fmt[i].sizeimage; isprk_buf->isp_buf.buff_addr[i + 1] = isprk_buf->isp_buf.buff_addr[i] + offset; @@ -331,6 +346,7 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg, struct rkisp_buffer *isp_buf, *buf_temp; int offset, i, ret; unsigned long lock_flags = 0; + u32 reg, val, bytesperline; stream = rkisp_rockit_get_stream(input_rockit_cfg); @@ -347,8 +363,18 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg, pr_err("stream id %d config failed\n", stream->id); return -EINVAL; } - if (stream->ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) + if (stream->ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) { rkisp_dvbm_init(stream); + if (!stream->dummy_buf.mem_priv && stream->dummy_buf.dma_addr) { + bytesperline = stream->out_fmt.plane_fmt[0].bytesperline; + val = stream->dummy_buf.dma_addr; + reg = stream->config->mi.y_base_ad_init; + rkisp_write(stream->ispdev, reg, val, false); + val += bytesperline * stream->ispdev->cap_dev.wrap_line; + reg = stream->config->mi.cb_base_ad_init; + rkisp_write(stream->ispdev, reg, val, false); + } + } spin_lock_irqsave(&stream->vbq_lock, lock_flags); if (stream->curr_buf) { @@ -365,11 +391,10 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg, if (stream->out_isp_fmt.mplanes == 1) { for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) { height = stream->out_fmt.height; - offset = (i == 0) ? - stream->out_fmt.plane_fmt[i].bytesperline * height : + bytesperline = stream->out_fmt.plane_fmt[i].bytesperline; + offset = (i == 0) ? bytesperline * height : stream->out_fmt.plane_fmt[i].sizeimage; - isp_buf->buff_addr[i + 1] = - isp_buf->buff_addr[i] + offset; + isp_buf->buff_addr[i + 1] = isp_buf->buff_addr[i] + offset; } } }