]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
media: rockchip: rga: reuse cmdbuf contents
authorSven Püschel <s.pueschel@pengutronix.de>
Wed, 20 May 2026 22:44:21 +0000 (00:44 +0200)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Thu, 21 May 2026 10:32:20 +0000 (12:32 +0200)
Reuse the command buffer contents instead of completely writing it
for every frame. Therefore we only need to replace the source and
destination addresses for each frame. This reduces the amount of CPU
and memory operations done in each frame. A new cmdbuf_dirty flag notes
if the cmdbuf has to be rewritten on the next frame.

The initial idea of initializing the cmdbuf on streamon broke the
ability to update controls while streaming (e.g. mirroring).

Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/rockchip/rga/rga-hw.c
drivers/media/platform/rockchip/rga/rga.c
drivers/media/platform/rockchip/rga/rga.h

index dac3cb6aa17d3a0c5fee69b07b3e5b17aba5d40f..567d39e58d33fe2bc8049a19ab4fb1a2d9c504e1 100644 (file)
@@ -417,8 +417,6 @@ static void rga_cmd_set(struct rga_ctx *ctx,
 {
        struct rockchip_rga *rga = ctx->rga;
 
-       memset(ctx->cmdbuf_virt, 0, RGA_CMDBUF_SIZE);
-
        rga_cmd_set_src_addr(ctx, src->dma_desc_pa);
        /*
         * Due to hardware bug,
@@ -427,11 +425,9 @@ static void rga_cmd_set(struct rga_ctx *ctx,
        rga_cmd_set_src1_addr(ctx, dst->dma_desc_pa);
 
        rga_cmd_set_dst_addr(ctx, dst->dma_desc_pa);
-       rga_cmd_set_mode(ctx);
 
        rga_cmd_set_src_info(ctx, &src->offset);
        rga_cmd_set_dst_info(ctx, &dst->offset);
-       rga_cmd_set_trans_info(ctx);
 
        rga_write(rga, RGA_CMD_BASE, ctx->cmdbuf_phy);
 
@@ -440,6 +436,14 @@ static void rga_cmd_set(struct rga_ctx *ctx,
                                   PAGE_SIZE, DMA_BIDIRECTIONAL);
 }
 
+static void rga_hw_setup_cmdbuf(struct rga_ctx *ctx)
+{
+       memset(ctx->cmdbuf_virt, 0, RGA_CMDBUF_SIZE);
+
+       rga_cmd_set_mode(ctx);
+       rga_cmd_set_trans_info(ctx);
+}
+
 static void rga_hw_start(struct rockchip_rga *rga,
                         struct rga_vb_buffer *src,  struct rga_vb_buffer *dst)
 {
@@ -582,6 +586,7 @@ const struct rga_hw rga2_hw = {
        .max_height = MAX_HEIGHT,
        .stride_alignment = 4,
 
+       .setup_cmdbuf = rga_hw_setup_cmdbuf,
        .start = rga_hw_start,
        .handle_irq = rga_handle_irq,
        .get_version = rga_get_version,
index d080cb672740b621ae02309f457b5068653e9c7c..394b14b9469dfef3a1ed35e28383d36ad23833c8 100644 (file)
@@ -38,6 +38,11 @@ static void device_run(void *prv)
        unsigned long flags;
 
        spin_lock_irqsave(&rga->ctrl_lock, flags);
+       if (ctx->cmdbuf_dirty) {
+               ctx->cmdbuf_dirty = false;
+               rga->hw->setup_cmdbuf(ctx);
+       }
+       spin_unlock_irqrestore(&rga->ctrl_lock, flags);
 
        rga->curr = ctx;
 
@@ -47,8 +52,6 @@ static void device_run(void *prv)
        dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
        rga->hw->start(rga, vb_to_rga(src), vb_to_rga(dst));
-
-       spin_unlock_irqrestore(&rga->ctrl_lock, flags);
 }
 
 static irqreturn_t rga_isr(int irq, void *prv)
@@ -141,6 +144,7 @@ static int rga_s_ctrl(struct v4l2_ctrl *ctrl)
                ctx->fill_color = ctrl->val;
                break;
        }
+       ctx->cmdbuf_dirty = true;
        spin_unlock_irqrestore(&ctx->rga->ctrl_lock, flags);
        return 0;
 }
@@ -228,6 +232,7 @@ static int rga_open(struct file *file)
                ret = -ENOMEM;
                goto rel_ctx;
        }
+       ctx->cmdbuf_dirty = true;
 
        ctx->rga = rga;
        /* Set default formats */
@@ -448,6 +453,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
        frm->crop.height = pix_fmt->height;
 
        frm->pix = *pix_fmt;
+       ctx->cmdbuf_dirty = true;
 
        v4l2_dbg(debug, 1, &rga->v4l2_dev,
                 "[%s] fmt - %p4cc %dx%d (stride %d, sizeimage %d)\n",
@@ -564,6 +570,7 @@ static int vidioc_s_selection(struct file *file, void *priv,
        }
 
        f->crop = s->r;
+       ctx->cmdbuf_dirty = true;
 
        return ret;
 }
index 38518146910a6f8c9f84ea4e0a302243bc219263..5360f092fecf0277b7f4f0ff8611d4030a7b9b5e 100644 (file)
@@ -55,6 +55,7 @@ struct rga_ctx {
 
        void *cmdbuf_virt;
        dma_addr_t cmdbuf_phy;
+       bool cmdbuf_dirty;
 
        int osequence;
        int csequence;
@@ -152,6 +153,7 @@ struct rga_hw {
        u32 max_width, max_height;
        u8 stride_alignment;
 
+       void (*setup_cmdbuf)(struct rga_ctx *ctx);
        void (*start)(struct rockchip_rga *rga,
                      struct rga_vb_buffer *src, struct rga_vb_buffer *dst);
        bool (*handle_irq)(struct rockchip_rga *rga);