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