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