xref: /OK3568_Linux_fs/external/mpp/osal/driver/mpp_device.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2020 Rockchip Electronics Co. LTD
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun  * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun  * You may obtain a copy of the License at
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun  * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun  * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun  * limitations under the License.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define MODULE_TAG "mpp_device"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <string.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include "mpp_env.h"
22*4882a593Smuzhiyun #include "mpp_mem.h"
23*4882a593Smuzhiyun #include "mpp_common.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "mpp_platform.h"
26*4882a593Smuzhiyun #include "mpp_device_debug.h"
27*4882a593Smuzhiyun #include "mpp_service_api.h"
28*4882a593Smuzhiyun #include "vcodec_service_api.h"
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun typedef struct MppDevImpl_t {
31*4882a593Smuzhiyun     MppClientType   type;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun     void            *ctx;
34*4882a593Smuzhiyun     const MppDevApi *api;
35*4882a593Smuzhiyun } MppDevImpl;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun RK_U32 mpp_device_debug = 0;
38*4882a593Smuzhiyun 
mpp_dev_init(MppDev * ctx,MppClientType type)39*4882a593Smuzhiyun MPP_RET mpp_dev_init(MppDev *ctx, MppClientType type)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun     if (NULL == ctx) {
42*4882a593Smuzhiyun         mpp_err_f("found NULL input ctx\n");
43*4882a593Smuzhiyun         return MPP_ERR_NULL_PTR;
44*4882a593Smuzhiyun     }
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun     mpp_env_get_u32("mpp_device_debug", &mpp_device_debug, 0);
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun     *ctx = NULL;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun     RK_U32 codec_type = mpp_get_vcodec_type();
51*4882a593Smuzhiyun     if (!(codec_type & (1 << type))) {
52*4882a593Smuzhiyun         mpp_err_f("found unsupported client type %d in platform %x\n",
53*4882a593Smuzhiyun                   type, codec_type);
54*4882a593Smuzhiyun         return MPP_ERR_VALUE;
55*4882a593Smuzhiyun     }
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun     MppIoctlVersion ioctl_version = mpp_get_ioctl_version();
58*4882a593Smuzhiyun     const MppDevApi *api = NULL;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun     switch (ioctl_version) {
61*4882a593Smuzhiyun     case IOCTL_VCODEC_SERVICE : {
62*4882a593Smuzhiyun         api = &vcodec_service_api;
63*4882a593Smuzhiyun     } break;
64*4882a593Smuzhiyun     case IOCTL_MPP_SERVICE_V1 : {
65*4882a593Smuzhiyun         api = &mpp_service_api;
66*4882a593Smuzhiyun     } break;
67*4882a593Smuzhiyun     default : {
68*4882a593Smuzhiyun         mpp_err_f("invalid ioctl verstion %d\n", ioctl_version);
69*4882a593Smuzhiyun         return MPP_NOK;
70*4882a593Smuzhiyun     } break;
71*4882a593Smuzhiyun     }
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun     MppDevImpl *impl = mpp_calloc(MppDevImpl, 1);
74*4882a593Smuzhiyun     void *impl_ctx = mpp_calloc_size(void, api->ctx_size);
75*4882a593Smuzhiyun     if (NULL == impl || NULL == impl_ctx) {
76*4882a593Smuzhiyun         mpp_err_f("malloc failed impl %p impl_ctx %p\n", impl, impl_ctx);
77*4882a593Smuzhiyun         MPP_FREE(impl);
78*4882a593Smuzhiyun         MPP_FREE(impl_ctx);
79*4882a593Smuzhiyun         return MPP_ERR_MALLOC;
80*4882a593Smuzhiyun     }
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun     impl->ctx = impl_ctx;
83*4882a593Smuzhiyun     impl->api = api;
84*4882a593Smuzhiyun     impl->type = type;
85*4882a593Smuzhiyun     *ctx = impl;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun     return api->init(impl_ctx, type);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
mpp_dev_deinit(MppDev ctx)90*4882a593Smuzhiyun MPP_RET mpp_dev_deinit(MppDev ctx)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun     if (NULL == ctx) {
93*4882a593Smuzhiyun         mpp_err_f("found NULL input ctx\n");
94*4882a593Smuzhiyun         return MPP_ERR_NULL_PTR;
95*4882a593Smuzhiyun     }
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun     MppDevImpl *p = (MppDevImpl *)ctx;
98*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun     if (p->api && p->api->deinit && p->ctx)
101*4882a593Smuzhiyun         ret = p->api->deinit(p->ctx);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun     MPP_FREE(p->ctx);
104*4882a593Smuzhiyun     MPP_FREE(p);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun     return ret;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
mpp_dev_ioctl(MppDev ctx,RK_S32 cmd,void * param)109*4882a593Smuzhiyun MPP_RET mpp_dev_ioctl(MppDev ctx, RK_S32 cmd, void *param)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun     if (NULL == ctx) {
112*4882a593Smuzhiyun         mpp_err_f("found NULL input ctx\n");
113*4882a593Smuzhiyun         return MPP_ERR_NULL_PTR;
114*4882a593Smuzhiyun     }
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun     MppDevImpl *p = (MppDevImpl *)ctx;
117*4882a593Smuzhiyun     const MppDevApi *api = p->api;
118*4882a593Smuzhiyun     void *impl_ctx = p->ctx;
119*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun     if (NULL == impl_ctx || NULL == api)
122*4882a593Smuzhiyun         return ret;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     switch (cmd) {
125*4882a593Smuzhiyun     case MPP_DEV_BATCH_ON : {
126*4882a593Smuzhiyun         if (api->attach)
127*4882a593Smuzhiyun             ret = api->attach(impl_ctx);
128*4882a593Smuzhiyun     } break;
129*4882a593Smuzhiyun     case MPP_DEV_BATCH_OFF : {
130*4882a593Smuzhiyun         if (api->detach)
131*4882a593Smuzhiyun             ret = api->detach(impl_ctx);
132*4882a593Smuzhiyun     } break;
133*4882a593Smuzhiyun     case MPP_DEV_DELIMIT : {
134*4882a593Smuzhiyun         if (api->delimit)
135*4882a593Smuzhiyun             ret = api->delimit(impl_ctx);
136*4882a593Smuzhiyun     } break;
137*4882a593Smuzhiyun     case MPP_DEV_SET_CB_CTX: {
138*4882a593Smuzhiyun         if (api->set_cb_ctx)
139*4882a593Smuzhiyun             ret = api->set_cb_ctx(impl_ctx, param);
140*4882a593Smuzhiyun     } break;
141*4882a593Smuzhiyun     case MPP_DEV_REG_WR : {
142*4882a593Smuzhiyun         if (api->reg_wr)
143*4882a593Smuzhiyun             ret = api->reg_wr(impl_ctx, param);
144*4882a593Smuzhiyun     } break;
145*4882a593Smuzhiyun     case MPP_DEV_REG_RD : {
146*4882a593Smuzhiyun         if (api->reg_rd)
147*4882a593Smuzhiyun             ret = api->reg_rd(impl_ctx, param);
148*4882a593Smuzhiyun     } break;
149*4882a593Smuzhiyun     case MPP_DEV_REG_OFFSET : {
150*4882a593Smuzhiyun         if (api->reg_offset)
151*4882a593Smuzhiyun             ret = api->reg_offset(impl_ctx, param);
152*4882a593Smuzhiyun     } break;
153*4882a593Smuzhiyun     case MPP_DEV_REG_OFFS : {
154*4882a593Smuzhiyun         if (api->reg_offs)
155*4882a593Smuzhiyun             ret = api->reg_offs(impl_ctx, param);
156*4882a593Smuzhiyun     } break;
157*4882a593Smuzhiyun     case MPP_DEV_RCB_INFO : {
158*4882a593Smuzhiyun         if (api->rcb_info)
159*4882a593Smuzhiyun             ret = api->rcb_info(impl_ctx, param);
160*4882a593Smuzhiyun     } break;
161*4882a593Smuzhiyun     case MPP_DEV_SET_INFO : {
162*4882a593Smuzhiyun         if (api->set_info)
163*4882a593Smuzhiyun             ret = api->set_info(impl_ctx, param);
164*4882a593Smuzhiyun     } break;
165*4882a593Smuzhiyun     case MPP_DEV_SET_ERR_REF_HACK : {
166*4882a593Smuzhiyun         if (api->set_err_ref_hack)
167*4882a593Smuzhiyun             ret = api->set_err_ref_hack(impl_ctx, param);
168*4882a593Smuzhiyun     } break;
169*4882a593Smuzhiyun     case MPP_DEV_CMD_SEND : {
170*4882a593Smuzhiyun         if (api->cmd_send)
171*4882a593Smuzhiyun             ret = api->cmd_send(impl_ctx);
172*4882a593Smuzhiyun     } break;
173*4882a593Smuzhiyun     case MPP_DEV_CMD_POLL : {
174*4882a593Smuzhiyun         if (api->cmd_poll)
175*4882a593Smuzhiyun             ret = api->cmd_poll(impl_ctx, param);
176*4882a593Smuzhiyun     } break;
177*4882a593Smuzhiyun     default : {
178*4882a593Smuzhiyun         mpp_err_f("invalid cmd %d\n", cmd);
179*4882a593Smuzhiyun     } break;
180*4882a593Smuzhiyun     }
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun     return ret;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
mpp_dev_set_reg_offset(MppDev dev,RK_S32 index,RK_U32 offset)185*4882a593Smuzhiyun MPP_RET mpp_dev_set_reg_offset(MppDev dev, RK_S32 index, RK_U32 offset)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun     MppDevRegOffsetCfg trans_cfg;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun     trans_cfg.reg_idx = index;
190*4882a593Smuzhiyun     trans_cfg.offset = offset;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun     return mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /* register offset multi config */
mpp_dev_multi_offset_init(MppDevRegOffCfgs ** cfgs,RK_S32 size)196*4882a593Smuzhiyun MPP_RET mpp_dev_multi_offset_init(MppDevRegOffCfgs **cfgs, RK_S32 size)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun     RK_S32 cfg_size = sizeof(MppDevRegOffCfgs) + size * sizeof(MppDevRegOffsetCfg);
199*4882a593Smuzhiyun     MppDevRegOffCfgs *p = NULL;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun     if (NULL == cfgs || size <= 0) {
202*4882a593Smuzhiyun         mpp_err_f("invalid pointer %p size %d\n", cfgs, size);
203*4882a593Smuzhiyun         return MPP_NOK;
204*4882a593Smuzhiyun     }
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun     p = mpp_calloc_size(MppDevRegOffCfgs, cfg_size);
207*4882a593Smuzhiyun     if (p)
208*4882a593Smuzhiyun         p->size = size;
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun     *cfgs = p;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun     return (p) ? MPP_OK : MPP_NOK;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun 
mpp_dev_multi_offset_deinit(MppDevRegOffCfgs * cfgs)215*4882a593Smuzhiyun MPP_RET mpp_dev_multi_offset_deinit(MppDevRegOffCfgs *cfgs)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun     MPP_FREE(cfgs);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun     return MPP_OK;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
mpp_dev_multi_offset_reset(MppDevRegOffCfgs * cfgs)222*4882a593Smuzhiyun MPP_RET mpp_dev_multi_offset_reset(MppDevRegOffCfgs *cfgs)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun     if (cfgs) {
225*4882a593Smuzhiyun         memset(cfgs->cfgs, 0, cfgs->count * sizeof(cfgs->cfgs[0]));
226*4882a593Smuzhiyun         cfgs->count = 0;
227*4882a593Smuzhiyun     }
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun     return MPP_OK;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun 
mpp_dev_multi_offset_update(MppDevRegOffCfgs * cfgs,RK_S32 index,RK_U32 offset)232*4882a593Smuzhiyun MPP_RET mpp_dev_multi_offset_update(MppDevRegOffCfgs *cfgs, RK_S32 index, RK_U32 offset)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun     MppDevRegOffsetCfg *cfg;
235*4882a593Smuzhiyun     RK_S32 count;
236*4882a593Smuzhiyun     RK_S32 i;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun     if (NULL == cfgs)
239*4882a593Smuzhiyun         return MPP_NOK;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun     if (cfgs->count >= cfgs->size) {
242*4882a593Smuzhiyun         mpp_err_f("invalid cfgs count %d : %d\n", cfgs->count, cfgs->size);
243*4882a593Smuzhiyun         return MPP_NOK;
244*4882a593Smuzhiyun     }
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun     count = cfgs->count;
247*4882a593Smuzhiyun     cfg = cfgs->cfgs;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun     for (i = 0; i < count; i++, cfg++) {
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun         if (cfg->reg_idx == (RK_U32)index) {
252*4882a593Smuzhiyun             cfg->offset = offset;
253*4882a593Smuzhiyun             return MPP_OK;
254*4882a593Smuzhiyun         }
255*4882a593Smuzhiyun     }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun     cfg->reg_idx = index;
258*4882a593Smuzhiyun     cfg->offset = offset;
259*4882a593Smuzhiyun     cfgs->count++;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun     return MPP_OK;
262*4882a593Smuzhiyun }
263