⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmmp.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -