2 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co.Ltd
3 * Author: Jacob Chen <jacob-chen@iotwrt.com>
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/pm_runtime.h>
17 #include <media/v4l2-device.h>
18 #include <media/v4l2-ioctl.h>
19 #include <media/v4l2-mem2mem.h>
20 #include <media/videobuf2-dma-sg.h>
21 #include <media/videobuf2-v4l2.h>
27 rga_queue_setup(struct vb2_queue
*vq
,
28 unsigned int *nbuffers
, unsigned int *nplanes
,
29 unsigned int sizes
[], struct device
*alloc_devs
[])
31 struct rga_ctx
*ctx
= vb2_get_drv_priv(vq
);
32 struct rga_frame
*f
= rga_get_frame(ctx
, vq
->type
);
38 return sizes
[0] < f
->size
? -EINVAL
: 0;
46 static int rga_buf_prepare(struct vb2_buffer
*vb
)
48 struct rga_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
49 struct rga_frame
*f
= rga_get_frame(ctx
, vb
->vb2_queue
->type
);
54 vb2_set_plane_payload(vb
, 0, f
->size
);
59 static void rga_buf_queue(struct vb2_buffer
*vb
)
61 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
62 struct rga_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
64 v4l2_m2m_buf_queue(ctx
->fh
.m2m_ctx
, vbuf
);
67 static int rga_buf_start_streaming(struct vb2_queue
*q
, unsigned int count
)
69 struct rga_ctx
*ctx
= vb2_get_drv_priv(q
);
70 struct rockchip_rga
*rga
= ctx
->rga
;
73 ret
= pm_runtime_get_sync(rga
->dev
);
78 for (i
= 0; i
< q
->num_buffers
; ++i
) {
79 if (q
->bufs
[i
]->state
== VB2_BUF_STATE_ACTIVE
) {
80 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q
->bufs
[i
]),
81 VB2_BUF_STATE_QUEUED
);
88 static void rga_buf_stop_streaming(struct vb2_queue
*q
)
90 struct rga_ctx
*ctx
= vb2_get_drv_priv(q
);
91 struct rockchip_rga
*rga
= ctx
->rga
;
92 struct vb2_v4l2_buffer
*vbuf
;
95 if (V4L2_TYPE_IS_OUTPUT(q
->type
))
96 vbuf
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
98 vbuf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
101 v4l2_m2m_buf_done(vbuf
, VB2_BUF_STATE_ERROR
);
104 pm_runtime_put(rga
->dev
);
107 const struct vb2_ops rga_qops
= {
108 .queue_setup
= rga_queue_setup
,
109 .buf_prepare
= rga_buf_prepare
,
110 .buf_queue
= rga_buf_queue
,
111 .wait_prepare
= vb2_ops_wait_prepare
,
112 .wait_finish
= vb2_ops_wait_finish
,
113 .start_streaming
= rga_buf_start_streaming
,
114 .stop_streaming
= rga_buf_stop_streaming
,
117 /* RGA MMU is a 1-Level MMU, so it can't be used through the IOMMU API.
118 * We use it more like a scatter-gather list.
120 void rga_buf_map(struct vb2_buffer
*vb
)
122 struct rga_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
123 struct rockchip_rga
*rga
= ctx
->rga
;
124 struct sg_table
*sgt
;
125 struct scatterlist
*sgl
;
127 unsigned int address
, len
, i
, p
;
128 unsigned int mapped_size
= 0;
130 if (vb
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
)
131 pages
= rga
->src_mmu_pages
;
133 pages
= rga
->dst_mmu_pages
;
135 /* Create local MMU table for RGA */
136 sgt
= vb2_plane_cookie(vb
, 0);
138 for_each_sg(sgt
->sgl
, sgl
, sgt
->nents
, i
) {
139 len
= sg_dma_len(sgl
) >> PAGE_SHIFT
;
140 address
= sg_phys(sgl
);
142 for (p
= 0; p
< len
; p
++) {
143 dma_addr_t phys
= address
+ (p
<< PAGE_SHIFT
);
145 pages
[mapped_size
+ p
] = phys
;
151 /* sync local MMU table for RGA */
152 dma_sync_single_for_device(rga
->dev
, virt_to_phys(pages
),
153 8 * PAGE_SIZE
, DMA_BIDIRECTIONAL
);