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