📄 tmhdvo.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 : tmHDVO.c 1.31
*
* Last update : 19:22:30 - 00/11/09
*
*
* Description :
*
* This is the HDVO device library file.
*
* Revision :
*
*/
/*-----------------------------includes-------------------------------------*/
#include <tm1/tmAssert.h>
#include <stdio.h>
#include <ops/custom_defs.h>
#include <tm1/tmHDVO.h>
#include "tmHDVOpriv.h"
#include <string.h>
#include <math.h>
#include <tm1/tmGPIO.h>
#include <tmlib/AppModel.h>
#include <tm1/tmProcessor.h>
#include <tmlib/dprintf.h>
/*-----------------------------defines---------------------------------------*/
/*
* Maximum microcode and initialised data sizes
*/
#define HDVO_MAX_MICROCODE_SIZE 6144 /* maximum of 6144 (6k)
instructions or 18k bytes */
#ifdef HDVO_NOKERNEL
#define HDVO_MAX_DATA_SIZE 896*2 /* max data segment size is
896 words (7 pages) == 256 bytes */
#else
#define HDVO_MAX_DATA_SIZE 256 /* max data segment size is
128 words == 256 bytes */
#endif
/*------------------------------types----------------------------------------*/
static UInt32 hdvoInstance;
static Bool interruptInstalled = False;
static boardHDVOConfig_t *boardHDVOConfig;
static unitSelect_t hdvoUnitName;
/*
* The following specifies the current endian swap operation
*/
static hdvoDMA_HWY_SWAP_TYPE_t hdvoCurrentSwapType = HDVO_DMA_HWY_NO_SWAP;
typedef struct {
UInt32 numberOfUnits;
phdvoCapabilities_t unitCapabilities;
} hdvoCapabilitiesList_t;
static hdvoCapabilitiesList_t capabilities = {
0, /* number of units */
Null /* array of unit descriptors */
};
static Int gpioInstance = 0;
/*------------------------ Internal function prototypes ---------------------*/
tmLibdevErr_t hdvoCalculateFrequency(UInt32 hdvoClockFrequency,
UInt32 *freq, UInt8 * divmux);
static tmLibdevErr_t hdvoPrepareCapabilities (void);
static tmLibdevErr_t HDVOsetup_board(tmVideoAnalogStandard_t videoStandard,
tmVideoAnalogAdapter_t adapterType,
tmVideoTypeFormat_t videoType,
hdvoImageOutputMode_t videoSubtype,
UInt32 description)
{
tmLibdevErr_t rval;
rval = tsaBoardGetHDVO(unit0, &boardHDVOConfig);
if (rval != TMLIBDEV_OK)
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
if (boardHDVOConfig->initFunc == Null)
return (BOARD_ERR_NULL_FUNCTION);
if (rval = boardHDVOConfig->initFunc(videoStandard, adapterType,
videoType, videoSubtype, description))
return (rval);
return TMLIBDEV_OK;
}
extern tmLibdevErr_t hdvoGetNumberOfUnits(UInt32 *pNumberOfUnits)
{
UInt32 i = 0;
boardHDVOConfig_t *dummyConfig;
tmAssert(pNumberOfUnits, TMLIBDEV_ERR_NULL_PARAMETER);
while (tsaBoardGetHDVO(i, &dummyConfig) == TMLIBDEV_OK)
i++;
*pNumberOfUnits = i;
return TMLIBDEV_OK;
}
static tmLibdevErr_t hdvoPrepareCapabilities(void)
{
UInt32 numberOfUnits, i;
boardHDVOConfig_t *HDVOConfig;
tmLibdevErr_t rval;
if (capabilities.unitCapabilities == Null) {
if (TMLIBDEV_OK != (rval = hdvoGetNumberOfUnits(&numberOfUnits)))
return rval;
if (numberOfUnits == 0) {
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
}
capabilities.numberOfUnits = numberOfUnits;
capabilities.unitCapabilities = (phdvoCapabilities_t)
malloc(capabilities.numberOfUnits * sizeof(hdvoCapabilities_t));
if (capabilities.unitCapabilities == Null)
return TMLIBDEV_ERR_MEMALLOC_FAILED;
for (i = 0; i < capabilities.numberOfUnits; i++) {
if (TMLIBDEV_OK != tsaBoardGetHDVO(i, &HDVOConfig)) {
/* this should never happen, since we already checked before */
/* FIXME : the error code is not appropriate */
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
}
capabilities.unitCapabilities[i].numCurrentInstances = 0;
capabilities.unitCapabilities[i].numSupportedInstances = 1;
capabilities.unitCapabilities[i].videoStandards = HDVOConfig->standards;
capabilities.unitCapabilities[i].adapterTypes = HDVOConfig->adapters;
capabilities.unitCapabilities[i].videoType =
(tmVideoTypeFormat_t) HDVOConfig->videoType;
capabilities.unitCapabilities[i].videoSubtype =
(hdvoImageOutputMode_t) HDVOConfig->videoSubtype;
capabilities.unitCapabilities[i].description = HDVOConfig->description;
if (HDVOConfig->codecName != Null) {
strncpy(capabilities.unitCapabilities[i].codecName,
HDVOConfig->codecName, DEVICE_NAME_LENGTH);
}
}
}
return TMLIBDEV_OK;
}
/****************************** Library Functions ****************************/
/*****************************************************************************/
/*
* Function : hdvoGetCapabilitiesM
* Return a pointer to the capabilities of HDVO.
*
* Parameters : 1. Pointer to hdvoCapabilities_t.
* 2. unit name
*
* Function Result: Return TMLIBDEV_OK on success.
* TMLIBDEV_ERR_NULL_PARAMETER, Null parameter passed.
* TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW - unit is not valid.
*/
tmLibdevErr_t
hdvoGetCapabilitiesM(phdvoCapabilities_t * hdvoCap,
unitSelect_t unitName)
{
tmLibdevErr_t rval;
tmAssert(hdvoCap != NULL, TMLIBDEV_ERR_NULL_PARAMETER);
AppModel_suspend_scheduling();
rval = hdvoPrepareCapabilities();
AppModel_resume_scheduling();
if (rval != TMLIBDEV_OK)
return rval;
if (unitName > capabilities.numberOfUnits)
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
*hdvoCap = &capabilities.unitCapabilities[unitName];
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function : hdvoOpenM
* Assign instance for usage. HDVO is
* a single instance device.
*
* Parameters : 1. Pointer to the instance
* 2. unit name
*
* Function Result: Return TMLIBDEV_OK on success
* TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW - unit is not valid.
* HDVO_ERR_NO_MORE_INSTANCES if someone else is using HDVO.
*/
tmLibdevErr_t
hdvoOpenM(Int * instance, unitSelect_t unitName)
{
gpioInstanceSetup_t gpioSetup;
tmLibdevErr_t rval;
boardHDVOConfig_t *hdvoBoardConfig;
UInt32 i;
tmAssert(instance != Null, TMLIBDEV_ERR_NULL_PARAMETER);
if (!instance)
return TMLIBDEV_ERR_NULL_PARAMETER;
rval = tsaBoardGetHDVO(unitName, &hdvoBoardConfig);
if (rval != TMLIBDEV_OK)
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
AppModel_suspend_scheduling();
/*
* Make sure that the capabilities are valid
*/
rval = hdvoPrepareCapabilities();
if (rval != TMLIBDEV_OK)
goto hdvoOpenExit;
if (capabilities.unitCapabilities[unitName].numCurrentInstances >=
capabilities.unitCapabilities[unitName].numSupportedInstances) {
rval = TMLIBDEV_ERR_NO_MORE_INSTANCES;
goto hdvoOpenExit;
}
/* atomic by nature */
hdvoInstance++;
capabilities.unitCapabilities[unitName].numCurrentInstances++;
boardHDVOConfig = hdvoBoardConfig;
hdvoUnitName = unitName;
/* this call will only fail if there is no GPIO capabilities */
/* this call should never fail because on TM2 there is some GPIO */
rval = gpioOpen(&gpioInstance);
if (rval == TMLIBDEV_OK)
{
/* Get the default instance setup */
gpioGetInstanceSetup(gpioInstance, &gpioSetup);
for (i = hdvoBoardConfig->gpioFirstPin; i <= hdvoBoardConfig->gpioLastPin;
i++) {
gpioInsertMode(gpioSetup.pinMode[i >> 4],
i - (hdvoBoardConfig->gpioFirstPin & 0xfffffff0),
gpioRegularMode);
gpioInsertPin(gpioSetup.pinMask[i >> 5],
i - (hdvoBoardConfig->gpioFirstPin & 0xffffffe0), 1);
}
rval = gpioInstanceSetup(gpioInstance, &gpioSetup);
if (rval != TMLIBDEV_OK) {
gpioClose(gpioInstance);
intClose(hdvoBoardConfig->intNumber);
goto hdvoOpenExit;
}
}
else {
gpioInstance = 0;
}
*instance = hdvoInstance;
hdvoOpenExit:
AppModel_resume_scheduling();
return (rval);
} /* end hdvoOpen */
/*****************************************************************************/
/*
* Function : hdvoInstanceSetup
* Prepare HDVO for operation by:
* Reseting HDVO if requested
* Install interrupt handler, if requested.
* Initialising the context structures self reference fields
* Loading the STM gamma table
* Loading the STM parameters
* Loading the MCP context structure
* Loading the MCP initialised data segment
* Loading the MCP program memory
* Enabling the MCP.
*
* Parameters : 1. Instance
* 2. Pointer to the hdvo setup block hdvoInstanceSetup_t
*
* Function Result: Return zero on success
* TMLIBDEV_ERR_NOT_OWNER; Someone else already has the
* device control
* TMLIBDEV_ERR_NULL_PARAMETER; the setup parameter is Null.
* BOARD_ERR_NULL_FUNCTION; the respective BSP initFunc
* pointer is Null.
*
* Precondition : Require hdvoOpen() to be called first.
*/
tmLibdevErr_t
hdvoInstanceSetup(Int instance, hdvoInstanceSetup_t * setup)
{
tmLibdevErr_t rval;
intInstanceSetup_t int_setup;
UInt8 *mdxParameters;
tmAssert(hdvoInstance == instance, TMLIBDEV_ERR_NOT_OWNER);
if (hdvoInstance != instance)
return TMLIBDEV_ERR_NOT_OWNER;
tmAssert(setup, TMLIBDEV_ERR_NULL_PARAMETER);
if (!setup)
return TMLIBDEV_ERR_NULL_PARAMETER;
tmAssert(setup->context, TMLIBDEV_ERR_NULL_PARAMETER);
if (!(setup->context))
return TMLIBDEV_ERR_NULL_PARAMETER;
tmAssert(!(((UInt32) setup->context) & 0xf), HDVO_ERR_ADDRESS_NOT_ALIGNED);
if (((UInt32) setup->context) & 0xf)
return HDVO_ERR_ADDRESS_NOT_ALIGNED;
if (setup->reset) {
hdvoReset();
if (setup->arbiterDelta != 0)
hdvoSetMCP_ARB1(setup->arbiterDelta);
else
hdvoSetMCP_ARB1(0x36); /* default value for 120MHz app */
if (setup->arbiterWait != 0)
hdvoSetMCP_ARB2_Wait(setup->arbiterWait);
else
hdvoSetMCP_ARB2_Wait(0x01); /* default value for 120MHz app */
}
if (!interruptInstalled) {
if (rval = intOpen(intHDVO)) {
tmAssert((rval == TMLIBDEV_OK), rval);
return rval;
}
}
int_setup.handler = setup->isr;
int_setup.priority = setup->interruptPriority;
int_setup.level_triggered = True;
int_setup.enabled = True;
if (rval = intInstanceSetup(intHDVO, &int_setup)) {
tmAssert((rval == TMLIBDEV_OK), rval);
return rval;
}
interruptInstalled = True;
/*
* Set the MCP Endian flag. This is set to the same value as the DSPCPU
* endianness
*/
#ifdef __LITTLE_ENDIAN__
hdvoEnableMCP_CTRL_Little_Endian();
#else
hdvoDisableMCP_CTRL_Little_Endian();
#endif
/*
* load streaming out parameters, streaming out gamma table, context,
* dataSegment, and microcode.
*/
#ifndef DISABLE_LOAD_STM_GAMMA
rval = hdvoLoadSTMGamma(setup->gammaTable);
tmAssert(rval == TMLIBDEV_OK, rval);
if (rval != TMLIBDEV_OK)
return rval;
#endif
#ifndef DISABLE_LOAD_STM_PARAMS
if (setup->clockFrequency) {
rval = hdvoSetHDVO_CLK(instance, setup->clockFrequency,
setup->stmParameters);
if (rval != TMLIBDEV_OK)
return rval;
rval = hdvoSetFrequency(instance, setup->clockFrequency,
setup->context);
if (rval != TMLIBDEV_OK)
return rval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -