On Thu May 21 00:44:21 2026 +0200, Sven Püschel wrote:
> 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 <[email protected]>
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
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 dac3cb6aa17d..567d39e58d33 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 d080cb672740..394b14b9469d 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 38518146910a..5360f092fecf 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);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]