vprocss: Added video processing subsystem driver

Video processing subsystem driver is added to the repo. This
driver currently is associated with a non-HIP version of the
IP. No makefile available. Hard-coded g.c file used, but not
included.

Signed-off-by: Rohit Consul <rohit.consul@xilinx.com>
This commit is contained in:
Rohit Consul 2015-05-27 08:11:33 +08:00 committed by Nava kishore Manne
parent a93e316656
commit 06de4b6538
8 changed files with 3688 additions and 0 deletions

View file

@ -0,0 +1,42 @@
##******************************************************************************
##
## Copyright (C) 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
## XILINX 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.
##
##*****************************************************************************/
OPTION psf_version = 2.1;
BEGIN driver vprocss
OPTION supported_peripherals = (vprocss);
OPTION driver_state = ACTIVE;
OPTION depends = (video_common_v1_0);
OPTION copyfiles = all;
OPTION VERSION = 1.0;
OPTION NAME = vprocss;
END driver

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,491 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xvprocss.h
*
* This is main header file of the Xilinx Video Processing Subsystem driver
*
* <b>Video Processing Subsystem Overview</b>
*
* Video Subsystem is a collection of IP cores bounded together by software
* to provide an abstract view of the processing pipe. It hides all the
* complexities of programming the underlying cores from end user.
*
* <b>Subsystem Driver Features</b>
*
* Video Subsystem supports following features
* - AXI Stream Input/Output interface
* - 2 or 4 pixel-wide video interface
* - up to 16 bits per component
* - RGB & YCbCb color space
* - Memory based/streaming mode scaling in either direction (Up/Down)
* - Up to 4k2k 60Hz resolution at both Input and Output interface
* - Interlaced input support
* - Frame rate conversion
* - Drop frames if input rate > output rate
* - Repeat frames if input rate < output rate
* - Auto configuration of processing pipe based on detected use case
* - Scale Up/Down
* - Zoom mode wherein a window in input is scaled to panel resolution
* - Picture-In-Picture mode wherein the input stream is scaled down to
* a defined window size and background is painted to user define color
* - Color Space and color format Conversion
* - Interlaced to Progressive conversion
*
* <b>Subsystem Configurations</b>
*
* Two types of configurations are supported via GUI in IPI
* - Full Configuration: provides all the features mentioned above
* - Streaming Mode Configuration (aka Scaler-Only) with limited functionality
*
* Number of processing cores that get included in the design will depend upon
* the configuration selected. Static configuration parameters are stored in
* vprocss_g.c file that gets generated when compiling the board support package
* (BSP). A table is defined where each entry contains configuration information
* for the instances of the subsystem in the design. This information includes
* the elected configuration, sub-cores used and their device ID, base addresses
* of memory mapped devices, user specified DDR address for buffer management
* and address range available for subsystem frame/field buffers.
*
* Full configuration mode includes following sub-cores in HW
* - Scalers (horizontal/vertical)
* - Chroma Resampler (horizontal/vertical)
* - Color Space Converter
* - VDMA for buffer management
* - De-Interlacer
* - Letter Box
* - AXIS Switch
*
* Stream mode configuration mode includes following sub-cores in HW
* - Scalers (horizontal/vertical)
*
* The subsystem driver itself always includes the full software stack
* irrespective of the configuration selected. Generic API's are provided to
* interact with the subsystem and/or with the included sub-cores.
* At run-time the subsystem will query the static configuration and configures
* itself for supported use cases
*
* <b>Subsystem Driver Description</b>
*
* Subsystem driver is built upon layer 1&2 device drivers of included sub-cores
* Layer 1 provides API's to peek/poke registers at HW level.
* Layer 2 provides API's that abstract sub-core functionality, providing an easy to
* use feature interface
*
* <b>Pre-Requisite's</b>
*
* Subsystem driver requires 2 support peripherals, Timer and an Interrupt
* Controller, to be present in the design and the application must register a
* handle to these with the subsystem using the provided API's.
*
* <b>Subsystem Driver Usage</b>
*
* The subsystem driver in itself is a dormant driver that needs application SW to
* make use of provided API's to configure it at boot-up. Thereafter application
* SW is responsible to monitor the system for external impetus and call the
* subsystem API's to communicate the change and trigger the reconfiguration of
* internal data processing pipe (refer API XVprocss_ConfigureSubsystem())
* AXI Stream configuration for input/output interface is derived from the
* Xilinx video common driver and only the resolutions listed therein are
* supported at this time
*
* <b>Interrupt Service</b>
*
* Currently no interrupts are available from the subsystem. User application is
* responsible for triggering processing pipe update when any change in subsystem
* configuration is performed at application level
*
* <b> Virtual Memory </b>
*
* This driver supports Virtual Memory. The RTOS is responsible for calculating
* the correct device base address in Virtual Memory space.
*
* <b> Threads </b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b>Asserts</b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and
* it is recommended that application developers leave asserts on during
* development.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rc 05/01/15 Initial Release
* </pre>
*
******************************************************************************/
#ifndef XVPROCSS_H /**< prevent circular inclusions by using protection macros*/
#define XVPROCSS_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xintc.h"
#include "xgpio.h"
#include "xaxis_switch.h"
#include "xvidc.h"
/**
* Sub-core Layer 2 driver includes
* Layer 2 includes Layer-1
*/
#include "xaxivdma.h"
#include "xv_csc_l2.h"
#include "xv_deinterlacer_l2.h"
#include "xv_hcresampler_l2.h"
#include "xv_vcresampler_l2.h"
#include "xv_hscaler_l2.h"
#include "xv_vscaler_l2.h"
#include "xv_letterbox_l2.h"
/****************************** Type Definitions ******************************/
/**
* AXIS Switch Port enumeration for Sub-Core connection
*/
typedef enum
{
XVPROCSS_RTR_VIDOUT = 0, //M0
XVPROCSS_RTR_SCALER_V, //M1
XVPROCSS_RTR_SCALER_H, //M2
XVPROCSS_RTR_VDMA, //M3
XVPROCSS_RTR_LBOX, //M4
XVPROCSS_RTR_CR_H, //M5
XVPROCSS_RTR_CR_V_IN, //M6
XVPROCSS_RTR_CR_V_OUT, //M7
XVPROCSS_RTR_CSC, //M8
XVPROCSS_RTR_DEINT, //M9
XVPROCSS_RTR_MAX
}XVPROCSS_RTR_MIx_ID;
/**
* Subsystem Configuration Mode Select
*/
typedef enum
{
XVPROCSS_MODE_MAX = 0,
XVPROCSS_MODE_STREAM
}XVPROCSS_CONFIG_MODE;
/**
* Types of Windows (Sub-frames) available in the Subsystem
*/
typedef enum
{
XVPROCSS_ZOOM_WIN = 0,
XVPROCSS_PIP_WIN,
XVPROCSS_PIXEL_WIN
}XVprocss_Win;
/**
* Scaling Modes supported
*/
typedef enum
{
XVPROCSS_SCALE_1_1 = 0,
XVPROCSS_SCALE_UP,
XVPROCSS_SCALE_DN,
XVPROCSS_SCALE_NOT_SUPPORTED
}XVprocss_ScaleMode;
/**
* Video Processing Subsystem internal scratch pad memory.
* This contains internal flags, state variables, routing table
* and other meta-data required by the subsystem. Each instance
* of the subsystem will have its own scratch pad memory
*/
typedef struct
{
XVidC_VideoWindow rdWindow; /**< window for Zoom/Pip feature support */
XVidC_VideoWindow wrWindow; /**< window for Zoom/Pip feature support */
u32 deintBufAddr; /**< Deinterlacer field buffer Addr. in DDR */
u8 vdmaBytesPerPixel; /**< Number of bytes required to store 1 pixel */
u8 RtngTable[XVPROCSS_RTR_MAX]; /**< Storage for computed routing map */
u8 startCore[XVPROCSS_RTR_MAX]; /**< Enable flag to start sub-core */
u8 RtrNumCores; /**< Number of sub-cores in routing map */
u8 ScaleMode; /**< Stored computed scaling mode - UP/DN/1:1 */
u8 memEn; /**< Flag to indicate if stream routes through memory */
u8 ZoomEn; /**< Flag to store Zoom feature state */
u8 PipEn; /**< Flag to store PIP feature state */
u16 vidInWidth; /**< Input H Active */
u16 vidInHeight; /**< Input V Active */
XVidC_ColorFormat strmCformat; /**< processing pipe color format */
XVidC_ColorFormat cscIn; /**< CSC core input color format */
XVidC_ColorFormat cscOut; /**< CSC core output color format */
XVidC_ColorFormat hcrIn; /**< horiz. cresmplr core input color format */
XVidC_ColorFormat hcrOut; /**< horiz. cresmplr core output color format */
}XVprocss_IData;
/**
* Sub-Core Configuration Table
*/
typedef struct
{
u16 isPresent; /**< Flag to indicate if sub-core is present in the design*/
u16 DeviceId; /**< Device ID of the sub-core */
}XSubCore;
/**
* Video Processing Subsystem configuration structure.
* Each subsystem device should have a configuration structure associated
* that defines the MAX supported sub-cores within subsystem
*/
typedef struct
{
u16 DeviceId; /**< DeviceId is the unique ID of the device */
u32 BaseAddress; /**< BaseAddress is the physical base address of
the device's registers */
u8 Mode; /**< Subsystem configuration mode */
u8 PixPerClock; /**< Number of Pixels Per Clock processed by Subsystem */
u16 PixPrecision; /**< Processing precision of the data pipe */
XSubCore HCrsmplr; /**< Sub-core instance configuration */
XSubCore VCrsmplrIn; /**< Sub-core instance configuration */
XSubCore VCrsmplrOut; /**< Sub-core instance configuration */
XSubCore Vscale; /**< Sub-core instance configuration */
XSubCore Hscale; /**< Sub-core instance configuration */
XSubCore Vdma; /**< Sub-core instance configuration */
XSubCore Lbox; /**< Sub-core instance configuration */
XSubCore Csc; /**< Sub-core instance configuration */
XSubCore Deint; /**< Sub-core instance configuration */
XSubCore Router; /**< Sub-core instance configuration */
XSubCore RstAxis; /**< Axi stream reset network instance configuration */
XSubCore RstAximm; /**< Axi MM reset network instance configuration */
u32 UsrExtMemBaseAddr; /**< DDR base address for buffer management */
u32 UsrExtMemAddr_Range; /**< Range of addresses available for buffers */
} XVprocss_Config;
/**
* The XVprocss driver instance data. The user is required to allocate a variable
* of this type for every XVprocss device in the system. A pointer to a variable
* of this type is then passed to the driver API functions.
*/
typedef struct
{
XVprocss_Config Config; /**< Hardware configuration */
u32 IsReady; /**< Device and the driver instance are initialized */
XAxis_Switch *router; /**< handle to sub-core driver instance */
XGpio *rstAxis; /**< handle to sub-core driver instance */
XGpio *rstAximm; /**< handle to sub-core driver instance */
/**< handle to sub-core driver instance */
XV_hcresampler *hcrsmplr; /**< handle to sub-core driver instance */
XV_vcresampler *vcrsmplrIn; /**< handle to sub-core driver instance */
XV_vcresampler *vcrsmplrOut; /**< handle to sub-core driver instance */
XV_vscaler *vscaler; /**< handle to sub-core driver instance */
XV_hscaler *hscaler; /**< handle to sub-core driver instance */
XAxiVdma *vdma; /**< handle to sub-core driver instance */
XV_letterbox *lbox; /**< handle to sub-core driver instance */
XV_csc *csc; /**< handle to sub-core driver instance */
XV_deinterlacer *deint; /**< handle to sub-core driver instance */
/**
* Layer2 SW Register (Every Subsystem instance will have it's own copy
of Layer 2 register bank for applicable sub-cores)
*/
XV_csc_L2Reg cscL2Reg; /**< Layer 2 register bank for csc sub-core */
XV_vscaler_l2 vscL2Reg; /**< Layer 2 register bank for vsc sub-core */
XV_hscaler_l2 hscL2Reg; /**< Layer 2 register bank for hsc sub-core */
//I/O Streams
XVidC_VideoStream VidIn; /**< Input AXIS configuration */
XVidC_VideoStream VidOut; /**< Output AXIS configuration */
XVprocss_IData idata; /**< Internal Scratch pad memory for subsystem instance */
XIntc *pXintc; /**< handle to system interrupt controller */
XVidC_DelayHandler UsrDelaymsec; /**< custom user function for delay/sleep */
void *pUsrTmr; /**< handle to timer instance used by user delay function */
} XVprocss;
/************************** Macros Definitions *******************************/
/*****************************************************************************/
/**
* This macro checks if subsystem is in Maximum configuration mode
*
* @param pVprocss is a pointer to the Video Processing subsystem instance
* @return Return 1 if condition is TRUE or 0 if FALSE
*
*****************************************************************************/
#define XVprocss_IsConfigModeMax(pVprocss) \
((pVprocss)->Config.Mode == XVPROCSS_MODE_MAX)
/*****************************************************************************/
/**
* This macro checks if subsystem configuration is in Stream Mode (Scaler Only)
*
* @param pVprocss is pointer to the Video Processing subsystem instance
*
* @return Returns 1 if condition is TRUE or 0 if FALSE
*
*****************************************************************************/
#define XVprocss_IsConfigModeStream(pVprocss) \
((pVprocss)->Config.Mode == XVPROCSS_MODE_STREAM)
/*****************************************************************************/
/**
* This macro returns the current state of PIP Mode stored in subsystem internal
* scratch pad memory
*
* @param pVprocss is a pointer to the Video Processing subsystem instance
*
* @return Returns 1 if PIP mode is ON or 0 if OFF
*
*****************************************************************************/
#define XVprocss_IsPipModeOn(pVprocss) ((pVprocss)->idata.PipEn)
/*****************************************************************************/
/**
* This macro returns the current state of Zoom Mode stored in subsystem internal
* scratch pad memory
*
* @param pVprocss is a pointer to the Video Processing subsystem instance
*
* @return Returns 1 if ZOOM mode is ON or 0 if OFF
*
*****************************************************************************/
#define XVprocss_IsZoomModeOn(pVprocss) ((pVprocss)->idata.ZoomEn)
/*****************************************************************************/
/**
* This macro clears the PIP mode flag stored in subsystem internal scratch
* pad memory. This call has no side-effect
*
* @param pVprocss is a pointer to the Video Processing subsystem instance
*
* @return None
*
*****************************************************************************/
#define XVprocss_ResetPipModeFlag(pVprocss) ((pVprocss)->idata.PipEn = FALSE)
/*****************************************************************************/
/**
* This macro clears the ZOOM mode flag stored in subsystem internal scratch
* pad memory. This call has no side-effect
*
* @param pVprocss is pointer to the Video Processing subsystem instance
*
* @return None
*
*****************************************************************************/
#define XVprocss_ResetZoomModeFlag(pVprocss) ((pVprocss)->idata.ZoomEn = FALSE)
/*****************************************************************************/
/**
* This macro sets the specified stream's color format. It can be used to
* update input or output stream. This call has no side-effect in isolation.
* For change to take effect user must trigger processing path reconfiguration
* by calling XVprocss_ConfigureSubsystem()
*
* @param Stream is a pointer to the Subsystem Input or Output Stream
* @param ColorFormat is the requested color format
*
* @return None
*
*****************************************************************************/
#define XVprocss_SetStreamColorFormat(Stream, ColorFormat) \
((Stream)->ColorFormatId = ColorFormat)
/*****************************************************************************/
/**
* This macro sets the specified stream's color depth. It can be used to update
* input or output stream. This call has no side-effect in isolation
* For change to take effect user must trigger processing path reconfiguration
* by calling XVprocss_ConfigureSubsystem()
*
* @param Stream is a pointer to the Subsystem Input or Output Stream
* @param ColorDepth is the requested color depth
*
* @return None
*
*****************************************************************************/
#define XVprocss_SetStreamColorDepth(Stream, ColorDepth) \
((Stream)->ColorDepth = ColorDepth)
/************************** Function Prototypes ******************************/
XVprocss_Config* XVprocss_LookupConfig(u32 DeviceId);
int XVprocss_CfgInitialize(XVprocss *InstancePtr,
XVprocss_Config *CfgPtr,
u32 EffectiveAddr);
int XVprocss_PowerOnInit(XVprocss *InstancePtr, u32 DeviceId);
void XVprocss_Start(XVprocss *InstancePtr);
void XVprocss_Stop(XVprocss *InstancePtr);
void XVprocss_Reset(XVprocss *InstancePtr);
int XVprocss_SetVidStreamIn(XVprocss *InstancePtr,
const XVidC_VideoStream *StrmIn);
int XVprocss_SetVidStreamOut(XVprocss *InstancePtr,
const XVidC_VideoStream *StrmOut);
int XVprocss_SetStreamResolution(XVidC_VideoStream *StreamPtr,
const XVidC_VideoMode VmId);
void XVprocss_ReportCoreInfo(XVprocss *InstancePtr);
int XVprocss_ConfigureSubsystem(XVprocss *InstancePtr);
void XVprocss_SetZoomMode(XVprocss *InstancePtr, u8 OnOff);
void XVprocss_SetPipMode(XVprocss *InstancePtr, u8 OnOff);
void XVprocss_SetZoomPipWindow(XVprocss *InstancePtr,
XVprocss_Win mode,
XVidC_VideoWindow *win);
void XVprocss_GetZoomPipWindow(XVprocss *InstancePtr,
XVprocss_Win mode,
XVidC_VideoWindow *win);
void XVprocss_UpdateZoomPipWindow(XVprocss *InstancePtr);
void XVprocss_RegisterSysIntc(XVprocss *InstancePtr, XIntc *sysIntc);
void XVprocss_RegisterDelayHandler(XVprocss *InstancePtr,
XVidC_DelayHandler waitmsec,
void *pTimer);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,574 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xvprocss_dma.c
* Video buffer management routine.
* The functions in this file provides an abstraction from the register peek/poke
* methodology by implementing most common use-case provided by the VDMA sub-core.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rc 05/18/15 Initial Release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xvidc.h"
#include "xvprocss_dma.h"
#include "microblaze_sleep.h"
#define XVDMA_RESET_TIMEOUT (1000000) //10ms at 10ns time period (100MHz clock))
/*****************************************************************************/
/**
* This function starts Read and Write channels
*
* @param pVdma is the pointer to core instance to be worked on
*
* @return None
*
*******************************************************************************/
void XVprocss_VdmaStart(XAxiVdma *pVdma)
{
if(pVdma)
{
XAxiVdma_DmaStart(pVdma, XAXIVDMA_WRITE);
XAxiVdma_DmaStart(pVdma, XAXIVDMA_READ);
}
}
/*****************************************************************************/
/**
* This function stops Read and Write channels
*
* @param pVdma is the pointer to core instance to be worked on
*
* @return None
*
*******************************************************************************/
void XVprocss_VdmaStop(XAxiVdma *pVdma)
{
if(pVdma)
{
XAxiVdma_DmaStop(pVdma, XAXIVDMA_WRITE);
XAxiVdma_DmaStop(pVdma, XAXIVDMA_READ);
}
}
/*****************************************************************************/
/**
* This function resets Read and Write channels.
*
* @param pVdma is the pointer to core instance to be worked on
*
* @return None
*
*******************************************************************************/
void XVprocss_VdmaReset(XAxiVdma *pVdma)
{
u32 timeout;
if(pVdma)
{
XAxiVdma_Reset(pVdma, XAXIVDMA_WRITE);
timeout = XVDMA_RESET_TIMEOUT;
while(timeout && XAxiVdma_ResetNotDone(pVdma, XAXIVDMA_WRITE))
{
timeout -= 1;
}
if(!timeout)
{
xil_printf("\r\n****CRITICAL HW ERR:: VDMA WR CH RESET STUCK HIGH****\r\n");
}
timeout = XVDMA_RESET_TIMEOUT;
XAxiVdma_Reset(pVdma, XAXIVDMA_READ);
while(timeout && XAxiVdma_ResetNotDone(pVdma, XAXIVDMA_READ))
{
timeout -= 1;
}
if(!timeout)
{
xil_printf("\r\n****CRITICAL HW ERR:: VDMA RD CH RESET STUCK HIGH****\r\n");
}
}
}
/*****************************************************************************/
/**
*
* This function sets up the write channel
*
* @param pVdma is the instance pointer to the DMA engine.
* @param WrBaseAddress is the address in DDR where frame buffers are located
* @param window is pointer to sub-frame window
* @param FrameWidth is the active width of the stream to be written
* @param FrameHeight is the active height of the stream to be written
* @param Bpp is Bytes Per Pixel required for the stream to be written
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
******************************************************************************/
int XVprocss_VdmaWriteSetup(XAxiVdma *pVdma,
u32 WrBaseAddress,
XVidC_VideoWindow *window,
u32 FrameWidth,
u32 FrameHeight,
u32 Bpp)
{
XAxiVdma_DmaSetup WriteCfg;
int Index;
u32 Addr;
int Status;
u32 HSizeInBytes;
u32 StrideInBytes;;
u32 BlockOffset;
u32 alignBytes = 0;
int MAX_WR_FRAMES;
if(pVdma)
{
MAX_WR_FRAMES = pVdma->MaxNumFrames;
HSizeInBytes = window->Width*Bpp;
StrideInBytes = FrameWidth*Bpp;
/* Compute start location for sub-frame */
BlockOffset = (window->StartY * StrideInBytes) + window->StartX*Bpp;
/* If DMA engine does not support unaligned transfers then align block
* offset to next data width boundary (DMA WR Data-width = 128)
*/
if(!pVdma->WriteChannel.HasDRE)
{
alignBytes = pVdma->WriteChannel.WordLength-1;
BlockOffset = (BlockOffset+alignBytes) & ~(alignBytes);
}
WriteCfg.VertSizeInput = window->Height;
WriteCfg.HoriSizeInput = HSizeInBytes;
WriteCfg.Stride = StrideInBytes;
WriteCfg.FrameDelay = 0; /* This example does not test frame delay */
WriteCfg.EnableCircularBuf = 1;
WriteCfg.EnableSync = 0; /* No Gen-Lock */
WriteCfg.PointNum = 0; /* Master we synchronize with -> vdma instance being worked with */
WriteCfg.EnableFrameCounter = 0; /* Endless transfers */
WriteCfg.FixedFrameStoreAddr = 0; /* We are not doing parking */
WriteCfg.GenLockRepeat = 1; /* Repeat previous frame on frame errors */
Status = XAxiVdma_DmaConfig(pVdma, XAXIVDMA_WRITE, &WriteCfg);
if (Status != XST_SUCCESS)
{
xil_printf("Write channel config failed %d\r\n", Status);
return XST_FAILURE;
}
/* Initialize buffer addresses
*
* Use physical addresses
*/
Addr = WrBaseAddress + BlockOffset;
for(Index = 0; Index < MAX_WR_FRAMES; Index++)
{
WriteCfg.FrameStoreStartAddr[Index] = Addr;
Addr += StrideInBytes * FrameHeight;
}
/* Set the buffer addresses for transfer in the DMA engine */
Status = XAxiVdma_DmaSetBufferAddr(pVdma, XAXIVDMA_WRITE,
WriteCfg.FrameStoreStartAddr);
if (Status != XST_SUCCESS)
{
xil_printf("Write channel set buffer address failed %d\r\n", Status);
return XST_FAILURE;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function sets up the read channel
*
* @param pVdma is the instance pointer to the DMA engine.
* @param RdBaseAddress is the address in DDR where frame buffers are located
* @param window is pointer to sub-frame window
* @param FrameWidth is the active width of the stream to be read
* @param FrameHeight is the active height of the stream to be read
* @param Bpp is Bytes Per Pixel required for the stream to be read
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
int XVprocss_VdmaReadSetup(XAxiVdma *pVdma,
u32 RdBaseAddress,
XVidC_VideoWindow *window,
u32 FrameWidth,
u32 FrameHeight,
u32 Bpp)
{
XAxiVdma_DmaSetup ReadCfg;
int Index;
u32 Addr;
int Status;
u32 HSizeInBytes;
u32 StrideInBytes;
u32 BlockOffset;
u32 alignBytes = 0;
int MAX_RD_FRAMES = pVdma->MaxNumFrames;
if(pVdma)
{
MAX_RD_FRAMES = pVdma->MaxNumFrames;
HSizeInBytes = window->Width*Bpp;
StrideInBytes = FrameWidth*Bpp;
//Compute start location for sub-frame
BlockOffset = (window->StartY * StrideInBytes) + window->StartX*Bpp;
/* If DMA engine does not support unaligned transfers then align block
* offset to next data width boundary (DMA WR Data-width = 128)
*/
if(!pVdma->ReadChannel.HasDRE)
{
alignBytes = pVdma->ReadChannel.WordLength-1;
BlockOffset = (BlockOffset+alignBytes) & ~(alignBytes);
}
ReadCfg.VertSizeInput = window->Height;
ReadCfg.HoriSizeInput = HSizeInBytes;
ReadCfg.Stride = StrideInBytes;
ReadCfg.FrameDelay = 1; /* Read is 1 Frame behind write */
ReadCfg.EnableCircularBuf = 1;
ReadCfg.EnableSync = 1; /* Gen-Lock Slave*/
ReadCfg.PointNum = 0; /* Master to synchronize with -> vdma instance being worked with */
ReadCfg.EnableFrameCounter = 0; /* Endless transfers */
ReadCfg.FixedFrameStoreAddr = 0; /* We are not doing parking */
Status = XAxiVdma_DmaConfig(pVdma, XAXIVDMA_READ, &ReadCfg);
if (Status != XST_SUCCESS)
{
xil_printf("Read channel config failed %d\r\n", Status);
return XST_FAILURE;
}
/* Initialize buffer addresses
*
* These addresses are physical addresses
*/
Addr = RdBaseAddress + BlockOffset;
for(Index = 0; Index < MAX_RD_FRAMES; Index++)
{
ReadCfg.FrameStoreStartAddr[Index] = Addr;
Addr += StrideInBytes * FrameHeight;
}
/* Set the buffer addresses for transfer in the DMA engine
* The buffer addresses are physical addresses
*/
Status = XAxiVdma_DmaSetBufferAddr(pVdma, XAXIVDMA_READ,
ReadCfg.FrameStoreStartAddr);
if (Status != XST_SUCCESS)
{
xil_printf("Read channel set buffer address failed %d\r\n", Status);
return XST_FAILURE;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function starts the transfer on Read/Write channels. Both channels must
* have been configured before this call is made
*
* @param pVdma is the instance pointer to the DMA engine.
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note Currently the return value is ignored at subsystem level.
*
******************************************************************************/
int XVprocss_VdmaStartTransfer(XAxiVdma *pVdma)
{
int Status;
if(pVdma)
{
Status = XAxiVdma_DmaStart(pVdma, XAXIVDMA_WRITE);
if (Status != XST_SUCCESS)
{
xil_printf("VDMA ERR:: Start Write transfer failed %d\r\n", Status);
return XST_FAILURE;
}
Status = XAxiVdma_DmaStart(pVdma, XAXIVDMA_READ);
if (Status != XST_SUCCESS)
{
xil_printf("VDMA ERR:: Start read transfer failed %d\r\n", Status);
return XST_FAILURE;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function prints VDMA status on the console
*
* @param pVdma is the instance pointer to the DMA engine.
* @param Bpp is Bytes per pixel to be used for data transfer
*
* @return None
*
******************************************************************************/
void XVprocss_VdmaDbgReportStatus(XAxiVdma *pVdma, u32 Bpp)
{
u32 height,width,stride;
u32 regOffset;
if(pVdma)
{
xil_printf("\r\n\r\n----->VDMA IP STATUS<----\r\n");
xil_printf("INFO: VDMA Rd/Wr Client Width/Stride defined in Bytes Per Pixel\r\n");
xil_printf("Bytes Per Pixel = %d\r\n\r\n", Bpp);
xil_printf("Read Channel Setting \r\n" );
//clear status register before reading
XAxiVdma_ClearDmaChannelErrors(pVdma, XAXIVDMA_READ, 0xFFFFFFFF);
MB_Sleep(100);
//Read Registers
XAxiVdma_DmaRegisterDump(pVdma, XAXIVDMA_READ);
regOffset = XAXIVDMA_MM2S_ADDR_OFFSET;
height = XAxiVdma_ReadReg(pVdma->BaseAddr, regOffset+0);
width = XAxiVdma_ReadReg(pVdma->BaseAddr, regOffset+4);
stride = XAxiVdma_ReadReg(pVdma->BaseAddr, regOffset+8);
stride &= XAXIVDMA_STRIDE_MASK;
xil_printf("Height: %d \r\n", height);
xil_printf("Width : %d (%d)\r\n", width, (width/Bpp));
xil_printf("Stride: %d (%d)\r\n", stride, (stride/Bpp));
xil_printf("\r\nWrite Channel Setting \r\n" );
//clear status register before reading
XAxiVdma_ClearDmaChannelErrors(pVdma, XAXIVDMA_WRITE, 0xFFFFFFFF);
MB_Sleep(100);
//Read Registers
XAxiVdma_DmaRegisterDump(pVdma, XAXIVDMA_WRITE);
regOffset = XAXIVDMA_S2MM_ADDR_OFFSET;
height = XAxiVdma_ReadReg(pVdma->BaseAddr, regOffset+0);
width = XAxiVdma_ReadReg(pVdma->BaseAddr, regOffset+4);
stride = XAxiVdma_ReadReg(pVdma->BaseAddr, regOffset+8);
stride &= XAXIVDMA_STRIDE_MASK;
xil_printf("Height: %d \r\n", height);
xil_printf("Width : %d (%d)\r\n", width, (width/Bpp));
xil_printf("Stride: %d (%d)\r\n", stride, (stride/Bpp));
}
}
/*****************************************************************************/
/**
* This function configures the VDMA RD/WR channel for down scale mode
*
* @param pVprocss is a pointer to the Subsystem instance to be worked on.
* @param updateCh defines VDMA channel (RD/WR or RD+WR) to update
*
* @return None
*
******************************************************************************/
void XVprocss_SetVdmaWinToDnScaleMode(XVprocss *pVprocss, u32 updateCh)
{
XVidC_VideoWindow wrWin, rdWin;
u32 OutputWidth, OutputHeight;
int status;
OutputWidth = pVprocss->VidOut.Timing.HActive;
OutputHeight = pVprocss->VidOut.Timing.VActive;
/*VDMA is After Scaler
WR client will receive PIP (or down scaled) stream from Scaler
RD client will read at Output resolution
*/
if((updateCh == XVPROCSS_VDMA_UPDATE_WR_CH) ||
(updateCh == XVPROCSS_VDMA_UPDATE_ALL_CH)
)
{
/* Setup WR CLIENT window size */
if(XVprocss_IsPipModeOn(pVprocss))
{
/* Read PIP window setting - set elsewhere */
XVprocss_GetZoomPipWindow(pVprocss, XVPROCSS_PIP_WIN, &wrWin);
}
else //Normal Downscale mode
{
/* set WR client window to output resolution */
wrWin.StartX = 0;
wrWin.StartY = 0;
wrWin.Width = OutputWidth;
wrWin.Height = OutputHeight;
}
/* write PIP window stream to DDR */
status = XVprocss_VdmaWriteSetup(pVprocss->vdma,
pVprocss->Config.UsrExtMemBaseAddr,
&wrWin,
OutputWidth,
OutputHeight,
pVprocss->idata.vdmaBytesPerPixel);
if(status != XST_SUCCESS)
{
xil_printf("VPROCSS ERR:: Unable to configure VDMA Write Channel \r\n");
}
}
if((updateCh == XVPROCSS_VDMA_UPDATE_RD_CH) ||
(updateCh == XVPROCSS_VDMA_UPDATE_ALL_CH)
)
{
/* Setup RD CLIENT window size to output resolution */
rdWin.StartX = 0;
rdWin.StartY = 0;
rdWin.Width = OutputWidth;
rdWin.Height = OutputHeight;
status = XVprocss_VdmaReadSetup(pVprocss->vdma,
pVprocss->Config.UsrExtMemBaseAddr,
&rdWin,
OutputWidth,
OutputHeight,
pVprocss->idata.vdmaBytesPerPixel);
if(status != XST_SUCCESS)
{
xil_printf("VPROCSS ERR:: Unable to configure VDMA Read Channel \r\n");
}
}
}
/*****************************************************************************/
/**
* This function configures the VDMA RD/WR channel for UP scale (or 1:1) mode
*
* @param pVprocss is a pointer to the Subsystem instance to be worked on.
* @param updateCh defines VDMA channel (RD/WR or RD+WR) to update
*
* @return None
*
******************************************************************************/
void XVprocss_SetVdmaWinToUpScaleMode(XVprocss *pVprocss, u32 updateCh)
{
XVidC_VideoWindow wrWin, rdWin;
u32 InputWidth, InputHeight;
int status;
InputWidth = pVprocss->idata.vidInWidth;
InputHeight = pVprocss->idata.vidInHeight;
/*VDMA is before Scaler
WR client will receive streaming input
RD client will read Window from specified coordinates
*/
if((updateCh == XVPROCSS_VDMA_UPDATE_WR_CH) ||
(updateCh == XVPROCSS_VDMA_UPDATE_ALL_CH))
{
/* Setup WR Client window size to Input Resolution */
wrWin.StartX = 0;
wrWin.StartY = 0;
wrWin.Width = InputWidth;
wrWin.Height = InputHeight;
/* write input stream to DDR */
status = XVprocss_VdmaWriteSetup(pVprocss->vdma,
pVprocss->Config.UsrExtMemBaseAddr,
&wrWin,
InputWidth,
InputHeight,
pVprocss->idata.vdmaBytesPerPixel);
if(status != XST_SUCCESS)
{
xil_printf("ERR:: Unable to configure VDMA Write Channel \r\n");
}
}
if((updateCh == XVPROCSS_VDMA_UPDATE_RD_CH) ||
(updateCh == XVPROCSS_VDMA_UPDATE_ALL_CH)
)
{
/* Setup RD CLIENT window size to either crop window or input resolution */
if(XVprocss_IsZoomModeOn(pVprocss))
{
/* Read user defined ZOOM window */
XVprocss_GetZoomPipWindow(pVprocss, XVPROCSS_ZOOM_WIN, &rdWin);
}
else //set RD window to input resolution
{
rdWin.StartX = 0;
rdWin.StartY = 0;
rdWin.Width = InputWidth;
rdWin.Height = InputHeight;
}
status = XVprocss_VdmaReadSetup(pVprocss->vdma,
pVprocss->Config.UsrExtMemBaseAddr,
&rdWin,
InputWidth,
InputHeight,
pVprocss->idata.vdmaBytesPerPixel);
if(status != XST_SUCCESS)
{
xil_printf("ERR:: Unable to configure VDMA Read Channel \r\n");
}
}
}

View file

@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xvprocss_dma.h
*
* This header file contains the video processing engine DMA buffer management
* routines and helper functions. AXI-VDMA core is used to provide DMA
* functionality and the function contained herein provides a high level
* implementation of features provided by the IP, abstracting away the low
* level core configuration details from the user
*
* <b>DMA Features </b>
*
* The DMA supports following features
* - Abstract AXI-VDMA API to setup/program RD/WR channel
* - Start/Stop transfer on all channels with single call
*
* <b>Initialization & Configuration</b>
*
* The device driver enables higher layer software to communicate with the
* vdma core.
*
* Before using these API's subsystem must initialize the core by calling
* Layer-1 API's XAxiVdma_LookupConfig(). This function will look for a
* configuration structure for the device and XAxiVdma_CfgInitialize() will
* initialize it to defined HW settings. After initialization included API's
* can be used to configure the core.
*
* <b> Interrupts </b>
*
* Currently VDMA core does not generate any interrupts
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rc 05/18/15 Initial Release
* </pre>
*
******************************************************************************/
#ifndef XVPROCSS_DMA_H_ /* prevent circular inclusions */
#define XVPROCSS_DMA_H_ /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
//#include "xaxivdma.h"
#include "xvprocss.h"
/************************** Constant Definitions *****************************/
/****************************** Type Definitions ******************************/
/**
* This typedef enumerates the VDMA channel that needs update
*/
typedef enum
{
XVPROCSS_VDMA_UPDATE_RD_CH = 0,
XVPROCSS_VDMA_UPDATE_WR_CH,
XVPROCSS_VDMA_UPDATE_ALL_CH
}XVPROCSS_VDMA_CH_UPDATE;
/************************** Function Prototypes ******************************/
void XVprocss_VdmaStart(XAxiVdma *pVdma);
void XVprocss_VdmaStop(XAxiVdma *pVdma);
void XVprocss_VdmaReset(XAxiVdma *pVdma);
int XVprocss_VdmaWriteSetup(XAxiVdma *pVdma,
u32 WrBaseAddress,
XVidC_VideoWindow *window,
u32 FrameWidth,
u32 FrameHeight,
u32 Bpp);
int XVprocss_VdmaReadSetup(XAxiVdma *pVdma,
u32 RdBaseAddress,
XVidC_VideoWindow *window,
u32 FrameWidth,
u32 FrameHeight,
u32 Bpp);
int XVprocss_VdmaStartTransfer(XAxiVdma *pVdma);
void XVprocss_VdmaDbgReportStatus(XAxiVdma *pVdma, u32 Bpp);
void XVprocss_SetVdmaWinToUpScaleMode(XVprocss *pVprocss, u32 updateCh);
void XVprocss_SetVdmaWinToDnScaleMode(XVprocss *pVprocss, u32 updateCh);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,757 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xvprocss_router.c
* Video buffer management routine.
* The functions in this file provides an abstraction from the register peek/poke
* methodology by implementing most common use-case provided by the VDMA sub-core.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rc 05/18/15 Initial Release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xvidc.h"
#include "xvprocss_router.h"
#include "xvprocss_dma.h"
/************************** Constant Definitions *****************************/
/* AXIS Switch Port# connected to input stream */
#define AXIS_SWITCH_VIDIN_S0 (0)
/************************** Function Prototypes ******************************/
static int validateWindowSize(const XVidC_VideoWindow *win,
const u32 HActive,
const u32 VActive);
static XVprocss_ScaleMode GetScalingMode(XVprocss *pVprocss);
/*****************************************************************************/
/**
* This function checks to make sure sub-frame is inside full frame
*
* @param win is a pointer to the sub-frame window
* @param Resolution is a pointer to the current output resolution
*
* @return XST_SUCCESS if window is valid else XST_FAILURE
*
******************************************************************************/
static int validateWindowSize(const XVidC_VideoWindow *win,
const u32 HActive,
const u32 VActive)
{
Xil_AssertNonvoid(win != NULL);
//Check if window is valid
if((win->Width == 0) || (win->Height == 0))
{
return(XST_FAILURE);
}
//Check if window is within the Resolution being programmed
if(((win->StartX > HActive)) ||
((win->StartY > VActive)) ||
((win->StartX + win->Width) > HActive) ||
((win->StartY + win->Height) > VActive))
{
return(XST_FAILURE);
}
else
{
return(XST_SUCCESS);
}
}
/*****************************************************************************/
/**
* This function computes the scaling mode based on input/output stream
* resolution. It also accounts for Zoom or PIP mode, if enabled
*
* @param pVprocss is a pointer to the Subsystem instance to be worked on.
*
* @return Scaling mode Up/Dpwn or 1:1
*
******************************************************************************/
static XVprocss_ScaleMode GetScalingMode(XVprocss *pVprocss)
{
int status;
XVprocss_ScaleMode mode;
XVidC_VideoWindow win;
XVidC_VideoStream *pStrIn = &pVprocss->VidIn;
XVidC_VideoStream *pStrOut = &pVprocss->VidOut;
if(XVprocss_IsPipModeOn(pVprocss))
{
/* Read PIP window setting - set elsewhere */
XVprocss_GetZoomPipWindow(pVprocss, XVPROCSS_PIP_WIN, &win);
/* validate window */
status = validateWindowSize(&win,
pVprocss->VidOut.Timing.HActive,
pVprocss->VidOut.Timing.VActive);
if(status != XST_SUCCESS)
{
xil_printf("VPROCSS ERR:: VDMA Write Channel Window Invalid \r\n");
xil_printf(" Start X = %d\r\n", win.StartX);
xil_printf(" Start Y = %d\r\n", win.StartY);
xil_printf(" Win Width = %d\r\n", win.Width);
xil_printf(" Win Height = %d\r\n", win.Height);
return(XVPROCSS_SCALE_NOT_SUPPORTED);
}
else
{
xil_printf("\r\n PIP Mode ON: Scale %dx%d -> %dx%d window in output stream\r\n",
pStrIn->Timing.HActive,
pStrIn->Timing.VActive,
pVprocss->idata.wrWindow.Width,
pVprocss->idata.wrWindow.Height);
return(XVPROCSS_SCALE_DN);
}
}
if(XVprocss_IsZoomModeOn(pVprocss))
{
/* Read PIP window setting - set elsewhere */
XVprocss_GetZoomPipWindow(pVprocss, XVPROCSS_ZOOM_WIN, &win);
/* validate window */
status = validateWindowSize(&win,
pStrIn->Timing.HActive,
pStrIn->Timing.VActive);
if(status != XST_SUCCESS)
{
xil_printf("ERR:: VDMA Read Channel Window Invalid \r\n");
xil_printf(" Start X = %d\r\n", win.StartX);
xil_printf(" Start Y = %d\r\n", win.StartY);
xil_printf(" Win Width = %d\r\n", win.Width);
xil_printf(" Win Height = %d\r\n", win.Height);
return(XVPROCSS_SCALE_NOT_SUPPORTED);
}
else
{
xil_printf("\r\n Zoom Mode ON: Scale %dx%d window from Input Stream -> %dx%d\r\n",
pVprocss->idata.rdWindow.Width,
pVprocss->idata.rdWindow.Height,
pStrOut->Timing.HActive,
pStrOut->Timing.VActive);
return (XVPROCSS_SCALE_UP);
}
}
/* Pip & Zoom mode are off. Check input/output resolution */
if((pStrIn->Timing.HActive > pStrOut->Timing.HActive) ||
(pStrIn->Timing.VActive > pStrOut->Timing.VActive))
{
mode = XVPROCSS_SCALE_DN;
}
else if((pStrIn->Timing.HActive < pStrOut->Timing.HActive) ||
(pStrIn->Timing.VActive < pStrOut->Timing.VActive))
{
mode = XVPROCSS_SCALE_UP;
}
else
{
mode = XVPROCSS_SCALE_1_1;
}
return(mode);
}
/*****************************************************************************/
/**
* This function examines the subsystem Input/Output Stream configuration and
* builds a routing table for the supported use-case. The computed routing
* table is stored in the scratch pad memory
*
* @param pVprocss is a pointer to the Subsystem instance to be worked on.
*
* @return XST_SUCCESS if routing table can be created else XST_FAILURE
*
******************************************************************************/
int XVprocss_BuildRoutingTable(XVprocss *pVprocss)
{
#ifdef DEBUG
const char *ipStr[XVPROCSS_RTR_MAX] =
{
"VID_OUT",
"SCALER-V",
"SCALER-H",
"VDMA",
"LBOX",
"CR-H",
"CR-VIn",
"CR-VOut",
"CSC",
"DEINT",
};
#endif
u32 index = 0;
XVidC_VideoStream *pStrIn = &pVprocss->VidIn;
XVidC_VideoStream *pStrOut = &pVprocss->VidOut;
XVprocss_IData *pCfg = &pVprocss->idata;
u8 *pTable = &pVprocss->idata.RtngTable[0];
int status = XST_SUCCESS;
xdbg_printf(XDBG_DEBUG_GENERAL," ->Build AXIS Routing Map for Subsystem Use-Case.... \r\n");
/* Save input resolution */
pCfg->vidInWidth = pStrIn->Timing.HActive;
pCfg->vidInHeight = pStrIn->Timing.VActive;
pCfg->strmCformat = pStrIn->ColorFormatId;
/* Determine Scaling Mode */
pVprocss->idata.memEn = FALSE;
pVprocss->idata.ScaleMode = GetScalingMode(pVprocss);
if(pVprocss->idata.ScaleMode == XVPROCSS_SCALE_NOT_SUPPORTED)
{
xil_printf("VPROCSS ERR:: Scaling Mode not supported\r\n");
return(XST_FAILURE);
}
/* Reset Routing Table */
memset(pTable, 0, sizeof(pVprocss->idata.RtngTable));
/* Check if input is I/P */
if(pStrIn->IsInterlaced)
{
if(pStrIn->ColorFormatId != XVIDC_CSF_YCRCB_420)
{
if(pVprocss->deint)
{
if((pVprocss->VidIn.VmId != XVIDC_VM_1080_60_I) &&
(pVprocss->VidIn.VmId != XVIDC_VM_1080_50_I))
{
xil_printf("VPROCSS ERR:: De-Interlacer supports only 1080i Input\r\n");
return(XST_FAILURE);
}
pTable[index++] = XVPROCSS_RTR_DEINT;
}
else
{
xil_printf("VPROCSS ERR:: De-Interlacer IP not found - Interlaced Input not supported\r\n");
return(XST_FAILURE);
}
}
else //YUV_420
{
xil_printf("VPROCSS ERR:: Interlaced 420 input not supported\r\n");
return(XST_FAILURE);
}
}
/* Check if input is 420 */
if(pStrIn->ColorFormatId == XVIDC_CSF_YCRCB_420)
{
if(pVprocss->vcrsmplrIn) //up-sample vertically to 422 as none of the IP supports 420
{
pTable[index++] = XVPROCSS_RTR_CR_V_IN;
pCfg->strmCformat = XVIDC_CSF_YCRCB_422;
}
else //V Chroma Resampler IP not included in design
{
xil_printf("VPROCSS ERR:: Vertical Chroma Resampler IP not found. YUV420 Input not supported\r\n");
return(XST_FAILURE);
}
}
switch(pVprocss->idata.ScaleMode)
{
case XVPROCSS_SCALE_1_1:
pTable[index++] = XVPROCSS_RTR_VDMA;
pVprocss->idata.memEn = TRUE;
break;
case XVPROCSS_SCALE_UP:
pTable[index++] = XVPROCSS_RTR_VDMA; /* VDMA is before Scaler */
pTable[index++] = XVPROCSS_RTR_SCALER_V;
pTable[index++] = XVPROCSS_RTR_SCALER_H;
pVprocss->idata.memEn = TRUE;
break;
case XVPROCSS_SCALE_DN:
pTable[index++] = XVPROCSS_RTR_SCALER_H;
pTable[index++] = XVPROCSS_RTR_SCALER_V;
pTable[index++] = XVPROCSS_RTR_VDMA; /* VDMA is after Scaler */
pVprocss->idata.memEn = TRUE;
break;
default:
xil_printf("VPROCSS ERR:: Scaling Mode cannot be determined.\r\n");
return(XST_FAILURE);
break;
}
/* Send stream to LBox to add H/V bars, if needed */
pTable[index++] = XVPROCSS_RTR_LBOX;
/* Check for input and output color format to derive required conversions */
switch(pStrOut->ColorFormatId)
{
case XVIDC_CSF_YCRCB_420:
switch(pStrIn->ColorFormatId)
{
case XVIDC_CSF_RGB:
pTable[index++] = XVPROCSS_RTR_CSC; //convert RGB->444
pTable[index++] = XVPROCSS_RTR_CR_H; //convert 444->422
pTable[index++] = XVPROCSS_RTR_CR_V_OUT; //convert 422->420
pCfg->cscIn = XVIDC_CSF_RGB;
pCfg->cscOut = XVIDC_CSF_YCRCB_444;
pCfg->hcrIn = XVIDC_CSF_YCRCB_444;
pCfg->hcrOut = XVIDC_CSF_YCRCB_422;
break;
case XVIDC_CSF_YCRCB_444:
pTable[index++] = XVPROCSS_RTR_CSC; //picture control in 444
pTable[index++] = XVPROCSS_RTR_CR_H; //convert 444->422
pTable[index++] = XVPROCSS_RTR_CR_V_OUT; //convert 422->420
pCfg->cscIn = XVIDC_CSF_YCRCB_444;
pCfg->cscOut = XVIDC_CSF_YCRCB_444;
pCfg->hcrIn = XVIDC_CSF_YCRCB_444;
pCfg->hcrOut = XVIDC_CSF_YCRCB_422;
break;
case XVIDC_CSF_YCRCB_422:
case XVIDC_CSF_YCRCB_420: //Input was up converted to 422
pTable[index++] = XVPROCSS_RTR_CSC; //picture control in 422
pTable[index++] = XVPROCSS_RTR_CR_V_OUT; //convert 422->420
pCfg->cscIn = XVIDC_CSF_YCRCB_422;
pCfg->cscOut = XVIDC_CSF_YCRCB_422;
break;
default: //Unsupported color format
xil_printf("VPROCSS ERR:: Input Color Format Not Supported \r\n");
status = XST_FAILURE;
break;
}
break;
case XVIDC_CSF_RGB:
switch(pStrIn->ColorFormatId)
{
case XVIDC_CSF_RGB:
case XVIDC_CSF_YCRCB_444: //convert 444->RGB
pTable[index++] = XVPROCSS_RTR_CSC;
pCfg->cscIn = pStrIn->ColorFormatId;
pCfg->cscOut = XVIDC_CSF_RGB;
break;
case XVIDC_CSF_YCRCB_422:
case XVIDC_CSF_YCRCB_420: //Input was up converted to 422
pTable[index++] = XVPROCSS_RTR_CR_H; //convert 422->444
pTable[index++] = XVPROCSS_RTR_CSC; //convert 444->RGB
pCfg->hcrIn = XVIDC_CSF_YCRCB_422;
pCfg->hcrOut = XVIDC_CSF_YCRCB_444;
pCfg->cscIn = XVIDC_CSF_YCRCB_444;
pCfg->cscOut = XVIDC_CSF_RGB;
break;
default: //Unsupported color format
xil_printf("VPROCSS ERR:: Input Color Format Not Supported \r\n");
status = XST_FAILURE;
break;
}
break;
case XVIDC_CSF_YCRCB_422:
switch(pStrIn->ColorFormatId)
{
case XVIDC_CSF_RGB:
pTable[index++] = XVPROCSS_RTR_CSC; //convert RGB->444
pTable[index++] = XVPROCSS_RTR_CR_H; //convert 444->422
pCfg->cscIn = XVIDC_CSF_RGB;
pCfg->cscOut = XVIDC_CSF_YCRCB_444;
pCfg->hcrIn = XVIDC_CSF_YCRCB_444;
pCfg->hcrOut = XVIDC_CSF_YCRCB_422;
break;
case XVIDC_CSF_YCRCB_444:
pTable[index++] = XVPROCSS_RTR_CSC; //picture control in 444
pTable[index++] = XVPROCSS_RTR_CR_H; //convert 444->422
pCfg->cscIn = XVIDC_CSF_YCRCB_444;
pCfg->cscOut = XVIDC_CSF_YCRCB_444;
pCfg->hcrIn = XVIDC_CSF_YCRCB_444;
pCfg->hcrOut = XVIDC_CSF_YCRCB_422;
break;
case XVIDC_CSF_YCRCB_422:
case XVIDC_CSF_YCRCB_420: //Input was up converted to 422
pTable[index++] = XVPROCSS_RTR_CSC; //picture control in 422
pCfg->cscIn = XVIDC_CSF_YCRCB_422;
pCfg->cscOut = XVIDC_CSF_YCRCB_422;
break;
default: //Unsupported color format
xil_printf("VPROCSS ERR:: Input Color Format Not Supported \r\n");
status = XST_FAILURE;
break;
}
break;
case XVIDC_CSF_YCRCB_444:
switch(pStrIn->ColorFormatId)
{
case XVIDC_CSF_RGB: //convert 444->RGB
case XVIDC_CSF_YCRCB_444:
pTable[index++] = XVPROCSS_RTR_CSC;
pCfg->cscIn = pStrIn->ColorFormatId;
pCfg->cscOut = XVIDC_CSF_YCRCB_444;
break;
case XVIDC_CSF_YCRCB_422:
case XVIDC_CSF_YCRCB_420: //Input was up converted to 422
pTable[index++] = XVPROCSS_RTR_CR_H; //convert 422->444
pTable[index++] = XVPROCSS_RTR_CSC; //picture control
pCfg->hcrIn = XVIDC_CSF_YCRCB_422;
pCfg->hcrOut = XVIDC_CSF_YCRCB_444;
pCfg->cscIn = XVIDC_CSF_YCRCB_444;
pCfg->cscOut = XVIDC_CSF_YCRCB_444;
break;
default: //Unsupported color format
xil_printf("VPROCSS ERR:: Input Color Format Not Supported \r\n");
status = XST_FAILURE;
break;
}
break;
default:
xil_printf("VPROCSS ERR:: Output Color Format Not Supported \r\n");
status = XST_FAILURE;
break;
}
/* Connect Last IP in chain to switch output */
pTable[index++] = XVPROCSS_RTR_VIDOUT;
/* save number of cores in processing path */
pVprocss->idata.RtrNumCores = index;
#ifdef DEBUG
if(status == XST_SUCCESS)
{
u32 count = 0;
//print IP Data Flow Map
xil_printf("\r\nGenerated Map: VidIn");
while(count<index)
{
xil_printf(" -> %s",ipStr[pTable[count++]]);
}
xil_printf("\r\n\r\n");
}
#endif
return(status);
}
/*****************************************************************************/
/**
* This function traverses the computed routing table and sets up the AXIS
* switch registers, to route the stream through processing cores, in the order
* defined in the routing map
*
* @param pVprocss is a pointer to the Subsystem instance to be worked on.
*
* @return None
*
******************************************************************************/
void XVprocss_ProgRouterMux(XVprocss *pVprocss)
{
u32 count, nextMi, prevSi;
u8 *pTable = &pVprocss->idata.RtngTable[0];
u32 numProcElem = pVprocss->idata.RtrNumCores;
XAxisScr_RegUpdateDisable(pVprocss->router);
/* Disable all ports */
XAxisScr_MiPortDisableAll(pVprocss->router);
/* Connect Input Stream to the 1st core in path */
nextMi = prevSi = pTable[0];
XAxisScr_MiPortEnable(pVprocss->router, nextMi, AXIS_SWITCH_VIDIN_S0);
/* Traverse routing map and connect cores in the chain */
for(count=1; count<numProcElem; ++count)
{
nextMi = pTable[count];
XAxisScr_MiPortEnable(pVprocss->router, nextMi, prevSi);
prevSi = nextMi;
}
//Enable Router register update
XAxisScr_RegUpdateEnable(pVprocss->router);
}
/*****************************************************************************/
/**
* This function traverses the routing map built earlier and configures each
* sub-core in the processing path per its location in the chain.
* Each core in the processing path is marked and only marked cores are started
* All remaining cores stay disabled
*
* @param pVprocss is a pointer to the Subsystem instance to be worked on.
*
* @return None
*
******************************************************************************/
void XVprocss_SetupRouterDataFlow(XVprocss *pVprocss)
{
XVidC_VideoWindow lboxWin;
u32 vsc_WidthIn, vsc_HeightIn, vsc_HeightOut;
u32 hsc_HeightIn, hsc_WidthIn, hsc_WidthOut;
u32 count;
XVprocss_IData *pCfg = &pVprocss->idata;
u8 *pTable = &pVprocss->idata.RtngTable[0];
u8 *pStartCore = &pVprocss->idata.startCore[0];
vsc_WidthIn = vsc_HeightIn = vsc_HeightOut = 0;
hsc_HeightIn = hsc_WidthIn = hsc_WidthOut = 0;
/* Program Video Pipe Sub-Cores */
if(pVprocss->VidIn.IsInterlaced)
{
/* Input will de-interlaced first. All downstream IP's work
* with progressive frame. Adjust active height to reflect the
* progressive frame to downstream cores
*/
pVprocss->idata.vidInHeight *= 2;
}
/* If Vdma is enabled, RD/WR Client needs to be programmed before Scaler */
if((pVprocss->vdma) && (pVprocss->idata.memEn))
{
switch(pVprocss->idata.ScaleMode)
{
case XVPROCSS_SCALE_1_1:
case XVPROCSS_SCALE_UP:
XVprocss_SetVdmaWinToUpScaleMode(pVprocss, XVPROCSS_VDMA_UPDATE_ALL_CH);
break;
case XVPROCSS_SCALE_DN:
XVprocss_SetVdmaWinToDnScaleMode(pVprocss, XVPROCSS_VDMA_UPDATE_ALL_CH);
break;
default:
break;
}
pStartCore[XVPROCSS_RTR_VDMA] = TRUE;
}
for(count=0; count<pVprocss->idata.RtrNumCores; ++count)
{
switch(pTable[count])
{
case XVPROCSS_RTR_SCALER_V:
if(pVprocss->vscaler)
{
if(pVprocss->idata.ScaleMode == XVPROCSS_SCALE_DN)
{
/* Downscale mode H Scaler is before V Scaler */
vsc_WidthIn = hsc_WidthOut;
vsc_HeightIn = hsc_HeightIn;
vsc_HeightOut = ((XVprocss_IsPipModeOn(pVprocss)) ? pVprocss->idata.wrWindow.Height
: pVprocss->VidOut.Timing.VActive);
}
else
{
/* UpScale mode V Scaler is before H Scaler */
vsc_WidthIn = ((XVprocss_IsZoomModeOn(pVprocss)) ? pVprocss->idata.rdWindow.Width
: pVprocss->idata.vidInWidth);
vsc_HeightIn = ((XVprocss_IsZoomModeOn(pVprocss)) ? pVprocss->idata.rdWindow.Height
: pVprocss->idata.vidInHeight);
vsc_HeightOut = pVprocss->VidOut.Timing.VActive;
}
xdbg_printf(XDBG_DEBUG_GENERAL," -> Configure VScaler for %dx%d to %dx%d\r\n", \
(int)vsc_WidthIn, (int)vsc_HeightIn, (int)vsc_WidthIn, (int)vsc_HeightOut);
XV_VScalerSetup(pVprocss->vscaler,
&pVprocss->vscL2Reg,
vsc_WidthIn,
vsc_HeightIn,
vsc_HeightOut);
pStartCore[XVPROCSS_RTR_SCALER_V] = TRUE;
}
break;
case XVPROCSS_RTR_SCALER_H:
if(pVprocss->hscaler)
{
if(pVprocss->idata.ScaleMode == XVPROCSS_SCALE_DN)
{
/* Downscale mode H Scaler is before V Scaler */
hsc_WidthIn = pVprocss->idata.vidInWidth;
hsc_HeightIn = pVprocss->idata.vidInHeight;
hsc_WidthOut = ((XVprocss_IsPipModeOn(pVprocss)) ? pVprocss->idata.wrWindow.Width
: pVprocss->VidOut.Timing.HActive);
}
else
{
/* Upscale mode V Scaler is before H Scaler */
hsc_WidthIn = vsc_WidthIn;
hsc_HeightIn = vsc_HeightOut;
hsc_WidthOut = pVprocss->VidOut.Timing.HActive;
}
xdbg_printf(XDBG_DEBUG_GENERAL," -> Configure HScaler for %dx%d to %dx%d\r\n", \
(int)hsc_WidthIn, (int)hsc_HeightIn, (int)hsc_WidthOut, (int)hsc_HeightIn);
XV_HScalerSetup(pVprocss->hscaler,
&pVprocss->hscL2Reg,
hsc_HeightIn,
hsc_WidthIn,
hsc_WidthOut,
pVprocss->Config.PixPerClock,
pVprocss->idata.strmCformat);
pStartCore[XVPROCSS_RTR_SCALER_H] = TRUE;
}
break;
case XVPROCSS_RTR_VDMA:
/* NOP - Programmed before the switch statement */
break;
case XVPROCSS_RTR_LBOX:
if(pVprocss->lbox)
{
if(XVprocss_IsPipModeOn(pVprocss))
{
/* get the active window for lbox */
lboxWin = pVprocss->idata.wrWindow;
}
else //Downscale - Read full image from VDMA
{
/* window is same as output resolution */
lboxWin.StartX = 0;
lboxWin.StartY = 0;
lboxWin.Width = pVprocss->VidOut.Timing.HActive;
lboxWin.Height = pVprocss->VidOut.Timing.VActive;
}
XV_LBoxSetActiveWin(pVprocss->lbox,
&lboxWin,
pVprocss->VidOut.Timing.HActive,
pVprocss->VidOut.Timing.VActive);
pStartCore[XVPROCSS_RTR_LBOX] = TRUE;
}
break;
case XVPROCSS_RTR_CR_H:
if(pVprocss->hcrsmplr)
{
XV_HCrsmplSetActiveSize(pVprocss->hcrsmplr,
pVprocss->VidOut.Timing.HActive,
pVprocss->VidOut.Timing.VActive);
XV_HCrsmplSetFormat(pVprocss->hcrsmplr,
pCfg->hcrIn,
pCfg->hcrOut);
pStartCore[XVPROCSS_RTR_CR_H] = TRUE;
}
break;
case XVPROCSS_RTR_CR_V_IN:
if(pVprocss->vcrsmplrIn)
{
XV_VCrsmplSetActiveSize(pVprocss->vcrsmplrIn,
pVprocss->idata.vidInWidth,
pVprocss->idata.vidInHeight);
XV_VCrsmplSetFormat(pVprocss->vcrsmplrIn,
XVIDC_CSF_YCRCB_420,
XVIDC_CSF_YCRCB_422);
pStartCore[XVPROCSS_RTR_CR_V_IN] = TRUE;
}
break;
case XVPROCSS_RTR_CR_V_OUT:
if(pVprocss->vcrsmplrOut)
{
XV_VCrsmplSetActiveSize(pVprocss->vcrsmplrOut,
pVprocss->VidOut.Timing.HActive,
pVprocss->VidOut.Timing.VActive);
XV_VCrsmplSetFormat(pVprocss->vcrsmplrOut,
XVIDC_CSF_YCRCB_422,
XVIDC_CSF_YCRCB_420);
pStartCore[XVPROCSS_RTR_CR_V_OUT] = TRUE;
}
break;
case XVPROCSS_RTR_CSC:
if(pVprocss->csc)
{
XV_CscSetColorspace(pVprocss->csc,
&pVprocss->cscL2Reg,
pVprocss->idata.cscIn,
pVprocss->idata.cscOut,
pVprocss->cscL2Reg.StandardIn,
pVprocss->cscL2Reg.StandardOut,
pVprocss->cscL2Reg.OutputRange);
XV_CscSetActiveSize(pVprocss->csc,
pVprocss->VidOut.Timing.HActive,
pVprocss->VidOut.Timing.VActive);
pStartCore[XVPROCSS_RTR_CSC] = TRUE;
}
break;
case XVPROCSS_RTR_DEINT:
if(pVprocss->deint)
{
xdbg_printf(XDBG_DEBUG_GENERAL," -> Configure Deinterlacer for %dx%d to %dx%d\r\n", \
(int)pVprocss->VidIn.Timing.HActive,
(int)pVprocss->VidIn.Timing.VActive,
(int)pVprocss->idata.vidInWidth,
(int)pVprocss->idata.vidInHeight);
XV_DeintSetFieldBuffers(pVprocss->deint,
pVprocss->idata.deintBufAddr,
pVprocss->VidIn.ColorFormatId);
pStartCore[XVPROCSS_RTR_DEINT] = TRUE;
}
break;
}
}
/* Start all IP Blocks in the processing chain */
XVprocss_Start(pVprocss);
}

View file

@ -0,0 +1,70 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xvprocss_router.h
*
* This header file contains the video processing engine data flow setup
* routines and helper functions.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rc 05/18/15 Initial Release
* </pre>
*
******************************************************************************/
#ifndef XVPROCSS_ROUTER_H__ /* prevent circular inclusions */
#define XVPROCSS_ROUTER_H__ /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
//#include "xaxivdma.h"
#include "xvprocss.h"
/************************** Constant Definitions *****************************/
/************************** Function Prototypes ******************************/
int XVprocss_BuildRoutingTable(XVprocss *pVprocss);
void XVprocss_ProgRouterMux(XVprocss *pVprocss);
void XVprocss_SetupRouterDataFlow(XVprocss *pVprocss);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,97 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xvprocss_sinit.c
*
* This file contains the implementation of the Video Processing Subsystem
* driver's static initialization functionality.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rc 05/01/15 Initial Release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xvprocss.h"
/************************** Constant Definitions *****************************/
//ToDo: This will be exported to xparameters.h
#define XPAR_XDSPSS_NUM_INSTANCES (1)
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XVprocss_Config XVprocss_ConfigTable[XPAR_XDSPSS_NUM_INSTANCES];
/*****************************************************************************/
/**
* This function looks for the device configuration based on the unique device
* ID. The table XVprocss_ConfigTable[] contains the configuration information
* for each instance of the device in the system.
*
* @param DeviceId is the unique device ID of the device being looked up
*
* @return A pointer to the configuration table entry corresponding to the
* given device ID, or NULL if no match is found
*
*******************************************************************************/
XVprocss_Config* XVprocss_LookupConfig(u32 DeviceId)
{
XVprocss_Config *CfgPtr = NULL;
u32 index;
for (index = 0U; index < (u32)XPAR_XDSPSS_NUM_INSTANCES; index++)
{
if (XVprocss_ConfigTable[index].DeviceId == DeviceId)
{
CfgPtr = &XVprocss_ConfigTable[index];
break;
}
}
return (CfgPtr);
}