1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co.Ltd
4 * Author: Jacob Chen <jacob-chen@iotwrt.com>
7 #include <linux/pm_runtime.h>
9 #include <media/v4l2-device.h>
10 #include <media/v4l2-ioctl.h>
11 #include <media/v4l2-mem2mem.h>
12 #include <media/videobuf2-dma-sg.h>
13 #include <media/videobuf2-v4l2.h>
19 rga_queue_setup(struct vb2_queue
*vq
,
20 unsigned int *nbuffers
, unsigned int *nplanes
,
21 unsigned int sizes
[], struct device
*alloc_devs
[])
23 struct rga_ctx
*ctx
= vb2_get_drv_priv(vq
);
24 struct rga_frame
*f
= rga_get_frame(ctx
, vq
->type
);
30 return sizes
[0] < f
->size
? -EINVAL
: 0;
38 static int rga_buf_prepare(struct vb2_buffer
*vb
)
40 struct rga_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
41 struct rga_frame
*f
= rga_get_frame(ctx
, vb
->vb2_queue
->type
);
46 vb2_set_plane_payload(vb
, 0, f
->size
);
51 static void rga_buf_queue(struct vb2_buffer
*vb
)
53 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
54 struct rga_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
56 v4l2_m2m_buf_queue(ctx
->fh
.m2m_ctx
, vbuf
);
59 static void rga_buf_return_buffers(struct vb2_queue
*q
,
60 enum vb2_buffer_state state
)
62 struct rga_ctx
*ctx
= vb2_get_drv_priv(q
);
63 struct vb2_v4l2_buffer
*vbuf
;
66 if (V4L2_TYPE_IS_OUTPUT(q
->type
))
67 vbuf
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
69 vbuf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
72 v4l2_m2m_buf_done(vbuf
, state
);
76 static int rga_buf_start_streaming(struct vb2_queue
*q
, unsigned int count
)
78 struct rga_ctx
*ctx
= vb2_get_drv_priv(q
);
79 struct rockchip_rga
*rga
= ctx
->rga
;
82 ret
= pm_runtime_get_sync(rga
->dev
);
84 pm_runtime_put_noidle(rga
->dev
);
85 rga_buf_return_buffers(q
, VB2_BUF_STATE_QUEUED
);
92 static void rga_buf_stop_streaming(struct vb2_queue
*q
)
94 struct rga_ctx
*ctx
= vb2_get_drv_priv(q
);
95 struct rockchip_rga
*rga
= ctx
->rga
;
97 rga_buf_return_buffers(q
, VB2_BUF_STATE_ERROR
);
98 pm_runtime_put(rga
->dev
);
101 const struct vb2_ops rga_qops
= {
102 .queue_setup
= rga_queue_setup
,
103 .buf_prepare
= rga_buf_prepare
,
104 .buf_queue
= rga_buf_queue
,
105 .wait_prepare
= vb2_ops_wait_prepare
,
106 .wait_finish
= vb2_ops_wait_finish
,
107 .start_streaming
= rga_buf_start_streaming
,
108 .stop_streaming
= rga_buf_stop_streaming
,
111 /* RGA MMU is a 1-Level MMU, so it can't be used through the IOMMU API.
112 * We use it more like a scatter-gather list.
114 void rga_buf_map(struct vb2_buffer
*vb
)
116 struct rga_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
117 struct rockchip_rga
*rga
= ctx
->rga
;
118 struct sg_table
*sgt
;
119 struct scatterlist
*sgl
;
121 unsigned int address
, len
, i
, p
;
122 unsigned int mapped_size
= 0;
124 if (vb
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
)
125 pages
= rga
->src_mmu_pages
;
127 pages
= rga
->dst_mmu_pages
;
129 /* Create local MMU table for RGA */
130 sgt
= vb2_plane_cookie(vb
, 0);
132 for_each_sg(sgt
->sgl
, sgl
, sgt
->nents
, i
) {
133 len
= sg_dma_len(sgl
) >> PAGE_SHIFT
;
134 address
= sg_phys(sgl
);
136 for (p
= 0; p
< len
; p
++) {
137 dma_addr_t phys
= address
+
138 ((dma_addr_t
)p
<< PAGE_SHIFT
);
140 pages
[mapped_size
+ p
] = phys
;
146 /* sync local MMU table for RGA */
147 dma_sync_single_for_device(rga
->dev
, virt_to_phys(pages
),
148 8 * PAGE_SIZE
, DMA_BIDIRECTIONAL
);