Re: [PATCH v7 16/28] media: rockchip: rga: reuse cmdbuf contents

From: Nicolas Dufresne

Date: Wed May 20 2026 - 20:10:02 EST


Le jeudi 21 mai 2026 à 00:44 +0200, Sven Püschel a écrit :
> 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@xxxxxxxxxxxxxx>

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx>

>
> ---
> Changes in v6:
> - Reworked the commit to not setup the cmdbuf on streamon but rather
>   re-initialize it on the next frame when something changed.
> - Sasahiko flagged the cmdbuf setup at streamon:
>   https://sashiko.dev/#/patchset/20260428-spu-rga3-v5-0-eb7f5d019d86%40pengutronix.de?part=17
> - Dropped Reviewed-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx>
>   due to the reworked patch and commit message contents
>
> Changes in v5:
> - Don't set the flipping and rotation values at streamon and preventing
>   the userspace from chainging them at runtime
> ---
>  drivers/media/platform/rockchip/rga/rga-hw.c | 13 +++++++++----
>  drivers/media/platform/rockchip/rga/rga.c    | 11 +++++++++--
>  drivers/media/platform/rockchip/rga/rga.h    |  2 ++
>  3 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c
> index dac3cb6aa17d3..567d39e58d33f 100644
> --- a/drivers/media/platform/rockchip/rga/rga-hw.c
> +++ b/drivers/media/platform/rockchip/rga/rga-hw.c
> @@ -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,
> diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
> index d080cb672740b..394b14b9469df 100644
> --- a/drivers/media/platform/rockchip/rga/rga.c
> +++ b/drivers/media/platform/rockchip/rga/rga.c
> @@ -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;
>  }
> diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
> index 38518146910a6..5360f092fecf0 100644
> --- a/drivers/media/platform/rockchip/rga/rga.h
> +++ b/drivers/media/platform/rockchip/rga/rga.h
> @@ -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);

Attachment: signature.asc
Description: This is a digitally signed message part