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))=='1'
1086 && *((MS_U8*)(u32SrcAddr+0xe8))=='V' && *((MS_U8*)(u32SrcAddr+0xe9))=='D'
1087 && *((MS_U8*)(u32SrcAddr+0xea))=='E' && *((MS_U8*)(u32SrcAddr+0xeb))=='C'
1088 && *((MS_U8*)(u32SrcAddr+0xec))=='3' && *((MS_U8*)(u32SrcAddr+0xed))=='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*VPU_FW_MEM_OFFSET);
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_START + u8Offset*VPU_FW_MEM_OFFSET);
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_START + u8Offset*VPU_FW_MEM_OFFSET);
1637
1638 memset(pTemp2,0,sizeof(CMD_QUEUE));
1639
1640 pTemp2->u32HVD_DISPCMDQ_DRAM_ST_ADDR = VDISP_COMMANDQ_START + u8Offset*VPU_FW_MEM_OFFSET;
1641
1642 pTemp2->u32HVD_CMDQ_DRAM_ST_ADDR = VNORMAL_COMMANDQ_START + u8Offset*VPU_FW_MEM_OFFSET;
1643
1644 unsigned char* pTemp3 = (unsigned char*)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + VDISP_COMMANDQ_START + u8Offset*VPU_FW_MEM_OFFSET);
1645
1646 memset(pTemp3,0,0x2000);
1647
1648 unsigned int* pVersion = (unsigned int*)MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + OFFSET_BASE + u8Offset*VPU_FW_MEM_OFFSET);
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
1763 eCmd = _VPU_EX_MapCtrlCmd(pTaskInfo);
1764 #if defined(SUPPORT_NEW_MEM_LAYOUT)
1765 if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
1766 #ifdef VDEC3
1767 {
1768 u32Arg = (u32BBUId << VDEC_BBU_ID_SHIFT) + u8Offset * VPU_FW_MEM_OFFSET + OFFSET_BASE;
1769 }
1770 #else
1771 u32Arg = u8Offset * VPU_FW_MEM_OFFSET + OFFSET_BASE;
1772 #endif
1773
1774 #ifdef VDEC3
1775 #if SUPPORT_G2VP9
1776 else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
1777 #else
1778 else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1779 #endif
1780 {
1781 u32Arg = (u32BBUId << VDEC_BBU_ID_SHIFT) + (u8Offset * VPU_FW_MEM_OFFSET) + HVD_SHARE_MEM_ST_OFFSET;
1782 }
1783 #else
1784 else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
1785 u32Arg = u8Offset * VPU_FW_MEM_OFFSET + HVD_SHARE_MEM_ST_OFFSET;
1786 #endif
1787 else
1788 {
1789 VPU_MSG_ERR("Can't find eDecType! %d\n", pTaskInfo->eDecType);
1790 _HAL_VPU_Release();
1791 return FALSE;
1792 }
1793 #else
1794 u32Arg = u8Offset * VPU_FW_MEM_OFFSET;
1795 #endif
1796
1797 VPRINTF("[%s][%d] create task : id 0x%x, cmd 0x%x, arg 0x%x, bbuID %d, offset %d \n", __FUNCTION__, __LINE__, u32Id, eCmd, u32Arg, u32BBUId, u8Offset);
1798 HAL_HVD_EX_SetCmd(u32Id, eCmd, u32Arg);
1799
1800 MsOS_ReadMemory();
1801 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",
1802 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]);
1803
1804 u32Timeout = HVD_GetSysTime_ms() + VPU_CMD_TIMEOUT;
1805 while (CTL_TASK_CMDRDY != ctl_ptr->task_statue[u8Offset])
1806 {
1807 if (HVD_GetSysTime_ms() > u32Timeout)
1808 {
1809 VPU_MSG_ERR("Task %d creation timeout\n", u8Offset);
1810 MS_U32 t=0;
1811 for (t=0; t<30; t++)
1812 {
1813 VPU_MSG_DBG("_pc=0x%x\n", HAL_VPU_EX_GetProgCnt());
1814 }
1815 //#ifndef VDEC3 // FIXME: workaround fw response time is slow sometimes in multiple stream case so far
1816 pVPUHalContext->bVpuExLoadFWRlt = FALSE; ///error handling
1817 VPU_MSG_ERR("set bVpuExLoadFWRlt as FALSE\n\n");
1818 _HAL_VPU_Release();
1819 return FALSE;
1820 //#endif
1821 }
1822
1823 MsOS_ReadMemory();
1824 }
1825
1826 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",
1827 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]);
1828
1829 #ifdef VDEC3
1830 if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType || E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1831 #else
1832 if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
1833 #endif
1834 {
1835 HAL_HVD_EX_SetBufferAddr(u32Id);
1836 }
1837
1838 if (E_VPU_EX_DECODER_MVD == pTaskInfo->eDecType)
1839 {
1840 eDecType = E_VPU_EX_DECODER_MVD;
1841 }
1842 else if (E_VPU_EX_DECODER_HVD == pTaskInfo->eDecType)
1843 {
1844 eDecType = E_VPU_EX_DECODER_HVD;
1845 }
1846 #ifdef VDEC3
1847 else if (E_VPU_EX_DECODER_EVD == pTaskInfo->eDecType)
1848 {
1849 eDecType = E_VPU_EX_DECODER_EVD;
1850 }
1851 #if SUPPORT_G2VP9
1852 else if (E_VPU_EX_DECODER_G2VP9 == pTaskInfo->eDecType)
1853 {
1854 eDecType = E_VPU_EX_DECODER_G2VP9;
1855 }
1856 #endif
1857 #endif
1858 else
1859 {
1860 VPU_MSG_ERR("Can't find eDecType! %d\n", pTaskInfo->eDecType);
1861 _HAL_VPU_Release();
1862 return FALSE;
1863 }
1864
1865 #ifdef VDEC3
1866 if ((bFWdecideFB == TRUE) && (pVPUHalContext->u8TaskCnt == 0))
1867 {
1868 HAL_HVD_EX_SetCmd(u32Id, E_DUAL_R2_CMD_FBADDR, pInitPara->pFBCfg->u32FrameBufAddr);
1869 HAL_HVD_EX_SetCmd(u32Id, E_DUAL_R2_CMD_FBSIZE, pInitPara->pFBCfg->u32FrameBufSize);
1870 }
1871 #endif
1872
1873 if (pTaskInfo->eDecType != eDecType)
1874 {
1875 VPU_MSG_ERR("warning pTaskInfo->eDecType=%x not %x\n",
1876 pTaskInfo->eDecType, eDecType);
1877 }
1878 goto _SAVE_DEC_TYPE;
1879
1880 _SAVE_DEC_TYPE:
1881 if (pVPUHalContext->_stVPUStream[u8Offset].eStreamId == (u32Id & 0xFF))
1882 {
1883 pVPUHalContext->_stVPUStream[u8Offset].eDecodertype = eDecType;
1884 }
1885 else
1886 {
1887 VPU_MSG_ERR("Cannot save eDecType!!\n");
1888 }
1889
1890 (pVPUHalContext->u8TaskCnt)++;
1891 _HAL_VPU_Release();
1892 return TRUE;
1893 }
1894
HAL_VPU_EX_TaskDelete(MS_U32 u32Id,VPU_EX_NDecInitPara * pInitPara)1895 MS_BOOL HAL_VPU_EX_TaskDelete(MS_U32 u32Id, VPU_EX_NDecInitPara *pInitPara)
1896 {
1897 HVD_Return eRet;
1898 #ifdef VDEC3
1899 HVD_User_Cmd eCmd = E_NST_CMD_DEL_TASK;
1900 #else
1901 HVD_User_Cmd eCmd = E_DUAL_CMD_DEL_TASK;
1902 #endif
1903 MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
1904 MS_U32 u32Timeout = HVD_GetSysTime_ms() + 3000;
1905
1906 _HAL_VPU_Entry();
1907 VPU_MSG_DBG("DecType=%d\n", pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype);
1908
1909 eRet = HAL_HVD_EX_SetCmd(u32Id, eCmd, u8OffsetIdx);
1910 if(eRet != E_HVD_RETURN_SUCCESS)
1911 {
1912 VPU_MSG_ERR("VPU fail to DEL Task %d\n", eRet);
1913 }
1914
1915 {
1916 struct _ctl_info *ctl_ptr = (struct _ctl_info *)
1917 MsOS_PA2KSEG1(MsOS_VA2PA(pInitPara->pFWCodeCfg->u32DstAddr) + CTL_INFO_ADDR);
1918 u32Timeout = HVD_GetSysTime_ms() + VPU_CMD_TIMEOUT;
1919
1920 MsOS_ReadMemory();
1921
1922 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",
1923 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]);
1924
1925 while (CTL_TASK_NONE != ctl_ptr->task_statue[u8OffsetIdx])
1926 {
1927 if (HVD_GetSysTime_ms() > u32Timeout)
1928 {
1929 VPU_MSG_ERR("Task %u deletion timeout\n", u8OffsetIdx);
1930 pVPUHalContext->bVpuExLoadFWRlt = FALSE; ///error handling
1931 VPU_MSG_ERR("Set bVpuExLoadFWRlt as FALSE\n");
1932
1933 if(pVPUHalContext->u8TaskCnt == 1)
1934 {
1935 VPU_MSG_ERR("Due to one task remain, driver can force delete task\n");
1936 break;
1937 }
1938 else if(pVPUHalContext->u8TaskCnt == 2)
1939 {
1940 VPU_MSG_ERR("Due to two tasks remain, driver can't force delete task\n");
1941 _HAL_VPU_Release();
1942 return FALSE;
1943 }
1944 else
1945 {
1946 VPU_MSG_ERR("Task number is not correct\n");
1947 _HAL_VPU_Release();
1948 return FALSE;
1949 }
1950 }
1951
1952 MsOS_ReadMemory();
1953 }
1954
1955 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",
1956 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]);
1957 }
1958
1959 #if SUPPORT_EVD
1960 if (pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype == E_VPU_EX_DECODER_EVD)
1961 {
1962 HAL_EVD_EX_ClearTSPInput(u32Id);
1963 }
1964 #endif
1965
1966 pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype = E_VPU_EX_DECODER_NONE;
1967 if( (u8OffsetIdx == 0) && (pVPUHalContext->_stVPUStream[u8OffsetIdx].eStreamId == E_HAL_VPU_MVC_MAIN_VIEW))
1968 {
1969 pVPUHalContext->_stVPUStream[u8OffsetIdx].eStreamId = E_HAL_VPU_N_STREAM0;
1970 pVPUHalContext->_stVPUStream[0].eDecodertype = E_VPU_EX_DECODER_NONE;
1971 pVPUHalContext->_stVPUStream[1].eDecodertype = E_VPU_EX_DECODER_NONE;
1972 }
1973
1974 if (pVPUHalContext->u8TaskCnt)
1975 {
1976 (pVPUHalContext->u8TaskCnt)--;
1977 }
1978 else
1979 {
1980 VPU_MSG_DBG("Warning: u8TaskCnt=0\n");
1981 }
1982
1983 if (0 == pVPUHalContext->u8TaskCnt)
1984 {
1985 int i;
1986 VPU_MSG_DBG("u8TaskCnt=%d time to terminate\n", pVPUHalContext->u8TaskCnt);
1987 _VPU_EX_DeinitAll();
1988 HAL_VPU_EX_SetSingleDecodeMode(FALSE);
1989 pVPUHalContext->u32VPUSHMAddr = 0;
1990
1991 for (i = 0; i < MAX_SUPPORT_DECODER_NUM; i++)
1992 pVPUHalContext->u32FWShareInfoAddr[i] = 0xFFFFFFFFUL;
1993 }
1994 else
1995 {
1996 pVPUHalContext->u32FWShareInfoAddr[u8OffsetIdx] = 0xFFFFFFFFUL;
1997 _VPU_EX_DeinitHW();
1998 }
1999
2000 _HAL_VPU_Release();
2001 return TRUE;
2002 }
2003
HAL_VPU_EX_LoadCode(VPU_EX_FWCodeCfg * pFWCodeCfg)2004 MS_BOOL HAL_VPU_EX_LoadCode(VPU_EX_FWCodeCfg *pFWCodeCfg)
2005 {
2006 MS_VIRT u32DestAddr = pFWCodeCfg->u32DstAddr;
2007 MS_VIRT u32BinAddr = pFWCodeCfg->u32BinAddr;
2008 MS_U32 u32Size = pFWCodeCfg->u32BinSize;
2009 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
2010 MS_U32 u32DestSize = pFWCodeCfg->u32DstSize;
2011 #endif
2012
2013 if (FALSE == HAL_VPU_EX_GetFWReload())
2014 {
2015 //printf("%s bFWReload FALSE!!!\n", __FUNCTION__);
2016 if (FALSE == pVPUHalContext->bVpuExLoadFWRlt)
2017 {
2018 VPU_MSG_INFO("Never load fw successfully, load it anyway!\n");
2019 }
2020 else
2021 {
2022 //Check f/w prefix "VDEC30"
2023 if (_VPU_EX_IsNeedDecompress(u32DestAddr)!=FALSE)
2024 {
2025 VPU_MSG_ERR("Wrong prefix: reload fw!\n");
2026 }
2027 else
2028 {
2029 VPU_MSG_INFO("Skip loading fw this time!!!\n");
2030 return TRUE;
2031 }
2032 }
2033 }
2034
2035 if (E_HVD_FW_INPUT_SOURCE_FLASH == pFWCodeCfg->u8SrcType)
2036 {
2037 #if VPU_ENABLE_BDMA_FW_FLASH_2_SDRAM
2038 if (u32Size != 0)
2039 {
2040 SPIDMA_Dev cpyflag = E_SPIDMA_DEV_MIU1;
2041
2042
2043 MS_U32 u32Start;
2044 MS_U32 u32StartOffset;
2045 MS_U8 u8MiuSel;
2046
2047 _phy_to_miu_offset(u8MiuSel, u32StartOffset, u32DestAddr);
2048
2049
2050 if(u8MiuSel == E_CHIP_MIU_0)
2051 cpyflag = E_SPIDMA_DEV_MIU0;
2052 else if(u8MiuSel == E_CHIP_MIU_1)
2053 cpyflag = E_SPIDMA_DEV_MIU1;
2054 else if(u8MiuSel == E_CHIP_MIU_2)
2055 ; ///TODO: cpyflag = E_SPIDMA_DEV_MIU2;
2056
2057 if (!HVD_FLASHcpy(MsOS_VA2PA(u32DestAddr), MsOS_VA2PA(u32BinAddr), u32Size, cpyflag))
2058 {
2059 goto _load_code_fail;
2060 }
2061 }
2062 else
2063 {
2064 goto _load_code_fail;
2065 }
2066 #else
2067 goto _load_code_fail;
2068 #endif
2069 }
2070 else if (E_HVD_FW_INPUT_SOURCE_DRAM == pFWCodeCfg->u8SrcType)
2071 {
2072 if (u32BinAddr != 0 && u32Size != 0)
2073 {
2074 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
2075 if(_VPU_EX_DecompressBin(u32BinAddr, u32Size, u32DestAddr, u32DestAddr+u32DestSize-WINDOW_SIZE)==TRUE)
2076 {
2077 if(_VPU_EX_IsNeedDecompress(u32DestAddr)==FALSE)
2078 {
2079 VPU_MSG_INFO("Decompress ok!!!\n");
2080 }
2081 else
2082 {
2083 VPU_MSG_INFO("Decompress fail!!!\n");
2084 }
2085 }
2086 else
2087 #endif
2088 {
2089 HVD_memcpy(u32DestAddr, u32BinAddr, u32Size);
2090 }
2091 }
2092 else
2093 {
2094 goto _load_code_fail;
2095 }
2096 }
2097 else
2098 {
2099 #if VPU_ENABLE_EMBEDDED_FW_BINARY
2100 VPU_MSG_INFO("Load FW inD2D: dest=0x%lx, source=0x%lx, size=%d\n",
2101 (unsigned long)u32DestAddr, ((unsigned long) u8HVD_FW_Binary),
2102 (MS_U32) sizeof(u8HVD_FW_Binary));
2103
2104 #if (ENABLE_DECOMPRESS_FUNCTION==TRUE)
2105 if(_VPU_EX_DecompressBin((MS_VIRT)u8HVD_FW_Binary, (MS_U32)sizeof(u8HVD_FW_Binary), u32DestAddr, u32DestAddr+u32DestSize-WINDOW_SIZE)==TRUE)
2106 {
2107 if(_VPU_EX_IsNeedDecompress(u32DestAddr)==FALSE)
2108 {
2109 VPU_MSG_INFO("Decompress ok!!!\n");
2110 }
2111 else
2112 {
2113 VPU_MSG_INFO("Decompress fail!!!\n");
2114 }
2115 }
2116 else
2117 #endif
2118 {
2119 HVD_memcpy(u32DestAddr, (MS_VIRT)u8HVD_FW_Binary, sizeof(u8HVD_FW_Binary));
2120 }
2121 #else
2122 goto _load_code_fail;
2123 #endif
2124 }
2125
2126 MAsm_CPU_Sync();
2127 MsOS_FlushMemory();
2128
2129 if (FALSE == (*((MS_U8*)(u32DestAddr+6))=='R' && *((MS_U8*)(u32DestAddr+7))=='2'))
2130 {
2131 VPU_MSG_ERR("FW is not R2 version! _%x_ _%x_\n", *(MS_U8*)(u32DestAddr+6), *(MS_U8*)(u32DestAddr+7));
2132 goto _load_code_fail;
2133 }
2134
2135 pVPUHalContext->bVpuExLoadFWRlt = TRUE;
2136 return TRUE;
2137
2138 _load_code_fail:
2139 pVPUHalContext->bVpuExLoadFWRlt = FALSE;
2140 return FALSE;
2141 }
2142
HAL_VPU_EX_InitRegBase(MS_VIRT u32RegBase)2143 void HAL_VPU_EX_InitRegBase(MS_VIRT u32RegBase)
2144 {
2145 u32VPURegOSBase = u32RegBase;
2146 }
2147
HAL_VPU_EX_Init_Share_Mem(void)2148 MS_BOOL HAL_VPU_EX_Init_Share_Mem(void)
2149 {
2150 #if ((defined(MSOS_TYPE_LINUX) || defined(MSOS_TYPE_ECOS)) && (!defined(SUPPORT_X_MODEL_FEATURE)))
2151
2152 MS_U32 u32ShmId;
2153 MS_VIRT u32Addr;
2154 MS_U32 u32BufSize;
2155
2156
2157 if (FALSE == MsOS_SHM_GetId( (MS_U8*)"Linux HAL VPU",
2158 sizeof(VPU_Hal_CTX),
2159 &u32ShmId,
2160 &u32Addr,
2161 &u32BufSize,
2162 MSOS_SHM_QUERY))
2163 {
2164 if (FALSE == MsOS_SHM_GetId((MS_U8*)"Linux HAL VPU",
2165 sizeof(VPU_Hal_CTX),
2166 &u32ShmId,
2167 &u32Addr,
2168 &u32BufSize,
2169 MSOS_SHM_CREATE))
2170 {
2171 VPU_MSG_ERR("[%s]SHM allocation failed!!!use global structure instead!!!\n",__FUNCTION__);
2172 if(pVPUHalContext == NULL)
2173 {
2174 pVPUHalContext = &gVPUHalContext;
2175 memset(pVPUHalContext,0,sizeof(VPU_Hal_CTX));
2176 _VPU_EX_Context_Init();
2177 VPU_MSG_INFO("[%s]Global structure init Success!!!\n",__FUNCTION__);
2178 }
2179 else
2180 {
2181 VPU_MSG_INFO("[%s]Global structure exists!!!\n",__FUNCTION__);
2182 }
2183 //return FALSE;
2184 }
2185 else
2186 {
2187 memset((MS_U8*)u32Addr,0,sizeof(VPU_Hal_CTX));
2188 pVPUHalContext = (VPU_Hal_CTX*)u32Addr; // for one process
2189 _VPU_EX_Context_Init();
2190 }
2191 }
2192 else
2193 {
2194 pVPUHalContext = (VPU_Hal_CTX*)u32Addr; // for another process
2195 }
2196 #else
2197 if(pVPUHalContext == NULL)
2198 {
2199 pVPUHalContext = &gVPUHalContext;
2200 memset(pVPUHalContext,0,sizeof(VPU_Hal_CTX));
2201 _VPU_EX_Context_Init();
2202 }
2203 #endif
2204
2205 return TRUE;
2206
2207 }
2208
HAL_VPU_EX_GetFreeStream(HAL_VPU_StreamType eStreamType)2209 HAL_VPU_StreamId HAL_VPU_EX_GetFreeStream(HAL_VPU_StreamType eStreamType)
2210 {
2211 MS_U32 i = 0;
2212
2213 _HAL_VPU_MutexCreate();
2214
2215 _HAL_VPU_Entry();
2216
2217 if (E_HAL_VPU_MVC_STREAM == eStreamType)
2218 {
2219 if((E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[0].eDecodertype) && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[1].eDecodertype))
2220 {
2221 pVPUHalContext->_stVPUStream[0].eStreamId = E_HAL_VPU_MVC_MAIN_VIEW;
2222 pVPUHalContext->_stVPUStream[0].eDecodertype = E_VPU_EX_DECODER_GET_MVC;
2223 pVPUHalContext->_stVPUStream[1].eDecodertype = E_VPU_EX_DECODER_GET_MVC;
2224 _HAL_VPU_Release();
2225 return pVPUHalContext->_stVPUStream[0].eStreamId; /// Need to check
2226 }
2227 }
2228 else if (E_HAL_VPU_MAIN_STREAM == eStreamType)
2229 {
2230 for (i = 0;i < MAX_SUPPORT_DECODER_NUM; i++)
2231 {
2232 if ((E_HAL_VPU_MAIN_STREAM_BASE & pVPUHalContext->_stVPUStream[i].eStreamId)
2233 && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[i].eDecodertype))
2234 {
2235 pVPUHalContext->_stVPUStream[i].eDecodertype = E_VPU_EX_DECODER_GET;
2236 _HAL_VPU_Release();
2237 return pVPUHalContext->_stVPUStream[i].eStreamId;
2238 }
2239 }
2240 }
2241 else if (E_HAL_VPU_SUB_STREAM == eStreamType)
2242 {
2243 for (i = 0;i < MAX_SUPPORT_DECODER_NUM; i++)
2244 {
2245 if ((E_HAL_VPU_SUB_STREAM_BASE & pVPUHalContext->_stVPUStream[i].eStreamId)
2246 && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[i].eDecodertype))
2247 {
2248 pVPUHalContext->_stVPUStream[i].eDecodertype = E_VPU_EX_DECODER_GET;
2249 _HAL_VPU_Release();
2250 return pVPUHalContext->_stVPUStream[i].eStreamId;
2251 }
2252 }
2253 }
2254 #ifdef VDEC3
2255 else if (eStreamType >= E_HAL_VPU_N_STREAM && eStreamType < (E_HAL_VPU_N_STREAM + VPU_MAX_DEC_NUM))
2256 {
2257 #if 1 // bound FW task to main/sub stream
2258 i = eStreamType - E_HAL_VPU_N_STREAM;
2259 if (pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_NONE)
2260 {
2261 pVPUHalContext->_stVPUStream[i].eDecodertype = E_VPU_EX_DECODER_GET;
2262 _HAL_VPU_Release();
2263 return pVPUHalContext->_stVPUStream[i].eStreamId;
2264 }
2265 #else // dynamic select FW task id
2266 for (i = 0;i < MAX_SUPPORT_DECODER_NUM; i++)
2267 {
2268 if ((E_HAL_VPU_N_STREAM_BASE & pVPUHalContext->_stVPUStream[i].eStreamId)
2269 && (E_VPU_EX_DECODER_NONE == pVPUHalContext->_stVPUStream[i].eDecodertype))
2270 {
2271 return pVPUHalContext->_stVPUStream[i].eStreamId;
2272 }
2273 }
2274 #endif
2275 }
2276 #endif
2277
2278 _HAL_VPU_Release();
2279
2280 return E_HAL_VPU_STREAM_NONE;
2281 }
2282
HAL_VPU_EX_ReleaseFreeStream(MS_U8 u8Idx)2283 MS_BOOL HAL_VPU_EX_ReleaseFreeStream(MS_U8 u8Idx)
2284 {
2285 if(u8Idx > 2)
2286 {
2287 return FALSE;
2288 }
2289
2290 _HAL_VPU_Entry();
2291
2292 if(pVPUHalContext->_stVPUStream[u8Idx].eDecodertype == E_VPU_EX_DECODER_GET_MVC)
2293 {
2294 pVPUHalContext->_stVPUStream[0].eDecodertype = E_VPU_EX_DECODER_NONE;
2295 pVPUHalContext->_stVPUStream[1].eDecodertype = E_VPU_EX_DECODER_NONE;
2296 }
2297 else if(pVPUHalContext->_stVPUStream[u8Idx].eDecodertype == E_VPU_EX_DECODER_GET)
2298 {
2299 pVPUHalContext->_stVPUStream[u8Idx].eDecodertype = E_VPU_EX_DECODER_NONE;
2300 }
2301
2302 _HAL_VPU_Release();
2303
2304 return TRUE;
2305 }
2306
HAL_VPU_EX_CheckFreeStream(void)2307 MS_U8 HAL_VPU_EX_CheckFreeStream(void)
2308 {
2309 MS_U8 u8Idx = 0;
2310
2311 for (u8Idx = 0; u8Idx < MAX_SUPPORT_DECODER_NUM; u8Idx++)
2312 {
2313 if (pVPUHalContext->_stVPUStream[u8Idx].eDecodertype == E_VPU_EX_DECODER_NONE)
2314 break;
2315 }
2316
2317 if (u8Idx >= MAX_SUPPORT_DECODER_NUM)
2318 {
2319 VPU_MSG_ERR("all vpu free streams are occupied \n");
2320 return -1;
2321 }
2322
2323 VPU_MSG_DBG("available vpu free stream %d \n", u8Idx);
2324 return u8Idx;
2325 }
2326
HAL_VPU_EX_Init(VPU_EX_InitParam * InitParams)2327 MS_BOOL HAL_VPU_EX_Init(VPU_EX_InitParam *InitParams)
2328 {
2329 VPU_MSG_DBG("Inv=%d, clk=%d\n", InitParams->bClockInv, InitParams->eClockSpeed);
2330
2331 // enable module
2332 _VPU_EX_ClockInv(InitParams->bClockInv);
2333 _VPU_EX_ClockSpeed(InitParams->eClockSpeed);
2334 HAL_VPU_EX_PowerCtrl(TRUE);
2335
2336 #if 1 //Create VPU's own mutex
2337 //_HAL_VPU_MutexCreate();
2338 #else
2339 pVPUHalContext->s32VPUMutexID = InitParams->s32VPUMutexID;
2340 pVPUHalContext->u32VPUMutexTimeOut = InitParams->u32VPUMutexTimeout;
2341 #endif
2342
2343 return TRUE;
2344 }
2345
HAL_VPU_EX_DeInit(void)2346 MS_BOOL HAL_VPU_EX_DeInit(void)
2347 {
2348 if (0 != _VPU_EX_GetActiveCodecCnt())
2349 {
2350 VPU_MSG_DBG("do nothing since codec is active.\n");
2351 return TRUE;
2352 }
2353
2354 memset(&(pVPUHalContext->_stVPUDecMode),0,sizeof(VPU_EX_DecModCfg));
2355
2356 HAL_VPU_EX_PowerCtrl(FALSE);
2357 HAL_VPU_EX_SwRelseMAU();
2358 //_HAL_VPU_MutexDelete();
2359
2360 return TRUE;
2361 }
2362
HAL_VPU_EX_PowerCtrl(MS_BOOL bEnable)2363 void HAL_VPU_EX_PowerCtrl(MS_BOOL bEnable)
2364 {
2365 if (bEnable)
2366 {
2367 _VPU_WriteWordMask(REG_TOP_VPU, 0, TOP_CKG_VPU_DIS);
2368 _VPU_WriteWordMask(REG_CHIPTOP_DUMMY_CODEC, REG_CHIPTOP_DUMMY_CODEC_ENABLE, REG_CHIPTOP_DUMMY_CODEC_ENABLE);
2369 pVPUHalContext->_bVPUPowered = TRUE;
2370 }
2371 else
2372 {
2373 _VPU_WriteWordMask(REG_TOP_VPU, TOP_CKG_VPU_DIS, TOP_CKG_VPU_DIS);
2374 _VPU_WriteWordMask(REG_CHIPTOP_DUMMY_CODEC, 0, REG_CHIPTOP_DUMMY_CODEC_ENABLE);
2375 pVPUHalContext->_bVPUPowered = FALSE;
2376 }
2377 }
2378
HAL_VPU_EX_MIU_RW_Protect(MS_BOOL bEnable)2379 void HAL_VPU_EX_MIU_RW_Protect(MS_BOOL bEnable)
2380 {
2381 _VPU_MIU_SetReqMask(VPU_D_RW, bEnable);
2382 _VPU_MIU_SetReqMask(VPU_Q_RW, bEnable);
2383 _VPU_MIU_SetReqMask(VPU_I_R, bEnable);
2384 VPU_EX_TimerDelayMS(1);
2385 }
2386
2387 ///-----------------------------------------------------------------------------
2388 /// config AVCH264 CPU
2389 /// @param u32StAddr \b IN: CPU binary code base address in DRAM.
2390 /// @param u8dlend_en \b IN: endian
2391 /// - 1, little endian
2392 /// - 0, big endian
2393 ///-----------------------------------------------------------------------------
HAL_VPU_EX_CPUSetting(MS_PHY u32StAddr)2394 MS_BOOL HAL_VPU_EX_CPUSetting(MS_PHY u32StAddr)
2395 {
2396 MS_BOOL bRet = TRUE;
2397 MS_U32 u32Offset = 0;
2398 MS_U16 tempreg = 0;
2399 MS_U8 u8MiuSel;
2400 //MS_U32 u32TmpStartOffset;
2401
2402 _phy_to_miu_offset(u8MiuSel, u32Offset, u32StAddr);
2403
2404 _VPU_Write2Byte(VPU_REG_SPI_BASE, 0xC000);
2405 _VPU_WriteWordMask( VPU_REG_MIU_LAST , 0 , VPU_REG_MIU_LAST_EN );
2406 _VPU_WriteWordMask( VPU_REG_CPU_SETTING , 0 , VPU_REG_CPU_SPI_BOOT );
2407 _VPU_WriteWordMask( VPU_REG_CPU_SETTING , 0 , VPU_REG_CPU_SDRAM_BOOT );
2408 _VPU_Write2Byte(VPU_REG_DQMEM_MASK_L, 0xc000);
2409 _VPU_Write2Byte(VPU_REG_DQMEM_MASK_H, 0xffff);
2410 _VPU_Write2Byte(VPU_REG_IO1_BASE, 0xf900); // UART BASE
2411 _VPU_Write2Byte(VPU_REG_IO2_BASE, 0xf000);
2412 _VPU_Write2Byte(VPU_REG_DQMEM_BASE_L, 0x0000);
2413 _VPU_Write2Byte(VPU_REG_DQMEM_BASE_H, 0xf200);
2414
2415 #if (HVD_ENABLE_IQMEM)
2416 _VPU_Write2Byte(VPU_REG_IQMEM_BASE_L, (MS_U16)(VPU_IQMEM_BASE & 0x0000ffff));
2417 _VPU_Write2Byte(VPU_REG_IQMEM_BASE_H, (MS_U16)((VPU_IQMEM_BASE>>16) & 0xffff));
2418 #endif
2419
2420 #if (VPU_FORCE_MIU_MODE)
2421 // Data sram base Unit: byte address
2422 _VPU_Write2Byte(VPU_REG_DCU_SDR_BASE_L, (MS_U16)(u32Offset & 0x0000ffff)) ;
2423 _VPU_Write2Byte(VPU_REG_DCU_SDR_BASE_H, (MS_U16)((u32Offset >>16) & 0xffff));
2424 // Instruction sram base Unit: byte address
2425 _VPU_Write2Byte(VPU_REG_ICU_SDR_BASE_L, (MS_U16)(u32Offset & 0x0000ffff)) ;
2426 _VPU_Write2Byte(VPU_REG_ICU_SDR_BASE_H, (MS_U16)((u32Offset >>16) & 0xffff));
2427
2428 #ifndef HAL_FEATURE_MAU
2429 MS_U16 r2_miu_sel = (_VPU_Read2Byte(VPU_REG_R2_MI_SEL_BASE) & 0xfff);
2430 #endif
2431 VPU_MSG_INFO("\033[1;32m[%s] %d u8MiuSel = %d r2_miu_sel = 0x%x \033[m\n",__FUNCTION__,__LINE__,u8MiuSel,r2_miu_sel);
2432
2433 //use force miu mode
2434 if(u8MiuSel == E_CHIP_MIU_0)
2435 {
2436 #ifdef HAL_FEATURE_MAU
2437 _VPU_Write2Byte(MAU1_MIU_SEL, 0x8900);
2438 _VPU_Write2Byte(MAU1_LV2_0_MIU_SEL, 0x8900);
2439 _VPU_Write2Byte(MAU1_LV2_1_MIU_SEL, 0x8900);
2440 #else
2441 _VPU_Write2Byte(VPU_REG_R2_MI_SEL_BASE, r2_miu_sel);//1 Manhattan has no MAU, use this register to select miu
2442 #endif
2443 }
2444 else if(u8MiuSel == E_CHIP_MIU_1)
2445 {
2446 #ifdef HAL_FEATURE_MAU
2447 _VPU_Write2Byte(MAU1_MIU_SEL, 0x8900);
2448 _VPU_Write2Byte(MAU1_LV2_0_MIU_SEL, 0x8b00);
2449 _VPU_Write2Byte(MAU1_LV2_1_MIU_SEL, 0x8900);
2450 #else
2451 _VPU_Write2Byte(VPU_REG_R2_MI_SEL_BASE, r2_miu_sel|0x5000);
2452 #endif
2453 }
2454 else //miu 2
2455 {
2456 #ifdef HAL_FEATURE_MAU
2457 _VPU_Write2Byte(MAU1_MIU_SEL, 0x8b00);
2458 _VPU_Write2Byte(MAU1_LV2_0_MIU_SEL, 0x8900);
2459 _VPU_Write2Byte(MAU1_LV2_1_MIU_SEL, 0x8900);
2460 #else
2461 _VPU_Write2Byte(VPU_REG_R2_MI_SEL_BASE, r2_miu_sel|0xa000);
2462 #endif
2463 }
2464 #else
2465 ///TODO:
2466 #endif
2467
2468
2469 tempreg = _VPU_Read2Byte(VPU_REG_CONTROL_SET);
2470 tempreg |= VPU_REG_IO2_EN;
2471 tempreg |= VPU_REG_QMEM_SPACE_EN;
2472 _VPU_Write2Byte(VPU_REG_CONTROL_SET, tempreg);
2473
2474 return bRet;
2475 }
2476
2477 ///-----------------------------------------------------------------------------
2478 /// Set IQMem data access mode or instruction fetch mode
2479 /// @param u8dlend_en \b IN: endian
2480 /// - 1, switch to data access mode
2481 /// - 0, switch to instruction fetch mode
2482 ///-----------------------------------------------------------------------------
HAL_VPU_EX_IQMemSetDAMode(MS_BOOL bEnable)2483 void HAL_VPU_EX_IQMemSetDAMode(MS_BOOL bEnable)
2484 {
2485
2486 if(bEnable){
2487
2488 _VPU_Write2Byte(VPU_REG_IQMEM_SETTING, _VPU_Read2Byte(VPU_REG_IQMEM_SETTING)|0x10);
2489 _VPU_Write2Byte(VPU_REG_QMEM_OWNER, _VPU_Read2Byte(VPU_REG_QMEM_OWNER)&0xFFDE);
2490
2491 }
2492 else{
2493
2494 _VPU_Write2Byte(VPU_REG_IQMEM_SETTING, _VPU_Read2Byte(VPU_REG_IQMEM_SETTING)& 0xFFEF);
2495
2496 }
2497 }
2498
2499 ///-----------------------------------------------------------------------------
2500 /// H.264 SW reset
2501 /// @return TRUE or FALSE
2502 /// - TRUE, Success
2503 /// - FALSE, Failed
2504 ///-----------------------------------------------------------------------------
HAL_VPU_EX_SwRst(MS_BOOL bCheckMauIdle)2505 MS_BOOL HAL_VPU_EX_SwRst(MS_BOOL bCheckMauIdle)
2506 {
2507 MS_U16 tempreg = 0, tempreg1 = 0;
2508 MS_U16 idle_cnt;
2509 tempreg = _VPU_Read2Byte(VPU_REG_CPU_CONFIG);
2510 tempreg |= VPU_REG_CPU_STALL_EN;
2511 _VPU_Write2Byte(VPU_REG_CPU_CONFIG, tempreg);
2512
2513 tempreg = _VPU_Read2Byte(VPU_REG_CPU_SETTING);
2514 // 0xf means VPU is not stalled
2515 if (tempreg & 0xf) {
2516 // write R2 RIU registers to select DCU/ICU debug data
2517 // Writing these registers here provides enough time for them to
2518 // take effect.
2519 tempreg1 = _VPU_Read2Byte(VPU_REG_DCU_DBG_SEL);
2520 tempreg1 |= VPU_REG_DCU_DBG_SEL_0 | VPU_REG_DCU_DBG_SEL_1;
2521 _VPU_Write2Byte(VPU_REG_DCU_DBG_SEL, tempreg1);
2522 _VPU_Write2Byte(VPU_REG_ICU_DBG_SEL, 0);
2523
2524 // wait at least 1ms for VPU_REG_CPU_STALL_EN to take effect
2525 // This step is important because in the next step we want to make
2526 // sure "DCU is not replaying when R2 is stalled".
2527 idle_cnt = 100;
2528 do
2529 {
2530 if (--idle_cnt == 0)
2531 {
2532 printf("VPU_REG_CPU_STALL_EN is not set\n");
2533 break;
2534 }
2535 MsOS_DelayTask(1);
2536 } while ((_VPU_Read2Byte(VPU_REG_CPU_CONFIG) & VPU_REG_CPU_STALL_EN) == 0);
2537 // check CPU status: DCU should NOT be replaying
2538 // If R2 has been stalled, we can guarantee that if we found DCU is
2539 // NOT replaying, it will NOT replay later even CPU is going to issue
2540 // a load/store instruction.
2541 idle_cnt = 100;
2542 while (_VPU_Read2Byte(VPU_REG_CPU_STATUS) & VPU_REG_CPU_D_REPLAY)
2543 {
2544 if (--idle_cnt == 0)
2545 {
2546 printf("DCU is replaying\n");
2547 break;
2548 }
2549 MsOS_DelayTask(1);
2550 }
2551 // wait 1ms to prevent race condition between (1) DCU is not
2552 // replaying, and (2) BIU start to doing new job or ICU start to
2553 // fetch new instruction
2554 MsOS_DelayTask(1);
2555
2556 // check BIU should be empty
2557 idle_cnt = 100;
2558 while ( (_VPU_Read2Byte(VPU_REG_DCU_STATUS) & VPU_REG_BIU_EMPTY) == 0 )
2559 {
2560 if (--idle_cnt == 0)
2561 {
2562 printf("BIU DCU idle time out~~~~~\n");
2563 break;
2564 }
2565 MsOS_DelayTask(1);
2566 }
2567 if (idle_cnt == 0)
2568 {
2569 VPU_MSG_INFO("BIU DCU idle time out~~~~~\n");
2570 }
2571 // check CPU is not requesting ICU
2572 idle_cnt = 100;
2573 while (_VPU_Read2Byte(VPU_REG_ICU_DBG_DAT0) & VPU_REG_ICPU_REQ)
2574 {
2575 if (--idle_cnt == 0)
2576 {
2577 printf("CPU keeps requesting ICU\n");
2578 break;
2579 }
2580 MsOS_DelayTask(1);
2581 }
2582 // wait 1ms to avoid race condition of (1) CPU stop requesting ICU, and
2583 // (2) ISB start to fetch
2584 MsOS_DelayTask(1);
2585
2586 // check ISB should be idle
2587 idle_cnt = 100;
2588 while ( (_VPU_Read2Byte(VPU_REG_ICU_STATUS) & VPU_REG_ISB_IDLE) == 0 )
2589 {
2590 if (--idle_cnt == 0) {
2591 VPU_MSG_INFO("BIU ICU idle time out~~~~~\n");
2592 break;
2593 }
2594 MsOS_DelayTask(1);
2595 }
2596 }
2597 #ifdef HAL_FEATURE_MAU
2598 //MAU has been removed since manhattan, so it is not necessary to check MAU status
2599
2600 if (bCheckMauIdle)
2601 {
2602 MS_U32 mau_idle_cnt = 100;// ms
2603 while (mau_idle_cnt)
2604 {
2605 if (TRUE == _VPU_EX_MAU_IDLE())
2606 {
2607 break;
2608 }
2609 mau_idle_cnt--;
2610 MsOS_DelayTask(1);
2611 }
2612
2613 if (mau_idle_cnt == 0)
2614 {
2615 VPU_MSG_INFO("MAU idle time out~~~~~\n");
2616 }
2617 }
2618 #endif
2619
2620 // this command set MIU to block R2 (does not ack R2's request)
2621 HAL_VPU_EX_MIU_RW_Protect(TRUE);
2622
2623 #ifdef HAL_FEATURE_MAU
2624 // reset MAU
2625 tempreg1 = _VPU_Read2Byte(MAU1_CPU_RST);
2626 tempreg1 |= MAU1_REG_SW_RESET;
2627 _VPU_Write2Byte(MAU1_CPU_RST, tempreg1);
2628 #if defined(UDMA_FPGA_ENVI)
2629 tempreg = _VPU_Read2Byte(VPU_REG_RESET);
2630 _VPU_Write2Byte(VPU_REG_RESET, (tempreg& 0xfffd));
2631 #endif
2632 #endif
2633
2634 // reset R2
2635 // We should trigger MIU reset before R2 reset. If we set MIU/R2 reset
2636 // by the same RIU write, the R2 reset signal may reach afifo eralier
2637 // than MIU reset and afifo write pointer will be reset to position 0.
2638 // In this case, afifo consider it is not empty because read/write
2639 // pointer are mismatch and then BIU sends out unpredicted MIU request.
2640 tempreg = _VPU_Read2Byte(VPU_REG_CPU_SETTING);
2641 tempreg &= ~VPU_REG_CPU_MIU_SW_RSTZ;
2642 _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2643 VPU_EX_TimerDelayMS(1);
2644 tempreg &= ~VPU_REG_CPU_R2_EN;
2645 tempreg &= ~VPU_REG_CPU_SW_RSTZ;
2646 _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2647
2648 VPU_EX_TimerDelayMS(1);
2649
2650 // this command set MIU to accept R2 (can ack R2's request)
2651 HAL_VPU_EX_MIU_RW_Protect(FALSE);
2652
2653 pVPUHalContext->_bVPURsted = FALSE;
2654 return TRUE;
2655 }
2656
2657 ///-----------------------------------------------------------------------------
2658 /// CPU reset release
2659 ///-----------------------------------------------------------------------------
HAL_VPU_EX_SwRstRelse(void)2660 void HAL_VPU_EX_SwRstRelse(void)
2661 {
2662 MS_U16 tempreg = 0;
2663
2664 tempreg = _VPU_Read2Byte(VPU_REG_CPU_CONFIG);
2665 tempreg &= ~VPU_REG_CPU_STALL_EN;
2666 _VPU_Write2Byte(VPU_REG_CPU_CONFIG, tempreg);
2667
2668 tempreg = _VPU_Read2Byte(VPU_REG_CPU_SETTING);
2669 tempreg |= VPU_REG_CPU_MIU_SW_RSTZ;
2670 _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2671 VPU_EX_TimerDelayMS(1);
2672 tempreg |= VPU_REG_CPU_SW_RSTZ;
2673 _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2674 VPU_EX_TimerDelayMS(1);
2675 tempreg |= VPU_REG_CPU_R2_EN;
2676 _VPU_Write2Byte(VPU_REG_CPU_SETTING, tempreg);
2677 #ifdef HAL_FEATURE_MAU
2678 MS_U16 tempreg1 = 0;
2679 tempreg1 = _VPU_Read2Byte(MAU1_CPU_RST);
2680 tempreg1 &= ~MAU1_REG_SW_RESET;
2681 _VPU_Write2Byte(MAU1_CPU_RST, tempreg1);
2682 #endif
2683 pVPUHalContext->_bVPURsted = TRUE;
2684 }
2685
HAL_VPU_EX_SwRelseMAU(void)2686 void HAL_VPU_EX_SwRelseMAU(void)
2687 {
2688 #ifdef HAL_FEATURE_MAU
2689 MS_U16 tempreg = 0;
2690
2691 tempreg = _VPU_Read2Byte(MAU1_CPU_RST);
2692 tempreg &= ~MAU1_REG_SW_RESET;
2693 _VPU_Write2Byte(MAU1_CPU_RST, tempreg);
2694 #endif
2695 }
2696
HAL_VPU_EX_MemRead(MS_VIRT u32Addr)2697 MS_U32 HAL_VPU_EX_MemRead(MS_VIRT u32Addr)
2698 {
2699 MS_U32 u32value = 0;
2700
2701 return u32value;
2702 }
2703
HAL_VPU_EX_MemWrite(MS_VIRT u32Addr,MS_U32 u32value)2704 MS_BOOL HAL_VPU_EX_MemWrite(MS_VIRT u32Addr, MS_U32 u32value)
2705 {
2706 MS_BOOL bRet = TRUE;
2707
2708 return bRet;
2709 }
2710
2711 ///-----------------------------------------------------------------------------
2712 /// Check AVCH264 Ready or not
2713 /// @return TRUE or FALSE
2714 /// - TRUE, MailBox is free
2715 /// - FALSE, MailBox is busy
2716 /// @param u8MBox \b IN: MailBox to check
2717 /// - AVCH264_HI_MBOX0,
2718 /// - AVCH264_HI_MBOX1,
2719 /// - AVCH264_RISC_MBOX0,
2720 /// - AVCH264_RISC_MBOX1,
2721 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxRdy(MS_U32 u32type)2722 MS_BOOL HAL_VPU_EX_MBoxRdy(MS_U32 u32type)
2723 {
2724 MS_BOOL bResult = FALSE;
2725
2726 switch (u32type)
2727 {
2728 case VPU_HI_MBOX0:
2729 bResult = (_VPU_Read2Byte(VPU_REG_HI_MBOX_RDY) & VPU_REG_HI_MBOX0_RDY) ? FALSE : TRUE;
2730 break;
2731 case VPU_HI_MBOX1:
2732 bResult = (_VPU_Read2Byte(VPU_REG_HI_MBOX_RDY) & VPU_REG_HI_MBOX1_RDY) ? FALSE : TRUE;
2733 break;
2734 case VPU_RISC_MBOX0:
2735 bResult = (_VPU_Read2Byte(VPU_REG_RISC_MBOX_RDY) & VPU_REG_RISC_MBOX0_RDY) ? TRUE : FALSE;
2736 break;
2737 case VPU_RISC_MBOX1:
2738 bResult = (_VPU_Read2Byte(VPU_REG_RISC_MBOX_RDY) & VPU_REG_RISC_MBOX1_RDY) ? TRUE : FALSE;
2739 break;
2740 default:
2741 break;
2742 }
2743 return bResult;
2744 }
2745
2746
2747 ///-----------------------------------------------------------------------------
2748 /// Read message from AVCH264
2749 /// @return TRUE or FALSE
2750 /// - TRUE, success
2751 /// - FALSE, failed
2752 /// @param u8MBox \b IN: MailBox to read
2753 /// - AVCH264_RISC_MBOX0
2754 /// - AVCH264_RISC_MBOX1
2755 /// @param u32Msg \b OUT: message read
2756 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxRead(MS_U32 u32type,MS_U32 * u32Msg)2757 MS_BOOL HAL_VPU_EX_MBoxRead(MS_U32 u32type, MS_U32 * u32Msg)
2758 {
2759 MS_BOOL bResult = TRUE;
2760
2761 switch (u32type)
2762 {
2763 case VPU_HI_MBOX0:
2764 *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX0_H)) << 16) |
2765 ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX0_L)));
2766 break;
2767 case VPU_HI_MBOX1:
2768 *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX1_H)) << 16) |
2769 ((MS_U32) (_VPU_Read2Byte(VPU_REG_HI_MBOX1_L)));
2770 break;
2771 case VPU_RISC_MBOX0:
2772 *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX0_H)) << 16) |
2773 ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX0_L)));
2774 break;
2775 case VPU_RISC_MBOX1:
2776 *u32Msg = ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX1_H)) << 16) |
2777 ((MS_U32) (_VPU_Read2Byte(VPU_REG_RISC_MBOX1_L)));
2778 break;
2779 default:
2780 *u32Msg = 0;
2781 bResult = FALSE;
2782 break;
2783 }
2784 return bResult;
2785 }
2786
2787 ///-----------------------------------------------------------------------------
2788 /// Mailbox from AVCH264 clear bit resest
2789 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxClear(MS_U32 u32type)2790 void HAL_VPU_EX_MBoxClear(MS_U32 u32type)
2791 {
2792 switch (u32type)
2793 {
2794 case VPU_RISC_MBOX0:
2795 _VPU_WriteWordMask(VPU_REG_RISC_MBOX_CLR, VPU_REG_RISC_MBOX0_CLR, VPU_REG_RISC_MBOX0_CLR);
2796 break;
2797 case VPU_RISC_MBOX1:
2798 _VPU_WriteWordMask(VPU_REG_RISC_MBOX_CLR, VPU_REG_RISC_MBOX1_CLR, VPU_REG_RISC_MBOX1_CLR);
2799 break;
2800 default:
2801 break;
2802 }
2803 }
2804
2805 ///-----------------------------------------------------------------------------
2806 /// Send message to AVCH264
2807 /// @return TRUE or FALSE
2808 /// - TRUE, Success
2809 /// - FALSE, Failed
2810 /// @param u8MBox \b IN: MailBox
2811 /// - AVCH264_HI_MBOX0,
2812 /// - AVCH264_HI_MBOX1,
2813 ///-----------------------------------------------------------------------------
HAL_VPU_EX_MBoxSend(MS_U32 u32type,MS_U32 u32Msg)2814 MS_BOOL HAL_VPU_EX_MBoxSend(MS_U32 u32type, MS_U32 u32Msg)
2815 {
2816 MS_BOOL bResult = TRUE;
2817
2818 VPU_MSG_DBG("type=%u, msg=0x%x\n", u32type, u32Msg);
2819
2820 switch (u32type)
2821 {
2822 case VPU_HI_MBOX0:
2823 {
2824 _VPU_Write4Byte(VPU_REG_HI_MBOX0_L, u32Msg);
2825 _VPU_WriteWordMask(VPU_REG_HI_MBOX_SET, VPU_REG_HI_MBOX0_SET, VPU_REG_HI_MBOX0_SET);
2826 break;
2827 }
2828 case VPU_HI_MBOX1:
2829 {
2830 _VPU_Write4Byte(VPU_REG_HI_MBOX1_L, u32Msg);
2831 _VPU_WriteWordMask(VPU_REG_HI_MBOX_SET, VPU_REG_HI_MBOX1_SET, VPU_REG_HI_MBOX1_SET);
2832 break;
2833 }
2834 default:
2835 {
2836 bResult = FALSE;
2837 break;
2838 }
2839 }
2840
2841 return bResult;
2842 }
2843
HAL_VPU_EX_GetProgCnt(void)2844 MS_U32 HAL_VPU_EX_GetProgCnt(void)
2845 {
2846
2847 MS_U16 expc_l=0;
2848 MS_U16 expc_h=0;
2849 expc_l = _VPU_Read2Byte(VPU_REG_EXPC_L) & 0xFFFF;
2850 expc_h = _VPU_Read2Byte(VPU_REG_EXPC_H) & 0xFFFF;
2851 return (((MS_U32)expc_h) << 16) | (MS_U32)expc_l;
2852 }
2853
HAL_VPU_EX_GetTaskId(MS_U32 u32Id)2854 MS_U8 HAL_VPU_EX_GetTaskId(MS_U32 u32Id)
2855 {
2856 return _VPU_EX_GetOffsetIdx(u32Id);
2857 }
2858
HAL_VPU_EX_SetShareInfoAddr(MS_U32 u32Id,MS_VIRT u32ShmAddr)2859 void HAL_VPU_EX_SetShareInfoAddr(MS_U32 u32Id, MS_VIRT u32ShmAddr)
2860 {
2861 MS_U8 u8Offset = _VPU_EX_GetOffsetIdx(u32Id);
2862
2863 if (u32ShmAddr == 0)
2864 {
2865 pVPUHalContext->u32FWShareInfoAddr[u8Offset] = 0xFFFFFFFFUL;
2866 }
2867 else
2868 {
2869 if (u8Offset == 0)
2870 {
2871 pVPUHalContext->u32FWShareInfoAddr[u8Offset] = u32ShmAddr;
2872 }
2873 else if (u8Offset == 1)
2874 {
2875 pVPUHalContext->u32FWShareInfoAddr[u8Offset] = u32ShmAddr + TEE_ONE_TASK_SHM_SIZE;
2876 }
2877 }
2878
2879 VPU_MSG_DBG("set PA ShareInfoAddr[%d] = 0x%lx \n", u8Offset, (unsigned long)pVPUHalContext->u32FWShareInfoAddr[u8Offset]);
2880 return;
2881 }
2882
HAL_VPU_EX_GetShareInfoAddr(MS_U32 u32Id)2883 MS_VIRT HAL_VPU_EX_GetShareInfoAddr(MS_U32 u32Id)
2884 {
2885 MS_U8 u8Offset = _VPU_EX_GetOffsetIdx(u32Id);
2886
2887 return pVPUHalContext->u32FWShareInfoAddr[u8Offset];
2888 }
2889
2890
HAL_VPU_EX_IsPowered(void)2891 MS_BOOL HAL_VPU_EX_IsPowered(void)
2892 {
2893 return pVPUHalContext->_bVPUPowered;
2894 }
2895
HAL_VPU_EX_IsRsted(void)2896 MS_BOOL HAL_VPU_EX_IsRsted(void)
2897 {
2898 return pVPUHalContext->_bVPURsted;
2899 }
2900
HAL_VPU_EX_IsEVDR2(void)2901 MS_BOOL HAL_VPU_EX_IsEVDR2(void)
2902 {
2903 #ifdef EVDR2
2904 return TRUE;
2905 #else
2906 return FALSE;
2907 #endif
2908 }
2909
HAL_VPU_EX_MVDInUsed(void)2910 MS_BOOL HAL_VPU_EX_MVDInUsed(void)
2911 {
2912 //MVD is in used for MVD or HVD_TSP mode.
2913 MS_U8 i;
2914 MS_U8 u8UseCnt = 0;
2915
2916 for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
2917 {
2918 if ((pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_MVD) ||
2919 #ifdef VDEC3
2920 (pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_EVD) ||
2921 #endif
2922 (pVPUHalContext->_stVPUStream[i].eDecodertype == E_VPU_EX_DECODER_HVD) )
2923 {
2924 u8UseCnt++;
2925 }
2926 }
2927
2928 VPU_MSG_DBG("MVD u8UseCnt=%d\n", u8UseCnt);
2929
2930 if (u8UseCnt != 0)
2931 {
2932 return TRUE;
2933 }
2934 else
2935 {
2936 return FALSE;
2937 }
2938 }
2939
HAL_VPU_EX_HVDInUsed(void)2940 MS_BOOL HAL_VPU_EX_HVDInUsed(void)
2941 {
2942 //HVD is in used for HVD or MVD in sub stream.
2943 MS_U8 i;
2944 MS_U8 u8UseCnt = 0;
2945 MS_BOOL bMVDTriggerHVD = FALSE;
2946 for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
2947 {
2948 #ifdef VDEC3
2949 bMVDTriggerHVD = (E_VPU_EX_DECODER_MVD == pVPUHalContext->_stVPUStream[i].eDecodertype) &&
2950 (pVPUHalContext->u8HALId[i] == 1) &&
2951 (E_VPU_DEC_MODE_DUAL_INDIE == pVPUHalContext->_stVPUDecMode.u8DecMod);
2952 #else
2953 bMVDTriggerHVD = (E_VPU_EX_DECODER_MVD == pVPUHalContext->_stVPUStream[i].eDecodertype) &&
2954 (E_HAL_VPU_SUB_STREAM0 == pVPUHalContext->_stVPUStream[i].eStreamId) &&
2955 (E_VPU_DEC_MODE_DUAL_INDIE == pVPUHalContext->_stVPUDecMode.u8DecMod);
2956 #endif
2957
2958 if(bMVDTriggerHVD)
2959 {
2960 VPU_MSG_DBG("%s i:%d eDecodertype:%d u8DecMod:%d\n",__FUNCTION__,i,pVPUHalContext->_stVPUStream[i].eDecodertype,pVPUHalContext->_stVPUDecMode.u8DecMod);
2961 }
2962
2963 if ((E_VPU_EX_DECODER_HVD == pVPUHalContext->_stVPUStream[i].eDecodertype)
2964 #ifdef VDEC3
2965 ||(E_VPU_EX_DECODER_EVD == pVPUHalContext->_stVPUStream[i].eDecodertype)
2966 #endif
2967 ||(TRUE == bMVDTriggerHVD)
2968 )
2969 {
2970 u8UseCnt++;
2971 }
2972 }
2973
2974 VPU_MSG_DBG("HVD u8UseCnt=%d\n", u8UseCnt);
2975
2976 if (u8UseCnt != 0)
2977 {
2978 return TRUE;
2979 }
2980 else
2981 {
2982 return FALSE;
2983 }
2984 }
2985
2986 #ifdef VDEC3
HAL_VPU_EX_EVDInUsed(void)2987 MS_BOOL HAL_VPU_EX_EVDInUsed(void)
2988 {
2989 MS_U8 i;
2990 MS_U8 u8UseCnt = 0;
2991
2992 for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
2993 {
2994 if (E_VPU_EX_DECODER_EVD == pVPUHalContext->_stVPUStream[i].eDecodertype)
2995 {
2996 u8UseCnt++;
2997 }
2998 }
2999
3000 VPU_MSG_DBG("EVD u8UseCnt=%d\n", u8UseCnt);
3001
3002 if (u8UseCnt != 0)
3003 {
3004 return TRUE;
3005 }
3006 else
3007 {
3008 return FALSE;
3009 }
3010 }
3011
3012 #if SUPPORT_G2VP9 && defined(VDEC3)
HAL_VPU_EX_G2VP9InUsed(void)3013 MS_BOOL HAL_VPU_EX_G2VP9InUsed(void)
3014 {
3015 MS_U8 i;
3016 MS_U8 u8UseCnt = 0;
3017
3018 for (i = 0; i < sizeof(pVPUHalContext->_stVPUStream) / sizeof(pVPUHalContext->_stVPUStream[0]); i++)
3019 {
3020 if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[i].eDecodertype)
3021 {
3022 u8UseCnt++;
3023 }
3024 }
3025
3026 VPU_MSG_DBG("G2 VP9 u8UseCnt=%d\n", u8UseCnt);
3027
3028 if (u8UseCnt != 0)
3029 {
3030 return TRUE;
3031 }
3032 else
3033 {
3034 return FALSE;
3035 }
3036 }
3037 #endif
3038 #endif
3039
3040 //-----------------------------------------------------------------------------
3041 /// @brief \b Function \b Name: MDrv_HVD_EX_SetDbgLevel()
3042 /// @brief \b Function \b Description: Set debug level
3043 /// @param -elevel \b IN : debug level
3044 //-----------------------------------------------------------------------------
HAL_VPU_EX_SetDbgLevel(VPU_EX_UartLevel eLevel)3045 void HAL_VPU_EX_SetDbgLevel(VPU_EX_UartLevel eLevel)
3046 {
3047 VPRINTF("%s eLevel=0x%x\n", __FUNCTION__, eLevel);
3048
3049 switch (eLevel)
3050 {
3051 case E_VPU_EX_UART_LEVEL_ERR:
3052 {
3053 u32VpuUartCtrl = E_VPU_UART_CTRL_ERR;
3054 break;
3055 }
3056 case E_VPU_EX_UART_LEVEL_INFO:
3057 {
3058 u32VpuUartCtrl = E_VPU_UART_CTRL_INFO | E_VPU_UART_CTRL_ERR;
3059 break;
3060 }
3061 case E_VPU_EX_UART_LEVEL_DBG:
3062 {
3063 u32VpuUartCtrl = E_VPU_UART_CTRL_DBG | E_VPU_UART_CTRL_ERR | E_VPU_UART_CTRL_INFO;
3064 break;
3065 }
3066 case E_VPU_EX_UART_LEVEL_TRACE:
3067 {
3068 u32VpuUartCtrl = E_VPU_UART_CTRL_TRACE | E_VPU_UART_CTRL_ERR | E_VPU_UART_CTRL_INFO | E_VPU_UART_CTRL_DBG;
3069 break;
3070 }
3071 case E_VPU_EX_UART_LEVEL_FW:
3072 {
3073 u32VpuUartCtrl = E_VPU_UART_CTRL_DISABLE;
3074 break;
3075 }
3076 default:
3077 {
3078 u32VpuUartCtrl = E_VPU_UART_CTRL_DISABLE;
3079 break;
3080 }
3081 }
3082 }
3083
HAL_VPU_EX_GetFWVer(MS_U32 u32Id,VPU_EX_FWVerType eVerType)3084 MS_U32 HAL_VPU_EX_GetFWVer(MS_U32 u32Id, VPU_EX_FWVerType eVerType)
3085 {
3086 HVD_Return eCtrlRet = E_HVD_RETURN_FAIL;
3087 MS_U32 u32CmdArg = (MS_U32)eVerType;
3088 MS_U32 u32Version = 0xFFFFFFFF;
3089 eCtrlRet = HAL_HVD_EX_SetCmd(u32Id, E_DUAL_VERSION, u32CmdArg);
3090 if (E_HVD_RETURN_SUCCESS != eCtrlRet)
3091 {
3092 VPU_MSG_ERR("E_DUAL_VERSION NG eCtrlRet=%x\n", eCtrlRet);
3093 return u32Version;
3094 }
3095
3096 MS_BOOL bRet = false;
3097 MS_U32 u32TimeOut = 0xFFFFFFFF;
3098
3099 while(--u32TimeOut)
3100 {
3101 if(HAL_VPU_EX_MBoxRdy(VPU_RISC_MBOX0))
3102 {
3103 bRet = HAL_VPU_EX_MBoxRead(VPU_RISC_MBOX0, &u32Version);
3104 if (false == bRet)
3105 {
3106 VPU_MSG_ERR("E_DUAL_VERSION NG bRet=%x\n", bRet);
3107 return u32Version;
3108 }
3109
3110 _VPU_WriteWordMask( VPU_REG_RISC_MBOX_CLR , VPU_REG_RISC_MBOX0_CLR , VPU_REG_RISC_MBOX0_CLR);
3111 VPU_MSG_DBG("E_DUAL_VERSION arg=%x u32Version = 0x%x\n", u32CmdArg, u32Version);
3112 return u32Version;
3113 }
3114 }
3115
3116 VPU_MSG_ERR("get E_DUAL_VERSION=%x timeout", eVerType);
3117
3118 return u32Version;
3119 }
3120
HAL_VPU_EX_NotSupportDS(void)3121 MS_BOOL HAL_VPU_EX_NotSupportDS(void)
3122 {
3123 return FALSE;
3124 }
3125
3126 //-----------------------------------------------------------------------------
3127 /// @brief \b Function \b Name: HAL_VPU_EX_MIU1BASE()
3128 /// @brief \b Function \b Description: Get VPU MIU base address
3129 /// @return - vpu MIU1 base
3130 //-----------------------------------------------------------------------------
HAL_VPU_EX_MIU1BASE(void)3131 MS_VIRT HAL_VPU_EX_MIU1BASE(void)
3132 {
3133 return VPU_MIU1BASE_ADDR;
3134 }
3135
3136
HAL_VPU_EX_GetSHMAddr(void)3137 MS_VIRT HAL_VPU_EX_GetSHMAddr(void)
3138 {
3139 if(pVPUHalContext->bEnableVPUSecureMode == FALSE)
3140 {
3141 return 0;
3142 }
3143 return pVPUHalContext->u32VPUSHMAddr;
3144 }
HAL_VPU_EX_EnableSecurityMode(MS_BOOL enable)3145 MS_BOOL HAL_VPU_EX_EnableSecurityMode(MS_BOOL enable)
3146 {
3147 pVPUHalContext->bEnableVPUSecureMode = enable;
3148 return TRUE;
3149 }
3150
HAL_VPU_EX_CHIP_Capability(void * pHWCap)3151 MS_BOOL HAL_VPU_EX_CHIP_Capability(void* pHWCap)
3152 {
3153 ((VDEC_HwCap*)pHWCap)->u8Cap_Support_Decoder_Num = 2;
3154
3155 ((VDEC_HwCap*)pHWCap)->bCap_Support_MPEG2 = TRUE;
3156 ((VDEC_HwCap*)pHWCap)->bCap_Support_H263 = TRUE;
3157 ((VDEC_HwCap*)pHWCap)->bCap_Support_MPEG4 = TRUE;
3158 ((VDEC_HwCap*)pHWCap)->bCap_Support_DIVX311 = TRUE;
3159 ((VDEC_HwCap*)pHWCap)->bCap_Support_DIVX412 = TRUE;
3160 ((VDEC_HwCap*)pHWCap)->bCap_Support_FLV = TRUE;
3161 ((VDEC_HwCap*)pHWCap)->bCap_Support_VC1ADV = TRUE;
3162 ((VDEC_HwCap*)pHWCap)->bCap_Support_VC1MAIN = TRUE;
3163
3164 ((VDEC_HwCap*)pHWCap)->bCap_Support_RV8 = TRUE;
3165 ((VDEC_HwCap*)pHWCap)->bCap_Support_RV9 = TRUE;
3166 ((VDEC_HwCap*)pHWCap)->bCap_Support_H264 = TRUE;
3167 ((VDEC_HwCap*)pHWCap)->bCap_Support_AVS = TRUE;
3168 ((VDEC_HwCap*)pHWCap)->bCap_Support_MJPEG = TRUE;
3169 ((VDEC_HwCap*)pHWCap)->bCap_Support_MVC = TRUE;
3170 ((VDEC_HwCap*)pHWCap)->bCap_Support_VP8 = TRUE;
3171 ((VDEC_HwCap*)pHWCap)->bCap_Support_HEVC = TRUE;
3172 ((VDEC_HwCap*)pHWCap)->bCap_Support_VP9 = TRUE;
3173 ((VDEC_HwCap*)pHWCap)->bCap_Support_AVS_PLUS = TRUE;
3174
3175 return TRUE;
3176 }
3177
3178 //-----------------------------------------------------------------------------
3179 /// @brief \b Function \b Name: HAL_VPU_EX_GetCodecCapInfo()
3180 /// @brief \b Function \b Description: Get chip codec capability (for vudu)
3181 /// @return - success/fail
3182 //-----------------------------------------------------------------------------
HAL_VPU_EX_GetCodecCapInfo(int eCodecType,VDEC_EX_CODEC_CAP_INFO * pCodecCapInfo)3183 MS_BOOL HAL_VPU_EX_GetCodecCapInfo( int eCodecType, VDEC_EX_CODEC_CAP_INFO *pCodecCapInfo)
3184 {
3185 #define MAX_CAPABILITY_INFO_NUM 8
3186 #define MAX_CODEC_TYPE_NUM 18
3187
3188 unsigned int capability[MAX_CODEC_TYPE_NUM][MAX_CAPABILITY_INFO_NUM] =
3189 {
3190 //width, height , frmrate, profile, level, version reserved1 reserved2
3191 { 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
3192 { 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
3193 { 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
3194 { 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
3195 { 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
3196 { 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
3197 { 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
3198 { 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
3199 { 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)
3200 { 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
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_RV9
3202 { 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
3203 { 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
3204 { 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
3205 { 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
3206 { 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
3207 { 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
3208 { 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
3209 };
3210
3211 if(eCodecType < MAX_CODEC_TYPE_NUM)
3212 {
3213 pCodecCapInfo->u16CodecCapWidth = capability[eCodecType][0];
3214 pCodecCapInfo->u16CodecCapHeight = capability[eCodecType][1];
3215 pCodecCapInfo->u8CodecCapFrameRate = capability[eCodecType][2];
3216 pCodecCapInfo->u8CodecCapProfile = capability[eCodecType][3];
3217 pCodecCapInfo->u8CodecCapLevel = capability[eCodecType][4];
3218 pCodecCapInfo->u8CodecCapVersion = capability[eCodecType][5];
3219 return TRUE;
3220 }
3221 else
3222 {
3223 return FALSE;
3224 }
3225 }
3226
3227
3228
3229
3230 #ifdef VDEC3
HAL_VPU_EX_GetBBUId(MS_U32 u32Id,VPU_EX_TaskInfo * pTaskInfo,MS_BOOL bIsNstreamMode)3231 MS_U32 HAL_VPU_EX_GetBBUId(MS_U32 u32Id, VPU_EX_TaskInfo *pTaskInfo, MS_BOOL bIsNstreamMode)
3232 {
3233 MS_U32 i, max_bbu_cnt;
3234 MS_U32 retBBUId = HAL_VPU_INVALID_BBU_ID;
3235
3236 if(pTaskInfo == NULL)
3237 return retBBUId;
3238
3239 BBU_STATE *bbu_state;
3240 SLQ_STATE *slq_state = &pVPUHalContext->stMVD_SLQ_STATE[0];
3241 MS_U8 u8TaskId = HAL_VPU_EX_GetTaskId(u32Id);
3242
3243 MS_BOOL bTSP = (pTaskInfo->eSrcType == E_VPU_EX_INPUT_TSP);
3244
3245 pVPUHalContext->u8HALId[u8TaskId] = pTaskInfo->u8HalId;
3246
3247 /* HVD_EX_MSG_ERR("[%d] DecType=0x%x \n", u32Id & 0xFF, pTaskInfo->eDecType);
3248 for(i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3249 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);
3250
3251 for(i = 0; i < MAX_EVD_BBU_COUNT; i++)
3252 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);
3253
3254 for(i = 0; i < MAX_HVD_BBU_COUNT; i++)
3255 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);
3256 */
3257 #if 1
3258 if(pTaskInfo->eDecType == E_VPU_EX_DECODER_MVD) // MVD case
3259 {
3260 max_bbu_cnt = MAX_MVD_SLQ_COUNT;
3261 if (bTSP)
3262 {
3263 if ((u8TaskId < MAX_MVD_SLQ_COUNT) && (slq_state[u8TaskId].u32Used == 0))
3264 {
3265 slq_state[u8TaskId].u32Used |= (1 << u8TaskId); // Record the HVD use the TSP parser
3266 slq_state[u8TaskId].bTSP = TRUE;
3267 slq_state[u8TaskId].bUsedbyMVD = TRUE;
3268 return u8TaskId;
3269 }
3270 }
3271 else
3272 {
3273 MS_U32 shared_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3274 MS_U32 avaliable_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3275 for (i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3276 {
3277 if (slq_state[i].u32Used != 0)
3278 {
3279 if (shared_bbu_idx == HAL_VPU_INVALID_BBU_ID && slq_state[i].bTSP == FALSE)
3280 {
3281 shared_bbu_idx = i; // recored the first used MM bbu for sharing
3282 }
3283 }
3284 else if (avaliable_bbu_idx == HAL_VPU_INVALID_BBU_ID)
3285 {
3286 avaliable_bbu_idx = i; // recored the first empty bbu
3287 }
3288 }
3289
3290 if (bIsNstreamMode && shared_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // In Nstream mode, first priority is sharing bbu
3291 slq_state[shared_bbu_idx].u32Used |= (1 << u8TaskId);
3292 slq_state[shared_bbu_idx].bTSP = FALSE;
3293 slq_state[shared_bbu_idx].bUsedbyMVD = TRUE;
3294 return shared_bbu_idx;
3295 }
3296 else if (slq_state[u8TaskId].u32Used == FALSE && u8TaskId < max_bbu_cnt) { // 2nd priority is task id
3297 slq_state[u8TaskId].u32Used |= (1 << u8TaskId);
3298 slq_state[u8TaskId].bTSP = FALSE;
3299 slq_state[u8TaskId].bUsedbyMVD = TRUE;
3300 return u8TaskId;
3301 }
3302 else if (avaliable_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // 3rd priority is avaliable bbu id
3303 slq_state[avaliable_bbu_idx].u32Used |= (1 << u8TaskId);
3304 slq_state[avaliable_bbu_idx].bTSP = FALSE;
3305 slq_state[avaliable_bbu_idx].bUsedbyMVD = TRUE;
3306 return avaliable_bbu_idx;
3307 }
3308 else {
3309 VPU_MSG_ERR("ERROR!!! can't get avaliable BBU ID taskId=%d at %s\n", u8TaskId, __FUNCTION__);
3310 }
3311 }
3312 }
3313 #if SUPPORT_G2VP9
3314 else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_G2VP9) // G2_VP9 case
3315 {
3316 // G2_VP9 don't have the concept of BBU, so we don't need to record the hardware BBU usage situation
3317 // Don't care the return value, G2_VP9 will not use it.
3318 return 0;
3319 }
3320 #endif
3321 else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_VP8) // VP8 case
3322 {
3323 // G2_VP8 always use the same BBU, so we don't need to record the hardware BBU usage situation
3324 // Don't care the return value, VP8 will not use it.
3325 return 0;
3326 }
3327 else
3328 {
3329 switch (pTaskInfo->eDecType)
3330 {
3331 case E_VPU_EX_DECODER_EVD:
3332 max_bbu_cnt = MAX_EVD_BBU_COUNT;
3333 bbu_state = &pVPUHalContext->stEVD_BBU_STATE[0];
3334 break;
3335 case E_VPU_EX_DECODER_HVD:
3336 case E_VPU_EX_DECODER_RVD:
3337 case E_VPU_EX_DECODER_MVC:
3338 default:
3339 max_bbu_cnt = MAX_HVD_BBU_COUNT;
3340 bbu_state = &pVPUHalContext->stHVD_BBU_STATE[0];
3341 break;
3342 }
3343
3344 // FIXME: TSP assume bbu id = u8TaskId, so it does not support N decode. Use the same logic with MM to support it
3345 if (bTSP)
3346 {
3347 if ((u8TaskId < max_bbu_cnt) && (bbu_state[u8TaskId].u32Used == 0) && (slq_state[u8TaskId].u32Used == 0))
3348 {
3349 bbu_state[u8TaskId].u32Used |= (1 << u8TaskId);
3350 bbu_state[u8TaskId].bTSP = TRUE;
3351 slq_state[u8TaskId].u32Used |= (1 << u8TaskId); // Record the HVD use the TSP parser
3352 slq_state[u8TaskId].bTSP = TRUE;
3353 slq_state[u8TaskId].bUsedbyMVD = FALSE;
3354 return u8TaskId;
3355 }
3356 }
3357 else
3358 {
3359 MS_U32 shared_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3360 MS_U32 avaliable_bbu_idx = HAL_VPU_INVALID_BBU_ID;
3361 for (i = 0; i < max_bbu_cnt; i++)
3362 {
3363 if (shared_bbu_idx == HAL_VPU_INVALID_BBU_ID && bbu_state[i].u32Used != 0)
3364 {
3365 if (bbu_state[i].bTSP == FALSE)
3366 {
3367 shared_bbu_idx = i;
3368 }
3369 }
3370 else if (avaliable_bbu_idx == HAL_VPU_INVALID_BBU_ID)
3371 {
3372 avaliable_bbu_idx = i;
3373 }
3374 }
3375 if (bIsNstreamMode && shared_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // // In Nstream mode, first priority is sharing bbu
3376 bbu_state[shared_bbu_idx].u32Used |= (1 << u8TaskId);
3377 return shared_bbu_idx;
3378 }
3379 else if (bbu_state[u8TaskId].u32Used == FALSE && u8TaskId < max_bbu_cnt) { // 2nd priority is task id
3380 bbu_state[u8TaskId].u32Used |= (1 << u8TaskId);
3381 return u8TaskId;
3382 }
3383 else if (avaliable_bbu_idx != HAL_VPU_INVALID_BBU_ID) { // 3rd priority is avaliable bbu id
3384 bbu_state[avaliable_bbu_idx].u32Used |= (1 << u8TaskId);
3385 return avaliable_bbu_idx;
3386 }
3387 else {
3388 VPU_MSG_ERR("ERROR!!! can't get avaliable BBU ID taskId=%d at %s\n", u8TaskId, __FUNCTION__);
3389 }
3390 }
3391 }
3392 #else // The following source code is wiser selecting BBU id. Howerver, it need HW to support and we mark it temporarily.
3393 MS_U32 j;
3394 MS_BOOL Got = FALSE;
3395 if(pTaskInfo->eDecType == E_VPU_EX_DECODER_MVD) // MVD case
3396 {
3397 for (i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3398 {
3399 if(slq_state[i].u32Used != 0)
3400 {
3401 if(!bTSP && slq_state[i].bTSP == FALSE) // MVD non-first MM case
3402 {
3403 retBBUId = i;
3404 slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3405 slq_state[retBBUId].bTSP = bTSP;
3406 slq_state[retBBUId].bUsedbyMVD = TRUE;
3407 return retBBUId;
3408 }
3409 }
3410 else if(!Got && slq_state[i].u32Used == 0) // MVD first MM or TS case
3411 {
3412 if(i < MAX_EVD_BBU_COUNT) // Trend to select used EVD BBU id
3413 {
3414 if(pVPUHalContext->stEVD_BBU_STATE[i].u32Used != 0 && pVPUHalContext->stEVD_BBU_STATE[i].bTSP == FALSE)
3415 {
3416 Got = TRUE;
3417 retBBUId = i;
3418 }
3419 }
3420
3421 if(!Got && i < MAX_HVD_BBU_COUNT) // Trend to select used HVD BBU id
3422 {
3423 if(pVPUHalContext->stHVD_BBU_STATE[i].u32Used != 0 && pVPUHalContext->stHVD_BBU_STATE[i].bTSP == FALSE)
3424 {
3425 Got = TRUE;
3426 retBBUId = i;
3427 }
3428 }
3429
3430 if(!Got && retBBUId == HAL_VPU_INVALID_BBU_ID) // if no used EVD BBU id, select the first BBU_ID
3431 retBBUId = i;
3432 }
3433 }
3434 if(retBBUId != HAL_VPU_INVALID_BBU_ID)
3435 {
3436 slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3437 slq_state[retBBUId].bTSP = bTSP;
3438 slq_state[retBBUId].bUsedbyMVD = TRUE;
3439 }
3440 }
3441 #if SUPPORT_G2VP9
3442 else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_G2VP9) // G2_VP9 case
3443 {
3444 // G2_VP9 don't have the concept of BBU, so we don't need to record the hardware BBU usage situation
3445 // Don't care the return value, G2_VP9 will not use it.
3446 return 0;
3447 }
3448 #endif
3449 else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_VP8) // VP8 case
3450 {
3451 // G2_VP8 always use the same BBU, so we don't need to record the hardware BBU usage situation
3452 // Don't care the return value, VP8 will not use it.
3453 return 0;
3454 }
3455 else // HVD/EVD case
3456 {
3457 switch (pTaskInfo->eDecType)
3458 {
3459 case E_VPU_EX_DECODER_EVD:
3460 case E_VPU_EX_DECODER_G2VP9:
3461 max_bbu_cnt = MAX_EVD_BBU_COUNT;
3462 bbu_state = &pVPUHalContext->stEVD_BBU_STATE[0];
3463 break;
3464 case E_VPU_EX_DECODER_HVD:
3465 case E_VPU_EX_DECODER_RVD:
3466 case E_VPU_EX_DECODER_MVC:
3467 default:
3468 max_bbu_cnt = MAX_HVD_BBU_COUNT;
3469 bbu_state = &pVPUHalContext->stHVD_BBU_STATE[0];
3470 break;
3471 }
3472
3473 for (i = 0; i < max_bbu_cnt; i++)
3474 {
3475 if(bbu_state[i].u32Used != 0)
3476 {
3477 if(!bTSP && bbu_state[i].bTSP == FALSE) // HVD/EVD non-first MM case
3478 {
3479 retBBUId = i;
3480 bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3481 bbu_state[retBBUId].bTSP = bTSP;
3482 return retBBUId;
3483 }
3484 }
3485 else if(bbu_state[i].u32Used == 0) // HVD/EVD first MM or TS case
3486 {
3487 if(i < MAX_MVD_SLQ_COUNT)
3488 {
3489 if(!bTSP) //HVD/EVD first MM case
3490 {
3491 if( slq_state[i].u32Used != 0 && slq_state[i].bUsedbyMVD== TRUE) // HVD/EVD MM will trend to select used MVD SLQ id
3492 {
3493 retBBUId = i;
3494 bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3495 bbu_state[retBBUId].bTSP = bTSP;
3496 return retBBUId;
3497 }
3498
3499 if(retBBUId == HAL_VPU_INVALID_BBU_ID) // if no used MVD SLQ id, select the first BBU_ID
3500 retBBUId = i;
3501 }
3502 else if(slq_state[i].u32Used == 0) //HVD/EVD TSP case, just find a empty slq id
3503 {
3504 retBBUId = i;
3505 bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3506 bbu_state[retBBUId].bTSP = bTSP;
3507 slq_state[retBBUId].bUsedbyMVD = FALSE;
3508 slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3509 slq_state[retBBUId].bTSP = bTSP;
3510 return retBBUId;
3511 }
3512 }
3513 }
3514 }
3515 if(retBBUId != HAL_VPU_INVALID_BBU_ID)
3516 {
3517 bbu_state[retBBUId].u32Used |= (1 << u8TaskId);
3518 bbu_state[retBBUId].bTSP = bTSP;
3519 if(bTSP)
3520 {
3521 slq_state[retBBUId].bUsedbyMVD = FALSE;
3522 slq_state[retBBUId].u32Used |= (1 << u8TaskId);
3523 slq_state[retBBUId].bTSP = bTSP;
3524 }
3525 }
3526 }
3527 #endif
3528 return retBBUId;
3529 }
3530
HAL_VPU_EX_FreeBBUId(MS_U32 u32Id,MS_U32 u32BBUId,VPU_EX_TaskInfo * pTaskInfo)3531 MS_BOOL HAL_VPU_EX_FreeBBUId(MS_U32 u32Id, MS_U32 u32BBUId, VPU_EX_TaskInfo *pTaskInfo)
3532 {
3533 MS_U32 max_bbu_cnt;
3534 BBU_STATE *bbu_state;
3535 SLQ_STATE *slq_state = &pVPUHalContext->stMVD_SLQ_STATE[0];
3536
3537 if(pTaskInfo == NULL)
3538 return FALSE;
3539 MS_U8 u8TaskId = HAL_VPU_EX_GetTaskId(u32Id);
3540 MS_BOOL bTSP = (pTaskInfo->eSrcType == E_VPU_EX_INPUT_TSP);
3541
3542 HVD_EX_MSG_DBG("[%d] DecType=0x%x \n", (int)(u32Id & 0xFF), pTaskInfo->eDecType);
3543 /* MS_U32 i;
3544 for(i = 0; i < MAX_MVD_SLQ_COUNT; i++)
3545 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);
3546
3547 for(i = 0; i < MAX_EVD_BBU_COUNT; i++)
3548 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);
3549
3550 for(i = 0; i < MAX_HVD_BBU_COUNT; i++)
3551 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);
3552 */
3553 if(pTaskInfo->eDecType == E_VPU_EX_DECODER_MVD) // MVD case
3554 {
3555 // TO DO
3556 if(u32BBUId < MAX_MVD_SLQ_COUNT)
3557 {
3558 slq_state[u32BBUId].u32Used &= ~(1 << u8TaskId); // Record the HVD use the TSP parser
3559 slq_state[u32BBUId].bTSP = FALSE;
3560 slq_state[u32BBUId].bUsedbyMVD = FALSE;
3561 return TRUE;
3562 }
3563 }
3564 #if SUPPORT_G2VP9
3565 else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_G2VP9) // G2_VP9 case
3566 {
3567 // G2_VP9 don't have the concept of BBU, so we don't need to record the hardware BBU usage situation
3568 return TRUE;
3569 }
3570 #endif
3571 else if(pTaskInfo->eDecType == E_VPU_EX_DECODER_VP8) // VP8 case
3572 {
3573 // G2_VP8 always use the same BBU, so we don't need to record the hardware BBU usage situation
3574 return TRUE;
3575 }
3576 else
3577 {
3578 switch (pTaskInfo->eDecType)
3579 {
3580 case E_VPU_EX_DECODER_EVD:
3581 max_bbu_cnt = MAX_EVD_BBU_COUNT;
3582 bbu_state = &pVPUHalContext->stEVD_BBU_STATE[0];
3583 break;
3584 case E_VPU_EX_DECODER_HVD:
3585 case E_VPU_EX_DECODER_RVD:
3586 case E_VPU_EX_DECODER_MVC:
3587 default:
3588 max_bbu_cnt = MAX_HVD_BBU_COUNT;
3589 bbu_state = &pVPUHalContext->stHVD_BBU_STATE[0];
3590 break;
3591 }
3592
3593 if (u32BBUId < max_bbu_cnt)
3594 {
3595 bbu_state[u32BBUId].u32Used &= ~(1 << u8TaskId);
3596 bbu_state[u32BBUId].bTSP = FALSE;
3597 if (bTSP)
3598 {
3599 slq_state[u32BBUId].u32Used &= ~(1 << u8TaskId); // Record the HVD use the TSP parser
3600 slq_state[u32BBUId].bTSP = FALSE;
3601 slq_state[u32BBUId].bUsedbyMVD = FALSE;
3602 }
3603 return TRUE;
3604 }
3605 }
3606 return FALSE;
3607 }
HAL_VPU_EX_GetVBBUVacancy(MS_VIRT u32VBBUAddr)3608 MS_U32 HAL_VPU_EX_GetVBBUVacancy(MS_VIRT u32VBBUAddr)
3609 {
3610 VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3611
3612 if (CHECK_NULL_PTR(pstVBBU))
3613 return 0;
3614 MS_U32 u32WrPtr = pstVBBU->u32WrPtr;
3615 MS_U32 u32RdPtr = pstVBBU->u32RdPtr;
3616 MS_U32 u32Vacancy = 0;
3617
3618 if (u32WrPtr == u32RdPtr)
3619 {
3620 u32Vacancy = MAX_VDEC_VBBU_ENTRY_COUNT;
3621 }
3622 else if (u32WrPtr > u32RdPtr)
3623 {
3624 u32Vacancy = MAX_VDEC_VBBU_ENTRY_COUNT - (u32WrPtr - u32RdPtr);
3625 }
3626 else
3627 {
3628 u32Vacancy = u32RdPtr - u32WrPtr - 1;
3629 }
3630
3631 return u32Vacancy;
3632 }
3633
HAL_VPU_EX_GetInputQueueNum(MS_U32 u32Id)3634 MS_U32 HAL_VPU_EX_GetInputQueueNum(MS_U32 u32Id)
3635 {
3636 return MAX_VDEC_VBBU_ENTRY_COUNT;
3637 }
3638
HAL_VPU_EX_GetESReadPtr(MS_U32 u32Id,MS_VIRT u32VBBUAddr)3639 MS_VIRT HAL_VPU_EX_GetESReadPtr(MS_U32 u32Id, MS_VIRT u32VBBUAddr)
3640 {
3641 VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3642 #if SUPPORT_G2VP9
3643 MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
3644 #endif
3645
3646 if (CHECK_NULL_PTR(pstVBBU))
3647 return FALSE;
3648 MsOS_ReadMemory();
3649 VDEC_VBBU_Entry *stEntry = (VDEC_VBBU_Entry *) &pstVBBU->stEntry[pstVBBU->u32RdPtr];
3650
3651 // ALOGE("JJJ1: %d %d %d", pstVBBU->u32RdPtr, pstVBBU->u32WrPtr, stEntry->u32Offset);
3652 if (pstVBBU->u32RdPtr == pstVBBU->u32WrPtr)
3653 {
3654 return HAL_VPU_EX_GetESWritePtr(u32Id, u32VBBUAddr);
3655 }
3656 else
3657 {
3658 #if SUPPORT_G2VP9
3659 if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype)
3660 {
3661 if (stEntry->u32Offset == 0)
3662 return 0;
3663 else
3664 return stEntry->u32Offset - pVPUHalContext->u32BitstreamAddress[u8OffsetIdx];
3665 }
3666 else
3667 #endif
3668 {
3669 return stEntry->u32Offset;
3670 }
3671 }
3672 }
3673
HAL_VPU_EX_GetESWritePtr(MS_U32 u32Id,MS_VIRT u32VBBUAddr)3674 MS_VIRT HAL_VPU_EX_GetESWritePtr(MS_U32 u32Id, MS_VIRT u32VBBUAddr)
3675 {
3676 VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3677 VDEC_VBBU_Entry *stEntry;
3678 #if SUPPORT_G2VP9
3679 MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
3680 #endif
3681
3682 MsOS_ReadMemory();
3683 if (CHECK_NULL_PTR(pstVBBU))
3684 return 0;
3685 MS_U32 u32WrPtr = pstVBBU->u32WrPtr;
3686
3687 if (u32WrPtr == 0)
3688 u32WrPtr = MAX_VDEC_VBBU_ENTRY_COUNT;
3689 else
3690 u32WrPtr--;
3691
3692 stEntry = (VDEC_VBBU_Entry*) &pstVBBU->stEntry[u32WrPtr];
3693
3694 //ALOGE("JJJ2: %d %d %d %d", pstVBBU->u32RdPtr, u32WrPtr, stEntry->u32Offset, stEntry->u32Length);
3695 #if SUPPORT_G2VP9
3696 if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype)
3697 {
3698 if (stEntry->u32Offset == 0)
3699 return 0;
3700 else
3701 return stEntry->u32Offset + stEntry->u32Length - pVPUHalContext->u32BitstreamAddress[u8OffsetIdx];
3702 }
3703 else
3704 #endif
3705 {
3706 return stEntry->u32Offset + stEntry->u32Length;
3707 }
3708 }
3709
HAL_VPU_EX_Push2VBBU(MS_U32 u32Id,HAL_VPU_EX_PacketInfo * stVpuPkt,MS_VIRT u32VBBUAddr)3710 MS_BOOL HAL_VPU_EX_Push2VBBU(MS_U32 u32Id, HAL_VPU_EX_PacketInfo *stVpuPkt, MS_VIRT u32VBBUAddr)
3711 {
3712 VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3713 #if SUPPORT_G2VP9
3714 MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
3715 #endif
3716
3717 if (CHECK_NULL_PTR(pstVBBU) || CHECK_NULL_PTR(stVpuPkt))
3718 return FALSE;
3719 MsOS_ReadMemory();
3720 VDEC_VBBU_Entry *stEntry = (VDEC_VBBU_Entry*) &pstVBBU->stEntry[pstVBBU->u32WrPtr];
3721 MS_U32 u32NewWrPtr;
3722
3723 u32NewWrPtr = pstVBBU->u32WrPtr + 1;
3724 if (u32NewWrPtr == (MAX_VDEC_VBBU_ENTRY_COUNT + 1))
3725 {
3726 u32NewWrPtr = 0;
3727 }
3728
3729 if (u32NewWrPtr == pstVBBU->u32RdPtr) return FALSE;
3730
3731 stEntry->u32Offset = stVpuPkt->u32Offset;
3732
3733 #if SUPPORT_G2VP9
3734 if (E_VPU_EX_DECODER_G2VP9 == pVPUHalContext->_stVPUStream[u8OffsetIdx].eDecodertype)
3735 {
3736 stEntry->u32Offset += pVPUHalContext->u32BitstreamAddress[u8OffsetIdx];
3737 }
3738 #endif
3739
3740 stEntry->u32Length = stVpuPkt->u32Length;
3741 stEntry->u64TimeStamp = stVpuPkt->u64TimeStamp;
3742 stEntry->u32ID_H = stVpuPkt->u32ID_H;
3743 stEntry->u32ID_L = stVpuPkt->u32ID_L;
3744
3745 MsOS_FlushMemory();//make sure vbbu offset/length already flushed to memory before vbbu wptr advancing
3746
3747 pstVBBU->u32WrPtr = u32NewWrPtr;
3748
3749 //ALOGE("JJJ3: %d", pstVBBU->u32WrPtr);
3750
3751 MsOS_FlushMemory();
3752
3753 return TRUE;
3754 }
3755
HAL_VPU_EX_IsVBBUEmpty(MS_VIRT u32VBBUAddr)3756 MS_BOOL HAL_VPU_EX_IsVBBUEmpty(MS_VIRT u32VBBUAddr)
3757 {
3758 VDEC_VBBU *pstVBBU = (VDEC_VBBU *)MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + u32VBBUAddr);
3759
3760 if (CHECK_NULL_PTR(pstVBBU))
3761 return FALSE;
3762 return pstVBBU->u32RdPtr == pstVBBU->u32WrPtr;
3763 }
3764
3765 ///-----------------------------------------------------------------------------
3766 /// specify the command send to Mail box or DRAM
3767 /// @return TRUE or FALSE
3768 /// - TRUE, Mail box
3769 /// - FALSE, Dram
3770 /// @param u32Cmd \b IN: Command is going to be sned
3771 ///-----------------------------------------------------------------------------
HAL_VPU_EX_IsMailBoxCMD(MS_U32 u32Cmd)3772 MS_BOOL HAL_VPU_EX_IsMailBoxCMD(MS_U32 u32Cmd)
3773 {
3774 MS_BOOL bResult = TRUE;
3775
3776 switch (u32Cmd)
3777 {
3778 // *********** Runtime action Command
3779 /* case E_HVD_CMD_RELEASE_DISPQ:
3780 case E_HVD_CMD_UPDATE_DISPQ:
3781 case E_HVD_CMD_FLUSH_DEC_Q:
3782 case E_HVD_CMD_FLUSH:
3783 case E_HVD_CMD_PLAY:
3784 case E_HVD_CMD_PAUSE:
3785 case E_HVD_CMD_STOP:
3786 case E_HVD_CMD_STEP_DECODE:
3787 case E_HVD_CMD_SKIP_DEC:
3788 case E_HVD_CMD_DISP_I_DIRECT:*/
3789 // *********** Dual-Stream Create Task Command
3790 case E_DUAL_CMD_TASK0_HVD_BBU:
3791 case E_DUAL_CMD_TASK0_HVD_TSP:
3792 case E_DUAL_CMD_TASK0_MVD_SLQ:
3793 case E_DUAL_CMD_TASK0_MVD_TSP:
3794 case E_DUAL_CMD_TASK1_HVD_BBU:
3795 case E_DUAL_CMD_TASK1_HVD_TSP:
3796 case E_DUAL_CMD_MODE:
3797 #ifndef _WIN32
3798 case E_DUAL_CMD_TASK1_MVD_SLQ:
3799 case E_DUAL_CMD_TASK1_MVD_TSP:
3800 #endif
3801 case E_DUAL_CMD_DEL_TASK:
3802 case E_DUAL_CMD_SINGLE_TASK:
3803 case E_DUAL_VERSION:
3804 case E_DUAL_R2_CMD_EXIT:
3805 #ifdef VDEC3
3806 case E_DUAL_R2_CMD_FBADDR:
3807 case E_DUAL_R2_CMD_FBSIZE:
3808 // *********** N-Streams
3809 case E_NST_CMD_TASK_HVD_TSP:
3810 case E_NST_CMD_TASK_HVD_BBU:
3811 case E_NST_CMD_TASK_MVD_TSP:
3812 case E_NST_CMD_TASK_MVD_SLQ:
3813 case E_NST_CMD_DEL_TASK:
3814 #endif
3815 case E_DUAL_CMD_COMMON:
3816 {
3817 bResult = TRUE;
3818 }
3819 break;
3820 default:
3821 {
3822 bResult = FALSE;
3823 }
3824 break;
3825 }
3826
3827 return bResult;
3828 }
3829
3830 ///-----------------------------------------------------------------------------
3831 /// specify the command send to Mail box or DRAM
3832 /// @return TRUE or FALSE
3833 /// - TRUE, Mail box
3834 /// - FALSE, Dram
3835 /// @param u32Cmd \b IN: Command is going to be sned
3836 ///-----------------------------------------------------------------------------
HAL_VPU_EX_IsDisplayQueueCMD(MS_U32 u32Cmd)3837 MS_BOOL HAL_VPU_EX_IsDisplayQueueCMD(MS_U32 u32Cmd)
3838 {
3839 MS_BOOL bResult = TRUE;
3840
3841 switch (u32Cmd)
3842 {
3843 // *********** Runtime action Command
3844 case E_HVD_CMD_RELEASE_DISPQ:
3845 case E_HVD_CMD_UPDATE_DISPQ:
3846 case E_HVD_CMD_FLUSH_DEC_Q:
3847 case E_HVD_CMD_PAUSE:
3848 case E_HVD_CMD_FLUSH:
3849 case E_HVD_CMD_PLAY:
3850 case E_HVD_CMD_STOP:
3851 case E_HVD_CMD_SKIP_DEC:
3852 case E_HVD_CMD_DISP_I_DIRECT:
3853 case E_HVD_CMD_STEP_DECODE:
3854 case E_HVD_CMD_INC_DISPQ_NUM:
3855 {
3856 bResult = TRUE;
3857 }
3858 break;
3859 default:
3860 {
3861 bResult = FALSE;
3862 }
3863 break;
3864 }
3865
3866 return bResult;
3867 }
3868
3869 ///-----------------------------------------------------------------------------
3870 /// Send message to HVD stream command queue
3871 /// @return TRUE or FALSE
3872 /// - TRUE, Success
3873 /// - FALSE, Failed
3874 /// @param u32DramAddr \b IN: address to be writen
3875 /// @param u32Msg \b IN: data to be writen
3876 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMCMDQueueSend(MS_VIRT u32DramAddr,MS_U32 u32Msg)3877 MS_BOOL HAL_VPU_EX_DRAMCMDQueueSend(MS_VIRT u32DramAddr, MS_U32 u32Msg)
3878 {
3879 MS_BOOL bResult = TRUE;
3880
3881 VPU_MSG_DBG("Send to Command Queue Address=0x%lx, msg=0x%x\n", (unsigned long)u32DramAddr, u32Msg);
3882
3883 WRITE_LONG(u32DramAddr,u32Msg);
3884
3885 return bResult;
3886 }
3887
3888 ///-----------------------------------------------------------------------------
3889 /// Read task share memory to specify that task command queue is empty or not
3890 /// @return TRUE or FALSE
3891 /// - TRUE, Empty
3892 /// - FALSE, Non empty
3893 /// @param u32Id \b IN: Task information
3894 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMCMDQueueIsEmpty(void * cmd_queue)3895 MS_BOOL HAL_VPU_EX_DRAMCMDQueueIsEmpty(void *cmd_queue)
3896 {
3897 // HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
3898 CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
3899 if (!cmd_q)
3900 {
3901 VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
3902 return FALSE;
3903 }
3904
3905 return cmd_q->u32HVD_STREAM_CMDQ_WD == cmd_q->u32HVD_STREAM_CMDQ_RD;
3906 }
3907
3908 ///-----------------------------------------------------------------------------
3909 /// Read task share memory to specify that task command queue is full or not
3910 /// @return TRUE or FALSE
3911 /// - TRUE, Full
3912 /// - FALSE, Non full
3913 /// @param u32Id \b IN: Task information
3914 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMCMDQueueIsFull(void * cmd_queue)3915 MS_BOOL HAL_VPU_EX_DRAMCMDQueueIsFull(void *cmd_queue)
3916 {
3917 // HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
3918 CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
3919 if (!cmd_q)
3920 {
3921 VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
3922 return TRUE;
3923 }
3924 MS_U32 NewWD = cmd_q->u32HVD_STREAM_CMDQ_WD + (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE); //preserve one slot
3925
3926 if(NewWD >= HVD_CMDQ_DRAM_ST_SIZE)
3927 NewWD -= HVD_CMDQ_DRAM_ST_SIZE;
3928
3929 return NewWD == cmd_q->u32HVD_STREAM_CMDQ_RD;
3930 }
3931
HAL_VPU_EX_DRAMStreamCMDQueueSend(MS_U32 u32Id,void * cmd_queue,MS_U8 u8CmdType,MS_U32 u32Msg)3932 MS_U32 HAL_VPU_EX_DRAMStreamCMDQueueSend(MS_U32 u32Id, void *cmd_queue, MS_U8 u8CmdType, MS_U32 u32Msg)
3933 {
3934 MS_U32 bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
3935 CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
3936 MS_U8 u8TaskID = HAL_VPU_EX_GetTaskId(u32Id);
3937
3938 #if HVD_ENABLE_MVC
3939 if (E_HAL_VPU_MVC_STREAM_BASE == u8TaskID)
3940 {
3941 u8TaskID = E_HAL_VPU_MAIN_STREAM_BASE;
3942 }
3943 #endif
3944
3945 if (CHECK_NULL_PTR(cmd_q))
3946 {
3947 VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
3948 return bResult;
3949 }
3950 MS_VIRT u32CmdQWdPtr;
3951
3952 if (CHECK_NULL_PTR((MS_VIRT)cmd_q->u32HVD_CMDQ_DRAM_ST_ADDR))
3953 return E_HVD_COMMAND_QUEUE_NOT_INITIALED;
3954
3955 if (HAL_VPU_EX_DRAMCMDQueueIsFull(cmd_q))
3956 return E_HVD_COMMAND_QUEUE_FULL;
3957 else
3958 {
3959 u32CmdQWdPtr = MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + cmd_q->u32HVD_CMDQ_DRAM_ST_ADDR + cmd_q->u32HVD_STREAM_CMDQ_WD);
3960 }
3961
3962 switch (u8CmdType)
3963 {
3964 case E_HVD_CMDQ_CMD:
3965 {
3966 u32Msg |= (u8TaskID << 24);
3967 bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32CmdQWdPtr, u32Msg);
3968
3969 MsOS_FlushMemory();//make sure u32DISPCMDQWdPtr already flushed to memory
3970
3971 if (bResult)
3972 {
3973 cmd_q->u32HVD_STREAM_CMDQ_WD += (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE);
3974
3975 if (cmd_q->u32HVD_STREAM_CMDQ_WD == HVD_CMDQ_DRAM_ST_SIZE)
3976 cmd_q->u32HVD_STREAM_CMDQ_WD = 0;
3977
3978 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
3979 }
3980 break;
3981 }
3982 case E_HVD_CMDQ_ARG:
3983 {
3984 bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32CmdQWdPtr + HVD_DRAM_CMDQ_CMD_SIZE, u32Msg);
3985 if (bResult)
3986 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
3987 break;
3988 }
3989 default:
3990 {
3991 bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
3992 break;
3993 }
3994 }
3995
3996 MsOS_FlushMemory();
3997
3998 return bResult;
3999 }
4000
4001 ///-----------------------------------------------------------------------------
4002 /// Read task share memory to specify that task display command queue is empty or not
4003 /// @return TRUE or FALSE
4004 /// - TRUE, Empty
4005 /// - FALSE, Non empty
4006 /// @param u32Id \b IN: Task information
4007 ///-----------------------------------------------------------------------------
HAL_VPU_EX_DRAMDispCMDQueueIsEmpty(void * cmd_queue)4008 MS_BOOL HAL_VPU_EX_DRAMDispCMDQueueIsEmpty(void *cmd_queue)
4009 {
4010 // HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
4011 CMD_QUEUE *cmd_q = (CMD_QUEUE *) cmd_queue;
4012 if (!cmd_q)
4013 {
4014 VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
4015 return FALSE;
4016 }
4017
4018 return cmd_q->u32HVD_STREAM_DISPCMDQ_WD == cmd_q->u32HVD_STREAM_DISPCMDQ_RD;
4019 }
4020
HAL_VPU_EX_DRAMDispCMDQueueIsFull(void * cmd_queue)4021 MS_BOOL HAL_VPU_EX_DRAMDispCMDQueueIsFull(void *cmd_queue)
4022 {
4023 // HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
4024 CMD_QUEUE *cmd_q = (CMD_QUEUE *) cmd_queue;
4025 if (!cmd_q)
4026 {
4027 VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
4028 return TRUE;
4029 }
4030
4031 MS_U32 NewWD = cmd_q->u32HVD_STREAM_DISPCMDQ_WD + (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE); //preserve one slot
4032
4033 if(NewWD >= HVD_DISPCMDQ_DRAM_ST_SIZE)
4034 NewWD -= HVD_DISPCMDQ_DRAM_ST_SIZE;
4035
4036 return NewWD == cmd_q->u32HVD_STREAM_DISPCMDQ_RD;
4037 }
4038
HAL_VPU_EX_DRAMStreamDispCMDQueueSend(MS_U32 u32Id,void * cmd_queue,MS_U8 u8CmdType,MS_U32 u32Msg)4039 MS_U32 HAL_VPU_EX_DRAMStreamDispCMDQueueSend(MS_U32 u32Id, void *cmd_queue, MS_U8 u8CmdType, MS_U32 u32Msg)
4040 {
4041 HVD_DRAM_COMMAND_QUEUE_SEND_STATUS bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
4042 CMD_QUEUE *cmd_q = (CMD_QUEUE *)cmd_queue;
4043 MS_U8 u8TaskID = HAL_VPU_EX_GetTaskId(u32Id);
4044
4045 #if HVD_ENABLE_MVC
4046 if (E_HAL_VPU_MVC_STREAM_BASE == u8TaskID)
4047 {
4048 u8TaskID = E_HAL_VPU_MAIN_STREAM_BASE;
4049 }
4050 #endif
4051
4052 // HVD_ShareMem *pShm = (HVD_ShareMem *) HAL_HVD_EX_GetShmAddr(u32Id);
4053 //HVD_EX_MSG_DBG("DP shmAddr=%X u8TaskID = %X u8CmdType = %X u32Msg = %X\n", pShm, u8TaskID, u8CmdType, u32Msg);
4054
4055 if (CHECK_NULL_PTR(cmd_q))
4056 {
4057 VPU_MSG_ERR("Invalid parameter with share memory address=0x%lx %s:%d \n", (unsigned long)cmd_q, __FUNCTION__, __LINE__);
4058 return bResult;
4059 }
4060
4061 MS_VIRT u32DISPCMDQWdPtr;
4062
4063 if (CHECK_NULL_PTR((MS_VIRT)cmd_q->u32HVD_DISPCMDQ_DRAM_ST_ADDR))
4064 return E_HVD_COMMAND_QUEUE_NOT_INITIALED;
4065
4066 if (HAL_VPU_EX_DRAMDispCMDQueueIsFull(cmd_q))
4067 return E_HVD_COMMAND_QUEUE_FULL;
4068 else
4069 {
4070 u32DISPCMDQWdPtr = MsOS_PA2KSEG1(pVPUHalContext->u32FWCodeAddr + cmd_q->u32HVD_DISPCMDQ_DRAM_ST_ADDR + cmd_q->u32HVD_STREAM_DISPCMDQ_WD);
4071 }
4072
4073 // 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);
4074
4075 switch (u8CmdType)
4076 {
4077 case E_HVD_CMDQ_CMD:
4078 {
4079 u32Msg |= (u8TaskID << 24);
4080 bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32DISPCMDQWdPtr, u32Msg);
4081
4082 MsOS_FlushMemory();//make sure u32DISPCMDQWdPtr already flushed to memory
4083
4084 if (bResult)
4085 {
4086 cmd_q->u32HVD_STREAM_DISPCMDQ_WD += (HVD_DRAM_CMDQ_CMD_SIZE + HVD_DRAM_CMDQ_ARG_SIZE);
4087
4088 if (cmd_q->u32HVD_STREAM_DISPCMDQ_WD == HVD_DISPCMDQ_DRAM_ST_SIZE)
4089 cmd_q->u32HVD_STREAM_DISPCMDQ_WD = 0;
4090
4091 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
4092 }
4093 break;
4094 }
4095 case E_HVD_CMDQ_ARG:
4096 {
4097 bResult = HAL_VPU_EX_DRAMCMDQueueSend(u32DISPCMDQWdPtr + HVD_DRAM_CMDQ_CMD_SIZE, u32Msg);
4098 if (bResult)
4099 bResult = E_HVD_COMMAND_QUEUE_SEND_SUCCESSFUL;
4100 break;
4101 }
4102 default:
4103 {
4104 bResult = E_HVD_COMMAND_QUEUE_SEND_FAIL;
4105 break;
4106 }
4107 }
4108
4109 MsOS_FlushMemory();
4110
4111 return bResult;
4112 }
4113
HAL_VPU_EX_SetBitstreamBufAddress(MS_U32 u32Id,MS_VIRT u32BsAddr)4114 MS_BOOL HAL_VPU_EX_SetBitstreamBufAddress(MS_U32 u32Id, MS_VIRT u32BsAddr)
4115 {
4116 MS_U8 u8OffsetIdx = _VPU_EX_GetOffsetIdx(u32Id);
4117 MS_U32 u32StAddr;
4118 MS_U8 u8TmpMiuSel;
4119
4120 _phy_to_miu_offset(u8TmpMiuSel, u32StAddr, u32BsAddr);
4121
4122 pVPUHalContext->u32BitstreamAddress[u8OffsetIdx] = u32StAddr;
4123
4124 return TRUE;
4125 }
4126 #endif
4127
HAL_VPU_EX_DynamicFBMode(MS_BOOL bEnable,MS_PHY u32address,MS_U32 u32Size)4128 void HAL_VPU_EX_DynamicFBMode(MS_BOOL bEnable,MS_PHY u32address,MS_U32 u32Size)
4129 {
4130 pVPUHalContext->bEnableDymanicFBMode = bEnable;
4131
4132 if(u32address >= HAL_MIU1_BASE)
4133 {
4134 pVPUHalContext->u32DynamicFBAddress = u32address-HAL_MIU1_BASE;
4135 }
4136 else
4137 {
4138 pVPUHalContext->u32DynamicFBAddress = u32address;
4139 }
4140
4141 pVPUHalContext->u32DynamicFBSize = u32Size;
4142 }
4143
4144
4145 #else
4146 #include "halVPU_EX.h"
4147 #include "drvMMIO.h"
4148 #include "../hvd_ex/regHVD_EX.h"
4149 #include "halCHIP.h"
4150
4151 #if defined(MSOS_TYPE_NUTTX)
4152 extern int lib_lowprintf(const char *fmt, ...);
4153 #define PRINTF lib_lowprintf
4154 #elif defined(MSOS_TYPE_OPTEE)
4155 #define PRINTF printf
4156 #endif
4157
4158 #define HVD_LWORD(x) (MS_U16)((x)&0xffff)
4159 #define HVD_HWORD(x) (MS_U16)(((x)>>16)&0xffff)
4160
4161 MS_U8 u8FW_Binary[] = {
4162 #include "fwVPU.dat"
4163 };
4164
4165 MS_U32 u32HVDRegOSBase;
4166
HAL_VPU_EX_LoadCodeInSecure(MS_VIRT addr)4167 MS_BOOL HAL_VPU_EX_LoadCodeInSecure(MS_VIRT addr)
4168 {
4169 //PRINTF("do load code,u32DestAddr %x\n",addr);
4170 memcpy((void*)addr, (void*)u8FW_Binary, sizeof(u8FW_Binary));
4171 MAsm_CPU_Sync();
4172 MsOS_FlushMemory();
4173
4174 if (FALSE == (*((MS_U8*)(addr+6))=='R' && *((MS_U8*)(addr+7))=='2'))
4175 {
4176 PRINTF("FW is not R2 version! _%x_ _%x_\n", *(MS_U8*)(addr+6), *(MS_U8*)(addr+7));
4177 return FALSE;
4178 }
4179 return TRUE;
4180 }
4181
HAL_VPU_EX_SetLockDownRegister(void * param)4182 MS_BOOL HAL_VPU_EX_SetLockDownRegister(void* param)
4183 {
4184 #if 1
4185 MS_PHY u32StAddr_main;
4186 MS_PHY u32StAddr_sub;
4187 MS_U32 u32NonPMBankSize = 0;
4188 VPU_EX_LOCK_DOWN_REGISTER* register_lockdown;
4189
4190 if(param == NULL)
4191 {
4192 return FALSE;
4193 }
4194
4195 register_lockdown = (VPU_EX_LOCK_DOWN_REGISTER*)param;
4196
4197 MDrv_MMIO_GetBASE(&u32HVDRegOSBase, &u32NonPMBankSize, MS_MODULE_HW);
4198
4199 // ES buffer
4200 u32StAddr_main = register_lockdown->Bitstream_Addr_Main;
4201 u32StAddr_sub = register_lockdown->Bitstream_Addr_Sub;
4202
4203
4204 MS_PHY u32StartOffset;
4205 MS_U8 u8MiuSel;
4206
4207 _phy_to_miu_offset(u8MiuSel, u32StartOffset, u32StAddr_main);
4208 u32StAddr_main = u32StartOffset;
4209
4210 _phy_to_miu_offset(u8MiuSel, u32StartOffset, u32StAddr_sub);
4211 u32StAddr_sub = u32StartOffset;
4212
4213 //Lock down register
4214 _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_L(REG_HVD_BASE), HVD_LWORD(u32StAddr_main >> 3));
4215 _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_H(REG_HVD_BASE), HVD_HWORD(u32StAddr_main >> 3));
4216
4217 _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_L_BS2, HVD_LWORD(u32StAddr_sub >> 3));
4218 _HVD_Write2Byte(HVD_REG_ESB_ST_ADDR_H_BS2, HVD_HWORD(u32StAddr_sub >> 3));
4219 //~
4220
4221 // Lock Down
4222 //_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)));
4223 //~
4224 #endif
4225 return TRUE;
4226 }
4227
4228
4229 #endif
4230
4231
4232 #ifdef CMA_DRV_DIRECT_INIT
4233 // 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)4234 MS_BOOL HAL_VPU_EX_GetCMAMemSize(VPU_EX_CodecType eCodecType, VPU_EX_SrcMode eSrcMode,
4235 MS_U64 *offset, MS_SIZE *length, MS_U64 total_length, MS_SIZE unUseSize)
4236 {
4237 MS_SIZE FrameBufferSize = 0;
4238
4239 if (!offset || !length)
4240 return FALSE;
4241
4242 total_length -= unUseSize;
4243 VPU_MSG_INFO("[HAL][%s]:[%d] total_length:%llu, cType:%d, sType:%d\n", __FUNCTION__, __LINE__,
4244 (unsigned long long)total_length, (int)eCodecType, (int)eSrcMode);
4245 switch(eCodecType)
4246 {
4247 case E_VPU_EX_CODEC_TYPE_MPEG2:
4248 case E_VPU_EX_CODEC_TYPE_H263:
4249 case E_VPU_EX_CODEC_TYPE_MPEG4:
4250 case E_VPU_EX_CODEC_TYPE_DIVX311:
4251 case E_VPU_EX_CODEC_TYPE_DIVX412:
4252 case E_VPU_EX_CODEC_TYPE_FLV:
4253 FrameBufferSize = 0x1E00000;
4254 break;
4255 case E_VPU_EX_CODEC_TYPE_VC1_ADV:
4256 case E_VPU_EX_CODEC_TYPE_VC1_MAIN:
4257 FrameBufferSize = 0x6C00000;
4258 break;
4259 case E_VPU_EX_CODEC_TYPE_RV8:
4260 case E_VPU_EX_CODEC_TYPE_RV9:
4261 FrameBufferSize = 0x1B00000;
4262 break;
4263 case E_VPU_EX_CODEC_TYPE_VP8:
4264 FrameBufferSize = 0x1500000;
4265 break;
4266 case E_VPU_EX_CODEC_TYPE_H264:
4267 FrameBufferSize = 0x8200000;
4268 //FrameBufferSize = 0x7A00000; //UHD 122MB ,5 ref frame
4269 //FrameBufferSize = 0x7A80000; //UHD 4K2K 16:19 126.5MB
4270 //FrameBufferSize = 0x8E00000; //UHD 4K2K 16:19 142MB
4271 break;
4272 case E_VPU_EX_CODEC_TYPE_AVS:
4273 FrameBufferSize = 0x1B00000;
4274 break;
4275 case E_VPU_EX_CODEC_TYPE_MJPEG:
4276 FrameBufferSize = 0x2800000;
4277 break;
4278 case E_VPU_EX_CODEC_TYPE_MVC:
4279 FrameBufferSize = 0x4200000;
4280 break;
4281 case E_VPU_EX_CODEC_TYPE_HEVC:
4282 #if SUPPORT_MSVP9
4283 case E_VPU_EX_CODEC_TYPE_VP9:
4284 #endif
4285 FrameBufferSize = 0xA000000;
4286 break;
4287 #if !SUPPORT_MSVP9
4288 case E_VPU_EX_CODEC_TYPE_VP9:
4289 FrameBufferSize = 0x7800000;
4290 break;
4291 #endif
4292 default:
4293 FrameBufferSize = 0;
4294 break;
4295 }
4296 if(FrameBufferSize == 0)
4297 {
4298 return FALSE;
4299 }
4300 VPU_MSG_INFO("[HAL][%s]:[%d] FrameSize:%llu, offset:%llu, length:%llu ", __FUNCTION__, __LINE__,
4301 (unsigned long long)FrameBufferSize, (unsigned long long)*offset, (unsigned long long)*length);
4302 if (total_length < FrameBufferSize)
4303 {
4304 *offset = unUseSize;
4305 *length = total_length;
4306 }
4307 else // todo, dual decode case
4308 {
4309 *offset = unUseSize;
4310 *length = FrameBufferSize;
4311 }
4312 return TRUE;
4313 }
4314 #endif
4315