xref: /rockchip-linux_mpp/mpp/vproc/rga/rga.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #include <sys/types.h>
7*437bfbebSnyanmisaka #include <sys/stat.h>
8*437bfbebSnyanmisaka #include <sys/ioctl.h>
9*437bfbebSnyanmisaka #include <errno.h>
10*437bfbebSnyanmisaka #include <string.h>
11*437bfbebSnyanmisaka #include <stdint.h>
12*437bfbebSnyanmisaka 
13*437bfbebSnyanmisaka #include "mpp_mem.h"
14*437bfbebSnyanmisaka #include "mpp_debug.h"
15*437bfbebSnyanmisaka #include "mpp_common.h"
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #include "rga.h"
18*437bfbebSnyanmisaka #include "rga_api.h"
19*437bfbebSnyanmisaka 
20*437bfbebSnyanmisaka static RK_U32 rga_debug = 0;
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #define RGB_DBG_FUNCTION    (0x00000001)
23*437bfbebSnyanmisaka #define RGB_DBG_COPY        (0x00000002)
24*437bfbebSnyanmisaka #define RGB_DBG_DUP_FIELD   (0x00000004)
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #define rga_dbg(flag, fmt, ...) _mpp_dbg(rga_debug, flag, fmt, ## __VA_ARGS__)
27*437bfbebSnyanmisaka #define rga_dbg_func(fmt, ...)  _mpp_dbg_f(rga_debug, RGB_DBG_FUNCTION, fmt, ## __VA_ARGS__)
28*437bfbebSnyanmisaka #define rga_dbg_copy(fmt, ...)  _mpp_dbg(rga_debug, RGB_DBG_COPY, fmt, ## __VA_ARGS__)
29*437bfbebSnyanmisaka #define rga_dbg_dup(fmt, ...)   _mpp_dbg(rga_debug, RGB_DBG_COPY, fmt, ## __VA_ARGS__)
30*437bfbebSnyanmisaka 
31*437bfbebSnyanmisaka #define DEFAULT_RGA_DEV     "/dev/rga"
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka typedef struct RgaCtxImpl_t {
34*437bfbebSnyanmisaka     RK_S32 rga_fd;
35*437bfbebSnyanmisaka 
36*437bfbebSnyanmisaka     // context holds only one request structure and serial process all input
37*437bfbebSnyanmisaka     RgaReq request;
38*437bfbebSnyanmisaka } RgaCtxImpl;
39*437bfbebSnyanmisaka 
is_yuv_format(int fmt)40*437bfbebSnyanmisaka static int is_yuv_format(int fmt)
41*437bfbebSnyanmisaka {
42*437bfbebSnyanmisaka     if (fmt >= RGA_FMT_YCbCr_422_SP && fmt <= RGA_FMT_YCrCb_420_P) {
43*437bfbebSnyanmisaka         return 1;
44*437bfbebSnyanmisaka     }
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     return 0;
47*437bfbebSnyanmisaka }
48*437bfbebSnyanmisaka 
is_rgb_format(int fmt)49*437bfbebSnyanmisaka static int is_rgb_format(int fmt)
50*437bfbebSnyanmisaka {
51*437bfbebSnyanmisaka     if (fmt >= RGA_FMT_RGBA_8888 && fmt <= RGA_FMT_BGR_888) {
52*437bfbebSnyanmisaka         return 1;
53*437bfbebSnyanmisaka     }
54*437bfbebSnyanmisaka 
55*437bfbebSnyanmisaka     return 0;
56*437bfbebSnyanmisaka }
57*437bfbebSnyanmisaka 
rga_fmt_map(MppFrameFormat fmt)58*437bfbebSnyanmisaka static RgaFormat rga_fmt_map(MppFrameFormat fmt)
59*437bfbebSnyanmisaka {
60*437bfbebSnyanmisaka     RgaFormat ret;
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka     switch (fmt) {
63*437bfbebSnyanmisaka     case MPP_FMT_YUV420P:
64*437bfbebSnyanmisaka         ret = RGA_FMT_YCbCr_420_P;
65*437bfbebSnyanmisaka         break;
66*437bfbebSnyanmisaka     case MPP_FMT_YUV420SP:
67*437bfbebSnyanmisaka         ret = RGA_FMT_YCbCr_420_SP;
68*437bfbebSnyanmisaka         break;
69*437bfbebSnyanmisaka     case MPP_FMT_YUV422P:
70*437bfbebSnyanmisaka         ret = RGA_FMT_YCbCr_422_P;
71*437bfbebSnyanmisaka         break;
72*437bfbebSnyanmisaka     case MPP_FMT_YUV422SP:
73*437bfbebSnyanmisaka         ret = RGA_FMT_YCrCb_422_SP;
74*437bfbebSnyanmisaka         break;
75*437bfbebSnyanmisaka     case MPP_FMT_RGB565:
76*437bfbebSnyanmisaka         ret = RGA_FMT_RGB_565;
77*437bfbebSnyanmisaka         break;
78*437bfbebSnyanmisaka     case MPP_FMT_RGB888:
79*437bfbebSnyanmisaka         ret = RGA_FMT_RGB_888;
80*437bfbebSnyanmisaka         break;
81*437bfbebSnyanmisaka     case MPP_FMT_ARGB8888:
82*437bfbebSnyanmisaka         ret = RGA_FMT_RGBA_8888;
83*437bfbebSnyanmisaka         break;
84*437bfbebSnyanmisaka     default:
85*437bfbebSnyanmisaka         ret = RGA_FMT_BUTT;
86*437bfbebSnyanmisaka         mpp_err("unsupport mpp fmt %d found\n", fmt);
87*437bfbebSnyanmisaka         break;
88*437bfbebSnyanmisaka     }
89*437bfbebSnyanmisaka 
90*437bfbebSnyanmisaka     return ret;
91*437bfbebSnyanmisaka }
92*437bfbebSnyanmisaka 
rga_init(RgaCtx * ctx)93*437bfbebSnyanmisaka MPP_RET rga_init(RgaCtx *ctx)
94*437bfbebSnyanmisaka {
95*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
96*437bfbebSnyanmisaka     RgaCtxImpl *impl = NULL;
97*437bfbebSnyanmisaka 
98*437bfbebSnyanmisaka     rga_dbg_func("in\n");
99*437bfbebSnyanmisaka 
100*437bfbebSnyanmisaka     *ctx = NULL;
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka     impl = mpp_malloc(RgaCtxImpl, 1);
103*437bfbebSnyanmisaka     if (!impl) {
104*437bfbebSnyanmisaka         mpp_err_f("malloc context failed\n");
105*437bfbebSnyanmisaka         ret = MPP_ERR_NULL_PTR;
106*437bfbebSnyanmisaka         goto END;
107*437bfbebSnyanmisaka     }
108*437bfbebSnyanmisaka 
109*437bfbebSnyanmisaka     impl->rga_fd = open(DEFAULT_RGA_DEV, O_RDWR | O_CLOEXEC, 0);
110*437bfbebSnyanmisaka     if (impl->rga_fd < 0) {
111*437bfbebSnyanmisaka         mpp_err_f("open device failed\n");
112*437bfbebSnyanmisaka         mpp_free(impl);
113*437bfbebSnyanmisaka         impl = NULL;
114*437bfbebSnyanmisaka         ret = MPP_ERR_OPEN_FILE;
115*437bfbebSnyanmisaka         goto END;
116*437bfbebSnyanmisaka     }
117*437bfbebSnyanmisaka 
118*437bfbebSnyanmisaka END:
119*437bfbebSnyanmisaka     *ctx = impl;
120*437bfbebSnyanmisaka     rga_dbg_func("out\n");
121*437bfbebSnyanmisaka     return ret;
122*437bfbebSnyanmisaka }
123*437bfbebSnyanmisaka 
rga_deinit(RgaCtx ctx)124*437bfbebSnyanmisaka MPP_RET rga_deinit(RgaCtx ctx)
125*437bfbebSnyanmisaka {
126*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
127*437bfbebSnyanmisaka     RgaCtxImpl *impl = NULL;
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     rga_dbg_func("in\n");
130*437bfbebSnyanmisaka 
131*437bfbebSnyanmisaka     impl = (RgaCtxImpl *)ctx;
132*437bfbebSnyanmisaka     if (!impl) {
133*437bfbebSnyanmisaka         mpp_err_f("invalid input");
134*437bfbebSnyanmisaka         ret = MPP_ERR_NULL_PTR;
135*437bfbebSnyanmisaka         goto END;
136*437bfbebSnyanmisaka     }
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka     if (impl->rga_fd >= 0) {
139*437bfbebSnyanmisaka         close(impl->rga_fd);
140*437bfbebSnyanmisaka         impl->rga_fd = -1;
141*437bfbebSnyanmisaka     }
142*437bfbebSnyanmisaka 
143*437bfbebSnyanmisaka     mpp_free(impl);
144*437bfbebSnyanmisaka END:
145*437bfbebSnyanmisaka     rga_dbg_func("out\n");
146*437bfbebSnyanmisaka     return ret;
147*437bfbebSnyanmisaka }
148*437bfbebSnyanmisaka 
rga_ioctl(RgaCtxImpl * impl)149*437bfbebSnyanmisaka static MPP_RET rga_ioctl(RgaCtxImpl *impl)
150*437bfbebSnyanmisaka {
151*437bfbebSnyanmisaka     int io_ret = ioctl(impl->rga_fd, RGA_BLIT_SYNC, &impl->request);
152*437bfbebSnyanmisaka     if (io_ret) {
153*437bfbebSnyanmisaka         mpp_err("rga ioctl failed errno:%d %s", errno, strerror(errno));
154*437bfbebSnyanmisaka         return MPP_NOK;
155*437bfbebSnyanmisaka     }
156*437bfbebSnyanmisaka 
157*437bfbebSnyanmisaka     return MPP_OK;
158*437bfbebSnyanmisaka }
159*437bfbebSnyanmisaka 
config_rga_image(RgaImg * img,MppFrame frame)160*437bfbebSnyanmisaka static MPP_RET config_rga_image(RgaImg *img, MppFrame frame)
161*437bfbebSnyanmisaka {
162*437bfbebSnyanmisaka     RgaFormat fmt = rga_fmt_map(mpp_frame_get_fmt(frame));
163*437bfbebSnyanmisaka     MppBuffer buf = mpp_frame_get_buffer(frame);
164*437bfbebSnyanmisaka     RK_U32 width  = mpp_frame_get_width(frame);
165*437bfbebSnyanmisaka     RK_U32 height = mpp_frame_get_height(frame);
166*437bfbebSnyanmisaka     RK_U32 h_str  = mpp_frame_get_hor_stride(frame);
167*437bfbebSnyanmisaka     RK_U32 v_str  = mpp_frame_get_ver_stride(frame);
168*437bfbebSnyanmisaka     RK_S32 fd = mpp_buffer_get_fd(buf);
169*437bfbebSnyanmisaka 
170*437bfbebSnyanmisaka     if (fmt >= RGA_FMT_BUTT) {
171*437bfbebSnyanmisaka         mpp_err("invalid input format for rga process %d\n", fmt);
172*437bfbebSnyanmisaka         return MPP_NOK;
173*437bfbebSnyanmisaka     }
174*437bfbebSnyanmisaka 
175*437bfbebSnyanmisaka     memset(img, 0, sizeof(RgaImg));
176*437bfbebSnyanmisaka     img->yrgb_addr = fd;
177*437bfbebSnyanmisaka     img->format = (RK_U32)fmt;
178*437bfbebSnyanmisaka     img->act_w = width;
179*437bfbebSnyanmisaka     img->act_h = height;
180*437bfbebSnyanmisaka     img->vir_w = h_str;
181*437bfbebSnyanmisaka     img->vir_h = v_str;
182*437bfbebSnyanmisaka 
183*437bfbebSnyanmisaka     return MPP_OK;
184*437bfbebSnyanmisaka }
185*437bfbebSnyanmisaka 
config_rga_yuv2rgb_mode(RgaCtx ctx)186*437bfbebSnyanmisaka static MPP_RET config_rga_yuv2rgb_mode(RgaCtx ctx)
187*437bfbebSnyanmisaka {
188*437bfbebSnyanmisaka     RgaCtxImpl *impl = (RgaCtxImpl *)ctx;
189*437bfbebSnyanmisaka     RgaReq *request = &impl->request;
190*437bfbebSnyanmisaka 
191*437bfbebSnyanmisaka     /*
192*437bfbebSnyanmisaka      * yuv2rgb_mode only set when translate yuv to rgb, or rga to yuv.
193*437bfbebSnyanmisaka      * If format of input and output are both yuv or rga, set yuv2rgb_mode to 0.
194*437bfbebSnyanmisaka      */
195*437bfbebSnyanmisaka     int src_format = request->src.format;
196*437bfbebSnyanmisaka     int dst_format = request->dst.format;
197*437bfbebSnyanmisaka 
198*437bfbebSnyanmisaka     request->yuv2rgb_mode = 0;
199*437bfbebSnyanmisaka     if (is_yuv_format(src_format) && is_rgb_format(dst_format)) {
200*437bfbebSnyanmisaka         /* Special config for yuv to rgb */
201*437bfbebSnyanmisaka         request->yuv2rgb_mode |= 0x1 << 0;
202*437bfbebSnyanmisaka     } else if (is_rgb_format(src_format) && is_yuv_format(dst_format)) {
203*437bfbebSnyanmisaka         /* Special config for rgb to yuv */
204*437bfbebSnyanmisaka         request->yuv2rgb_mode = (2 << 4);
205*437bfbebSnyanmisaka     }
206*437bfbebSnyanmisaka 
207*437bfbebSnyanmisaka     return MPP_OK;
208*437bfbebSnyanmisaka }
209*437bfbebSnyanmisaka 
rga_control(RgaCtx ctx,RgaCmd cmd,void * param)210*437bfbebSnyanmisaka MPP_RET rga_control(RgaCtx ctx, RgaCmd cmd, void *param)
211*437bfbebSnyanmisaka {
212*437bfbebSnyanmisaka     if (NULL == ctx) {
213*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input\n");
214*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
215*437bfbebSnyanmisaka     }
216*437bfbebSnyanmisaka 
217*437bfbebSnyanmisaka     rga_dbg_func("in\n");
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
220*437bfbebSnyanmisaka     RgaCtxImpl *impl = (RgaCtxImpl *)ctx;
221*437bfbebSnyanmisaka     RgaReq *request = &impl->request;
222*437bfbebSnyanmisaka 
223*437bfbebSnyanmisaka     switch (cmd) {
224*437bfbebSnyanmisaka     case RGA_CMD_INIT : {
225*437bfbebSnyanmisaka         memset(request, 0, sizeof(*request));
226*437bfbebSnyanmisaka         request->mmu_info.mmu_en = 1;
227*437bfbebSnyanmisaka         request->mmu_info.mmu_flag = 1;
228*437bfbebSnyanmisaka         request->mmu_info.mmu_flag = ((2 & 0x3) << 4) | 1;
229*437bfbebSnyanmisaka         request->mmu_info.mmu_flag |= (1 << 31) | (1 << 10) | (1 << 8);
230*437bfbebSnyanmisaka     } break;
231*437bfbebSnyanmisaka     case RGA_CMD_SET_SRC : {
232*437bfbebSnyanmisaka         if (NULL == param) {
233*437bfbebSnyanmisaka             mpp_err("invalid NULL param for setup source\n");
234*437bfbebSnyanmisaka             ret = MPP_NOK;
235*437bfbebSnyanmisaka             break;
236*437bfbebSnyanmisaka         }
237*437bfbebSnyanmisaka 
238*437bfbebSnyanmisaka         MppFrame *src = (MppFrame *)param;
239*437bfbebSnyanmisaka         ret = config_rga_image(&request->src, src);
240*437bfbebSnyanmisaka     } break;
241*437bfbebSnyanmisaka     case RGA_CMD_SET_DST : {
242*437bfbebSnyanmisaka         if (NULL == param) {
243*437bfbebSnyanmisaka             mpp_err("invalid NULL param for setup destination\n");
244*437bfbebSnyanmisaka             ret = MPP_NOK;
245*437bfbebSnyanmisaka             break;
246*437bfbebSnyanmisaka         }
247*437bfbebSnyanmisaka 
248*437bfbebSnyanmisaka         MppFrame *dst = (MppFrame *)param;
249*437bfbebSnyanmisaka         ret = config_rga_image(&request->dst, dst);
250*437bfbebSnyanmisaka         // When config dst setup default clip
251*437bfbebSnyanmisaka         RK_U32 width  = mpp_frame_get_width(dst);
252*437bfbebSnyanmisaka         RK_U32 height = mpp_frame_get_height(dst);
253*437bfbebSnyanmisaka         request->clip.xmin = 0;
254*437bfbebSnyanmisaka         request->clip.xmax = width - 1;
255*437bfbebSnyanmisaka         request->clip.ymin = 0;
256*437bfbebSnyanmisaka         request->clip.ymax = height - 1;
257*437bfbebSnyanmisaka     } break;
258*437bfbebSnyanmisaka     case RGA_CMD_RUN_SYNC : {
259*437bfbebSnyanmisaka         config_rga_yuv2rgb_mode(ctx);
260*437bfbebSnyanmisaka         ret = rga_ioctl(impl);
261*437bfbebSnyanmisaka     } break;
262*437bfbebSnyanmisaka     default : {
263*437bfbebSnyanmisaka         mpp_err("invalid command %d\n", cmd);
264*437bfbebSnyanmisaka         ret = MPP_NOK;
265*437bfbebSnyanmisaka     } break;
266*437bfbebSnyanmisaka     }
267*437bfbebSnyanmisaka 
268*437bfbebSnyanmisaka     rga_dbg_func("out\n");
269*437bfbebSnyanmisaka     return ret;
270*437bfbebSnyanmisaka }
271*437bfbebSnyanmisaka 
272*437bfbebSnyanmisaka // sample for copy function
rga_copy(RgaCtx ctx,MppFrame src,MppFrame dst)273*437bfbebSnyanmisaka MPP_RET rga_copy(RgaCtx ctx, MppFrame src, MppFrame dst)
274*437bfbebSnyanmisaka {
275*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
276*437bfbebSnyanmisaka     RgaCtxImpl *impl = (RgaCtxImpl *)ctx;
277*437bfbebSnyanmisaka     MppBuffer src_buf = mpp_frame_get_buffer(src);
278*437bfbebSnyanmisaka     MppBuffer dst_buf = mpp_frame_get_buffer(dst);
279*437bfbebSnyanmisaka     RK_U32 src_w = mpp_frame_get_width(src);
280*437bfbebSnyanmisaka     RK_U32 src_h = mpp_frame_get_height(src);
281*437bfbebSnyanmisaka     RK_U32 dst_w = mpp_frame_get_width(dst);
282*437bfbebSnyanmisaka     RK_U32 dst_h = mpp_frame_get_height(dst);
283*437bfbebSnyanmisaka     RK_S32 src_fd = mpp_buffer_get_fd(src_buf);
284*437bfbebSnyanmisaka     RK_S32 dst_fd = mpp_buffer_get_fd(dst_buf);
285*437bfbebSnyanmisaka     RgaReq *request = &impl->request;
286*437bfbebSnyanmisaka 
287*437bfbebSnyanmisaka     RgaFormat src_fmt = rga_fmt_map(mpp_frame_get_fmt(src));
288*437bfbebSnyanmisaka     RgaFormat dst_fmt = rga_fmt_map(mpp_frame_get_fmt(dst));
289*437bfbebSnyanmisaka 
290*437bfbebSnyanmisaka     rga_dbg_func("in\n");
291*437bfbebSnyanmisaka 
292*437bfbebSnyanmisaka     if (src_fmt >= RGA_FMT_BUTT || dst_fmt >= RGA_FMT_BUTT) {
293*437bfbebSnyanmisaka         mpp_err("invalid input format for rga process src %d dst %d\n",
294*437bfbebSnyanmisaka                 src_fmt, dst_fmt);
295*437bfbebSnyanmisaka         ret = MPP_NOK;
296*437bfbebSnyanmisaka         goto END;
297*437bfbebSnyanmisaka     }
298*437bfbebSnyanmisaka 
299*437bfbebSnyanmisaka     mpp_assert(src_w > 0 && src_h > 0);
300*437bfbebSnyanmisaka 
301*437bfbebSnyanmisaka     if (dst_w == 0 || dst_h == 0) {
302*437bfbebSnyanmisaka         dst_w = src_w;
303*437bfbebSnyanmisaka         dst_h = src_h;
304*437bfbebSnyanmisaka     }
305*437bfbebSnyanmisaka 
306*437bfbebSnyanmisaka     rga_dbg_copy("[fd:w:h:fmt] src - %d:%d:%d:%d dst - %d:%d:%d:%d\n",
307*437bfbebSnyanmisaka                  src_fd, src_w, src_h, src_fmt,
308*437bfbebSnyanmisaka                  dst_fd, dst_w, dst_h, dst_fmt);
309*437bfbebSnyanmisaka 
310*437bfbebSnyanmisaka     memset(request, 0, sizeof(*request));
311*437bfbebSnyanmisaka     request->src.yrgb_addr = src_fd;
312*437bfbebSnyanmisaka     request->src.format = (RK_U32)src_fmt;
313*437bfbebSnyanmisaka     request->src.vir_w = mpp_frame_get_hor_stride(src);
314*437bfbebSnyanmisaka     request->src.vir_h = mpp_frame_get_ver_stride(src);
315*437bfbebSnyanmisaka     request->src.act_w = src_w;
316*437bfbebSnyanmisaka     request->src.act_h = src_h;
317*437bfbebSnyanmisaka 
318*437bfbebSnyanmisaka     request->dst.yrgb_addr = dst_fd;
319*437bfbebSnyanmisaka     request->dst.vir_w = dst_w;
320*437bfbebSnyanmisaka     request->dst.vir_h = dst_h;
321*437bfbebSnyanmisaka     request->dst.format = (RK_U32)dst_fmt;
322*437bfbebSnyanmisaka     request->clip.xmin = 0;
323*437bfbebSnyanmisaka     request->clip.xmax = dst_w - 1;
324*437bfbebSnyanmisaka     request->clip.ymin = 0;
325*437bfbebSnyanmisaka     request->clip.ymax = dst_h - 1;
326*437bfbebSnyanmisaka     request->dst.act_w = dst_w;
327*437bfbebSnyanmisaka     request->dst.act_h = dst_h;
328*437bfbebSnyanmisaka 
329*437bfbebSnyanmisaka     config_rga_yuv2rgb_mode(ctx);
330*437bfbebSnyanmisaka 
331*437bfbebSnyanmisaka     request->mmu_info.mmu_en = 1;
332*437bfbebSnyanmisaka     request->mmu_info.mmu_flag = 1;
333*437bfbebSnyanmisaka     request->mmu_info.mmu_flag = ((2 & 0x3) << 4) | 1;
334*437bfbebSnyanmisaka     request->mmu_info.mmu_flag |= (1 << 31) | (1 << 10) | (1 << 8);
335*437bfbebSnyanmisaka 
336*437bfbebSnyanmisaka     ret = rga_ioctl(impl);
337*437bfbebSnyanmisaka END:
338*437bfbebSnyanmisaka     rga_dbg_func("out\n");
339*437bfbebSnyanmisaka     return ret;
340*437bfbebSnyanmisaka }
341*437bfbebSnyanmisaka 
342*437bfbebSnyanmisaka // sample for duplicate field to frame function
rga_dup_field(RgaCtx ctx,MppFrame frame)343*437bfbebSnyanmisaka MPP_RET rga_dup_field(RgaCtx ctx, MppFrame frame)
344*437bfbebSnyanmisaka {
345*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
346*437bfbebSnyanmisaka     RgaCtxImpl *impl = (RgaCtxImpl *)ctx;
347*437bfbebSnyanmisaka     MppBuffer buf = mpp_frame_get_buffer(frame);
348*437bfbebSnyanmisaka     RK_U32 width  = mpp_frame_get_width(frame);
349*437bfbebSnyanmisaka     RK_U32 height = mpp_frame_get_height(frame);
350*437bfbebSnyanmisaka     RK_U32 h_str  = mpp_frame_get_hor_stride(frame);
351*437bfbebSnyanmisaka     RK_U32 v_str  = mpp_frame_get_ver_stride(frame);
352*437bfbebSnyanmisaka     RK_S32 fd = mpp_buffer_get_fd(buf);
353*437bfbebSnyanmisaka     void *ptr = mpp_buffer_get_ptr(buf);
354*437bfbebSnyanmisaka     RgaFormat fmt = rga_fmt_map(mpp_frame_get_fmt(frame));
355*437bfbebSnyanmisaka     RgaReq *request = &impl->request;
356*437bfbebSnyanmisaka 
357*437bfbebSnyanmisaka     rga_dbg_func("in\n");
358*437bfbebSnyanmisaka 
359*437bfbebSnyanmisaka     mpp_assert(fmt == RGA_FMT_YCbCr_420_SP);
360*437bfbebSnyanmisaka     mpp_assert(width > 0 && height > 0);
361*437bfbebSnyanmisaka     if (fmt != RGA_FMT_YCbCr_420_SP || width == 0 || height == 0) {
362*437bfbebSnyanmisaka         ret = MPP_NOK;
363*437bfbebSnyanmisaka         goto END;
364*437bfbebSnyanmisaka     }
365*437bfbebSnyanmisaka 
366*437bfbebSnyanmisaka     rga_dbg_dup("[fd:w:h:h_str:v_str:fmt] %d:%d:%d:%d:%d:%d\n",
367*437bfbebSnyanmisaka                 fd, width, height, h_str, v_str, fmt);
368*437bfbebSnyanmisaka 
369*437bfbebSnyanmisaka     memset(request, 0, sizeof(*request));
370*437bfbebSnyanmisaka     request->src.yrgb_addr = fd;
371*437bfbebSnyanmisaka     request->src.format = (RK_U32)fmt;
372*437bfbebSnyanmisaka     request->src.vir_w = h_str * 2;
373*437bfbebSnyanmisaka     request->src.vir_h = v_str / 2;
374*437bfbebSnyanmisaka     request->src.act_w = width;
375*437bfbebSnyanmisaka     request->src.act_h = height / 2;
376*437bfbebSnyanmisaka 
377*437bfbebSnyanmisaka     request->dst.yrgb_addr = 0;
378*437bfbebSnyanmisaka     request->dst.uv_addr = (RK_U32)((uintptr_t)ptr) + h_str; // special process here
379*437bfbebSnyanmisaka     request->dst.vir_w = h_str * 2;
380*437bfbebSnyanmisaka     request->dst.vir_h = v_str / 2;
381*437bfbebSnyanmisaka     request->dst.format = (RK_U32)fmt;
382*437bfbebSnyanmisaka     request->dst.act_w = width;
383*437bfbebSnyanmisaka     request->dst.act_h = height / 2;
384*437bfbebSnyanmisaka 
385*437bfbebSnyanmisaka     request->clip.xmin = 0;
386*437bfbebSnyanmisaka     request->clip.xmax = h_str * 2 - 1;
387*437bfbebSnyanmisaka     request->clip.ymin = 0;
388*437bfbebSnyanmisaka     request->clip.ymax = v_str / 2 - 1;
389*437bfbebSnyanmisaka 
390*437bfbebSnyanmisaka     request->mmu_info.mmu_en = 1;
391*437bfbebSnyanmisaka     request->mmu_info.mmu_flag = ((2 & 0x3) << 4) | 1;
392*437bfbebSnyanmisaka     request->mmu_info.mmu_flag |= (1 << 31) | (1 << 10) | (1 << 8);
393*437bfbebSnyanmisaka 
394*437bfbebSnyanmisaka     ret = rga_ioctl(impl);
395*437bfbebSnyanmisaka END:
396*437bfbebSnyanmisaka     rga_dbg_func("out\n");
397*437bfbebSnyanmisaka     return ret;
398*437bfbebSnyanmisaka }
399