📄 drvmvd.c
字号:
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2007 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// (¨MStar Confidential Information〃) by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///@file drvmvd.h
///@brief Driver interface for accessing the MPEG video decoder.
///
///@author MStarSemi Inc.
///
///- Providing MPEG video decoder command functions for controlling firmware.
///- MPEG video decoder can support Standard definition and High definition video
///
///@image html mvd.jpg MVD module
///
///@par Example
///@code
/// //Sample code for MVD Command
/// //Input: MVD command
/// void msAPI_VID_MVDCommand ( U8 u8MVDCommand )
/// {
/// /*Reset MVD command argument*/
/// memset(&stCmdArg,0x00,sizeof(MVD_CMD_ARG));
/// switch ( u8MVDCommand )
/// {
/// case MSAPI_VID_PLAY:
/// /*Send play command*/
/// MDrv_Mvd_MVDCommand( MVD_PLAY, &stCmdArg );
/// break;
/// case MSAPI_VID_RESET:
/// /*Reset MVD*/
/// MDrv_Mvd_MVDReset( );
/// break;
/// case default:
/// break;
/// }
/// }
///@endcode
///////////////////////////////////////////////////////////////////////////////
#define DRV_MVD_C
#include <stdio.h>
#include <string.h>
#include "debug.h"
#include "drvuart.h"
#include "datatype.h"
#include "sysinfo.h"
#include "hwreg.h"
#include "board.h"
#include "drvmiu.h"
#include "drvtimer.h"
#include "drvmvd.h"
#include "drvgop.h"
#include "Analog_Reg.h"
#include "drvsys.h"
#include "drvGlobal.h"
#include "debug.h"
#define ASSERT(x) __ASSERT(x)
#if (CHANNEL_SCAN_AUTO_TEST == 0)
# define MVD_DEBUGINFO(x) //x
# define MVD_DEBUGERROR(x) //x
#else
# define MVD_DEBUGINFO(x)
# define MVD_DEBUGERROR(x)
#endif
#define H_DWORD(x) (U8)(((x)>>24)&0xff)
#define L_DWORD(x) (U8)(((x)>>16)&0xff)
#define H_WORD(x) (U8)(((x)>>8 )&0xff)
#define L_WORD(x) (U8)((x)&0xff)
#define COMBWORD(hi,lo) ((((U16)hi)<<8) | ((U16)lo))
#define COMBDWORD(hh,hl,lh,ll) ((((U32)hi)<<24) | (((U32)hi)<<16) | (((U32)hi)<<8) | ((U32)lo))
/*************************************************************************************************/
#if VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_HD
#include "Mvd_dm_var_HD.h"
#define MVD_CODE_ID BIN_ID_CODE_MVD_HD
#elif VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_SD
#include "Mvd_dm_var_SD.h"
#define MVD_CODE_ID BIN_ID_CODE_MVD_SD
#elif VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_SD_REDUCE
#include "Mvd_dm_var_SD_reduce.h"
#define MVD_CODE_ID BIN_ID_CODE_MVD_SD_REDUCE
#endif
#define MVD_PollingTimes 0x200000UL
static U8 u8MvdPlayMode = 0;
/*************************************************************************************************/
extern unsigned char get_bank ( void );
/********************************************************************************/
///Local functions (will not include in DDI document)
/********************************************************************************/
/********************************************************************************/
/// Wait MVD command ready or timeout
/// @return -MVD command ready or timeout
/********************************************************************************/
BOOLEAN MVD_TimeOut ()
{
U32 i;
for ( i = 0; i < MVD_PollingTimes; i++ )
{
///- wait until MVD command ready or timeout
if ( ( XBYTE[MVD_STATUS] & 0x2 ) == 0x2 )
{
return FALSE;
}
}
MVD_DEBUGERROR( printf("MVD_TimeOut=%d\n", i) );
return TRUE;
}
/********************************************************************************/
/// Initialize MVD
/// @param -u8cmd \b IN : MVD command
/// @param -pstCmdArg \b IN : pointer to command argument
/********************************************************************************/
BOOLEAN MDrv_Mvd_MVDCommand ( U8 u8cmd, MVD_CMD_ARG *pstCmdArg )
{
if ( MVD_TimeOut() == TRUE )
return FALSE;
XBYTE[MVD_ARG0] = pstCmdArg->Arg0;
XBYTE[MVD_ARG1] = pstCmdArg->Arg1;
XBYTE[MVD_ARG2] = pstCmdArg->Arg2;
XBYTE[MVD_ARG3] = pstCmdArg->Arg3;
XBYTE[MVD_COMMAND] = u8cmd;
MVD_DEBUGINFO(printf("%bx,%bx,%bx,%bx,%bx\n", u8cmd, pstCmdArg->Arg0, pstCmdArg->Arg1, pstCmdArg->Arg2, pstCmdArg->Arg3));
if ( MVD_TimeOut() == TRUE )
return FALSE;
pstCmdArg->Arg0 = XBYTE[MVD_ARG0];
pstCmdArg->Arg1 = XBYTE[MVD_ARG1];
pstCmdArg->Arg2 = XBYTE[MVD_ARG2];
pstCmdArg->Arg3 = XBYTE[MVD_ARG3];
return TRUE;
}
static U16 MDrv_Mvd_FWChecksum(U32 addr, U32 len)
{
U16 chksum = 0;
U32 start, end;
MVD_DEBUGINFO(printf("addrss=%08lx, len=%08lx\n",addr,len));
while(len > 0) {
MDrv_Sys_SetXdataWindow1Base( addr >> 12 );
start = addr & 0xfffL;
end = start+len;
if (end > 0x1000L)
end = 0x1000L;
len-= (end - start);
start += 0xf000L;
end += 0xf000L;
MVD_DEBUGINFO(printf("[addr=0x%08lX,w1start=0x%08lX,w1end=0x%08lX]\r\n", addr, start, end));
while(start < end) {
chksum+= XBYTE[(U16)start];
start++;
}
addr = ((addr + 0x1000L)>>12)<<12;
}
return chksum;
}
/********************************************************************************/
/// Load MVD firmware code to RISC
/// @return -Load firmware success or not
/********************************************************************************/
BOOLEAN MDrv_Mvd_LoadCode ( void )
{
#define TMP_ADR ((MVD_FRAMEBUFFER_ADR + 0x1FFFUL) & ~0x1FFFUL) // 8k aligned
U32 i;
U16 CODE_SIZE;
BINFORMAT BinInfo;
/// mvd reset, clear interrupt, BIU reset
XBYTE[MVD_CTRL] = 0x0D;
for ( i = 0; i < MVD_PollingTimes; i++ ) {
if (XBYTE[MVD_CTRL] == 0x0) {
MVD_DEBUGINFO( printf( "MVD reset done\n" ) );
break;
}
}
///-Get MVD binary information
BinInfo.B_ID = MVD_CODE_ID;
MVD_DEBUGINFO( printf("mvd_code_id=0x%04X\n", BinInfo.B_ID) );
if (MDrv_MIU_Get_BinInfo(&BinInfo) != PASS)
{
MVD_DEBUGERROR( printf( "could not find MVD binary on flash.\r\n" ) );
return FALSE;
}
#if VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_HD
MVD_DEBUGINFO( printf("MVD-HD fw\n") );
#else
MVD_DEBUGINFO( printf("MVD-SD fw\n") );
#endif
CODE_SIZE = BinInfo.B_Len;
MVD_DEBUGINFO( printf( "MVD code address:0x%8lx, length=0x%4x\n", TMP_ADR, CODE_SIZE) );
///-Copy firmware code from flash to SDRAM
MDrv_MIU_XCopy( MCPY_LOADMVDFW, BinInfo.B_FAddr, TMP_ADR, CODE_SIZE );
MVD_DEBUGINFO(printf("MVD Firmware checksum=0x%04x\n", MDrv_Mvd_FWChecksum(TMP_ADR, CODE_SIZE)));
XBYTE[MVD_ARG0] = LOWBYTE( TMP_ADR >> 11 );
XBYTE[MVD_ARG1] = HIGHBYTE( TMP_ADR >> 11 );
CODE_SIZE = (CODE_SIZE + 7) >> 3;
XBYTE[MVD_ARG2] = LOWBYTE( CODE_SIZE );
XBYTE[MVD_ARG3] = HIGHBYTE( CODE_SIZE );
///-Enable booting, load firmware from SDRAM to MVD's program memory
XBYTE[MVD_CTRL] = 2;
for ( i = 0; i < MVD_PollingTimes; i++ )
{
if ( ( XBYTE[MVD_STATUS] & 0x3 ) == 0x3 ) // booting finished
{
MVD_DEBUGINFO( printf("MVD Booting done\n") );
return TRUE;
}
}
MVD_DEBUGERROR( printf("MVD BOOT TIMEOUT\n") );
msWarning(ERR_MVD_BOOT_TIMEOUT);
return FALSE;
#undef TMP_ADR
}
/********************************************************************************/
/// Initialize MVD
/********************************************************************************/
void MDrv_Mvd_MVDInit ( void )
{
if ( ( XBYTE[MVD_STATUS] & 0x1 ) != 0x1 ) // booting not finished
{
///-Load MVD firmware code
if ( MDrv_Mvd_LoadCode() == FALSE )
{
MVD_DEBUGERROR( printf( "MVD load code fail\n!!" ) );
return;
}
}
XBYTE[REG_CKG_MVD]=0x44; // set mvd_clk & mvd_boot_clk to 123MHz
MVD_DEBUGINFO( printf( "MVD load code and start OK!\r\n" ) );
MDrv_Mvd_MVDReset();
///-program bitstream address
MDrv_Mvd_SetBitStreamAddr( MVD_BITSTREAM_ADR, MVD_BITSTREAM_ADR + MVD_BITSTREAM_LEN );
( printf("MVD_BITSTREAM_STARTADDR=0x%lx, MVD_BITSTREAM_ENDADDR=0x%lx\n",
MVD_BITSTREAM_ADR, MVD_BITSTREAM_ADR + MVD_BITSTREAM_LEN) );
///-program frambuffer start address
MDrv_Mvd_SetFrameBufferAddr( MVD_FRAMEBUFFER_ADR );
( printf("MVD_FRAMEBUFFER_ADR=0x%lx\n", MVD_FRAMEBUFFER_ADR) );
}
void MDrv_Mvd_MVDResetBuffAddr ( void )
{
///-program bitstream address
MDrv_Mvd_SetBitStreamAddr( MVD_BITSTREAM_ADR, MVD_BITSTREAM_ADR + MVD_BITSTREAM_LEN );
///-program frambuffer start address
MDrv_Mvd_SetFrameBufferAddr( MVD_FRAMEBUFFER_ADR );
}
/********************************************************************************/
/// Reset MVD
/********************************************************************************/
void MDrv_Mvd_MVDReset ( void )
{
XBYTE[MVD_CTRL] = 1;
MDrv_Timer_Delayms(2); // Delay 2ms to make MVD reset complete
u8MvdPlayMode = 0;
}
/********************************************************************************/
/// Play MVD
/********************************************************************************/
void MDrv_Mvd_Play()
{
MVD_CMD_ARG mvdcmd;
mvdcmd.Arg0 = u8MvdPlayMode;
mvdcmd.Arg1 = 0;
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_PLAY, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_PLAY ) );
return;
}
}
/********************************************************************************/
/// Set bit stream buffer address to MVD
/// @param -u32start \b IN : start address
/// @param -u32end \b IN : end address
/********************************************************************************/
void MDrv_Mvd_SetBitStreamAddr ( U32 u32start, U32 u32end )
{
MVD_CMD_ARG mvdcmd;
ASSERT((u32start%8)==0);
u32start >>= 3;
mvdcmd.Arg0 = L_WORD(u32start);
mvdcmd.Arg1 = H_WORD(u32start);
mvdcmd.Arg2 = L_DWORD(u32start);
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_SET_BS_START, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_BS_START ) );
return;
}
ASSERT((u32end%8)==0);
u32end >>= 3;
mvdcmd.Arg0 = L_WORD(u32end);
mvdcmd.Arg1 = H_WORD(u32end);
mvdcmd.Arg2 = L_DWORD(u32end);
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_SET_BS_END, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_BS_END ) );
return;
}
}
/********************************************************************************/
/// Set frame buffer address to MVD
/// @param -u32addr \b IN : start address
/********************************************************************************/
void MDrv_Mvd_SetFrameBufferAddr ( U32 u32addr )
{
MVD_CMD_ARG mvdcmd;
#if VIDEO_FIRMWARE_CODE >= VIDEO_FIRMWARE_CODE_HD
ASSERT((u32addr%2048)==0);
u32addr >>= ( 3 + 8 );
#else
ASSERT((u32addr%512)==0);
u32addr >>= ( 3 + 6 );
#endif
mvdcmd.Arg0 = L_WORD(u32addr);
mvdcmd.Arg1 = H_WORD(u32addr);
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_SET_FB_START, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_FB_START ) );
return;
}
}
//#if ( KEEP_UNUSED_FUNC == 1 )
/********************************************************************************/
/// Set frame rate to MVD
/// @param -u8rate \b IN : frame rate
/********************************************************************************/
void MDrv_Mvd_SetFrameRate ( U8 u8rate )
{
MVD_CMD_ARG mvdcmd;
mvdcmd.Arg0 = u8rate;
mvdcmd.Arg1 = 0;
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_SET_FRAMERATE, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_FRAMERATE ) );
return;
}
}
//#endif
/********************************************************************************/
/// Check MVD decode status
/// @return -MVD decode ready or not
/********************************************************************************/
BOOLEAN MDrv_Mvd_CheckDecodeStatus ( void )
{
MVD_CMD_ARG mvdcmd;
U16 num;
mvdcmd.Arg0 = 0;
mvdcmd.Arg1 = 0;
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_GET_VALID_DATA_STATUS, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_GET_VALID_DATA_STATUS ) );
return FALSE;
}
num = COMBWORD(mvdcmd.Arg3, mvdcmd.Arg2);
MVD_DEBUGERROR( printf( "mvd decode stall count=%u\n", num) );
if (num <= 30)
return TRUE;
else
return FALSE;
}
/********************************************************************************/
/// Get MVD decoded picture counter
/// @return -decoded picture counter
/********************************************************************************/
U8 MDrv_Mvd_GetPicCounter ( void )
{
MVD_CMD_ARG mvdcmd;
mvdcmd.Arg0 = PIC_COUNT;
mvdcmd.Arg1 = 0;
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_COMMAND_CTRL, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Ctrl: PIC_COUNT fail!!\r\n" ) );
return 0;
}
return mvdcmd.Arg2;
}
/********************************************************************************/
/// Get valid MVD stream detected flag
/// @return -decoded flag
/********************************************************************************/
BOOLEAN MDrv_Mvd_GetValidStreamFlag ( void )
{
MVD_CMD_ARG mvdcmd;
mvdcmd.Arg0 = INT_STAT;
mvdcmd.Arg1 = 0;
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_COMMAND_CTRL, &mvdcmd ) == FALSE)
{
MVD_DEBUGERROR( printf( "Ctrl: INT_STAT fail!!\r\n" ) );
return FALSE;
}
// 1 : New CC, 2: CC608 buffer overflow,3:CC708 overflow, 4: Valid MPEG , 0, 5: Invalid MPEG
if (0x01 == mvdcmd.Arg2 || 0x02 == mvdcmd.Arg2 ||
0x03 == mvdcmd.Arg2 || 0x04 == mvdcmd.Arg2)
return TRUE;
else
return FALSE;
}
/********************************************************************************/
/// Get video frame information from MVD
/// @param -pinfo \b IN : pointer to video frame information
/********************************************************************************/
void MDrv_Mvd_GetFrameInfo ( MVD_FRAMEINFO *pinfo )
{
MVD_CMD_ARG mvdcmd;
mvdcmd.Arg0 = 0;
mvdcmd.Arg1 = 0;
mvdcmd.Arg2 = 0;
mvdcmd.Arg3 = 0;
if (MDrv_Mvd_MVDCommand( MVD_I_GET_PICTURE_SIZE, &mvdcmd ) == FALSE)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -