xref: /rockchip-linux_mpp/mpp/vproc/vdpp/vdpp.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define MODULE_TAG "vdpp"
7 
8 #include <sys/ioctl.h>
9 #include <errno.h>
10 
11 #include "mpp_buffer.h"
12 #include "mpp_env.h"
13 #include "mpp_service.h"
14 #include "mpp_platform.h"
15 
16 #include "vdpp.h"
17 
18 #define VDPP_MODE_MIN_WIDTH   (128)
19 #define VDPP_MODE_MIN_HEIGHT  (128)
20 
21 RK_U32 vdpp_debug = 0;
22 
vdpp_params_to_reg(struct vdpp_params * src_params,struct vdpp_api_ctx * ctx)23 static MPP_RET vdpp_params_to_reg(struct vdpp_params* src_params, struct vdpp_api_ctx *ctx)
24 {
25     struct vdpp_reg *dst_reg = &ctx->reg;
26     struct zme_params *zme_params = &src_params->zme_params;
27 
28     memset(dst_reg, 0, sizeof(*dst_reg));
29 
30     /* 1. set reg::common */
31     dst_reg->common.reg0.sw_vdpp_frm_en = 1;
32 
33     /* 0x0004(reg1), TODO: add debug function */
34     dst_reg->common.reg1.sw_vdpp_src_fmt = VDPP_FMT_YUV420;
35     dst_reg->common.reg1.sw_vdpp_src_yuv_swap = src_params->src_yuv_swap;
36     dst_reg->common.reg1.sw_vdpp_dst_fmt = src_params->dst_fmt;
37     dst_reg->common.reg1.sw_vdpp_dst_yuv_swap = src_params->dst_yuv_swap;
38     dst_reg->common.reg1.sw_vdpp_dbmsr_en = src_params->dmsr_params.dmsr_enable;
39 
40     /* 0x0008(reg2) */
41     dst_reg->common.reg2.sw_vdpp_working_mode = VDPP_WORK_MODE_VEP;
42 
43     /* 0x000C ~ 0x001C(reg3 ~ reg7), skip */
44     dst_reg->common.reg4.sw_vdpp_clk_on = 1;
45     dst_reg->common.reg4.sw_md_clk_on = 1;
46     dst_reg->common.reg4.sw_dect_clk_on = 1;
47     dst_reg->common.reg4.sw_me_clk_on = 1;
48     dst_reg->common.reg4.sw_mc_clk_on = 1;
49     dst_reg->common.reg4.sw_eedi_clk_on = 1;
50     dst_reg->common.reg4.sw_ble_clk_on = 1;
51     dst_reg->common.reg4.sw_out_clk_on = 1;
52     dst_reg->common.reg4.sw_ctrl_clk_on = 1;
53     dst_reg->common.reg4.sw_ram_clk_on = 1;
54     dst_reg->common.reg4.sw_dma_clk_on = 1;
55     dst_reg->common.reg4.sw_reg_clk_on = 1;
56 
57     /* 0x0020(reg8) */
58     dst_reg->common.reg8.sw_vdpp_frm_done_en = 1;
59     dst_reg->common.reg8.sw_vdpp_osd_max_en = 1;
60     dst_reg->common.reg8.sw_vdpp_bus_error_en = 1;
61     dst_reg->common.reg8.sw_vdpp_timeout_int_en = 1;
62     dst_reg->common.reg8.sw_vdpp_config_error_en = 1;
63     /* 0x0024 ~ 0x002C(reg9 ~ reg11), skip */
64     {
65         RK_U32 src_right_redundant = src_params->src_width % 16 == 0 ? 0 : 16 - src_params->src_width % 16;
66         RK_U32 src_down_redundant  = src_params->src_height % 8 == 0 ? 0 : 8 - src_params->src_height % 8;
67         RK_U32 dst_right_redundant = src_params->dst_width % 16 == 0 ? 0 : 16 - src_params->dst_width % 16;
68         /* 0x0030(reg12) */
69         dst_reg->common.reg12.sw_vdpp_src_vir_y_stride = (src_params->src_width + src_right_redundant + 3) / 4;
70 
71         /* 0x0034(reg13) */
72         dst_reg->common.reg13.sw_vdpp_dst_vir_y_stride = (src_params->dst_width + dst_right_redundant + 3) / 4;
73 
74         /* 0x0038(reg14) */
75         dst_reg->common.reg14.sw_vdpp_src_pic_width = src_params->src_width + src_right_redundant - 1;
76         dst_reg->common.reg14.sw_vdpp_src_right_redundant = src_right_redundant;
77         dst_reg->common.reg14.sw_vdpp_src_pic_height = src_params->src_height + src_down_redundant - 1;
78         dst_reg->common.reg14.sw_vdpp_src_down_redundant = src_down_redundant;
79 
80         /* 0x003C(reg15) */
81         dst_reg->common.reg15.sw_vdpp_dst_pic_width = src_params->dst_width + dst_right_redundant - 1;
82         dst_reg->common.reg15.sw_vdpp_dst_right_redundant = dst_right_redundant;
83         dst_reg->common.reg15.sw_vdpp_dst_pic_height = src_params->dst_height - 1;
84     }
85     /* 0x0040 ~ 0x005C(reg16 ~ reg23), skip */
86     dst_reg->common.reg20.sw_vdpp_timeout_en = 1;
87     dst_reg->common.reg20.sw_vdpp_timeout_cnt = 0x8FFFFFF;
88 
89     /* 0x0060(reg24) */
90     dst_reg->common.reg24.sw_vdpp_src_addr_y = src_params->src.y;
91 
92     /* 0x0064(reg25) */
93     dst_reg->common.reg25.sw_vdpp_src_addr_uv = src_params->src.cbcr;
94 
95     /* 0x0068(reg26) */
96     dst_reg->common.reg26.sw_vdpp_dst_addr_y = src_params->dst.y;
97 
98     /* 0x006C(reg27) */
99     dst_reg->common.reg27.sw_vdpp_dst_addr_uv = src_params->dst.cbcr;
100 
101     set_dmsr_to_vdpp_reg(&src_params->dmsr_params, &ctx->dmsr);
102 
103     zme_params->src_width = src_params->src_width;
104     zme_params->src_height = src_params->src_height;
105     zme_params->dst_width = src_params->dst_width;
106     zme_params->dst_height = src_params->dst_height;
107     zme_params->dst_fmt = src_params->dst_fmt;
108     set_zme_to_vdpp_reg(zme_params, &ctx->zme);
109 
110     return MPP_OK;
111 }
112 
vdpp_set_default_dmsr_param(struct dmsr_params * p_dmsr_param)113 static void vdpp_set_default_dmsr_param(struct dmsr_params* p_dmsr_param)
114 {
115     p_dmsr_param->dmsr_enable = 1;
116     p_dmsr_param->dmsr_str_pri_y = 10;
117     p_dmsr_param->dmsr_str_sec_y = 4;
118     p_dmsr_param->dmsr_dumping_y = 6;
119     p_dmsr_param->dmsr_wgt_pri_gain_even_1 = 12;
120     p_dmsr_param->dmsr_wgt_pri_gain_even_2 = 12;
121     p_dmsr_param->dmsr_wgt_pri_gain_odd_1 = 8;
122     p_dmsr_param->dmsr_wgt_pri_gain_odd_2 = 16;
123     p_dmsr_param->dmsr_wgt_sec_gain = 5;
124     p_dmsr_param->dmsr_blk_flat_th = 20;
125     p_dmsr_param->dmsr_contrast_to_conf_map_x0 = 1680;
126     p_dmsr_param->dmsr_contrast_to_conf_map_x1 = 6720;
127     p_dmsr_param->dmsr_contrast_to_conf_map_y0 = 0;
128     p_dmsr_param->dmsr_contrast_to_conf_map_y1 = 65535;
129     p_dmsr_param->dmsr_diff_core_th0 = 2;
130     p_dmsr_param->dmsr_diff_core_th1 = 5;
131     p_dmsr_param->dmsr_diff_core_wgt0 = 16;
132     p_dmsr_param->dmsr_diff_core_wgt1 = 12;
133     p_dmsr_param->dmsr_diff_core_wgt2 = 8;
134     p_dmsr_param->dmsr_edge_th_low_arr[0] = 30;
135     p_dmsr_param->dmsr_edge_th_low_arr[1] = 10;
136     p_dmsr_param->dmsr_edge_th_low_arr[2] = 0;
137     p_dmsr_param->dmsr_edge_th_low_arr[3] = 0;
138     p_dmsr_param->dmsr_edge_th_low_arr[4] = 0;
139     p_dmsr_param->dmsr_edge_th_low_arr[5] = 0;
140     p_dmsr_param->dmsr_edge_th_low_arr[6] = 0;
141     p_dmsr_param->dmsr_edge_th_high_arr[0] = 60;
142     p_dmsr_param->dmsr_edge_th_high_arr[1] = 40;
143     p_dmsr_param->dmsr_edge_th_high_arr[2] = 20;
144     p_dmsr_param->dmsr_edge_th_high_arr[3] = 10;
145     p_dmsr_param->dmsr_edge_th_high_arr[4] = 10;
146     p_dmsr_param->dmsr_edge_th_high_arr[5] = 10;
147     p_dmsr_param->dmsr_edge_th_high_arr[6] = 10;
148 }
149 
vdpp_set_default_param(struct vdpp_params * param)150 static MPP_RET vdpp_set_default_param(struct vdpp_params *param)
151 {
152     /* src_fmt only NV12 supported */
153     param->src_yuv_swap = VDPP_YUV_SWAP_SP_UV;
154     param->dst_fmt = VDPP_FMT_YUV444;
155     param->dst_yuv_swap = VDPP_YUV_SWAP_SP_UV;
156     param->src_width = 1920;
157     param->src_height = 1080;
158     param->dst_width = 1920;
159     param->dst_height = 1080;
160 
161 
162     vdpp_set_default_dmsr_param(&param->dmsr_params);
163     vdpp_set_default_zme_param(&param->zme_params);
164 
165     return MPP_OK;
166 }
167 
vdpp_init(VdppCtx * ictx)168 MPP_RET vdpp_init(VdppCtx *ictx)
169 {
170     MPP_RET ret;
171     MppReqV1 mpp_req;
172     RK_U32 client_data = VDPP_CLIENT_TYPE;
173     struct vdpp_api_ctx *ctx = NULL;
174 
175     if (NULL == *ictx) {
176         mpp_err_f("found NULL input vdpp ctx %p\n", *ictx);
177         return MPP_ERR_NULL_PTR;
178     }
179 
180     ctx = *ictx;
181 
182     mpp_env_get_u32("vdpp_debug", &vdpp_debug, 0);
183 
184     ctx->fd = open("/dev/mpp_service", O_RDWR | O_CLOEXEC);
185     if (ctx->fd < 0) {
186         mpp_err("can NOT find device /dev/vdpp\n");
187         return MPP_NOK;
188     }
189 
190     mpp_req.cmd = MPP_CMD_INIT_CLIENT_TYPE;
191     mpp_req.flag = 0;
192     mpp_req.size = sizeof(client_data);
193     mpp_req.data_ptr = REQ_DATA_PTR(&client_data);
194 
195     memset(&ctx->params, 0, sizeof(struct vdpp_params));
196     /* set default parameters */
197     vdpp_set_default_param(&ctx->params);
198 
199     ret = (RK_S32)ioctl(ctx->fd, MPP_IOC_CFG_V1, &mpp_req);
200     if (ret) {
201         mpp_err("ioctl set_client failed\n");
202         return MPP_NOK;
203     }
204 
205     return MPP_OK;
206 }
207 
vdpp_deinit(VdppCtx ictx)208 MPP_RET vdpp_deinit(VdppCtx ictx)
209 {
210     struct vdpp_api_ctx *ctx = NULL;
211 
212     if (NULL == ictx) {
213         mpp_err_f("found NULL input vdpp ctx %p\n", ictx);
214         return MPP_ERR_NULL_PTR;
215     }
216 
217     ctx = ictx;
218 
219     if (ctx->fd >= 0) {
220         close(ctx->fd);
221         ctx->fd = -1;
222     }
223 
224     return MPP_OK;
225 }
226 
vdpp_set_param(struct vdpp_api_ctx * ctx,union vdpp_api_content * param,enum VDPP_PARAM_TYPE type)227 static MPP_RET vdpp_set_param(struct vdpp_api_ctx *ctx,
228                               union vdpp_api_content *param,
229                               enum VDPP_PARAM_TYPE type)
230 {
231     MPP_RET ret = MPP_OK;
232 
233     switch (type) {
234     case VDPP_PARAM_TYPE_COM :
235         ctx->params.src_yuv_swap = param->com.sswap;
236         ctx->params.dst_fmt = param->com.dfmt;
237         ctx->params.dst_yuv_swap = param->com.dswap;
238         ctx->params.src_width = param->com.src_width;
239         ctx->params.src_height = param->com.src_height;
240         ctx->params.dst_width = param->com.dst_width;
241         ctx->params.dst_height = param->com.dst_height;
242         break;
243 
244     case VDPP_PARAM_TYPE_DMSR :
245         memcpy(&ctx->params.dmsr_params, &param->dmsr, sizeof(struct dmsr_params));
246         break;
247 
248     case VDPP_PARAM_TYPE_ZME_COM :
249         ctx->params.zme_params.zme_bypass_en = param->zme.bypass_enable;
250         ctx->params.zme_params.zme_dering_enable = param->zme.dering_enable;
251         ctx->params.zme_params.zme_dering_sen_0 = param->zme.dering_sen_0;
252         ctx->params.zme_params.zme_dering_sen_1 = param->zme.dering_sen_1;
253         ctx->params.zme_params.zme_dering_blend_alpha = param->zme.dering_blend_alpha;
254         ctx->params.zme_params.zme_dering_blend_beta = param->zme.dering_blend_beta;
255         break;
256 
257     case VDPP_PARAM_TYPE_ZME_COEFF :
258         if (param->zme.tap8_coeff != NULL)
259             ctx->params.zme_params.zme_tap8_coeff = param->zme.tap8_coeff;
260         if (param->zme.tap6_coeff != NULL)
261             ctx->params.zme_params.zme_tap6_coeff = param->zme.tap6_coeff;
262         break;
263 
264     default:
265         break;
266     }
267 
268     return ret;
269 }
270 
check_cap(struct vdpp_params * params)271 static RK_S32 check_cap(struct vdpp_params *params)
272 {
273     RK_S32 ret_cap = VDPP_CAP_UNSUPPORTED;
274     RK_U32 vep_mode_check = 0;
275 
276     if (NULL == params) {
277         VDPP_DBG(VDPP_DBG_CHECK, "found null pointer params\n");
278         return VDPP_CAP_UNSUPPORTED;
279     }
280 
281     if ((params->src_height < VDPP_MODE_MIN_HEIGHT) ||
282         (params->src_width < VDPP_MODE_MIN_WIDTH)) {
283         VDPP_DBG(VDPP_DBG_CHECK, "vep src unsupported img_w %d img_h %d\n",
284                  params->src_height, params->src_width);
285         vep_mode_check++;
286     }
287 
288     if ((params->dst_height < VDPP_MODE_MIN_HEIGHT) ||
289         (params->dst_width < VDPP_MODE_MIN_WIDTH)) {
290         VDPP_DBG(VDPP_DBG_CHECK, "vep dst unsupported img_w %d img_h %d\n",
291                  params->dst_height, params->dst_width);
292         vep_mode_check++;
293     }
294 
295     if ((params->src_width & 1) || (params->src_height & 1) ||
296         (params->dst_width & 1) || (params->dst_height & 1)) {
297         VDPP_DBG(VDPP_DBG_CHECK, "vep only support img_w/h_vld 2pix align\n");
298         VDPP_DBG(VDPP_DBG_CHECK, "vep unsupported img_w_i %d img_h_i %d img_w_o %d img_h_o %d\n",
299                  params->src_width, params->src_height, params->dst_width, params->dst_height);
300         vep_mode_check++;
301     }
302 
303     if (!vep_mode_check) {
304         ret_cap |= VDPP_CAP_VEP;
305         VDPP_DBG(VDPP_DBG_INT, "vdpp support mode: VDPP_CAP_VEP\n");
306     }
307 
308     return ret_cap;
309 }
310 
vdpp_start(struct vdpp_api_ctx * ctx)311 static MPP_RET vdpp_start(struct vdpp_api_ctx *ctx)
312 {
313     MPP_RET ret;
314     RegOffsetInfo reg_off[2];
315     MppReqV1 mpp_req[9];
316     RK_U32 req_cnt = 0;
317     struct vdpp_reg *reg = NULL;
318     struct zme_reg *zme = NULL;
319     RK_S32 ret_cap = VDPP_CAP_UNSUPPORTED;
320 
321     if (NULL == ctx) {
322         mpp_err_f("found NULL input vdpp ctx %p\n", ctx);
323         return MPP_ERR_NULL_PTR;
324     }
325 
326     ret_cap = check_cap(&ctx->params);
327     if (!(ret_cap & VDPP_CAP_VEP)) {
328         mpp_err_f("found incompat work mode %s cap %d\n",
329                   working_mode_name[VDPP_WORK_MODE_VEP], ret_cap);
330         return MPP_NOK;
331     }
332 
333     reg = &ctx->reg;
334     zme = &ctx->zme;
335 
336     memset(reg_off, 0, sizeof(reg_off));
337     memset(mpp_req, 0, sizeof(mpp_req));
338     memset(reg, 0, sizeof(*reg));
339 
340     vdpp_params_to_reg(&ctx->params, ctx);
341 
342     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
343     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
344     mpp_req[req_cnt].size =  sizeof(zme->yrgb_hor_coe);
345     mpp_req[req_cnt].offset = VDPP_REG_OFF_YRGB_HOR_COE;
346     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&zme->yrgb_hor_coe);
347 
348     req_cnt++;
349     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
350     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
351     mpp_req[req_cnt].size =  sizeof(zme->yrgb_ver_coe);
352     mpp_req[req_cnt].offset = VDPP_REG_OFF_YRGB_VER_COE;
353     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&zme->yrgb_ver_coe);
354 
355     req_cnt++;
356     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
357     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
358     mpp_req[req_cnt].size =  sizeof(zme->cbcr_hor_coe);
359     mpp_req[req_cnt].offset = VDPP_REG_OFF_CBCR_HOR_COE;
360     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&zme->cbcr_hor_coe);
361 
362     req_cnt++;
363     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
364     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
365     mpp_req[req_cnt].size =  sizeof(zme->cbcr_ver_coe);
366     mpp_req[req_cnt].offset = VDPP_REG_OFF_CBCR_VER_COE;
367     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&zme->cbcr_ver_coe);
368 
369     req_cnt++;
370     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
371     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
372     mpp_req[req_cnt].size =  sizeof(zme->common);
373     mpp_req[req_cnt].offset = VDPP_REG_OFF_ZME_COMMON;
374     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&zme->common);
375 
376     req_cnt++;
377     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
378     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
379     mpp_req[req_cnt].size =  sizeof(ctx->dmsr);
380     mpp_req[req_cnt].offset = VDPP_REG_OFF_DMSR;
381     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&ctx->dmsr);
382 
383     /* set reg offset */
384     reg_off[0].reg_idx = 25;
385     reg_off[0].offset = ctx->params.src.cbcr_offset;
386     reg_off[1].reg_idx = 27;
387     reg_off[1].offset = ctx->params.dst.cbcr_offset;
388     req_cnt++;
389     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_ADDR_OFFSET;
390     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG | MPP_FLAGS_REG_OFFSET_ALONE;
391     mpp_req[req_cnt].size = sizeof(reg_off);
392     mpp_req[req_cnt].offset = 0;
393     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(reg_off);
394 
395     req_cnt++;
396     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_WRITE;
397     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG;
398     mpp_req[req_cnt].size =  sizeof(reg->common);
399     mpp_req[req_cnt].offset = 0;
400     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&reg->common);
401 
402     req_cnt++;
403     mpp_req[req_cnt].cmd = MPP_CMD_SET_REG_READ;
404     mpp_req[req_cnt].flag = MPP_FLAGS_MULTI_MSG | MPP_FLAGS_LAST_MSG;
405     mpp_req[req_cnt].size =  sizeof(reg->common);
406     mpp_req[req_cnt].offset = 0;
407     mpp_req[req_cnt].data_ptr = REQ_DATA_PTR(&reg->common);
408 
409     ret = (RK_S32)ioctl(ctx->fd, MPP_IOC_CFG_V1, &mpp_req[0]);
410 
411     if (ret) {
412         mpp_err_f("ioctl SET_REG failed ret %d errno %d %s\n",
413                   ret, errno, strerror(errno));
414         ret = errno;
415     }
416 
417     return ret;
418 }
419 
vdpp_wait(struct vdpp_api_ctx * ctx)420 static MPP_RET vdpp_wait(struct vdpp_api_ctx *ctx)
421 {
422     MPP_RET ret;
423     MppReqV1 mpp_req;
424 
425     if (NULL == ctx) {
426         mpp_err_f("found NULL input vdpp ctx %p\n", ctx);
427         return MPP_ERR_NULL_PTR;
428     }
429 
430     memset(&mpp_req, 0, sizeof(mpp_req));
431     mpp_req.cmd = MPP_CMD_POLL_HW_FINISH;
432     mpp_req.flag |= MPP_FLAGS_LAST_MSG;
433 
434     ret = (RK_S32)ioctl(ctx->fd, MPP_IOC_CFG_V1, &mpp_req);
435     if (ret) {
436         mpp_err_f("ioctl POLL_HW_FINISH failed ret %d errno %d %s\n",
437                   ret, errno, strerror(errno));
438     }
439 
440     return ret;
441 }
442 
vdpp_done(struct vdpp_api_ctx * ctx)443 static MPP_RET vdpp_done(struct vdpp_api_ctx *ctx)
444 {
445     struct vdpp_reg *reg = NULL;
446 
447     if (NULL == ctx) {
448         mpp_err_f("found NULL input vdpp ctx %p\n", ctx);
449         return MPP_ERR_NULL_PTR;
450     }
451 
452     reg = &ctx->reg;
453 
454     VDPP_DBG(VDPP_DBG_INT, "ro_frm_done_sts=%d\n", reg->common.reg10.ro_frm_done_sts);
455     VDPP_DBG(VDPP_DBG_INT, "ro_osd_max_sts=%d\n", reg->common.reg10.ro_osd_max_sts);
456     VDPP_DBG(VDPP_DBG_INT, "ro_bus_error_sts=%d\n", reg->common.reg10.ro_bus_error_sts);
457     VDPP_DBG(VDPP_DBG_INT, "ro_timeout_sts=%d\n", reg->common.reg10.ro_timeout_sts);
458     VDPP_DBG(VDPP_DBG_INT, "ro_config_error_sts=%d\n", reg->common.reg10.ro_timeout_sts);
459 
460     if (reg->common.reg8.sw_vdpp_frm_done_en &&
461         !reg->common.reg10.ro_frm_done_sts) {
462         mpp_err_f("run vdpp failed\n");
463         return MPP_NOK;
464     }
465 
466     VDPP_DBG(VDPP_DBG_INT, "run vdpp success\n");
467 
468     return MPP_OK;
469 }
470 
set_addr(struct vdpp_addr * addr,VdppImg * img)471 static inline MPP_RET set_addr(struct vdpp_addr *addr, VdppImg *img)
472 {
473     if (NULL == addr || NULL == img) {
474         mpp_err_f("found NULL vdpp_addr %p img %p\n", addr, img);
475         return MPP_ERR_NULL_PTR;
476     }
477 
478     addr->y = img->mem_addr;
479     addr->cbcr = img->uv_addr;
480     addr->cbcr_offset = img->uv_off;
481 
482     return MPP_OK;
483 }
484 
vdpp_control(VdppCtx ictx,VdppCmd cmd,void * iparam)485 MPP_RET vdpp_control(VdppCtx ictx, VdppCmd cmd, void *iparam)
486 {
487     struct vdpp_api_ctx *ctx = ictx;
488     MPP_RET ret = MPP_OK;
489 
490     if ((NULL == iparam && VDPP_CMD_RUN_SYNC != cmd) ||
491         (NULL == ictx)) {
492         mpp_err_f("found NULL iparam %p cmd %d ctx %p\n", iparam, cmd, ictx);
493         return MPP_ERR_NULL_PTR;
494     }
495 
496     switch (cmd) {
497     case VDPP_CMD_SET_COM_CFG:
498     case VDPP_CMD_SET_DMSR_CFG:
499     case VDPP_CMD_SET_ZME_COM_CFG:
500     case VDPP_CMD_SET_ZME_COEFF_CFG: {
501         struct vdpp_api_params *param = (struct vdpp_api_params *)iparam;
502 
503         ret = vdpp_set_param(ctx, &param->param, param->ptype);
504         if (ret) {
505             mpp_err_f("set vdpp parameter failed, type %d\n", param->ptype);
506         }
507         break;
508     }
509     case VDPP_CMD_SET_SRC:
510         set_addr(&ctx->params.src, (VdppImg *)iparam);
511         break;
512     case VDPP_CMD_SET_DST:
513         set_addr(&ctx->params.dst, (VdppImg *)iparam);
514         break;
515     case VDPP_CMD_RUN_SYNC:
516         ret = vdpp_start(ctx);
517         if (ret) {
518             mpp_err_f("run vdpp failed\n");
519             return MPP_NOK;
520         }
521 
522         vdpp_wait(ctx);
523         vdpp_done(ctx);
524         break;
525     default:
526         ;
527     }
528 
529     return ret;
530 }
531 
vdpp_check_cap(VdppCtx ictx)532 RK_S32 vdpp_check_cap(VdppCtx ictx)
533 {
534     struct vdpp_api_ctx *ctx = ictx;
535 
536     if (NULL == ictx) {
537         mpp_err_f("found NULL ctx %p\n", ictx);
538         return VDPP_CAP_UNSUPPORTED;
539     }
540 
541     return check_cap(&ctx->params);
542 }
543