From e76af5fc7cde1ba464bcd4939e856e6987007927 Mon Sep 17 00:00:00 2001 From: Lian Xu Date: Sat, 26 Mar 2022 15:07:20 +0800 Subject: [PATCH] media: rockchip: isp: Solve the wrap_line frame rate problem Change-Id: I6a949723c1b8caa90897b111a37d19f32644b6ba Signed-off-by: Lian Xu --- drivers/media/platform/rockchip/isp/capture.h | 5 ++ .../media/platform/rockchip/isp/capture_v32.c | 10 +++- .../media/platform/rockchip/isp/capture_v3x.h | 4 +- .../media/platform/rockchip/isp/isp_rockit.c | 48 ++++++++++++++----- include/soc/rockchip/rockchip_rockit.h | 21 ++++---- 5 files changed, 61 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.h b/drivers/media/platform/rockchip/isp/capture.h index b310012bf066..be7d91f7e635 100644 --- a/drivers/media/platform/rockchip/isp/capture.h +++ b/drivers/media/platform/rockchip/isp/capture.h @@ -59,6 +59,11 @@ struct rkisp_stream; +enum { + ROCKIT_DVBM_END, + ROCKIT_DVBM_START, +}; + enum { RDBK_L, RDBK_M, diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index 70f5d53d24bb..0b0d8b1d245b 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -992,6 +992,11 @@ static int mi_frame_start(struct rkisp_stream *stream, u32 mis) { unsigned long lock_flags = 0; + if (stream->ispdev->cap_dev.wrap_line && + stream->id == RKISP_STREAM_MP && + stream->streaming && mis != 0) + rkisp_rockit_buf_done(stream, ROCKIT_DVBM_START); + /* readback start to update stream buf if null */ spin_lock_irqsave(&stream->vbq_lock, lock_flags); if (stream->streaming) { @@ -1058,7 +1063,7 @@ static int mi_frame_end(struct rkisp_stream *stream) if (vb2_buf->memory) vb2_buffer_done(vb2_buf, VB2_BUF_STATE_DONE); else - rkisp_rockit_buf_done(stream); + rkisp_rockit_buf_done(stream, ROCKIT_DVBM_END); } spin_lock_irqsave(&stream->vbq_lock, lock_flags); @@ -1716,7 +1721,8 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) wake_up(&stream->done); } } else { - mi_frame_end(stream); + if (stream->id != RKISP_STREAM_MP || !dev->cap_dev.wrap_line) + mi_frame_end(stream); } } diff --git a/drivers/media/platform/rockchip/isp/capture_v3x.h b/drivers/media/platform/rockchip/isp/capture_v3x.h index 4270c6403039..f0c686da58a1 100644 --- a/drivers/media/platform/rockchip/isp/capture_v3x.h +++ b/drivers/media/platform/rockchip/isp/capture_v3x.h @@ -28,7 +28,7 @@ void rkisp_mipi_v32_isr(u32 phy, u32 packet, u32 overflow, u32 state, struct rki int rkisp_rockit_buf_free(struct rkisp_stream *stream); void rkisp_rockit_dev_init(struct rkisp_device *dev); -int rkisp_rockit_buf_done(struct rkisp_stream *stream); +int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd); #else static inline int rkisp_register_stream_v32(struct rkisp_device *dev) { return -EINVAL; } static inline void rkisp_unregister_stream_v32(struct rkisp_device *dev) {} @@ -37,7 +37,7 @@ static inline void rkisp_mipi_v32_isr(u32 phy, u32 packet, u32 overflow, u32 sta static inline int rkisp_rockit_buf_free(struct rkisp_stream *stream) { return -EINVAL; } static inline void rkisp_rockit_dev_init(struct rkisp_device *dev) { return; } -static inline int rkisp_rockit_buf_done(struct rkisp_stream *stream) { return -EINVAL; } +static inline int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) { return -EINVAL; } #endif #if IS_ENABLED(CONFIG_ROCKCHIP_DVBM) diff --git a/drivers/media/platform/rockchip/isp/isp_rockit.c b/drivers/media/platform/rockchip/isp/isp_rockit.c index 9d6200b68f6c..db7498888f83 100644 --- a/drivers/media/platform/rockchip/isp/isp_rockit.c +++ b/drivers/media/platform/rockchip/isp/isp_rockit.c @@ -95,8 +95,6 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) return -EINVAL; } - ispdev = stream->ispdev; - g_ops = ispdev->hw_dev->mem_ops; stream_cfg = &rockit_cfg->rkisp_stream_cfg[stream->id]; for (i = 0; i < ROCKIT_BUF_NUM_MAX; i++) { @@ -107,6 +105,13 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) } stream_cfg->node = input_rockit_cfg->node; + + if (!input_rockit_cfg->buf) + return -EINVAL; + + ispdev = stream->ispdev; + g_ops = ispdev->hw_dev->mem_ops; + if (input_rockit_cfg->is_alloc) { for (i = 0; i < ROCKIT_BUF_NUM_MAX; i++) { if (stream_cfg->buff_id[i] == 0) { @@ -124,6 +129,8 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) return -EINVAL; isprk_buf = stream_cfg->rkisp_buff[i]; + isprk_buf->mpi_buf = input_rockit_cfg->mpibuf; + mem = g_ops->attach_dmabuf(stream->ispdev->hw_dev->dev, input_rockit_cfg->buf, input_rockit_cfg->buf->size, @@ -133,7 +140,6 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) isprk_buf->mpi_mem = mem; isprk_buf->dmabuf = input_rockit_cfg->buf; - isprk_buf->mpi_buf = input_rockit_cfg->mpibuf; ret = g_ops->map_dmabuf(mem); if (ret) @@ -153,14 +159,13 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) break; } } + for (i = 0; i < stream->out_isp_fmt.mplanes; i++) isprk_buf->isp_buf.buff_addr[i] = isprk_buf->buff_addr; if (stream->out_isp_fmt.mplanes == 1) { for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) { height = stream->out_fmt.height; - if (ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) - height = ispdev->cap_dev.wrap_line; offset = (i == 0) ? stream->out_fmt.plane_fmt[i].bytesperline * height : stream->out_fmt.plane_fmt[i].sizeimage; @@ -189,18 +194,39 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) return 0; } -int rkisp_rockit_buf_done(struct rkisp_stream *stream) +int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) { struct rkisp_device *dev = stream->ispdev; - struct rkisp_rockit_buffer *isprk_buf = - container_of(stream->curr_buf, struct rkisp_rockit_buffer, isp_buf); + struct rkisp_rockit_buffer *isprk_buf = NULL; struct rkisp_stream_cfg *stream_cfg = &rockit_cfg->rkisp_stream_cfg[stream->id]; + u32 seq; + u64 ns = 0; if (!rockit_cfg->rkisp_rockit_mpibuf_done) { pr_err("mpi_buf_done is null\n"); return -EINVAL; } + if (stream->curr_buf != NULL) { + isprk_buf = + container_of(stream->curr_buf, struct rkisp_rockit_buffer, isp_buf); + + rockit_cfg->mpibuf = isprk_buf->mpi_buf; + + rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp; + + rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence; + } else { + rkisp_dmarx_get_frame(stream->ispdev, &seq, NULL, &ns, true); + + if (!ns) + ns = ktime_get_ns(); + + rockit_cfg->frame.u64PTS = ns; + + rockit_cfg->frame.u32TimeRef = seq; + } + rockit_cfg->frame.u32Height = stream->out_fmt.height; rockit_cfg->frame.u32Width = stream->out_fmt.width; @@ -211,15 +237,11 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream) rockit_cfg->frame.u32VirHeight = stream->out_fmt.height; - rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp; - - rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence; - rockit_cfg->current_name = dev->name; rockit_cfg->node = stream_cfg->node; - rockit_cfg->mpibuf = isprk_buf->mpi_buf; + rockit_cfg->event = cmd; if (list_empty(&stream->buf_queue)) rockit_cfg->is_empty = true; diff --git a/include/soc/rockchip/rockchip_rockit.h b/include/soc/rockchip/rockchip_rockit.h index e938a204f2b8..9b688f86bb6a 100644 --- a/include/soc/rockchip/rockchip_rockit.h +++ b/include/soc/rockchip/rockchip_rockit.h @@ -47,21 +47,22 @@ struct rkisp_dev_cfg { }; struct rockit_cfg { - u32 nick_id; - int *buff_id; - int mpi_id; - void *vvi_dev[ROCKIT_ISP_NUM_MAX]; - void *node; - void *mpibuf; - char *current_name; bool is_alloc; bool is_empty; - struct dma_buf *buf; + char *current_name; dma_addr_t dma_addr; + int *buff_id; + int mpi_id; + int isp_num; + u32 nick_id; + u32 event; + void *node; + void *mpibuf; + void *vvi_dev[ROCKIT_ISP_NUM_MAX]; + struct dma_buf *buf; struct ISP_VIDEO_FRAMES frame; struct rkisp_dev_cfg rkisp_dev_cfg[ROCKIT_ISP_NUM_MAX]; struct rkisp_stream_cfg rkisp_stream_cfg[ROCKIT_STREAM_NUM_MAX]; - int isp_num; int (*rkisp_rockit_mpibuf_done)(struct rockit_cfg *rockit_isp_cfg); }; @@ -73,7 +74,7 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg); #else -static inline void rkisp_rockit_function_register(void *function, int cmd) { return } +static inline void *rkisp_rockit_function_register(void *function, int cmd) { return NULL; } static inline int rkisp_rockit_get_ispdev(char **name) { return -EINVAL; } static inline int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) {