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