📄 tmmp.c
字号:
/*
* Copyright (c) 1998,1999 by TriMedia Technologies.
*
* +------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such |
* | a license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided|
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | This code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +------------------------------------------------------------------+
*
* Module name : tmMP.c 1.57
*
* Last update : 19:37:59 - 00/11/09
*
* Description :
*
* Behavioral description of Hardware MPEG Pipe (MP) unit.
*
*/
#include <ops/custom_defs.h>
#include <tm1/tmAssert.h>
#include <tm1/tmLibdevErr.h>
#ifdef APPMODEL
#include <tmlib/AppSem.h>
#endif
#include <tm1/tmMPmmio.h>
#include <tm1/tmMP.h>
#include <tm1/tmProcessor.h>
#ifdef _DVP_
#include <tmVIPERmmio.h>
#include <tmHalDefs.h>
#include <tmbslCore.h>
#include <tmosal.h>
#include "common.h"
#else
#include <tm1/tmVIPERmmio.h>
#include <tm1/tmBoard.h>
#endif
#include "tmMPprivate.h"
#ifndef MAJOR_VERSION
#define MAJOR_VERSION 0
#endif
#ifndef MINOR_VERSION
#define MINOR_VERSION 1
#endif
#ifndef BUILD_VERSION
#define BUILD_VERSION 0xffff
#endif
/*
* Number of supported instances
*/
#define MP_MAX_INSTANCES 6
#define TM32_BLOCK_ID (0x100FFC)
#define TM3218_2B80_MOD_ID (0x00002B80)
#define DVP_MOD_ID_MASK 0xFFFFU
#define DVP_MOD_ID_SHIFT 16U
#define MP_SW_TIMEOUT_CNT (500)
/* SORTED list of valid MMI_LINE_SIZE values */
static UInt32 _valid_line_size [10] = {
320, 352, 368, 640, 704, 720, 960,1280,1440,1920
};
/*
* Global global
*/
UInt32 tmMPGlobalBase;
/*
* Local globals
*/
static Int _mpCurInstance;
static Int _mpOwner = -1;
static Int _mpLockCount = 0;
static Bool _mpFirstInstance = True;
static Int _mpInterruptActive = 0;
static Bool _mpErrorCon1Pending;
static Bool _mpErrorCon2Pending;
#ifdef APPMODEL
static struct _AppSem_Semaphore _mpMutex = _AppSem_INITIALISED_SEM;
#endif
static mpInstanceInfo_t MpInfo[MP_MAX_INSTANCES];
static mpCapabilities_t Capabilities =
{
{MAJOR_VERSION, MINOR_VERSION, BUILD_VERSION}, /* version */
MP_MAX_INSTANCES, /* numSupportedInstances */
0 /* numCurrentInstances */
};
/****************************************************************************
tmLibdevErr_t mpGetCapabilities(pmpCapabilities_t *cap)
Return capabilities
****************************************************************************/
extern tmLibdevErr_t
mpGetCapabilities(pmpCapabilities_t * cap)
{
*cap = &Capabilities;
return TMLIBDEV_OK;
}
/****************************************************************************
tmLibdevErr_t mpOpen(Int *instance)
Open an instance.
Id to the instance is returned in *instance.
*instance contains -1 if failure.
Need to be protected from simultaneous invocation.
****************************************************************************/
extern tmLibdevErr_t
mpOpen(Int * instance)
{
Int id, err;
#ifndef _DVP_
boardMPConfig_t *mpBoardConfig;
#endif
MPENT(instance);
SUSPEND_SCHEDULING();
id = getNextInstance();
if (id < 0 || id >= MP_MAX_INSTANCES) {
*instance = -1;
RESUME_SCHEDULING();
return TMLIBDEV_ERR_NO_MORE_INSTANCES;
}
*instance = id;
memset(&MpInfo[id], 0, sizeof(mpInstanceInfo_t));
MpInfo[id].used = 1;
MpInfo[id].mpContext.valid = False;
MpInfo[id].mpContext.fifo = (UInt8 *)
((((Int)(MpInfo[id].mpContext.fifoBuf)) + 63) & ~0x3f);
#ifdef _DVP_
err = tmbslGetModuleInfo(VMPG_100_MOD_ID,tmUnit0,&(MpInfo[id].mpModuleInfo));
if (err != TM_OK) {
DP(("tmbslGetModuleInfo failed %x\n",err));
return ERR_BASE_TMBSL;
}
#else
err = tsaBoardGetMP(unit0, &mpBoardConfig);
if (err == TMLIBDEV_OK)
MpInfo[id].boardMPConfig = mpBoardConfig;
else
MpInfo[id].boardMPConfig = NULL;
#endif
Capabilities.numCurrentInstances++;
RESUME_SCHEDULING();
MPEXT(instance);
return TMLIBDEV_OK;
}
/****************************************************************************
tmLibdevErr_t mpClose(Int instance)
Shut down the device and deinstall interrupt
****************************************************************************/
extern tmLibdevErr_t
mpClose(Int instance)
{
tmLibdevErr_t err = TMLIBDEV_OK;
#ifdef _DVP_
tmosalErrorCode_t osalerr = TMOSAL_ERR_OK;
#endif
MPENT(instance);
STD_ASSERTS(instance);
SUSPEND_SCHEDULING();
MpInfo[instance].used = 0;
MpInfo[instance].mpContext.valid = False;
Capabilities.numCurrentInstances--;
/*
* Unlock pipe if owner
*/
if(_mpOwner == instance){
_mpLockCount = 0;
#ifdef APPMODEL
AppSem_V(&_mpMutex);
#endif
_mpOwner = -1;
}
/*
* Close interrupt only when no more user
*/
if (Capabilities.numCurrentInstances == 0) {
_mpFirstInstance = True;
#ifdef _DVP_
osalerr = tmosalIntDestroy( MpInfo[instance].mpIntHandle );
if (osalerr != TMOSAL_ERR_OK) {
goto mpCloseExit;
}
#else
err = intClose(intINT_14);
if (err != TMLIBDEV_OK) {
goto mpCloseExit;
}
#endif
}
mpCloseExit:
RESUME_SCHEDULING();
MPEXT(instance);
return err;
}
/****************************************************************************
tmLibdevErr_t mpInstanceSetup(Int instance, mpInstanceSetup_t *mpSetup)
Function : Validates the owner, fills the shift register,
broad init and installs interrupt handler
Parameters : (I) owner instance and
(I) mpInstanceSetup_t structure instance pointer
Function Result : zero on success and error code on failure
****************************************************************************/
extern tmLibdevErr_t
mpInstanceSetup(Int instance, mpInstanceSetup_t * mpSetup)
{
#ifdef _DVP_
tmosalErrorCode_t status = tmosalErrOk;
tmosalIntDescriptor_t setup;
tmbslMemAccessInfo_t memAccess;
#else
tmLibdevErr_t status = TMLIBDEV_OK;
intInstanceSetup_t setup;
#endif
MPENT(instance);
STD_ASSERTS(instance);
tmAssert(((mpSetup->mpEmptyFunc != NULL) &&
(mpSetup->mpErrorFunc != NULL) &&
(mpSetup->mpSuccessFunc != NULL) &&
(mpSetup->mpReqCompleteFunc != NULL)),MP_ERR_INVALID_SETUP);
#ifdef _DVP_
status = tmbslGetMemAccess(&memAccess);
if (status != TM_OK) {
DP(("tmbslGetMemAccess failed %x\n",status));
return ERR_BASE_TMBSL;
}
tmMPGlobalBase = (UInt32) MpInfo[instance].mpModuleInfo.mmioPhysAddr - memAccess.physMmioBase;
#else
if ( MpInfo[instance].boardMPConfig )
tmMPGlobalBase = MpInfo[instance].boardMPConfig->mmioBase;
else
tmMPGlobalBase = MP_VLD_COMMAND;
#endif
if(_mpFirstInstance == True){
/*
* This is the current instance
*/
RETURN_IF_NOT_OK(_mpIntReset()); /* Reset MP first of all */
_mpCurInstance = instance;
_mpFirstInstance = False;
}
/*
* Record mpSetup into MpInfo
*/
MpInfo[instance].mpContext.mpEmptyFunc = mpSetup->mpEmptyFunc;
MpInfo[instance].mpContext.prevInputCnt = 0;
MpInfo[instance].mpContext.prevBitCnt = mpGetBIT_CNT();
MpInfo[instance].mpContext.prevVldOcc = 0;
MpInfo[instance].mpSetup = *mpSetup;
if (mpSetup->mpSliceFunc == NULL) {
MpInfo[instance].mpSetup.mpSliceFunc = (pFnMpCallback_t) _mpSliceHeader;
}
#ifdef APPMODEL
MpInfo[instance].CurrThread = AppModel_current_thread;
#else
MpInfo[instance].CurrThread = 0;
#endif
/*
* install interrupt.
* Do not check the result since it may be opened already
*/
#ifndef _DVP_
if ( MpInfo[instance].boardMPConfig )
intOpen( MpInfo[instance].boardMPConfig->intNumber);
else
intOpen( intMPEG );
setup.enabled = True;
setup.handler = _mpISR;
setup.priority = intPRIO_2;
setup.level_triggered = True;
if ( MpInfo[instance].boardMPConfig )
intInstanceSetup( MpInfo[instance].boardMPConfig->intNumber, &setup);
else
intInstanceSetup( intMPEG, &setup );
#else
status = tmosalIntCreate ( "VMPG0", &(MpInfo[instance].mpIntHandle), 0);
/* Fix up this error handling. Incompatible error codes. */
tmAssert(status == TMOSAL_ERR_OK, status);
if (status != TMOSAL_ERR_OK) {
/* Use some error for now */
DP(("tmosalIntCreate failed %x\n",status));
status = INT_ERR_INVALID_NODE;
goto localExit;
}
setup.pHandler = _mpISR;
setup.interruptible = True;
setup.priority = tmosalIntPRIO_2;
setup.enabled = True;
setup.pContextArgument = NULL;
status = tmosalIntInstanceSetup( MpInfo[instance].mpIntHandle, &setup);
/* Fix up this error handling. Incompatible error codes. */
tmAssert(status == TMOSAL_ERR_OK, status);
if (status != TMOSAL_ERR_OK) {
DP(("tmosalIntInstanceSetup failed %x\n",status));
/* Use some error for now */
status = INT_ERR_INVALID_NODE;
goto localExit;
}
#endif
localExit:
MPEXT(instance);
return status;
}
/****************************************************************************
tmLibdevErr_t mpDecodeRows(Int instance, Int32 numRows)
Issue a MP Parse LINE command
Return when numRows have been decoded
****************************************************************************/
extern tmLibdevErr_t
mpDecodeRows(Int instance, Int32 endRow, Bool exSync)
{
UInt32 imask;
MPENT(instance);
STD_ASSERTS(instance);
tmAssert(mpCheckSTATUS_SUCCESS(), MP_ERR_PREV_COMMAND_NOT_DONE);
tmAssert((_mpInterruptActive == 0), MP_ERR_INTERRUPT_LEVEL_CALL);
LOCK_MPEG_PIPE(instance);
MpInfo[instance].callBackStatus = TMMPCALLBACK_OK;
MpInfo[instance].endRow = endRow;
if(MpInfo[instance].mpPictInfo & MP_VLD_PI_MPEG2){
/* +1 because startcode will stop it at the end of a row */
mpSetCOMMAND(MP_VLD_COMMAND_PARSE_LINE | (( MpInfo[instance].mpMCPictInfo0 & MP_MC_PI0_MB_WIDTH) + 1));
}
else{
mpSetCOMMAND(MP_VLD_COMMAND_PARSE | (( MpInfo[instance].mpMCPictInfo0 & MP_MC_PI0_MB_WIDTH)));
}
imask = (MP_VLD_MC_STATUS_ANY_ERROR | MP_VLD_MC_STATUS_SUCCESS | MP_VLD_MC_STATUS_STARTCODE |
MP_VLD_MC_STATUS_DMA_IN_DONE | MP_VLD_MC_STATUS_FLUSH_DONE);
imask |= (_mpErrorCon1Pending ? MP_VLD_MC_STATUS_ERRCON_DONE : 0);
mpSetIE(imask);
if(False == exSync){
MpInfo[instance].aSyncPending = True;
MPEXT(instance);
return (TMLIBDEV_OK);
}
MpInfo[_mpCurInstance].suspended = True;
SUSPEND_SELF();
UNLOCK_MPEG_PIPE();
MPEXT(instance);
return (MpInfo[instance].callBackStatus == TMMPCALLBACK_OK ?
TMLIBDEV_OK: MP_ERR_CALLBACK_FAILED);
}
/****************************************************************************
tmLibdevErr_t mpInput(Int instance, Pointer readaddr, UInt32 readcount)
Supply MP more data by giving addr and cnt.
This should normally be called only when the count is zero.
readcount should be 14 bits
****************************************************************************/
extern tmLibdevErr_t
mpInput(Int instance, Pointer readaddr, UInt32 readcount)
{
UInt32 curr_bit_cnt;
Int32 bits_consumed;
MPENT(instance);
STD_ASSERTS(instance);
tmAssert(readcount < (1 << 15), MP_ERR_BIT_CNT_OVERFLOW);
tmAssert(!(readcount & 3), MP_ERR_BIT_CNT_OVERFLOW);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -