]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/dspdce.git/blob - src/ti/framework/dce/dce.c
get_rproc_info: Introduce new API to query remoteproc
[glsdk/dspdce.git] / src / ti / framework / dce / dce.c
1 /*\r
2  * Copyright (c) 2011, Texas Instruments Incorporated\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  *\r
9  * *  Redistributions of source code must retain the above copyright\r
10  *    notice, this list of conditions and the following disclaimer.\r
11  *\r
12  * *  Redistributions in binary form must reproduce the above copyright\r
13  *    notice, this list of conditions and the following disclaimer in the\r
14  *    documentation and/or other materials provided with the distribution.\r
15  *\r
16  * *  Neither the name of Texas Instruments Incorporated nor the names of\r
17  *    its contributors may be used to endorse or promote products derived\r
18  *    from this software without specific prior written permission.\r
19  *\r
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31  */\r
32 \r
33 #include <stdlib.h>\r
34 #include <stdint.h>\r
35 #include <string.h>\r
36 #include <stdio.h>\r
37 #include <ti/grcm/RcmServer.h>\r
38 #include <ti/grcm/RcmTypes.h>\r
39 #include <ti/ipc/mm/MmServiceMgr.h>\r
40 #include <ti/ipc/mm/MmRpc.h>\r
41 #include <ti/ipc/MultiProc.h>\r
42 #include <ti/ipc/rpmsg/RPMessage.h>\r
43 #include <ti/ipc/rpmsg/NameMap.h>\r
44 #include <ti/pm/IpcPower.h>\r
45 #include <ti/sdo/ce/global/CESettings.h>\r
46 #include <ti/sdo/ce/CERuntime.h>\r
47 #include <ti/sdo/ce/Engine.h>\r
48 #include <ti/sdo/ce/video2/viddec2.h>\r
49 #include <ti/sdo/ce/universal/universal.h>\r
50 #include <ti/sdo/fc/global/FCSettings.h>\r
51 #include <ti/sdo/fc/utils/fcutils.h>\r
52 #include <ti/sysbios/BIOS.h>\r
53 #include <ti/sysbios/hal/Cache.h>\r
54 #include <ti/sysbios/knl/Task.h>\r
55 #include <ti/xdais/dm/xdm.h>\r
56 #include <xdc/cfg/global.h>\r
57 #include <xdc/runtime/System.h>\r
58 #include <xdc/runtime/Diags.h>\r
59 #include <xdc/runtime/Memory.h>\r
60 #include <xdc/runtime/IHeap.h>\r
61 #include <xdc/runtime/knl/Thread.h>\r
62 #include <xdc/std.h>\r
63 #include <ti/sysbios/utils/Load.h>\r
64 \r
65 #include "dce_priv.h"\r
66 #include "dce_rpc.h"\r
67 \r
68 static uint32_t    suspend_initialised = 0;\r
69 uint32_t           dce_debug = DCE_DEBUG_LEVEL;\r
70 \r
71 #define SERVER_NAME "rpmsg-dce-dsp"\r
72 #define MEMORYSTATS_DEBUG\r
73 \r
74 #define MmRpc_NUM_PARAMETERS(size) \\r
75     (size / sizeof(MmType_Param))\r
76 \r
77 /* dce_inv, dce_clean needs to be modified to expect buffers */\r
78 /* without headers (relevant for GLP                                    */\r
79 static void dce_inv(void *ptr)\r
80 {\r
81     if( ptr ) {\r
82         Cache_inv(ptr, P2H(ptr)->size, Cache_Type_ALL, TRUE);\r
83     }\r
84 }\r
85 \r
86 static void dce_clean(void *ptr)\r
87 {\r
88     if( ptr ) {\r
89         Cache_wbInv(ptr, P2H(ptr)->size, Cache_Type_ALL, TRUE);\r
90     }\r
91 }\r
92 \r
93 typedef void * (*CreateFxn)(Engine_Handle, String, void *);\r
94 typedef Int32 (*ControlFxn)(void *, int, void *, void *);\r
95 typedef Int32 (*ProcessFxn)(void *, void *, void *, void *, void *);\r
96 typedef Int32 (*RelocFxn)(void *, uint8_t *ptr, uint32_t len);\r
97 typedef void (*DeleteFxn)(void *);\r
98 \r
99 /* DCE Server static function declarations */\r
100 static Int32 engine_open(UInt32 size, UInt32 *data);\r
101 static Int32 engine_close(UInt32 size, UInt32 *data);\r
102 static Int32 get_rproc_info(UInt32 size, UInt32 *data);\r
103 \r
104 /* VIDDEC2 Decoder Server static function declarations */\r
105 static VIDDEC2_Handle viddec2_create(Engine_Handle engine, String name, VIDDEC2_Params *params);\r
106 static int viddec2_reloc(VIDDEC2_Handle handle, uint8_t *ptr, uint32_t len);\r
107 static int viddec2_control(VIDDEC2_Handle handle, VIDDEC2_Cmd id, VIDDEC2_DynamicParams *dynParams,\r
108                               VIDDEC2_Status *status );\r
109 static int viddec2_process(VIDDEC2_Handle handle, XDM1_BufDesc *inBufs,\r
110                          XDM_BufDesc *outBufs, VIDDEC2_InArgs *inArgs, VIDDEC2_OutArgs *outArgs );\r
111 static int viddec2_delete(VIDDEC2_Handle handle);\r
112 \r
113 static struct {\r
114     CreateFxn  create;\r
115     ControlFxn control;\r
116     ProcessFxn process;\r
117     DeleteFxn  delete;\r
118     RelocFxn   reloc;   /* handle buffer relocation table */\r
119 } codec_fxns[] =\r
120 {\r
121     [OMAP_DCE_VIDDEC2] =\r
122     {\r
123         (CreateFxn)viddec2_create,   (ControlFxn)viddec2_control,\r
124         (ProcessFxn)viddec2_process, (DeleteFxn)viddec2_delete,\r
125         (RelocFxn)viddec2_reloc,\r
126     },\r
127 };\r
128 \r
129 #define UNIVERSAL_COPY_EXAMPLE\r
130 /* Static version string buffer.\r
131  * Note: codec version can be large. For example, h264vdec needs more than\r
132  * 58 characters, or the query will fail. */\r
133 #define VERSION_SIZE 128\r
134 static char    version_buffer[VERSION_SIZE];\r
135 \r
136 /* the following callbacks are needed for suspend/resume\r
137  * on the linux side.\r
138  * - FC_suspend() waits for all algorithms to get deactivated and\r
139  * and takes care of the resources acquired.\r
140  * - FC_resume() does nothing for now, but we add it just in case\r
141  * it gets populated in the future versions of framework components.\r
142  *\r
143  * Forced off mode during video decode/encode is not supported. */\r
144 #if 0\r
145 static void dce_suspend()\r
146 {\r
147     INFO("Preparing for suspend...");\r
148     FC_suspend();\r
149 }\r
150 \r
151 static void dce_resume()\r
152 {\r
153     INFO("Restoring after suspend...");\r
154     FC_resume();\r
155 }\r
156 #endif\r
157 \r
158 #ifdef UNIVERSAL_COPY_EXAMPLE\r
159 static void get_universal_version(UNIVERSAL_Handle h, char *buffer, unsigned size)\r
160 {\r
161     UNIVERSAL_DynamicParams    params =\r
162     {\r
163         .size = sizeof(UNIVERSAL_DynamicParams),\r
164     };\r
165 \r
166     UNIVERSAL_Status    status =\r
167     {\r
168         .size = sizeof(UNIVERSAL_Status),\r
169         .data =\r
170         {\r
171                     .numBufs = 1,\r
172             .descs[0].buf = (XDAS_Int8 *)buffer,\r
173             .descs[0].bufSize = (XDAS_Int32)size,\r
174         },\r
175     };\r
176 \r
177     XDAS_Int32    s;\r
178 \r
179     memset(buffer, 0, size);\r
180     s = UNIVERSAL_control(h, XDM_GETVERSION, &params, &status);\r
181 \r
182     if( s != IUNIVERSAL_EOK ) {\r
183         ERROR("Unknown version Error = %d:: buffer = %p size = %d", s, buffer, size);\r
184     }\r
185 }\r
186 #else\r
187 static void get_viddec2_version(VIDDEC2_Handle h, char *buffer, unsigned size)\r
188 {\r
189     VIDDEC2_DynamicParams    params =\r
190     {\r
191         .size = sizeof(VIDDEC2_DynamicParams),\r
192     };\r
193 \r
194     VIDDEC2_Status    status =\r
195     {\r
196         .size = sizeof(VIDDEC2_Status),\r
197         .data =\r
198         {\r
199             .buf = (XDAS_Int8 *)buffer,\r
200             .bufSize = (XDAS_Int32)size,\r
201         },\r
202     };\r
203 \r
204     XDAS_Int32    s;\r
205 \r
206     memset(buffer, 0, size);\r
207     s = VIDDEC2_control(h, XDM_GETVERSION, &params, &status);\r
208 \r
209     if( s != VIDDEC2_EOK ) {\r
210         ERROR("Unknown version Error = %d:: buffer = %p size = %d", s, buffer, size);\r
211     }\r
212 }\r
213 \r
214 #endif\r
215 \r
216 // VIDDEC2_create wrapper, to display version string in the trace.\r
217 static VIDDEC2_Handle viddec2_create(Engine_Handle engine, String name, VIDDEC2_Params *params)\r
218 {\r
219 #ifdef UNIVERSAL_COPY_EXAMPLE\r
220     UNIVERSAL_Handle   h;\r
221 \r
222     DEBUG(">> engine=%08x, name=%s, params=%p", engine, name, params);\r
223 \r
224     h = UNIVERSAL_create(engine, name, (IUNIVERSAL_Params*)params);\r
225     if(h){\r
226         get_universal_version(h, version_buffer, VERSION_SIZE);\r
227         INFO("Created codec %s: version %s", name, version_buffer);\r
228       }\r
229 #else\r
230     VIDDEC2_Handle    h;\r
231 \r
232     h = VIDDEC2_create(engine, name, params);\r
233 \r
234     if( h ) {\r
235         get_viddec2_version(h, version_buffer, VERSION_SIZE);\r
236         INFO("Created viddec2 %s: version %s", name, version_buffer);\r
237     }\r
238 #endif\r
239     return ((VIDDEC2_Handle)h);\r
240 }\r
241 \r
242 /* needs to be updated when XDM_MOVEBUFS added in XDC tools */\r
243 static int viddec2_reloc(VIDDEC2_Handle handle, uint8_t *ptr, uint32_t len)\r
244 {\r
245     return (-1); // TODO\r
246 \r
247 }\r
248 \r
249 static int viddec2_control(VIDDEC2_Handle handle, VIDDEC2_Cmd id, VIDDEC2_DynamicParams *dynParams,\r
250                               VIDDEC2_Status *status )\r
251 {\r
252    int ret = 0;\r
253 #ifdef UNIVERSAL_COPY_EXAMPLE\r
254    UNIVERSAL_DynamicParams udynParam;\r
255    UNIVERSAL_Status ustatus;\r
256 \r
257    udynParam.size = sizeof(UNIVERSAL_DynamicParams);\r
258    ustatus.size = sizeof(UNIVERSAL_Status);\r
259 \r
260    if(id == XDM_GETVERSION){\r
261        ustatus.data.numBufs = 1;\r
262            ustatus.data.descs[0].buf = status->data.buf;\r
263            ustatus.data.descs[0].bufSize = status->data.bufSize;\r
264      }\r
265 \r
266    ret = UNIVERSAL_control((UNIVERSAL_Handle)handle, (UNIVERSAL_Cmd)id,\r
267                               &udynParam, &ustatus);\r
268 \r
269    /*universal copy supports only XDM_GETVERSION cmd id    */\r
270    /*This is to return success to VIDDEC2 application in case of other cmd ids */\r
271    if(ret == IUNIVERSAL_EFAIL)ret = IUNIVERSAL_EOK;\r
272 #else\r
273    ret = VIDDEC2_control(handle, id, dynParams, status);\r
274 #endif\r
275    return ret;\r
276 }\r
277 \r
278 static int viddec2_process(VIDDEC2_Handle handle, XDM1_BufDesc *inBufs,\r
279                          XDM_BufDesc *outBufs, VIDDEC2_InArgs *inArgs, VIDDEC2_OutArgs *outArgs )\r
280 {\r
281      int ret = 0;\r
282 #ifdef UNIVERSAL_COPY_EXAMPLE\r
283          XDM1_BufDesc inBuf, outBuf;\r
284          UNIVERSAL_InArgs inArg;\r
285          UNIVERSAL_OutArgs outArg;\r
286 \r
287      inArg.size = sizeof(UNIVERSAL_InArgs);\r
288      outArg.size = sizeof(UNIVERSAL_OutArgs);\r
289      outArg.extendedError = 0;\r
290 \r
291          inBuf.numBufs = 1;\r
292          outBuf.numBufs = 1;\r
293          inBuf.descs[0].buf = inBufs->descs[0].buf;\r
294          inBuf.descs[0].bufSize = inBufs->descs[0].bufSize;\r
295 \r
296          outBuf.descs[0].buf = outBufs->bufs[0];\r
297          outBuf.descs[0].bufSize = outBufs->bufSizes[0];\r
298 \r
299      ret = UNIVERSAL_process((UNIVERSAL_Handle)handle, &inBuf, &outBuf, NULL,\r
300                                 &inArg, &outArg);\r
301 #else\r
302     ret = VIDDEC2_process(handle, inBufs, outBufs, inArgs, outArgs);\r
303 #endif\r
304           return ret;\r
305 }\r
306 \r
307 static int viddec2_delete(VIDDEC2_Handle handle)\r
308 {\r
309 #ifdef UNIVERSAL_COPY_EXAMPLE\r
310    UNIVERSAL_delete((UNIVERSAL_Handle)handle);\r
311 #else\r
312    VIDDEC2_delete(handle);\r
313 #endif\r
314    return 0;\r
315 }\r
316 \r
317 \r
318 /*\r
319  * RPC message handlers\r
320  */\r
321 static int connect(void *msg)\r
322 {\r
323     //dce_connect   *req = msg;\r
324     //DEBUG(">> chipset_id=0x%x, debug=%d", req->chipset_id, req->debug);\r
325 \r
326     if( dce_debug >= MAX_DEBUG_LEVEL ) {\r
327         DEBUG("Enable FC, CE and IPC traces");\r
328 \r
329         FCSettings_init();\r
330         Diags_setMask(FCSETTINGS_MODNAME "+12345678LEXAIZFS");\r
331 \r
332                 CESettings_init();\r
333         Diags_setMask(CESETTINGS_MODNAME "+12345678LEXAIZFS");\r
334 \r
335         /*\r
336             * Enable use of runtime Diags_setMask per module:\r
337             *\r
338             * Codes: E = ENTRY, X = EXIT, L = LIFECYCLE, F = INFO, S = STATUS\r
339             */\r
340         Diags_setMask("ti.ipc.rpmsg.RPMessage=EXLFS");\r
341         Diags_setMask("ti.ipc.rpmsg.VirtQueue=EXLFS");\r
342     }\r
343 \r
344           CERuntime_init();\r
345 \r
346       if( !suspend_initialised ) {\r
347 \r
348         /* registering sysbios-rpmsg callbacks for suspend/resume */\r
349      //   IpcPower_registerCallback(IpcPower_Event_SUSPEND, (IpcPower_CallbackFuncPtr)dce_suspend, 0);\r
350      //   IpcPower_registerCallback(IpcPower_Event_RESUME, (IpcPower_CallbackFuncPtr)dce_resume, 0);\r
351         suspend_initialised++;\r
352     }\r
353 \r
354     DEBUG("<<");\r
355 \r
356     return (0);\r
357 }\r
358 \r
359 /*\r
360  * Engine_open:\r
361  */\r
362 static Int32 engine_open(UInt32 size, UInt32 *data)\r
363 {\r
364     MmType_Param      *payload = (MmType_Param *)data;\r
365     dce_engine_open   *engine_open_msg = (dce_engine_open *)payload[0].data;\r
366     Engine_Handle      eng_handle = NULL;\r
367     Uint32             num_params = MmRpc_NUM_PARAMETERS(size);\r
368 \r
369     DEBUG(">> engine_open");\r
370     if( num_params != 1 ) {\r
371         ERROR("Invalid number of params sent");\r
372         return (-1);\r
373     }\r
374 \r
375     dce_inv(engine_open_msg);\r
376 \r
377         eng_handle = Engine_open(engine_open_msg->name, engine_open_msg->engine_attrs, &engine_open_msg->error_code);\r
378         DEBUG("<< engine=%08x, ec=%d", eng_handle, engine_open_msg->error_code);\r
379 \r
380     dce_clean(engine_open_msg);\r
381 \r
382     return ((Int32)eng_handle);\r
383 }\r
384 \r
385 /*\r
386  * Engine_close:\r
387  */\r
388 static Int32 engine_close(UInt32 size, UInt32 *data)\r
389 {\r
390     MmType_Param    *payload = (MmType_Param *)data;\r
391     Engine_Handle    eng_handle = (Engine_Handle)payload[0].data;\r
392     Uint32           num_params = MmRpc_NUM_PARAMETERS(size);\r
393 \r
394     if( num_params != 1 ) {\r
395         ERROR("invalid number of params sent");\r
396         return (-1);\r
397     }\r
398 \r
399     Engine_close(eng_handle);\r
400     DEBUG("<<");\r
401 \r
402     return (0);\r
403 }\r
404 \r
405 #define INFO_TYPE_CPU_LOAD 0\r
406 #define INFO_TYPE_TOTAL_HEAP_SIZE 1\r
407 #define INFO_TYPE_AVAILABLE_HEAP_SIZE 2\r
408 \r
409 static Int32 get_rproc_info(UInt32 size, UInt32 *data)\r
410 {\r
411     MmType_Param    *payload = (MmType_Param *)data;\r
412     Uint32           info_type = (Uint32)payload[0].data;\r
413     Uint32 output = 0;\r
414     Memory_Stats    stats;\r
415 \r
416     switch(info_type)\r
417     {\r
418             case INFO_TYPE_CPU_LOAD:\r
419                output = Load_getCPULoad();\r
420                 break;\r
421 \r
422             case INFO_TYPE_TOTAL_HEAP_SIZE:\r
423                 Memory_getStats(NULL, &stats);\r
424                 output = stats.totalSize;\r
425                 break;\r
426 \r
427             case INFO_TYPE_AVAILABLE_HEAP_SIZE:\r
428                 Memory_getStats(NULL, &stats);\r
429                 output = stats.totalFreeSize;\r
430                 break;\r
431 \r
432             default:\r
433                 System_printf("\n ERROR: Invalid INFO TYPE chosen \n");\r
434                 break;\r
435     }\r
436 \r
437     return output;\r
438 }\r
439 \r
440 \r
441 /*\r
442   * codec_create\r
443   */\r
444 static Int32 codec_create(UInt32 size, UInt32 *data)\r
445 {\r
446     MmType_Param    *payload = (MmType_Param *)data;\r
447     Uint32           codec_id      = (Uint32)payload[0].data;\r
448     Engine_Handle    engine = (Engine_Handle)payload[1].data;\r
449     char            *codec_name    = (char *)payload[2].data;\r
450     void            *static_params = (void *)payload[3].data;\r
451     Uint32           num_params = MmRpc_NUM_PARAMETERS(size);\r
452     void            *codec_handle;\r
453 \r
454 #ifdef MEMORYSTATS_DEBUG\r
455     Memory_Stats    stats;\r
456 #endif\r
457     DEBUG(">> codec_create");\r
458 \r
459     if( num_params != 4 ) {\r
460         ERROR("invalid number of params sent");\r
461         return (-1);\r
462     }\r
463 \r
464         if(codec_id != OMAP_DCE_VIDDEC2){\r
465         ERROR("invalid codec id sent");\r
466         return (-1);\r
467     }\r
468 \r
469     dce_inv(static_params);\r
470 \r
471     codec_handle = (void *)codec_fxns[codec_id].create(engine, codec_name, static_params);\r
472 \r
473     DEBUG("<< codec_handle=%08x", codec_handle);\r
474 \r
475     dce_clean(static_params);\r
476 \r
477 #ifdef MEMORYSTATS_DEBUG\r
478     Memory_getStats(NULL, &stats);\r
479     INFO("Total: %d\tFree: %d\tLargest: %d", stats.totalSize,\r
480          stats.totalFreeSize, stats.largestFreeSize);\r
481 #endif\r
482     return ((Int32)codec_handle);\r
483 }\r
484 \r
485 /*\r
486   * codec_control\r
487   */\r
488 static int codec_control(UInt32 size, UInt32 *data)\r
489 {\r
490     MmType_Param   *payload = (MmType_Param *)data;\r
491     Uint32          codec_id            = (Uint32)payload[0].data;\r
492     void           *codec_handle = (Engine_Handle)payload[1].data;\r
493     uint32_t        cmd_id              = (Uint32)payload[2].data;\r
494     void           *dyn_params          = (void *)payload[3].data;\r
495     void           *status              = (void *)payload[4].data;\r
496     Uint32          num_params = MmRpc_NUM_PARAMETERS(size);\r
497     Int32           ret = 0;\r
498 \r
499 \r
500     DEBUG(">> codec_control");\r
501 \r
502     if( num_params != 5 ) {\r
503         ERROR("invalid number of params sent");\r
504         return (-1);\r
505     }\r
506 \r
507         if(codec_id != OMAP_DCE_VIDDEC2){\r
508         ERROR("invalid codec id sent");\r
509         return (-1);\r
510     }\r
511 \r
512     dce_inv(dyn_params);\r
513     dce_inv(status);\r
514 \r
515     ret = (uint32_t) codec_fxns[codec_id].control(codec_handle, cmd_id, dyn_params, status);\r
516 \r
517     DEBUG("<< result=%d", ret);\r
518 \r
519     dce_clean(dyn_params);\r
520     dce_clean(status);\r
521 \r
522     return (ret);\r
523 }\r
524 \r
525 /*\r
526   * codec get version\r
527   */\r
528 static int codec_get_version(UInt32 size, UInt32 *data)\r
529 {\r
530     MmType_Param   *payload = (MmType_Param *)data;\r
531     Uint32          codec_id            = (Uint32)payload[0].data;\r
532     void           *codec_handle = (Engine_Handle)payload[1].data;\r
533     void           *dyn_params          = (void *)payload[2].data;\r
534     void           *status              = (void *)payload[3].data;\r
535     Uint32          num_params = MmRpc_NUM_PARAMETERS(size);\r
536     void           *version_buf = NULL;\r
537     Int32           ret = 0;\r
538 \r
539     DEBUG(">> codec_get_version");\r
540 \r
541     if( num_params != 4 ) {\r
542         ERROR("invalid number of params sent");\r
543         return (-1);\r
544     }\r
545 \r
546         if(codec_id != OMAP_DCE_VIDDEC2){\r
547         ERROR("invalid codec id sent");\r
548         return (-1);\r
549     }\r
550 \r
551     version_buf = (void *)(H2P((MemHeader *)((IVIDDEC2_Status *)status)->data.buf));\r
552 \r
553     dce_inv(dyn_params);\r
554     dce_inv(status);\r
555     dce_inv(version_buf);\r
556 \r
557     ret = (uint32_t) codec_fxns[codec_id].control(codec_handle, XDM_GETVERSION, dyn_params, status);\r
558 \r
559     DEBUG("<< result=%d", ret);\r
560 \r
561     dce_clean(dyn_params);\r
562     dce_clean(status);\r
563     dce_clean(version_buf);\r
564 \r
565     return (ret);\r
566 }\r
567 \r
568 /* Notes about serialization of process command:\r
569  *\r
570  * Since codec_process code on kernel side is doing buffer mapping/unmapping,\r
571  * and keeping track of codec's locked buffers, it is necessary for it to\r
572  * look into the contents of some of the parameter structs, and in some cases\r
573  * re-write them.  For this reason inArgs/outBufs/inBufs are serialized within\r
574  * the rpmsg rather than just passed by pointer.\r
575 \r
576 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle handle, XDM1_BufDesc *inBufs,\r
577     XDM_BufDesc *outBufs, VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs);\r
578 \r
579   REQ:\r
580     struct dce_rpc_hdr hdr   -> 4\r
581     codec_id                 -> 4\r
582     codec                    -> 4\r
583     reloc length             -> 1   (length/4)\r
584     inArgs length            -> 1   (length/4)\r
585     outBufs length           -> 1   (length/4)\r
586     inBufs length            -> 1   (length/4)\r
587     VIDDEC3_OutArgs *outArgs -> 4   (pass by pointer)\r
588     reloc table              -> 12 * nreloc (typically <= 16)\r
589     VIDDEC3_InArgs   inArgs  -> 12  (need inputID from userspace)\r
590     XDM_BufDesc     outBufs -> 44  (4 + 2 * 20)\r
591     XDM1_BufDesc     inBufs  -> 24  (4 + 1 * 20)\r
592     -------------------------------\r
593                                99\r
594 \r
595   RSP\r
596     struct dce_rpc_hdr hdr   -> 4\r
597     result                   -> 4\r
598     inBufs length            -> 1   (length/4)\r
599     XDAS_Int32 freeBufID[]   -> 4*n (n typically 0 or 2, but could be up to 20)\r
600     -------------------------------\r
601                                9-89\r
602     Note: freeBufID[] duplicates what is returned in outArgs, but avoids\r
603     needing to create kernel mappings of these objects which are to big\r
604     to copy inline.  Also it avoids differences between VIDDEC3/VIDDENC2.\r
605 \r
606 \r
607 XDAS_Int32 VIDENC2_process(VIDENC2_Handle handle, IVIDEO2_BufDesc *inBufs,\r
608     XDM2_BufDesc *outBufs, IVIDENC2_InArgs *inArgs, IVIDENC2_OutArgs *outArgs);\r
609 \r
610   REQ:\r
611     struct dce_rpc_hdr hdr   -> 4\r
612     codec_id                 -> 4\r
613     codec                    -> 4\r
614     reloc length             -> 1   (length/4)\r
615     inArgs length            -> 1   (length/4)\r
616     outBufs length           -> 1   (length/4)\r
617     inBufs length            -> 1   (length/4)\r
618     VIDENC2_OutArgs *outArgs -> 4   (pass by pointer)\r
619     reloc table              -> ???\r
620     VIDENC2_InArgs   inArgs  -> 12  (need inputID from userspace)\r
621     XDM2_BufDesc     outBufs -> 24  (4 + 1 * 20)\r
622     IVIDEO2_BufDesc  inBufs  -> 252\r
623     -------------------------------\r
624                               307\r
625 \r
626   RSP\r
627     struct dce_rpc_hdr hdr   -> 4\r
628     result                   -> 4\r
629     inBufs length            -> 1   (length/4)\r
630     XDAS_Int32 freeBufID[]   -> 4*n (n typically 0 or 2, but could be up to 20)\r
631     -------------------------------\r
632                                9-89\r
633  */\r
634 \r
635 static int codec_process(UInt32 size, UInt32 *data)\r
636 {\r
637     MmType_Param   *payload = (MmType_Param *)data;\r
638     Uint32          num_params = MmRpc_NUM_PARAMETERS(size);\r
639     Uint32          codec_id = (Uint32) payload[0].data;\r
640     Uint32          codec    = (Uint32) payload[1].data;\r
641     void           *inBufs   = (void *) payload[2].data;\r
642     void           *outBufs  = (void *) payload[3].data;\r
643     void           *inArgs   = (void *) payload[4].data;\r
644     void           *outArgs  = (void *) payload[5].data;\r
645         void           *outBufptr  = (void *)payload[6].data;\r
646     Int32           ret = 0;\r
647     void           *outBufSize = NULL;\r
648 \r
649     DEBUG(">> codec_process");\r
650 \r
651     if( num_params != 7 ) {\r
652         ERROR("invalid number of params sent");\r
653         return (-1);\r
654     }\r
655 \r
656         if(codec_id != OMAP_DCE_VIDDEC2){\r
657         ERROR("invalid codec id sent");\r
658         return (-1);\r
659     }\r
660 \r
661         outBufSize = (void *)(H2P((MemHeader *)((XDM_BufDesc *)outBufs)->bufSizes));\r
662 \r
663     dce_inv(inBufs);\r
664     dce_inv(outBufs);\r
665     dce_inv(inArgs);\r
666     dce_inv(outArgs);\r
667         dce_inv(outBufptr);\r
668     dce_inv(outBufSize);\r
669 \r
670     DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p codec_id=%d",\r
671           codec, inBufs, outBufs, inArgs, outArgs, codec_id);\r
672 \r
673     ret = codec_fxns[codec_id].process((void *)codec, inBufs, outBufs, inArgs, outArgs);\r
674 \r
675 \r
676     DEBUG("<< ret=%d extendedError=%08x", ret, ((VIDDEC3_OutArgs *)outArgs)->extendedError);\r
677 \r
678     dce_clean(inBufs);\r
679     dce_clean(outBufs);\r
680     dce_clean(inArgs);\r
681     dce_clean(outArgs);\r
682         dce_clean(outBufptr);\r
683         dce_clean(outBufSize);\r
684 \r
685     return ((Int32)ret);\r
686 }\r
687 \r
688 /*\r
689   * codec delete\r
690   */\r
691 \r
692 static int codec_delete(UInt32 size, UInt32 *data)\r
693 {\r
694     MmType_Param   *payload = (MmType_Param *)data;\r
695     Uint32          num_params = MmRpc_NUM_PARAMETERS(size);\r
696     Uint32          codec_id = (Uint32) payload[0].data;\r
697     Uint32          codec    = (Uint32) payload[1].data;\r
698 \r
699 #ifdef MEMORYSTATS_DEBUG\r
700     Memory_Stats    stats;\r
701 #endif\r
702 \r
703     DEBUG(">> codec_delete");\r
704 \r
705     if( num_params != 2 ) {\r
706         ERROR("invalid number of params sent");\r
707         return (-1);\r
708     }\r
709 \r
710         if(codec_id != OMAP_DCE_VIDDEC2){\r
711         ERROR("invalid codec id sent");\r
712         return (-1);\r
713     }\r
714 \r
715     codec_fxns[codec_id].delete((void *)codec);\r
716 \r
717 #ifdef MEMORYSTATS_DEBUG\r
718     Memory_getStats(NULL, &stats);\r
719     INFO("Total: %d\tFree: %d\tLargest: %d", stats.totalSize,\r
720          stats.totalFreeSize, stats.largestFreeSize);\r
721 #endif\r
722 \r
723     DEBUG("<<");\r
724 \r
725     return (0);\r
726 }\r
727 \r
728 /* the server create parameters, must be in persistent memory */\r
729 static RcmServer_Params    rpc_Params;\r
730 \r
731 /* DCE Server skel function array */\r
732 static RcmServer_FxnDesc    DCEServerFxnAry[] =\r
733 {\r
734     { "engine_open",       (RcmServer_MsgFxn) engine_open },\r
735     { "engine_close",      (RcmServer_MsgFxn) engine_close },\r
736     { "codec_create",      (RcmServer_MsgFxn) codec_create },\r
737     { "codec_control",     (RcmServer_MsgFxn) codec_control },\r
738     { "codec_get_version", (RcmServer_MsgFxn) codec_get_version },\r
739     { "codec_process",     (RcmServer_MsgFxn) codec_process },\r
740     { "codec_delete",      (RcmServer_MsgFxn) codec_delete },\r
741     { "get_rproc_info",    (RcmServer_MsgFxn) get_rproc_info }\r
742 };\r
743 \r
744 /* DCE Server skel function table */\r
745 #define DCEServerFxnAryLen (sizeof(DCEServerFxnAry) / sizeof(DCEServerFxnAry[0]))\r
746 \r
747 static const RcmServer_FxnDescAry    DCEServer_fxnTab =\r
748 {\r
749     DCEServerFxnAryLen,\r
750     DCEServerFxnAry\r
751 };\r
752 \r
753 static MmType_FxnSig    DCEServer_sigAry[] =\r
754 {\r
755     { "engine_open", 2,\r
756       {\r
757           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
758           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 }\r
759       } },\r
760     { "engine_close", 2,\r
761       {\r
762           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
763           { MmType_Dir_In, MmType_Param_U32, 1 }\r
764 \r
765       } },\r
766     { "codec_create", 5,\r
767       {\r
768           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
769           { MmType_Dir_In, MmType_Param_U32, 1 },\r
770           { MmType_Dir_In, MmType_Param_U32, 1 },\r
771           { MmType_Dir_In, MmType_PtrType(MmType_Param_VOID), 1 },\r
772           { MmType_Dir_In, MmType_PtrType(MmType_Param_VOID), 1 }\r
773       } },\r
774     { "codec_control", 6,\r
775       {\r
776           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
777           { MmType_Dir_In, MmType_Param_U32, 1 },\r
778           { MmType_Dir_In, MmType_Param_U32, 1 },\r
779           { MmType_Dir_In, MmType_Param_U32, 1 },\r
780           { MmType_Dir_In, MmType_PtrType(MmType_Param_VOID), 1 },\r
781           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 }\r
782       } },\r
783     { "codec_get_version", 5,\r
784       {\r
785           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
786           { MmType_Dir_In, MmType_Param_U32, 1 },\r
787           { MmType_Dir_In, MmType_Param_U32, 1 },\r
788           { MmType_Dir_In, MmType_PtrType(MmType_Param_VOID), 1 },\r
789           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 }\r
790       } },\r
791 \r
792      { "codec_process", 8,\r
793       {\r
794           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
795           { MmType_Dir_In, MmType_Param_U32, 1 },\r
796           { MmType_Dir_In, MmType_Param_U32, 1 },\r
797           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 },\r
798           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 },\r
799           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 },\r
800           { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 },\r
801                   { MmType_Dir_Bi, MmType_PtrType(MmType_Param_VOID), 1 }\r
802       } },\r
803 \r
804     { "codec_delete", 3,\r
805       {\r
806           { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
807           { MmType_Dir_In, MmType_Param_U32, 1 },\r
808           { MmType_Dir_In, MmType_Param_U32, 1 }\r
809      } },\r
810     { "get_rproc_info", 2,\r
811       {\r
812          { MmType_Dir_Out, MmType_Param_S32, 1 }, // return\r
813           { MmType_Dir_In, MmType_Param_U32, 1 }\r
814      } }\r
815 };\r
816 \r
817 static MmType_FxnSigTab    dce_fxnSigTab =\r
818 {\r
819     MmType_NumElem(DCEServer_sigAry), DCEServer_sigAry\r
820 };\r
821 \r
822 Void dce_SrvDelNotification(Void)\r
823 {\r
824     DEBUG("dce_SrvDelNotification: Nothing to cleanup\n");\r
825 }\r
826 \r
827 static void dce_main(uint32_t arg0, uint32_t arg1)\r
828 {\r
829     int            err = 0;\r
830     dce_connect    dce_connect_msg;\r
831 \r
832     err = MmServiceMgr_init();  // MmServiceMgr_init() will always return MmServiceMgr_S_SUCCESS.\r
833 \r
834     // setup the RCM Server create params\r
835     RcmServer_Params_init(&rpc_Params);\r
836     rpc_Params.priority = Thread_Priority_ABOVE_NORMAL;\r
837     rpc_Params.stackSize = 0x1000;\r
838     rpc_Params.fxns.length = DCEServer_fxnTab.length;\r
839     rpc_Params.fxns.elem = DCEServer_fxnTab.elem;\r
840 \r
841     // Get the Service Manager handle\r
842     err = MmServiceMgr_register(SERVER_NAME, &rpc_Params, &dce_fxnSigTab, dce_SrvDelNotification);\r
843 \r
844     if( err < 0 ) {\r
845         DEBUG("failed to start " SERVER_NAME " \n");\r
846                 //err = -1;\r
847     } else {\r
848         DEBUG(SERVER_NAME " running through MmServiceMgr");\r
849         }\r
850 \r
851     // Question to IPC team: where is the call to OmapRpc_deleteChannel(handle). The OmapRpc_createChannel is part of MmServiceMgr_register\r
852     // missing the call to OmapRpc_deleteChannel(handle).\r
853     MmServiceMgr_exit();\r
854 \r
855     DEBUG("deleted " SERVER_NAME);\r
856 \r
857     /* Read the register for ID_CODE to figure out the correct configuration: */\r
858     /* CONTROL_STD_FUSE_ID_CODE[31:0] ID_CODE STD_FUSE_IDCODE */\r
859     /* physical address: 0x4A00 2204 Address offset: 0x204                       */\r
860 #ifdef OMAP5430_ES10\r
861     dce_connect_msg.chipset_id = 0x5430;\r
862 #elif OMAP5432_ES20\r
863     dce_connect_msg.chipset_id = 0x5432;\r
864 #elif VAYU_ES10\r
865     dce_connect_msg.chipset_id = 0x5436;\r
866 #endif\r
867     dce_connect_msg.debug = dce_debug;\r
868     connect(&dce_connect_msg);\r
869 \r
870     return;\r
871 }\r
872 \r
873 /*\r
874   * dce init : Startup Function\r
875   */\r
876 Bool dce_init(void)\r
877 {\r
878     Task_Params    params;\r
879 \r
880     INFO("Creating DCE server thread...");\r
881 \r
882 \r
883     /* Create DCE task. */\r
884     Task_Params_init(&params);\r
885     params.instance->name = "dce-server";\r
886     params.priority = Thread_Priority_ABOVE_NORMAL;\r
887         Task_create(dce_main, &params, NULL);\r
888 \r
889     return (TRUE);\r
890 }\r
891 \r
892 /*\r
893   * dce deinit\r
894   */\r
895 \r
896 void dce_deinit(void)\r
897 {\r
898     DEBUG("dce_deinit");\r
899 }\r
900 \r