xref: /rockchip-linux_mpp/osal/driver/vcodec_service.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define MODULE_TAG "vcodec_service"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <sys/ioctl.h>
9*437bfbebSnyanmisaka #include <fcntl.h>
10*437bfbebSnyanmisaka #include <errno.h>
11*437bfbebSnyanmisaka #include <string.h>
12*437bfbebSnyanmisaka #include <unistd.h>
13*437bfbebSnyanmisaka 
14*437bfbebSnyanmisaka #include "mpp_env.h"
15*437bfbebSnyanmisaka #include "mpp_mem.h"
16*437bfbebSnyanmisaka #include "mpp_time.h"
17*437bfbebSnyanmisaka #include "mpp_list.h"
18*437bfbebSnyanmisaka #include "mpp_debug.h"
19*437bfbebSnyanmisaka #include "mpp_common.h"
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "vpu.h"
22*437bfbebSnyanmisaka #include "mpp_soc.h"
23*437bfbebSnyanmisaka #include "mpp_platform.h"
24*437bfbebSnyanmisaka #include "vcodec_service.h"
25*437bfbebSnyanmisaka #include "vcodec_service_api.h"
26*437bfbebSnyanmisaka 
27*437bfbebSnyanmisaka #define MAX_REGS_COUNT      3
28*437bfbebSnyanmisaka #define MPX_EXTRA_INFO_NUM  16
29*437bfbebSnyanmisaka #define MAX_INFO_COUNT      16
30*437bfbebSnyanmisaka #define INFO_FORMAT_TYPE    3
31*437bfbebSnyanmisaka 
32*437bfbebSnyanmisaka typedef struct MppReq_t {
33*437bfbebSnyanmisaka     RK_U32 *req;
34*437bfbebSnyanmisaka     RK_U32  size;
35*437bfbebSnyanmisaka } MppReq;
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka typedef struct VcodecExtraSlot_t {
38*437bfbebSnyanmisaka     RK_U32              reg_idx;
39*437bfbebSnyanmisaka     RK_U32              offset;
40*437bfbebSnyanmisaka } VcodecExtraSlot;
41*437bfbebSnyanmisaka 
42*437bfbebSnyanmisaka typedef struct VcodecExtraInfo_t {
43*437bfbebSnyanmisaka     RK_U32              magic;      // Fix magic value 0x4C4A46
44*437bfbebSnyanmisaka     RK_U32              count;      // valid patch info count
45*437bfbebSnyanmisaka     VcodecExtraSlot     slots[MPX_EXTRA_INFO_NUM];
46*437bfbebSnyanmisaka } VcodecExtraInfo;
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka typedef struct VcodecRegCfg_t {
49*437bfbebSnyanmisaka     RK_U32              reg_size;
50*437bfbebSnyanmisaka     VcodecExtraInfo     extra_info;
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka     void                *reg_set;
53*437bfbebSnyanmisaka     void                *reg_get;
54*437bfbebSnyanmisaka } VcodecRegCfg;
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka typedef struct MppDevVcodecService_t {
57*437bfbebSnyanmisaka     RK_S32              client_type;
58*437bfbebSnyanmisaka     RK_U64              fmt;
59*437bfbebSnyanmisaka     RK_S32              fd;
60*437bfbebSnyanmisaka     RK_S32              max_regs;
61*437bfbebSnyanmisaka     RK_U32              reg_size;
62*437bfbebSnyanmisaka 
63*437bfbebSnyanmisaka     RK_S32              reg_send_idx;
64*437bfbebSnyanmisaka     RK_S32              reg_poll_idx;
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     VcodecRegCfg        regs[MAX_REGS_COUNT];
67*437bfbebSnyanmisaka 
68*437bfbebSnyanmisaka     RK_S32              info_count;
69*437bfbebSnyanmisaka     MppDevInfoCfg       info[MAX_INFO_COUNT];
70*437bfbebSnyanmisaka } MppDevVcodecService;
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka /* For vpu1 / vpu2 */
73*437bfbebSnyanmisaka static const char *mpp_vpu_dev[] = {
74*437bfbebSnyanmisaka     "/dev/vpu_service",
75*437bfbebSnyanmisaka     "/dev/vpu-service",
76*437bfbebSnyanmisaka     "/dev/mpp_service",
77*437bfbebSnyanmisaka };
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka /* For hevc 4K decoder */
80*437bfbebSnyanmisaka static const char *mpp_hevc_dev[] = {
81*437bfbebSnyanmisaka     "/dev/hevc_service",
82*437bfbebSnyanmisaka     "/dev/hevc-service",
83*437bfbebSnyanmisaka     "/dev/mpp_service",
84*437bfbebSnyanmisaka };
85*437bfbebSnyanmisaka 
86*437bfbebSnyanmisaka /* For H.264/H.265/VP9 4K decoder */
87*437bfbebSnyanmisaka static const char *mpp_rkvdec_dev[] = {
88*437bfbebSnyanmisaka     "/dev/rkvdec",
89*437bfbebSnyanmisaka     "/dev/mpp_service",
90*437bfbebSnyanmisaka };
91*437bfbebSnyanmisaka 
92*437bfbebSnyanmisaka /* For H.264 4K encoder */
93*437bfbebSnyanmisaka static const char *mpp_rkvenc_dev[] = {
94*437bfbebSnyanmisaka     "/dev/rkvenc",
95*437bfbebSnyanmisaka     "/dev/mpp_service",
96*437bfbebSnyanmisaka };
97*437bfbebSnyanmisaka 
98*437bfbebSnyanmisaka /* For avs+ decoder */
99*437bfbebSnyanmisaka static const char *mpp_avsd_dev[] = {
100*437bfbebSnyanmisaka     "/dev/avsd",
101*437bfbebSnyanmisaka     "/dev/mpp_service",
102*437bfbebSnyanmisaka };
103*437bfbebSnyanmisaka 
104*437bfbebSnyanmisaka /* For H.264 / jpeg encoder */
105*437bfbebSnyanmisaka static const char *mpp_vepu_dev[] = {
106*437bfbebSnyanmisaka     "/dev/vepu",
107*437bfbebSnyanmisaka     "/dev/mpp_service",
108*437bfbebSnyanmisaka };
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka /* For H.265 encoder */
111*437bfbebSnyanmisaka static const char *mpp_h265e_dev[] = {
112*437bfbebSnyanmisaka     "/dev/h265e",
113*437bfbebSnyanmisaka     "/dev/mpp_service",
114*437bfbebSnyanmisaka };
115*437bfbebSnyanmisaka 
116*437bfbebSnyanmisaka /* For jpeg decoder */
117*437bfbebSnyanmisaka static const char *mpp_jpegd_dev[] = {
118*437bfbebSnyanmisaka     "/dev/mpp_service",
119*437bfbebSnyanmisaka };
120*437bfbebSnyanmisaka 
121*437bfbebSnyanmisaka static const char *mpp_jpege_dev[] = {
122*437bfbebSnyanmisaka     "/dev/mpp_service",
123*437bfbebSnyanmisaka };
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka #define mpp_find_device(dev) _mpp_find_device(dev, MPP_ARRAY_ELEMS(dev))
126*437bfbebSnyanmisaka 
_mpp_find_device(const char ** dev,RK_U32 size)127*437bfbebSnyanmisaka static const char *_mpp_find_device(const char **dev, RK_U32 size)
128*437bfbebSnyanmisaka {
129*437bfbebSnyanmisaka     RK_U32 i;
130*437bfbebSnyanmisaka 
131*437bfbebSnyanmisaka     for (i = 0; i < size; i++)
132*437bfbebSnyanmisaka         if (!access(dev[i], F_OK))
133*437bfbebSnyanmisaka             return dev[i];
134*437bfbebSnyanmisaka 
135*437bfbebSnyanmisaka     return NULL;
136*437bfbebSnyanmisaka }
137*437bfbebSnyanmisaka 
mpp_get_platform_dev_name(MppCtxType type,MppCodingType coding,RK_U32 platform)138*437bfbebSnyanmisaka const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform)
139*437bfbebSnyanmisaka {
140*437bfbebSnyanmisaka     const char *dev = NULL;
141*437bfbebSnyanmisaka 
142*437bfbebSnyanmisaka     if ((platform & HAVE_RKVDEC) && (type == MPP_CTX_DEC) &&
143*437bfbebSnyanmisaka         (coding == MPP_VIDEO_CodingAVC ||
144*437bfbebSnyanmisaka          coding == MPP_VIDEO_CodingHEVC ||
145*437bfbebSnyanmisaka          coding == MPP_VIDEO_CodingAVS2 ||
146*437bfbebSnyanmisaka          coding == MPP_VIDEO_CodingVP9)) {
147*437bfbebSnyanmisaka         dev = mpp_find_device(mpp_rkvdec_dev);
148*437bfbebSnyanmisaka     } else if ((platform & HAVE_HEVC_DEC) && (type == MPP_CTX_DEC) &&
149*437bfbebSnyanmisaka                (coding == MPP_VIDEO_CodingHEVC)) {
150*437bfbebSnyanmisaka         dev = mpp_find_device(mpp_hevc_dev);
151*437bfbebSnyanmisaka     } else if ((platform & HAVE_AVSDEC) && (type == MPP_CTX_DEC) &&
152*437bfbebSnyanmisaka                (coding == MPP_VIDEO_CodingAVS)) {
153*437bfbebSnyanmisaka         dev = mpp_find_device(mpp_avsd_dev);
154*437bfbebSnyanmisaka     } else if ((platform & HAVE_RKVENC) && (type == MPP_CTX_ENC) &&
155*437bfbebSnyanmisaka                (coding == MPP_VIDEO_CodingAVC)) {
156*437bfbebSnyanmisaka         dev = mpp_find_device(mpp_rkvenc_dev);
157*437bfbebSnyanmisaka     } else if ((platform & HAVE_VEPU22) && (type == MPP_CTX_ENC) &&
158*437bfbebSnyanmisaka                (coding == MPP_VIDEO_CodingHEVC)) {
159*437bfbebSnyanmisaka         dev = mpp_find_device(mpp_h265e_dev);
160*437bfbebSnyanmisaka     } else {
161*437bfbebSnyanmisaka         if (type == MPP_CTX_ENC)
162*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vepu_dev);
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka         if (dev == NULL)
165*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
166*437bfbebSnyanmisaka     }
167*437bfbebSnyanmisaka 
168*437bfbebSnyanmisaka     return dev;
169*437bfbebSnyanmisaka }
170*437bfbebSnyanmisaka 
mpp_get_vcodec_dev_name(MppCtxType type,MppCodingType coding)171*437bfbebSnyanmisaka const char *mpp_get_vcodec_dev_name(MppCtxType type, MppCodingType coding)
172*437bfbebSnyanmisaka {
173*437bfbebSnyanmisaka     const char *dev = NULL;
174*437bfbebSnyanmisaka     RockchipSocType soc_type = mpp_get_soc_type();
175*437bfbebSnyanmisaka 
176*437bfbebSnyanmisaka     switch (soc_type) {
177*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3036 : {
178*437bfbebSnyanmisaka         /* rk3036 do NOT have encoder */
179*437bfbebSnyanmisaka         if (type == MPP_CTX_ENC)
180*437bfbebSnyanmisaka             dev = NULL;
181*437bfbebSnyanmisaka         else if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
182*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_hevc_dev);
183*437bfbebSnyanmisaka         else
184*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
185*437bfbebSnyanmisaka     } break;
186*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3066 :
187*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3188 : {
188*437bfbebSnyanmisaka         /* rk3066/rk3188 have vpu1 only */
189*437bfbebSnyanmisaka         dev = mpp_find_device(mpp_vpu_dev);
190*437bfbebSnyanmisaka     } break;
191*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3288 :
192*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK312X :
193*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3368 :
194*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3326 :
195*437bfbebSnyanmisaka     case ROCKCHIP_SOC_PX30 : {
196*437bfbebSnyanmisaka         /*
197*437bfbebSnyanmisaka          * rk3288/rk312x/rk3368 have codec:
198*437bfbebSnyanmisaka          * 1 - vpu1
199*437bfbebSnyanmisaka          * 2 - RK hevc decoder
200*437bfbebSnyanmisaka          */
201*437bfbebSnyanmisaka         if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
202*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_hevc_dev);
203*437bfbebSnyanmisaka         else
204*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
205*437bfbebSnyanmisaka     } break;
206*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3128H : {
207*437bfbebSnyanmisaka         /*
208*437bfbebSnyanmisaka          * rk3128H have codec:
209*437bfbebSnyanmisaka          * 1 - vpu2
210*437bfbebSnyanmisaka          * 2 - RK H.264/H.265 1080p@60fps decoder
211*437bfbebSnyanmisaka          * NOTE: rk3128H do NOT have jpeg encoder
212*437bfbebSnyanmisaka          */
213*437bfbebSnyanmisaka         if (type == MPP_CTX_DEC &&
214*437bfbebSnyanmisaka             (coding == MPP_VIDEO_CodingAVC ||
215*437bfbebSnyanmisaka              coding == MPP_VIDEO_CodingHEVC))
216*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_rkvdec_dev);
217*437bfbebSnyanmisaka         else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
218*437bfbebSnyanmisaka             dev = NULL;
219*437bfbebSnyanmisaka         else if (type == MPP_CTX_DEC && coding == MPP_VIDEO_CodingVP9)
220*437bfbebSnyanmisaka             dev = NULL;
221*437bfbebSnyanmisaka         else
222*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
223*437bfbebSnyanmisaka     } break;
224*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3399 :
225*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3229 : {
226*437bfbebSnyanmisaka         /*
227*437bfbebSnyanmisaka          * rk3399/rk3229 have codec:
228*437bfbebSnyanmisaka          * 1 - vpu2
229*437bfbebSnyanmisaka          * 2 - RK H.264/H.265/VP9 4K decoder
230*437bfbebSnyanmisaka          */
231*437bfbebSnyanmisaka         if (type == MPP_CTX_DEC &&
232*437bfbebSnyanmisaka             (coding == MPP_VIDEO_CodingAVC ||
233*437bfbebSnyanmisaka              coding == MPP_VIDEO_CodingHEVC ||
234*437bfbebSnyanmisaka              coding == MPP_VIDEO_CodingVP9))
235*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_rkvdec_dev);
236*437bfbebSnyanmisaka         else
237*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
238*437bfbebSnyanmisaka     } break;
239*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3228 : {
240*437bfbebSnyanmisaka         /*
241*437bfbebSnyanmisaka          * rk3228 have codec:
242*437bfbebSnyanmisaka          * 1 - vpu2
243*437bfbebSnyanmisaka          * 2 - RK H.264/H.265 4K decoder
244*437bfbebSnyanmisaka          * NOTE: rk3228 do NOT have jpeg encoder
245*437bfbebSnyanmisaka          */
246*437bfbebSnyanmisaka         if (type == MPP_CTX_DEC &&
247*437bfbebSnyanmisaka             (coding == MPP_VIDEO_CodingAVC ||
248*437bfbebSnyanmisaka              coding == MPP_VIDEO_CodingHEVC))
249*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_rkvdec_dev);
250*437bfbebSnyanmisaka         else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
251*437bfbebSnyanmisaka             dev = NULL;
252*437bfbebSnyanmisaka         else
253*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
254*437bfbebSnyanmisaka     } break;
255*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3228H : {
256*437bfbebSnyanmisaka         /*
257*437bfbebSnyanmisaka          * rk3228h has codec:
258*437bfbebSnyanmisaka          * 1 - vpu2
259*437bfbebSnyanmisaka          * 2 - RK H.264/H.265 4K decoder
260*437bfbebSnyanmisaka          * 3 - avs+ decoder
261*437bfbebSnyanmisaka          * 4 - H.265 encoder
262*437bfbebSnyanmisaka          */
263*437bfbebSnyanmisaka         if (type == MPP_CTX_ENC) {
264*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingHEVC)
265*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_h265e_dev);
266*437bfbebSnyanmisaka             else
267*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vepu_dev);
268*437bfbebSnyanmisaka         } else if (type == MPP_CTX_DEC) {
269*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingAVS)
270*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_avsd_dev);
271*437bfbebSnyanmisaka             else if (coding == MPP_VIDEO_CodingAVC ||
272*437bfbebSnyanmisaka                      coding == MPP_VIDEO_CodingHEVC)
273*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
274*437bfbebSnyanmisaka             else
275*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vpu_dev);
276*437bfbebSnyanmisaka         }
277*437bfbebSnyanmisaka     } break;
278*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3328 : {
279*437bfbebSnyanmisaka         /*
280*437bfbebSnyanmisaka          * rk3228 has codec:
281*437bfbebSnyanmisaka          * 1 - vpu2
282*437bfbebSnyanmisaka          * 2 - RK H.264/H.265/VP9 4K decoder
283*437bfbebSnyanmisaka          * 4 - H.265 encoder
284*437bfbebSnyanmisaka          */
285*437bfbebSnyanmisaka         if (type == MPP_CTX_ENC) {
286*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingHEVC)
287*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_h265e_dev);
288*437bfbebSnyanmisaka             else
289*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vepu_dev);
290*437bfbebSnyanmisaka         } else if (type == MPP_CTX_DEC) {
291*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingAVC ||
292*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingHEVC ||
293*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingVP9) {
294*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
295*437bfbebSnyanmisaka             } else
296*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vpu_dev);
297*437bfbebSnyanmisaka         }
298*437bfbebSnyanmisaka     } break;
299*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RV1108 : {
300*437bfbebSnyanmisaka         /*
301*437bfbebSnyanmisaka          * rv1108 has codec:
302*437bfbebSnyanmisaka          * 1 - vpu2
303*437bfbebSnyanmisaka          * 2 - RK H.264 4K decoder
304*437bfbebSnyanmisaka          * 3 - RK H.264 4K encoder
305*437bfbebSnyanmisaka          */
306*437bfbebSnyanmisaka         if (coding == MPP_VIDEO_CodingAVC) {
307*437bfbebSnyanmisaka             if (type == MPP_CTX_ENC)
308*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvenc_dev);
309*437bfbebSnyanmisaka             else
310*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
311*437bfbebSnyanmisaka         } else if (coding == MPP_VIDEO_CodingMJPEG)
312*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
313*437bfbebSnyanmisaka     } break;
314*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RV1109 :
315*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RV1126 : {
316*437bfbebSnyanmisaka         /*
317*437bfbebSnyanmisaka          * rv1108 has codec:
318*437bfbebSnyanmisaka          * 1 - vpu2 for jpeg encoder and decoder
319*437bfbebSnyanmisaka          * 2 - RK H.264/H.265 4K decoder
320*437bfbebSnyanmisaka          * 3 - RK H.264/H.265 4K encoder
321*437bfbebSnyanmisaka          */
322*437bfbebSnyanmisaka         if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC) {
323*437bfbebSnyanmisaka             if (type == MPP_CTX_ENC)
324*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvenc_dev);
325*437bfbebSnyanmisaka             else
326*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
327*437bfbebSnyanmisaka         } else if (coding == MPP_VIDEO_CodingMJPEG)
328*437bfbebSnyanmisaka             dev = mpp_find_device(mpp_vpu_dev);
329*437bfbebSnyanmisaka     } break;
330*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3566 :
331*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3567 :
332*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3568 : {
333*437bfbebSnyanmisaka         /*
334*437bfbebSnyanmisaka          * rk3566/rk3568 has codec:
335*437bfbebSnyanmisaka          * 1 - vpu2 for jpeg/vp8 encoder and decoder
336*437bfbebSnyanmisaka          * 2 - RK H.264/H.265/VP9 4K decoder
337*437bfbebSnyanmisaka          * 3 - RK H.264/H.265 4K encoder
338*437bfbebSnyanmisaka          * 3 - RK jpeg decoder
339*437bfbebSnyanmisaka          */
340*437bfbebSnyanmisaka         if (type == MPP_CTX_DEC) {
341*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingAVC ||
342*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingHEVC ||
343*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingVP9)
344*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
345*437bfbebSnyanmisaka             else if (coding == MPP_VIDEO_CodingMJPEG)
346*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_jpegd_dev);
347*437bfbebSnyanmisaka             else
348*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vpu_dev);
349*437bfbebSnyanmisaka         } else if (type == MPP_CTX_ENC) {
350*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingAVC ||
351*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingHEVC)
352*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvenc_dev);
353*437bfbebSnyanmisaka             else if (coding == MPP_VIDEO_CodingMJPEG ||
354*437bfbebSnyanmisaka                      coding == MPP_VIDEO_CodingVP8)
355*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vpu_dev);
356*437bfbebSnyanmisaka             else
357*437bfbebSnyanmisaka                 dev = NULL;
358*437bfbebSnyanmisaka         }
359*437bfbebSnyanmisaka     } break;
360*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3588 : {
361*437bfbebSnyanmisaka         /*
362*437bfbebSnyanmisaka          * rk3588 has codec:
363*437bfbebSnyanmisaka          * 1 - RK H.264/H.265/VP9/AVS2 8K decoder
364*437bfbebSnyanmisaka          * 2 - RK H.264/H.265 8K encoder
365*437bfbebSnyanmisaka          * 3 - vpu2 for jpeg/vp8 encoder and decoder
366*437bfbebSnyanmisaka          * 4 - RK jpeg decoder
367*437bfbebSnyanmisaka          */
368*437bfbebSnyanmisaka         if (type == MPP_CTX_DEC) {
369*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingAVC ||
370*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingHEVC ||
371*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingAVS2 ||
372*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingVP9)
373*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
374*437bfbebSnyanmisaka             else if (coding == MPP_VIDEO_CodingMJPEG)
375*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_jpegd_dev);
376*437bfbebSnyanmisaka             else
377*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vpu_dev);
378*437bfbebSnyanmisaka         } else if (type == MPP_CTX_ENC) {
379*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingAVC ||
380*437bfbebSnyanmisaka                 coding == MPP_VIDEO_CodingHEVC)
381*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvenc_dev);
382*437bfbebSnyanmisaka             else if (coding == MPP_VIDEO_CodingMJPEG ||
383*437bfbebSnyanmisaka                      coding == MPP_VIDEO_CodingVP8)
384*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_vpu_dev);
385*437bfbebSnyanmisaka             else
386*437bfbebSnyanmisaka                 dev = NULL;
387*437bfbebSnyanmisaka         }
388*437bfbebSnyanmisaka     } break;
389*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RK3576 :
390*437bfbebSnyanmisaka     case ROCKCHIP_SOC_RV1126B : {
391*437bfbebSnyanmisaka         if (type == MPP_CTX_DEC) {
392*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingMJPEG)
393*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_jpegd_dev);
394*437bfbebSnyanmisaka             else
395*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvdec_dev);
396*437bfbebSnyanmisaka         } else if (type == MPP_CTX_ENC) {
397*437bfbebSnyanmisaka             if (coding == MPP_VIDEO_CodingMJPEG)
398*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_jpege_dev);
399*437bfbebSnyanmisaka             else
400*437bfbebSnyanmisaka                 dev = mpp_find_device(mpp_rkvenc_dev);
401*437bfbebSnyanmisaka         }
402*437bfbebSnyanmisaka     } break;
403*437bfbebSnyanmisaka     default : {
404*437bfbebSnyanmisaka         /* default case for unknown compatible  */
405*437bfbebSnyanmisaka         RK_U32 vcodec_type = mpp_get_vcodec_type();
406*437bfbebSnyanmisaka 
407*437bfbebSnyanmisaka         dev = mpp_get_platform_dev_name(type, coding, vcodec_type);
408*437bfbebSnyanmisaka     } break;
409*437bfbebSnyanmisaka     }
410*437bfbebSnyanmisaka 
411*437bfbebSnyanmisaka     return dev;
412*437bfbebSnyanmisaka }
413*437bfbebSnyanmisaka 
vcodec_service_ioctl(RK_S32 fd,RK_S32 cmd,void * regs,RK_S32 size)414*437bfbebSnyanmisaka static RK_S32 vcodec_service_ioctl(RK_S32 fd, RK_S32 cmd, void *regs, RK_S32 size)
415*437bfbebSnyanmisaka {
416*437bfbebSnyanmisaka     MppReq req;
417*437bfbebSnyanmisaka 
418*437bfbebSnyanmisaka     req.req = regs;
419*437bfbebSnyanmisaka     req.size = size;
420*437bfbebSnyanmisaka 
421*437bfbebSnyanmisaka     return (RK_S32)ioctl(fd, cmd, &req);
422*437bfbebSnyanmisaka }
423*437bfbebSnyanmisaka 
extra_info_init(VcodecExtraInfo * info)424*437bfbebSnyanmisaka static void extra_info_init(VcodecExtraInfo *info)
425*437bfbebSnyanmisaka {
426*437bfbebSnyanmisaka     info->magic = EXTRA_INFO_MAGIC;
427*437bfbebSnyanmisaka     info->count = 0;
428*437bfbebSnyanmisaka }
429*437bfbebSnyanmisaka 
update_extra_info(VcodecExtraInfo * info,char * fmt,VcodecRegCfg * send_cfg)430*437bfbebSnyanmisaka static void update_extra_info(VcodecExtraInfo *info, char* fmt, VcodecRegCfg* send_cfg)
431*437bfbebSnyanmisaka {
432*437bfbebSnyanmisaka     void *reg_set = send_cfg->reg_set;
433*437bfbebSnyanmisaka     RK_U32 reg_size = send_cfg->reg_size;
434*437bfbebSnyanmisaka 
435*437bfbebSnyanmisaka     if (info->count) {
436*437bfbebSnyanmisaka         if (!strstr(fmt, "mjpeg")) {
437*437bfbebSnyanmisaka             RK_U32 *reg = (RK_U32*)reg_set;
438*437bfbebSnyanmisaka             RK_U32 i = 0;
439*437bfbebSnyanmisaka 
440*437bfbebSnyanmisaka             for (i = 0; i < info->count; i++) {
441*437bfbebSnyanmisaka                 VcodecExtraSlot *slot = &info->slots[i];
442*437bfbebSnyanmisaka 
443*437bfbebSnyanmisaka                 reg[slot->reg_idx] |= (slot->offset << 10);
444*437bfbebSnyanmisaka             }
445*437bfbebSnyanmisaka             info->count = 0;
446*437bfbebSnyanmisaka         } else {
447*437bfbebSnyanmisaka             void *extra_data = reg_set + reg_size;
448*437bfbebSnyanmisaka             RK_S32 extra_size = sizeof(send_cfg->extra_info);
449*437bfbebSnyanmisaka 
450*437bfbebSnyanmisaka             memcpy(extra_data, info, extra_size);
451*437bfbebSnyanmisaka             send_cfg->reg_size += extra_size;
452*437bfbebSnyanmisaka             extra_info_init(info);
453*437bfbebSnyanmisaka         }
454*437bfbebSnyanmisaka     }
455*437bfbebSnyanmisaka }
456*437bfbebSnyanmisaka 
vcodec_service_init(void * ctx,MppClientType type)457*437bfbebSnyanmisaka MPP_RET vcodec_service_init(void *ctx, MppClientType type)
458*437bfbebSnyanmisaka {
459*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
460*437bfbebSnyanmisaka     static RK_S32 vcodec_ioctl_version = -1;
461*437bfbebSnyanmisaka     VPU_CLIENT_TYPE client_type;
462*437bfbebSnyanmisaka     const char *name = NULL;
463*437bfbebSnyanmisaka     RK_U32 reg_size = 0;
464*437bfbebSnyanmisaka     RK_S32 max_regs = 2;
465*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
466*437bfbebSnyanmisaka 
467*437bfbebSnyanmisaka     switch (type) {
468*437bfbebSnyanmisaka     case VPU_CLIENT_VDPU1 : {
469*437bfbebSnyanmisaka         name = mpp_find_device(mpp_vpu_dev);
470*437bfbebSnyanmisaka         client_type = VPU_DEC;
471*437bfbebSnyanmisaka         reg_size = VDPU1_REGISTERS;
472*437bfbebSnyanmisaka     } break;
473*437bfbebSnyanmisaka     case VPU_CLIENT_VDPU2 : {
474*437bfbebSnyanmisaka         name = mpp_find_device(mpp_vpu_dev);
475*437bfbebSnyanmisaka         client_type = VPU_DEC;
476*437bfbebSnyanmisaka         reg_size = VDPU2_REGISTERS;
477*437bfbebSnyanmisaka     } break;
478*437bfbebSnyanmisaka     case VPU_CLIENT_VDPU1_PP : {
479*437bfbebSnyanmisaka         name = mpp_find_device(mpp_vpu_dev);
480*437bfbebSnyanmisaka         client_type = VPU_DEC_PP;
481*437bfbebSnyanmisaka         if (ROCKCHIP_SOC_RK3036 == mpp_get_soc_type())
482*437bfbebSnyanmisaka             reg_size = VDPU1_REGISTERS;
483*437bfbebSnyanmisaka         else
484*437bfbebSnyanmisaka             reg_size = VDPU1_PP_REGISTERS;
485*437bfbebSnyanmisaka     } break;
486*437bfbebSnyanmisaka     case VPU_CLIENT_VDPU2_PP : {
487*437bfbebSnyanmisaka         name = mpp_find_device(mpp_vpu_dev);
488*437bfbebSnyanmisaka         client_type = VPU_DEC_PP;
489*437bfbebSnyanmisaka         reg_size = VDPU2_PP_REGISTERS;
490*437bfbebSnyanmisaka     } break;
491*437bfbebSnyanmisaka     case VPU_CLIENT_HEVC_DEC : {
492*437bfbebSnyanmisaka         name = mpp_find_device(mpp_hevc_dev);
493*437bfbebSnyanmisaka         client_type = VPU_DEC;
494*437bfbebSnyanmisaka         reg_size = RKHEVC_REGISTERS;
495*437bfbebSnyanmisaka         max_regs = 3;
496*437bfbebSnyanmisaka     } break;
497*437bfbebSnyanmisaka     case VPU_CLIENT_RKVDEC : {
498*437bfbebSnyanmisaka         name = mpp_find_device(mpp_rkvdec_dev);
499*437bfbebSnyanmisaka         client_type = VPU_DEC;
500*437bfbebSnyanmisaka         reg_size = RKVDEC_REGISTERS;
501*437bfbebSnyanmisaka         max_regs = 3;
502*437bfbebSnyanmisaka     } break;
503*437bfbebSnyanmisaka     case VPU_CLIENT_AVSPLUS_DEC : {
504*437bfbebSnyanmisaka         name = mpp_find_device(mpp_avsd_dev);
505*437bfbebSnyanmisaka         client_type = VPU_DEC;
506*437bfbebSnyanmisaka         reg_size = AVSD_REGISTERS;
507*437bfbebSnyanmisaka     } break;
508*437bfbebSnyanmisaka     case VPU_CLIENT_RKVENC : {
509*437bfbebSnyanmisaka         name = mpp_find_device(mpp_rkvenc_dev);
510*437bfbebSnyanmisaka         client_type = VPU_ENC;
511*437bfbebSnyanmisaka         reg_size = AVSD_REGISTERS;
512*437bfbebSnyanmisaka     } break;
513*437bfbebSnyanmisaka     case VPU_CLIENT_VEPU1 : {
514*437bfbebSnyanmisaka         name = mpp_find_device(mpp_vpu_dev);
515*437bfbebSnyanmisaka         client_type = VPU_ENC;
516*437bfbebSnyanmisaka         reg_size = VEPU1_REGISTERS;
517*437bfbebSnyanmisaka     } break;
518*437bfbebSnyanmisaka     case VPU_CLIENT_VEPU2 : {
519*437bfbebSnyanmisaka         name = mpp_find_device(mpp_vepu_dev);
520*437bfbebSnyanmisaka         if (NULL == name)
521*437bfbebSnyanmisaka             name = mpp_find_device(mpp_vpu_dev);
522*437bfbebSnyanmisaka         client_type = VPU_ENC;
523*437bfbebSnyanmisaka         reg_size = VEPU2_REGISTERS;
524*437bfbebSnyanmisaka     } break;
525*437bfbebSnyanmisaka     default : {
526*437bfbebSnyanmisaka         mpp_err_f("unsupported client type %d\n", type);
527*437bfbebSnyanmisaka         return ret;
528*437bfbebSnyanmisaka     } break;
529*437bfbebSnyanmisaka     }
530*437bfbebSnyanmisaka 
531*437bfbebSnyanmisaka     p->fd = open(name, O_RDWR | O_CLOEXEC);
532*437bfbebSnyanmisaka     if (p->fd < 0) {
533*437bfbebSnyanmisaka         mpp_err("open vcodec_service %s failed\n", name);
534*437bfbebSnyanmisaka         return ret;
535*437bfbebSnyanmisaka     }
536*437bfbebSnyanmisaka 
537*437bfbebSnyanmisaka     if (vcodec_ioctl_version < 0) {
538*437bfbebSnyanmisaka         ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE, (unsigned long)client_type);
539*437bfbebSnyanmisaka         if (!ret) {
540*437bfbebSnyanmisaka             vcodec_ioctl_version = 0;
541*437bfbebSnyanmisaka         } else {
542*437bfbebSnyanmisaka             ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE_U32, (RK_U32)client_type);
543*437bfbebSnyanmisaka             if (!ret)
544*437bfbebSnyanmisaka                 vcodec_ioctl_version = 1;
545*437bfbebSnyanmisaka         }
546*437bfbebSnyanmisaka         mpp_assert(ret == MPP_OK);
547*437bfbebSnyanmisaka     } else {
548*437bfbebSnyanmisaka         RK_U32 cmd = (vcodec_ioctl_version == 0) ?
549*437bfbebSnyanmisaka                      (VPU_IOC_SET_CLIENT_TYPE) :
550*437bfbebSnyanmisaka                      (VPU_IOC_SET_CLIENT_TYPE_U32);
551*437bfbebSnyanmisaka 
552*437bfbebSnyanmisaka         ret = (RK_S32)ioctl(p->fd, cmd, client_type);
553*437bfbebSnyanmisaka     }
554*437bfbebSnyanmisaka 
555*437bfbebSnyanmisaka     p->max_regs = max_regs;
556*437bfbebSnyanmisaka     p->reg_size = reg_size * sizeof(RK_U32);
557*437bfbebSnyanmisaka     {
558*437bfbebSnyanmisaka         RK_S32 i;
559*437bfbebSnyanmisaka 
560*437bfbebSnyanmisaka         for (i = 0; i < max_regs; i++) {
561*437bfbebSnyanmisaka             VcodecRegCfg *reg = &p->regs[i];
562*437bfbebSnyanmisaka 
563*437bfbebSnyanmisaka             reg->reg_size = p->reg_size;
564*437bfbebSnyanmisaka             extra_info_init(&reg->extra_info);
565*437bfbebSnyanmisaka         }
566*437bfbebSnyanmisaka     }
567*437bfbebSnyanmisaka 
568*437bfbebSnyanmisaka     return ret;
569*437bfbebSnyanmisaka }
570*437bfbebSnyanmisaka 
vcodec_service_deinit(void * ctx)571*437bfbebSnyanmisaka MPP_RET vcodec_service_deinit(void *ctx)
572*437bfbebSnyanmisaka {
573*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
574*437bfbebSnyanmisaka 
575*437bfbebSnyanmisaka     if (p->fd)
576*437bfbebSnyanmisaka         close(p->fd);
577*437bfbebSnyanmisaka 
578*437bfbebSnyanmisaka     return MPP_OK;
579*437bfbebSnyanmisaka }
580*437bfbebSnyanmisaka 
vcodec_service_reg_wr(void * ctx,MppDevRegWrCfg * cfg)581*437bfbebSnyanmisaka MPP_RET vcodec_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
582*437bfbebSnyanmisaka {
583*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
584*437bfbebSnyanmisaka     VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
585*437bfbebSnyanmisaka 
586*437bfbebSnyanmisaka     mpp_assert(cfg->offset == 0);
587*437bfbebSnyanmisaka     send_cfg->reg_set = cfg->reg;
588*437bfbebSnyanmisaka     send_cfg->reg_size = cfg->size;
589*437bfbebSnyanmisaka 
590*437bfbebSnyanmisaka     if (p->reg_size != cfg->size)
591*437bfbebSnyanmisaka         mpp_err_f("reg size mismatch wr %d rd %d\n",
592*437bfbebSnyanmisaka                   p->reg_size, cfg->size);
593*437bfbebSnyanmisaka 
594*437bfbebSnyanmisaka     return MPP_OK;
595*437bfbebSnyanmisaka }
596*437bfbebSnyanmisaka 
vcodec_service_reg_rd(void * ctx,MppDevRegRdCfg * cfg)597*437bfbebSnyanmisaka MPP_RET vcodec_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
598*437bfbebSnyanmisaka {
599*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
600*437bfbebSnyanmisaka     VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
601*437bfbebSnyanmisaka 
602*437bfbebSnyanmisaka     mpp_assert(cfg->offset == 0);
603*437bfbebSnyanmisaka     send_cfg->reg_get = cfg->reg;
604*437bfbebSnyanmisaka     if (send_cfg->reg_size != cfg->size)
605*437bfbebSnyanmisaka         mpp_err_f("reg size mismatch rd %d rd %d\n",
606*437bfbebSnyanmisaka                   send_cfg->reg_size, cfg->size);
607*437bfbebSnyanmisaka 
608*437bfbebSnyanmisaka     return MPP_OK;
609*437bfbebSnyanmisaka }
610*437bfbebSnyanmisaka 
vcodec_service_reg_offset(void * ctx,MppDevRegOffsetCfg * cfg)611*437bfbebSnyanmisaka MPP_RET vcodec_service_reg_offset(void *ctx, MppDevRegOffsetCfg *cfg)
612*437bfbebSnyanmisaka {
613*437bfbebSnyanmisaka     if (cfg->offset) {
614*437bfbebSnyanmisaka         MppDevVcodecService *p = (MppDevVcodecService *)ctx;
615*437bfbebSnyanmisaka         VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
616*437bfbebSnyanmisaka         VcodecExtraInfo *extra = &send_cfg->extra_info;
617*437bfbebSnyanmisaka         VcodecExtraSlot *slot;
618*437bfbebSnyanmisaka         RK_U32 i;
619*437bfbebSnyanmisaka 
620*437bfbebSnyanmisaka         for (i = 0; i < extra->count; i++) {
621*437bfbebSnyanmisaka             slot = &extra->slots[i];
622*437bfbebSnyanmisaka 
623*437bfbebSnyanmisaka             if (slot->reg_idx == cfg->reg_idx) {
624*437bfbebSnyanmisaka                 mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n",
625*437bfbebSnyanmisaka                           slot->reg_idx, slot->offset, cfg->offset);
626*437bfbebSnyanmisaka                 slot->offset = cfg->offset;
627*437bfbebSnyanmisaka                 return MPP_OK;
628*437bfbebSnyanmisaka             }
629*437bfbebSnyanmisaka         }
630*437bfbebSnyanmisaka 
631*437bfbebSnyanmisaka         slot = &extra->slots[extra->count];
632*437bfbebSnyanmisaka         slot->reg_idx = cfg->reg_idx;
633*437bfbebSnyanmisaka         slot->offset = cfg->offset;
634*437bfbebSnyanmisaka         extra->count++;
635*437bfbebSnyanmisaka     }
636*437bfbebSnyanmisaka 
637*437bfbebSnyanmisaka     return MPP_OK;
638*437bfbebSnyanmisaka }
639*437bfbebSnyanmisaka 
vcodec_service_cmd_send(void * ctx)640*437bfbebSnyanmisaka MPP_RET vcodec_service_cmd_send(void *ctx)
641*437bfbebSnyanmisaka {
642*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
643*437bfbebSnyanmisaka     VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
644*437bfbebSnyanmisaka     VcodecExtraInfo *extra = &send_cfg->extra_info;
645*437bfbebSnyanmisaka     void *reg_set = send_cfg->reg_set;
646*437bfbebSnyanmisaka     char *fmt = (char*)&p->fmt;
647*437bfbebSnyanmisaka 
648*437bfbebSnyanmisaka     update_extra_info(extra, fmt, send_cfg);
649*437bfbebSnyanmisaka 
650*437bfbebSnyanmisaka     MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_SET_REG,
651*437bfbebSnyanmisaka                                        reg_set, send_cfg->reg_size);
652*437bfbebSnyanmisaka     if (ret) {
653*437bfbebSnyanmisaka         mpp_err_f("ioctl VPU_IOC_SET_REG failed ret %d errno %d %s\n",
654*437bfbebSnyanmisaka                   ret, errno, strerror(errno));
655*437bfbebSnyanmisaka         ret = errno;
656*437bfbebSnyanmisaka     }
657*437bfbebSnyanmisaka 
658*437bfbebSnyanmisaka     p->reg_send_idx++;
659*437bfbebSnyanmisaka     if (p->reg_send_idx >= p->max_regs)
660*437bfbebSnyanmisaka         p->reg_send_idx = 0;
661*437bfbebSnyanmisaka     p->info_count = 0;
662*437bfbebSnyanmisaka 
663*437bfbebSnyanmisaka     return ret;
664*437bfbebSnyanmisaka }
665*437bfbebSnyanmisaka 
vcodec_service_cmd_poll(void * ctx,MppDevPollCfg * cfg)666*437bfbebSnyanmisaka MPP_RET vcodec_service_cmd_poll(void *ctx, MppDevPollCfg *cfg)
667*437bfbebSnyanmisaka {
668*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
669*437bfbebSnyanmisaka     VcodecRegCfg *poll_cfg = &p->regs[p->reg_poll_idx];
670*437bfbebSnyanmisaka     void *reg_get = poll_cfg->reg_get;
671*437bfbebSnyanmisaka     RK_S32 reg_size = poll_cfg->reg_size;
672*437bfbebSnyanmisaka     MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_GET_REG,
673*437bfbebSnyanmisaka                                        reg_get, reg_size);
674*437bfbebSnyanmisaka     if (ret) {
675*437bfbebSnyanmisaka         mpp_err_f("ioctl VPU_IOC_GET_REG failed ret %d errno %d %s\n",
676*437bfbebSnyanmisaka                   ret, errno, strerror(errno));
677*437bfbebSnyanmisaka         ret = errno;
678*437bfbebSnyanmisaka     }
679*437bfbebSnyanmisaka 
680*437bfbebSnyanmisaka     p->reg_poll_idx++;
681*437bfbebSnyanmisaka     if (p->reg_poll_idx >= p->max_regs)
682*437bfbebSnyanmisaka         p->reg_poll_idx = 0;
683*437bfbebSnyanmisaka 
684*437bfbebSnyanmisaka     (void)cfg;
685*437bfbebSnyanmisaka     return ret;
686*437bfbebSnyanmisaka }
687*437bfbebSnyanmisaka 
vcodec_service_set_info(void * ctx,MppDevInfoCfg * cfg)688*437bfbebSnyanmisaka MPP_RET vcodec_service_set_info(void *ctx, MppDevInfoCfg *cfg)
689*437bfbebSnyanmisaka {
690*437bfbebSnyanmisaka     MppDevVcodecService *p = (MppDevVcodecService *)ctx;
691*437bfbebSnyanmisaka 
692*437bfbebSnyanmisaka     if (!p->info_count)
693*437bfbebSnyanmisaka         memset(p->info, 0, sizeof(p->info));
694*437bfbebSnyanmisaka 
695*437bfbebSnyanmisaka     if (p->info_count >= MAX_INFO_COUNT) {
696*437bfbebSnyanmisaka         mpp_err("info count reach max\n");
697*437bfbebSnyanmisaka         return MPP_NOK;
698*437bfbebSnyanmisaka     }
699*437bfbebSnyanmisaka 
700*437bfbebSnyanmisaka     memcpy(&p->info[p->info_count], cfg, sizeof(MppDevInfoCfg));
701*437bfbebSnyanmisaka     p->info_count++;
702*437bfbebSnyanmisaka 
703*437bfbebSnyanmisaka     if (cfg->type == INFO_FORMAT_TYPE) {
704*437bfbebSnyanmisaka         p->fmt = cfg->data;
705*437bfbebSnyanmisaka     }
706*437bfbebSnyanmisaka     return MPP_OK;
707*437bfbebSnyanmisaka }
708*437bfbebSnyanmisaka 
709*437bfbebSnyanmisaka const MppDevApi vcodec_service_api = {
710*437bfbebSnyanmisaka     "vcodec_service",
711*437bfbebSnyanmisaka     sizeof(MppDevVcodecService),
712*437bfbebSnyanmisaka     vcodec_service_init,
713*437bfbebSnyanmisaka     vcodec_service_deinit,
714*437bfbebSnyanmisaka     NULL,
715*437bfbebSnyanmisaka     NULL,
716*437bfbebSnyanmisaka     NULL,
717*437bfbebSnyanmisaka     NULL,
718*437bfbebSnyanmisaka     vcodec_service_reg_wr,
719*437bfbebSnyanmisaka     vcodec_service_reg_rd,
720*437bfbebSnyanmisaka     vcodec_service_reg_offset,
721*437bfbebSnyanmisaka     NULL,
722*437bfbebSnyanmisaka     NULL,
723*437bfbebSnyanmisaka     vcodec_service_set_info,
724*437bfbebSnyanmisaka     NULL,
725*437bfbebSnyanmisaka     NULL,
726*437bfbebSnyanmisaka     NULL,
727*437bfbebSnyanmisaka     NULL,
728*437bfbebSnyanmisaka     NULL,
729*437bfbebSnyanmisaka     vcodec_service_cmd_send,
730*437bfbebSnyanmisaka     vcodec_service_cmd_poll,
731*437bfbebSnyanmisaka };
732