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