media: rockchip: rga: extract helper to fill descriptors
authorMichael Tretter <m.tretter@pengutronix.de>
Fri, 13 Oct 2023 11:00:23 +0000 (13:00 +0200)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Thu, 7 Dec 2023 07:56:13 +0000 (08:56 +0100)
The IOMMU of the RGA is programmed with a list of DMA descriptors that
contain an 32 bit address per 4k page in the video buffers. The address
in the descriptor points to the start address of the page.

Introduce 'struct rga_dma_desc' to make the handling of the DMA
descriptors explicit instead of hiding them behind standard types.

While at it, use provided helpers for iterating the sg_table instead of
manually calculating the DMA addresses.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/platform/rockchip/rga/rga-buf.c
drivers/media/platform/rockchip/rga/rga.c
drivers/media/platform/rockchip/rga/rga.h

index 81508ed5abf34066d68d82ede28d3d81e8981da0..fc3f38f6b5e1bd9945df2b911c2aa4c00c326d32 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/pm_runtime.h>
+#include <linux/scatterlist.h>
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include "rga-hw.h"
 #include "rga.h"
 
+static size_t fill_descriptors(struct rga_dma_desc *desc, struct sg_table *sgt)
+{
+       struct sg_dma_page_iter iter;
+       struct rga_dma_desc *tmp = desc;
+       size_t n_desc = 0;
+       dma_addr_t addr;
+
+       for_each_sgtable_dma_page(sgt, &iter, 0) {
+               addr = sg_page_iter_dma_address(&iter);
+               tmp->addr = lower_32_bits(addr);
+               tmp++;
+               n_desc++;
+       }
+
+       return n_desc;
+}
+
 static int
 rga_queue_setup(struct vb2_queue *vq,
                unsigned int *nbuffers, unsigned int *nplanes,
@@ -114,11 +132,8 @@ void rga_buf_map(struct vb2_buffer *vb)
 {
        struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
        struct rockchip_rga *rga = ctx->rga;
-       struct sg_table *sgt;
-       struct scatterlist *sgl;
-       unsigned int *pages;
-       unsigned int address, len, i, p;
-       unsigned int mapped_size = 0;
+       struct rga_dma_desc *pages;
+       size_t n_desc = 0;
 
        if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
                pages = rga->src_mmu_pages;
@@ -126,23 +141,9 @@ void rga_buf_map(struct vb2_buffer *vb)
                pages = rga->dst_mmu_pages;
 
        /* Create local MMU table for RGA */
-       sgt = vb2_plane_cookie(vb, 0);
-
-       for_each_sg(sgt->sgl, sgl, sgt->nents, i) {
-               len = sg_dma_len(sgl) >> PAGE_SHIFT;
-               address = sg_phys(sgl);
-
-               for (p = 0; p < len; p++) {
-                       dma_addr_t phys = address +
-                                         ((dma_addr_t)p << PAGE_SHIFT);
-
-                       pages[mapped_size + p] = phys;
-               }
-
-               mapped_size += len;
-       }
+       n_desc = fill_descriptors(pages, vb2_dma_sg_plane_desc(vb, 0));
 
        /* sync local MMU table for RGA */
        dma_sync_single_for_device(rga->dev, virt_to_phys(pages),
-                                  8 * PAGE_SIZE, DMA_BIDIRECTIONAL);
+                                  n_desc * sizeof(*pages), DMA_BIDIRECTIONAL);
 }
index 25f5b5eebf13ff6f1a05937ed7742116459f826c..36d7f255af909df3b61ba4c370277528ece31313 100644 (file)
@@ -873,13 +873,13 @@ static int rga_probe(struct platform_device *pdev)
        }
 
        rga->src_mmu_pages =
-               (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
+               (struct rga_dma_desc *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
        if (!rga->src_mmu_pages) {
                ret = -ENOMEM;
                goto free_dma;
        }
        rga->dst_mmu_pages =
-               (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
+               (struct rga_dma_desc *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
        if (!rga->dst_mmu_pages) {
                ret = -ENOMEM;
                goto free_src_pages;
index 5fa9d2f366dc46bbc10b551076104bd2b932d28c..22f7da28ac519331ffb232b7467baacaad9d1ba3 100644 (file)
@@ -40,6 +40,10 @@ struct rga_frame {
        u32 size;
 };
 
+struct rga_dma_desc {
+       u32 addr;
+};
+
 struct rockchip_rga_version {
        u32 major;
        u32 minor;
@@ -81,8 +85,8 @@ struct rockchip_rga {
        struct rga_ctx *curr;
        dma_addr_t cmdbuf_phy;
        void *cmdbuf_virt;
-       unsigned int *src_mmu_pages;
-       unsigned int *dst_mmu_pages;
+       struct rga_dma_desc *src_mmu_pages;
+       struct rga_dma_desc *dst_mmu_pages;
 };
 
 struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type);