diff --git a/drivers/media/platform/rockchip/rga/Kconfig b/drivers/media/platform/rockchip/rga/Kconfig index 727a0f6ea466..846e555829f3 100644 --- a/drivers/media/platform/rockchip/rga/Kconfig +++ b/drivers/media/platform/rockchip/rga/Kconfig @@ -3,6 +3,7 @@ config VIDEO_ROCKCHIP_RGA depends on V4L_MEM2MEM_DRIVERS depends on VIDEO_DEV depends on ARCH_ROCKCHIP || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG select VIDEOBUF2_DMA_SG select V4L2_MEM2MEM_DEV help diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c index ab9554c1c4cd..cd6904d5fe5a 100644 --- a/drivers/media/platform/rockchip/rga/rga-buf.c +++ b/drivers/media/platform/rockchip/rga/rga-buf.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "rga.h" @@ -82,6 +83,9 @@ static int rga_buf_init(struct vb2_buffer *vb) if (IS_ERR(f)) return PTR_ERR(f); + if (!rga_has_internal_iommu(rga)) + return 0; + n_desc = DIV_ROUND_UP(f->size, PAGE_SIZE); rbuf->n_desc = n_desc; @@ -136,17 +140,21 @@ static int rga_buf_prepare(struct vb2_buffer *vb) for (i = 0; i < vb->num_planes; i++) { 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[curr_desc], - rbuf->n_desc - curr_desc, - vb2_dma_sg_plane_desc(vb, i)); - if (n_desc < 0) { - v4l2_err(&ctx->rga->v4l2_dev, - "Failed to map video buffer to RGA\n"); - return n_desc; + if (rga_has_internal_iommu(ctx->rga)) { + /* Create local MMU table for RGA */ + n_desc = fill_descriptors(&rbuf->dma_desc[curr_desc], + rbuf->n_desc - curr_desc, + vb2_dma_sg_plane_desc(vb, i)); + if (n_desc < 0) { + v4l2_err(&ctx->rga->v4l2_dev, + "Failed to map video buffer to RGA\n"); + return n_desc; + } + dma_addrs[i] = curr_desc << PAGE_SHIFT; + curr_desc += n_desc; + } else { + dma_addrs[i] = vb2_dma_contig_plane_dma_addr(vb, i); } - dma_addrs[i] = curr_desc << PAGE_SHIFT; - curr_desc += n_desc; } /* Fill the remaining planes */ @@ -176,6 +184,9 @@ static void rga_buf_cleanup(struct vb2_buffer *vb) struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct rockchip_rga *rga = ctx->rga; + if (!rga_has_internal_iommu(rga)) + return; + dma_free_coherent(rga->dev, rbuf->n_desc * sizeof(*rbuf->dma_desc), rbuf->dma_desc, 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 99cf57d5ba89..73584706a47e 100644 --- a/drivers/media/platform/rockchip/rga/rga-hw.c +++ b/drivers/media/platform/rockchip/rga/rga-hw.c @@ -577,6 +577,7 @@ static struct rga_fmt formats[] = { const struct rga_hw rga2_hw = { .card_type = "rga2", + .has_internal_iommu = true, .formats = formats, .num_formats = ARRAY_SIZE(formats), .cmdbuf_size = RGA_CMDBUF_SIZE, diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 91775b43ff61..e3c99c3f7c5b 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "rga.h" @@ -98,7 +99,10 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) src_vq->io_modes = VB2_MMAP | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->ops = &rga_qops; - src_vq->mem_ops = &vb2_dma_sg_memops; + if (rga_has_internal_iommu(ctx->rga)) + src_vq->mem_ops = &vb2_dma_sg_memops; + else + src_vq->mem_ops = &vb2_dma_contig_memops; src_vq->gfp_flags = __GFP_DMA32; src_vq->buf_struct_size = sizeof(struct rga_vb_buffer); src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; @@ -113,7 +117,10 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->ops = &rga_qops; - dst_vq->mem_ops = &vb2_dma_sg_memops; + if (rga_has_internal_iommu(ctx->rga)) + dst_vq->mem_ops = &vb2_dma_sg_memops; + else + dst_vq->mem_ops = &vb2_dma_contig_memops; dst_vq->gfp_flags = __GFP_DMA32; dst_vq->buf_struct_size = sizeof(struct rga_vb_buffer); dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h index bf21a57555a5..b180df5c4837 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -150,6 +150,7 @@ static inline void rga_mod(struct rockchip_rga *rga, u32 reg, u32 val, u32 mask) struct rga_hw { const char *card_type; + bool has_internal_iommu; struct rga_fmt *formats; u32 num_formats; size_t cmdbuf_size; @@ -165,6 +166,11 @@ struct rga_hw { void (*get_version)(struct rockchip_rga *rga); }; +static inline bool rga_has_internal_iommu(const struct rockchip_rga *rga) +{ + return rga->hw->has_internal_iommu; +} + extern const struct rga_hw rga2_hw; #endif