From d75c905bab44f4ec4f6375fa4b8aca2d1d5ddfbe Mon Sep 17 00:00:00 2001 From: Rohit Consul Date: Thu, 4 Jun 2015 05:49:49 +0800 Subject: [PATCH] v_vscaler: Update tcl to include model parameters Updated tcl file to include model parameters. Also updated the code to use new parameters instead of hard-coded values defined earlier Signed-off-by: Rohit Consul --- .../drivers/v_vscaler/data/v_vscaler.tcl | 28 ++++++- .../drivers/v_vscaler/src/xv_vscaler.c | 6 ++ .../drivers/v_vscaler/src/xv_vscaler.h | 24 +++++- .../drivers/v_vscaler/src/xv_vscaler_l2.c | 73 ++++++++++--------- .../drivers/v_vscaler/src/xv_vscaler_l2.h | 25 +++++-- 5 files changed, 108 insertions(+), 48 deletions(-) diff --git a/XilinxProcessorIPLib/drivers/v_vscaler/data/v_vscaler.tcl b/XilinxProcessorIPLib/drivers/v_vscaler/data/v_vscaler.tcl index e7353411..5f63b8f0 100644 --- a/XilinxProcessorIPLib/drivers/v_vscaler/data/v_vscaler.tcl +++ b/XilinxProcessorIPLib/drivers/v_vscaler/data/v_vscaler.tcl @@ -10,14 +10,36 @@ proc generate {drv_handle} { "NUM_INSTANCES" \ "DEVICE_ID" \ "C_S_AXI_CTRL_BASEADDR" \ - "C_S_AXI_CTRL_HIGHADDR" + "C_S_AXI_CTRL_HIGHADDR" \ + "SAMPLES_PER_CLOCK" \ + "MAX_COLS" \ + "MAX_ROWS" \ + "MAX_DATA_WIDTH" \ + "PHASE_SHIFT" \ + "SCALE_MODE" \ + "TAPS" xdefine_config_file $drv_handle "xv_vscaler_g.c" "XV_vscaler" \ "DEVICE_ID" \ - "C_S_AXI_CTRL_BASEADDR" + "C_S_AXI_CTRL_BASEADDR" \ + "SAMPLES_PER_CLOCK" \ + "MAX_COLS" \ + "MAX_ROWS" \ + "MAX_DATA_WIDTH" \ + "PHASE_SHIFT" \ + "SCALE_MODE" \ + "TAPS" xdefine_canonical_xpars $drv_handle "xparameters.h" "XV_vscaler" \ "DEVICE_ID" \ "C_S_AXI_CTRL_BASEADDR" \ - "C_S_AXI_CTRL_HIGHADDR" + "C_S_AXI_CTRL_HIGHADDR" \ + "SAMPLES_PER_CLOCK" \ + "MAX_COLS" \ + "MAX_ROWS" \ + "MAX_DATA_WIDTH" \ + "PHASE_SHIFT" \ + "SCALE_MODE" \ + "TAPS" } + diff --git a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.c b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.c index ac3baf4a..f6bc1a0d 100644 --- a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.c +++ b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.c @@ -7,6 +7,7 @@ /***************************** Include Files *********************************/ #include "xv_vscaler.h" +#include "string.h" /************************** Function Implementation *************************/ #ifndef __linux__ @@ -14,6 +15,11 @@ int XV_vscaler_CfgInitialize(XV_vscaler *InstancePtr, XV_vscaler_Config *ConfigP Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(ConfigPtr != NULL); + /* Setup the instance */ + (void)memset((void *)InstancePtr, 0, sizeof(XV_vscaler)); + (void)memcpy((void *)&(InstancePtr->Config), (const void *)ConfigPtr, + sizeof(XV_vscaler_Config)); + InstancePtr->Ctrl_BaseAddress = ConfigPtr->Ctrl_BaseAddress; InstancePtr->IsReady = XIL_COMPONENT_IS_READY; diff --git a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.h b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.h index 72b5b350..9e1e297e 100644 --- a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.h +++ b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler.h @@ -38,15 +38,31 @@ typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; #else +/** +* This typedef contains configuration information for the vertical scaler +* core. Each core instance should have a configuration structure +* associated. +*/ typedef struct { - u16 DeviceId; - u32 Ctrl_BaseAddress; + u16 DeviceId; /**< Unique ID of device */ + u32 Ctrl_BaseAddress; /**< The base address of the core instance. */ + int PixPerClk; /**< Samples Per Clock supported by core instance */ + u16 MaxWidth; /**< Maximum columns supported by core instance */ + u16 MaxHeight; /**< Maximum rows supported by core instance */ + int MaxDataWidth; /**< Maximum Data width of each channel */ + u16 PhaseShift; /**< Max num of phases (2^PhaseShift) */ + int ScalerType; /**< Scaling Algorithm Selected */ + int NumTaps; /**< Number of taps */ } XV_vscaler_Config; #endif +/** +* Driver instance data. An instance must be allocated for each core in use. +*/ typedef struct { - u32 Ctrl_BaseAddress; - u32 IsReady; + XV_vscaler_Config Config; /**< Hardware Configuration */ + u32 Ctrl_BaseAddress; /**< The base address of the core instance. */ + u32 IsReady; /**< Device is initialized and ready */ } XV_vscaler; /***************** Macros (Inline Functions) Definitions *********************/ diff --git a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.c b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.c index 75b03ae2..24a07bb1 100644 --- a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.c +++ b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.c @@ -75,11 +75,11 @@ static float NormCoeffs[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_MAX_V_TAPS]; /************************** Function Prototypes ******************************/ static float hamming( int x, int taps); static float sinc(float x); -static void XV_VScalerGetCoeff(XV_vscaler *InstancePtr, +static void XV_VScalerGetCoeff(XV_vscaler *pVsc, XV_vscaler_l2 *pVscL2Data, u32 HeightIn, u32 HeightOut); -static void XV_VScalerSetCoeff(XV_vscaler *InstancePtr, +static void XV_VScalerSetCoeff(XV_vscaler *pVsc, XV_vscaler_l2 *pVscL2Data); /*****************************************************************************/ @@ -159,30 +159,30 @@ static float sinc(float x) ******************************************************************************/ void XV_VscalerLoadUsrCoeffients(XV_vscaler *InstancePtr, XV_vscaler_l2 *pVscL2Data, - const short VCoeff[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_MAX_V_TAPS]) + u16 num_phases, + u16 num_taps, + const short *Coeff) { - int i,j,k, pad, offset; - int num_phases = XV_VSCALER_MAX_V_PHASES; - int num_taps = pVscL2Data->EffectiveTaps; + int i,j, pad, offset; /* * Assert validates the input arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(pVscL2Data != NULL); - Xil_AssertVoid((pVscL2Data->EffectiveTaps > 0) && - (pVscL2Data->EffectiveTaps <= XV_VSCALER_MAX_V_TAPS)); + Xil_AssertVoid(num_taps <= InstancePtr->Config.NumTaps); + Xil_AssertVoid(num_phases <= (1<Config.PhaseShift)); //determine if coefficient needs padding (effective vs. max taps) - pad = XV_VSCALER_MAX_V_TAPS - num_taps; + pad = XV_VSCALER_MAX_V_TAPS - InstancePtr->Config.NumTaps; offset = ((pad) ? (pad>>1) : 0); //Load User defined coefficients into scaler coefficient table for (i = 0; i < num_phases; i++) { - for (k=0,j=offset; jcoeff[i][j] = VCoeff[i][k]; + pVscL2Data->coeff[i][j+offset] = Coeff[i*num_taps+j]; } } @@ -202,6 +202,9 @@ void XV_VscalerLoadUsrCoeffients(XV_vscaler *InstancePtr, } } } + + /* Enable use of external coefficients */ + pVscL2Data->UseExtCoeff = TRUE; } /*****************************************************************************/ @@ -217,25 +220,19 @@ void XV_VscalerLoadUsrCoeffients(XV_vscaler *InstancePtr, * @return None * ******************************************************************************/ -static void XV_VScalerGetCoeff(XV_vscaler *InstancePtr, +static void XV_VScalerGetCoeff(XV_vscaler *pVsc, XV_vscaler_l2 *pVscL2Data, u32 HeightIn, u32 HeightOut) { - int num_phases = XV_VSCALER_MAX_V_PHASES; - int num_taps = pVscL2Data->EffectiveTaps; + int num_phases = (1<Config.PhaseShift); + int num_taps = pVsc->Config.NumTaps; int center_tap = num_taps/2; int i,j, pad, offset; float x, fc; float sum[XV_VSCALER_MAX_V_PHASES]; float cos_win[XV_VSCALER_MAX_V_TAPS]; - /* - * Assert validates the input arguments - */ - Xil_AssertVoid((pVscL2Data->EffectiveTaps > 0) && - (pVscL2Data->EffectiveTaps <= XV_VSCALER_MAX_V_TAPS)); - if(HeightIn < HeightOut) { fc = (float)HeightIn/(float)HeightOut; @@ -304,10 +301,10 @@ static void XV_VScalerGetCoeff(XV_vscaler *InstancePtr, for (i = 0; i < num_phases; i++) { - for (j = offset; j < num_taps; j++) + for (j = 0; j < num_taps; j++) { NormCoeffs[i][j] = WinCoeffs[i][j]/sum[i]; - pVscL2Data->coeff[i][j] = (short) ((NormCoeffs[i][j] * COEFF_QUANT) + 0.5); + pVscL2Data->coeff[i][j+offset] = (short) ((NormCoeffs[i][j] * COEFF_QUANT) + 0.5); } } @@ -347,20 +344,22 @@ static void XV_VScalerGetCoeff(XV_vscaler *InstancePtr, * maintain the sw latency for driver version which would eventually use * computed coefficients ******************************************************************************/ -static void XV_VScalerSetCoeff(XV_vscaler *InstancePtr, +static void XV_VScalerSetCoeff(XV_vscaler *pVsc, XV_vscaler_l2 *pVscL2Data) { - int num_phases = XV_VSCALER_MAX_V_PHASES; - int num_taps = XV_VSCALER_MAX_V_TAPS/2; - int val,i,j; + int num_phases = 1<Config.PhaseShift; + int num_taps = pVsc->Config.NumTaps/2; + int val,i,j,offset,rdIndx; u32 baseAddr; - baseAddr = XV_vscaler_Get_HwReg_vfltCoeff_BaseAddress(InstancePtr); + offset = (XV_VSCALER_MAX_V_TAPS - pVsc->Config.NumTaps)/2; + baseAddr = XV_vscaler_Get_HwReg_vfltCoeff_BaseAddress(pVsc); for (i=0; i < num_phases; i++) { for(j=0; j < num_taps; j++) { - val = (pVscL2Data->coeff[i][(j*2)+1] << 16) | (pVscL2Data->coeff[i][j*2] & XMASK_LOW_16BITS); + rdIndx = j*2+offset; + val = (pVscL2Data->coeff[i][rdIndx+1] << 16) | (pVscL2Data->coeff[i][rdIndx] & XMASK_LOW_16BITS); Xil_Out32(baseAddr+((i*num_taps+j)*4), val); } } @@ -393,10 +392,16 @@ void XV_VScalerSetup(XV_vscaler *InstancePtr, Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(pVscL2Data != NULL); - if(pVscL2Data->ScalerType == XV_VSCALER_POLYPHASE) + if(InstancePtr->Config.ScalerType == XV_VSCALER_POLYPHASE) { if(!pVscL2Data->UseExtCoeff) //No predefined coefficients { + /* If user has not selected any filter set default */ + if(pVscL2Data->FilterSel == 0) + { + XV_VScalerSetFilterType(pVscL2Data, XV_VFILT_LANCZOS); + } + /* Generate coefficients for vertical scaling ratio */ XV_VScalerGetCoeff(InstancePtr, pVscL2Data, @@ -431,7 +436,6 @@ void XV_VScalerDbgReportStatus(XV_vscaler *InstancePtr) XV_vscaler *pVsc = InstancePtr; u32 done, idle, ready, ctrl; u32 widthin, heightin, heightout, linerate; - u32 type = 3; //hard-coded to polyphase for now u32 baseAddr, taps, phases; int val,i,j; @@ -450,26 +454,25 @@ void XV_VScalerDbgReportStatus(XV_vscaler *InstancePtr) heightin = XV_vscaler_Get_HwReg_HeightIn(pVsc); widthin = XV_vscaler_Get_HwReg_Width(pVsc); heightout = XV_vscaler_Get_HwReg_HeightOut(pVsc); -// type = XV_vscaler_GetHwreg_scaletype(pVsc); linerate = XV_vscaler_Get_HwReg_LineRate(pVsc); - taps = XV_VSCALER_MAX_V_TAPS/2; - phases = XV_VSCALER_MAX_V_PHASES; + taps = pVsc->Config.NumTaps/2; + phases = (1<Config.PhaseShift); xil_printf("IsDone: %d\r\n", done); xil_printf("IsIdle: %d\r\n", idle); xil_printf("IsReady: %d\r\n", ready); xil_printf("Ctrl: 0x%x\r\n\r\n", ctrl); + xil_printf("Scaler Type: %d\r\n",pVsc->Config.ScalerType); xil_printf("Input Width: %d\r\n",widthin); xil_printf("Input Height: %d\r\n",heightin); xil_printf("Output Height: %d\r\n",heightout); -// xil_printf("Scaler Type: %d\r\n",type); xil_printf("Line Rate: %d\r\n",linerate); xil_printf("Num Phases: %d\r\n",phases); xil_printf("Num Taps: %d\r\n",taps*2); - if(type == 3) + if(pVsc->Config.ScalerType == XV_VSCALER_POLYPHASE) { short lsb, msb; diff --git a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.h b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.h index f7a745fc..2f3e1720 100644 --- a/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.h +++ b/XilinxProcessorIPLib/drivers/v_vscaler/src/xv_vscaler_l2.h @@ -107,7 +107,6 @@ extern "C" { #endif -#include "xvidc.h" #include "xv_vscaler.h" /************************** Constant Definitions *****************************/ @@ -121,7 +120,7 @@ extern "C" { * accessible via instance pointer * */ - #define XV_VSCALER_MAX_V_TAPS (6) + #define XV_VSCALER_MAX_V_TAPS (10) #define XV_VSCALER_MAX_V_PHASES (64) /**************************** Type Definitions *******************************/ @@ -152,20 +151,34 @@ typedef enum */ typedef struct { - u8 EffectiveTaps; u8 UseExtCoeff; XV_VFILTER_ID FilterSel; - XV_VSCALER_TYPE ScalerType; - u8 Gain; short coeff[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_MAX_V_TAPS]; }XV_vscaler_l2; +/************************** Macros Definitions *******************************/ +/*****************************************************************************/ +/** + * This macro selects the filter used for generating coefficients. + * Applicable only for Ployphase Scaler Type + * + * @param pVscL2Data is pointer to the V Scaler Layer 2 structure instance + * @param value is the filter type + * + * @return None + * + *****************************************************************************/ +#define XV_VScalerSetFilterType(pVscL2Data, value) \ + ((pVscL2Data)->FilterSel = value) + /************************** Function Prototypes ******************************/ void XV_VScalerStart(XV_vscaler *InstancePtr); void XV_VScalerStop(XV_vscaler *InstancePtr); void XV_VscalerLoadUsrCoeffients(XV_vscaler *InstancePtr, XV_vscaler_l2 *pVscL2Data, - const short VCoeff[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_MAX_V_TAPS]); + u16 num_phases, + u16 num_taps, + const short *Coeff); void XV_VScalerSetup(XV_vscaler *InstancePtr, XV_vscaler_l2 *pVscL2Data, u32 WidthIn,