diff mbox series

[05/13] media: rockchip: rga: pre-calculate plane offsets

Message ID 20230914-rockchip-rga-multiplanar-v1-5-abfd77260ae3@pengutronix.de (mailing list archive)
State New, archived
Headers show
Series media: rockchip: rga: add support for multi-planar formats | expand

Commit Message

Michael Tretter Sept. 14, 2023, 12:40 p.m. UTC
Calculate the plane offsets and store them with the video buffer while
creating the buffer mapping.

This allows the driver to more freely handle the memory of the DMA
mapping as the offsets and the mapping can be kept in sync.

The driver still has to update the offsets to respect the configured
cropping and rotation, but this calculation is now separated from the
calculation of the plane offsets.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 drivers/media/platform/rockchip/rga/rga-buf.c | 15 ++++++++++++
 drivers/media/platform/rockchip/rga/rga-hw.c  | 33 ++++++++++++---------------
 drivers/media/platform/rockchip/rga/rga.h     |  9 ++++++++
 3 files changed, 38 insertions(+), 19 deletions(-)

Comments

kernel test robot Sept. 14, 2023, 1:56 p.m. UTC | #1
Hi Michael,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 0bb80ecc33a8fb5a682236443c1e740d5c917d1d]

url:    https://github.com/intel-lab-lkp/linux/commits/Michael-Tretter/media-rockchip-rga-fix-swizzling-for-RGB-formats/20230914-204330
base:   0bb80ecc33a8fb5a682236443c1e740d5c917d1d
patch link:    https://lore.kernel.org/r/20230914-rockchip-rga-multiplanar-v1-5-abfd77260ae3%40pengutronix.de
patch subject: [PATCH 05/13] media: rockchip: rga: pre-calculate plane offsets
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230914/202309142156.JJwE4Eke-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230914/202309142156.JJwE4Eke-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309142156.JJwE4Eke-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/media/platform/rockchip/rga/rga-hw.c: In function 'rga_get_addr_offset':
>> drivers/media/platform/rockchip/rga/rga-hw.c:46:65: warning: variable 'uv_factor' set but not used [-Wunused-but-set-variable]
      46 |                      y_div = 0, uv_stride = 0, pixel_width = 0, uv_factor = 0;
         |                                                                 ^~~~~~~~~


vim +/uv_factor +46 drivers/media/platform/rockchip/rga/rga-hw.c

f7e7b48e6d796d Jacob Chen      2017-10-11  38  
f7e7b48e6d796d Jacob Chen      2017-10-11  39  static struct rga_corners_addr_offset
7c2b289b29ea42 Michael Tretter 2023-09-14  40  rga_get_addr_offset(struct rga_frame *frm, struct rga_addr_offset *offset,
7c2b289b29ea42 Michael Tretter 2023-09-14  41  		    unsigned int x, unsigned int y, unsigned int w, unsigned int h)
f7e7b48e6d796d Jacob Chen      2017-10-11  42  {
f7e7b48e6d796d Jacob Chen      2017-10-11  43  	struct rga_corners_addr_offset offsets;
f7e7b48e6d796d Jacob Chen      2017-10-11  44  	struct rga_addr_offset *lt, *lb, *rt, *rb;
f7e7b48e6d796d Jacob Chen      2017-10-11  45  	unsigned int x_div = 0,
f7e7b48e6d796d Jacob Chen      2017-10-11 @46  		     y_div = 0, uv_stride = 0, pixel_width = 0, uv_factor = 0;
f7e7b48e6d796d Jacob Chen      2017-10-11  47  
f7e7b48e6d796d Jacob Chen      2017-10-11  48  	lt = &offsets.left_top;
f7e7b48e6d796d Jacob Chen      2017-10-11  49  	lb = &offsets.left_bottom;
f7e7b48e6d796d Jacob Chen      2017-10-11  50  	rt = &offsets.right_top;
f7e7b48e6d796d Jacob Chen      2017-10-11  51  	rb = &offsets.right_bottom;
f7e7b48e6d796d Jacob Chen      2017-10-11  52  
f7e7b48e6d796d Jacob Chen      2017-10-11  53  	x_div = frm->fmt->x_div;
f7e7b48e6d796d Jacob Chen      2017-10-11  54  	y_div = frm->fmt->y_div;
f7e7b48e6d796d Jacob Chen      2017-10-11  55  	uv_factor = frm->fmt->uv_factor;
f7e7b48e6d796d Jacob Chen      2017-10-11  56  	uv_stride = frm->stride / x_div;
f7e7b48e6d796d Jacob Chen      2017-10-11  57  	pixel_width = frm->stride / frm->width;
f7e7b48e6d796d Jacob Chen      2017-10-11  58  
7c2b289b29ea42 Michael Tretter 2023-09-14  59  	lt->y_off = offset->y_off + y * frm->stride + x * pixel_width;
7c2b289b29ea42 Michael Tretter 2023-09-14  60  	lt->u_off = offset->u_off + (y / y_div) * uv_stride + x / x_div;
7c2b289b29ea42 Michael Tretter 2023-09-14  61  	lt->v_off = offset->v_off + (y / y_div) * uv_stride + x / x_div;
f7e7b48e6d796d Jacob Chen      2017-10-11  62  
f7e7b48e6d796d Jacob Chen      2017-10-11  63  	lb->y_off = lt->y_off + (h - 1) * frm->stride;
f7e7b48e6d796d Jacob Chen      2017-10-11  64  	lb->u_off = lt->u_off + (h / y_div - 1) * uv_stride;
f7e7b48e6d796d Jacob Chen      2017-10-11  65  	lb->v_off = lt->v_off + (h / y_div - 1) * uv_stride;
f7e7b48e6d796d Jacob Chen      2017-10-11  66  
f7e7b48e6d796d Jacob Chen      2017-10-11  67  	rt->y_off = lt->y_off + (w - 1) * pixel_width;
f7e7b48e6d796d Jacob Chen      2017-10-11  68  	rt->u_off = lt->u_off + w / x_div - 1;
f7e7b48e6d796d Jacob Chen      2017-10-11  69  	rt->v_off = lt->v_off + w / x_div - 1;
f7e7b48e6d796d Jacob Chen      2017-10-11  70  
f7e7b48e6d796d Jacob Chen      2017-10-11  71  	rb->y_off = lb->y_off + (w - 1) * pixel_width;
f7e7b48e6d796d Jacob Chen      2017-10-11  72  	rb->u_off = lb->u_off + w / x_div - 1;
f7e7b48e6d796d Jacob Chen      2017-10-11  73  	rb->v_off = lb->v_off + w / x_div - 1;
f7e7b48e6d796d Jacob Chen      2017-10-11  74  
f7e7b48e6d796d Jacob Chen      2017-10-11  75  	return offsets;
f7e7b48e6d796d Jacob Chen      2017-10-11  76  }
f7e7b48e6d796d Jacob Chen      2017-10-11  77
diff mbox series

Patch

diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c
index e8dcc0d5cb90..137f4f4be14c 100644
--- a/drivers/media/platform/rockchip/rga/rga-buf.c
+++ b/drivers/media/platform/rockchip/rga/rga-buf.c
@@ -76,6 +76,18 @@  static int rga_buf_init(struct vb2_buffer *vb)
 	return 0;
 }
 
+static int get_plane_offset(struct rga_frame *f, int plane)
+{
+	if (plane == 0)
+		return 0;
+	if (plane == 1)
+		return f->width * f->height;
+	if (plane == 2)
+		return f->width * f->height + (f->width * f->height / f->fmt->uv_factor);
+
+	return -EINVAL;
+}
+
 static int rga_buf_prepare(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -97,6 +109,9 @@  static int rga_buf_prepare(struct vb2_buffer *vb)
 		dev_err(rga->dev, "Failed to map buffer");
 		return n_desc;
 	}
+	rbuf->offset.y_off = get_plane_offset(f, 0);
+	rbuf->offset.u_off = get_plane_offset(f, 1);
+	rbuf->offset.v_off = get_plane_offset(f, 2);
 
 	/* sync local MMU table for RGA */
 	dma_sync_single_for_device(rga->dev, rbuf->dma_desc_pa,
diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c
index 836ec7721b21..8cbee059100b 100644
--- a/drivers/media/platform/rockchip/rga/rga-hw.c
+++ b/drivers/media/platform/rockchip/rga/rga-hw.c
@@ -16,12 +16,6 @@  enum e_rga_start_pos {
 	RB = 3,
 };
 
-struct rga_addr_offset {
-	unsigned int y_off;
-	unsigned int u_off;
-	unsigned int v_off;
-};
-
 struct rga_corners_addr_offset {
 	struct rga_addr_offset left_top;
 	struct rga_addr_offset right_top;
@@ -43,8 +37,8 @@  static unsigned int rga_get_scaling(unsigned int src, unsigned int dst)
 }
 
 static struct rga_corners_addr_offset
-rga_get_addr_offset(struct rga_frame *frm, unsigned int x, unsigned int y,
-		    unsigned int w, unsigned int h)
+rga_get_addr_offset(struct rga_frame *frm, struct rga_addr_offset *offset,
+		    unsigned int x, unsigned int y, unsigned int w, unsigned int h)
 {
 	struct rga_corners_addr_offset offsets;
 	struct rga_addr_offset *lt, *lb, *rt, *rb;
@@ -62,10 +56,9 @@  rga_get_addr_offset(struct rga_frame *frm, unsigned int x, unsigned int y,
 	uv_stride = frm->stride / x_div;
 	pixel_width = frm->stride / frm->width;
 
-	lt->y_off = y * frm->stride + x * pixel_width;
-	lt->u_off =
-		frm->width * frm->height + (y / y_div) * uv_stride + x / x_div;
-	lt->v_off = lt->u_off + frm->width * frm->height / uv_factor;
+	lt->y_off = offset->y_off + y * frm->stride + x * pixel_width;
+	lt->u_off = offset->u_off + (y / y_div) * uv_stride + x / x_div;
+	lt->v_off = offset->v_off + (y / y_div) * uv_stride + x / x_div;
 
 	lb->y_off = lt->y_off + (h - 1) * frm->stride;
 	lb->u_off = lt->u_off + (h / y_div - 1) * uv_stride;
@@ -317,7 +310,8 @@  static void rga_cmd_set_trans_info(struct rga_ctx *ctx)
 	dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2] = dst_info.val;
 }
 
-static void rga_cmd_set_src_info(struct rga_ctx *ctx)
+static void rga_cmd_set_src_info(struct rga_ctx *ctx,
+				 struct rga_addr_offset *offset)
 {
 	struct rga_corners_addr_offset src_offsets;
 	struct rockchip_rga *rga = ctx->rga;
@@ -332,8 +326,8 @@  static void rga_cmd_set_src_info(struct rga_ctx *ctx)
 	/*
 	 * Calculate the source framebuffer base address with offset pixel.
 	 */
-	src_offsets = rga_get_addr_offset(&ctx->in, src_x, src_y,
-					  src_w, src_h);
+	src_offsets = rga_get_addr_offset(&ctx->in, offset,
+					  src_x, src_y, src_w, src_h);
 
 	dest[(RGA_SRC_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
 		src_offsets.left_top.y_off;
@@ -343,7 +337,8 @@  static void rga_cmd_set_src_info(struct rga_ctx *ctx)
 		src_offsets.left_top.v_off;
 }
 
-static void rga_cmd_set_dst_info(struct rga_ctx *ctx)
+static void rga_cmd_set_dst_info(struct rga_ctx *ctx,
+				 struct rga_addr_offset *offset)
 {
 	struct rga_addr_offset *dst_offset;
 	struct rga_corners_addr_offset offsets;
@@ -381,7 +376,7 @@  static void rga_cmd_set_dst_info(struct rga_ctx *ctx)
 	/*
 	 * Configure the dest framebuffer base address with pixel offset.
 	 */
-	offsets = rga_get_addr_offset(&ctx->out, dst_x, dst_y, dst_w, dst_h);
+	offsets = rga_get_addr_offset(&ctx->out, offset, dst_x, dst_y, dst_w, dst_h);
 	dst_offset = rga_lookup_draw_pos(&offsets, mir_mode, rot_mode);
 
 	dest[(RGA_DST_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
@@ -432,8 +427,8 @@  static void rga_cmd_set(struct rga_ctx *ctx,
 	rga_cmd_set_dst_addr(ctx, dst->dma_desc_pa);
 	rga_cmd_set_mode(ctx);
 
-	rga_cmd_set_src_info(ctx);
-	rga_cmd_set_dst_info(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, rga->cmdbuf_phy);
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index ae984d5a236d..d8e76ab9c7e4 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -87,6 +87,12 @@  struct rockchip_rga {
 	void *cmdbuf_virt;
 };
 
+struct rga_addr_offset {
+	unsigned int y_off;
+	unsigned int u_off;
+	unsigned int v_off;
+};
+
 struct rga_vb_buffer {
 	struct vb2_v4l2_buffer vb_buf;
 	struct list_head queue;
@@ -95,6 +101,9 @@  struct rga_vb_buffer {
 	struct rga_dma_desc *dma_desc;
 	dma_addr_t dma_desc_pa;
 	int n_desc;
+
+	/* Plane offsets of this buffer into the mapping */
+	struct rga_addr_offset offset;
 };
 
 static inline struct rga_vb_buffer *vb_to_rga(struct vb2_v4l2_buffer *vb)