📄 tmdlmbs2_support.c
字号:
//-----------------------------------------------------------------------------// (C) Copyright 2003 Philips Semiconductors, All rights reserved//// This source code and any compilation or derivative thereof is the sole// property of Philips Corporation and is provided pursuant to a Software// License Agreement. This code is the proprietary information of Philips// Corporation and is confidential in nature. Its use and dissemination by// any party other than Philips Corporation is strictly limited by the// confidential information provisions of the Agreement referenced above.//-----------------------------------------------------------------------------// FILE NAME: tmdlMbs2_Support.c//// DESCRIPTION: This file contains the support routines for the MBS2 Device // library.//// DOCUMENT REF://// NOTES: Function prototypes can be found in the tmdlMbs2_Support.h // header file.////-----------------------------------------------------------------------------// Programming Notes://// * YUV pair source formats (YUY2, YUV42xSemiPlanar, YUV42xPlanar, etc.):// - if the source rectangle ul.x does not start on the first pixel of the // pixel pair, ul.x MUST be decremented and 0x400 added to the dto offset// to discard the extra run-in pixel.// - the source width (reg 0xC104 PFU_LSIZE) MUST be a multiple of 2. If// the source rect width is not, increment and let the dest rect clip the// extra data.//// * YUV pair dest formats:// - dest rect ul.x MUST start on the first pixel of the pixel pair (even// number).// - dest rect ul.y MUST start on an even line for 420 formats.//// * Horizontal scaling AND color space conversion is not supported//-----------------------------------------------------------------------------// Standard include files://-----------------------------------------------------------------------------#include <stdlib.h>//-----------------------------------------------------------------------------// Project include files://-----------------------------------------------------------------------------#include <tmdlMbs.h>#include <tmosal.h>#include <tmml.h>#include <tmbslCore.h>#include <tmdlClock.h>#include "tmdlMbs2_Local.h"#include "tmdlMbs2_Support.h"#include "tmdlMbs2_Coeff.h"#include <tmdlMbs2_0119.h>#include <tmdlMbs2_Cfg.h>//-----------------------------------------------------------------------------typedef enum{ tmdlMbsBugsNone = 0, tmdlMbsBugsSmallLineDiff = 1, // vsp_ldiff not large enough tmdlMbsBugsSmallDtoOffset = 2, // hsp_offset, vsp_offset_o & _c // not large enough tmdlMbsBugsNoChromaPrevFirst = 4, // no previous_first_c bit tmdlMbsBugsEddiHang = 8 // Hang when EDDI enabled PR DE#623} tmdlMbsChipBugs_t;#define MBS_V2_REVA_BUGS ( tmdlMbsBugsSmallLineDiff | \ tmdlMbsBugsSmallDtoOffset | \ tmdlMbsBugsNoChromaPrevFirst | \ tmdlMbsBugsEddiHang)#define MBS_V2_REVB_BUGS tmdlMbsBugsEddiHang//-----------------------------------------------------------------------------// Global variables://-----------------------------------------------------------------------------//static Int32 gNumberOfUnits = 0;static UInt32 mbsInstanceCount [MBS_MAX_UNITCOUNT];static Bool mbsInStreamMode [MBS_MAX_UNITCOUNT];// eh04#468tmInstance_t gMbsUnitClock [MBS_MAX_UNITCOUNT];// eh04#468 END// pointer to HW registersstatic ptmdlMbsRegs_t gpRegs [MBS_MAX_UNITCOUNT] = {Null};static UInt32 mbsRegDefaults [tlIndexAfterCtrlRegs];static UInt32 gMbsChipBugs [MBS_MAX_UNITCOUNT];UInt32 gMbsFeatures [MBS_MAX_UNITCOUNT];tmdlMbs2_clockFreq_t mbsClockFreq [MBS_MAX_UNITCOUNT];// eh04#468tmdlMbs2_clockFreq_t gMbsInitialClockFreq [MBS_MAX_UNITCOUNT];// eh04#468 ENDstatic UInt32 gMbsTlCount [MBS_MAX_UNITCOUNT];static Int32 gMbsLineSize [MBS_MAX_UNITCOUNT];static Int32 gMbsLineCount [MBS_MAX_UNITCOUNT];#if ( (TMFL_PNX_ID == 1500)|| (TMFL_PNX_ID == 1700))static Int32 gMbsLineBufferSize [MBS_MAX_UNITCOUNT];#endifstatic Int32 gMbsLineDifMax [MBS_MAX_UNITCOUNT];static UInt32 gMbsDtoOffsetMax [MBS_MAX_UNITCOUNT];static UInt32 gMbsDtoLineMask [MBS_MAX_UNITCOUNT];#define yuvIndex 0#define rgbIndex 1#define clutIndex 2static tmAvDataClass_t gClassList [NR_OF_SUPPORTED_FORMAT_TYPES] ={ avdcVideo, avdcVideo, avdcVideo};static UInt32 gTypeList [NR_OF_SUPPORTED_FORMAT_TYPES] ={ vtfYUV, vtfRGB, vtfCLUT};static UInt32 gInputSubTypeList [NR_OF_SUPPORTED_INPUT_FORMATS] ={ // supported YUV formats vdfUYVY | vdfYUY2 | vdfVYUY | vdfUYVYInterspersed | vdfYUY2Interspersed | vdfVYUYInterspersed | vdfAVYU8888 | vdfXVYU8888 | vdfAYUV8888 | vdfXYUV8888 | vdfYUV444Planar | vdfYUV422Planar | vdfYUV420Planar | vdfYUV422SemiPlanar | vdfYUV420SemiPlanar | vdfYInterleavedUV | vdfYUV420Interspersed | vdfYUV422Interspersed, // supported RGB formats vcfRGB565 | vcfXRGB4444 | vcfARGB4444 | vcfXRGB4453 | vcfARGB4453 | vcfXRGB8888 | vcfARGB8888 | vcfXRGB1555, // supported CLUT formats vdfRGBCLUT1bpp | vdfRGBCLUT2bpp | vdfRGBCLUT4bpp | vdfRGBCLUT8bpp | vdfARGBCLUT1bpp | vdfARGBCLUT2bpp | vdfARGBCLUT4bpp | vdfARGBCLUT8bpp | vdfYUVCLUT1bpp | vdfYUVCLUT2bpp | vdfYUVCLUT4bpp | vdfYUVCLUT8bpp | vdfAYUVCLUT1bpp | vdfAYUVCLUT2bpp | vdfAYUVCLUT4bpp | vdfAYUVCLUT8bpp,};static UInt32 gOutputSubTypeList [NR_OF_SUPPORTED_OUTPUT_FORMATS] ={ // supported YUV formats vdfUYVY | vdfYUY2 | vdfUYVYInterspersed | vdfYUY2Interspersed | vdfAVYU8888 | vdfXVYU8888 | vdfAYUV8888 | vdfXYUV8888 | vdfYUV444Planar | vdfYUV422Planar | vdfYUV420Planar | vdfYUV422SemiPlanar | vdfYUV420SemiPlanar | vdfYUV420Interspersed | vdfYUV422Interspersed, // supported RGB formats vcfRGB565 | vcfXRGB4444 | vcfARGB4444 | vcfXRGB4453 | vcfARGB4453 | vcfXRGB8888 | vcfARGB8888};static tmAvFormatTypeList_t gSupportedInputFormats = { NR_OF_SUPPORTED_INPUT_FORMATS, Null, Null, Null};static tmAvFormatTypeList_t gSupportedOutputFormats = { NR_OF_SUPPORTED_OUTPUT_FORMATS, Null, Null, Null};tmdlMbsCapabilities_t gMbsCaps [MBS_MAX_UNITCOUNT];// indexed by tmdlMbsPhaseMode_tstatic Int32 gPhases[8] = {64, 32, 16, 8, 4, 2, 1, 0};#define DESTINATION_BUFFER False#define SOURCE_BUFFER True#define NORMAL_POLYPHASE False#define TRANSPOSED_POLYPHASE True#define RIGHT_BOTTOM_EDGE False#define LEFT_TOP_EDGE True// slicing related flags#define MBS_MIDDLE_SLICE 0#define MBS_TOP_SLICE 1#define MBS_BOTTOM_SLICE 2#define MBS_LEFT_SLICE 4#define MBS_RIGHT_SLICE 8#define MBS_HORZ_SLICING 16#define MBS_VERT_SLICING 32//-----------------------------------------------------------------------------// Default Color Space Conversion Tables://-----------------------------------------------------------------------------// YUV CCIR range to RGB full range, all values need to be multiplied with -4static tmdlMbsConvMatrix_t yuvToRgbFullCoeff ={ {-149,0,-204,-149,50,104,-149,-258,0}, {-16,-128,-128}, {0,0,0}, 2, // multiply by four (shift of 2) True, // negative};// RGB full range to YUV CCIR range , all values need to be multiplied with -2static tmdlMbsConvMatrix_t rgbFullToYuvCoeff ={ {-66,-129,-25,38,74,-112,-112,94,18}, {0,0,0}, {-8*4,-64*4,-64*4}, 1, // multiply by two (shift of 1) True, // negative}; //-----------------------------------------------------------------------------// Task Queue/HW FIFO variables//-----------------------------------------------------------------------------static Bool mbsTaskDispInitialized [MBS_MAX_UNITCOUNT] = {False, False, False, False};// the code is designed such that the queue size is a power of 2 (16, 32, etc.)//#define MBS_TASK_Q_SIZE 64#define MBS_TASK_Q_MASK (MBS_TASK_Q_SIZE - 1)#define MBS_HWFIFO_Q_SIZE MBS_HW_TASK_FIFO_SIZE#define MBS_HWFIFO_Q_MASK (MBS_HWFIFO_Q_SIZE - 1)typedef struct { ptmdlMbsTaskInfo_t elems [MBS_TASK_Q_SIZE]; Int32 readPtr; Int32 writePtr; Int32 size; Int32 mask;} Queue_t;static Queue_t taskQ [tmdlMbsTaskPriority_Count][MBS_MAX_UNITCOUNT];static Queue_t fifoQ [MBS_MAX_UNITCOUNT];#define MBS_Q_IS_EMPTY(q) (q.readPtr == q.writePtr)#define MBS_Q_IS_FULL(q) (((q.writePtr + 1) & q.mask) == q.readPtr)#define MBS_Q_COUNT(q) ((q.writePtr + q.size - q.readPtr) & q.mask)#define MBS_Q_READ(q, pTask) \ { \ pTask = q.elems [q.readPtr]; \ q.readPtr = ((q.readPtr + 1) & q.mask); \ }// interrupt related globalsstatic Bool mbsInterruptInitialized [MBS_MAX_UNITCOUNT] = {False, False, False, False};static tmosalIntHandle_t mbsIntHandle [MBS_MAX_UNITCOUNT];static UInt32 mbsIntParam [MBS_MAX_UNITCOUNT];//-----------------------------------------------------------------------------// Local Functions (not exported from the DevLib)://-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// FUNCTION: MbsAppendTask://// DESCRIPTION: Appends task2 to the end of task1.//// RETURN: None//// NOTES: If pTask2 is Null, Task1 is the final Task of the concatenated // list, else task2 will be queued for execution after task1 // completes.//// Assumes the mode control register will be flushed from the cache// when the task is dispatched.//-----------------------------------------------------------------------------//#define MBS_MASK_TASK_INTS 1#define MBS_UNMASK_TASK_INTS 0voidMbsAppendTask ( ptmdlMbsTaskInfo_t pTask1, // I: ptr to Task1 ptmdlMbsTaskInfo_t pTask2 // I: ptr to Task2 ){ UInt32 intEnableState; union _mbsModeCtrl *pModeControl; if (pTask2 == Null) { // end of task list *(pTask1->pNextCmd) = MBS_TASK_END_START_PROCESS; intEnableState = MBS_UNMASK_TASK_INTS; } else { // else link task2 to task1 *(pTask1->pNextCmd) = MBS_TASK_START_AND_QUEUE + pTask2->taskBase; intEnableState = MBS_MASK_TASK_INTS; } tmmlCacheFlush (pTask1->pNextCmd, sizeof(UInt32)); // set the interrupt enable register pModeControl = (union _mbsModeCtrl *) &(pTask1->pCtrlRegs [tlModeControl]); pModeControl->bits.maskTaskInts = intEnableState;} // MbsAppendTask//-----------------------------------------------------------------------------// FUNCTION: MbsSliceTask://// DESCRIPTION: Subdivides given task into chunks (horz) which fit into the // internal line buffer//// RETURN: None//// NOTES: If pTask2 is Null, Task1 is the final Task of the concatenated // list, else task2 will be queued for execution after task1 // completes.//// Assumes the mode control register will be flushed from the cache// when the task is dispatched.//-----------------------------------------------------------------------------//voidMbsSliceTask ( ptmdlMbsInstance_t pMbsInst, // I: mbs instance UInt32 taskIndex, // I: UInt32 *pNrOfSlices // O: ){ ptmdlMbsTaskInfo_t pTask; ptmdlMbsTaskDescriptor_t pTaskDescr; ptmdlMbsTaskInfo_t pCurrSliceTask; ptmdlMbsTaskDescriptor_t pCurrSliceTaskDescr; UInt32 srcWidth,dstWidth; UInt32 srcHeight,dstHeight; UInt32 maxHeight; UInt32 nrOfVertSlices,nrOfHorzSlices; tmXY_t prevSliceEnd; tmErrorCode_t status = TM_OK; UInt32 sliceWidth; UInt32 sliceHeight; Int32 i,j; Bool horizSliced; Bool vertSliced; UInt32 limitX; UInt32 limitY; DBG_ASSERT(taskIndex < pMbsInst->totalNrOfTasks); pTask = &(pMbsInst->pTaskInfo [taskIndex]); pTaskDescr = &(pTask->dlTaskDescr); srcWidth = pTaskDescr->inputBuffer.rect.lr.x - pTaskDescr->inputBuffer.rect.ul.x; dstWidth = pTaskDescr->outputBuffer.rect.lr.x - pTaskDescr->outputBuffer.rect.ul.x; srcHeight = pTaskDescr->inputBuffer.rect.lr.y - pTaskDescr->inputBuffer.rect.ul.y; dstHeight = pTaskDescr->outputBuffer.rect.lr.y - pTaskDescr->outputBuffer.rect.ul.y;#if ( (TMFL_PNX_ID == 1500)|| (TMFL_PNX_ID == 1700)) limitX = gMbsLineBufferSize [pMbsInst->unit];#else limitX = gMbsLineSize [pMbsInst->unit];#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -