
Modified TCL file, source files, and renamed example.c as scaler_example.c Signed-off-by: Durga challa <vnsldurg@xilinx.com>
948 lines
34 KiB
C
Executable file
948 lines
34 KiB
C
Executable file
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* Use of the Software is limited solely to applications:
|
|
* (a) running on a Xilinx device, or
|
|
* (b) that interact with a Xilinx device through a bus or interconnect.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the Xilinx shall not be used
|
|
* in advertising or otherwise to promote the sale, use or other dealings in
|
|
* this Software without prior written authorization from Xilinx.
|
|
*
|
|
******************************************************************************/
|
|
/**
|
|
*
|
|
* @file xscaler.c
|
|
*
|
|
* This is main code of Xilinx MVI Video Scaler device driver. The Scaler device
|
|
* converts a specified rectangular area of an input digital video image from
|
|
* one original sampling grid to a desired target sampling grid. Please see
|
|
* xscaler.h for more details of the driver.
|
|
*
|
|
* <pre>
|
|
* MODIFICATION HISTORY:
|
|
*
|
|
* Ver Who Date Changes
|
|
* ----- ---- -------- -------------------------------------------------------
|
|
* 1.00a xd 02/10/09 First release
|
|
* 2.00a xd 12/14/09 Updated Doxygen document tags
|
|
* 4.01a cw 06/27/12 Updated tcl file with new parameter names (num_x_taps)
|
|
* Updated mdd file with updated supported_peripherals
|
|
* field.
|
|
* 4.02a mpv 03/11/13 Updated the Driver to select the correct coeff bin.
|
|
* Changed RegValue variable to a volatile type
|
|
* Removed 10.x patch in the Tcl file
|
|
* 4.03a mpv 05/28/13 Fixed version limit in MDD file
|
|
* Updated the Driver input, output and aperture size
|
|
* mask
|
|
* 5.00a mpv 12/13/13 Updated to dynamic coeff generation to reduce driver
|
|
* size
|
|
* 7.0 adk 08/22/14 Modified prototype of XScaler_GetVersion API.
|
|
* and functionality of StubCallBack. Modified assert
|
|
* conditions in functions XScaler_CfgInitialize,
|
|
* XScaler_SetPhaseNum, XScaler_LoadCoeffBank.
|
|
* Removed error callback from XScaler_CfgInitialize
|
|
* function.
|
|
* Uncommented XScaler_Reset in XScaler_CfgInitialize
|
|
* function.
|
|
* Removed ErrorMask parameter in StubCallBack as there
|
|
* was only one interrupt.
|
|
* </pre>
|
|
*
|
|
******************************************************************************/
|
|
|
|
/***************************** Include Files *********************************/
|
|
|
|
#include "xscaler.h"
|
|
#include "xenv.h"
|
|
#include "xil_io.h"
|
|
#include "xil_assert.h"
|
|
|
|
/************************** Constant Definitions *****************************/
|
|
|
|
|
|
/**************************** Type Definitions *******************************/
|
|
|
|
|
|
/***************** Macros (Inline Functions) Definitions *********************/
|
|
|
|
/** @name Utility Macros
|
|
* @{
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This macro calculates the integral value nearest to x rounding half-way cases
|
|
* away from zero, regardless of the current rounding direction.
|
|
*
|
|
* @param x has a float type value
|
|
*
|
|
* @return The integral value nearest to x rounding half-way cases away
|
|
* from zero, regardless of the current rounding direction.
|
|
*
|
|
* @note C-style signature: s32 round(float x);
|
|
*
|
|
******************************************************************************/
|
|
#define round(x) ((x) >= 0 ? (s32)((x) + 0.5) : (s32)((x) - 0.5))
|
|
|
|
/*@}*/
|
|
|
|
/************************** Function Prototypes ******************************/
|
|
|
|
static u32 XScaler_CoeffBinOffset(u32 InSize, u32 OutSize);
|
|
static void StubCallBack(void *CallBackRef);
|
|
|
|
/************************* Data Structure Definitions ************************/
|
|
|
|
/**
|
|
* XScaler_CoefficientsBinScalingFactors contains scaling factors calculated
|
|
* using (Output_Size * 10000 / Input_Size). This table could help find
|
|
* the index of coefficient Bin given an input size and a output size.
|
|
*/
|
|
extern u16 XScaler_CoefficientBinScalingFactors[XSCL_NUM_COEF_BINS];
|
|
|
|
/**
|
|
* XScaler_GenCoefTable generates XScaler_coef_table containing the coefficient
|
|
* values for scaling operations
|
|
*/
|
|
|
|
extern s16 *XScaler_GenCoefTable(u32 Tap, u32 Phase);
|
|
|
|
/************************** Function Definition ******************************/
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function initializes a Scaler device. This function must be called
|
|
* prior to using a Scaler device. Initialization of a Scaler includes setting
|
|
* up the instance data, and ensuring the hardware is in a quiescent state.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param CfgPtr points to the configuration structure associated with
|
|
* the Scaler device.
|
|
* @param EffectiveAddr is the base address of the device. If address
|
|
* translation is being used, then this parameter must
|
|
* reflect the virtual base address. Otherwise, the physical
|
|
* address should be used.
|
|
*
|
|
* @return XST_SUCCESS
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
int XScaler_CfgInitialize(XScaler *InstancePtr, XScaler_Config *CfgPtr,
|
|
u32 EffectiveAddr)
|
|
{
|
|
|
|
/* Verify arguments */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(CfgPtr != NULL);
|
|
|
|
Xil_AssertNonvoid(CfgPtr->MaxPhaseNum <= XSCL_MAX_PHASE_NUM);
|
|
|
|
Xil_AssertNonvoid(CfgPtr->HoriTapNum <= XSCL_MAX_TAP_NUM);
|
|
|
|
Xil_AssertNonvoid(CfgPtr->VertTapNum <= XSCL_MAX_TAP_NUM);
|
|
|
|
Xil_AssertNonvoid(CfgPtr->CoeffSetNum <= XSCL_MAX_COEFF_SET_NUM);
|
|
|
|
Xil_AssertNonvoid(EffectiveAddr != (u32)NULL);
|
|
|
|
/* Setup the instance */
|
|
memset((void *)InstancePtr, 0, sizeof(XScaler));
|
|
memcpy((void *)&(InstancePtr->Config), (const void *)CfgPtr,
|
|
sizeof(XScaler_Config));
|
|
InstancePtr->Config.BaseAddress = EffectiveAddr;
|
|
|
|
/* Set all handlers to stub values, let user configure this data later
|
|
*/
|
|
InstancePtr->CallBack = (XScaler_CallBack)StubCallBack;
|
|
|
|
/* Reset the hardware and set the flag to indicate the driver is ready
|
|
*/
|
|
|
|
XScaler_Reset(InstancePtr);
|
|
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function sets up aperture of a Scaler device. The aperture setting
|
|
* consists of input video aperture and output video size. This function
|
|
* calculates the scale factor accordingly based on the aperture setting and
|
|
* sets up the Scaler appropriately.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param AperturePtr points to the aperture setting structure to set up
|
|
* the Scaler device.
|
|
*
|
|
* @return XST_SUCCESS.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
int XScaler_SetAperture(XScaler *InstancePtr, XScalerAperture *AperturePtr)
|
|
{
|
|
double VertScaleFactor;
|
|
double HoriScaleFactor;
|
|
u32 InLine;
|
|
u32 InPixel;
|
|
u32 OutSize;
|
|
u32 SrcSize;
|
|
u32 QuantizedHoriSize;
|
|
u32 QuantizedVertSize;
|
|
u32 QuantizedInLastPixel;
|
|
u32 QuantizedInLastLine;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(AperturePtr != NULL);
|
|
Xil_AssertNonvoid(AperturePtr->InFirstLine <= AperturePtr->InLastLine);
|
|
Xil_AssertNonvoid(AperturePtr->InFirstPixel <= AperturePtr->InLastPixel);
|
|
Xil_AssertNonvoid(AperturePtr->OutVertSize > 0);
|
|
Xil_AssertNonvoid(AperturePtr->OutHoriSize > 0);
|
|
|
|
/* Calculate vertical and horizontal scale factors */
|
|
VertScaleFactor =
|
|
(float)(AperturePtr->InLastLine - AperturePtr->InFirstLine
|
|
+ 1);
|
|
VertScaleFactor /=
|
|
(float)(AperturePtr->OutVertSize);
|
|
HoriScaleFactor =
|
|
(float)(AperturePtr->InLastPixel - AperturePtr->InFirstPixel
|
|
+ 1);
|
|
HoriScaleFactor /=
|
|
(float)AperturePtr->OutHoriSize;
|
|
|
|
/* Convert HoriScaleFactor and VertScaleFactor values into a format
|
|
* to write to HSF and VSF registers.
|
|
*/
|
|
VertScaleFactor *= XSCL_SHRINK_FACTOR;
|
|
HoriScaleFactor *= XSCL_SHRINK_FACTOR;
|
|
|
|
/* Quantize Aperture - feed scale-factor back in to provide the
|
|
* actual aperture required to generate the desired number of output
|
|
* samples.
|
|
*/
|
|
QuantizedHoriSize = AperturePtr->OutHoriSize - 1;
|
|
QuantizedHoriSize =
|
|
(u32)(((float)QuantizedHoriSize * HoriScaleFactor) /
|
|
XSCL_SHRINK_FACTOR);
|
|
QuantizedHoriSize += 1 + (InstancePtr->Config.HoriTapNum + 1) / 2;
|
|
|
|
QuantizedInLastPixel = AperturePtr->InFirstPixel + QuantizedHoriSize
|
|
- 1;
|
|
if (QuantizedInLastPixel > AperturePtr->InLastPixel)
|
|
QuantizedInLastPixel = AperturePtr->InLastPixel;
|
|
|
|
QuantizedVertSize = AperturePtr->OutVertSize - 1;
|
|
QuantizedVertSize =
|
|
(u32)(((float)QuantizedVertSize * VertScaleFactor) /
|
|
XSCL_SHRINK_FACTOR);
|
|
QuantizedVertSize += 1 + (InstancePtr->Config.VertTapNum + 1) / 2;
|
|
|
|
QuantizedInLastLine = AperturePtr->InFirstLine + QuantizedVertSize - 1;
|
|
if (QuantizedInLastLine > AperturePtr->InLastLine)
|
|
QuantizedInLastLine = AperturePtr->InLastLine;
|
|
|
|
/* Calculate input line, pixel and output size values */
|
|
InLine = AperturePtr->InFirstLine & XSCL_APTVERT_FIRSTLINE_MASK;
|
|
InLine |= (QuantizedInLastLine << XSCL_APTVERT_LASTLINE_SHIFT)
|
|
& XSCL_APTVERT_LASTLINE_MASK;
|
|
InPixel = AperturePtr->InFirstPixel & XSCL_APTHORI_FIRSTPXL_MASK;
|
|
InPixel |= (QuantizedInLastPixel << XSCL_APTHORI_LASTPXL_SHIFT)
|
|
& XSCL_APTHORI_LASTPXL_MASK;
|
|
OutSize = AperturePtr->OutHoriSize & XSCL_OUTSIZE_NUMPXL_MASK;
|
|
OutSize |= (AperturePtr->OutVertSize << XSCL_OUTSIZE_NUMLINE_SHIFT)
|
|
& XSCL_OUTSIZE_NUMLINE_MASK;
|
|
|
|
SrcSize = AperturePtr->SrcHoriSize & XSCL_SRCSIZE_NUMPXL_MASK;
|
|
SrcSize |= (AperturePtr->SrcVertSize << XSCL_SRCSIZE_NUMLINE_SHIFT)
|
|
& XSCL_SRCSIZE_NUMLINE_MASK;
|
|
|
|
/* Set up aperture related register in the Scaler */
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_APTVERT_OFFSET), InLine);
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_APTHORI_OFFSET), InPixel);
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_OUTSIZE_OFFSET), OutSize);
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_SRCSIZE_OFFSET), SrcSize);
|
|
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_HSF_OFFSET), (u32)(round(HoriScaleFactor)));
|
|
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_VSF_OFFSET), (u32)(round(VertScaleFactor)));
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function gets aperture of a Scaler device. The aperture setting
|
|
* consists of input video aperture and output video size.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param AperturePtr points to the aperture structure to store the
|
|
* current Scaler device setting after this function returns.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_GetAperture(XScaler *InstancePtr, XScalerAperture *AperturePtr)
|
|
{
|
|
u32 InLine;
|
|
u32 InPixel;
|
|
u32 OutSize;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(AperturePtr != NULL);
|
|
|
|
/* Read the first/last line and pixel info for input side and
|
|
* vertical/horizontal size for output size
|
|
*/
|
|
InLine = XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_APTVERT);
|
|
InPixel = XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_APTHORI);
|
|
OutSize = XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_OUTSIZE);
|
|
|
|
/* Parse the info and populate the aperture structure */
|
|
AperturePtr->InFirstLine = InLine & XSCL_APTVERT_FIRSTLINE_MASK;
|
|
AperturePtr->InLastLine =
|
|
(InLine & XSCL_APTVERT_LASTLINE_MASK) >>
|
|
XSCL_APTVERT_LASTLINE_SHIFT;
|
|
|
|
AperturePtr->InFirstPixel = InPixel & XSCL_APTHORI_FIRSTPXL_MASK;
|
|
AperturePtr->InLastPixel =
|
|
(InPixel & XSCL_APTHORI_LASTPXL_MASK) >>
|
|
XSCL_APTHORI_LASTPXL_SHIFT;
|
|
|
|
AperturePtr->OutHoriSize = OutSize & XSCL_OUTSIZE_NUMPXL_MASK;
|
|
AperturePtr->OutVertSize =
|
|
(OutSize & XSCL_OUTSIZE_NUMLINE_MASK) >>
|
|
XSCL_OUTSIZE_NUMLINE_SHIFT;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function sets the numbers of vertical and horizontal phases to be used
|
|
* by a Scaler device.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param VertPhaseNum is the number of vertical phase to set to
|
|
* @param HoriPhaseNum is the number of horizontal phase to set to
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_SetPhaseNum(XScaler *InstancePtr, u16 VertPhaseNum,
|
|
u16 HoriPhaseNum)
|
|
{
|
|
u32 PhaseRegValue;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(VertPhaseNum <= InstancePtr->Config.MaxPhaseNum);
|
|
Xil_AssertVoid(HoriPhaseNum <= InstancePtr->Config.MaxPhaseNum);
|
|
|
|
/* Calculate the value to write to "Number of Phases Register" */
|
|
PhaseRegValue =
|
|
(VertPhaseNum << XSCL_NUMPHASE_VERT_SHIFT) &
|
|
XSCL_NUMPHASE_VERT_MASK;
|
|
PhaseRegValue |= HoriPhaseNum & XSCL_NUMPHASE_HORI_MASK;
|
|
|
|
/* Set up the Scaler core using the numbers of phases */
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_NUMPHASE_OFFSET), PhaseRegValue);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function gets the numbers of vertical and horizontal phases currently
|
|
* used by a Scaler device.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param VertPhaseNumPtr will point to the number of vertical phases
|
|
* used after this function returns.
|
|
* @param HoriPhaseNumPtr will point to the number of horizontal phases
|
|
* used after this function returns.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_GetPhaseNum(XScaler *InstancePtr, u16 *VertPhaseNumPtr,
|
|
u16 *HoriPhaseNumPtr)
|
|
{
|
|
u32 PhaseRegValue;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(VertPhaseNumPtr != NULL);
|
|
Xil_AssertVoid(HoriPhaseNumPtr != NULL);
|
|
|
|
/* Get the value of "Number of Phases Register" */
|
|
PhaseRegValue = XScaler_ReadReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_NUMPHASE_OFFSET));
|
|
|
|
/* Parse the value and store the results */
|
|
*VertPhaseNumPtr =
|
|
(PhaseRegValue & XSCL_NUMPHASE_VERT_MASK) >>
|
|
XSCL_NUMPHASE_VERT_SHIFT;
|
|
*HoriPhaseNumPtr = PhaseRegValue & XSCL_NUMPHASE_HORI_MASK;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function sets up Luma and Chroma start fractional values used by a
|
|
* Scaler device.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param StartFractionPtr is a pointer to a start fractional value set
|
|
* to be used.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_SetStartFraction(XScaler *InstancePtr,
|
|
XScalerStartFraction *StartFractionPtr)
|
|
{
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(StartFractionPtr != NULL);
|
|
|
|
/* Set up the fractional values */
|
|
XScaler_WriteReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTLUMALEFT_OFFSET,
|
|
(u32)StartFractionPtr->LumaLeftHori &
|
|
XSCL_FRCTLUMALEFT_VALUE_MASK);
|
|
|
|
XScaler_WriteReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTLUMATOP_OFFSET,
|
|
(u32)StartFractionPtr->LumaTopVert &
|
|
XSCL_FRCTLUMATOP_VALUE_MASK);
|
|
|
|
XScaler_WriteReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTCHROMALEFT,
|
|
(u32)StartFractionPtr->ChromaLeftHori &
|
|
XSCL_FRCTCHROMALEFT_VALUE_MASK);
|
|
|
|
XScaler_WriteReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTCHROMATOP_OFFSET,
|
|
(u32)StartFractionPtr->ChromaTopVert &
|
|
XSCL_FRCTCHROMATOP_VALUE_MASK);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function gets Luma and Chroma start fractional values currently used
|
|
* by a Scaler device.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param StartFractionPtr is a pointer to a start fractional value
|
|
* structure to be populated with the fractional values after this
|
|
* function returns.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_GetStartFraction(XScaler *InstancePtr,
|
|
XScalerStartFraction *StartFractionPtr)
|
|
{
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(StartFractionPtr != NULL);
|
|
|
|
/* Fetch the fractional values */
|
|
StartFractionPtr->LumaLeftHori = (s32)
|
|
XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTLUMALEFT_OFFSET)
|
|
& XSCL_FRCTLUMALEFT_VALUE_MASK;
|
|
|
|
StartFractionPtr->LumaTopVert = (s32)
|
|
XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTLUMATOP_OFFSET)
|
|
& XSCL_FRCTLUMATOP_VALUE_MASK;
|
|
|
|
StartFractionPtr->ChromaLeftHori = (s32)
|
|
XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTCHROMALEFT_OFFSET)
|
|
& XSCL_FRCTCHROMALEFT_VALUE_MASK;
|
|
|
|
StartFractionPtr->ChromaTopVert = (s32)
|
|
XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_FRCTCHROMATOP_OFFSET)
|
|
& XSCL_FRCTCHROMATOP_VALUE_MASK;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function fetches the color space format and coefficient bank sharing
|
|
* decisions made on a Scaler device at build-time.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param ChromaFormat points to an 8-bit variable that will be assigned
|
|
* with the Chroma format chosen for the Scaler device at the
|
|
* build time after this function returns. Please use
|
|
* XSCL_CHROMA_FORMAT_* defined in xscaler_hw.h to interpret the
|
|
* variable value.
|
|
* @param ChromaLumaShareCoeff points to an 8-bit variable that will be
|
|
* assigned by this function with the decision value on coefficient
|
|
* bank sharing between Chroma and Luma filter operations. The
|
|
* decision is made for the Scaler device at build time and can
|
|
* NOT be changed at run-time. Value 0 indicates that each of Chroma
|
|
* and Luma filter operations has its own coefficient bank. Value
|
|
* 1 indicates that Chroma and Luma filter operations share one
|
|
* common coefficient bank.
|
|
* @param HoriVertShareCoeff points to an 8-bit variable that will be
|
|
* assigned by this function with the decision value on coefficient
|
|
* bank sharing between Horizontal and Vertical filter operations.
|
|
* The decision is made for the Scaler device at build time and
|
|
* can NOT be changed at run-time. Value 0 indicates that each of
|
|
* Horizontal and Vertical filter operations has its own
|
|
* coefficient bank. Value 1 indicates that Horizontal and
|
|
* Vertical filter operations share one common coefficient bank.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* !!!IMPORTANT!!!
|
|
*
|
|
* The application of this function is responsible for loading the correct
|
|
* number of coefficient banks in the proper sequence order. The number of
|
|
* coefficient banks to load and the proper loading sequence totally depends
|
|
* on the values of the output parameters of this function. Please use the
|
|
* table below as reference.
|
|
*
|
|
* <pre>
|
|
* ChromaFormat ChromaLumaShareCoeff HoriVertShareCoeff # of sequence
|
|
* coeff of
|
|
* banks loading
|
|
* to load coeff
|
|
* banks
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV420 1 1 1 1.Single bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV420 1 0 2 1.Hori bank
|
|
* 2.Vert bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV420 0 1 2 1.Luma bank
|
|
* 2.Chroma bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV420 0 0 4 1.Hori Luma
|
|
* 2.Hori Chroma
|
|
* 3.Vert Luma
|
|
* 4.Vert Chroma
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV422 1 1 1 1.Single bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV422 1 0 2 1.Hori bank
|
|
* 2.Vert bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV422 0 1 2 1.Luma bank
|
|
* 2.Chroma bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV422 0 0 4 1.Hori Luma
|
|
* 2.Hori Chroma
|
|
* 3.Vert Luma
|
|
* 4.Vert Chroma
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV444 Always 1 1 1 1.Single bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* YUV444 Always 1 0 2 1.Hori bank
|
|
* 2.Vert bank
|
|
* ------------ -------------------- ------------------ -------- -------------
|
|
* </pre>
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_GetCoeffBankSharingInfo(XScaler *InstancePtr,
|
|
u8 *ChromaFormat,
|
|
u8 *ChromaLumaShareCoeff,
|
|
u8 *HoriVertShareCoeff)
|
|
{
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(ChromaFormat != NULL);
|
|
Xil_AssertVoid(ChromaLumaShareCoeff != NULL);
|
|
Xil_AssertVoid(HoriVertShareCoeff != NULL);
|
|
|
|
/* Output the Chroma format info */
|
|
*ChromaFormat = InstancePtr->Config.ChromaFormat;
|
|
|
|
/* Output the Coefficient bank sharing info between Horizontal and
|
|
* Vertical filter operations */
|
|
if (InstancePtr->Config.SeparateHvCoef)
|
|
*HoriVertShareCoeff = 0;
|
|
else
|
|
*HoriVertShareCoeff = 1;
|
|
|
|
/* Output the Coefficient bank sharing info between Chroma and
|
|
* Luma filter operations */
|
|
switch (*ChromaFormat) {
|
|
|
|
case XSCL_CHROMA_FORMAT_420:
|
|
case XSCL_CHROMA_FORMAT_422:
|
|
if (InstancePtr->Config.SeparateYcCoef)
|
|
*ChromaLumaShareCoeff = 0;
|
|
else
|
|
*ChromaLumaShareCoeff = 1;
|
|
break;
|
|
case XSCL_CHROMA_FORMAT_444:
|
|
*ChromaLumaShareCoeff = 1;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function returns the pointer to the coefficients for a scaling
|
|
* operation given input/output sizes and the Tap and Phase numbers.
|
|
*
|
|
* @param InSize indicates the size (width or height) of the input video.
|
|
* @param OutSize indicates the size (width or height) of the output
|
|
* video.
|
|
* @param Tap indicates the Tap number.
|
|
* @param Phase indicates the Phase number.
|
|
*
|
|
* @return The points to the coefficients ready for the scaling operation.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
s16 *XScaler_CoefValueLookup(u32 InSize, u32 OutSize, u32 Tap, u32 Phase)
|
|
{
|
|
u32 CoeffBinIndex;
|
|
u32 CoeffValueOffset;
|
|
|
|
/* Validate the input parameters */
|
|
Xil_AssertNonvoid(InSize > 0);
|
|
Xil_AssertNonvoid(OutSize > 0);
|
|
Xil_AssertNonvoid(Tap >= XSCL_MIN_TAP_NUM);
|
|
Xil_AssertNonvoid(Tap <= XSCL_MAX_TAP_NUM);
|
|
Xil_AssertNonvoid(Phase >= XSCL_MIN_PHASE_NUM);
|
|
Xil_AssertNonvoid(Phase <= XSCL_MAX_PHASE_NUM);
|
|
|
|
/* Find the index of the Coefficient Bin */
|
|
CoeffBinIndex = XScaler_CoeffBinOffset(InSize, OutSize);
|
|
|
|
/* Find the offset of the Coefficients within the Bin */
|
|
CoeffValueOffset = XScaler_CoefTapOffset(Tap);
|
|
CoeffValueOffset += XScaler_CoefPhaseOffset(Tap, Phase);
|
|
|
|
return (XScaler_GenCoefTable(Tap,Phase));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function loads a coefficient bank to the Scaler core. A complete
|
|
* coefficient set contains 4 banks (if Luma, Chroma, Horizontal and Vertical
|
|
* filter operations do not share common banks. For more details see
|
|
* XScaler_GetCoeffBankSharingInfo()): Horizontal Luma, Horizontal Chroma,
|
|
* Vertical Luma and Vertical Chroma. all 4 banks must be loaded back to back
|
|
* in the order listed here. The caller is responsible for ensuring the
|
|
* sequence and this function does not check it.
|
|
*
|
|
* An example sequence to load an whole coefficient set is like:
|
|
* <pre>
|
|
* XScaler_LoadCoeffBank(&Scaler, &HoriLumaCoeffBank);
|
|
* XScaler_LoadCoeffBank(&Scaler, &HoriChromaCoeffBank);
|
|
* XScaler_LoadCoeffBank(&Scaler, &VertLumaCoeffBank);
|
|
* XScaler_LoadCoeffBank(&Scaler, &VertChromaCoeffBank);
|
|
* </pre>
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param CoeffBankPtr is a pointer to a coefficient bank that is to be
|
|
* loaded.
|
|
*
|
|
* @return None.
|
|
*
|
|
*****************************************************************************/
|
|
void XScaler_LoadCoeffBank(XScaler *InstancePtr,
|
|
XScalerCoeffBank *CoeffBankPtr)
|
|
{
|
|
int PhaseIndex;
|
|
int TapIndex;
|
|
s16 *CoeffValueTapBase;
|
|
u32 CoeffValue;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(CoeffBankPtr != NULL);
|
|
Xil_AssertVoid(CoeffBankPtr->SetIndex < InstancePtr->Config.CoeffSetNum);
|
|
Xil_AssertVoid(CoeffBankPtr->CoeffValueBuf != NULL);
|
|
|
|
Xil_AssertVoid(CoeffBankPtr->PhaseNum <=
|
|
InstancePtr->Config.MaxPhaseNum);
|
|
|
|
Xil_AssertVoid(CoeffBankPtr->TapNum <= XSCL_MAX_TAP_NUM);
|
|
|
|
/* Start the coefficient bank loading by writing the bank index first
|
|
*/
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_COEFFSETADDR_OFFSET), ((CoeffBankPtr->SetIndex) &
|
|
(XSCL_COEFFSETADDR_ADDR_MASK)));
|
|
|
|
/* Now load the valid values */
|
|
CoeffValueTapBase = CoeffBankPtr->CoeffValueBuf;
|
|
for (PhaseIndex = 0;
|
|
PhaseIndex < CoeffBankPtr->PhaseNum; PhaseIndex++) {
|
|
for (TapIndex = 0; TapIndex < CoeffBankPtr->TapNum;) {
|
|
CoeffValue = ((u32)CoeffValueTapBase[TapIndex++]) &
|
|
0xFFFF;
|
|
if (TapIndex < CoeffBankPtr->TapNum) {
|
|
CoeffValue |=
|
|
(((u32)CoeffValueTapBase[TapIndex++]) &
|
|
0xFFFF) << 16;
|
|
}
|
|
XScaler_WriteReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_COEFFVALUE_OFFSET), CoeffValue);
|
|
}
|
|
CoeffValueTapBase += CoeffBankPtr->TapNum;
|
|
}
|
|
|
|
/*
|
|
* Load padding if the real phase number is less than the maximum phase
|
|
* number
|
|
*/
|
|
for (PhaseIndex = CoeffBankPtr->PhaseNum;
|
|
PhaseIndex < InstancePtr->Config.MaxPhaseNum; PhaseIndex++) {
|
|
for (TapIndex = 0; TapIndex < (CoeffBankPtr->TapNum + 1) / 2;
|
|
TapIndex++) {
|
|
XScaler_WriteReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_COEFFVALUE_OFFSET, 0);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function chooses the active vertical and horizontal coefficient sets to
|
|
* be used by a Scaler device.
|
|
*
|
|
* Each coefficient set contains 4 banks: Horizontal Luma, Horizontal Chroma,
|
|
* Vertical Luma and Vertical Chroma. The horizontal part is independent from
|
|
* the vertical part and the Scaler device supports using the horizontal part
|
|
* of one coefficient set w/ the vertical part of a different coefficient set.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param VertSetIndex indicates the index of the coefficient set in which
|
|
* the vertical part will be used by the Scaler device. Valid value
|
|
* is from 0 to (the number of the coefficient sets implemented by
|
|
* the Scaler device - 1).
|
|
* @param HoriSetIndex indicates the index of the coefficient set in which
|
|
* the horizontal part will be used by the Scaler device. Valid
|
|
* value is from 0 to (the number of the coefficient sets
|
|
* implemented by the Scaler device - 1).
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void XScaler_SetActiveCoeffSet(XScaler *InstancePtr,
|
|
u8 VertSetIndex,
|
|
u8 HoriSetIndex)
|
|
{
|
|
volatile u32 RegValue;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(VertSetIndex < InstancePtr->Config.CoeffSetNum);
|
|
Xil_AssertVoid(HoriSetIndex < InstancePtr->Config.CoeffSetNum);
|
|
|
|
RegValue = ((u32)HoriSetIndex) & XSCL_COEFFSETS_HORI_MASK;
|
|
RegValue |= (((u32)VertSetIndex) << XSCL_COEFFSETS_VERT_SHIFT) &
|
|
XSCL_COEFFSETS_VERT_MASK;
|
|
|
|
XScaler_WriteReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_COEFFSETS_OFFSET, RegValue);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function fetches the indexes of active vertical and horizontal
|
|
* coefficient sets being used by a Scaler device.
|
|
*
|
|
* Each coefficient set contains 4 banks: Horizontal Luma, Horizontal Chroma,
|
|
* Vertical Luma and Vertical Chroma. The horizontal part is independent from
|
|
* the vertical part and the Scaler device supports using the horizontal part
|
|
* of one coefficient set w/ the vertical part of a different coefficient set.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler device instance to be
|
|
* worked on.
|
|
* @param VertSetIndexPtr points to the index of the active coefficient
|
|
* set in which the vertical part is being used by the Scaler
|
|
* device after this function returns.
|
|
* @param HoriSetIndexPtr points to the index of the active coefficient
|
|
* set in which the horizontal part is being used by the Scaler
|
|
* device after this function returns.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void XScaler_GetActiveCoeffSet(XScaler *InstancePtr,
|
|
u8 *VertSetIndexPtr,
|
|
u8 *HoriSetIndexPtr)
|
|
{
|
|
u32 RegValue;
|
|
|
|
/* Assert bad arguments and conditions */
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(VertSetIndexPtr != NULL);
|
|
Xil_AssertVoid(HoriSetIndexPtr != NULL);
|
|
|
|
RegValue = XScaler_ReadReg((InstancePtr)->Config.BaseAddress,
|
|
XSCL_COEFFSETS);
|
|
|
|
*VertSetIndexPtr = (u8)
|
|
((RegValue & XSCL_COEFFSETS_VERT_MASK) >>
|
|
XSCL_COEFFSETS_VERT_SHIFT);
|
|
|
|
*HoriSetIndexPtr = (u8)(RegValue & XSCL_COEFFSETS_HORI_MASK);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function calculates the index of the coefficient Bin to use based on
|
|
* the input and output video size (Width or Height)
|
|
*
|
|
* @param InSize indicates the size (width or height) of the input video.
|
|
* @param OutSize indicates the size (width or height) of the output
|
|
* video.
|
|
*
|
|
* @return The index of the coefficient Bin.
|
|
*
|
|
*****************************************************************************/
|
|
static u32 XScaler_CoeffBinOffset(u32 InSize, u32 OutSize)
|
|
{
|
|
u32 CoeffBinIndex;
|
|
|
|
/* Validate the input parameters */
|
|
Xil_AssertNonvoid(InSize > 0);
|
|
Xil_AssertNonvoid(OutSize > 0);
|
|
|
|
if (OutSize > InSize)
|
|
CoeffBinIndex = 0;
|
|
else
|
|
CoeffBinIndex = 1 + (OutSize * 16 / InSize);
|
|
|
|
return CoeffBinIndex;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function returns the contents of version register of the Scaler core.
|
|
*
|
|
* @param InstancePtr is a pointer to the Scaler core instance to be
|
|
* worked on.
|
|
*
|
|
* @return Contents of the version register.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 XScaler_GetVersion(XScaler *InstancePtr)
|
|
{
|
|
u32 Data;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
Data = XScaler_ReadReg(InstancePtr->Config.BaseAddress,
|
|
(XSCL_VER_OFFSET));
|
|
|
|
return Data;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*
|
|
*
|
|
* This routine is a stub for the frame done interrupt callback. The stub is
|
|
* here in case the upper layer forgot to set the callback. On initialization,
|
|
* the frame done interrupt callback is set to this stub. It is considered an
|
|
* error for this function to be invoked.
|
|
*
|
|
* @param CallBackRef is a callback reference passed in by the upper
|
|
* layer when setting the callback functions, and passed back
|
|
* to the upper layer when the callback is invoked.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
static void StubCallBack(void *CallBackRef)
|
|
{
|
|
|
|
(void)CallBackRef;
|
|
Xil_AssertVoidAlways();
|
|
}
|