From patchwork Thu Sep 14 12:40:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 722897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63544EDE9BE for ; Thu, 14 Sep 2023 12:41:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238443AbjINMlb (ORCPT ); Thu, 14 Sep 2023 08:41:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238337AbjINMla (ORCPT ); Thu, 14 Sep 2023 08:41:30 -0400 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18C2B1FD5 for ; Thu, 14 Sep 2023 05:41:26 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1qgles-0008Mc-Pt; Thu, 14 Sep 2023 14:41:22 +0200 From: Michael Tretter Date: Thu, 14 Sep 2023 14:40:33 +0200 Subject: [PATCH 01/13] media: rockchip: rga: fix swizzling for RGB formats MIME-Version: 1.0 Message-Id: <20230914-rockchip-rga-multiplanar-v1-1-abfd77260ae3@pengutronix.de> References: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> In-Reply-To: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Shengyu Qu , Nicolas Frattaroli , Robin Murphy , Diederik de Haas Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.12.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org When using 32 bit RGB formats, the RGA on the rk3568 produces wrong colors as the wrong color channels are read or written. The reason is that the format description for the channel swizzeling is wrong and the wrong bits are configured. For example, when converting ARGB32 to NV12, the alpha channel is used as blue channel.. This doesn't happen if the color format is the same on both sides. Fix the color_swap settings of the formats to correctly handle 32 bit RGB formats. For RGA_COLOR_FMT_XBGR8888, the RGA_COLOR_ALPHA_SWAP bit doesn't have an effect. Thus, it isn't possible to handle the V4L2_PIX_FMT_XRGB32. Thus, it is removed from the list of supported formats. Signed-off-by: Michael Tretter --- drivers/media/platform/rockchip/rga/rga.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index f1c532a5802a..25f5b5eebf13 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -184,25 +184,16 @@ static int rga_setup_ctrls(struct rga_ctx *ctx) static struct rga_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_ARGB32, - .color_swap = RGA_COLOR_RB_SWAP, + .color_swap = RGA_COLOR_ALPHA_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, .y_div = 1, .x_div = 1, }, - { - .fourcc = V4L2_PIX_FMT_XRGB32, - .color_swap = RGA_COLOR_RB_SWAP, - .hw_format = RGA_COLOR_FMT_XBGR8888, - .depth = 32, - .uv_factor = 1, - .y_div = 1, - .x_div = 1, - }, { .fourcc = V4L2_PIX_FMT_ABGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -211,7 +202,7 @@ static struct rga_fmt formats[] = { }, { .fourcc = V4L2_PIX_FMT_XBGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_XBGR8888, .depth = 32, .uv_factor = 1, From patchwork Thu Sep 14 12:40:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 722894 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F10EACA553C for ; Thu, 14 Sep 2023 12:41:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238457AbjINMle (ORCPT ); Thu, 14 Sep 2023 08:41:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238431AbjINMla (ORCPT ); Thu, 14 Sep 2023 08:41:30 -0400 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21A251FD8 for ; Thu, 14 Sep 2023 05:41:26 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1qglet-0008Mc-1e; Thu, 14 Sep 2023 14:41:23 +0200 From: Michael Tretter Date: Thu, 14 Sep 2023 14:40:37 +0200 Subject: [PATCH 05/13] media: rockchip: rga: pre-calculate plane offsets MIME-Version: 1.0 Message-Id: <20230914-rockchip-rga-multiplanar-v1-5-abfd77260ae3@pengutronix.de> References: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> In-Reply-To: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Shengyu Qu , Nicolas Frattaroli , Robin Murphy , Diederik de Haas Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.12.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- 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(-) 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) From patchwork Thu Sep 14 12:40:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 722896 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58BE7EDE9BC for ; Thu, 14 Sep 2023 12:41:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238451AbjINMlc (ORCPT ); Thu, 14 Sep 2023 08:41:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbjINMla (ORCPT ); Thu, 14 Sep 2023 08:41:30 -0400 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 188F81FC9 for ; Thu, 14 Sep 2023 05:41:26 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1qglet-0008Mc-3Q; Thu, 14 Sep 2023 14:41:23 +0200 From: Michael Tretter Date: Thu, 14 Sep 2023 14:40:38 +0200 Subject: [PATCH 06/13] media: rockchip: rga: set dma mask to 32 bits MIME-Version: 1.0 Message-Id: <20230914-rockchip-rga-multiplanar-v1-6-abfd77260ae3@pengutronix.de> References: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> In-Reply-To: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Shengyu Qu , Nicolas Frattaroli , Robin Murphy , Diederik de Haas Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.12.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The RGA DMA descriptor list contains only 32-bit addresses. Set the dma_mask to only allocate memory that is addressable by the descriptors. This prevents errors when preparing vb2 buffers that were allocated by the RGA. Imported buffers may still fail the preparation, as they may be allocated above the 4 GB boundary. Signed-off-by: Michael Tretter --- drivers/media/platform/rockchip/rga/rga.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index f18fccc7b204..149deb1f1e03 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -824,6 +824,12 @@ static int rga_probe(struct platform_device *pdev) goto err_put_clk; } + ret = dma_set_mask(rga->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(rga->dev, "32-bit DMA not supported"); + goto err_put_clk; + } + ret = v4l2_device_register(&pdev->dev, &rga->v4l2_dev); if (ret) goto err_put_clk; From patchwork Thu Sep 14 12:40:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 722895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B91D8CA0EF3 for ; Thu, 14 Sep 2023 12:41:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238454AbjINMle (ORCPT ); Thu, 14 Sep 2023 08:41:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238434AbjINMla (ORCPT ); Thu, 14 Sep 2023 08:41:30 -0400 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18DFA1FD7 for ; Thu, 14 Sep 2023 05:41:26 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1qglet-0008Mc-59; Thu, 14 Sep 2023 14:41:23 +0200 From: Michael Tretter Date: Thu, 14 Sep 2023 14:40:39 +0200 Subject: [PATCH 07/13] media: rockchip: rga: use clamp() to clamp size to limits MIME-Version: 1.0 Message-Id: <20230914-rockchip-rga-multiplanar-v1-7-abfd77260ae3@pengutronix.de> References: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> In-Reply-To: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Shengyu Qu , Nicolas Frattaroli , Robin Murphy , Diederik de Haas Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.12.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The try_fmt should limit the width and height to the know limits of the RGA. Use the clamp() helper instead of open coding the clamping. Signed-off-by: Michael Tretter --- drivers/media/platform/rockchip/rga/rga.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 149deb1f1e03..49403498bc17 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -480,15 +480,10 @@ static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) f->fmt.pix.field = V4L2_FIELD_NONE; - if (f->fmt.pix.width > MAX_WIDTH) - f->fmt.pix.width = MAX_WIDTH; - if (f->fmt.pix.height > MAX_HEIGHT) - f->fmt.pix.height = MAX_HEIGHT; - - if (f->fmt.pix.width < MIN_WIDTH) - f->fmt.pix.width = MIN_WIDTH; - if (f->fmt.pix.height < MIN_HEIGHT) - f->fmt.pix.height = MIN_HEIGHT; + f->fmt.pix.width = clamp(f->fmt.pix.width, + (u32)MIN_WIDTH, (u32)MAX_WIDTH); + f->fmt.pix.height = clamp(f->fmt.pix.height, + (u32)MIN_HEIGHT, (u32)MAX_HEIGHT); if (fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) f->fmt.pix.bytesperline = f->fmt.pix.width; From patchwork Thu Sep 14 12:40:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 722891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 782F2EE0205 for ; Thu, 14 Sep 2023 12:41:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233510AbjINMlg (ORCPT ); Thu, 14 Sep 2023 08:41:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238461AbjINMlf (ORCPT ); Thu, 14 Sep 2023 08:41:35 -0400 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0522B1FCC for ; Thu, 14 Sep 2023 05:41:31 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1qglet-0008Mc-G4; Thu, 14 Sep 2023 14:41:23 +0200 From: Michael Tretter Date: Thu, 14 Sep 2023 14:40:43 +0200 Subject: [PATCH 11/13] media: rockchip: rga: switch to multi-planar API MIME-Version: 1.0 Message-Id: <20230914-rockchip-rga-multiplanar-v1-11-abfd77260ae3@pengutronix.de> References: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> In-Reply-To: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Shengyu Qu , Nicolas Frattaroli , Robin Murphy , Diederik de Haas Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.12.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Switch to the multi-planar API, which allows to handle buffers with separate planes. The RGA driver doesn't expose multi-planar formats, yet. The existing contiguous planar formats can be used with the multi-planar API as well, but the multi-planar API is required for multi-planar formats. Signed-off-by: Michael Tretter --- drivers/media/platform/rockchip/rga/rga.c | 60 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 516069d720fa..db2160407b83 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -93,7 +93,7 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) struct rga_ctx *ctx = priv; int ret; - src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; src_vq->io_modes = VB2_MMAP | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->ops = &rga_qops; @@ -107,7 +107,7 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) if (ret) return ret; - dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->ops = &rga_qops; @@ -443,7 +443,7 @@ static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) { - struct v4l2_pix_format *pix_fmt = &f->fmt.pix; + struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; struct rga_ctx *ctx = prv; struct vb2_queue *vq; struct rga_frame *frm; @@ -455,12 +455,9 @@ static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) if (IS_ERR(frm)) return PTR_ERR(frm); - pix_fmt->width = frm->width; - pix_fmt->height = frm->height; + v4l2_fill_pixfmt_mp(pix_fmt, frm->fmt->fourcc, frm->width, frm->height); + pix_fmt->field = V4L2_FIELD_NONE; - pix_fmt->pixelformat = frm->fmt->fourcc; - pix_fmt->bytesperline = frm->stride; - pix_fmt->sizeimage = frm->size; pix_fmt->colorspace = frm->colorspace; return 0; @@ -468,41 +465,33 @@ static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) { - struct v4l2_pix_format *pix_fmt = &f->fmt.pix; + struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; struct rga_fmt *fmt; - fmt = rga_fmt_find(f->fmt.pix.pixelformat); + fmt = rga_fmt_find(pix_fmt->pixelformat); if (!fmt) fmt = &formats[0]; - pix_fmt->pixelformat = fmt->fourcc; - - pix_fmt->field = V4L2_FIELD_NONE; - pix_fmt->width = clamp(pix_fmt->width, (u32)MIN_WIDTH, (u32)MAX_WIDTH); pix_fmt->height = clamp(pix_fmt->height, (u32)MIN_HEIGHT, (u32)MAX_HEIGHT); - if (fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) - pix_fmt->bytesperline = pix_fmt->width; - else - pix_fmt->bytesperline = (pix_fmt->width * fmt->depth) >> 3; - - pix_fmt->sizeimage = - pix_fmt->height * (pix_fmt->width * fmt->depth) >> 3; + v4l2_fill_pixfmt_mp(pix_fmt, fmt->fourcc, pix_fmt->width, pix_fmt->height); + pix_fmt->field = V4L2_FIELD_NONE; return 0; } static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) { - struct v4l2_pix_format *pix_fmt = &f->fmt.pix; + struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; struct rga_ctx *ctx = prv; struct rockchip_rga *rga = ctx->rga; struct vb2_queue *vq; struct rga_frame *frm; int ret = 0; + int i; /* Adjust all values accordingly to the hardware capabilities * and chosen format. @@ -520,9 +509,11 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) return PTR_ERR(frm); frm->width = pix_fmt->width; frm->height = pix_fmt->height; - frm->size = pix_fmt->sizeimage; + frm->size = 0; + for (i = 0; i < pix_fmt->num_planes; i++) + frm->size += pix_fmt->plane_fmt[i].sizeimage; frm->fmt = rga_fmt_find(pix_fmt->pixelformat); - frm->stride = pix_fmt->bytesperline; + frm->stride = pix_fmt->plane_fmt[0].bytesperline; frm->colorspace = pix_fmt->colorspace; /* Reset crop settings */ @@ -537,6 +528,13 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) &frm->fmt->fourcc, frm->width, frm->height, frm->stride, frm->size); + for (i = 0; i < pix_fmt->num_planes; i++) { + v4l2_dbg(debug, 1, &rga->v4l2_dev, + "plane[%d]: size %d, bytesperline %d\n", + i, pix_fmt->plane_fmt[i].sizeimage, + pix_fmt->plane_fmt[i].bytesperline); + } + return 0; } @@ -647,14 +645,14 @@ static const struct v4l2_ioctl_ops rga_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt, + .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, + .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt, .vidioc_enum_fmt_vid_out = vidioc_enum_fmt, - .vidioc_g_fmt_vid_out = vidioc_g_fmt, - .vidioc_try_fmt_vid_out = vidioc_try_fmt, - .vidioc_s_fmt_vid_out = vidioc_s_fmt, + .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, + .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt, + .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt, .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, @@ -681,7 +679,7 @@ static const struct video_device rga_videodev = { .minor = -1, .release = video_device_release, .vfl_dir = VFL_DIR_M2M, - .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, + .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, }; static int rga_enable_clocks(struct rockchip_rga *rga) From patchwork Thu Sep 14 12:40:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 722892 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD87ECA553F for ; Thu, 14 Sep 2023 12:41:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238440AbjINMlg (ORCPT ); Thu, 14 Sep 2023 08:41:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238435AbjINMlf (ORCPT ); Thu, 14 Sep 2023 08:41:35 -0400 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02BD21FC9 for ; Thu, 14 Sep 2023 05:41:31 -0700 (PDT) Received: from dude05.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::54]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1qglet-0008Mc-IM; Thu, 14 Sep 2023 14:41:23 +0200 From: Michael Tretter Date: Thu, 14 Sep 2023 14:40:44 +0200 Subject: [PATCH 12/13] media: rockchip: rga: rework buffer handling for multi-planar formats MIME-Version: 1.0 Message-Id: <20230914-rockchip-rga-multiplanar-v1-12-abfd77260ae3@pengutronix.de> References: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> In-Reply-To: <20230914-rockchip-rga-multiplanar-v1-0-abfd77260ae3@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Shengyu Qu , Nicolas Frattaroli , Robin Murphy , Diederik de Haas Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, Michael Tretter X-Mailer: b4 0.12.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::54 X-SA-Exim-Mail-From: m.tretter@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Multi-planar formats may have multiple planes that must be handled and correctly mapped into a continuous buffer for the RGA by using the DMA descriptors. The plane offsets in the continuous mapping may now start at page boundaries and the previous calculation based on the frame sizes is only valid for planar buffers in a single memory. Therefore, the offsets must be detected and set while creating the mapping. Signed-off-by: Michael Tretter --- drivers/media/platform/rockchip/rga/rga-buf.c | 60 ++++++++++++++++++++------- drivers/media/platform/rockchip/rga/rga.c | 7 ++++ drivers/media/platform/rockchip/rga/rga.h | 1 + 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c index 137f4f4be14c..8eb89b28ba48 100644 --- a/drivers/media/platform/rockchip/rga/rga-buf.c +++ b/drivers/media/platform/rockchip/rga/rga-buf.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -42,15 +43,29 @@ rga_queue_setup(struct vb2_queue *vq, { struct rga_ctx *ctx = vb2_get_drv_priv(vq); struct rga_frame *f = rga_get_frame(ctx, vq->type); + const struct v4l2_pix_format_mplane *pix_fmt; + int i; if (IS_ERR(f)) return PTR_ERR(f); - if (*nplanes) - return sizes[0] < f->size ? -EINVAL : 0; + pix_fmt = &f->pix; - sizes[0] = f->size; - *nplanes = 1; + if (*nplanes) { + if (*nplanes != pix_fmt->num_planes) + return -EINVAL; + + for (i = 0; i < pix_fmt->num_planes; i++) + if (sizes[i] < pix_fmt->plane_fmt[i].sizeimage) + return -EINVAL; + + return 0; + } + + *nplanes = pix_fmt->num_planes; + + for (i = 0; i < pix_fmt->num_planes; i++) + sizes[i] = pix_fmt->plane_fmt[i].sizeimage; return 0; } @@ -95,23 +110,38 @@ static int rga_buf_prepare(struct vb2_buffer *vb) struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct rga_frame *f = rga_get_frame(ctx, vb->vb2_queue->type); struct rockchip_rga *rga = ctx->rga; - int n_desc; + int n_desc = 0; + int i; + const struct v4l2_format_info *info; + unsigned int offsets[VIDEO_MAX_PLANES]; if (IS_ERR(f)) return PTR_ERR(f); - vb2_set_plane_payload(vb, 0, f->size); + for (i = 0; i < vb->num_planes; i++) { + unsigned int ret; + + vb2_set_plane_payload(vb, i, f->pix.plane_fmt[i].sizeimage); - /* Create local MMU table for RGA */ - n_desc = fill_descriptors(rbuf->dma_desc, - vb2_dma_sg_plane_desc(vb, 0)); - if (n_desc < 0) { - dev_err(rga->dev, "Failed to map buffer"); - return n_desc; + /* Create local MMU table for RGA */ + ret = fill_descriptors(&rbuf->dma_desc[n_desc], + vb2_dma_sg_plane_desc(vb, i)); + if (ret < 0) { + dev_err(rga->dev, "Failed to map buffer"); + return ret; + } + offsets[i] = n_desc << PAGE_SHIFT; + n_desc += ret; } - 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); + + /* Fill the remaining planes */ + info = v4l2_format_info(f->fmt->fourcc); + for (i = info->mem_planes; i < info->comp_planes; i++) + offsets[i] = get_plane_offset(f, i); + + rbuf->offset.y_off = offsets[0]; + rbuf->offset.u_off = offsets[1]; + rbuf->offset.v_off = offsets[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.c b/drivers/media/platform/rockchip/rga/rga.c index db2160407b83..e0324341e702 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -363,6 +363,11 @@ static int rga_open(struct file *file) ctx->in = def_frame; ctx->out = def_frame; + v4l2_fill_pixfmt_mp(&ctx->in.pix, + ctx->in.fmt->fourcc, ctx->out.width, ctx->out.height); + v4l2_fill_pixfmt_mp(&ctx->out.pix, + ctx->out.fmt->fourcc, ctx->out.width, ctx->out.height); + if (mutex_lock_interruptible(&rga->mutex)) { kfree(ctx); return -ERESTARTSYS; @@ -522,6 +527,8 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) frm->crop.width = frm->width; frm->crop.height = frm->height; + frm->pix = *pix_fmt; + v4l2_dbg(debug, 1, &rga->v4l2_dev, "[%s] fmt - %p4cc %dx%d (stride %d, sizeimage %d)\n", V4L2_TYPE_IS_OUTPUT(f->type) ? "OUTPUT" : "CAPTURE", diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h index d8e76ab9c7e4..b279483aecf8 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -34,6 +34,7 @@ struct rga_frame { /* Image format */ struct rga_fmt *fmt; + struct v4l2_pix_format_mplane pix; /* Variables that can calculated once and reused */ u32 stride;