xref: /utopia/UTPA2-700.0.x/modules/vdec_v3/hal/messi/vpu_v3/halVPU_EX.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 
96 //-------------------------------------------------------------------------------------------------
97 //  Include Files
98 //-------------------------------------------------------------------------------------------------
99 // Common Definition
100 #include <string.h>
101 
102 #if defined(REDLION_LINUX_KERNEL_ENVI)
103 #include "drvHVD_Common.h"
104 #else
105 #include "MsCommon.h"
106 #endif
107 
108 #include "MsOS.h"
109 #include "asmCPU.h"
110 #include "drvSYS.h"
111 
112 #if (!defined(MSOS_TYPE_NUTTX) && !defined(MSOS_TYPE_OPTEE)) || defined(SUPPORT_X_MODEL_FEATURE)
113 
114 // Internal Definition
115 #include "regVPU_EX.h"
116 #include "halVPU_EX.h"
117 #include "halCHIP.h"
118 #if defined(VDEC3)
119 #include "../../../drv/hvd_v3/drvHVD_def.h"
120 #include "../hvd_v3/fwHVD_if.h"
121 #include "../mvd_v3/mvd4_interface.h"
122 #include "halHVD_EX.h"
123 #else
124 #include "../../../drv/hvd_v3/drvHVD_def.h"
125 #include "../hvd_v3/fwHVD_if.h"
126 #include "../mvd_v3/mvd4_interface.h"
127 #endif
128 #include "controller.h"
129 
130 #if (ENABLE_DECOMPRESS_FUNCTION == TRUE)
131 #include "ms_decompress.h"
132 #include "ms_decompress_priv.h"
133 #endif
134 #include "../../drv/mbx/apiMBX_St.h"
135 #include "../../drv/mbx/apiMBX.h"
136 
137 #if VPU_ENABLE_BDMA_FW_FLASH_2_SDRAM
138 #include "drvSERFLASH.h"
139 #define HVD_FLASHcpy(DESTADDR, SRCADDR, LEN, Flag)  MDrv_SERFLASH_CopyHnd((MS_PHY)(SRCADDR), (MS_PHY)(DESTADDR), (LEN), (Flag), SPIDMA_OPCFG_DEF)
140 #endif
141 
142 
143 
144 #include "ULog.h"
145 #define VPRINTF(format,args...) ULOGI("VDEC", format, ##args)
146 
147 
148 //-------------------------------------------------------------------------------------------------
149 //  Driver Compiler Options
150 //-------------------------------------------------------------------------------------------------
151 
152 
153 //-------------------------------------------------------------------------------------------------
154 //  Local Defines
155 //-------------------------------------------------------------------------------------------------
156 #define VPU_CTL_INTERFACE_VER   0x00000001  //the interface version of VPU driver
157 
158 #define VPU_MIU1BASE_ADDR    0x40000000UL   //Notice: this define must be comfirm with designer
159 #ifdef VDEC3
160 #define MAX_EVD_BBU_COUNT 2 // This definition is chip-dependent.
161 #define MAX_HVD_BBU_COUNT 2 // The Chip after Monaco(included) have two EVD BBU, must check this definition when bring up
162 #define MAX_MVD_SLQ_COUNT 2
163 #define MAX_SUPPORT_DECODER_NUM 4
164 #else
165 #define MAX_SUPPORT_DECODER_NUM 2
166 #endif
167 typedef enum
168 {
169     E_VDEC_EX_REE_TO_TEE_MBX_MSG_NULL,
170     E_VDEC_EX_REE_TO_TEE_MBX_MSG_FW_LoadCode,
171     E_VDEC_EX_REE_TO_TEE_MBX_MSG_GETSHMBASEADDR,
172 } VDEC_REE_TO_TEE_MBX_MSG_TYPE;
173 
174 
175 typedef enum
176 {
177     E_VDEC_EX_TEE_TO_REE_MBX_MSG_NULL,
178     E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_INVALID,
179     E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_NO_TEE,
180     E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_SUCCESS,
181     E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_FAIL
182 } VDEC_TEE_TO_REE_MBX_ACK_TYPE;
183 
184 typedef enum
185 {
186     E_VPU_UART_CTRL_DISABLE = BIT(4),
187     E_VPU_UART_CTRL_ERR     = BIT(0),
188     E_VPU_UART_CTRL_INFO    = BIT(1),
189     E_VPU_UART_CTRL_DBG     = BIT(2),
190     E_VPU_UART_CTRL_FW      = BIT(3),
191     E_VPU_UART_CTRL_MUST    = BIT(4),
192     E_VPU_UART_CTRL_TRACE   = BIT(5),
193 } VPU_EX_UartCtrl;
194 
195 typedef struct
196 {
197     HAL_VPU_StreamId eStreamId;
198     VPU_EX_DecoderType eDecodertype;
199 } VPU_EX_Stream;
200 
201 
202 #define VPU_MSG_ERR(format, args...)                \
203     do                                              \
204     {                                               \
205         if (u32VpuUartCtrl & E_VPU_UART_CTRL_ERR)  \
206         {                                           \
207             ULOGE("VDEC","[VPU][ERR]%s:", __FUNCTION__);  \
208             ULOGE("VDEC",format, ##args);                 \
209         }                                           \
210     } while (0)
211 
212 #define VPU_MSG_DBG(format, args...)                \
213     do                                              \
214     {                                               \
215         if (u32VpuUartCtrl & E_VPU_UART_CTRL_DBG)  \
216         {                                           \
217             ULOGD("VDEC","[VPU][DBG]%s:", __FUNCTION__);  \
218             ULOGD("VDEC",format, ##args);                 \
219         }                                           \
220     } while (0)
221 
222 #define VPU_MSG_INFO(format, args...)               \
223     do                                              \
224     {                                               \
225         if (u32VpuUartCtrl & E_VPU_UART_CTRL_INFO) \
226         {                                           \
227             ULOGI("VDEC","[VPU][INF]%s:", __FUNCTION__);  \
228             ULOGI("VDEC",format, ##args);                 \
229         }                                           \
230     } while (0)
231 
232 //------------------------------ MIU SETTINGS ----------------------------------
233 #ifdef EVDR2
234 #define _MaskMiuReq_VPU_D_RW(m)     _VPU_WriteRegBit(MIU0_REG_RQ0_MASK, m, BIT(5))
235 #define _MaskMiuReq_VPU_Q_RW(m)     _VPU_WriteRegBit(MIU0_REG_RQ0_MASK, m, BIT(5))
236 #define _MaskMiuReq_VPU_I_R(m)      _VPU_WriteRegBit(MIU0_REG_RQ0_MASK, m, BIT(6))
237 
238 #define _MaskMiu1Req_VPU_D_RW(m)    _VPU_WriteRegBit(MIU1_REG_RQ0_MASK, m, BIT(5))
239 #define _MaskMiu1Req_VPU_Q_RW(m)    _VPU_WriteRegBit(MIU1_REG_RQ0_MASK, m, BIT(5))
240 #define _MaskMiu1Req_VPU_I_R(m)     _VPU_WriteRegBit(MIU1_REG_RQ0_MASK, m, BIT(6))
241 
242 #define VPU_D_RW_ON_MIU0            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == 0)
243 #define VPU_Q_RW_ON_MIU0            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == 0)
244 #define VPU_I_R_ON_MIU0             ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(6)) == 0)
245 #define VPU_D_RW_ON_MIU1            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == BIT(5))
246 #define VPU_Q_RW_ON_MIU1            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == BIT(5))
247 #define VPU_I_R_ON_MIU1             ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(6)) == BIT(6))
248 #else
249 #define _MaskMiuReq_VPU_D_RW(m)     _VPU_WriteRegBit(MIU0_REG_RQ0_MASK, m, BIT(5))
250 #define _MaskMiuReq_VPU_Q_RW(m)     _VPU_WriteRegBit(MIU0_REG_RQ0_MASK, m, BIT(5))
251 #define _MaskMiuReq_VPU_I_R(m)      _VPU_WriteRegBit(MIU0_REG_RQ0_MASK, m, BIT(6))
252 
253 #define _MaskMiu1Req_VPU_D_RW(m)    _VPU_WriteRegBit(MIU1_REG_RQ0_MASK, m, BIT(5))
254 #define _MaskMiu1Req_VPU_Q_RW(m)    _VPU_WriteRegBit(MIU1_REG_RQ0_MASK, m, BIT(5))
255 #define _MaskMiu1Req_VPU_I_R(m)     _VPU_WriteRegBit(MIU1_REG_RQ0_MASK, m, BIT(6))
256 
257 #define VPU_D_RW_ON_MIU0            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == 0)
258 #define VPU_Q_RW_ON_MIU0            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == 0)
259 #define VPU_I_R_ON_MIU0             ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(6)) == 0)
260 #define VPU_D_RW_ON_MIU1            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == BIT(5))
261 #define VPU_Q_RW_ON_MIU1            ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(5)) == BIT(5))
262 #define VPU_I_R_ON_MIU1             ((_VPU_ReadByte(MIU0_REG_SEL0) & BIT(6)) == BIT(6))
263 #endif
264 
265 
266 
267 #define _VPU_MIU_SetReqMask(miu_clients, mask)  \
268     do                                          \
269     {                                           \
270        if (miu_clients##_ON_MIU0 == 1)   \
271        {                                       \
272            _MaskMiuReq_##miu_clients(mask);     \
273        }                                       \
274        else                                     \
275        {                                       \
276            _MaskMiu1Req_##miu_clients(mask);    \
277        }                                       \
278    } while(0)
279 
280 
281 
282 
283 #if ENABLE_VPU_MUTEX_PROTECTION
284 static MS_S32 s32VPUMutexID = -1;
285 MS_U8 _u8VPU_Mutex[] = { "VPU_Mutex" };
286 
287 #define _HAL_VPU_MutexCreate()  \
288     if (s32VPUMutexID < 0)      \
289     {                           \
290         s32VPUMutexID = MsOS_CreateMutex(E_MSOS_FIFO,(char*)_u8VPU_Mutex, MSOS_PROCESS_SHARED); \
291     }
292 
293 #define _HAL_VPU_MutexDelete()              \
294     if (s32VPUMutexID >= 0)                 \
295     {                                       \
296         MsOS_DeleteMutex(s32VPUMutexID);    \
297         s32VPUMutexID = -1;                 \
298     }
299 
300 #define _HAL_VPU_Entry()                                                \
301     if (s32VPUMutexID >= 0)                                             \
302     {                                                                   \
303         if (!MsOS_ObtainMutex(s32VPUMutexID, VPU_DEFAULT_MUTEX_TIMEOUT))       \
304         {                                                               \
305             VPRINTF("[HAL VPU][%06d] Mutex taking timeout\n", __LINE__); \
306         }                                                               \
307     }
308 
309 #define _HAL_VPU_Return(_ret)                   \
310     {                                           \
311         if (s32VPUMutexID >= 0)                 \
312         {                                       \
313             MsOS_ReleaseMutex(s32VPUMutexID);   \
314         }                                       \
315         return _ret;                            \
316     }
317 
318 #define _HAL_VPU_Release()                      \
319     {                                           \
320         if (s32VPUMutexID >= 0)                 \
321         {                                       \
322             MsOS_ReleaseMutex(s32VPUMutexID);   \
323         }                                       \
324     }
325 #else
326 #define _HAL_VPU_MutexCreate()
327 #define _HAL_VPU_MutexDelete()
328 #define _HAL_VPU_Entry()
329 #define _HAL_VPU_Return(_ret)       {return _ret;}
330 #define _HAL_VPU_Release()
331 #endif
332 
333 #define VPU_FW_MEM_OFFSET   0x100000UL  // 1M
334 #define VPU_CMD_TIMEOUT     1000 // 1 sec
335 
336 //-------------------------------------------------------------------------------------------------
337 //  Local Structures
338 //-------------------------------------------------------------------------------------------------
339 typedef struct _VPU_HWInitFunc
340 {
341     MS_BOOL (*pfMVDHW_Init)(void);
342     MS_BOOL (*pfMVDHW_Deinit)(void);
343     MS_BOOL (*pfHVDHW_Init)(MS_U32 u32Arg);
344     MS_BOOL (*pfHVDHW_Deinit)(void);
345 } VPU_HWInitFunc;
346 
347 typedef struct
348 {
349     MS_U32  u32ApiHW_Version;   //<Version of current structure>
350     MS_U16  u16ApiHW_Length;    //<Length of this structure>
351 
352     MS_U8   u8Cap_Support_Decoder_Num;
353 
354     MS_BOOL bCap_Support_MPEG2;
355     MS_BOOL bCap_Support_H263;
356     MS_BOOL bCap_Support_MPEG4;
357     MS_BOOL bCap_Support_DIVX311;
358     MS_BOOL bCap_Support_DIVX412;
359     MS_BOOL bCap_Support_FLV;
360     MS_BOOL bCap_Support_VC1ADV;
361     MS_BOOL bCap_Support_VC1MAIN;
362 
363     MS_BOOL bCap_Support_RV8;
364     MS_BOOL bCap_Support_RV9;
365     MS_BOOL bCap_Support_H264;
366     MS_BOOL bCap_Support_AVS;
367     MS_BOOL bCap_Support_AVS_PLUS;
368     MS_BOOL bCap_Support_MJPEG;
369     MS_BOOL bCap_Support_MVC;
370     MS_BOOL bCap_Support_VP8;
371     MS_BOOL bCap_Support_VP9;
372     MS_BOOL bCap_Support_HEVC;
373 
374     /*New HW Cap and Feature add in struct at the end*/
375 }VDEC_HwCap;
376 
377 //-------------------------------------------------------------------------------------------------
378 //  Local Functions Prototype
379 //-------------------------------------------------------------------------------------------------
380 static MS_BOOL          _VPU_EX_LoadVLCTable(VPU_EX_VLCTblCfg *pVlcCfg, MS_U8 u8FwSrcType);
381 static MS_U8            _VPU_EX_GetOffsetIdx(MS_U32 u32Id);
382 static HVD_User_Cmd     _VPU_EX_MapCtrlCmd(VPU_EX_TaskInfo *pTaskInfo);
383 
384 //-------------------------------------------------------------------------------------------------
385 //  Global Variables
386 //-------------------------------------------------------------------------------------------------
387 extern HVD_Return HAL_HVD_EX_SetCmd(MS_U32 u32Id, HVD_User_Cmd eUsrCmd, MS_U32 u32CmdArg);
388 extern MS_BOOL HAL_MVD_InitHW(void);
389 extern MS_BOOL HAL_MVD_DeinitHW(void);
390 extern MS_BOOL HAL_HVD_EX_InitHW(MS_U32 u32Id,VPU_EX_DecoderType DecoderType);
391 extern MS_BOOL HAL_HVD_EX_DeinitHW(void);
392 extern void    HAL_HVD_EX_SetBufferAddr(MS_U32 u32Id);
393 extern MS_VIRT HAL_HVD_EX_GetShmAddr(MS_U32 u32Id);
394 #if SUPPORT_G2VP9 && defined(VDEC3)
395 extern MS_BOOL HAL_VP9_EX_DeinitHW(void);
396 #endif
397 #if defined (__aeon__)
398 static MS_VIRT u32VPURegOSBase = 0xA0000000UL;
399 #else
400 static MS_VIRT u32VPURegOSBase = 0xBF200000UL;
401 #endif
402 
403 //-------------------------------------------------------------------------------------------------
404 //  Local Variables
405 //-------------------------------------------------------------------------------------------------
406 #if 0
407 
408 static MS_BOOL _bVPUPowered = FALSE;
409 static MS_BOOL _bVPURsted = FALSE;
410 static MS_BOOL _bVPUSingleMode = FALSE;
411 static VPU_EX_DecModCfg _stVPUDecMode;
412 
413 static MS_U8 u8TaskCnt = 0;
414 
415 static MS_U32 u32VpuUartCtrl = (E_VPU_UART_CTRL_ERR | E_VPU_UART_CTRL_MUST);
416 
417 //Notice: this function must be consistent with _VPU_EX_GetOffsetIdx()
418 static VPU_EX_Stream _stVPUStream[] =
419 {
420     {E_HAL_VPU_MAIN_STREAM0, E_VPU_EX_DECODER_NONE},
421     {E_HAL_VPU_SUB_STREAM0, E_VPU_EX_DECODER_NONE},
422 };
423 static VPU_HWInitFunc stHWInitFunc =
424 {
425     &HAL_MVD_InitHW,
426     &HAL_MVD_DeinitHW,
427     &HAL_HVD_EX_InitHW,
428     &HAL_HVD_EX_DeinitHW,
429 };
430 
431 #endif
432 
433 #if VPU_ENABLE_EMBEDDED_FW_BINARY
434 static const MS_U8 u8HVD_FW_Binary[] = {
435     #include "fwVPU.dat"
436 };
437 
438 #if HVD_ENABLE_RV_FEATURE
439 static const MS_U8 u8HVD_VLC_Binary[] = {
440     #include "fwVPU_VLC.dat"
441 };
442 #endif
443 #endif
444 
445 
446 #ifdef VDEC3
447 typedef struct
448 {
449     MS_BOOL bTSP;
450     MS_U32 u32Used;
451 } BBU_STATE;
452 
453 typedef struct
454 {
455     MS_BOOL bTSP;
456     MS_BOOL bUsedbyMVD;
457     MS_U32 u32Used;
458 } SLQ_STATE;
459 #endif
460 
461 typedef struct
462 {
463     MS_BOOL _bVPUPowered;
464     MS_BOOL _bVPURsted;
465     MS_BOOL _bVPUSingleMode;
466     VPU_EX_DecModCfg _stVPUDecMode;
467     MS_U8 u8TaskCnt;
468     //Notice: this function must be consistent with _VPU_EX_GetOffsetIdx()
469 #ifdef VDEC3
470     VPU_EX_Stream _stVPUStream[MAX_SUPPORT_DECODER_NUM];
471 #else
472     VPU_EX_Stream _stVPUStream[2];
473 #endif
474 
475     VPU_HWInitFunc stHWInitFunc;
476 
477     MS_BOOL bVpuExReloadFW;
478     MS_BOOL bVpuExLoadFWRlt;
479     MS_VIRT  u32VPUSHMAddr;    //PA
480     MS_BOOL bEnableVPUSecureMode;
481 
482     MS_VIRT  u32FWShareInfoAddr[MAX_SUPPORT_DECODER_NUM];
483     MS_BOOL bEnableDymanicFBMode;
484     MS_PHY u32DynamicFBAddress;
485     MS_U32 u32DynamicFBSize;
486     #ifdef VDEC3
487     MS_VIRT  u32FWCodeAddr;
488     MS_VIRT  u32BitstreamAddress[MAX_SUPPORT_DECODER_NUM];
489 
490     BBU_STATE stHVD_BBU_STATE[MAX_HVD_BBU_COUNT];
491     BBU_STATE stEVD_BBU_STATE[MAX_EVD_BBU_COUNT];
492     SLQ_STATE stMVD_SLQ_STATE[MAX_MVD_SLQ_COUNT];
493 
494     MS_U8 u8HALId[MAX_SUPPORT_DECODER_NUM];
495     #endif
496 } VPU_Hal_CTX;
497 
498 //global variables
499 VPU_Hal_CTX* pVPUHalContext = NULL;
500 VPU_Hal_CTX gVPUHalContext;
501 MS_U32 u32VpuUartCtrl = (E_VPU_UART_CTRL_ERR | E_VPU_UART_CTRL_MUST);
502 MS_BOOL bVPUMbxInitFlag = 0;
503 MS_U8 u8VPUMbxMsgClass = 0;
504 MBX_Msg VPUReeToTeeMbxMsg;
505 MBX_Msg VPUTeeToReeMbxMsg;
506 
507 //-------------------------------------------------------------------------------------------------
508 //  Debug Functions
509 //-------------------------------------------------------------------------------------------------
510 
511 
512 //-------------------------------------------------------------------------------------------------
513 //  Local Functions
514 //-------------------------------------------------------------------------------------------------
515 
_VPU_EX_LoadVLCTable(VPU_EX_VLCTblCfg * pVlcCfg,MS_U8 u8FwSrcType)516 static MS_BOOL _VPU_EX_LoadVLCTable(VPU_EX_VLCTblCfg *pVlcCfg, MS_U8 u8FwSrcType)
517 {
518 #if HVD_ENABLE_RV_FEATURE
519     if (E_HVD_FW_INPUT_SOURCE_FLASH == u8FwSrcType)
520     {
521 #if VPU_ENABLE_BDMA_FW_FLASH_2_SDRAM
522         VPU_MSG_DBG("Load VLC outF2D: dest:0x%lx source:%lx size:%lx\n",
523             pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize);
524 
525         if (pVlcCfg->u32BinSize)
526         {
527             SPIDMA_Dev cpyflag = E_SPIDMA_DEV_MIU1;
528 
529             MS_U32 u32Start;
530             MS_U32 u32StartOffset;
531             MS_U8  u8MiuSel;
532 
533             // Get MIU selection and offset from physical address = 0x30000000
534             _phy_to_miu_offset(u8MiuSel, u32StartOffset, pVlcCfg->u32FrameBufAddr);
535 
536 
537             if(u8MiuSel == E_CHIP_MIU_0)
538                 cpyflag = E_SPIDMA_DEV_MIU0;
539             else if(u8MiuSel == E_CHIP_MIU_1)
540                 cpyflag = E_SPIDMA_DEV_MIU1;
541             else if(u8MiuSel == E_CHIP_MIU_2)
542                 cpyflag = E_SPIDMA_DEV_MIU2;
543 
544             if (!HVD_FLASHcpy(MsOS_VA2PA(pVlcCfg->u32DstAddr), MsOS_VA2PA(pVlcCfg->u32BinAddr), pVlcCfg->u32BinSize, cpyflag))
545             {
546                 VPU_MSG_ERR("HVD_BDMAcpy VLC table Flash 2 DRAM failed: dest:0x%lx src:0x%lx size:0x%lx flag:%lu\n",
547                      pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize, (MS_U32) cpyflag);
548 
549                 return FALSE;
550             }
551         }
552         else
553         {
554             VPU_MSG_ERR("During copy VLC from Flash to Dram, the source size of FW is zero\n");
555             return FALSE;
556         }
557 #else
558         VPU_MSG_ERR("driver not enable to use BDMA copy VLC from flash 2 sdram.\n");
559         return FALSE;
560 #endif
561     }
562     else
563     {
564         if (E_HVD_FW_INPUT_SOURCE_DRAM == u8FwSrcType)
565         {
566             if ((pVlcCfg->u32BinAddr != 0) && (pVlcCfg->u32BinSize != 0))
567             {
568                 VPU_MSG_INFO("Load VLC outD2D: dest:0x%lx source:%lx size:%lx\n",
569                             (unsigned long)pVlcCfg->u32DstAddr, (unsigned long)pVlcCfg->u32BinAddr, (unsigned long)pVlcCfg->u32BinSize);
570 
571 #if HVD_ENABLE_BDMA_2_BITSTREAMBUF
572                 BDMA_Result bdmaRlt;
573                 MS_VIRT u32DstAdd = 0, u32SrcAdd = 0, u32tabsize = 0;
574 
575                 u32DstAdd   = pVlcCfg->u32FrameBufAddr + pVlcCfg->u32VLCTableOffset;
576                 u32SrcAdd   = pVlcCfg->u32BinAddr;
577                 u32tabsize  = pVlcCfg->u32BinSize;
578                 //bdmaRlt = MDrv_BDMA_MemCopy(u32SrcAdd, u32DstAdd, SLQ_TBL_SIZE);
579                 MsOS_FlushMemory();
580                 bdmaRlt = HVD_dmacpy(u32DstAdd, u32SrcAdd, u32tabsize);
581 
582                 if (E_BDMA_OK != bdmaRlt)
583                 {
584                     VPU_MSG_ERR("MDrv_BDMA_MemCopy fail in %s(), ret=%x!\n", __FUNCTION__, bdmaRlt);
585                 }
586 #else
587                 HVD_memcpy(pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize);
588 #endif
589             }
590             else
591             {
592                 VPU_MSG_ERR
593                     ("During copy VLC from out Dram to Dram, the source size or virtual address of VLC is zero\n");
594                 return FALSE;
595             }
596         }
597         else
598         {
599 #if VPU_ENABLE_EMBEDDED_FW_BINARY
600 #ifdef HVD_CACHE_TO_UNCACHE_CONVERT
601             MS_U8 *pu8HVD_VLC_Binary;
602 
603             pu8HVD_VLC_Binary = (MS_U8 *) ((MS_U32) u8HVD_VLC_Binary | 0xA0000000);
604 
605             VPU_MSG_DBG("Load VLC inD2D: dest:0x%lx source:%lx size:%lx\n",
606                         pVlcCfg->u32FrameBufAddr + pVlcCfg->u32VLCTableOffset, ((MS_U32) pu8HVD_VLC_Binary),
607                         (MS_U32) sizeof(u8HVD_VLC_Binary));
608 
609             HVD_memcpy((void *) (pVlcCfg->u32FrameBufAddr + pVlcCfg->u32VLCTableOffset),
610                        (void *) ((MS_U32) pu8HVD_VLC_Binary), sizeof(u8HVD_VLC_Binary));
611 #else
612             VPU_MSG_INFO("Load VLC inD2D: dest:0x%lx source:%lx size:%x\n",
613                         (unsigned long)MsOS_VA2PA(pVlcCfg->u32DstAddr), (unsigned long)u8HVD_VLC_Binary,
614                         (MS_U32) sizeof(u8HVD_VLC_Binary));
615 
616             HVD_memcpy(pVlcCfg->u32DstAddr, ((unsigned long)u8HVD_VLC_Binary), sizeof(u8HVD_VLC_Binary));
617 #endif
618 #else
619             VPU_MSG_ERR("driver not enable to use embedded VLC binary.\n");
620             return FALSE;
621 #endif
622         }
623     }
624 #endif
625 
626     return TRUE;
627 }
628 
629 //Notice: this function must be consistent with _stVPUStream[]
_VPU_EX_GetOffsetIdx(MS_U32 u32Id)630 static MS_U8 _VPU_EX_GetOffsetIdx(MS_U32 u32Id)
631 {
632     MS_U8 u8OffsetIdx = 0;
633     MS_U8 u8VSidBaseMask = 0xF0;
634     HAL_VPU_StreamId eVSidBase = (HAL_VPU_StreamId)(u32Id & u8VSidBaseMask);
635 
636     switch (eVSidBase)
637     {
638         case E_HAL_VPU_MAIN_STREAM_BASE:
639         {
640             u8OffsetIdx = 0;
641             break;
642         }
643         case E_HAL_VPU_SUB_STREAM_BASE:
644         {
645             u8OffsetIdx = 1;
646             break;
647         }
648         case E_HAL_VPU_MVC_STREAM_BASE:
649         {
650             u8OffsetIdx = 0;
651             break;
652         }
653 #ifdef VDEC3
654         case E_HAL_VPU_N_STREAM_BASE:
655         {
656             u8OffsetIdx = u32Id & 0x0F;
657             break;
658         }
659 #endif
660         default:
661         {
662             u8OffsetIdx = 0;
663             break;
664         }
665     }
666 
667     /*
668     VPU_MSG_DBG("u32Id=0x%lx, eVSidBase=0x%x, u8OffsetIdx=0x%x\n",
669         u32Id, eVSidBase, u8OffsetIdx);
670         */
671     return u8OffsetIdx;
672 }
673 
_VPU_EX_Context_Init(void)674 static void _VPU_EX_Context_Init(void)
675 {
676 #ifdef VDEC3
677     MS_U8 i;
678 
679     for (i = 0; i < MAX_SUPPORT_DECODER_NUM; i++)
680     {
681         pVPUHalContext->_stVPUStream[i].eStreamId = E_HAL_VPU_N_STREAM0 + i;
682         pVPUHalContext->u32FWShareInfoAddr[i] = 0xFFFFFFFFUL;
683     }
684 
685     for (i = 0; i < MAX_HVD_BBU_COUNT; i++)
686     {
687         pVPUHalContext->stHVD_BBU_STATE[i].bTSP = FALSE;
688         pVPUHalContext->stHVD_BBU_STATE[i].u32Used = 0;
689     }
690 
691     for (i = 0; i < MAX_EVD_BBU_COUNT; i++)
692     {
693         pVPUHalContext->stEVD_BBU_STATE[i].bTSP = FALSE;
694         pVPUHalContext->stEVD_BBU_STATE[i].u32Used = 0;
695     }
696 
697     for (i = 0; i < MAX_MVD_SLQ_COUNT; i++)
698     {
699         pVPUHalContext->stMVD_SLQ_STATE[i].bTSP = FALSE;
700         pVPUHalContext->stMVD_SLQ_STATE[i].bUsedbyMVD= FALSE;
701         pVPUHalContext->stMVD_SLQ_STATE[i].u32Used = 0;
702     }
703 #else
704     pVPUHalContext->_stVPUStream[0].eStreamId = E_HAL_VPU_MAIN_STREAM0;
705     pVPUHalContext->_stVPUStream[1].eStreamId = E_HAL_VPU_SUB_STREAM0;
706 #endif
707     pVPUHalContext->bVpuExReloadFW = TRUE;
708 }
709 
_VPU_EX_MapCtrlCmd(VPU_EX_TaskInfo * pTaskInfo)710 static HVD_User_Cmd _VPU_EX_MapCtrlCmd(VPU_EX_TaskInfo *pTaskInfo)
711 {
712     HVD_User_Cmd eCmd = E_HVD_CMD_INVALID_CMD;
713     MS_U8 u8OffsetIdx = 0;
714 
715     if (NULL == pTaskInfo)
716     {
717         return eCmd;
718     }
719 
720     u8OffsetIdx = _VPU_EX_GetOffsetIdx(pTaskInfo->u32Id);
721 
722     VPU_MSG_INFO("input TaskInfo u32Id=0x%08x eVpuId=0x%x src=0x%x dec=0x%x\n",
723          pTaskInfo->u32Id, pTaskInfo->eVpuId, pTaskInfo->eSrcType, pTaskInfo->eDecType);
724 
725 #ifdef VDEC3
726     if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
727     {
728         if (E_VPU_EX_INPUT_TSP == pTaskInfo->eSrcType)
729         {
730             eCmd = E_NST_CMD_TASK_MVD_TSP;
731         }
732         else if (E_VPU_EX_INPUT_FILE == pTaskInfo->eSrcType)
733         {
734             eCmd = E_NST_CMD_TASK_MVD_SLQ;
735         }
736     }
737 #else
738     if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
739     {
740         if (E_VPU_EX_INPUT_TSP == pTaskInfo->eSrcType)
741         {
742             eCmd = (u8OffsetIdx == 0) ? E_DUAL_CMD_TASK0_MVD_TSP : E_DUAL_CMD_TASK1_MVD_TSP;
743         }
744         else if (E_VPU_EX_INPUT_FILE == pTaskInfo->eSrcType)
745         {
746             eCmd = (u8OffsetIdx == 0) ? E_DUAL_CMD_TASK0_MVD_SLQ : E_DUAL_CMD_TASK1_MVD_SLQ;
747         }
748     }
749 #endif
750 #ifdef VDEC3
751   #if SUPPORT_G2VP9
752     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
753   #else
754     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
755   #endif
756     {
757         if (E_VPU_EX_INPUT_TSP == pTaskInfo->eSrcType)
758         {
759             eCmd = E_NST_CMD_TASK_HVD_TSP;
760         }
761         else if (E_VPU_EX_INPUT_FILE == pTaskInfo->eSrcType)
762         {
763             eCmd = E_NST_CMD_TASK_HVD_BBU;
764         }
765     }
766 #else
767     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
768     {
769         if (E_VPU_EX_INPUT_TSP == pTaskInfo->eSrcType)
770         {
771             eCmd = (u8OffsetIdx == 0) ? E_DUAL_CMD_TASK0_HVD_TSP : E_DUAL_CMD_TASK1_HVD_TSP;
772         }
773         else if (E_VPU_EX_INPUT_FILE == pTaskInfo->eSrcType)
774         {
775             eCmd = (u8OffsetIdx == 0) ? E_DUAL_CMD_TASK0_HVD_BBU : E_DUAL_CMD_TASK1_HVD_BBU;
776         }
777     }
778 #endif
779 
780     VPU_MSG_INFO("output: eCmd=0x%x offsetIdx=0x%x\n", eCmd, u8OffsetIdx);
781     return eCmd;
782 }
783 
_VPU_EX_InitHW(VPU_EX_TaskInfo * pTaskInfo)784 static MS_BOOL _VPU_EX_InitHW(VPU_EX_TaskInfo *pTaskInfo)
785 {
786     if (!pTaskInfo)
787     {
788         VPU_MSG_ERR("null input\n");
789         return FALSE;
790     }
791 
792     //Check if we need to init MVD HW
793     if ((E_VPU_EX_INPUT_TSP == pTaskInfo->eSrcType) ||
794         (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType))
795     {
796         //Init HW
797         if (FALSE == HAL_VPU_EX_MVDInUsed())
798         {
799             if (TRUE != HAL_MVD_InitHW())
800             {
801                 VPU_MSG_ERR("(%d):HAL_MVD_InitHW failed\n", __LINE__);
802                 return FALSE;
803             }
804         }
805         else
806         {
807             VPU_MSG_ERR("(%d): do nothing\n", __LINE__);
808         }
809     }
810 
811     //MVD use sub mvop
812     if((E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType) &&
813 #ifdef VDEC3
814         (pTaskInfo->u8HalId == 1) )
815 #else
816         (E_HAL_VPU_SUB_STREAM0 == pTaskInfo->eVpuId))
817 #endif
818     {
819         VPU_MSG_ERR("Force turn on HVD\n");
820         if(!HAL_VPU_EX_HVDInUsed())
821         {
822             if(E_VPU_DEC_MODE_DUAL_INDIE == pVPUHalContext->_stVPUDecMode.u8DecMod)
823             {
824                 if (!HAL_HVD_EX_InitHW(pTaskInfo->u32Id,pTaskInfo->eDecType))
825                 {
826                      VPU_MSG_ERR("(%d):HAL_HVD_EX_InitHW failed\n", __LINE__);
827                      return FALSE;
828                 }
829             }
830             else
831             {
832                 VPU_MSG_INFO("%s  MVD 3DTV sub\n",__FUNCTION__);
833                 HAL_HVD_EX_PowerCtrl(TRUE);
834             }
835         }
836         else
837         {
838             VPU_MSG_ERR("(%d): do nothing, HVD already init\n", __LINE__);
839         }
840     }
841 
842     //Check if we need to init HVD HW
843 #ifdef VDEC3
844     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
845 #else
846     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
847 #endif
848     {
849         if (!HAL_VPU_EX_MVDInUsed())
850         {
851             if (!HAL_MVD_InitHW())
852             {
853                 VPU_MSG_ERR("(%d):HAL_MVD_InitHW failed\n", __LINE__);
854                 return FALSE;
855             }
856         }
857 
858         if (!HAL_HVD_EX_InitHW(pTaskInfo->u32Id,pTaskInfo->eDecType))
859         {
860             VPU_MSG_ERR("(%d):HAL_HVD_EX_InitHW failed\n", __LINE__);
861             return FALSE;
862         }
863     }
864 
865     #if SUPPORT_G2VP9 && defined(VDEC3)
866     if (E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
867     {
868         if (!HAL_VPU_EX_MVDInUsed())
869         {
870             if (!HAL_MVD_InitHW())
871             {
872                 VPU_MSG_ERR("(%d):HAL_MVD_InitHW failed\n", __LINE__);
873                 return FALSE;
874             }
875         }
876         if (!HAL_HVD_EX_InitHW(pTaskInfo->u32Id,pTaskInfo->eDecType))
877         {
878             VPU_MSG_ERR("(%d):HAL_HVD_EX_InitHW failed for VP9\n", __LINE__);
879             return FALSE;
880         }
881     }
882     #endif
883 
884     return TRUE;
885 }
886 
_VPU_EX_InClock(MS_U32 u32type)887 static MS_U32 _VPU_EX_InClock(MS_U32 u32type)
888 {
889     switch (u32type)
890     {
891         case VPU_CLOCK_240MHZ:
892             return 240000000UL;
893         case VPU_CLOCK_216MHZ:
894             return 216000000UL;
895         case VPU_CLOCK_192MHZ:
896             return 192000000UL;
897         case VPU_CLOCK_12MHZ:
898             return 12000000UL;
899         case VPU_CLOCK_320MHZ:
900             return 320000000UL;
901         case VPU_CLOCK_288MHZ:
902             return 288000000UL;
903         case VPU_CLOCK_432MHZ:
904             return 432000000UL;
905         case VPU_CLOCK_384MHZ:
906             return 384000000UL;
907         default:
908             return 432000000UL;
909     }
910 }
911 
912 
913 #if defined(MSOS_TYPE_LINUX)
914 //For REE
HAL_VPU_EX_REE_RegisterMBX(void)915 MS_BOOL HAL_VPU_EX_REE_RegisterMBX(void)
916 {
917     MS_U8 ClassNum = 0;
918     MBX_Result result;
919 
920     if (bVPUMbxInitFlag == TRUE)
921     {
922         return TRUE;
923     }
924 
925     if (E_MBX_SUCCESS != MApi_MBX_Init(E_MBX_CPU_MIPS,E_MBX_ROLE_HK,1000))
926     {
927         VPU_MSG_ERR("VDEC_TEE MApi_MBX_Init fail\n");
928         return FALSE;
929     }
930     else
931     {
932         MApi_MBX_Enable(TRUE);
933     }
934 
935     result = MApi_MBX_QueryDynamicClass(E_MBX_CPU_MIPS_VPE1, "VDEC_TEE", (MS_U8 *)&ClassNum);
936 
937     if (E_MBX_SUCCESS != result)
938     {
939         VPU_MSG_ERR("VDEC_TEE MApi_MBX_QueryDynamicClass fail,result %d\n",(unsigned int)result);
940         return FALSE;
941     }
942 
943     result = MApi_MBX_RegisterMSG(ClassNum, 10);
944 
945     if (( E_MBX_SUCCESS != result) && ( E_MBX_ERR_SLOT_AREADY_OPENNED != result ))
946     {
947         VPU_MSG_ERR("%s fail\n",__FUNCTION__);
948         return FALSE;
949     }
950     else
951     {
952         bVPUMbxInitFlag = TRUE;
953         u8VPUMbxMsgClass = ClassNum;
954         return TRUE;
955     }
956 }
_VPU_EX_REE_SendMBXMsg(VDEC_REE_TO_TEE_MBX_MSG_TYPE msg_type)957 VDEC_TEE_TO_REE_MBX_ACK_TYPE _VPU_EX_REE_SendMBXMsg(VDEC_REE_TO_TEE_MBX_MSG_TYPE msg_type)
958 {
959     MBX_Result result;
960     MS_U8 u8Index;
961 
962     if (pVPUHalContext->bEnableVPUSecureMode == FALSE)
963     {
964         return E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_NO_TEE;
965     }
966 
967     if (bVPUMbxInitFlag == FALSE)
968     {
969         return E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_INVALID;
970     }
971 
972     VPUReeToTeeMbxMsg.eRoleID = E_MBX_CPU_MIPS_VPE1;
973     VPUReeToTeeMbxMsg.u8Ctrl = 0;
974     VPUReeToTeeMbxMsg.eMsgType = E_MBX_MSG_TYPE_INSTANT;
975     VPUReeToTeeMbxMsg.u8MsgClass = u8VPUMbxMsgClass;
976     VPUReeToTeeMbxMsg.u8Index = msg_type;
977 
978     result = MApi_MBX_SendMsg(&VPUReeToTeeMbxMsg);
979     if (E_MBX_SUCCESS != result)
980     {
981         printf("VDEC_TEE Send MBX fail,result %d\n",(unsigned int)result);
982         return E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_FAIL;
983     }
984 
985     // Receive Reply ACK from TEE side.
986     memset(&VPUTeeToReeMbxMsg, 0, sizeof(MBX_Msg));
987 
988     VPUTeeToReeMbxMsg.u8MsgClass = u8VPUMbxMsgClass;
989 
990 #if 0 // marked temperarily, wait kernel team to fix MApi_MBX_RecvMsg.
991     if(E_MBX_SUCCESS != MApi_MBX_RecvMsg(TEE_MBX_MSG_CLASS, &(TEE_TO_REE_MBX_MSG), 20, MBX_CHECK_INSTANT_MSG))
992     {
993         VPU_MSG_ERR("VDEC get Secure world ACK fail\n");
994         return E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_FAIL;
995     }
996     else
997 #else
998     do
999     {
1000         result = MApi_MBX_RecvMsg(u8VPUMbxMsgClass, &VPUTeeToReeMbxMsg, 2000, MBX_CHECK_INSTANT_MSG);
1001     } while(E_MBX_SUCCESS != result);
1002 #endif
1003     {
1004         u8Index = VPUTeeToReeMbxMsg.u8Index;
1005         VPU_MSG_DBG("VDEC get ACK cmd:%x\n", u8Index);
1006 
1007         if (E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_FAIL == u8Index)
1008         {
1009             return E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_FAIL;
1010         }
1011     }
1012 
1013     return E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_SUCCESS;
1014 }
1015 
HAL_VPU_EX_REE_SetSHMBaseAddr(MS_U32 U32Type,MS_PHY u32SHMAddr,MS_PHY u32SHMSize,MS_PHY u32MIU1Addr)1016 MS_BOOL HAL_VPU_EX_REE_SetSHMBaseAddr(MS_U32 U32Type,MS_PHY u32SHMAddr,MS_PHY u32SHMSize,MS_PHY u32MIU1Addr)
1017 {
1018     if(U32Type == SYS_TEEINFO_OSTYPE_NUTTX)
1019     {
1020         if(_VPU_EX_REE_SendMBXMsg(E_VDEC_EX_REE_TO_TEE_MBX_MSG_GETSHMBASEADDR) != E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_SUCCESS)
1021         {
1022             VPU_MSG_ERR("[Error] VDEC load code in Secure world fail!\n");
1023             return FALSE;
1024         }
1025         else
1026         {
1027             MS_VIRT u32VPUSHMoffset = (VPUTeeToReeMbxMsg.u8Parameters[0]&0xff) |
1028                                      ((VPUTeeToReeMbxMsg.u8Parameters[1]<<8)&0xff00)|
1029                                      ((VPUTeeToReeMbxMsg.u8Parameters[2]<<16)&0xff0000)|
1030                                      ((VPUTeeToReeMbxMsg.u8Parameters[3]<<24)&0xff000000);
1031             MS_U32 u32VPUSHMsize =   (VPUTeeToReeMbxMsg.u8Parameters[4]&0xff) |
1032                                      ((VPUTeeToReeMbxMsg.u8Parameters[5]<<8)&0xff00)|
1033                                      ((VPUTeeToReeMbxMsg.u8Parameters[6]<<16)&0xff0000)|
1034                                      ((VPUTeeToReeMbxMsg.u8Parameters[7]<<24)&0xff000000);
1035 
1036             VPU_MSG_INFO("u32VPUSHMoffset %lx,u32VPUSHMsize %x,miu %d\n",(unsigned long)u32VPUSHMoffset,(unsigned int)u32VPUSHMsize,VPUTeeToReeMbxMsg.u8Parameters[8]);
1037 
1038 
1039             MS_U32 u32Start;
1040 
1041             if(VPUTeeToReeMbxMsg.u8Parameters[8] == 1)
1042             {
1043                 _miu_offset_to_phy(E_CHIP_MIU_1, u32VPUSHMoffset, u32Start);
1044                 pVPUHalContext->u32VPUSHMAddr =  u32Start;
1045             }
1046             else if(VPUTeeToReeMbxMsg.u8Parameters[8] == 2)
1047             {
1048                 _miu_offset_to_phy(E_CHIP_MIU_2, u32VPUSHMoffset, u32Start);
1049                 pVPUHalContext->u32VPUSHMAddr =  u32Start;
1050 
1051             }
1052             else // == 0
1053             {
1054                 pVPUHalContext->u32VPUSHMAddr = u32VPUSHMoffset;
1055             }
1056         }
1057     }
1058     else if(U32Type == SYS_TEEINFO_OSTYPE_OPTEE)
1059     {
1060         MS_U32 u32Offset;
1061         if((u32SHMAddr >= u32MIU1Addr) && (u32MIU1Addr!=0))
1062         {
1063             u32Offset = u32SHMAddr-u32MIU1Addr;
1064             _miu_offset_to_phy(E_CHIP_MIU_1, u32Offset, pVPUHalContext->u32VPUSHMAddr);
1065         }
1066         else
1067         {
1068             pVPUHalContext->u32VPUSHMAddr = u32SHMAddr;
1069         }
1070     }
1071 
1072     return true;
1073 }
1074 #endif
1075 
HAL_VPU_EX_GetFWReload(void)1076 MS_BOOL HAL_VPU_EX_GetFWReload(void)
1077 {
1078     return pVPUHalContext->bVpuExReloadFW;
1079 }
1080 
_VPU_EX_IsNeedDecompress(MS_VIRT u32SrcAddr)1081 static MS_BOOL _VPU_EX_IsNeedDecompress(MS_VIRT u32SrcAddr)
1082 {
1083     if(*((MS_U8*)(u32SrcAddr))=='V' && *((MS_U8*)(u32SrcAddr+1))=='D'
1084         && *((MS_U8*)(u32SrcAddr+2))=='E' && *((MS_U8*)(u32SrcAddr+3))=='C'
1085         && *((MS_U8*)(u32SrcAddr+4))=='3' && *((MS_U8*)(u32SrcAddr+5))=='0'
1086         && *((MS_U8*)(u32SrcAddr+0x88))=='V' && *((MS_U8*)(u32SrcAddr+0x89))=='D'
1087         && *((MS_U8*)(u32SrcAddr+0x8a))=='E' && *((MS_U8*)(u32SrcAddr+0x8b))=='C'
1088         && *((MS_U8*)(u32SrcAddr+0x8c))=='3' && *((MS_U8*)(u32SrcAddr+0x8d))=='0'
1089         )
1090     {
1091         return FALSE;
1092     }
1093     else
1094     {
1095         return TRUE;
1096     }
1097 }
1098 
_VPU_EX_InitAll(VPU_EX_NDecInitPara * pInitPara)1099 static MS_BOOL _VPU_EX_InitAll(VPU_EX_NDecInitPara *pInitPara)
1100 {
1101     MS_PHY u32fwPA = NULL;  //physical address
1102     VPU_EX_ClockSpeed eClkSpeed = E_VPU_EX_CLOCK_432MHZ;
1103 
1104     if (TRUE == HAL_VPU_EX_IsPowered())
1105     {
1106         VPU_MSG_DBG("IsPowered\n");
1107         return TRUE;
1108     }
1109     else
1110     {
1111         //VPU hold
1112         HAL_VPU_EX_SwRst(FALSE);
1113 
1114         //VPU clock on
1115         VPU_EX_InitParam VPUInitParams = {eClkSpeed, FALSE, -1, VPU_DEFAULT_MUTEX_TIMEOUT, TRUE};
1116 
1117         if (VPU_I_R_ON_MIU0)
1118             VPUInitParams.u8MiuSel = 0;
1119         else
1120             VPUInitParams.u8MiuSel = 1;
1121 
1122         HAL_VPU_EX_Init(&VPUInitParams);
1123     }
1124 
1125     VPU_EX_FWCodeCfg *pFWCodeCfg   = NULL;
1126     VPU_EX_TaskInfo  *pTaskInfo    = NULL;
1127     VPU_EX_VLCTblCfg *pVlcCfg      = NULL;
1128 
1129     if (pInitPara)
1130     {
1131         pFWCodeCfg  = pInitPara->pFWCodeCfg;
1132         pTaskInfo   = pInitPara->pTaskInfo;
1133         pVlcCfg     = pInitPara->pVLCCfg;
1134     }
1135     else
1136     {
1137         VPU_MSG_DBG("(%d) NULL para\n", __LINE__);
1138         return FALSE;
1139     }
1140 
1141     u32fwPA = MsOS_VA2PA(pFWCodeCfg->u32DstAddr);
1142 #if defined(MSOS_TYPE_LINUX)
1143     if(pVPUHalContext->bEnableVPUSecureMode == TRUE)
1144     {
1145         SYS_TEEINFO teemode;
1146         MDrv_SYS_ReadKernelCmdLine();
1147         MDrv_SYS_GetTEEInfo(&teemode);
1148 
1149         if(teemode.OsType == SYS_TEEINFO_OSTYPE_NUTTX)
1150         {
1151             VPU_MSG_INFO("Load VDEC f/w code in Secure World\n");
1152 
1153             if (FALSE == HAL_VPU_EX_GetFWReload())
1154             {
1155                 if (FALSE == pVPUHalContext->bVpuExLoadFWRlt)
1156                 {
1157                     VPU_MSG_INFO("Never load fw successfully, load it anyway!\n");
1158                     if(_VPU_EX_REE_SendMBXMsg(E_VDEC_EX_REE_TO_TEE_MBX_MSG_FW_LoadCode) != E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_SUCCESS)
1159                     {
1160                         VPU_MSG_ERR("[Error] VDEC load code in Secure world fail!\n");
1161                         return FALSE;
1162                     }
1163                     pVPUHalContext->bVpuExLoadFWRlt = TRUE;
1164                 }
1165                 else
1166                 {
1167                     //Check f/w prefix "VDEC30"
1168                     if (_VPU_EX_IsNeedDecompress(pFWCodeCfg->u32DstAddr) != FALSE)
1169                     {
1170                         VPU_MSG_ERR("Wrong prefix: reload fw!\n");
1171                         if(_VPU_EX_REE_SendMBXMsg(E_VDEC_EX_REE_TO_TEE_MBX_MSG_FW_LoadCode) != E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_SUCCESS)
1172                         {
1173                             VPU_MSG_ERR("[Error] VDEC load code in Secure world fail!\n");
1174                             pVPUHalContext->bVpuExLoadFWRlt = FALSE;
1175                             return FALSE;
1176                         }
1177                     }
1178                     else
1179                     {
1180                         VPU_MSG_INFO("Skip loading fw this time!!!\n");
1181                     }
1182                 }
1183             }
1184             else
1185             {
1186                 if(_VPU_EX_REE_SendMBXMsg(E_VDEC_EX_REE_TO_TEE_MBX_MSG_FW_LoadCode) != E_VDEC_EX_TEE_TO_REE_MBX_ACK_MSG_ACTION_SUCCESS)
1187                 {
1188                     VPU_MSG_ERR("[Error] VDEC load code in Secure world fail!\n");
1189                     pVPUHalContext->bVpuExLoadFWRlt = FALSE;
1190                     return FALSE;
1191                 }
1192                 pVPUHalContext->bVpuExLoadFWRlt = TRUE;
1193             }
1194         }
1195     }
1196     else
1197 #endif
1198     {
1199         VPU_MSG_INFO("Load VDEC f/w code in Normal World\n");
1200 
1201         if (!HAL_VPU_EX_LoadCode(pFWCodeCfg))
1202         {
1203             VPU_MSG_ERR("HAL_VPU_EX_LoadCode fail!\n");
1204             return FALSE;
1205         }
1206     }
1207 
1208     if (pVlcCfg)
1209     {
1210         if (!_VPU_EX_LoadVLCTable(pVlcCfg, pFWCodeCfg->u8SrcType))
1211         {
1212             VPU_MSG_ERR("HAL_VPU_LoadVLCTable fail!\n");
1213             return FALSE;
1214         }
1215     }
1216 
1217     if (!HAL_VPU_EX_CPUSetting(u32fwPA))
1218     {
1219         VPU_MSG_ERR("HAL_VPU_EX_CPUSetting fail!\n");
1220         return FALSE;
1221     }
1222 
1223     //Init HW
1224     if (FALSE == _VPU_EX_InitHW(pTaskInfo))
1225     {
1226         VPU_MSG_ERR("(%d): InitHW failed\n", __LINE__);
1227         //_MVD_INIT_FAIL_RET();
1228         return FALSE;
1229     }
1230     else
1231     {
1232         VPU_MSG_DBG("(%d): InitHW success\n", __LINE__);
1233     }
1234 
1235     //set vpu clock to FW
1236     struct _ctl_info *ctl_ptr = (struct _ctl_info *)
1237                     MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + CTL_INFO_ADDR);
1238 
1239     ctl_ptr->statue = CTL_STU_NONE;
1240     //notify controller the interface version of VPU driver.
1241     ctl_ptr->ctl_interface = VPU_CTL_INTERFACE_VER;
1242     ctl_ptr->vpu_clk = _VPU_EX_InClock(eClkSpeed);
1243     MsOS_FlushMemory();
1244     VPU_MSG_DBG("clock speed=0x%x\n", ctl_ptr->vpu_clk);
1245 
1246     //Release VPU: For dual decoder, we only release VPU if it is not released yet.
1247     if (TRUE == HAL_VPU_EX_IsRsted())
1248     {
1249         VPU_MSG_DBG("VPU_IsRsted\n");
1250         return TRUE;
1251     }
1252     else
1253     {
1254         HAL_VPU_EX_SwRstRelse();
1255     }
1256 
1257     return TRUE;
1258 }
1259 
_VPU_EX_DeinitHW(void)1260 static MS_BOOL _VPU_EX_DeinitHW(void)
1261 {
1262     MS_BOOL bRet = FALSE;
1263 
1264     if (FALSE == HAL_VPU_EX_MVDInUsed())
1265     {
1266         bRet = HAL_MVD_DeinitHW();
1267     }
1268 
1269     if (FALSE == HAL_VPU_EX_HVDInUsed())
1270     {
1271         bRet = HAL_HVD_EX_DeinitHW();
1272     }
1273 #if SUPPORT_G2VP9 && defined(VDEC3)
1274     if (FALSE == HAL_VPU_EX_G2VP9InUsed())
1275     {
1276         bRet = HAL_VP9_EX_DeinitHW();
1277     }
1278 #endif
1279     return bRet;
1280 }
1281 
_VPU_EX_DeinitAll(void)1282 static MS_BOOL _VPU_EX_DeinitAll(void)
1283 {
1284     HAL_VPU_EX_SwRst(TRUE);
1285     _VPU_EX_DeinitHW();
1286     HAL_VPU_EX_DeInit();
1287 
1288     return TRUE;
1289 }
1290 
_VPU_EX_GetActiveCodecCnt(void)1291 static MS_U8 _VPU_EX_GetActiveCodecCnt(void)
1292 {
1293     MS_U32 i;
1294     MS_U8  u8ActiveCnt = 0;
1295     for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
1296     {
1297         if (E_VPU_EX_DECODER_NONE != pVPUHalContext->_stVPUStream[i].eDecodertype &&
1298             E_VPU_EX_DECODER_GET != pVPUHalContext->_stVPUStream[i].eDecodertype &&
1299             E_VPU_EX_DECODER_GET_MVC != pVPUHalContext->_stVPUStream[i].eDecodertype)
1300         {
1301             u8ActiveCnt++;
1302         }
1303     }
1304     if (pVPUHalContext->u8TaskCnt != u8ActiveCnt)
1305     {
1306         VPU_MSG_ERR("Err u8TaskCnt(%d) != u8ActiveCnt(%d)\n", pVPUHalContext->u8TaskCnt, u8ActiveCnt);
1307     }
1308     VPU_MSG_DBG(" = %d\n", u8ActiveCnt);
1309     return u8ActiveCnt;
1310 }
_VPU_EX_ClockInv(MS_BOOL bEnable)1311 static void _VPU_EX_ClockInv(MS_BOOL bEnable)
1312 {
1313     if (TRUE)
1314     {
1315         _VPU_WriteWordMask(REG_TOP_VPU, 0, TOP_CKG_VPU_INV);
1316     }
1317     else
1318     {
1319         _VPU_WriteWordMask(REG_TOP_VPU, TOP_CKG_VPU_INV, TOP_CKG_VPU_INV);
1320     }
1321 }
1322 
_VPU_EX_ClockSpeed(MS_U32 u32type)1323 static void _VPU_EX_ClockSpeed(MS_U32 u32type)
1324 {
1325     switch (u32type)
1326     {
1327         case VPU_CLOCK_240MHZ:
1328         case VPU_CLOCK_216MHZ:
1329         case VPU_CLOCK_192MHZ:
1330         case VPU_CLOCK_12MHZ:
1331         case VPU_CLOCK_320MHZ:
1332         case VPU_CLOCK_288MHZ:
1333         case VPU_CLOCK_384MHZ:
1334         case VPU_CLOCK_432MHZ:
1335             _VPU_WriteWordMask(REG_TOP_VPU, u32type, TOP_CKG_VPU_CLK_MASK);
1336             break;
1337         default:
1338             _VPU_WriteWordMask(REG_TOP_VPU, VPU_CLOCK_384MHZ, TOP_CKG_VPU_CLK_MASK);
1339             break;
1340     }
1341 }
1342 #ifdef HAL_FEATURE_MAU
_VPU_EX_MAU_IDLE(void)1343 static MS_BOOL _VPU_EX_MAU_IDLE(void)
1344 {
1345     if (((_VPU_Read2Byte(MAU1_ARB0_DBG0) & MAU1_FSM_CS_MASK) == MAU1_FSM_CS_IDLE)
1346         && ((_VPU_Read2Byte(MAU1_ARB1_DBG0) & MAU1_FSM_CS_MASK) == MAU1_FSM_CS_IDLE))
1347     {
1348         return TRUE;
1349     }
1350     return FALSE;
1351 }
1352 #endif
1353 
1354 
1355 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
_VPU_EX_DecompressBin(MS_VIRT u32SrcAddr,MS_U32 u32SrcSize,MS_VIRT u32DestAddr,MS_VIRT u32SlidingAddr)1356 static MS_BOOL _VPU_EX_DecompressBin(MS_VIRT u32SrcAddr, MS_U32 u32SrcSize, MS_VIRT u32DestAddr, MS_VIRT u32SlidingAddr)
1357 {
1358     if(_VPU_EX_IsNeedDecompress(u32SrcAddr))
1359     {
1360         ms_VDECDecompressInit((MS_U8*)u32SlidingAddr, (MS_U8*)u32DestAddr);
1361         ms_VDECDecompress((MS_U8*)u32SrcAddr, u32SrcSize);
1362         ms_VDECDecompressDeInit();
1363         return TRUE;
1364     }
1365     else
1366     {
1367         return FALSE;
1368     }
1369 }
1370 #endif
1371 
HAL_VPU_EX_SetSingleDecodeMode(MS_BOOL bEnable)1372 MS_BOOL HAL_VPU_EX_SetSingleDecodeMode(MS_BOOL bEnable)
1373 {
1374     MS_BOOL bRet = TRUE;
1375     pVPUHalContext->_bVPUSingleMode = bEnable;
1376     return bRet;
1377 }
1378 
HAL_VPU_EX_SetDecodeMode(VPU_EX_DecModCfg * pstCfg)1379 MS_BOOL HAL_VPU_EX_SetDecodeMode(VPU_EX_DecModCfg *pstCfg)
1380 {
1381     MS_BOOL bRet = TRUE;
1382     MS_U8 i=0;
1383     if (pstCfg != NULL)
1384     {
1385         pVPUHalContext->_stVPUDecMode.u8DecMod = pstCfg->u8DecMod;
1386         pVPUHalContext->_stVPUDecMode.u8CodecCnt = pstCfg->u8CodecCnt;
1387         for (i=0; ((i<pstCfg->u8CodecCnt)&&(i<VPU_MAX_DEC_NUM)); i++)
1388         {
1389             pVPUHalContext->_stVPUDecMode.u8CodecType[i] = pstCfg->u8CodecType[i];
1390         }
1391         pVPUHalContext->_stVPUDecMode.u8ArgSize = pstCfg->u8ArgSize;
1392         pVPUHalContext->_stVPUDecMode.u32Arg    = pstCfg->u32Arg;
1393     }
1394     else
1395     {
1396         bRet = FALSE;
1397     }
1398     return bRet;
1399 }
1400 
1401 //static MS_BOOL bVpuExReloadFW = TRUE;
1402 //static MS_BOOL bVpuExLoadFWRlt = FALSE;
HAL_VPU_EX_SetFWReload(MS_BOOL bReload)1403 MS_BOOL HAL_VPU_EX_SetFWReload(MS_BOOL bReload)
1404 {
1405     pVPUHalContext->bVpuExReloadFW = bReload;
1406     //printf("%s bVpuExReloadFW = %x\n", __FUNCTION__, bVpuExReloadFW);
1407     return TRUE;
1408 }
1409 
1410 
1411 //-------------------------------------------------------------------------------------------------
1412 //  Global Functions
1413 //-------------------------------------------------------------------------------------------------
1414 #ifdef VDEC3_FB
HAL_VPU_EX_LoadVLCTable(VPU_EX_VLCTblCfg * pVlcCfg,MS_U8 u8FwSrcType)1415 MS_BOOL HAL_VPU_EX_LoadVLCTable(VPU_EX_VLCTblCfg *pVlcCfg, MS_U8 u8FwSrcType)
1416 {
1417 #if HVD_ENABLE_RV_FEATURE
1418     if (E_HVD_FW_INPUT_SOURCE_FLASH == u8FwSrcType)
1419     {
1420 #if VPU_ENABLE_BDMA_FW_FLASH_2_SDRAM
1421         VPU_MSG_DBG("Load VLC outF2D: dest:0x%lx source:%lx size:%lx\n",
1422             pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize);
1423 
1424         if (pVlcCfg->u32BinSize)
1425         {
1426             SPIDMA_Dev cpyflag = E_SPIDMA_DEV_MIU1;
1427 
1428             if (HAL_MIU1_BASE <= MsOS_VA2PA(pVlcCfg->u32DstAddr))
1429             {
1430                 cpyflag = E_SPIDMA_DEV_MIU1;
1431             }
1432             else
1433             {
1434                 cpyflag = E_SPIDMA_DEV_MIU0;
1435             }
1436 
1437             if (!HVD_FLASHcpy(MsOS_VA2PA(pVlcCfg->u32DstAddr), MsOS_VA2PA(pVlcCfg->u32BinAddr), pVlcCfg->u32BinSize, cpyflag))
1438             {
1439                 VPU_MSG_ERR("HVD_BDMAcpy VLC table Flash 2 DRAM failed: dest:0x%lx src:0x%lx size:0x%lx flag:%lu\n",
1440                      pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize, (MS_U32) cpyflag);
1441 
1442                 return FALSE;
1443             }
1444         }
1445         else
1446         {
1447             VPU_MSG_ERR("During copy VLC from Flash to Dram, the source size of FW is zero\n");
1448             return FALSE;
1449         }
1450 #else
1451         VPU_MSG_ERR("driver not enable to use BDMA copy VLC from flash 2 sdram.\n");
1452         return FALSE;
1453 #endif
1454     }
1455     else
1456     {
1457         if (E_HVD_FW_INPUT_SOURCE_DRAM == u8FwSrcType)
1458         {
1459             if ((pVlcCfg->u32BinAddr != 0) && (pVlcCfg->u32BinSize != 0))
1460             {
1461                 VPU_MSG_INFO("Load VLC outD2D: dest:0x%lx source:%lx size:%lx\n",
1462                             (unsigned long)pVlcCfg->u32DstAddr, (unsigned long)pVlcCfg->u32BinAddr, (unsigned long)pVlcCfg->u32BinSize);
1463 
1464 #if HVD_ENABLE_BDMA_2_BITSTREAMBUF
1465                 BDMA_Result bdmaRlt;
1466 
1467                 MsOS_FlushMemory();
1468                 bdmaRlt = HVD_dmacpy(pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize);
1469 
1470                 if (E_BDMA_OK != bdmaRlt)
1471                 {
1472                     VPU_MSG_ERR("MDrv_BDMA_MemCopy fail in %s(), ret=%x!\n", __FUNCTION__, bdmaRlt);
1473                 }
1474 #else
1475                 HVD_memcpy(pVlcCfg->u32DstAddr, pVlcCfg->u32BinAddr, pVlcCfg->u32BinSize);
1476 #endif
1477             }
1478             else
1479             {
1480                 VPU_MSG_ERR
1481                     ("During copy VLC from out Dram to Dram, the source size or virtual address of VLC is zero\n");
1482                 return FALSE;
1483             }
1484         }
1485         else
1486         {
1487 #if VPU_ENABLE_EMBEDDED_FW_BINARY
1488 #ifdef HVD_CACHE_TO_UNCACHE_CONVERT
1489             MS_U8 *pu8HVD_VLC_Binary;
1490 
1491             pu8HVD_VLC_Binary = (MS_U8 *) ((MS_U32) u8HVD_VLC_Binary | 0xA0000000);
1492 
1493             VPU_MSG_DBG("Load VLC inD2D: dest:0x%lx source:%lx size:%lx\n",
1494                         (unsigned long)pVlcCfg->u32DstAddr, (unsigned long) pu8HVD_VLC_Binary),
1495                         (MS_U32) sizeof(u8HVD_VLC_Binary));
1496 
1497             HVD_memcpy((void *) (pVlcCfg->u32DstAddr),
1498                        (void *) ((MS_U32) pu8HVD_VLC_Binary), sizeof(u8HVD_VLC_Binary));
1499 #else
1500             VPU_MSG_INFO("Load VLC inD2D: dest:0x%lx source:%lx size:%x\n",
1501                         (unsigned long)MsOS_VA2PA(pVlcCfg->u32DstAddr), (unsigned long) u8HVD_VLC_Binary,
1502                         (MS_U32) sizeof(u8HVD_VLC_Binary));
1503 
1504             HVD_memcpy(pVlcCfg->u32DstAddr, ((MS_VIRT) u8HVD_VLC_Binary), sizeof(u8HVD_VLC_Binary));
1505 #endif
1506 #else
1507             VPU_MSG_ERR("driver not enable to use embedded VLC binary.\n");
1508             return FALSE;
1509 #endif
1510         }
1511     }
1512 #endif
1513 
1514     return TRUE;
1515 }
1516 #endif
1517 #ifdef VDEC3
HAL_VPU_EX_TaskCreate(MS_U32 u32Id,VPU_EX_NDecInitPara * pInitPara,MS_BOOL bFWdecideFB,MS_U32 u32BBUId)1518 MS_BOOL HAL_VPU_EX_TaskCreate(MS_U32 u32Id, VPU_EX_NDecInitPara *pInitPara, MS_BOOL bFWdecideFB, MS_U32 u32BBUId)
1519 #else
1520 MS_BOOL HAL_VPU_EX_TaskCreate(MS_U32 u32Id, VPU_EX_NDecInitPara *pInitPara)
1521 #endif
1522 {
1523     VPU_EX_TaskInfo *pTaskInfo  = pInitPara->pTaskInfo;
1524     MS_U8 u8Offset              = _VPU_EX_GetOffsetIdx(u32Id);
1525     HVD_User_Cmd eCmd           = E_HVD_CMD_INVALID_CMD;
1526     VPU_EX_DecoderType eDecType = E_VPU_EX_DECODER_NONE;
1527     MS_U32 u32Arg = 0xFFFFFFFF;
1528     MS_U32 u32Timeout = 0;
1529     HVD_Return eCtrlRet = E_HVD_RETURN_FAIL;
1530     MS_U32 u32CmdArg = 0;
1531     struct _ctl_info *ctl_ptr = (struct _ctl_info *)
1532                     MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + CTL_INFO_ADDR);
1533 
1534     _HAL_VPU_Entry();
1535     //Check FW buffer size
1536     if (1 == u8Offset)
1537     {
1538         MS_VIRT u32MinFWBuffSize = (u8Offset + 1) * VPU_FW_MEM_OFFSET;
1539         MS_VIRT u32CurFWBuffSize = pInitPara->pFWCodeCfg->u32DstSize;
1540 
1541         if (u32CurFWBuffSize < u32MinFWBuffSize)
1542         {
1543             VPU_MSG_ERR("FW BuffSize(0x%lx < 0x%lx) is too small!\n", (unsigned long)u32CurFWBuffSize, (unsigned long)u32MinFWBuffSize);
1544             _HAL_VPU_Release();
1545             return FALSE;
1546         }
1547     }
1548 
1549     if(( E_HAL_VPU_MVC_STREAM_BASE == (0xFF & u32Id))
1550 	    &&(E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[0].eDecodertype)
1551 	    &&(E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[1].eDecodertype))
1552     {
1553         pVPUHalContext->_stVPUStream[0].eStreamId = E_HAL_VPU_MVC_MAIN_VIEW;
1554     }
1555     #ifdef VDEC3
1556     pVPUHalContext->u32FWCodeAddr = MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr);
1557     #endif
1558 
1559     if (0 == pVPUHalContext->u8TaskCnt)
1560     {
1561         //No task is created, need to load f/w, etc.
1562         VPU_MSG_DBG("u8TaskCnt=%d\n", pVPUHalContext->u8TaskCnt);
1563 
1564         if (!_VPU_EX_InitAll(pInitPara))
1565         {
1566             VPU_MSG_DBG("(%d) fail to InitAll\n", __LINE__);
1567             _HAL_VPU_Release();
1568             return FALSE;
1569         }
1570 
1571         //Check if controller finish initialization: clear mailbox, etc.
1572         //Need to check it before sending any controller commands!
1573         u32Timeout = HVD_GetSysTime_ms() + VPU_CMD_TIMEOUT;
1574         while (CTL_STU_NONE == ctl_ptr->statue)
1575         {
1576             if (HVD_GetSysTime_ms() > u32Timeout)
1577             {
1578                 VPU_MSG_ERR("Ctl init timeout, st=%x\n", ctl_ptr->statue);
1579                 VPU_MSG_ERR("version=0x%x, statue=0x%x, last_ctl_cmd=0x%x, last_ctl_arg=0x%x, t0=%d, t1=%d\n",
1580                      ctl_ptr->verion, ctl_ptr->statue, ctl_ptr->last_ctl_cmd, ctl_ptr->last_ctl_arg, ctl_ptr->task_statue[0], ctl_ptr->task_statue[1]);
1581                 MS_U32 t=0;
1582                 for (t=0; t<30; t++)
1583                 {
1584                     VPU_MSG_DBG("_pc=0x%x\n", HAL_VPU_EX_GetProgCnt());
1585                 }
1586                 _HAL_VPU_Release();
1587                 return FALSE;
1588             }
1589 
1590             MsOS_ReadMemory();
1591         }
1592 
1593         VPU_MSG_INFO("ctl_init_done: version=0x%x, statue=0x%x, last_ctl_cmd=0x%x, last_ctl_arg=0x%x, t0=%d, t1=%d\n",
1594              ctl_ptr->verion, ctl_ptr->statue, ctl_ptr->last_ctl_cmd, ctl_ptr->last_ctl_arg, ctl_ptr->task_statue[0], ctl_ptr->task_statue[1]);
1595 
1596     }
1597     else
1598     {
1599         if (pVPUHalContext->_bVPUSingleMode)
1600         {
1601             //Show error message
1602             VPU_MSG_INFO("VDEC warn: this task will use dram instead of sram!!!\n");
1603         }
1604 
1605         if (!_VPU_EX_InitHW(pInitPara->pTaskInfo))
1606         {
1607             VPU_MSG_DBG("(%d) fail to InitHW\n", __LINE__);
1608             _HAL_VPU_Release();
1609             return FALSE;
1610         }
1611         if (pInitPara->pVLCCfg)
1612         {
1613             if (!_VPU_EX_LoadVLCTable(pInitPara->pVLCCfg, pInitPara->pFWCodeCfg->u8SrcType))
1614             {
1615                 VPU_MSG_ERR("HAL_VPU_LoadVLCTable fail!\n");
1616                 _HAL_VPU_Release();
1617                 return FALSE;
1618             }
1619         }
1620     }
1621 
1622 
1623     #ifdef VDEC3
1624     if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
1625     {
1626             VDEC_VBBU *pTemp4 = (VDEC_VBBU *)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + VBBU_TABLE_START + u8Offset*0x100000);
1627 
1628             memset(pTemp4,0,sizeof(VDEC_VBBU));
1629 
1630             *((unsigned int*)(pTemp4->u8Reserved)) = MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr)-HAL_MIU1_BASE;
1631 
1632             DISPQ_IN_DRAM *pTemp = (DISPQ_IN_DRAM *)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + DISP_QUEUE + u8Offset*0x100000);
1633 
1634             memset(pTemp,0,sizeof(DISPQ_IN_DRAM));
1635 
1636             CMD_QUEUE *pTemp2 = (CMD_QUEUE *)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + VCOMMANDQ_INFO + u8Offset*0x100000);
1637 
1638             memset(pTemp2,0,sizeof(CMD_QUEUE));
1639 
1640             pTemp2->u32HVD_DISPCMDQ_DRAM_ST_ADDR = VDISP_COMMANDQ + u8Offset*0x100000;
1641 
1642             pTemp2->u32HVD_CMDQ_DRAM_ST_ADDR = VNORMAL_COMMANDQ + u8Offset*0x100000;
1643 
1644             unsigned char* pTemp3 = (unsigned char*)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + VDISP_COMMANDQ + u8Offset*0x100000);
1645 
1646             memset(pTemp3,0,0x2000);
1647 
1648             unsigned int* pVersion = (unsigned int*)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + OFFSET_BASE + u8Offset*0x100000);
1649 
1650             memset((void*)pVersion,0,0x8);
1651 
1652             *pVersion = 1; //0:diu, 1:wb
1653     }
1654 
1655     #endif
1656 
1657     #if 1  // For TEE
1658 #ifdef VDEC3
1659   #if SUPPORT_G2VP9
1660     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType ||
1661         E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
1662   #else
1663     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1664   #endif
1665 #else
1666     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
1667 #endif
1668     {
1669         MS_VIRT u32FWPhyAddr = MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr);
1670 
1671         if (pVPUHalContext->u32FWShareInfoAddr[u8Offset] == 0xFFFFFFFFUL)
1672         {
1673             ctl_ptr->u32TaskShareInfoAddr[u8Offset] = 0xFFFFFFFFUL;
1674         }
1675         else
1676         {
1677             ctl_ptr->u32TaskShareInfoAddr[u8Offset] = pVPUHalContext->u32FWShareInfoAddr[u8Offset] - u32FWPhyAddr;
1678         }
1679 
1680         MsOS_FlushMemory();
1681         VPU_MSG_DBG("task share info offset = 0x%x\n", ctl_ptr->u32TaskShareInfoAddr[u8Offset]);
1682 
1683         ///printf("DRV side,      share info offset = 0x%lx\n", pVPUHalContext->u32FWShareInfoAddr[u8Offset]);
1684         ///printf("FW side,  task share info offset = 0x%x\n", ctl_ptr->u32TaskShareInfoAddr[u8Offset]);
1685     }
1686     #endif
1687 
1688     if ((pVPUHalContext->bEnableDymanicFBMode == TRUE) && (pVPUHalContext->u8TaskCnt == 0))
1689     {
1690         ctl_ptr->FB_ADDRESS = pVPUHalContext->u32DynamicFBAddress;
1691         ctl_ptr->FB_Total_SIZE = pVPUHalContext->u32DynamicFBSize;
1692 
1693         HAL_HVD_EX_SetCmd(u32Id, E_DUAL_CMD_COMMON, 0);
1694 
1695         MsOS_FlushMemory();
1696     }
1697 
1698     if ((TRUE==pVPUHalContext->_bVPUSingleMode) || (E_VPU_DEC_MODE_SINGLE==pVPUHalContext->_stVPUDecMode.u8DecMod))
1699     {
1700         //Issue E_DUAL_CMD_SINGLE_TASK to FW controller
1701         //arg=1 to get better performance for single task
1702         u32CmdArg = (pVPUHalContext->_bVPUSingleMode) ? 1 : 0;
1703         VPU_MSG_DBG("Issue E_DUAL_CMD_SINGLE_TASK to FW controller arg=%x\n", u32CmdArg);
1704         eCtrlRet = HAL_HVD_EX_SetCmd(u32Id, E_DUAL_CMD_SINGLE_TASK, u32CmdArg);
1705         if (E_HVD_RETURN_SUCCESS != eCtrlRet)
1706         {
1707             VPU_MSG_ERR("E_DUAL_CMD_SINGLE_TASK NG eCtrlRet=%x\n", eCtrlRet);
1708         }
1709     }
1710     else if (E_VPU_DEC_MODE_DUAL_3D==pVPUHalContext->_stVPUDecMode.u8DecMod)
1711     {
1712         if(pVPUHalContext->_stVPUDecMode.u8CodecType[0] != pVPUHalContext->_stVPUDecMode.u8CodecType[1])
1713         {
1714             switch (pVPUHalContext->_stVPUDecMode.u32Arg)
1715             {
1716                 case E_VPU_CMD_MODE_KR3D_INTERLACE:
1717                     u32CmdArg = CTL_MODE_3DTV;
1718                     break;
1719                 case E_VPU_CMD_MODE_KR3D_FORCE_P:
1720                     u32CmdArg = CTL_MODE_3DTV_PROG;
1721                     break;
1722                 case E_VPU_CMD_MODE_KR3D_INTERLACE_TWO_PITCH:
1723                     u32CmdArg = CTL_MODE_3DTV_TWO_PITCH;
1724                     break;
1725                 case E_VPU_CMD_MODE_KR3D_FORCE_P_TWO_PITCH:
1726                     u32CmdArg = CTL_MODE_3DTV_PROG_TWO_PITCH;
1727                     break;
1728                 default:
1729                     u32CmdArg = CTL_MODE_3DTV;
1730                     VPU_MSG_INFO("%x not defined, use CTL_MODE_3DTV for KR3D\n", pVPUHalContext->_stVPUDecMode.u32Arg);
1731                     break;
1732             }
1733         }
1734         else
1735         {
1736             u32CmdArg = CTL_MODE_3DWMV;
1737         }
1738         VPU_MSG_DBG("Issue E_DUAL_CMD_MODE to FW controller arg=%x\n", u32CmdArg);
1739         eCtrlRet = HAL_HVD_EX_SetCmd(u32Id, E_DUAL_CMD_MODE, u32CmdArg);
1740         if (E_HVD_RETURN_SUCCESS != eCtrlRet)
1741         {
1742             VPU_MSG_ERR("E_DUAL_CMD_MODE NG eCtrlRet=%x\n", eCtrlRet);
1743         }
1744     }
1745     else if(E_VPU_DEC_MODE_DUAL_INDIE == pVPUHalContext->_stVPUDecMode.u8DecMod)
1746     {
1747         if(E_VPU_CMD_MODE_PIP_SYNC_MAIN_STC == pVPUHalContext->_stVPUDecMode.u32Arg)
1748         {
1749             u32CmdArg = CTL_MODE_ONE_STC;
1750         }
1751         else
1752         {
1753             u32CmdArg = (pVPUHalContext->_stVPUDecMode.u32Arg==E_VPU_CMD_MODE_PIP_SYNC_SWITCH) ? CTL_MODE_SWITCH_STC : CTL_MODE_NORMAL;
1754         }
1755         VPU_MSG_DBG("Issue E_DUAL_CMD_MODE to FW controller arg=%x\n", u32CmdArg);
1756         eCtrlRet = HAL_HVD_EX_SetCmd(u32Id, E_DUAL_CMD_MODE, u32CmdArg);
1757         if (E_HVD_RETURN_SUCCESS != eCtrlRet)
1758         {
1759             VPU_MSG_ERR("E_DUAL_CMD_MODE NG eCtrlRet=%x\n", eCtrlRet);
1760         }
1761     }
1762     // Set heap size for current task
1763     ctl_ptr->heap_size[u8Offset] = pInitPara->pTaskInfo->u32HeapSize;
1764     MsOS_FlushMemory();
1765 
1766     eCmd = _VPU_EX_MapCtrlCmd(pTaskInfo);
1767 #if defined(SUPPORT_NEW_MEM_LAYOUT)
1768     if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
1769 #ifdef VDEC3
1770     {
1771         u32Arg = (u32BBUId << VDEC_BBU_ID_SHIFT) + u8Offset * VPU_FW_MEM_OFFSET + OFFSET_BASE;
1772     }
1773 #else
1774         u32Arg = u8Offset * VPU_FW_MEM_OFFSET + OFFSET_BASE;
1775 #endif
1776 
1777 #ifdef VDEC3
1778     #if SUPPORT_G2VP9
1779     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
1780     #else
1781     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1782     #endif
1783     {
1784         u32Arg = (u32BBUId << VDEC_BBU_ID_SHIFT) + (u8Offset * VPU_FW_MEM_OFFSET) + HVD_SHARE_MEM_ST_OFFSET;
1785     }
1786 #else
1787     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
1788         u32Arg = u8Offset * VPU_FW_MEM_OFFSET + HVD_SHARE_MEM_ST_OFFSET;
1789 #endif
1790     else
1791     {
1792         VPU_MSG_ERR("Can't find eDecType! %d\n", pTaskInfo->eDecType);
1793         _HAL_VPU_Release();
1794         return FALSE;
1795     }
1796 #else
1797     u32Arg = u8Offset * VPU_FW_MEM_OFFSET;
1798 #endif
1799     HAL_HVD_EX_SetCmd(u32Id, eCmd, u32Arg);
1800 
1801     MsOS_ReadMemory();
1802     VPU_MSG_INFO("before: version=0x%x, statue=0x%x, last_ctl_cmd=0x%x, last_ctl_arg=0x%x, t0=%d, t1=%d\n",
1803          ctl_ptr->verion, ctl_ptr->statue, ctl_ptr->last_ctl_cmd, ctl_ptr->last_ctl_arg, ctl_ptr->task_statue[0], ctl_ptr->task_statue[1]);
1804 
1805     u32Timeout = HVD_GetSysTime_ms() + VPU_CMD_TIMEOUT;
1806     while (CTL_TASK_CMDRDY != ctl_ptr->task_statue[u8Offset])
1807     {
1808         if (HVD_GetSysTime_ms() > u32Timeout)
1809         {
1810             VPU_MSG_ERR("Task %d creation timeout\n", u8Offset);
1811             MS_U32 t=0;
1812             for (t=0; t<30; t++)
1813             {
1814                 VPU_MSG_DBG("_pc=0x%x\n", HAL_VPU_EX_GetProgCnt());
1815             }
1816 //#ifndef VDEC3 // FIXME: workaround fw response time is slow sometimes in multiple stream case so far
1817             pVPUHalContext->bVpuExLoadFWRlt = FALSE; ///error handling
1818             VPU_MSG_ERR("set bVpuExLoadFWRlt as FALSE\n\n");
1819             _HAL_VPU_Release();
1820             return FALSE;
1821 //#endif
1822         }
1823 
1824         MsOS_ReadMemory();
1825     }
1826 
1827     VPU_MSG_INFO("after: version=0x%x, statue=0x%x, last_ctl_cmd=0x%x, last_ctl_arg=0x%x, t0=%d, t1=%d\n",
1828          ctl_ptr->verion, ctl_ptr->statue, ctl_ptr->last_ctl_cmd, ctl_ptr->last_ctl_arg, ctl_ptr->task_statue[0], ctl_ptr->task_statue[1]);
1829 
1830 #ifdef VDEC3
1831     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1832 #else
1833     if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
1834 #endif
1835     {
1836         HAL_HVD_EX_SetBufferAddr(u32Id);
1837     }
1838 
1839     if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
1840     {
1841         eDecType = E_VPU_EX_DECODER_MVD;
1842     }
1843     else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
1844     {
1845         eDecType = E_VPU_EX_DECODER_HVD;
1846     }
1847 #ifdef VDEC3
1848     else if (E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1849     {
1850         eDecType = E_VPU_EX_DECODER_EVD;
1851     }
1852     #if SUPPORT_G2VP9
1853     else if (E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
1854     {
1855         eDecType = E_VPU_EX_DECODER_G2VP9;
1856     }
1857     #endif
1858 #endif
1859     else
1860     {
1861         VPU_MSG_ERR("Can't find eDecType! %d\n", pTaskInfo->eDecType);
1862         _HAL_VPU_Release();
1863         return FALSE;
1864     }
1865 
1866 #ifdef VDEC3
1867     if ((bFWdecideFB == TRUE) && (pVPUHalContext->u8TaskCnt == 0))
1868     {
1869         HAL_HVD_EX_SetCmd(u32Id, E_DUAL_R2_CMD_FBADDR, pInitPara->pFBCfg->u32FrameBufAddr);
1870         HAL_HVD_EX_SetCmd(u32Id, E_DUAL_R2_CMD_FBSIZE, pInitPara->pFBCfg->u32FrameBufSize);
1871     }
1872 #endif
1873 
1874     if (pTaskInfo->eDecType != eDecType)
1875     {
1876         VPU_MSG_ERR("warning pTaskInfo->eDecType=%x not %x\n",
1877             pTaskInfo->eDecType, eDecType);
1878     }
1879     goto _SAVE_DEC_TYPE;
1880 
1881 _SAVE_DEC_TYPE:
1882     if (pVPUHalContext->_stVPUStream[u8Offset].eStreamId == (u32Id & 0xFF))
1883     {
1884         pVPUHalContext->_stVPUStream[u8Offset].eDecodertype = eDecType;
1885     }
1886     else
1887     {
1888         VPU_MSG_ERR("Cannot save eDecType!!\n");
1889     }
1890 
1891     (pVPUHalContext->u8TaskCnt)++;
1892     _HAL_VPU_Release();
1893     return TRUE;
1894 }
1895 
HAL_VPU_EX_TaskDelete(MS_U32 u32Id,VPU_EX_NDecInitPara * pInitPara)1896 MS_BOOL HAL_VPU_EX_TaskDelete(MS_U32 u32Id, VPU_EX_NDecInitPara *pInitPara)
1897 {
1898     HVD_Return eRet;
1899 #ifdef VDEC3
1900     HVD_User_Cmd eCmd = E_NST_CMD_DEL_TASK;
1901 #else
1902     HVD_User_Cmd eCmd = E_DUAL_CMD_DEL_TASK;
1903 #endif
1904     MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
1905     MS_U32 u32Timeout       = HVD_GetSysTime_ms() + 3000;
1906 
1907     _HAL_VPU_Entry();
1908     VPU_MSG_DBG("DecType=%d\n", pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype);
1909 
1910     eRet = HAL_HVD_EX_SetCmd(u32Id, eCmd, u8OffsetIdx);
1911     if(eRet != E_HVD_RETURN_SUCCESS)
1912     {
1913         VPU_MSG_ERR("VPU fail to DEL Task %d\n", eRet);
1914     }
1915 
1916     {
1917         struct _ctl_info *ctl_ptr = (struct _ctl_info *)
1918             MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + CTL_INFO_ADDR);
1919         u32Timeout = HVD_GetSysTime_ms() + VPU_CMD_TIMEOUT;
1920 
1921         MsOS_ReadMemory();
1922 
1923         VPU_MSG_DBG("before: version=0x%x, statue=0x%x, last_ctl_cmd=0x%x, last_ctl_arg=0x%x, t0=%d, t1=%d\n",
1924             ctl_ptr->verion, ctl_ptr->statue, ctl_ptr->last_ctl_cmd, ctl_ptr->last_ctl_arg, ctl_ptr->task_statue[0], ctl_ptr->task_statue[1]);
1925 
1926         while (CTL_TASK_NONE != ctl_ptr->task_statue[u8OffsetIdx])
1927         {
1928             if (HVD_GetSysTime_ms() > u32Timeout)
1929             {
1930                 VPU_MSG_ERR("Task %u deletion timeout\n", u8OffsetIdx);
1931                 pVPUHalContext->bVpuExLoadFWRlt = FALSE; ///error handling
1932                 VPU_MSG_ERR("Set bVpuExLoadFWRlt as FALSE\n");
1933 
1934                 if(pVPUHalContext->u8TaskCnt == 1)
1935                 {
1936                     VPU_MSG_ERR("Due to one task remain, driver can force delete task\n");
1937                     break;
1938                 }
1939                 else if(pVPUHalContext->u8TaskCnt == 2)
1940                 {
1941                     VPU_MSG_ERR("Due to two tasks remain, driver can't force delete task\n");
1942                     _HAL_VPU_Release();
1943                     return FALSE;
1944                 }
1945                 else
1946                 {
1947                     VPU_MSG_ERR("Task number is not correct\n");
1948                     _HAL_VPU_Release();
1949                     return FALSE;
1950                 }
1951             }
1952 
1953             MsOS_ReadMemory();
1954         }
1955 
1956         VPU_MSG_DBG("after: version=0x%x, statue=0x%x, last_ctl_cmd=0x%x, last_ctl_arg=0x%x, t0=%d, t1=%d\n",
1957             ctl_ptr->verion, ctl_ptr->statue, ctl_ptr->last_ctl_cmd, ctl_ptr->last_ctl_arg, ctl_ptr->task_statue[0], ctl_ptr->task_statue[1]);
1958     }
1959 
1960     #if SUPPORT_EVD
1961     if (pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype == E_VPU_EX_DECODER_EVD)
1962     {
1963         HAL_EVD_EX_ClearTSPInput(u32Id);
1964     }
1965     #endif
1966 
1967     pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype = E_VPU_EX_DECODER_NONE;
1968     if( (u8OffsetIdx == 0) && (pVPUHalContext->_stVPUStream[u8OffsetIdx].eStreamId == E_HAL_VPU_MVC_MAIN_VIEW))
1969     {
1970         pVPUHalContext->_stVPUStream[u8OffsetIdx].eStreamId = E_HAL_VPU_N_STREAM0;
1971         pVPUHalContext->_stVPUStream[0].eDecodertype = E_VPU_EX_DECODER_NONE;
1972         pVPUHalContext->_stVPUStream[1].eDecodertype = E_VPU_EX_DECODER_NONE;
1973     }
1974 
1975     if (pVPUHalContext->u8TaskCnt)
1976     {
1977         (pVPUHalContext->u8TaskCnt)--;
1978     }
1979     else
1980     {
1981         VPU_MSG_DBG("Warning: u8TaskCnt=0\n");
1982     }
1983 
1984     if (0 == pVPUHalContext->u8TaskCnt)
1985     {
1986         int i;
1987         VPU_MSG_DBG("u8TaskCnt=%d time to terminate\n", pVPUHalContext->u8TaskCnt);
1988         _VPU_EX_DeinitAll();
1989         HAL_VPU_EX_SetSingleDecodeMode(FALSE);
1990         pVPUHalContext->u32VPUSHMAddr = 0;
1991 
1992         for (i = 0; i < MAX_SUPPORT_DECODER_NUM; i++)
1993             pVPUHalContext->u32FWShareInfoAddr[i] = 0xFFFFFFFFUL;
1994     }
1995     else
1996     {
1997         pVPUHalContext->u32FWShareInfoAddr[u8OffsetIdx] = 0xFFFFFFFFUL;
1998         _VPU_EX_DeinitHW();
1999     }
2000 
2001     _HAL_VPU_Release();
2002     return TRUE;
2003 }
2004 
HAL_VPU_EX_LoadCode(VPU_EX_FWCodeCfg * pFWCodeCfg)2005 MS_BOOL HAL_VPU_EX_LoadCode(VPU_EX_FWCodeCfg *pFWCodeCfg)
2006 {
2007     MS_VIRT u32DestAddr  = pFWCodeCfg->u32DstAddr;
2008     MS_VIRT u32BinAddr   = pFWCodeCfg->u32BinAddr;
2009     MS_U32 u32Size      = pFWCodeCfg->u32BinSize;
2010 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
2011     MS_U32 u32DestSize  = pFWCodeCfg->u32DstSize;
2012 #endif
2013 
2014     if (FALSE == HAL_VPU_EX_GetFWReload())
2015     {
2016         //printf("%s bFWReload FALSE!!!\n", __FUNCTION__);
2017         if (FALSE == pVPUHalContext->bVpuExLoadFWRlt)
2018         {
2019             VPU_MSG_INFO("Never load fw successfully, load it anyway!\n");
2020         }
2021         else
2022         {
2023             //Check f/w prefix "VDEC30"
2024             if (_VPU_EX_IsNeedDecompress(u32DestAddr)!=FALSE)
2025             {
2026                 VPU_MSG_ERR("Wrong prefix: reload fw!\n");
2027             }
2028             else
2029             {
2030                 VPU_MSG_INFO("Skip loading fw this time!!!\n");
2031                 return TRUE;
2032             }
2033         }
2034     }
2035 
2036     if (E_HVD_FW_INPUT_SOURCE_FLASH == pFWCodeCfg->u8SrcType)
2037     {
2038 #if VPU_ENABLE_BDMA_FW_FLASH_2_SDRAM
2039         if (u32Size != 0)
2040         {
2041             SPIDMA_Dev cpyflag = E_SPIDMA_DEV_MIU1;
2042 
2043 
2044             MS_U32 u32Start;
2045             MS_U32 u32StartOffset;
2046             MS_U8  u8MiuSel;
2047 
2048             _phy_to_miu_offset(u8MiuSel, u32StartOffset, u32DestAddr);
2049 
2050 
2051             if(u8MiuSel == E_CHIP_MIU_0)
2052                 cpyflag = E_SPIDMA_DEV_MIU0;
2053             else if(u8MiuSel == E_CHIP_MIU_1)
2054                 cpyflag = E_SPIDMA_DEV_MIU1;
2055             else if(u8MiuSel == E_CHIP_MIU_2)
2056                 ; ///TODO:  cpyflag = E_SPIDMA_DEV_MIU2;
2057 
2058             if (!HVD_FLASHcpy(MsOS_VA2PA(u32DestAddr), MsOS_VA2PA(u32BinAddr), u32Size, cpyflag))
2059             {
2060                 goto _load_code_fail;
2061             }
2062         }
2063         else
2064         {
2065             goto _load_code_fail;
2066         }
2067 #else
2068         goto _load_code_fail;
2069 #endif
2070     }
2071     else if (E_HVD_FW_INPUT_SOURCE_DRAM == pFWCodeCfg->u8SrcType)
2072     {
2073         if (u32BinAddr != 0 && u32Size != 0)
2074         {
2075 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
2076             if(_VPU_EX_DecompressBin(u32BinAddr, u32Size, u32DestAddr, u32DestAddr+u32DestSize-WINDOW_SIZE)==TRUE)
2077             {
2078                 if(_VPU_EX_IsNeedDecompress(u32DestAddr)==FALSE)
2079                 {
2080                     VPU_MSG_INFO("Decompress ok!!!\n");
2081                 }
2082                 else
2083                 {
2084                     VPU_MSG_INFO("Decompress fail!!!\n");
2085                 }
2086             }
2087             else
2088 #endif
2089             {
2090                 HVD_memcpy(u32DestAddr, u32BinAddr, u32Size);
2091             }
2092         }
2093         else
2094         {
2095             goto _load_code_fail;
2096         }
2097     }
2098     else
2099     {
2100 #if VPU_ENABLE_EMBEDDED_FW_BINARY
2101         VPU_MSG_INFO("Load FW inD2D: dest=0x%lx, source=0x%lx, size=%d\n",
2102                     (unsigned long)u32DestAddr, ((unsigned long) u8HVD_FW_Binary),
2103                     (MS_U32) sizeof(u8HVD_FW_Binary));
2104 
2105 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
2106         if(_VPU_EX_DecompressBin((MS_VIRT)u8HVD_FW_Binary, (MS_U32)sizeof(u8HVD_FW_Binary), u32DestAddr, u32DestAddr+u32DestSize-WINDOW_SIZE)==TRUE)
2107         {
2108             if(_VPU_EX_IsNeedDecompress(u32DestAddr)==FALSE)
2109             {
2110                 VPU_MSG_INFO("Decompress ok!!!\n");
2111             }
2112             else
2113             {
2114                 VPU_MSG_INFO("Decompress fail!!!\n");
2115             }
2116         }
2117         else
2118 #endif
2119         {
2120             HVD_memcpy(u32DestAddr, (MS_VIRT)u8HVD_FW_Binary, sizeof(u8HVD_FW_Binary));
2121         }
2122 #else
2123         goto _load_code_fail;
2124 #endif
2125     }
2126 
2127     MAsm_CPU_Sync();
2128     MsOS_FlushMemory();
2129 
2130     if (FALSE == (*((MS_U8*)(u32DestAddr+6))=='R' && *((MS_U8*)(u32DestAddr+7))=='2'))
2131     {
2132         VPU_MSG_ERR("FW is not R2 version! _%x_ _%x_\n", *(MS_U8*)(u32DestAddr+6), *(MS_U8*)(u32DestAddr+7));
2133         goto _load_code_fail;
2134     }
2135 
2136     pVPUHalContext->bVpuExLoadFWRlt = TRUE;
2137     return TRUE;
2138 
2139 _load_code_fail:
2140     pVPUHalContext->bVpuExLoadFWRlt = FALSE;
2141     return FALSE;
2142 }
2143 
HAL_VPU_EX_InitRegBase(MS_VIRT u32RegBase)2144 void HAL_VPU_EX_InitRegBase(MS_VIRT u32RegBase)
2145 {
2146     u32VPURegOSBase = u32RegBase;
2147 }
2148 
HAL_VPU_EX_Init_Share_Mem(void)2149 MS_BOOL HAL_VPU_EX_Init_Share_Mem(void)
2150 {
2151 #if ((defined(MSOS_TYPE_LINUX) || defined(MSOS_TYPE_ECOS)) && (!defined(SUPPORT_X_MODEL_FEATURE)))
2152 
2153     MS_U32 u32ShmId;
2154     MS_VIRT u32Addr;
2155     MS_U32 u32BufSize;
2156 
2157 
2158     if (FALSE == MsOS_SHM_GetId( (MS_U8*)"Linux HAL VPU",
2159                                           sizeof(VPU_Hal_CTX),
2160                                           &u32ShmId,
2161                                           &u32Addr,
2162                                           &u32BufSize,
2163                                           MSOS_SHM_QUERY))
2164     {
2165         if (FALSE == MsOS_SHM_GetId((MS_U8*)"Linux HAL VPU",
2166                                              sizeof(VPU_Hal_CTX),
2167                                              &u32ShmId,
2168                                              &u32Addr,
2169                                              &u32BufSize,
2170                                              MSOS_SHM_CREATE))
2171         {
2172             VPU_MSG_ERR("[%s]SHM allocation failed!!!use global structure instead!!!\n",__FUNCTION__);
2173             if(pVPUHalContext == NULL)
2174             {
2175                 pVPUHalContext = &gVPUHalContext;
2176                 memset(pVPUHalContext,0,sizeof(VPU_Hal_CTX));
2177                 _VPU_EX_Context_Init();
2178                 VPU_MSG_INFO("[%s]Global structure init Success!!!\n",__FUNCTION__);
2179             }
2180             else
2181             {
2182                 VPU_MSG_INFO("[%s]Global structure exists!!!\n",__FUNCTION__);
2183             }
2184             //return FALSE;
2185         }
2186         else
2187         {
2188             memset((MS_U8*)u32Addr,0,sizeof(VPU_Hal_CTX));
2189             pVPUHalContext = (VPU_Hal_CTX*)u32Addr; // for one process
2190             _VPU_EX_Context_Init();
2191         }
2192     }
2193     else
2194     {
2195         pVPUHalContext = (VPU_Hal_CTX*)u32Addr; // for another process
2196     }
2197 #else
2198     if(pVPUHalContext == NULL)
2199     {
2200         pVPUHalContext = &gVPUHalContext;
2201         memset(pVPUHalContext,0,sizeof(VPU_Hal_CTX));
2202         _VPU_EX_Context_Init();
2203     }
2204 #endif
2205 
2206     return TRUE;
2207 
2208 }
2209 
HAL_VPU_EX_GetFreeStream(HAL_VPU_StreamType eStreamType)2210 HAL_VPU_StreamId HAL_VPU_EX_GetFreeStream(HAL_VPU_StreamType eStreamType)
2211 {
2212     MS_U32 i = 0;
2213 
2214     _HAL_VPU_MutexCreate();
2215 
2216     _HAL_VPU_Entry();
2217 
2218     if (E_HAL_VPU_MVC_STREAM == eStreamType)
2219     {
2220         if((E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[0].eDecodertype) && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[1].eDecodertype))
2221         {
2222             pVPUHalContext->_stVPUStream[0].eStreamId = E_HAL_VPU_MVC_MAIN_VIEW;
2223             pVPUHalContext->_stVPUStream[0].eDecodertype = E_VPU_EX_DECODER_GET_MVC;
2224             pVPUHalContext->_stVPUStream[1].eDecodertype = E_VPU_EX_DECODER_GET_MVC;
2225             _HAL_VPU_Release();
2226             return pVPUHalContext->_stVPUStream[0].eStreamId;       /// Need to check
2227         }
2228     }
2229     else if (E_HAL_VPU_MAIN_STREAM == eStreamType)
2230     {
2231         for (i = 0;i < MAX_SUPPORT_DECODER_NUM; i++)
2232         {
2233             if ((E_HAL_VPU_MAIN_STREAM_BASE & pVPUHalContext->_stVPUStream[i].eStreamId)
2234                 && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[i].eDecodertype))
2235             {
2236                 pVPUHalContext->_stVPUStream[i].eDecodertype = E_VPU_EX_DECODER_GET;
2237                 _HAL_VPU_Release();
2238                 return pVPUHalContext->_stVPUStream[i].eStreamId;
2239             }
2240         }
2241     }
2242     else if (E_HAL_VPU_SUB_STREAM == eStreamType)
2243     {
2244         for (i = 0;i < MAX_SUPPORT_DECODER_NUM; i++)
2245         {
2246             if ((E_HAL_VPU_SUB_STREAM_BASE & pVPUHalContext->_stVPUStream[i].eStreamId)
2247                 && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[i].eDecodertype))
2248             {
2249                 pVPUHalContext->_stVPUStream[i].eDecodertype = E_VPU_EX_DECODER_GET;
2250                 _HAL_VPU_Release();
2251                 return pVPUHalContext->_stVPUStream[i].eStreamId;
2252             }
2253         }
2254     }
2255 #ifdef VDEC3
2256     else if (eStreamType >= E_HAL_VPU_N_STREAM && eStreamType < (E_HAL_VPU_N_STREAM + VPU_MAX_DEC_NUM))
2257     {
2258 #if 1 // bound FW task to main/sub stream
2259         i = eStreamType - E_HAL_VPU_N_STREAM;
2260         if (pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_NONE)
2261         {
2262             pVPUHalContext->_stVPUStream[i].eDecodertype = E_VPU_EX_DECODER_GET;
2263             _HAL_VPU_Release();
2264             return pVPUHalContext->_stVPUStream[i].eStreamId;
2265         }
2266 #else // dynamic select FW task id
2267         for (i = 0;i < MAX_SUPPORT_DECODER_NUM; i++)
2268         {
2269             if ((E_HAL_VPU_N_STREAM_BASE & pVPUHalContext->_stVPUStream[i].eStreamId)
2270                 && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[i].eDecodertype))
2271             {
2272                 return pVPUHalContext->_stVPUStream[i].eStreamId;
2273             }
2274         }
2275 #endif
2276     }
2277 #endif
2278 
2279     _HAL_VPU_Release();
2280 
2281     return E_HAL_VPU_STREAM_NONE;
2282 }
2283 
HAL_VPU_EX_ReleaseFreeStream(MS_U8 u8Idx)2284 MS_BOOL HAL_VPU_EX_ReleaseFreeStream(MS_U8 u8Idx)
2285 {
2286     if(u8Idx > 2)
2287     {
2288         return FALSE;
2289     }
2290 
2291     _HAL_VPU_Entry();
2292 
2293     if(pVPUHalContext->_stVPUStream[u8Idx].eDecodertype == E_VPU_EX_DECODER_GET_MVC)
2294     {
2295         pVPUHalContext->_stVPUStream[0].eDecodertype = E_VPU_EX_DECODER_NONE;
2296         pVPUHalContext->_stVPUStream[1].eDecodertype = E_VPU_EX_DECODER_NONE;
2297     }
2298     else if(pVPUHalContext->_stVPUStream[u8Idx].eDecodertype == E_VPU_EX_DECODER_GET)
2299     {
2300         pVPUHalContext->_stVPUStream[u8Idx].eDecodertype = E_VPU_EX_DECODER_NONE;
2301     }
2302 
2303     _HAL_VPU_Release();
2304 
2305     return TRUE;
2306 }
2307 
HAL_VPU_EX_CheckFreeStream(void)2308 MS_U8 HAL_VPU_EX_CheckFreeStream(void)
2309 {
2310     MS_U8 u8Idx = 0;
2311 
2312     for (u8Idx = 0; u8Idx < MAX_SUPPORT_DECODER_NUM; u8Idx++)
2313     {
2314         if (pVPUHalContext->_stVPUStream[u8Idx].eDecodertype == E_VPU_EX_DECODER_NONE)
2315             break;
2316     }
2317 
2318     if (u8Idx >= MAX_SUPPORT_DECODER_NUM)
2319     {
2320         VPU_MSG_ERR("all vpu free streams are occupied \n");
2321         return -1;
2322     }
2323 
2324     VPU_MSG_DBG("available vpu free stream %d \n", u8Idx);
2325     return u8Idx;
2326 }
2327 
HAL_VPU_EX_Init(VPU_EX_InitParam * InitParams)2328 MS_BOOL HAL_VPU_EX_Init(VPU_EX_InitParam *InitParams)
2329 {
2330     VPU_MSG_DBG("Inv=%d, clk=%d\n", InitParams->bClockInv, InitParams->eClockSpeed);
2331 
2332     // enable module
2333     _VPU_EX_ClockInv(InitParams->bClockInv);
2334     _VPU_EX_ClockSpeed(InitParams->eClockSpeed);
2335     HAL_VPU_EX_PowerCtrl(TRUE);
2336 
2337 #if 1                           //Create VPU's own mutex
2338     //_HAL_VPU_MutexCreate();
2339 #else
2340     pVPUHalContext->s32VPUMutexID = InitParams->s32VPUMutexID;
2341     pVPUHalContext->u32VPUMutexTimeOut = InitParams->u32VPUMutexTimeout;
2342 #endif
2343 
2344     return TRUE;
2345 }
2346 
HAL_VPU_EX_DeInit(void)2347 MS_BOOL HAL_VPU_EX_DeInit(void)
2348 {
2349     if (0 != _VPU_EX_GetActiveCodecCnt())
2350     {
2351         VPU_MSG_DBG("do nothing since codec is active.\n");
2352         return TRUE;
2353     }
2354 
2355     memset(&(pVPUHalContext->_stVPUDecMode),0,sizeof(VPU_EX_DecModCfg));
2356 
2357     HAL_VPU_EX_PowerCtrl(FALSE);
2358     HAL_VPU_EX_SwRelseMAU();
2359     //_HAL_VPU_MutexDelete();
2360 
2361     return TRUE;
2362 }
2363 
HAL_VPU_EX_PowerCtrl(MS_BOOL bEnable)2364 void HAL_VPU_EX_PowerCtrl(MS_BOOL bEnable)
2365 {
2366     if (bEnable)
2367     {
2368         _VPU_WriteWordMask(REG_TOP_VPU, 0, TOP_CKG_VPU_DIS);
2369         _VPU_WriteWordMask( REG_CHIPTOP_DUMMY_CODEC, REG_CHIPTOP_DUMMY_CODEC_ENABLE, REG_CHIPTOP_DUMMY_CODEC_ENABLE);
2370         pVPUHalContext->_bVPUPowered = TRUE;
2371     }
2372     else
2373     {
2374         _VPU_WriteWordMask(REG_TOP_VPU, TOP_CKG_VPU_DIS, TOP_CKG_VPU_DIS);
2375         _VPU_WriteWordMask( REG_CHIPTOP_DUMMY_CODEC, 0, REG_CHIPTOP_DUMMY_CODEC_ENABLE);
2376         pVPUHalContext->_bVPUPowered = FALSE;
2377     }
2378 }
2379 
HAL_VPU_EX_MIU_RW_Protect(MS_BOOL bEnable)2380 void HAL_VPU_EX_MIU_RW_Protect(MS_BOOL bEnable)
2381 {
2382     _VPU_MIU_SetReqMask(VPU_D_RW, bEnable);
2383     _VPU_MIU_SetReqMask(VPU_Q_RW, bEnable);
2384     _VPU_MIU_SetReqMask(VPU_I_R, bEnable);
2385     VPU_EX_TimerDelayMS(1);
2386 }
2387 
2388 ///-----------------------------------------------------------------------------
2389 /// config AVCH264 CPU
2390 /// @param u32StAddr \b IN: CPU binary code base address in DRAM.
2391 /// @param u8dlend_en \b IN: endian
2392 ///     - 1, little endian
2393 ///     - 0, big endian
2394 ///-----------------------------------------------------------------------------
HAL_VPU_EX_CPUSetting(MS_PHY u32StAddr)2395 MS_BOOL HAL_VPU_EX_CPUSetting(MS_PHY u32StAddr)
2396 {
2397     MS_BOOL bRet = TRUE;
2398     MS_U32 u32Offset = 0;
2399     MS_U16 tempreg = 0;
2400     MS_U8  u8MiuSel;
2401     //MS_U32 u32TmpStartOffset;
2402 
2403     _phy_to_miu_offset(u8MiuSel, u32Offset, u32StAddr);
2404 
2405     _VPU_Write2Byte(VPU_REG_SPI_BASE,  0xC000);
2406     _VPU_WriteWordMask( VPU_REG_MIU_LAST , 0 , VPU_REG_MIU_LAST_EN );
2407     _VPU_WriteWordMask( VPU_REG_CPU_SETTING , 0 , VPU_REG_CPU_SPI_BOOT );
2408     _VPU_WriteWordMask( VPU_REG_CPU_SETTING , 0 , VPU_REG_CPU_SDRAM_BOOT );
2409     _VPU_Write2Byte(VPU_REG_DQMEM_MASK_L,  0xc000);
2410     _VPU_Write2Byte(VPU_REG_DQMEM_MASK_H,  0xffff);
2411     _VPU_Write2Byte(VPU_REG_IO1_BASE,  0xf900); // UART BASE
2412     _VPU_Write2Byte(VPU_REG_IO2_BASE,  0xf000);
2413     _VPU_Write2Byte(VPU_REG_DQMEM_BASE_L,  0x0000);
2414     _VPU_Write2Byte(VPU_REG_DQMEM_BASE_H, 0xf200);
2415 
2416     #if (HVD_ENABLE_IQMEM)
2417     _VPU_Write2Byte(VPU_REG_IQMEM_BASE_L, (MS_U16)(VPU_IQMEM_BASE & 0x0000ffff));
2418     _VPU_Write2Byte(VPU_REG_IQMEM_BASE_H, (MS_U16)((VPU_IQMEM_BASE>>16) & 0xffff));
2419     #endif
2420 
2421     #if (VPU_FORCE_MIU_MODE)
2422         // Data sram base Unit: byte address
2423         _VPU_Write2Byte(VPU_REG_DCU_SDR_BASE_L, (MS_U16)(u32Offset & 0x0000ffff)) ;
2424         _VPU_Write2Byte(VPU_REG_DCU_SDR_BASE_H, (MS_U16)((u32Offset >>16) & 0xffff));
2425         // Instruction sram base Unit: byte address
2426         _VPU_Write2Byte(VPU_REG_ICU_SDR_BASE_L, (MS_U16)(u32Offset & 0x0000ffff)) ;
2427         _VPU_Write2Byte(VPU_REG_ICU_SDR_BASE_H, (MS_U16)((u32Offset >>16) & 0xffff));
2428 
2429 #ifndef HAL_FEATURE_MAU
2430     MS_U16 r2_miu_sel = (_VPU_Read2Byte(VPU_REG_R2_MI_SEL_BASE) & 0xfff);
2431 #endif
2432     VPU_MSG_INFO("\033[1;32m[%s] %d  u8MiuSel = %d  r2_miu_sel = 0x%x \033[m\n",__FUNCTION__,__LINE__,u8MiuSel,r2_miu_sel);
2433 
2434 	//use force miu mode
2435     if(u8MiuSel == E_CHIP_MIU_0)
2436     {
2437 #ifdef HAL_FEATURE_MAU
2438         _VPU_Write2Byte(MAU1_MIU_SEL, 0x8900);
2439         _VPU_Write2Byte(MAU1_LV2_0_MIU_SEL, 0x8900);
2440         _VPU_Write2Byte(MAU1_LV2_1_MIU_SEL, 0x8900);
2441 #else
2442         _VPU_Write2Byte(VPU_REG_R2_MI_SEL_BASE, r2_miu_sel);//1 Manhattan has no MAU, use this register to select miu
2443 #endif
2444     }
2445     else if(u8MiuSel == E_CHIP_MIU_1)
2446     {
2447 #ifdef HAL_FEATURE_MAU
2448         _VPU_Write2Byte(MAU1_MIU_SEL, 0x8900);
2449         _VPU_Write2Byte(MAU1_LV2_0_MIU_SEL, 0x8b00);
2450         _VPU_Write2Byte(MAU1_LV2_1_MIU_SEL, 0x8900);
2451 #else
2452         _VPU_Write2Byte(VPU_REG_R2_MI_SEL_BASE, r2_miu_sel|0x5000);
2453 #endif
2454     }
2455     else //miu 2
2456     {
2457 #ifdef HAL_FEATURE_MAU
2458         _VPU_Write2Byte(MAU1_MIU_SEL, 0x8b00);
2459         _VPU_Write2Byte(MAU1_LV2_0_MIU_SEL, 0x8900);
2460         _VPU_Write2Byte(MAU1_LV2_1_MIU_SEL, 0x8900);
2461 #else
2462         _VPU_Write2Byte(VPU_REG_R2_MI_SEL_BASE, r2_miu_sel|0xa000);
2463 #endif
2464     }
2465     #else
2466     ///TODO:
2467     #endif
2468 
2469 
2470     tempreg = _VPU_Read2Byte(VPU_REG_CONTROL_SET);
2471     tempreg |= VPU_REG_IO2_EN;
2472     tempreg |= VPU_REG_QMEM_SPACE_EN;
2473     _VPU_Write2Byte(VPU_REG_CONTROL_SET, tempreg);
2474 
2475     return bRet;
2476 }
2477 
2478 ///-----------------------------------------------------------------------------
2479 /// Set IQMem data access mode or instruction fetch mode
2480 /// @param u8dlend_en \b IN: endian
2481 ///     - 1, switch to data access mode
2482 ///     - 0, switch to instruction fetch mode
2483 ///-----------------------------------------------------------------------------
HAL_VPU_EX_IQMemSetDAMode(MS_BOOL bEnable)2484 void HAL_VPU_EX_IQMemSetDAMode(MS_BOOL bEnable)
2485 {
2486 
2487     if(bEnable){
2488 
2489         _VPU_Write2Byte(VPU_REG_IQMEM_SETTING, _VPU_Read2Byte(VPU_REG_IQMEM_SETTING)|0x10);
2490         _VPU_Write2Byte(VPU_REG_QMEM_OWNER, _VPU_Read2Byte(VPU_REG_QMEM_OWNER)&0xFFDE);
2491 
2492     }
2493     else{
2494 
2495         _VPU_Write2Byte(VPU_REG_IQMEM_SETTING, _VPU_Read2Byte(VPU_REG_IQMEM_SETTING)& 0xFFEF);
2496 
2497     }
2498 }
2499 
2500 ///-----------------------------------------------------------------------------
2501 /// H.264 SW reset
2502 /// @return TRUE or FALSE
2503 ///     - TRUE, Success
2504 ///     - FALSE, Failed
2505 ///-----------------------------------------------------------------------------
HAL_VPU_EX_SwRst(MS_BOOL bCheckMauIdle)2506 MS_BOOL HAL_VPU_EX_SwRst(MS_BOOL bCheckMauIdle)
2507 {
2508     MS_U16 tempreg = 0, tempreg1 = 0;
2509     MS_U16 idle_cnt;
2510     tempreg = _VPU_Read2Byte(VPU_REG_CPU_CONFIG);
2511     tempreg |= VPU_REG_CPU_STALL_EN;
2512     _VPU_Write2Byte(VPU_REG_CPU_CONFIG, tempreg);
2513 
2514     tempreg = _VPU_Read2Byte(VPU_REG_CPU_SETTING);
2515     // 0xf means VPU is not stalled
2516     if (tempreg & 0xf) {
2517         // write R2 RIU registers to select DCU/ICU debug data
2518         // Writing these registers here provides enough time for them to
2519         // take effect.
2520         tempreg1 = _VPU_Read2Byte(VPU_REG_DCU_DBG_SEL);
2521         tempreg1 |= VPU_REG_DCU_DBG_SEL_0 | VPU_REG_DCU_DBG_SEL_1;
2522         _VPU_Write2Byte(VPU_REG_DCU_DBG_SEL, tempreg1);
2523         _VPU_Write2Byte(VPU_REG_ICU_DBG_SEL, 0);
2524 
2525         // wait at least 1ms for VPU_REG_CPU_STALL_EN to take effect
2526         // This step is important because in the next step we want to make
2527         // sure "DCU is not replaying when R2 is stalled".
2528         idle_cnt = 100;
2529         do
2530         {
2531             if (--idle_cnt == 0)
2532             {
2533                 printf("VPU_REG_CPU_STALL_EN is not set\n");
2534                 break;
2535             }
2536             MsOS_DelayTask(1);
2537         } while ((_VPU_Read2Byte(VPU_REG_CPU_CONFIG) & VPU_REG_CPU_STALL_EN) == 0);
2538         // check CPU status: DCU should NOT be replaying
2539         // If R2 has been stalled, we can guarantee that if we found DCU is
2540         // NOT replaying, it will NOT replay later even CPU is going to issue
2541         // a load/store instruction.
2542         idle_cnt = 100;
2543         while (_VPU_Read2Byte(VPU_REG_CPU_STATUS) & VPU_REG_CPU_D_REPLAY)
2544         {
2545             if (--idle_cnt == 0)
2546             {
2547                 printf("DCU is replaying\n");
2548                 break;
2549             }
2550             MsOS_DelayTask(1);
2551         }
2552         // wait 1ms to prevent race condition between (1) DCU is not
2553         // replaying, and (2) BIU start to doing new job or ICU start to
2554         // fetch new instruction
2555         MsOS_DelayTask(1);
2556 
2557         // check BIU should be empty
2558         idle_cnt = 100;
2559         while ( (_VPU_Read2Byte(VPU_REG_DCU_STATUS) & VPU_REG_BIU_EMPTY) == 0 )
2560         {
2561             if (--idle_cnt == 0)
2562             {
2563                 printf("BIU DCU idle time out~~~~~\n");
2564                 break;
2565             }
2566             MsOS_DelayTask(1);
2567         }
2568         if (idle_cnt == 0)
2569         {
2570              VPU_MSG_INFO("BIU DCU idle time out~~~~~\n");
2571         }
2572         // check CPU is not requesting ICU
2573         idle_cnt = 100;
2574         while (_VPU_Read2Byte(VPU_REG_ICU_DBG_DAT0) & VPU_REG_ICPU_REQ)
2575         {
2576             if (--idle_cnt == 0)
2577             {
2578                 printf("CPU keeps requesting ICU\n");
2579                 break;
2580             }
2581             MsOS_DelayTask(1);
2582         }
2583         // wait 1ms to avoid race condition of (1) CPU stop requesting ICU, and
2584         // (2) ISB start to fetch
2585         MsOS_DelayTask(1);
2586 
2587         // check ISB should be idle
2588         idle_cnt = 100;
2589         while ( (_VPU_Read2Byte(VPU_REG_ICU_STATUS) & VPU_REG_ISB_IDLE) == 0 )
2590         {
2591             if (--idle_cnt == 0) {
2592                 VPU_MSG_INFO("BIU ICU idle time out~~~~~\n");
2593                 break;
2594             }
2595             MsOS_DelayTask(1);
2596         }
2597     }
2598 #ifdef HAL_FEATURE_MAU
2599 //MAU has been removed since manhattan, so it is not necessary to check MAU status
2600 
2601     if (bCheckMauIdle)
2602     {
2603         MS_U32 mau_idle_cnt = 100;// ms
2604         while (mau_idle_cnt)
2605         {
2606             if (TRUE == _VPU_EX_MAU_IDLE())
2607             {
2608                 break;
2609             }
2610             mau_idle_cnt--;
2611             MsOS_DelayTask(1);
2612         }
2613 
2614         if (mau_idle_cnt == 0)
2615         {
2616             VPU_MSG_INFO("MAU idle time out~~~~~\n");
2617         }
2618     }
2619 #endif
2620 
2621     // this command set MIU to block R2 (does not ack R2's request)
2622     HAL_VPU_EX_MIU_RW_Protect(TRUE);
2623 
2624 #ifdef HAL_FEATURE_MAU
2625     // reset MAU
2626     tempreg1 = _VPU_Read2Byte(MAU1_CPU_RST);
2627     tempreg1 |= MAU1_REG_SW_RESET;
2628     _VPU_Write2Byte(MAU1_CPU_RST, tempreg1);
2629 #if defined(UDMA_FPGA_ENVI)
2630     tempreg = _VPU_Read2Byte(VPU_REG_RESET);
2631    _VPU_Write2Byte(VPU_REG_RESET, (tempreg& 0xfffd));
2632 #endif
2633 #endif
2634 
2635     // reset R2
2636     // We should trigger MIU reset before R2 reset. If we set MIU/R2 reset
2637     // by the same RIU write, the R2 reset signal may reach afifo eralier
2638     // than MIU reset and afifo write pointer will be reset to position 0.
2639     // In this case, afifo consider it is not empty because read/write
2640     // pointer are mismatch and then BIU sends out unpredicted MIU request.
2641     tempreg = _VPU_Read2Byte(VPU_REG_CPU_SETTING);
2642     tempreg &= ~VPU_REG_CPU_MIU_SW_RSTZ;
2643     _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2644     VPU_EX_TimerDelayMS(1);
2645     tempreg &= ~VPU_REG_CPU_R2_EN;
2646     tempreg &= ~VPU_REG_CPU_SW_RSTZ;
2647     _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2648 
2649     VPU_EX_TimerDelayMS(1);
2650 
2651     // this command set MIU to accept R2 (can ack R2's request)
2652     HAL_VPU_EX_MIU_RW_Protect(FALSE);
2653 
2654     pVPUHalContext->_bVPURsted = FALSE;
2655     return TRUE;
2656 }
2657 
2658 ///-----------------------------------------------------------------------------
2659 /// CPU reset release
2660 ///-----------------------------------------------------------------------------
HAL_VPU_EX_SwRstRelse(void)2661 void HAL_VPU_EX_SwRstRelse(void)
2662 {
2663     MS_U16 tempreg = 0;
2664 
2665     tempreg = _VPU_Read2Byte(VPU_REG_CPU_CONFIG);
2666     tempreg &= ~VPU_REG_CPU_STALL_EN;
2667     _VPU_Write2Byte(VPU_REG_CPU_CONFIG, tempreg);
2668 
2669     tempreg = _VPU_Read2Byte(VPU_REG_CPU_SETTING);
2670     tempreg |= VPU_REG_CPU_MIU_SW_RSTZ;
2671     _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2672     VPU_EX_TimerDelayMS(1);
2673     tempreg |= VPU_REG_CPU_SW_RSTZ;
2674     _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2675     VPU_EX_TimerDelayMS(1);
2676     tempreg |= VPU_REG_CPU_R2_EN;
2677     _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2678 #ifdef HAL_FEATURE_MAU
2679     MS_U16 tempreg1 = 0;
2680     tempreg1 = _VPU_Read2Byte(MAU1_CPU_RST);
2681     tempreg1 &= ~MAU1_REG_SW_RESET;
2682     _VPU_Write2Byte(MAU1_CPU_RST, tempreg1);
2683 #endif
2684     pVPUHalContext->_bVPURsted = TRUE;
2685 }
2686 
HAL_VPU_EX_SwRelseMAU(void)2687 void HAL_VPU_EX_SwRelseMAU(void)
2688 {
2689 #ifdef HAL_FEATURE_MAU
2690     MS_U16 tempreg = 0;
2691 
2692     tempreg = _VPU_Read2Byte(MAU1_CPU_RST);
2693     tempreg &= ~MAU1_REG_SW_RESET;
2694     _VPU_Write2Byte(MAU1_CPU_RST, tempreg);
2695 #endif
2696 }
2697 
HAL_VPU_EX_MemRead(MS_VIRT u32Addr)2698 MS_U32 HAL_VPU_EX_MemRead(MS_VIRT u32Addr)
2699 {
2700     MS_U32 u32value = 0;
2701 
2702     return u32value;
2703 }
2704 
HAL_VPU_EX_MemWrite(MS_VIRT u32Addr,MS_U32 u32value)2705 MS_BOOL HAL_VPU_EX_MemWrite(MS_VIRT u32Addr, MS_U32 u32value)
2706 {
2707     MS_BOOL bRet = TRUE;
2708 
2709     return bRet;
2710 }
2711 
2712 ///-----------------------------------------------------------------------------
2713 /// Check AVCH264 Ready or not
2714 /// @return TRUE or FALSE
2715 ///     - TRUE, MailBox is free
2716 ///     - FALSE, MailBox is busy
2717 /// @param u8MBox \b IN: MailBox to check
2718 ///     - AVCH264_HI_MBOX0,
2719 ///     - AVCH264_HI_MBOX1,
2720 ///     - AVCH264_RISC_MBOX0,
2721 ///     - AVCH264_RISC_MBOX1,
2722 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxRdy(MS_U32 u32type)2723 MS_BOOL HAL_VPU_EX_MBoxRdy(MS_U32 u32type)
2724 {
2725     MS_BOOL bResult = FALSE;
2726 
2727     switch (u32type)
2728     {
2729         case VPU_HI_MBOX0:
2730             bResult = (_VPU_Read2Byte(VPU_REG_HI_MBOX_RDY) & VPU_REG_HI_MBOX0_RDY) ? FALSE : TRUE;
2731             break;
2732         case VPU_HI_MBOX1:
2733             bResult = (_VPU_Read2Byte(VPU_REG_HI_MBOX_RDY) & VPU_REG_HI_MBOX1_RDY) ? FALSE : TRUE;
2734             break;
2735         case VPU_RISC_MBOX0:
2736             bResult = (_VPU_Read2Byte(VPU_REG_RISC_MBOX_RDY) & VPU_REG_RISC_MBOX0_RDY) ? TRUE : FALSE;
2737             break;
2738         case VPU_RISC_MBOX1:
2739             bResult = (_VPU_Read2Byte(VPU_REG_RISC_MBOX_RDY) & VPU_REG_RISC_MBOX1_RDY) ? TRUE : FALSE;
2740             break;
2741         default:
2742             break;
2743     }
2744     return bResult;
2745 }
2746 
2747 
2748 ///-----------------------------------------------------------------------------
2749 /// Read message from AVCH264
2750 /// @return TRUE or FALSE
2751 ///     - TRUE, success
2752 ///     - FALSE, failed
2753 /// @param u8MBox \b IN: MailBox to read
2754 ///     - AVCH264_RISC_MBOX0
2755 ///     - AVCH264_RISC_MBOX1
2756 /// @param u32Msg \b OUT: message read
2757 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxRead(MS_U32 u32type,MS_U32 * u32Msg)2758 MS_BOOL HAL_VPU_EX_MBoxRead(MS_U32 u32type, MS_U32 * u32Msg)
2759 {
2760     MS_BOOL bResult = TRUE;
2761 
2762     switch (u32type)
2763     {
2764         case VPU_HI_MBOX0:
2765             *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX0_H)) << 16) |
2766                 ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX0_L)));
2767             break;
2768         case VPU_HI_MBOX1:
2769             *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX1_H)) << 16) |
2770                 ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX1_L)));
2771             break;
2772         case VPU_RISC_MBOX0:
2773             *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX0_H)) << 16) |
2774                 ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX0_L)));
2775             break;
2776         case VPU_RISC_MBOX1:
2777             *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX1_H)) << 16) |
2778                 ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX1_L)));
2779             break;
2780         default:
2781             *u32Msg = 0;
2782             bResult = FALSE;
2783             break;
2784     }
2785     return bResult;
2786 }
2787 
2788 ///-----------------------------------------------------------------------------
2789 /// Mailbox from AVCH264 clear bit resest
2790 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxClear(MS_U32 u32type)2791 void HAL_VPU_EX_MBoxClear(MS_U32 u32type)
2792 {
2793     switch (u32type)
2794     {
2795         case VPU_RISC_MBOX0:
2796             _VPU_WriteWordMask(VPU_REG_RISC_MBOX_CLR, VPU_REG_RISC_MBOX0_CLR, VPU_REG_RISC_MBOX0_CLR);
2797             break;
2798         case VPU_RISC_MBOX1:
2799             _VPU_WriteWordMask(VPU_REG_RISC_MBOX_CLR, VPU_REG_RISC_MBOX1_CLR, VPU_REG_RISC_MBOX1_CLR);
2800             break;
2801         default:
2802             break;
2803     }
2804 }
2805 
2806 ///-----------------------------------------------------------------------------
2807 /// Send message to AVCH264
2808 /// @return TRUE or FALSE
2809 ///     - TRUE, Success
2810 ///     - FALSE, Failed
2811 /// @param u8MBox \b IN: MailBox
2812 ///     - AVCH264_HI_MBOX0,
2813 ///     - AVCH264_HI_MBOX1,
2814 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxSend(MS_U32 u32type,MS_U32 u32Msg)2815 MS_BOOL HAL_VPU_EX_MBoxSend(MS_U32 u32type, MS_U32 u32Msg)
2816 {
2817     MS_BOOL bResult = TRUE;
2818 
2819     VPU_MSG_DBG("type=%u, msg=0x%x\n", u32type, u32Msg);
2820 
2821     switch (u32type)
2822     {
2823         case VPU_HI_MBOX0:
2824         {
2825             _VPU_Write4Byte(VPU_REG_HI_MBOX0_L, u32Msg);
2826             _VPU_WriteWordMask(VPU_REG_HI_MBOX_SET, VPU_REG_HI_MBOX0_SET, VPU_REG_HI_MBOX0_SET);
2827             break;
2828         }
2829         case VPU_HI_MBOX1:
2830         {
2831             _VPU_Write4Byte(VPU_REG_HI_MBOX1_L, u32Msg);
2832             _VPU_WriteWordMask(VPU_REG_HI_MBOX_SET, VPU_REG_HI_MBOX1_SET, VPU_REG_HI_MBOX1_SET);
2833             break;
2834         }
2835         default:
2836         {
2837             bResult = FALSE;
2838             break;
2839         }
2840     }
2841 
2842     return bResult;
2843 }
2844 
HAL_VPU_EX_GetProgCnt(void)2845 MS_U32 HAL_VPU_EX_GetProgCnt(void)
2846 {
2847 
2848     MS_U16 expc_l=0;
2849     MS_U16 expc_h=0;
2850     expc_l = _VPU_Read2Byte(VPU_REG_EXPC_L) & 0xFFFF;
2851     expc_h = _VPU_Read2Byte(VPU_REG_EXPC_H) & 0xFFFF;
2852     return (((MS_U32)expc_h) << 16) | (MS_U32)expc_l;
2853 }
2854 
HAL_VPU_EX_GetTaskId(MS_U32 u32Id)2855 MS_U8 HAL_VPU_EX_GetTaskId(MS_U32 u32Id)
2856 {
2857     return _VPU_EX_GetOffsetIdx(u32Id);
2858 }
2859 
HAL_VPU_EX_SetShareInfoAddr(MS_U32 u32Id,MS_VIRT u32ShmAddr)2860 void HAL_VPU_EX_SetShareInfoAddr(MS_U32 u32Id, MS_VIRT u32ShmAddr)
2861 {
2862     MS_U8 u8Offset = _VPU_EX_GetOffsetIdx(u32Id);
2863 
2864     if (u32ShmAddr == 0)
2865     {
2866         pVPUHalContext->u32FWShareInfoAddr[u8Offset] = 0xFFFFFFFFUL;
2867     }
2868     else
2869     {
2870         if (u8Offset == 0)
2871         {
2872             pVPUHalContext->u32FWShareInfoAddr[u8Offset] = u32ShmAddr;
2873         }
2874         else if (u8Offset == 1)
2875         {
2876             pVPUHalContext->u32FWShareInfoAddr[u8Offset] = u32ShmAddr + TEE_ONE_TASK_SHM_SIZE;
2877         }
2878     }
2879 
2880     VPU_MSG_DBG("set PA ShareInfoAddr[%d] = 0x%lx \n", u8Offset, (unsigned long)pVPUHalContext->u32FWShareInfoAddr[u8Offset]);
2881     return;
2882 }
2883 
HAL_VPU_EX_GetShareInfoAddr(MS_U32 u32Id)2884 MS_VIRT HAL_VPU_EX_GetShareInfoAddr(MS_U32 u32Id)
2885 {
2886     MS_U8 u8Offset = _VPU_EX_GetOffsetIdx(u32Id);
2887 
2888     return pVPUHalContext->u32FWShareInfoAddr[u8Offset];
2889 }
2890 
2891 
HAL_VPU_EX_IsPowered(void)2892 MS_BOOL HAL_VPU_EX_IsPowered(void)
2893 {
2894     return pVPUHalContext->_bVPUPowered;
2895 }
2896 
HAL_VPU_EX_IsRsted(void)2897 MS_BOOL HAL_VPU_EX_IsRsted(void)
2898 {
2899     return pVPUHalContext->_bVPURsted;
2900 }
2901 
HAL_VPU_EX_IsEVDR2(void)2902 MS_BOOL HAL_VPU_EX_IsEVDR2(void)
2903 {
2904 #ifdef EVDR2
2905     return TRUE;
2906 #else
2907     return FALSE;
2908 #endif
2909 }
2910 
HAL_VPU_EX_MVDInUsed(void)2911 MS_BOOL HAL_VPU_EX_MVDInUsed(void)
2912 {
2913     //MVD is in used for MVD or HVD_TSP mode.
2914     MS_U8 i;
2915     MS_U8 u8UseCnt = 0;
2916 
2917     for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
2918     {
2919         if ((pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_MVD) ||
2920 #ifdef VDEC3
2921             (pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_EVD) ||
2922 #endif
2923             (pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_HVD) )
2924         {
2925             u8UseCnt++;
2926         }
2927     }
2928 
2929     VPU_MSG_DBG("MVD u8UseCnt=%d\n", u8UseCnt);
2930 
2931     if (u8UseCnt != 0)
2932     {
2933         return TRUE;
2934     }
2935     else
2936     {
2937         return FALSE;
2938     }
2939 }
2940 
HAL_VPU_EX_HVDInUsed(void)2941 MS_BOOL HAL_VPU_EX_HVDInUsed(void)
2942 {
2943     //HVD is in used for HVD or MVD in sub stream.
2944     MS_U8 i;
2945     MS_U8 u8UseCnt = 0;
2946     MS_BOOL bMVDTriggerHVD = FALSE;
2947     for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
2948     {
2949 #ifdef VDEC3
2950         bMVDTriggerHVD = (E_VPU_EX_DECODER_MVD == pVPUHalContext->_stVPUStream[i].eDecodertype) &&
2951                          (pVPUHalContext->u8HALId[i] == 1) &&
2952                          (E_VPU_DEC_MODE_DUAL_INDIE == pVPUHalContext->_stVPUDecMode.u8DecMod);
2953 #else
2954         bMVDTriggerHVD = (E_VPU_EX_DECODER_MVD == pVPUHalContext->_stVPUStream[i].eDecodertype) &&
2955                          (E_HAL_VPU_SUB_STREAM0 == pVPUHalContext->_stVPUStream[i].eStreamId) &&
2956                          (E_VPU_DEC_MODE_DUAL_INDIE == pVPUHalContext->_stVPUDecMode.u8DecMod);
2957 #endif
2958 
2959         if(bMVDTriggerHVD)
2960         {
2961             VPU_MSG_DBG("%s  i:%d  eDecodertype:%d  u8DecMod:%d\n",__FUNCTION__,i,pVPUHalContext->_stVPUStream[i].eDecodertype,pVPUHalContext->_stVPUDecMode.u8DecMod);
2962         }
2963 
2964         if ((E_VPU_EX_DECODER_HVD == pVPUHalContext->_stVPUStream[i].eDecodertype)
2965 #ifdef VDEC3
2966             ||(E_VPU_EX_DECODER_EVD == pVPUHalContext->_stVPUStream[i].eDecodertype)
2967 #endif
2968             ||(TRUE == bMVDTriggerHVD)
2969         )
2970         {
2971             u8UseCnt++;
2972         }
2973     }
2974 
2975     VPU_MSG_DBG("HVD u8UseCnt=%d\n", u8UseCnt);
2976 
2977     if (u8UseCnt != 0)
2978     {
2979         return TRUE;
2980     }
2981     else
2982     {
2983         return FALSE;
2984     }
2985 }
2986 
2987 #ifdef VDEC3
HAL_VPU_EX_EVDInUsed(void)2988 MS_BOOL HAL_VPU_EX_EVDInUsed(void)
2989 {
2990     MS_U8 i;
2991     MS_U8 u8UseCnt = 0;
2992 
2993     for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
2994     {
2995         if (E_VPU_EX_DECODER_EVD == pVPUHalContext->_stVPUStream[i].eDecodertype)
2996         {
2997             u8UseCnt++;
2998         }
2999     }
3000 
3001     VPU_MSG_DBG("EVD u8UseCnt=%d\n", u8UseCnt);
3002 
3003     if (u8UseCnt != 0)
3004     {
3005         return TRUE;
3006     }
3007     else
3008     {
3009         return FALSE;
3010     }
3011 }
3012 
3013 #if SUPPORT_G2VP9 && defined(VDEC3)
HAL_VPU_EX_G2VP9InUsed(void)3014 MS_BOOL HAL_VPU_EX_G2VP9InUsed(void)
3015 {
3016     MS_U8 i;
3017     MS_U8 u8UseCnt = 0;
3018 
3019     for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
3020     {
3021         if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[i].eDecodertype)
3022         {
3023             u8UseCnt++;
3024         }
3025     }
3026 
3027     VPU_MSG_DBG("G2 VP9 u8UseCnt=%d\n", u8UseCnt);
3028 
3029     if (u8UseCnt != 0)
3030     {
3031         return TRUE;
3032     }
3033     else
3034     {
3035         return FALSE;
3036     }
3037 }
3038 #endif
3039 #endif
3040 
3041 //-----------------------------------------------------------------------------
3042 /// @brief \b Function \b Name: MDrv_HVD_EX_SetDbgLevel()
3043 /// @brief \b Function \b Description:  Set debug level
3044 /// @param -elevel \b IN : debug level
3045 //-----------------------------------------------------------------------------
HAL_VPU_EX_SetDbgLevel(VPU_EX_UartLevel eLevel)3046 void HAL_VPU_EX_SetDbgLevel(VPU_EX_UartLevel eLevel)
3047 {
3048     VPRINTF("%s eLevel=0x%x\n", __FUNCTION__, eLevel);
3049 
3050     switch (eLevel)
3051     {
3052         case E_VPU_EX_UART_LEVEL_ERR:
3053         {
3054             u32VpuUartCtrl = E_VPU_UART_CTRL_ERR;
3055             break;
3056         }
3057         case E_VPU_EX_UART_LEVEL_INFO:
3058         {
3059             u32VpuUartCtrl = E_VPU_UART_CTRL_INFO | E_VPU_UART_CTRL_ERR;
3060             break;
3061         }
3062         case E_VPU_EX_UART_LEVEL_DBG:
3063         {
3064             u32VpuUartCtrl = E_VPU_UART_CTRL_DBG | E_VPU_UART_CTRL_ERR | E_VPU_UART_CTRL_INFO;
3065             break;
3066         }
3067         case E_VPU_EX_UART_LEVEL_TRACE:
3068         {
3069             u32VpuUartCtrl = E_VPU_UART_CTRL_TRACE | E_VPU_UART_CTRL_ERR | E_VPU_UART_CTRL_INFO | E_VPU_UART_CTRL_DBG;
3070             break;
3071         }
3072         case E_VPU_EX_UART_LEVEL_FW:
3073         {
3074             u32VpuUartCtrl = E_VPU_UART_CTRL_DISABLE;
3075             break;
3076         }
3077         default:
3078         {
3079             u32VpuUartCtrl = E_VPU_UART_CTRL_DISABLE;
3080             break;
3081         }
3082     }
3083 }
3084 
HAL_VPU_EX_GetFWVer(MS_U32 u32Id,VPU_EX_FWVerType eVerType)3085 MS_U32 HAL_VPU_EX_GetFWVer(MS_U32 u32Id, VPU_EX_FWVerType eVerType)
3086 {
3087     HVD_Return eCtrlRet = E_HVD_RETURN_FAIL;
3088     MS_U32 u32CmdArg = (MS_U32)eVerType;
3089     MS_U32 u32Version = 0xFFFFFFFF;
3090     eCtrlRet = HAL_HVD_EX_SetCmd(u32Id, E_DUAL_VERSION, u32CmdArg);
3091     if (E_HVD_RETURN_SUCCESS != eCtrlRet)
3092     {
3093         VPU_MSG_ERR("E_DUAL_VERSION NG eCtrlRet=%x\n", eCtrlRet);
3094         return u32Version;
3095     }
3096 
3097     MS_BOOL bRet = false;
3098     MS_U32 u32TimeOut = 0xFFFFFFFF;
3099 
3100     while(--u32TimeOut)
3101     {
3102         if(HAL_VPU_EX_MBoxRdy(VPU_RISC_MBOX0))
3103         {
3104             bRet = HAL_VPU_EX_MBoxRead(VPU_RISC_MBOX0, &u32Version);
3105             if (false == bRet)
3106             {
3107                 VPU_MSG_ERR("E_DUAL_VERSION NG bRet=%x\n", bRet);
3108                 return u32Version;
3109             }
3110 
3111             _VPU_WriteWordMask(  VPU_REG_RISC_MBOX_CLR , VPU_REG_RISC_MBOX0_CLR  , VPU_REG_RISC_MBOX0_CLR);
3112             VPU_MSG_DBG("E_DUAL_VERSION arg=%x u32Version = 0x%x\n", u32CmdArg, u32Version);
3113             return u32Version;
3114         }
3115     }
3116 
3117     VPU_MSG_ERR("get E_DUAL_VERSION=%x timeout", eVerType);
3118 
3119     return u32Version;
3120 }
3121 
HAL_VPU_EX_NotSupportDS(void)3122 MS_BOOL HAL_VPU_EX_NotSupportDS(void)
3123 {
3124     return FALSE;
3125 }
3126 
3127 //-----------------------------------------------------------------------------
3128 /// @brief \b Function \b Name: HAL_VPU_EX_MIU1BASE()
3129 /// @brief \b Function \b Description:  Get VPU MIU base address
3130 /// @return - vpu MIU1 base
3131 //-----------------------------------------------------------------------------
HAL_VPU_EX_MIU1BASE(void)3132 MS_VIRT HAL_VPU_EX_MIU1BASE(void)
3133 {
3134     return VPU_MIU1BASE_ADDR;
3135 }
3136 
3137 
HAL_VPU_EX_GetSHMAddr(void)3138 MS_VIRT HAL_VPU_EX_GetSHMAddr(void)
3139 {
3140     if(pVPUHalContext->bEnableVPUSecureMode == FALSE)
3141     {
3142         return 0;
3143     }
3144     return pVPUHalContext->u32VPUSHMAddr;
3145 }
HAL_VPU_EX_EnableSecurityMode(MS_BOOL enable)3146 MS_BOOL HAL_VPU_EX_EnableSecurityMode(MS_BOOL enable)
3147 {
3148     pVPUHalContext->bEnableVPUSecureMode = enable;
3149     return TRUE;
3150 }
3151 
HAL_VPU_EX_CHIP_Capability(void * pHWCap)3152 MS_BOOL HAL_VPU_EX_CHIP_Capability(void* pHWCap)
3153 {
3154     ((VDEC_HwCap*)pHWCap)->u8Cap_Support_Decoder_Num = 2;
3155 
3156     ((VDEC_HwCap*)pHWCap)->bCap_Support_MPEG2 = TRUE;
3157     ((VDEC_HwCap*)pHWCap)->bCap_Support_H263 = TRUE;
3158     ((VDEC_HwCap*)pHWCap)->bCap_Support_MPEG4 = TRUE;
3159     ((VDEC_HwCap*)pHWCap)->bCap_Support_DIVX311 = TRUE;
3160     ((VDEC_HwCap*)pHWCap)->bCap_Support_DIVX412 = TRUE;
3161     ((VDEC_HwCap*)pHWCap)->bCap_Support_FLV = TRUE;
3162     ((VDEC_HwCap*)pHWCap)->bCap_Support_VC1ADV = TRUE;
3163     ((VDEC_HwCap*)pHWCap)->bCap_Support_VC1MAIN = TRUE;
3164 
3165     ((VDEC_HwCap*)pHWCap)->bCap_Support_RV8 = TRUE;
3166     ((VDEC_HwCap*)pHWCap)->bCap_Support_RV9 = TRUE;
3167     ((VDEC_HwCap*)pHWCap)->bCap_Support_H264 = TRUE;
3168     ((VDEC_HwCap*)pHWCap)->bCap_Support_AVS = TRUE;
3169     ((VDEC_HwCap*)pHWCap)->bCap_Support_MJPEG = TRUE;
3170     ((VDEC_HwCap*)pHWCap)->bCap_Support_MVC = TRUE;
3171     ((VDEC_HwCap*)pHWCap)->bCap_Support_VP8 = TRUE;
3172     ((VDEC_HwCap*)pHWCap)->bCap_Support_HEVC = TRUE;
3173     ((VDEC_HwCap*)pHWCap)->bCap_Support_VP9 = TRUE;
3174     ((VDEC_HwCap*)pHWCap)->bCap_Support_AVS_PLUS = TRUE;
3175 
3176     return TRUE;
3177 }
3178 
3179 //-----------------------------------------------------------------------------
3180 /// @brief \b Function \b Name: HAL_VPU_EX_GetCodecCapInfo()
3181 /// @brief \b Function \b Description:  Get chip codec capability  (for vudu)
3182 /// @return - success/fail
3183 //-----------------------------------------------------------------------------
HAL_VPU_EX_GetCodecCapInfo(int eCodecType,VDEC_EX_CODEC_CAP_INFO * pCodecCapInfo)3184 MS_BOOL HAL_VPU_EX_GetCodecCapInfo( int eCodecType, VDEC_EX_CODEC_CAP_INFO *pCodecCapInfo)
3185 {
3186 #define MAX_CAPABILITY_INFO_NUM 8
3187 #define MAX_CODEC_TYPE_NUM 18
3188 
3189     unsigned int capability[MAX_CODEC_TYPE_NUM][MAX_CAPABILITY_INFO_NUM] =
3190     {
3191             //width, height , frmrate,                                                 profile,                                        level,                                          version                          reserved1   reserved2
3192             {    0,    0,      0,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_NONE
3193             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_MP2_MAIN,         E_VDEC_EX_CODEC_LEVEL_MP2_HIGH,     E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_MPEG2
3194             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_H263_BASELINE,    E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_H263_1,       0,        0},//E_HVD_EX_CODEC_TYPE_H263
3195             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_MP4_ASP,          E_VDEC_EX_CODEC_LEVEL_MP4_L5,       E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_MPEG4
3196             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_DIVX_311,     0,        0},//E_HVD_EX_CODEC_TYPE_DIVX311
3197             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_DIVX_6,       0,        0},//E_HVD_EX_CODEC_TYPE_DIVX412
3198             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_FLV_1,        0,        0},//E_HVD_EX_CODEC_TYPE_FLV
3199             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_VC1_AP,           E_VDEC_EX_CODEC_LEVEL_VC1_L3,       E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_VC1_ADV
3200             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_RCV_MAIN,         E_VDEC_EX_CODEC_LEVEL_RCV_HIGH,     E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_VC1_MAIN (RCV)
3201             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_RV8
3202             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_RV9
3203             { 3840, 2160,     30,     E_VDEC_EX_CODEC_PROFILE_H264_HIP,         E_VDEC_EX_CODEC_LEVEL_H264_5,       E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_H264
3204             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_AVS_BROADCASTING, E_VDEC_EX_CODEC_LEVEL_AVS_6010860,  E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_AVS
3205             { 1920, 1080,     30,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_MJPEG
3206             { 1920, 1080,     30,     E_VDEC_EX_CODEC_PROFILE_H264_HIP,         E_VDEC_EX_CODEC_LEVEL_H264_5,       E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_MVC
3207             { 1920, 1080,     60,     E_VDEC_EX_CODEC_PROFILE_NONE,             E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_VP8
3208             { 4096, 2160,     60,     E_VDEC_EX_CODEC_PROFILE_H265_MAIN_10,     E_VDEC_EX_CODEC_LEVEL_H265_5_1_HT,  E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_HEVC
3209             { 4096, 2160,     60,     E_VDEC_EX_CODEC_PROFILE_VP9_2,            E_VDEC_EX_CODEC_LEVEL_NONE,         E_VDEC_EX_CODEC_VERSION_NONE,         0,        0},//E_HVD_EX_CODEC_TYPE_VP9
3210     };
3211 
3212     if(eCodecType < MAX_CODEC_TYPE_NUM)
3213     {
3214         pCodecCapInfo->u16CodecCapWidth     = capability[eCodecType][0];
3215         pCodecCapInfo->u16CodecCapHeight    = capability[eCodecType][1];
3216         pCodecCapInfo->u8CodecCapFrameRate  = capability[eCodecType][2];
3217         pCodecCapInfo->u8CodecCapProfile    = capability[eCodecType][3];
3218         pCodecCapInfo->u8CodecCapLevel      = capability[eCodecType][4];
3219         pCodecCapInfo->u8CodecCapVersion    = capability[eCodecType][5];
3220         return TRUE;
3221     }
3222     else
3223     {
3224         return FALSE;
3225     }
3226 }
3227 
3228 
3229 
3230 
3231 #ifdef VDEC3
HAL_VPU_EX_GetBBUId(MS_U32 u32Id,VPU_EX_TaskInfo * pTaskInfo,MS_BOOL bIsNstreamMode)3232 MS_U32 HAL_VPU_EX_GetBBUId(MS_U32 u32Id, VPU_EX_TaskInfo *pTaskInfo, MS_BOOL bIsNstreamMode)
3233 {
3234     MS_U32 i, max_bbu_cnt;
3235     MS_U32 retBBUId = HAL_VPU_INVALID_BBU_ID;
3236 
3237     if(pTaskInfo == NULL)
3238         return retBBUId;
3239 
3240     BBU_STATE *bbu_state;
3241     SLQ_STATE *slq_state = &pVPUHalContext->stMVD_SLQ_STATE[0];
3242     MS_U8 u8TaskId = HAL_VPU_EX_GetTaskId(u32Id);
3243 
3244     MS_BOOL bTSP = (pTaskInfo->eSrcType == E_VPU_EX_INPUT_TSP);
3245 
3246     pVPUHalContext->u8HALId[u8TaskId] = pTaskInfo->u8HalId;
3247 
3248 /*    HVD_EX_MSG_ERR("[%d] DecType=0x%x \n", u32Id & 0xFF, pTaskInfo->eDecType);
3249     for(i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3250         HVD_EX_MSG_ERR("slq_state[%d] u32Used=0x%x bTSP=%x bUsedbyMVD=%x\n",i,slq_state[i].u32Used,slq_state[i].bTSP,slq_state[i].bUsedbyMVD);
3251 
3252     for(i = 0; i < MAX_EVD_BBU_COUNT; i++)
3253         HVD_EX_MSG_ERR("EVD_BBU_state[%d] u32Used=0x%x bTSP=%x\n",i,pVPUHalContext->stEVD_BBU_STATE[i].u32Used,pVPUHalContext->stEVD_BBU_STATE[i].bTSP);
3254 
3255     for(i = 0; i < MAX_HVD_BBU_COUNT; i++)
3256         HVD_EX_MSG_ERR("HVD_BBU_state[%d] u32Used=0x%x bTSP=%x\n",i,pVPUHalContext->stHVD_BBU_STATE[i].u32Used,pVPUHalContext->stHVD_BBU_STATE[i].bTSP);
3257 */
3258 #if 1
3259     if(pTaskInfo->eDecType == E_VPU_EX_DECODER_MVD) // MVD case
3260     {
3261         max_bbu_cnt = MAX_MVD_SLQ_COUNT;
3262         if (bTSP)
3263         {
3264             if ((u8TaskId < MAX_MVD_SLQ_COUNT) && (slq_state[u8TaskId].u32Used == 0))
3265             {
3266                 slq_state[u8TaskId].u32Used |= (1 << u8TaskId); // Record the HVD use the TSP parser
3267                 slq_state[u8TaskId].bTSP = TRUE;
3268                 slq_state[u8TaskId].bUsedbyMVD = TRUE;
3269                 return u8TaskId;
3270             }
3271         }
3272         else
3273         {
3274             MS_U32 shared_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3275             MS_U32 avaliable_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3276             for (i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3277             {
3278                 if (slq_state[i].u32Used != 0)
3279                 {
3280                     if (shared_bbu_idx == HAL_VPU_INVALID_BBU_ID && slq_state[i].bTSP == FALSE)
3281                     {
3282                         shared_bbu_idx = i; // recored the first used MM bbu for sharing
3283                     }
3284                 }
3285                 else if (avaliable_bbu_idx == HAL_VPU_INVALID_BBU_ID)
3286                 {
3287                     avaliable_bbu_idx = i; // recored the first empty bbu
3288                 }
3289             }
3290 
3291             if (bIsNstreamMode && shared_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // In Nstream mode, first priority is sharing bbu
3292                 slq_state[shared_bbu_idx].u32Used |= (1 << u8TaskId);
3293                 slq_state[shared_bbu_idx].bTSP = FALSE;
3294                 slq_state[shared_bbu_idx].bUsedbyMVD = TRUE;
3295                 return shared_bbu_idx;
3296             }
3297             else if (slq_state[u8TaskId].u32Used == FALSE && u8TaskId < max_bbu_cnt) { // 2nd priority is task id
3298                 slq_state[u8TaskId].u32Used |= (1 << u8TaskId);
3299                 slq_state[u8TaskId].bTSP = FALSE;
3300                 slq_state[u8TaskId].bUsedbyMVD = TRUE;
3301                 return u8TaskId;
3302             }
3303             else if (avaliable_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // 3rd priority is avaliable bbu id
3304                 slq_state[avaliable_bbu_idx].u32Used |= (1 << u8TaskId);
3305                 slq_state[avaliable_bbu_idx].bTSP = FALSE;
3306                 slq_state[avaliable_bbu_idx].bUsedbyMVD = TRUE;
3307                 return avaliable_bbu_idx;
3308             }
3309             else {
3310                 VPU_MSG_ERR("ERROR!!! can't get avaliable BBU ID taskId=%d at %s\n", u8TaskId, __FUNCTION__);
3311             }
3312         }
3313     }
3314 #if SUPPORT_G2VP9
3315     else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_G2VP9) // G2_VP9 case
3316     {
3317         // G2_VP9 don't have the concept of BBU, so we don't need to record the hardware BBU usage situation
3318         // Don't care the return value, G2_VP9 will not use it.
3319         return 0;
3320     }
3321 #endif
3322     else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_VP8) // VP8 case
3323     {
3324         // G2_VP8 always use the same BBU, so we don't need to record the hardware BBU usage situation
3325         // Don't care the return value, VP8 will not use it.
3326         return 0;
3327     }
3328     else
3329     {
3330         switch (pTaskInfo->eDecType)
3331         {
3332             case E_VPU_EX_DECODER_EVD:
3333                 max_bbu_cnt = MAX_EVD_BBU_COUNT;
3334                 bbu_state = &pVPUHalContext->stEVD_BBU_STATE[0];
3335                 break;
3336             case E_VPU_EX_DECODER_HVD:
3337             case E_VPU_EX_DECODER_RVD:
3338             case E_VPU_EX_DECODER_MVC:
3339             default:
3340                 max_bbu_cnt = MAX_HVD_BBU_COUNT;
3341                 bbu_state = &pVPUHalContext->stHVD_BBU_STATE[0];
3342                 break;
3343         }
3344 
3345         // FIXME: TSP assume bbu id = u8TaskId, so it does not support N decode. Use the same logic with MM to support it
3346         if (bTSP)
3347         {
3348             if ((u8TaskId < max_bbu_cnt) && (bbu_state[u8TaskId].u32Used == 0) && (slq_state[u8TaskId].u32Used == 0))
3349             {
3350                 bbu_state[u8TaskId].u32Used |= (1 << u8TaskId);
3351                 bbu_state[u8TaskId].bTSP = TRUE;
3352                 slq_state[u8TaskId].u32Used |= (1 << u8TaskId); // Record the HVD use the TSP parser
3353                 slq_state[u8TaskId].bTSP = TRUE;
3354                 slq_state[u8TaskId].bUsedbyMVD = FALSE;
3355                 return u8TaskId;
3356             }
3357         }
3358         else
3359         {
3360             MS_U32 shared_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3361             MS_U32 avaliable_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3362             for (i = 0; i < max_bbu_cnt; i++)
3363             {
3364                 if (shared_bbu_idx == HAL_VPU_INVALID_BBU_ID && bbu_state[i].u32Used != 0)
3365                 {
3366                     if (bbu_state[i].bTSP == FALSE)
3367                     {
3368                         shared_bbu_idx = i;
3369                     }
3370                 }
3371                 else if (avaliable_bbu_idx == HAL_VPU_INVALID_BBU_ID)
3372                 {
3373                     avaliable_bbu_idx = i;
3374                 }
3375             }
3376             if (bIsNstreamMode && shared_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // // In Nstream mode, first priority is sharing bbu
3377                 bbu_state[shared_bbu_idx].u32Used |= (1 << u8TaskId);
3378                 return shared_bbu_idx;
3379             }
3380             else if (bbu_state[u8TaskId].u32Used == FALSE && u8TaskId < max_bbu_cnt) { // 2nd priority is task id
3381                 bbu_state[u8TaskId].u32Used |= (1 << u8TaskId);
3382                 return u8TaskId;
3383             }
3384             else if (avaliable_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // 3rd priority is avaliable bbu id
3385                 bbu_state[avaliable_bbu_idx].u32Used |= (1 << u8TaskId);
3386                 return avaliable_bbu_idx;
3387             }
3388             else {
3389                 VPU_MSG_ERR("ERROR!!! can't get avaliable BBU ID taskId=%d at %s\n", u8TaskId, __FUNCTION__);
3390             }
3391         }
3392     }
3393 #else // The following source code is wiser selecting BBU id. Howerver, it need HW to support and we mark it temporarily.
3394     MS_U32 j;
3395     MS_BOOL Got = FALSE;
3396     if(pTaskInfo->eDecType == E_VPU_EX_DECODER_MVD) // MVD case
3397     {
3398         for (i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3399         {
3400             if(slq_state[i].u32Used != 0)
3401             {
3402                 if(!bTSP && slq_state[i].bTSP == FALSE) // MVD non-first MM case
3403                 {
3404                         retBBUId = i;
3405                         slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3406                         slq_state[retBBUId].bTSP = bTSP;
3407                         slq_state[retBBUId].bUsedbyMVD = TRUE;
3408                         return retBBUId;
3409                 }
3410             }
3411             else if(!Got && slq_state[i].u32Used == 0) // MVD first MM or TS case
3412             {
3413                 if(i < MAX_EVD_BBU_COUNT) // Trend to select used EVD BBU id
3414                 {
3415                     if(pVPUHalContext->stEVD_BBU_STATE[i].u32Used != 0 && pVPUHalContext->stEVD_BBU_STATE[i].bTSP == FALSE)
3416                     {
3417                         Got = TRUE;
3418                         retBBUId = i;
3419                     }
3420                 }
3421 
3422                 if(!Got && i < MAX_HVD_BBU_COUNT) // Trend to select used HVD BBU id
3423                 {
3424                     if(pVPUHalContext->stHVD_BBU_STATE[i].u32Used != 0 && pVPUHalContext->stHVD_BBU_STATE[i].bTSP == FALSE)
3425                     {
3426                         Got = TRUE;
3427                         retBBUId = i;
3428                     }
3429                 }
3430 
3431                  if(!Got && retBBUId == HAL_VPU_INVALID_BBU_ID) // if no used EVD BBU id, select the first BBU_ID
3432                     retBBUId = i;
3433             }
3434         }
3435         if(retBBUId != HAL_VPU_INVALID_BBU_ID)
3436         {
3437             slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3438             slq_state[retBBUId].bTSP = bTSP;
3439             slq_state[retBBUId].bUsedbyMVD = TRUE;
3440         }
3441     }
3442     #if SUPPORT_G2VP9
3443     else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_G2VP9) // G2_VP9 case
3444     {
3445         // G2_VP9 don't have the concept of BBU, so we don't need to record the hardware BBU usage situation
3446         // Don't care the return value, G2_VP9 will not use it.
3447         return 0;
3448     }
3449     #endif
3450     else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_VP8) // VP8 case
3451     {
3452         // G2_VP8 always use the same BBU, so we don't need to record the hardware BBU usage situation
3453         // Don't care the return value, VP8 will not use it.
3454         return 0;
3455     }
3456     else // HVD/EVD case
3457     {
3458         switch (pTaskInfo->eDecType)
3459         {
3460             case E_VPU_EX_DECODER_EVD:
3461             case E_VPU_EX_DECODER_G2VP9:
3462                 max_bbu_cnt = MAX_EVD_BBU_COUNT;
3463                 bbu_state = &pVPUHalContext->stEVD_BBU_STATE[0];
3464                 break;
3465             case E_VPU_EX_DECODER_HVD:
3466             case E_VPU_EX_DECODER_RVD:
3467             case E_VPU_EX_DECODER_MVC:
3468             default:
3469                 max_bbu_cnt = MAX_HVD_BBU_COUNT;
3470                 bbu_state = &pVPUHalContext->stHVD_BBU_STATE[0];
3471                 break;
3472         }
3473 
3474         for (i = 0; i < max_bbu_cnt; i++)
3475         {
3476             if(bbu_state[i].u32Used != 0)
3477             {
3478                 if(!bTSP && bbu_state[i].bTSP == FALSE) // HVD/EVD non-first MM case
3479                 {
3480                         retBBUId = i;
3481                         bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3482                         bbu_state[retBBUId].bTSP = bTSP;
3483                         return retBBUId;
3484                 }
3485             }
3486             else if(bbu_state[i].u32Used == 0) // HVD/EVD first MM or TS case
3487             {
3488                 if(i < MAX_MVD_SLQ_COUNT)
3489                 {
3490                     if(!bTSP) //HVD/EVD first MM case
3491                     {
3492                         if( slq_state[i].u32Used != 0 && slq_state[i].bUsedbyMVD== TRUE) // HVD/EVD MM will trend to select used MVD SLQ id
3493                         {
3494                             retBBUId = i;
3495                             bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3496                             bbu_state[retBBUId].bTSP = bTSP;
3497                             return retBBUId;
3498                         }
3499 
3500                         if(retBBUId == HAL_VPU_INVALID_BBU_ID) // if no used MVD SLQ id, select the first BBU_ID
3501                             retBBUId = i;
3502                     }
3503                     else if(slq_state[i].u32Used == 0) //HVD/EVD TSP case, just find a empty slq id
3504                     {
3505                         retBBUId = i;
3506                         bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3507                         bbu_state[retBBUId].bTSP = bTSP;
3508                         slq_state[retBBUId].bUsedbyMVD = FALSE;
3509                         slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3510                         slq_state[retBBUId].bTSP = bTSP;
3511                         return retBBUId;
3512                     }
3513                 }
3514             }
3515         }
3516         if(retBBUId != HAL_VPU_INVALID_BBU_ID)
3517         {
3518             bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3519             bbu_state[retBBUId].bTSP = bTSP;
3520             if(bTSP)
3521             {
3522                 slq_state[retBBUId].bUsedbyMVD = FALSE;
3523                 slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3524                 slq_state[retBBUId].bTSP = bTSP;
3525             }
3526         }
3527     }
3528 #endif
3529     return retBBUId;
3530 }
3531 
HAL_VPU_EX_FreeBBUId(MS_U32 u32Id,MS_U32 u32BBUId,VPU_EX_TaskInfo * pTaskInfo)3532 MS_BOOL HAL_VPU_EX_FreeBBUId(MS_U32 u32Id, MS_U32 u32BBUId, VPU_EX_TaskInfo *pTaskInfo)
3533 {
3534     MS_U32 max_bbu_cnt;
3535     BBU_STATE *bbu_state;
3536     SLQ_STATE *slq_state = &pVPUHalContext->stMVD_SLQ_STATE[0];
3537 
3538     if(pTaskInfo == NULL)
3539         return FALSE;
3540     MS_U8 u8TaskId = HAL_VPU_EX_GetTaskId(u32Id);
3541     MS_BOOL bTSP = (pTaskInfo->eSrcType == E_VPU_EX_INPUT_TSP);
3542 
3543     HVD_EX_MSG_DBG("[%d] DecType=0x%x \n", (int)(u32Id & 0xFF), pTaskInfo->eDecType);
3544 /*  MS_U32 i;
3545     for(i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3546         HVD_EX_MSG_ERR("slq_state[%d] u32Used=0x%x bTSP=%x bUsedbyMVD=%x\n",i,slq_state[i].u32Used,slq_state[i].bTSP,slq_state[i].bUsedbyMVD);
3547 
3548     for(i = 0; i < MAX_EVD_BBU_COUNT; i++)
3549         HVD_EX_MSG_ERR("EVD_BBU_state[%d] u32Used=0x%x bTSP=%x\n",i,pVPUHalContext->stEVD_BBU_STATE[i].u32Used,pVPUHalContext->stEVD_BBU_STATE[i].bTSP);
3550 
3551     for(i = 0; i < MAX_HVD_BBU_COUNT; i++)
3552         HVD_EX_MSG_ERR("HVD_BBU_state[%d] u32Used=0x%x bTSP=%x\n",i,pVPUHalContext->stHVD_BBU_STATE[i].u32Used,pVPUHalContext->stHVD_BBU_STATE[i].bTSP);
3553 */
3554     if(pTaskInfo->eDecType == E_VPU_EX_DECODER_MVD) // MVD case
3555     {
3556         // TO DO
3557         if(u32BBUId < MAX_MVD_SLQ_COUNT)
3558         {
3559             slq_state[u32BBUId].u32Used &= ~(1 << u8TaskId); // Record the HVD use the TSP parser
3560             slq_state[u32BBUId].bTSP = FALSE;
3561             slq_state[u32BBUId].bUsedbyMVD = FALSE;
3562             return TRUE;
3563         }
3564     }
3565 #if SUPPORT_G2VP9
3566     else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_G2VP9) // G2_VP9 case
3567     {
3568         // G2_VP9 don't have the concept of BBU, so we don't need to record the hardware BBU usage situation
3569         return TRUE;
3570     }
3571 #endif
3572     else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_VP8) // VP8 case
3573     {
3574         // G2_VP8 always use the same BBU, so we don't need to record the hardware BBU usage situation
3575         return TRUE;
3576     }
3577     else
3578     {
3579         switch (pTaskInfo->eDecType)
3580         {
3581             case E_VPU_EX_DECODER_EVD:
3582                 max_bbu_cnt = MAX_EVD_BBU_COUNT;
3583                 bbu_state = &pVPUHalContext->stEVD_BBU_STATE[0];
3584                 break;
3585             case E_VPU_EX_DECODER_HVD:
3586             case E_VPU_EX_DECODER_RVD:
3587             case E_VPU_EX_DECODER_MVC:
3588             default:
3589                 max_bbu_cnt = MAX_HVD_BBU_COUNT;
3590                 bbu_state = &pVPUHalContext->stHVD_BBU_STATE[0];
3591                 break;
3592         }
3593 
3594         if (u32BBUId < max_bbu_cnt)
3595         {
3596             bbu_state[u32BBUId].u32Used &= ~(1 << u8TaskId);
3597             bbu_state[u32BBUId].bTSP = FALSE;
3598             if (bTSP)
3599             {
3600                 slq_state[u32BBUId].u32Used &= ~(1 << u8TaskId); // Record the HVD use the TSP parser
3601                 slq_state[u32BBUId].bTSP = FALSE;
3602                 slq_state[u32BBUId].bUsedbyMVD = FALSE;
3603             }
3604             return TRUE;
3605         }
3606     }
3607     return FALSE;
3608 }
HAL_VPU_EX_GetVBBUVacancy(MS_VIRT u32VBBUAddr)3609 MS_U32 HAL_VPU_EX_GetVBBUVacancy(MS_VIRT u32VBBUAddr)
3610 {
3611     VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3612 
3613     if (CHECK_NULL_PTR(pstVBBU))
3614         return 0;
3615     MS_U32 u32WrPtr = pstVBBU->u32WrPtr;
3616     MS_U32 u32RdPtr = pstVBBU->u32RdPtr;
3617     MS_U32 u32Vacancy = 0;
3618 
3619     if (u32WrPtr == u32RdPtr)
3620     {
3621         u32Vacancy = MAX_VDEC_VBBU_ENTRY_COUNT;
3622     }
3623     else if (u32WrPtr > u32RdPtr)
3624     {
3625         u32Vacancy = MAX_VDEC_VBBU_ENTRY_COUNT - (u32WrPtr - u32RdPtr);
3626     }
3627     else
3628     {
3629         u32Vacancy = u32RdPtr - u32WrPtr - 1;
3630     }
3631 
3632     return u32Vacancy;
3633 }
3634 
HAL_VPU_EX_GetInputQueueNum(MS_U32 u32Id)3635 MS_U32 HAL_VPU_EX_GetInputQueueNum(MS_U32 u32Id)
3636 {
3637     return MAX_VDEC_VBBU_ENTRY_COUNT;
3638 }
3639 
HAL_VPU_EX_GetESReadPtr(MS_U32 u32Id,MS_VIRT u32VBBUAddr)3640 MS_VIRT HAL_VPU_EX_GetESReadPtr(MS_U32 u32Id, MS_VIRT u32VBBUAddr)
3641 {
3642     VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3643     #if SUPPORT_G2VP9
3644     MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
3645     #endif
3646 
3647     if (CHECK_NULL_PTR(pstVBBU))
3648         return FALSE;
3649     MsOS_ReadMemory();
3650     VDEC_VBBU_Entry *stEntry = (VDEC_VBBU_Entry *) &pstVBBU->stEntry[pstVBBU->u32RdPtr];
3651 
3652 //    ALOGE("JJJ1: %d %d %d", pstVBBU->u32RdPtr, pstVBBU->u32WrPtr, stEntry->u32Offset);
3653     if (pstVBBU->u32RdPtr == pstVBBU->u32WrPtr)
3654     {
3655         return HAL_VPU_EX_GetESWritePtr(u32Id, u32VBBUAddr);
3656     }
3657     else
3658     {
3659         #if SUPPORT_G2VP9
3660         if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype)
3661         {
3662             if (stEntry->u32Offset == 0)
3663                 return 0;
3664             else
3665                 return stEntry->u32Offset - pVPUHalContext->u32BitstreamAddress[u8OffsetIdx];
3666         }
3667         else
3668         #endif
3669         {
3670             return stEntry->u32Offset;
3671         }
3672     }
3673 }
3674 
HAL_VPU_EX_GetESWritePtr(MS_U32 u32Id,MS_VIRT u32VBBUAddr)3675 MS_VIRT HAL_VPU_EX_GetESWritePtr(MS_U32 u32Id, MS_VIRT u32VBBUAddr)
3676 {
3677     VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3678     VDEC_VBBU_Entry *stEntry;
3679     #if SUPPORT_G2VP9
3680     MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
3681     #endif
3682 
3683     MsOS_ReadMemory();
3684     if (CHECK_NULL_PTR(pstVBBU))
3685         return 0;
3686     MS_U32 u32WrPtr = pstVBBU->u32WrPtr;
3687 
3688     if (u32WrPtr == 0)
3689         u32WrPtr = MAX_VDEC_VBBU_ENTRY_COUNT;
3690     else
3691         u32WrPtr--;
3692 
3693     stEntry = (VDEC_VBBU_Entry*) &pstVBBU->stEntry[u32WrPtr];
3694 
3695     //ALOGE("JJJ2: %d %d %d %d", pstVBBU->u32RdPtr, u32WrPtr, stEntry->u32Offset, stEntry->u32Length);
3696     #if SUPPORT_G2VP9
3697     if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype)
3698     {
3699         if (stEntry->u32Offset == 0)
3700             return 0;
3701         else
3702             return stEntry->u32Offset + stEntry->u32Length - pVPUHalContext->u32BitstreamAddress[u8OffsetIdx];
3703     }
3704     else
3705     #endif
3706     {
3707         return stEntry->u32Offset + stEntry->u32Length;
3708     }
3709 }
3710 
HAL_VPU_EX_Push2VBBU(MS_U32 u32Id,HAL_VPU_EX_PacketInfo * stVpuPkt,MS_VIRT u32VBBUAddr)3711 MS_BOOL HAL_VPU_EX_Push2VBBU(MS_U32 u32Id, HAL_VPU_EX_PacketInfo *stVpuPkt, MS_VIRT u32VBBUAddr)
3712 {
3713     VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3714     #if SUPPORT_G2VP9
3715     MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
3716     #endif
3717 
3718     if (CHECK_NULL_PTR(pstVBBU) || CHECK_NULL_PTR(stVpuPkt))
3719         return FALSE;
3720     MsOS_ReadMemory();
3721     VDEC_VBBU_Entry *stEntry = (VDEC_VBBU_Entry*) &pstVBBU->stEntry[pstVBBU->u32WrPtr];
3722     MS_U32 u32NewWrPtr;
3723 
3724     u32NewWrPtr = pstVBBU->u32WrPtr + 1;
3725     if (u32NewWrPtr == (MAX_VDEC_VBBU_ENTRY_COUNT + 1))
3726     {
3727         u32NewWrPtr = 0;
3728     }
3729 
3730     if (u32NewWrPtr == pstVBBU->u32RdPtr) return FALSE;
3731 
3732     stEntry->u32Offset = stVpuPkt->u32Offset;
3733 
3734     #if SUPPORT_G2VP9
3735     if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype)
3736     {
3737         stEntry->u32Offset += pVPUHalContext->u32BitstreamAddress[u8OffsetIdx];
3738     }
3739     #endif
3740 
3741     stEntry->u32Length = stVpuPkt->u32Length;
3742     stEntry->u64TimeStamp = stVpuPkt->u64TimeStamp;
3743     stEntry->u32ID_H = stVpuPkt->u32ID_H;
3744     stEntry->u32ID_L = stVpuPkt->u32ID_L;
3745 
3746     MsOS_FlushMemory();//make sure vbbu offset/length already flushed to memory before vbbu wptr advancing
3747 
3748     pstVBBU->u32WrPtr = u32NewWrPtr;
3749 
3750     //ALOGE("JJJ3: %d", pstVBBU->u32WrPtr);
3751 
3752     MsOS_FlushMemory();
3753 
3754     return TRUE;
3755 }
3756 
HAL_VPU_EX_IsVBBUEmpty(MS_VIRT u32VBBUAddr)3757 MS_BOOL HAL_VPU_EX_IsVBBUEmpty(MS_VIRT u32VBBUAddr)
3758 {
3759     VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3760 
3761     if (CHECK_NULL_PTR(pstVBBU))
3762         return FALSE;
3763     return pstVBBU->u32RdPtr == pstVBBU->u32WrPtr;
3764 }
3765 
3766 ///-----------------------------------------------------------------------------
3767 /// specify the command send to Mail box or DRAM
3768 /// @return TRUE or FALSE
3769 ///     - TRUE, Mail box
3770 ///     - FALSE, Dram
3771 /// @param u32Cmd \b IN: Command is going to be sned
3772 ///-----------------------------------------------------------------------------
HAL_VPU_EX_IsMailBoxCMD(MS_U32 u32Cmd)3773 MS_BOOL HAL_VPU_EX_IsMailBoxCMD(MS_U32 u32Cmd)
3774 {
3775     MS_BOOL bResult = TRUE;
3776 
3777     switch (u32Cmd)
3778     {
3779         // *********** Runtime action Command
3780 /*        case E_HVD_CMD_RELEASE_DISPQ:
3781         case E_HVD_CMD_UPDATE_DISPQ:
3782         case E_HVD_CMD_FLUSH_DEC_Q:
3783         case E_HVD_CMD_FLUSH:
3784         case E_HVD_CMD_PLAY:
3785         case E_HVD_CMD_PAUSE:
3786         case E_HVD_CMD_STOP:
3787         case E_HVD_CMD_STEP_DECODE:
3788         case E_HVD_CMD_SKIP_DEC:
3789         case E_HVD_CMD_DISP_I_DIRECT:*/
3790         // *********** Dual-Stream Create Task Command
3791         case E_DUAL_CMD_TASK0_HVD_BBU:
3792         case E_DUAL_CMD_TASK0_HVD_TSP:
3793         case E_DUAL_CMD_TASK0_MVD_SLQ:
3794         case E_DUAL_CMD_TASK0_MVD_TSP:
3795         case E_DUAL_CMD_TASK1_HVD_BBU:
3796         case E_DUAL_CMD_TASK1_HVD_TSP:
3797         case E_DUAL_CMD_MODE:
3798 #ifndef _WIN32
3799         case E_DUAL_CMD_TASK1_MVD_SLQ:
3800         case E_DUAL_CMD_TASK1_MVD_TSP:
3801 #endif
3802         case E_DUAL_CMD_DEL_TASK:
3803         case E_DUAL_CMD_SINGLE_TASK:
3804         case E_DUAL_VERSION:
3805         case E_DUAL_R2_CMD_EXIT:
3806 #ifdef VDEC3
3807         case E_DUAL_R2_CMD_FBADDR:
3808         case E_DUAL_R2_CMD_FBSIZE:
3809         // *********** N-Streams
3810         case E_NST_CMD_TASK_HVD_TSP:
3811         case E_NST_CMD_TASK_HVD_BBU:
3812         case E_NST_CMD_TASK_MVD_TSP:
3813         case E_NST_CMD_TASK_MVD_SLQ:
3814         case E_NST_CMD_DEL_TASK:
3815 #endif
3816         case E_DUAL_CMD_COMMON:
3817             {
3818                 bResult = TRUE;
3819             }
3820                 break;
3821         default:
3822             {
3823                 bResult = FALSE;
3824             }
3825             break;
3826     }
3827 
3828     return bResult;
3829 }
3830 
3831 ///-----------------------------------------------------------------------------
3832 /// specify the command send to Mail box or DRAM
3833 /// @return TRUE or FALSE
3834 ///     - TRUE, Mail box
3835 ///     - FALSE, Dram
3836 /// @param u32Cmd \b IN: Command is going to be sned
3837 ///-----------------------------------------------------------------------------
HAL_VPU_EX_IsDisplayQueueCMD(MS_U32 u32Cmd)3838 MS_BOOL HAL_VPU_EX_IsDisplayQueueCMD(MS_U32 u32Cmd)
3839 {
3840     MS_BOOL bResult = TRUE;
3841 
3842     switch (u32Cmd)
3843     {
3844         // *********** Runtime action Command
3845         case E_HVD_CMD_RELEASE_DISPQ:
3846         case E_HVD_CMD_UPDATE_DISPQ:
3847         case E_HVD_CMD_FLUSH_DEC_Q:
3848         case E_HVD_CMD_PAUSE:
3849         case E_HVD_CMD_FLUSH:
3850         case E_HVD_CMD_PLAY:
3851         case E_HVD_CMD_STOP:
3852         case E_HVD_CMD_SKIP_DEC:
3853         case E_HVD_CMD_DISP_I_DIRECT:
3854         case E_HVD_CMD_STEP_DECODE:
3855         case E_HVD_CMD_INC_DISPQ_NUM:
3856             {
3857                 bResult = TRUE;
3858             }
3859                 break;
3860         default:
3861             {
3862                 bResult = FALSE;
3863             }
3864             break;
3865     }
3866 
3867     return bResult;
3868 }
3869 
3870 ///-----------------------------------------------------------------------------
3871 /// Send message to HVD stream command queue
3872 /// @return TRUE or FALSE
3873 ///     - TRUE, Success
3874 ///     - FALSE, Failed
3875 /// @param u32DramAddr \b IN: address to be writen
3876 /// @param u32Msg \b IN: data to be writen
3877 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMCMDQueueSend(MS_VIRT u32DramAddr,MS_U32 u32Msg)3878 MS_BOOL HAL_VPU_EX_DRAMCMDQueueSend(MS_VIRT u32DramAddr, MS_U32 u32Msg)
3879 {
3880     MS_BOOL bResult = TRUE;
3881 
3882     VPU_MSG_DBG("Send to Command Queue Address=0x%lx, msg=0x%x\n", (unsigned long)u32DramAddr, u32Msg);
3883 
3884     WRITE_LONG(u32DramAddr,u32Msg);
3885 
3886     return bResult;
3887 }
3888 
3889 ///-----------------------------------------------------------------------------
3890 /// Read task share memory to specify that task command queue is empty or not
3891 /// @return TRUE or FALSE
3892 ///     - TRUE, Empty
3893 ///     - FALSE, Non empty
3894 /// @param u32Id \b IN: Task information
3895 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMCMDQueueIsEmpty(void * cmd_queue)3896 MS_BOOL HAL_VPU_EX_DRAMCMDQueueIsEmpty(void *cmd_queue)
3897 {
3898 //    HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
3899     CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
3900     if (!cmd_q)
3901     {
3902         VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
3903         return FALSE;
3904     }
3905 
3906     return cmd_q->u32HVD_STREAM_CMDQ_WD == cmd_q->u32HVD_STREAM_CMDQ_RD;
3907 }
3908 
3909 ///-----------------------------------------------------------------------------
3910 /// Read task share memory to specify that task command queue is full or not
3911 /// @return TRUE or FALSE
3912 ///     - TRUE, Full
3913 ///     - FALSE, Non full
3914 /// @param u32Id \b IN: Task information
3915 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMCMDQueueIsFull(void * cmd_queue)3916 MS_BOOL HAL_VPU_EX_DRAMCMDQueueIsFull(void *cmd_queue)
3917 {
3918 //    HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
3919     CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
3920     if (!cmd_q)
3921     {
3922         VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
3923         return TRUE;
3924     }
3925     MS_U32 NewWD = cmd_q->u32HVD_STREAM_CMDQ_WD + (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE); //preserve one slot
3926 
3927     if(NewWD >= HVD_CMDQ_DRAM_ST_SIZE)
3928         NewWD -= HVD_CMDQ_DRAM_ST_SIZE;
3929 
3930     return NewWD == cmd_q->u32HVD_STREAM_CMDQ_RD;
3931 }
3932 
HAL_VPU_EX_DRAMStreamCMDQueueSend(MS_U32 u32Id,void * cmd_queue,MS_U8 u8CmdType,MS_U32 u32Msg)3933 MS_U32 HAL_VPU_EX_DRAMStreamCMDQueueSend(MS_U32 u32Id, void *cmd_queue, MS_U8 u8CmdType, MS_U32 u32Msg)
3934 {
3935     MS_U32 bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
3936     CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
3937     MS_U8 u8TaskID = HAL_VPU_EX_GetTaskId(u32Id);
3938 
3939 #if HVD_ENABLE_MVC
3940     if (E_HAL_VPU_MVC_STREAM_BASE == u8TaskID)
3941     {
3942         u8TaskID = E_HAL_VPU_MAIN_STREAM_BASE;
3943     }
3944 #endif
3945 
3946     if (CHECK_NULL_PTR(cmd_q))
3947     {
3948         VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
3949         return bResult;
3950     }
3951     MS_VIRT u32CmdQWdPtr;
3952 
3953     if (CHECK_NULL_PTR((MS_VIRT)cmd_q->u32HVD_CMDQ_DRAM_ST_ADDR))
3954         return E_HVD_COMMAND_QUEUE_NOT_INITIALED;
3955 
3956     if (HAL_VPU_EX_DRAMCMDQueueIsFull(cmd_q))
3957         return E_HVD_COMMAND_QUEUE_FULL;
3958     else
3959     {
3960         u32CmdQWdPtr = MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + cmd_q->u32HVD_CMDQ_DRAM_ST_ADDR + cmd_q->u32HVD_STREAM_CMDQ_WD);
3961     }
3962 
3963     switch (u8CmdType)
3964     {
3965         case E_HVD_CMDQ_CMD:
3966         {
3967             u32Msg |= (u8TaskID << VDEC_BBU_ID_SHIFT);
3968             bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32CmdQWdPtr, u32Msg);
3969 
3970             MsOS_FlushMemory();//make sure u32DISPCMDQWdPtr already flushed to memory
3971 
3972             if (bResult)
3973             {
3974                 cmd_q->u32HVD_STREAM_CMDQ_WD += (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE);
3975 
3976                 if (cmd_q->u32HVD_STREAM_CMDQ_WD == HVD_CMDQ_DRAM_ST_SIZE)
3977                     cmd_q->u32HVD_STREAM_CMDQ_WD = 0;
3978 
3979                 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
3980             }
3981             break;
3982         }
3983         case E_HVD_CMDQ_ARG:
3984         {
3985             bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32CmdQWdPtr + HVD_DRAM_CMDQ_CMD_SIZE, u32Msg);
3986             if (bResult)
3987                 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
3988             break;
3989         }
3990         default:
3991         {
3992             bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
3993             break;
3994         }
3995     }
3996 
3997     MsOS_FlushMemory();
3998 
3999     return bResult;
4000 }
4001 
4002 ///-----------------------------------------------------------------------------
4003 /// Read task share memory to specify that task display command queue is empty or not
4004 /// @return TRUE or FALSE
4005 ///     - TRUE, Empty
4006 ///     - FALSE, Non empty
4007 /// @param u32Id \b IN: Task information
4008 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMDispCMDQueueIsEmpty(void * cmd_queue)4009 MS_BOOL HAL_VPU_EX_DRAMDispCMDQueueIsEmpty(void *cmd_queue)
4010 {
4011 //    HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
4012     CMD_QUEUE *cmd_q = (CMD_QUEUE *) cmd_queue;
4013     if (!cmd_q)
4014     {
4015         VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
4016         return FALSE;
4017     }
4018 
4019     return cmd_q->u32HVD_STREAM_DISPCMDQ_WD == cmd_q->u32HVD_STREAM_DISPCMDQ_RD;
4020 }
4021 
HAL_VPU_EX_DRAMDispCMDQueueIsFull(void * cmd_queue)4022 MS_BOOL HAL_VPU_EX_DRAMDispCMDQueueIsFull(void *cmd_queue)
4023 {
4024 //    HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
4025     CMD_QUEUE *cmd_q = (CMD_QUEUE *) cmd_queue;
4026     if (!cmd_q)
4027     {
4028         VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
4029         return TRUE;
4030     }
4031 
4032     MS_U32 NewWD = cmd_q->u32HVD_STREAM_DISPCMDQ_WD + (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE); //preserve one slot
4033 
4034     if(NewWD >= HVD_DISPCMDQ_DRAM_ST_SIZE)
4035         NewWD -= HVD_DISPCMDQ_DRAM_ST_SIZE;
4036 
4037     return NewWD == cmd_q->u32HVD_STREAM_DISPCMDQ_RD;
4038 }
4039 
HAL_VPU_EX_DRAMStreamDispCMDQueueSend(MS_U32 u32Id,void * cmd_queue,MS_U8 u8CmdType,MS_U32 u32Msg)4040 MS_U32 HAL_VPU_EX_DRAMStreamDispCMDQueueSend(MS_U32 u32Id, void *cmd_queue, MS_U8 u8CmdType, MS_U32 u32Msg)
4041 {
4042     HVD_DRAM_COMMAND_QUEUE_SEND_STATUS bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
4043     CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
4044     MS_U8 u8TaskID = HAL_VPU_EX_GetTaskId(u32Id);
4045 
4046 #if HVD_ENABLE_MVC
4047     if (E_HAL_VPU_MVC_STREAM_BASE == u8TaskID)
4048     {
4049         u8TaskID = E_HAL_VPU_MAIN_STREAM_BASE;
4050     }
4051 #endif
4052 
4053 //    HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
4054     //HVD_EX_MSG_DBG("DP shmAddr=%X u8TaskID = %X u8CmdType = %X u32Msg = %X\n", pShm, u8TaskID, u8CmdType, u32Msg);
4055 
4056     if (CHECK_NULL_PTR(cmd_q))
4057     {
4058         VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
4059         return bResult;
4060     }
4061 
4062     MS_VIRT u32DISPCMDQWdPtr;
4063 
4064     if (CHECK_NULL_PTR((MS_VIRT)cmd_q->u32HVD_DISPCMDQ_DRAM_ST_ADDR))
4065         return E_HVD_COMMAND_QUEUE_NOT_INITIALED;
4066 
4067     if (HAL_VPU_EX_DRAMDispCMDQueueIsFull(cmd_q))
4068         return E_HVD_COMMAND_QUEUE_FULL;
4069     else
4070     {
4071         u32DISPCMDQWdPtr = MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + cmd_q->u32HVD_DISPCMDQ_DRAM_ST_ADDR + cmd_q->u32HVD_STREAM_DISPCMDQ_WD);
4072     }
4073 
4074     // HVD_EX_MSG_DBG("VDispCmdQ_BASE_ADDR=%X PDispCmsQ_BASE_ADDR=%X u32DISPCMDQWdPtr=%X DISPCMDQ_TOTAL_SIZE = %X\n", cmd_q->u32HVD_DISPCMDQ_DRAM_ST_ADDR, pVPUHalContext->u32FWCodeVAddr + cmd_q->u32HVD_DISPCMDQ_DRAM_ST_ADDR, u32DISPCMDQWdPtr,HVD_DISPCMDQ_DRAM_ST_SIZE);
4075 
4076     switch (u8CmdType)
4077     {
4078         case E_HVD_CMDQ_CMD:
4079         {
4080             u32Msg |= (u8TaskID << VDEC_BBU_ID_SHIFT);
4081             bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32DISPCMDQWdPtr, u32Msg);
4082 
4083             MsOS_FlushMemory();//make sure u32DISPCMDQWdPtr already flushed to memory
4084 
4085             if (bResult)
4086             {
4087                 cmd_q->u32HVD_STREAM_DISPCMDQ_WD += (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE);
4088 
4089                 if (cmd_q->u32HVD_STREAM_DISPCMDQ_WD == HVD_DISPCMDQ_DRAM_ST_SIZE)
4090                     cmd_q->u32HVD_STREAM_DISPCMDQ_WD = 0;
4091 
4092                 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
4093             }
4094             break;
4095         }
4096         case E_HVD_CMDQ_ARG:
4097         {
4098             bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32DISPCMDQWdPtr + HVD_DRAM_CMDQ_CMD_SIZE, u32Msg);
4099             if (bResult)
4100                 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
4101             break;
4102         }
4103         default:
4104         {
4105             bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
4106             break;
4107         }
4108     }
4109 
4110     MsOS_FlushMemory();
4111 
4112     return bResult;
4113 }
4114 
HAL_VPU_EX_SetBitstreamBufAddress(MS_U32 u32Id,MS_VIRT u32BsAddr)4115 MS_BOOL HAL_VPU_EX_SetBitstreamBufAddress(MS_U32 u32Id, MS_VIRT u32BsAddr)
4116 {
4117     MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
4118     MS_U32 u32StAddr;
4119     MS_U8 u8TmpMiuSel;
4120 
4121     _phy_to_miu_offset(u8TmpMiuSel, u32StAddr, u32BsAddr);
4122 
4123     pVPUHalContext->u32BitstreamAddress[u8OffsetIdx] = u32StAddr;
4124 
4125     return TRUE;
4126 }
4127 #endif
4128 
HAL_VPU_EX_DynamicFBMode(MS_BOOL bEnable,MS_PHY u32address,MS_U32 u32Size)4129 void HAL_VPU_EX_DynamicFBMode(MS_BOOL bEnable,MS_PHY u32address,MS_U32 u32Size)
4130 {
4131     pVPUHalContext->bEnableDymanicFBMode = bEnable;
4132 
4133     if(u32address >= HAL_MIU1_BASE)
4134     {
4135         pVPUHalContext->u32DynamicFBAddress = u32address-HAL_MIU1_BASE;
4136     }
4137     else
4138     {
4139         pVPUHalContext->u32DynamicFBAddress = u32address;
4140     }
4141 
4142     pVPUHalContext->u32DynamicFBSize = u32Size;
4143 }
4144 
4145 
4146 #else
4147 #include "halVPU_EX.h"
4148 #include "drvMMIO.h"
4149 #include "../hvd_ex/regHVD_EX.h"
4150 #include "halCHIP.h"
4151 
4152 #if defined(MSOS_TYPE_NUTTX)
4153 extern int lib_lowprintf(const char *fmt, ...);
4154 #define PRINTF lib_lowprintf
4155 #elif defined(MSOS_TYPE_OPTEE)
4156 #define PRINTF printf
4157 #endif
4158 
4159 #define HVD_LWORD(x)    (MS_U16)((x)&0xffff)
4160 #define HVD_HWORD(x)    (MS_U16)(((x)>>16)&0xffff)
4161 
4162 MS_U8 u8FW_Binary[] = {
4163     #include "fwVPU.dat"
4164 };
4165 
4166 MS_U32 u32HVDRegOSBase;
4167 
HAL_VPU_EX_LoadCodeInSecure(MS_VIRT addr)4168 MS_BOOL HAL_VPU_EX_LoadCodeInSecure(MS_VIRT addr)
4169 {
4170     //PRINTF("do load code,u32DestAddr %x\n",addr);
4171     memcpy((void*)addr, (void*)u8FW_Binary, sizeof(u8FW_Binary));
4172     MAsm_CPU_Sync();
4173     MsOS_FlushMemory();
4174 
4175     if (FALSE == (*((MS_U8*)(addr+6))=='R' && *((MS_U8*)(addr+7))=='2'))
4176     {
4177         PRINTF("FW is not R2 version! _%x_ _%x_\n", *(MS_U8*)(addr+6), *(MS_U8*)(addr+7));
4178         return FALSE;
4179     }
4180     return TRUE;
4181 }
4182 
HAL_VPU_EX_SetLockDownRegister(void * param)4183 MS_BOOL HAL_VPU_EX_SetLockDownRegister(void* param)
4184 {
4185 #if 1
4186     MS_PHY u32StAddr_main;
4187     MS_PHY u32StAddr_sub;
4188     MS_U32 u32NonPMBankSize = 0;
4189     VPU_EX_LOCK_DOWN_REGISTER* register_lockdown;
4190 
4191     if(param == NULL)
4192     {
4193         return FALSE;
4194     }
4195 
4196     register_lockdown = (VPU_EX_LOCK_DOWN_REGISTER*)param;
4197 
4198     MDrv_MMIO_GetBASE(&u32HVDRegOSBase, &u32NonPMBankSize, MS_MODULE_HW);
4199 
4200     // ES buffer
4201     u32StAddr_main = register_lockdown->Bitstream_Addr_Main;
4202     u32StAddr_sub = register_lockdown->Bitstream_Addr_Sub;
4203 
4204 
4205     MS_PHY u32StartOffset;
4206     MS_U8  u8MiuSel;
4207 
4208      _phy_to_miu_offset(u8MiuSel, u32StartOffset, u32StAddr_main);
4209     u32StAddr_main = u32StartOffset;
4210 
4211      _phy_to_miu_offset(u8MiuSel, u32StartOffset, u32StAddr_sub);
4212     u32StAddr_sub = u32StartOffset;
4213 
4214     //Lock down register
4215     _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_L(REG_HVD_BASE), HVD_LWORD(u32StAddr_main >> 3));
4216     _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_H(REG_HVD_BASE), HVD_HWORD(u32StAddr_main >> 3));
4217 
4218     _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_L_BS2, HVD_LWORD(u32StAddr_sub >> 3));
4219     _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_H_BS2, HVD_HWORD(u32StAddr_sub >> 3));
4220     //~
4221 
4222     // Lock Down
4223     //_HVD_Write2Byte(HVD_REG_HI_DUMMY_0, (_HVD_Read2Byte(HVD_REG_HI_DUMMY_0) | (HVD_REG_LOCK_REG_ESB_ST_ADR_L_H|HVD_REG_LOCK_REG_ESB_ST_ADR_L_H_BS2)));
4224     //~
4225 #endif
4226     return TRUE;
4227 }
4228 
4229 
4230 #endif
4231 
4232 
4233 #ifdef CMA_DRV_DIRECT_INIT
4234 // To-do: Taking the source type into consideration
HAL_VPU_EX_GetCMAMemSize(VPU_EX_CodecType eCodecType,VPU_EX_SrcMode eSrcMode,MS_U64 * offset,MS_SIZE * length,MS_U64 total_length,MS_SIZE unUseSize)4235 MS_BOOL HAL_VPU_EX_GetCMAMemSize(VPU_EX_CodecType eCodecType, VPU_EX_SrcMode eSrcMode,
4236     MS_U64 *offset, MS_SIZE *length, MS_U64 total_length, MS_SIZE unUseSize)
4237 {
4238     MS_SIZE FrameBufferSize = 0;
4239 
4240     if (!offset || !length)
4241         return FALSE;
4242 
4243     total_length -= unUseSize;
4244     VPU_MSG_INFO("[HAL][%s]:[%d] total_length:%llu, cType:%d, sType:%d\n", __FUNCTION__, __LINE__,
4245         (unsigned long long)total_length, (int)eCodecType, (int)eSrcMode);
4246     switch(eCodecType)
4247     {
4248         case E_VPU_EX_CODEC_TYPE_MPEG2:
4249         case E_VPU_EX_CODEC_TYPE_H263:
4250         case E_VPU_EX_CODEC_TYPE_MPEG4:
4251         case E_VPU_EX_CODEC_TYPE_DIVX311:
4252         case E_VPU_EX_CODEC_TYPE_DIVX412:
4253         case E_VPU_EX_CODEC_TYPE_FLV:
4254             FrameBufferSize = 0x1E00000;
4255             break;
4256         case E_VPU_EX_CODEC_TYPE_VC1_ADV:
4257         case E_VPU_EX_CODEC_TYPE_VC1_MAIN:
4258             FrameBufferSize = 0x6C00000;
4259             break;
4260         case E_VPU_EX_CODEC_TYPE_RV8:
4261         case E_VPU_EX_CODEC_TYPE_RV9:
4262             FrameBufferSize = 0x1B00000;
4263             break;
4264         case E_VPU_EX_CODEC_TYPE_VP8:
4265             FrameBufferSize = 0x1500000;
4266             break;
4267         case E_VPU_EX_CODEC_TYPE_H264:
4268             FrameBufferSize = 0x8200000;
4269             //FrameBufferSize = 0x7A00000;  //UHD 122MB ,5 ref frame
4270             //FrameBufferSize = 0x7A80000;  //UHD 4K2K 16:19  126.5MB
4271             //FrameBufferSize = 0x8E00000;  //UHD 4K2K 16:19  142MB
4272             break;
4273         case E_VPU_EX_CODEC_TYPE_AVS:
4274             FrameBufferSize = 0x1B00000;
4275             break;
4276         case E_VPU_EX_CODEC_TYPE_MJPEG:
4277             FrameBufferSize = 0x2800000;
4278             break;
4279         case E_VPU_EX_CODEC_TYPE_MVC:
4280             FrameBufferSize = 0x4200000;
4281             break;
4282         case E_VPU_EX_CODEC_TYPE_HEVC:
4283 #if SUPPORT_MSVP9
4284         case E_VPU_EX_CODEC_TYPE_VP9:
4285 #endif
4286             FrameBufferSize = 0xA000000;
4287             break;
4288 #if !SUPPORT_MSVP9
4289         case E_VPU_EX_CODEC_TYPE_VP9:
4290             FrameBufferSize = 0x7800000;
4291             break;
4292 #endif
4293         default:
4294             FrameBufferSize = 0;
4295             break;
4296     }
4297     if(FrameBufferSize == 0)
4298     {
4299         return FALSE;
4300     }
4301     VPU_MSG_INFO("[HAL][%s]:[%d] FrameSize:%llu, offset:%llu, length:%llu ", __FUNCTION__, __LINE__,
4302         (unsigned long long)FrameBufferSize, (unsigned long long)*offset, (unsigned long long)*length);
4303     if (total_length < FrameBufferSize)
4304     {
4305         *offset = unUseSize;
4306         *length = total_length;
4307     }
4308     else  // todo, dual decode case
4309     {
4310         *offset = unUseSize;
4311         *length = FrameBufferSize;
4312     }
4313     return TRUE;
4314 }
4315 #endif
4316