vphy: Initial release of Video PHY driver.

Video PHY driver for abstraction of GTs.

Contribution from Gilbert Magnaye on HDMI.
Contribution from Vamsi Krishna Dhanikonda on DisplayPort.

Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
Acked-by: Rohit Consul <rohitco@xilinx.com>
This commit is contained in:
Andrei-Liviu Simion 2015-10-19 23:33:59 -07:00 committed by Nava kishore Manne
parent 46eae7368d
commit 4b33a35165
20 changed files with 10698 additions and 0 deletions

View file

@ -0,0 +1,41 @@
##******************************************************************************
##
## 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 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 vphy
OPTION supported_peripherals = (vid_phy_controller);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 1.0;
OPTION NAME = vphy;
END driver

View file

@ -0,0 +1,190 @@
##******************************************************************************
##
## 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 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.
##
##*****************************************************************************/
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "XVPHY" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "Transceiver" "C_Tx_No_Of_Channels" "C_Rx_No_Of_Channels" "C_Tx_Protocol" "C_Rx_Protocol" "C_TX_REFCLK_SEL" "C_RX_REFCLK_SEL" "C_TX_PLL_SELECTION" "C_RX_PLL_SELECTION" "C_NIDRU" "C_NIDRU_REFCLK_SEL"
::hsi::utils::define_config_file $drv_handle "xvphy_g.c" "XVphy" "DEVICE_ID" "C_BASEADDR" "TRANSCEIVER" "C_Tx_No_Of_Channels" "C_Rx_No_Of_Channels" "C_Tx_Protocol" "C_Rx_Protocol" "C_TX_REFCLK_SEL" "C_RX_REFCLK_SEL" "C_TX_PLL_SELECTION" "C_RX_PLL_SELECTION" "C_NIDRU" "C_NIDRU_REFCLK_SEL"
xdefine_canonical_xpars $drv_handle "xparameters.h" "VPHY" "DEVICE_ID" "C_BASEADDR" "Transceiver" "C_Tx_No_Of_Channels" "C_Rx_No_Of_Channels" "C_Tx_Protocol" "C_Rx_Protocol" "C_TX_REFCLK_SEL" "C_RX_REFCLK_SEL" "C_TX_PLL_SELECTION" "C_RX_PLL_SELECTION" "C_NIDRU" "C_NIDRU_REFCLK_SEL"
}
#
# Given a list of arguments, define them all in an include file.
# Handles IP model/user parameters, as well as the special parameters NUM_INSTANCES,
# DEVICE_ID
# Will not work for a processor.
#
proc xdefine_include_file {drv_handle file_name drv_string args} {
set args [::hsi::utils::get_exact_arg_list $args]
# Open include file
set file_handle [::hsi::utils::open_include_file $file_name]
# Get all peripherals connected to this driver
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
# Handle special cases
set arg "NUM_INSTANCES"
set posn [lsearch -exact $args $arg]
if {$posn > -1} {
puts $file_handle "/* Definitions for driver [string toupper [common::get_property name $drv_handle]] */"
# Define NUM_INSTANCES
puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [llength $periphs]"
set args [lreplace $args $posn $posn]
}
# Check if it is a driver parameter
lappend newargs
foreach arg $args {
set value [common::get_property CONFIG.$arg $drv_handle]
if {[llength $value] == 0} {
lappend newargs $arg
} else {
puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [common::get_property $arg $drv_handle]"
}
}
set args $newargs
# Print all parameters for all peripherals
set device_id 0
foreach periph $periphs {
puts $file_handle ""
puts $file_handle "/* Definitions for peripheral [string toupper [common::get_property NAME $periph]] */"
foreach arg $args {
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
set value $device_id
incr device_id
} else {
set value [common::get_property CONFIG.$arg $periph]
}
if {[llength $value] == 0} {
set value 0
}
set value [::hsi::utils::format_addr_string $value $arg]
if {[string compare -nocase "HW_VER" $arg] == 0} {
puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] \"$value\""
} elseif {[string compare -nocase "TRANSCEIVER" $arg] == 0} {
puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg]_STR \"$value\""
if {[string compare -nocase "GTXE2" "$value"] == 0} {
puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] 1"
} elseif {[string compare -nocase "GTHE3" "$value"] == 0} {
puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] 4"
} else {
puts $file_handle "#error \"Video PHY currently supports only GTHE3 and GTXE2; $value not supported\""
}
} else {
puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] $value"
}
}
puts $file_handle ""
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
#
# define_canonical_xpars - Used to print out canonical defines for a driver.
# Given a list of arguments, define each as a canonical constant name, using
# the driver name, in an include file.
#
proc xdefine_canonical_xpars {drv_handle file_name drv_string args} {
set args [::hsi::utils::get_exact_arg_list $args]
# Open include file
set file_handle [::hsi::utils::open_include_file $file_name]
# Get all the peripherals connected to this driver
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
# Get the names of all the peripherals connected to this driver
foreach periph $periphs {
set peripheral_name [string toupper [common::get_property NAME $periph]]
lappend peripherals $peripheral_name
}
# Get possible canonical names for all the peripherals connected to this
# driver
set device_id 0
foreach periph $periphs {
set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]]
lappend canonicals $canonical_name
# Create a list of IDs of the peripherals whose hardware instance name
# doesn't match the canonical name. These IDs can be used later to
# generate canonical definitions
if { [lsearch $peripherals $canonical_name] < 0 } {
lappend indices $device_id
}
incr device_id
}
set i 0
foreach periph $periphs {
set periph_name [string toupper [common::get_property NAME $periph]]
# Generate canonical definitions only for the peripherals whose
# canonical name is not the same as hardware instance name
if { [lsearch $canonicals $periph_name] < 0 } {
puts $file_handle "/* Canonical definitions for peripheral $periph_name */"
set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]]
foreach arg $args {
set lvalue [::hsi::utils::get_driver_param_name $canonical_name $arg]
# The commented out rvalue is the name of the instance-specific constant
# set rvalue [::hsi::utils::get_ip_param_name $periph $arg]
# The rvalue set below is the actual value of the parameter
set rvalue [::hsi::utils::get_param_value $periph $arg]
if {[llength $rvalue] == 0} {
set rvalue 0
}
set rvalue [::hsi::utils::format_addr_string $rvalue $arg]
if {[string compare -nocase "TRANSCEIVER" $arg] == 0} {
puts $file_handle "#define [string toupper $lvalue]_STR \"$rvalue\""
if {[string compare -nocase "GTXE2" "$rvalue"] == 0} {
puts $file_handle "#define [string toupper $lvalue] 1"
} elseif {[string compare -nocase "GTHE3" "$rvalue"] == 0} {
puts $file_handle "#define [string toupper $lvalue] 4"
} else {
puts $file_handle "#error \"Video PHY currently supports only GTHE3 and GTXE2; $rvalue not supported\""
}
} else {
puts $file_handle "#define [string toupper $lvalue] $rvalue"
}
}
puts $file_handle ""
incr i
}
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xvphy_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling vphy"
xvphy_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xvphy_includes
xvphy_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,800 @@
/*******************************************************************************
*
* 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 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 xvphy.h
*
* The Xilinx Video PHY (VPHY) driver. This driver supports the Xilinx Video PHY
* IP core.
* Version 1.0 supports:
* - GTXE2 and GTHE3 GT types.
* - DisplayPort and HDMI protocols.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
#ifndef XVPHY_H_
/* Prevent circular inclusions by using protection macros. */
#define XVPHY_H_
/******************************* Include Files ********************************/
#include "xil_assert.h"
#include "xvphy_hw.h"
#include "xvidc.h"
#include "xvphy_dp.h"
/****************************** Type Definitions ******************************/
/* This typedef enumerates the different GT types available. */
typedef enum {
XVPHY_GT_TYPE_GTXE2 = 1,
XVPHY_GT_TYPE_GTHE2 = 2,
XVPHY_GT_TYPE_GTPE2 = 3,
XVPHY_GT_TYPE_GTHE3 = 4,
XVPHY_GT_TYPE_GTHE4 = 5,
} XVphy_GtType;
/**
* This typedef enumerates the various protocols handled by the Video PHY
* controller (VPHY).
*/
typedef enum {
XVPHY_PROTOCOL_DP = 0,
XVPHY_PROTOCOL_HDMI,
XVPHY_PROTOCOL_NONE
} XVphy_ProtocolType;
/* This typedef enumerates is used to specify RX/TX direction information. */
typedef enum {
XVPHY_DIR_RX = 0,
XVPHY_DIR_TX
} XVphy_DirectionType;
/**
* This typedef enumerates the list of available interrupt handler types. The
* values are used as parameters to the XVphy_SetIntrHandler function.
*/
typedef enum {
XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE = XVPHY_INTR_TXRESETDONE_MASK,
XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE = XVPHY_INTR_RXRESETDONE_MASK,
XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK = XVPHY_INTR_CPLL_LOCK_MASK,
XVPHY_INTR_HANDLER_TYPE_QPLL_LOCK = XVPHY_INTR_QPLL_LOCK_MASK,
XVPHY_INTR_HANDLER_TYPE_QPLL0_LOCK = XVPHY_INTR_QPLL_LOCK_MASK,
XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE = XVPHY_INTR_TXALIGNDONE_MASK,
XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK = XVPHY_INTR_QPLL1_LOCK_MASK,
XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE =
XVPHY_INTR_TXCLKDETFREQCHANGE_MASK,
XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE =
XVPHY_INTR_RXCLKDETFREQCHANGE_MASK,
XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT = XVPHY_INTR_TXTMRTIMEOUT_MASK,
XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT = XVPHY_INTR_RXTMRTIMEOUT_MASK,
} XVphy_IntrHandlerType;
/**
* This typedef enumerates the list of available hdmi handler types. The
* values are used as parameters to the XVphy_SetHdmiCallback function.
*/
typedef enum {
XVPHY_HDMI_HANDLER_TXINIT = 1, /**< TX init handler. */
XVPHY_HDMI_HANDLER_TXREADY, /**< TX ready handler. */
XVPHY_HDMI_HANDLER_RXINIT, /**< RX init handler. */
XVPHY_HDMI_HANDLER_RXREADY /**< RX ready handler. */
} XVphy_HdmiHandlerType;
/**
* This typedef enumerates the different PLL types for a given GT channel.
*/
typedef enum {
XVPHY_PLL_TYPE_CPLL = 1,
XVPHY_PLL_TYPE_QPLL = 2,
XVPHY_PLL_TYPE_QPLL0 = 3,
XVPHY_PLL_TYPE_QPLL1 = 4,
XVPHY_PLL_TYPE_PLL0 = 5,
XVPHY_PLL_TYPE_PLL1 = 6,
XVPHY_PLL_TYPE_UNKNOWN = 7,
} XVphy_PllType;
/**
* This typedef enumerates the available channels.
*/
typedef enum {
XVPHY_CHANNEL_ID_CH1 = 1,
XVPHY_CHANNEL_ID_CH2 = 2,
XVPHY_CHANNEL_ID_CH3 = 3,
XVPHY_CHANNEL_ID_CH4 = 4,
XVPHY_CHANNEL_ID_CMN0 = 5,
XVPHY_CHANNEL_ID_CMN1 = 6,
XVPHY_CHANNEL_ID_CHA = 7,
XVPHY_CHANNEL_ID_CMNA = 8,
XVPHY_CHANNEL_ID_CMN = XVPHY_CHANNEL_ID_CMN0,
} XVphy_ChannelId;
/**
* This typedef enumerates the available reference clocks for the PLL clock
* selection multiplexer.
*/
typedef enum {
XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0 = XVPHY_REF_CLK_SEL_XPLL_GTREFCLK0,
XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK1 = XVPHY_REF_CLK_SEL_XPLL_GTREFCLK1,
XVPHY_PLL_REFCLKSEL_TYPE_GTNORTHREFCLK0 =
XVPHY_REF_CLK_SEL_XPLL_GTNORTHREFCLK0,
XVPHY_PLL_REFCLKSEL_TYPE_GTNORTHREFCLK1 =
XVPHY_REF_CLK_SEL_XPLL_GTNORTHREFCLK1,
XVPHY_PLL_REFCLKSEL_TYPE_GTSOUTHREFCLK0 =
XVPHY_REF_CLK_SEL_XPLL_GTSOUTHREFCLK0,
XVPHY_PLL_REFCLKSEL_TYPE_GTSOUTHREFCLK1 =
XVPHY_REF_CLK_SEL_XPLL_GTSOUTHREFCLK1,
XVPHY_PLL_REFCLKSEL_TYPE_GTGREFCLK = XVPHY_REF_CLK_SEL_XPLL_GTGREFCLK,
} XVphy_PllRefClkSelType;
/**
* This typedef enumerates the available reference clocks used to drive the
* RX/TX datapaths.
*/
typedef enum {
XVPHY_SYSCLKSELDATA_TYPE_CPLL_OUTCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_CPLL,
XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_QPLL,
XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_QPLL0,
XVPHY_SYSCLKSELDATA_TYPE_QPLL1_OUTCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_QPLL1,
} XVphy_SysClkDataSelType;
/**
* This typedef enumerates the available reference clocks used to drive the
* RX/TX output clocks.
*/
typedef enum {
XVPHY_SYSCLKSELOUT_TYPE_CPLL_REFCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CH,
XVPHY_SYSCLKSELOUT_TYPE_QPLL_REFCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN,
XVPHY_SYSCLKSELOUT_TYPE_QPLL0_REFCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN0,
XVPHY_SYSCLKSELOUT_TYPE_QPLL1_REFCLK =
XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN1,
} XVphy_SysClkOutSelType;
/**
* This typedef enumerates the available clocks that are used as multiplexer
* input selections for the RX/TX output clock.
*/
typedef enum {
XVPHY_OUTCLKSEL_TYPE_OUTCLKPCS = 1,
XVPHY_OUTCLKSEL_TYPE_OUTCLKPMA,
XVPHY_OUTCLKSEL_TYPE_PLLREFCLK_DIV1,
XVPHY_OUTCLKSEL_TYPE_PLLREFCLK_DIV2,
XVPHY_OUTCLKSEL_TYPE_PROGDIVCLK
} XVphy_OutClkSelType;
/* This typedef enumerates the possible states a transceiver can be in. */
typedef enum {
XVPHY_GT_STATE_IDLE, /**< Idle state. */
XVPHY_GT_STATE_LOCK, /**< Lock state. */
XVPHY_GT_STATE_RESET, /**< Reset state. */
XVPHY_GT_STATE_ALIGN, /**< Align state. */
XVPHY_GT_STATE_READY /**< Ready state. */
} XVphy_GtState;
typedef enum {
XVPHY_LOG_EVT_NONE = 1, /**< Log event none. */
XVPHY_LOG_EVT_QPLL_EN, /**< Log event QPLL enable. */
XVPHY_LOG_EVT_QPLL_RST, /**< Log event QPLL reset. */
XVPHY_LOG_EVT_QPLL_LOCK, /**< Log event QPLL lock. */
XVPHY_LOG_EVT_QPLL_RECONFIG, /**< Log event QPLL reconfig. */
XVPHY_LOG_EVT_QPLL0_EN, /**< Log event QPLL0 enable. */
XVPHY_LOG_EVT_QPLL0_RST, /**< Log event QPLL0 reset. */
XVPHY_LOG_EVT_QPLL0_LOCK, /**< Log event QPLL0 lock. */
XVPHY_LOG_EVT_QPLL0_RECONFIG, /**< Log event QPLL0 reconfig. */
XVPHY_LOG_EVT_QPLL1_EN, /**< Log event QPLL1 enable. */
XVPHY_LOG_EVT_QPLL1_RST, /**< Log event QPLL1 reset. */
XVPHY_LOG_EVT_QPLL1_LOCK, /**< Log event QPLL1 lock. */
XVPHY_LOG_EVT_QPLL1_RECONFIG, /**< Log event QPLL1 reconfig. */
XVPHY_LOG_EVT_PLL0_EN, /**< Log event PLL0 reset. */
XVPHY_LOG_EVT_PLL0_RST, /**< Log event PLL0 reset. */
XVPHY_LOG_EVT_PLL0_LOCK, /**< Log event PLL0 lock. */
XVPHY_LOG_EVT_PLL0_RECONFIG, /**< Log event PLL0 reconfig. */
XVPHY_LOG_EVT_PLL1_EN, /**< Log event PLL1 reset. */
XVPHY_LOG_EVT_PLL1_RST, /**< Log event PLL1 reset. */
XVPHY_LOG_EVT_PLL1_LOCK, /**< Log event PLL1 lock. */
XVPHY_LOG_EVT_PLL1_RECONFIG, /**< Log event PLL1 reconfig. */
XVPHY_LOG_EVT_CPLL_EN, /**< Log event CPLL reset. */
XVPHY_LOG_EVT_CPLL_RST, /**< Log event CPLL reset. */
XVPHY_LOG_EVT_CPLL_LOCK, /**< Log event CPLL lock. */
XVPHY_LOG_EVT_CPLL_RECONFIG, /**< Log event CPLL reconfig. */
XVPHY_LOG_EVT_TXPLL_EN, /**< Log event TXPLL enable. */
XVPHY_LOG_EVT_TXPLL_RST, /**< Log event TXPLL reset. */
XVPHY_LOG_EVT_RXPLL_EN, /**< Log event RXPLL enable. */
XVPHY_LOG_EVT_RXPLL_RST, /**< Log event RXPLL reset. */
XVPHY_LOG_EVT_GTRX_RST, /**< Log event GT RX reset. */
XVPHY_LOG_EVT_GTTX_RST, /**< Log event GT TX reset. */
XVPHY_LOG_EVT_VID_TX_RST, /**< Log event Vid TX reset. */
XVPHY_LOG_EVT_VID_RX_RST, /**< Log event Vid RX reset. */
XVPHY_LOG_EVT_TX_ALIGN, /**< Log event TX align. */
XVPHY_LOG_EVT_TX_TMR, /**< Log event TX timer. */
XVPHY_LOG_EVT_RX_TMR, /**< Log event RX timer. */
XVPHY_LOG_EVT_GT_RECONFIG, /**< Log event GT reconfig. */
XVPHY_LOG_EVT_INIT, /**< Log event init. */
XVPHY_LOG_EVT_TXPLL_RECONFIG, /**< Log event TXPLL reconfig. */
XVPHY_LOG_EVT_RXPLL_RECONFIG, /**< Log event RXPLL reconfig. */
XVPHY_LOG_EVT_RXPLL_LOCK, /**< Log event RXPLL lock. */
XVPHY_LOG_EVT_TXPLL_LOCK, /**< Log event TXPLL lock. */
XVPHY_LOG_EVT_TX_RST_DONE, /**< Log event TX reset done. */
XVPHY_LOG_EVT_RX_RST_DONE, /**< Log event RX reset done. */
XVPHY_LOG_EVT_TX_FREQ, /**< Log event TX frequency. */
XVPHY_LOG_EVT_RX_FREQ /**< Log event RX frequency. */
} XVphy_LogEvent;
/******************************************************************************/
/**
* Callback type which represents the handler for interrupts.
*
* @param InstancePtr is a pointer to the XVphy instance.
*
* @note None.
*
*******************************************************************************/
typedef void (*XVphy_IntrHandler)(void *InstancePtr);
/******************************************************************************/
/**
* Callback type which represents a custom timer wait handler. This is only
* used for Microblaze since it doesn't have a native sleep function. To avoid
* dependency on a hardware timer, the default wait functionality is implemented
* using loop iterations; this isn't too accurate. If a custom timer handler is
* used, the user may implement their own wait implementation using a hardware
* timer (see example/) for better accuracy.
*
* @param InstancePtr is a pointer to the XVphy instance.
* @param MicroSeconds is the number of microseconds to be passed to the
* timer function.
*
* @note None.
*
*******************************************************************************/
typedef void (*XVphy_TimerHandler)(void *InstancePtr, u32 MicroSeconds);
/******************************************************************************/
/**
* Generic callback type.
*
* @param CallbackRef is a pointer to the callback reference.
*
* @note None.
*
*******************************************************************************/
typedef void (*XVphy_Callback)(void *CallbackRef);
/**
* This typedef contains configuration information for CPLL/QPLL programming.
*/
typedef struct {
u8 MRefClkDiv;
/* Aliases for N (QPLL) and N1/N2 (CPLL). */
union {
u8 NFbDivs[2];
u8 NFbDiv;
struct {
u8 N1FbDiv;
u8 N2FbDiv;
};
};
u16 Cdr[5];
u8 IsLowerBand;
} XVphy_PllParam;
/**
* This typedef contains configuration information for PLL type and its
* reference clock.
*/
typedef struct {
/* Below members are common between CPLL/QPLL. */
u64 LineRateHz; /**< The line rate for the
channel. */
union {
XVphy_PllParam QpllParams;
XVphy_PllParam CpllParams; /**< Parameters for a CPLL. */
XVphy_PllParam PllParams;
};
union {
XVphy_PllRefClkSelType CpllRefClkSel;
/**< Multiplexer selection for
the reference clock of
the CPLL. */
XVphy_PllRefClkSelType PllRefClkSel;
};
/* Below members are CPLL specific. */
union {
struct {
u8 RxOutDiv; /**< Output clock divider D for
the RX datapath. */
u8 TxOutDiv; /**< Output clock divider D for
the TX datapath. */
};
u8 OutDiv[2];
};
union {
struct {
XVphy_GtState RxState; /**< Current state of RX GT. */
XVphy_GtState TxState; /**< Current state of TX GT. */
};
XVphy_GtState GtState[2];
};
union {
struct {
XVphy_ProtocolType RxProtocol;
/**< The protocol which the RX
path is used for. */
XVphy_ProtocolType TxProtocol;
/**< The protocol which the TX
path is used for. */
};
XVphy_ProtocolType Protocol[2];
};
union {
struct {
XVphy_SysClkDataSelType RxDataRefClkSel;
/**< Multiplexer selection for
the reference clock of
the RX datapath. */
XVphy_SysClkDataSelType TxDataRefClkSel;
/**< Multiplexer selection for
the reference clock of
the TX datapath. */
};
XVphy_SysClkDataSelType DataRefClkSel[2];
};
union {
struct {
XVphy_SysClkOutSelType RxOutRefClkSel;
/**< Multiplexer selection for
the reference clock of
the RX output clock. */
XVphy_SysClkOutSelType TxOutRefClkSel;
/**< Multiplexer selection for
the reference clock of
the TX output clock. */
};
XVphy_SysClkOutSelType OutRefClkSel[2];
};
union {
struct {
XVphy_OutClkSelType RxOutClkSel;
/**< Multiplexer selection for
which clock to use as
the RX output clock. */
XVphy_OutClkSelType TxOutClkSel;
/**< Multiplexer selection for
which clock to use as
the TX output clock. */
};
XVphy_OutClkSelType OutClkSel[2];
};
union {
struct {
u8 RxDelayBypass; /**< Bypasses the delay
alignment block for the
RX output clock. */
u8 TxDelayBypass; /**< Bypasses the delay
alignment block for the
TX output clock. */
};
u8 DelayBypass;
};
u8 RxDataWidth; /**< In bits. */
u8 RxIntDataWidth; /**< In bytes. */
} XVphy_Channel;
/**
* This typedef contains configuration information for MMCM programming.
*/
typedef struct {
u8 DivClkDivide;
u8 ClkFbOutMult;
u16 ClkFbOutFrac;
u8 ClkOut0Div;
u16 ClkOut0Frac;
u8 ClkOut1Div;
u8 ClkOut2Div;
} XVphy_Mmcm;
/**
* This typedef represents a GT quad.
*/
typedef struct {
union {
struct {
XVphy_Mmcm RxMmcm; /**< Mixed-mode clock manager
(MMCM) parameters for
RX. */
XVphy_Mmcm TxMmcm; /**< MMCM parameters for TX. */
};
XVphy_Mmcm Mmcm[2]; /**< MMCM parameters. */
};
union {
struct {
XVphy_Channel Ch1;
XVphy_Channel Ch2;
XVphy_Channel Ch3;
XVphy_Channel Ch4;
XVphy_Channel Cmn0;
XVphy_Channel Cmn1;
};
XVphy_Channel Plls[6];
};
union {
struct {
u32 GtRefClk0Hz;
u32 GtRefClk1Hz;
u32 GtNorthRefClk0Hz;
u32 GtNorthRefClk1Hz;
u32 GtSouthRefClk0Hz;
u32 GtSouthRefClk1Hz;
u32 GtgRefClkHz;
};
u32 RefClkHz[7];
};
} XVphy_Quad;
/**
* This typedef contains the logging mechanism for debug.
*/
typedef struct {
u16 DataBuffer[256]; /**< Log buffer with event data. */
u8 HeadIndex; /**< Index of the head entry of the
Event/DataBuffer. */
u8 TailIndex; /**< Index of the tail entry of the
Event/DataBuffer. */
} XVphy_Log;
/**
* This typedef contains configuration information for the Video PHY core.
*/
typedef struct {
u16 DeviceId; /**< Device instance ID. */
u32 BaseAddr; /**< The base address of the core
instance. */
XVphy_GtType XcvrType; /**< VPHY Transceiver Type */
u8 TxChannels; /**< No. of active channels in TX */
u8 RxChannels; /**< No. of active channels in RX */
XVphy_ProtocolType TxProtocol; /**< Protocol which TX is used for. */
XVphy_ProtocolType RxProtocol; /**< Protocol which RX is used for. */
XVphy_PllRefClkSelType TxRefClkSel; /**< TX REFCLK selection. */
XVphy_PllRefClkSelType RxRefClkSel; /**< RX REFCLK selection. */
XVphy_SysClkDataSelType TxSysPllClkSel; /**< TX SYSCLK selection. */
XVphy_SysClkDataSelType RxSysPllClkSel; /**< RX SYSCLK selectino. */
u8 DruIsPresent; /**< A data recovery unit (DRU) exists
in the design .*/
XVphy_PllRefClkSelType DruRefClkSel; /**< DRU REFCLK selection. */
} XVphy_Config;
/* Forward declaration. */
struct XVphy_GtConfigS;
/**
* The XVphy driver instance data. The user is required to allocate a variable
* of this type for every XVphy device in the system. A pointer to a variable of
* this type is then passed to the driver API functions.
*/
typedef struct {
u32 IsReady; /**< Device is initialized and
ready. */
XVphy_Config Config; /**< Configuration structure for
the Video PHY core. */
const struct XVphy_GtConfigS *GtAdaptor;
XVphy_Log Log; /**< A log of events. */
XVphy_Quad Quads[2]; /**< The quads available to the
Video PHY core.*/
u32 HdmiRxRefClkHz; /**< HDMI RX refclk. */
u32 HdmiTxRefClkHz; /**< HDMI TX refclk. */
u8 HdmiRxTmdsClockRatio; /**< HDMI TMDS clock ratio. */
u8 HdmiTxSampleRate; /**< HDMI TX sample rate. */
u8 HdmiRxDruIsEnabled; /**< The DRU is enabled. */
XVphy_IntrHandler IntrCpllLockHandler; /**< Callback function for CPLL
lock interrupts. */
void *IntrCpllLockCallbackRef; /**< A pointer to the user data
passed to the CPLL lock
callback function. */
XVphy_IntrHandler IntrQpllLockHandler; /**< Callback function for QPLL
lock interrupts. */
void *IntrQpllLockCallbackRef; /**< A pointer to the user data
passed to the QPLL lock
callback function. */
XVphy_IntrHandler IntrQpll1LockHandler; /**< Callback function for QPLL
lock interrupts. */
void *IntrQpll1LockCallbackRef; /**< A pointer to the user data
passed to the QPLL lock
callback function. */
XVphy_IntrHandler IntrTxResetDoneHandler; /**< Callback function for TX
reset done lock
interrupts. */
void *IntrTxResetDoneCallbackRef; /**< A pointer to the user data
passed to the TX reset
done lock callback
function. */
XVphy_IntrHandler IntrRxResetDoneHandler; /**< Callback function for RX
reset done lock
interrupts. */
void *IntrRxResetDoneCallbackRef; /**< A pointer to the user data
passed to the RX reset
done lock callback
function. */
XVphy_IntrHandler IntrTxAlignDoneHandler; /**< Callback function for TX
align done lock
interrupts. */
void *IntrTxAlignDoneCallbackRef; /**< A pointer to the user data
passed to the TX align
done lock callback
function. */
XVphy_IntrHandler IntrTxClkDetFreqChangeHandler; /**< Callback function
for TX clock detector
frequency change
interrupts. */
void *IntrTxClkDetFreqChangeCallbackRef; /**< A pointer to the user data
passed to the TX clock
detector frequency
change callback
function. */
XVphy_IntrHandler IntrRxClkDetFreqChangeHandler; /**< Callback function
for RX clock detector
frequency change
interrupts. */
void *IntrRxClkDetFreqChangeCallbackRef; /**< A pointer to the user data
passed to the RX clock
detector frequency
change callback
function. */
XVphy_IntrHandler IntrTxTmrTimeoutHandler; /**< Callback function for TX
timer timeout
interrupts. */
void *IntrTxTmrTimeoutCallbackRef; /**< A pointer to the user data
passed to the TX timer
timeout callback
function. */
XVphy_IntrHandler IntrRxTmrTimeoutHandler; /**< Callback function for RX
timer timeout
interrupts. */
void *IntrRxTmrTimeoutCallbackRef; /**< A pointer to the user data
passed to the RX timer
timeout callback
function. */
/* HDMI callbacks. */
XVphy_Callback HdmiTxInitCallback; /**< Callback for TX init. */
void *HdmiTxInitRef; /**< To be passed to the TX init
callback. */
XVphy_Callback HdmiTxReadyCallback; /**< Callback for TX ready. */
void *HdmiTxReadyRef; /**< To be passed to the TX
ready callback. */
XVphy_Callback HdmiRxInitCallback; /**< Callback for RX init. */
void *HdmiRxInitRef; /**< To be passed to the RX
init callback. */
XVphy_Callback HdmiRxReadyCallback; /**< Callback for RX ready. */
void *HdmiRxReadyRef; /**< To be passed to the RX
ready callback. */
XVphy_TimerHandler UserTimerWaitUs; /**< Custom user function for
delay/sleep. */
void *UserTimerPtr; /**< Pointer to a timer instance
used by the custom user
delay/sleep function. */
} XVphy;
/**************************** Function Prototypes *****************************/
/* xvphy.c: Setup and initialization functions. */
void XVphy_CfgInitialize(XVphy *InstancePtr, XVphy_Config *ConfigPtr,
u32 EffectiveAddr);
u32 XVphy_PllInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_PllRefClkSelType QpllRefClkSel,
XVphy_PllRefClkSelType CpllxRefClkSel,
XVphy_PllType TxPllSelect, XVphy_PllType RxPllSelect);
u32 XVphy_ClkInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir);
void XVphy_WaitUs(XVphy *InstancePtr, u32 MicroSeconds);
void XVphy_SetUserTimerHandler(XVphy *InstancePtr,
XVphy_TimerHandler CallbackFunc, void *CallbackRef);
/* xvphy.c: GT attributes update function. */
u32 XVphy_UpdateGtProtocolParameters(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_ProtocolType Protocol);
/* xvphy.c: Voltage swing and preemphasis. */
void XVphy_SetRxLpm(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir, u8 Enable);
void XVphy_SetTxVoltageSwing(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 Vs);
void XVphy_SetTxPreEmphasis(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
u8 Pe);
/* xvphy.c: Channel configuration functions - setters. */
u32 XVphy_WriteCfgRefClkSelReg(XVphy *InstancePtr, u8 QuadId);
u32 XVphy_CfgLineRate(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
u64 LineRateHz);
u32 XVphy_CfgQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
XVphy_PllRefClkSelType RefClkType, u32 FreqHz);
void XVphy_CfgPllRefClkSel(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_PllRefClkSelType RefClkSel);
void XVphy_CfgSysClkDataSel(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir, XVphy_SysClkDataSelType SysClkDataSel);
void XVphy_CfgSysClkOutSel(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir, XVphy_SysClkOutSelType SysClkOutSel);
u32 XVphy_ClkCalcParams(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir, u32 PllClkInFreqHz);
u32 XVphy_OutDivReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
u32 XVphy_DirReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir);
u32 XVphy_ClkReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
/* xvphy.c: Channel configuration functions - getters. */
XVphy_PllType XVphy_GetPllType(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir, XVphy_ChannelId ChId);
u32 XVphy_GetQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
XVphy_PllRefClkSelType RefClkType);
XVphy_PllRefClkSelType XVphy_GetPllRefClkSel(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
XVphy_SysClkDataSelType XVphy_GetSysClkDataSel(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir, XVphy_ChannelId ChId);
XVphy_SysClkOutSelType XVphy_GetSysClkOutSel(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir, XVphy_ChannelId ChId);
/* xvphy.c: Reset functions. */
u32 XVphy_WaitForPmaResetDone(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
u32 XVphy_WaitForResetDone(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir);
u32 XVphy_WaitForPllLock(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
u32 XVphy_ResetGtPll(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir, u8 Hold);
u32 XVphy_ResetGtTxRx(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir, u8 Hold);
u32 XVphy_GtUserRdyEnable(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir, u8 Hold);
u32 XVphy_ResetGt(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir);
/* xvphy.c: GT/MMCM DRP access. */
u32 XVphy_DrpWrite(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
u16 Addr, u16 Val);
u16 XVphy_DrpRead(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
u16 Addr);
void XVphy_MmcmReset(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
u8 Hold);
void XVphy_MmcmPowerDown(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
u8 Hold);
void XVphy_MmcmStart(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir);
void XVphy_BufgGtReset(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Reset);
void XVphy_SetBufgGtDiv(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Div);
void XVphy_IBufDsEnable(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
u8 Enable);
void XVphy_Clkout1OBufTdsEnable(XVphy *InstancePtr, XVphy_DirectionType Dir,
u8 Enable);
/* xvphy.c Miscellaneous control. */
u32 XVphy_GetVersion(XVphy *InstancePtr);
void XVphy_Set8b10b(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir, u8 Enable);
u32 XVphy_PowerDownGtPll(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
u8 Hold);
u32 XVphy_IsBonded(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
/* xvphy_log.c: Logging functions. */
void XVphy_LogReset(XVphy *InstancePtr);
void XVphy_LogWrite(XVphy *InstancePtr, XVphy_LogEvent Evt, u8 Data);
u16 XVphy_LogRead(XVphy *InstancePtr);
void XVphy_LogDisplay(XVphy *InstancePtr);
/* xvphy_intr.c: Interrupt handling functions. */
void XVphy_SetIntrHandler(XVphy *InstancePtr, XVphy_IntrHandlerType HandlerType,
XVphy_IntrHandler CallbackFunc, void *CallbackRef);
void XVphy_InterruptHandler(XVphy *InstancePtr);
void XVphy_IntrEnable(XVphy *InstancePtr, XVphy_IntrHandlerType Intr);
void XVphy_IntrDisable(XVphy *InstancePtr, XVphy_IntrHandlerType Intr);
/* xvphy_selftest.c: Self test function. */
u32 XVphy_SelfTest(XVphy *InstancePtr);
/* xvphy_sinit.c: Configuration extraction function. */
XVphy_Config *XVphy_LookupConfig(u16 DeviceId);
/* xvphy_dp.c, xvphy_hdmi.c, xvphy_hdmi_intr.c: Protocol specific functions. */
u32 XVphy_DpInitialize(XVphy *InstancePtr, XVphy_Config *CfgPtr, u8 QuadId,
XVphy_PllRefClkSelType CpllRefClkSel,
XVphy_PllRefClkSelType QpllRefClkSel,
XVphy_PllType TxPllSelect, XVphy_PllType RxPllSelect,
u8 LinkRate);
u32 XVphy_HdmiInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_Config *CfgPtr,
u32 SystemFrequency);
u32 XVphy_SetHdmiTxParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVidC_PixelsPerClock Ppc, XVidC_ColorDepth Bpc,
XVidC_ColorFormat ColorFormat);
u32 XVphy_SetHdmiRxParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
u32 XVphy_HdmiCfgCalcMmcmParam(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir,
XVidC_PixelsPerClock Ppc, XVidC_ColorDepth Bpc);
void XVphy_HdmiUpdateClockSelection(XVphy *InstancePtr, u8 QuadId,
XVphy_SysClkDataSelType TxSysPllClkSel,
XVphy_SysClkDataSelType RxSysPllClkSel);
void XVphy_ClkDetFreqReset(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir);
u32 XVphy_ClkDetGetRefClkFreqHz(XVphy *InstancePtr, XVphy_DirectionType Dir);
u32 XVphy_DruGetRefClkFreqHz(XVphy *InstancePtr);
void XVphy_HdmiDebugInfo(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
void XVphy_DpDebugInfo(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
void XVphy_SetHdmiCallback(XVphy *InstancePtr,
XVphy_HdmiHandlerType HandlerType,
void *CallbackFunc, void *CallbackRef);
/******************* Macros (Inline Functions) Definitions ********************/
#define XVPHY_CH2IDX(Id) ((Id) - XVPHY_CHANNEL_ID_CH1)
#define XVPHY_ISCH(Id) (((Id) == XVPHY_CHANNEL_ID_CHA) || \
((XVPHY_CHANNEL_ID_CH1 <= (Id)) && ((Id) <= XVPHY_CHANNEL_ID_CH4)))
#define XVPHY_ISCMN(Id) (((Id) == XVPHY_CHANNEL_ID_CMNA) || \
((XVPHY_CHANNEL_ID_CMN0 <= (Id)) && ((Id) <= XVPHY_CHANNEL_ID_CMN1)))
#define XVphy_IsTxUsingQpll(InstancePtr, QuadId, ChId) \
((XVPHY_PLL_TYPE_QPLL == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId)) || \
(XVPHY_PLL_TYPE_QPLL0 == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId)) || \
(XVPHY_PLL_TYPE_QPLL1 == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId)))
#define XVphy_IsRxUsingQpll(InstancePtr, QuadId, ChId) \
((XVPHY_PLL_TYPE_QPLL == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId)) || \
(XVPHY_PLL_TYPE_QPLL0 == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId)) || \
(XVPHY_PLL_TYPE_QPLL1 == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId)))
#define XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId) \
(XVPHY_PLL_TYPE_CPLL == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId))
#define XVphy_IsRxUsingCpll(InstancePtr, QuadId, ChId) \
(XVPHY_PLL_TYPE_CPLL == \
XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId))
#endif /* XVPHY_H_ */

View file

@ -0,0 +1,335 @@
/*******************************************************************************
*
* 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 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 xvphy_dp.c
*
* This file contains video PHY functionality specific to the DisplayPort
* protocol.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 vkd 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xvphy_dp.h"
#include "xvphy.h"
#include "string.h"
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function initializes the Video PHY for DisplayPort.
*
* @param InstancePtr is a pointer to the XVphy instance.
* @param CfgPtr is a pointer to the configuration structure that will
* be used to copy the settings from.
* @param QuadId is the GT quad ID to operate on.
* @param CpllRefClkSel is the CPLL reference clock selection for the
* quad.
* @param QpllRefClkSel is the QPLL reference clock selection for the
* quad.
* @param TxPllSelect is the reference clock selection for the quad's
* TX PLL dividers.
* @param RxPllSelect is the reference clock selection for the quad's
* RX PLL dividers.
* @param LinkRate is the line rate to set for the quad's channels.
*
* @return
* - XST_SUCCESS.
*
* @note None.
*
*******************************************************************************/
u32 XVphy_DpInitialize(XVphy *InstancePtr, XVphy_Config *CfgPtr, u8 QuadId,
XVphy_PllRefClkSelType CpllRefClkSel,
XVphy_PllRefClkSelType QpllRefClkSel,
XVphy_PllType TxPllSelect, XVphy_PllType RxPllSelect,
u8 LinkRate)
{
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(CfgPtr != NULL);
/* Setup the instance */
(void)memset((void *)InstancePtr, 0, sizeof(XVphy));
XVphy_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddr);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_QPLL_LOCK);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE);
XVphy_IntrDisable(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE);
XVphy_IntrDisable(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT);
XVphy_IntrDisable(InstancePtr, XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT);
XVphy_LogReset(InstancePtr);
XVphy_LogWrite(InstancePtr, (XVPHY_LOG_EVT_INIT), 0);
InstancePtr->Quads[QuadId].Plls[0].TxState = (XVPHY_GT_STATE_IDLE);
InstancePtr->Quads[QuadId].Plls[0].RxState = (XVPHY_GT_STATE_IDLE);
switch (InstancePtr->Config.XcvrType) {
case XVPHY_GT_TYPE_GTXE2:
case XVPHY_GT_TYPE_GTHE2:
XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId,
XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0,
XVPHY_DP_REF_CLK_FREQ_HZ_135);
XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId,
XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK1,
XVPHY_DP_REF_CLK_FREQ_HZ_135);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH1,
XVPHY_GTXE2_DIFF_SWING_DP_L1);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH2,
XVPHY_GTXE2_DIFF_SWING_DP_L1);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH3,
XVPHY_GTXE2_DIFF_SWING_DP_L1);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH4,
XVPHY_GTXE2_DIFF_SWING_DP_L1);
break;
case XVPHY_GT_TYPE_GTHE3:
XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId,
XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0,
XVPHY_DP_REF_CLK_FREQ_HZ_162);
XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId,
XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK1,
XVPHY_DP_REF_CLK_FREQ_HZ_162);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH1, XVPHY_GTHE3_DIFF_SWING_DP_L1);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH2, XVPHY_GTHE3_DIFF_SWING_DP_L1);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH3, XVPHY_GTHE3_DIFF_SWING_DP_L1);
XVphy_SetTxVoltageSwing(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH4, XVPHY_GTHE3_DIFF_SWING_DP_L1);
XVphy_SetTxPreEmphasis(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH1, XVPHY_GTHE3_PREEMP_DP_L0);
XVphy_SetTxPreEmphasis(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH2, XVPHY_GTHE3_PREEMP_DP_L0);
XVphy_SetTxPreEmphasis(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH3, XVPHY_GTHE3_PREEMP_DP_L0);
XVphy_SetTxPreEmphasis(InstancePtr, QuadId,
XVPHY_CHANNEL_ID_CH4, XVPHY_GTHE3_PREEMP_DP_L0);
break;
default:
break;
}
XVphy_Set8b10b(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,
1);
XVphy_Set8b10b(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,
1);
XVphy_SetRxLpm(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,
1);
XVphy_PllInitialize(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
QpllRefClkSel, CpllRefClkSel, TxPllSelect, RxPllSelect);
InstancePtr->IsReady = (u32)(XIL_COMPONENT_IS_READY);
XVphy_LogWrite(InstancePtr, (XVPHY_LOG_EVT_INIT), 1);
return (XST_SUCCESS);
}
/******************************************************************************/
/**
* This function prints Vphy debug information on STDIO/Uart console.
*
* @param InstancePtr is a pointer to the Vphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_DpDebugInfo(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
XVphy_Channel *ChPtr;
XVphy_ChannelId CmnId;
u8 CpllDVal;
u8 QpllDVal;
u8 UsesQpll0;
ChPtr = &InstancePtr->Quads[QuadId].Plls[0];
if (XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId)) {
xil_printf("TX => CPLL / ");
}
else if (ChPtr->TxDataRefClkSel ==
XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK) {
UsesQpll0 = (TRUE);
CmnId = XVPHY_CHANNEL_ID_CMN0;
xil_printf("TX => QPLL1, ");
}
else if (ChPtr->TxDataRefClkSel ==
XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK) {
UsesQpll0 = (FALSE);
CmnId = XVPHY_CHANNEL_ID_CMN;
xil_printf("TX => QPLL, ");
}
else {
UsesQpll0 = (FALSE);
CmnId = XVPHY_CHANNEL_ID_CMN1;
xil_printf("TX => QPLL0, ");
}
if (XVphy_IsRxUsingCpll(InstancePtr, QuadId, ChId)) {
xil_printf("RX => CPLL\n\r");
}
else if (ChPtr->RxDataRefClkSel ==
XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK) {
UsesQpll0 = (TRUE);
CmnId = XVPHY_CHANNEL_ID_CMN0;
xil_printf("RX => QPLL0, \n\r");
}
else if (ChPtr->RxDataRefClkSel ==
XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK){
UsesQpll0 = (FALSE);
CmnId = XVPHY_CHANNEL_ID_CMN;
xil_printf("RX => QPLL, \n\r");
}
else {
UsesQpll0 = (FALSE);
CmnId = XVPHY_CHANNEL_ID_CMN1;
xil_printf("RX => QPLL1, \n\r");
}
xil_printf("RX state: ");
switch (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].RxState) {
case (XVPHY_GT_STATE_IDLE):
xil_printf("idle\n\r");
break;
case (XVPHY_GT_STATE_LOCK):
if (XVphy_IsRxUsingCpll(InstancePtr, QuadId, ChId)) {
xil_printf("CPLL lock\n\r");
}
else {
xil_printf("QPLL%d lock\n\r", (UsesQpll0 ? 0 : 1));
}
break;
case (XVPHY_GT_STATE_RESET):
xil_printf("GT reset\n\r");
break;
case (XVPHY_GT_STATE_READY):
xil_printf("ready\n\r");
break;
default:
xil_printf("unknown\n\r");
break;
}
xil_printf("TX state: ");
switch (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].TxState) {
case (XVPHY_GT_STATE_IDLE):
xil_printf("idle\n\r");
break;
case (XVPHY_GT_STATE_LOCK):
if (XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId)) {
xil_printf("CPLL lock\n\r");
}
else {
xil_printf("QPLL%d lock\n\r", (UsesQpll0 ? 0 : 1));
}
break;
case (XVPHY_GT_STATE_RESET):
xil_printf("GT reset\n\r");
break;
case (XVPHY_GT_STATE_ALIGN):
xil_printf("align\n\r");
break;
case (XVPHY_GT_STATE_READY):
xil_printf("ready\n\r");
break;
default:
xil_printf("unknown\n\r");
break;
}
if (XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId)) {
QpllDVal = ChPtr->RxOutDiv;
CpllDVal = ChPtr->TxOutDiv;
}
else {
CpllDVal = ChPtr->RxOutDiv;
QpllDVal = ChPtr->TxOutDiv;
}
xil_printf("\n\r");
xil_printf("QPLL settings\n\r");
xil_printf("-------------\n\r");
xil_printf("M : %d - N : %d - D : %d\n\r",
InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
PllParams.MRefClkDiv,
InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
PllParams.NFbDiv,
QpllDVal);
xil_printf("\n\r");
xil_printf("CPLL settings\n\r");
xil_printf("-------------\n\r");
xil_printf("M : %d - N1 : %d - N2 : %d - D : %d\n\r",
ChPtr->PllParams.MRefClkDiv,
ChPtr->PllParams.N1FbDiv,
ChPtr->PllParams.N2FbDiv,
CpllDVal);
xil_printf("\n\r");
print(" \n\r");
}

View file

@ -0,0 +1,94 @@
/*******************************************************************************
*
* 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 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 xvphy_hdmi.h
*
* The Xilinx Video PHY (VPHY) driver. This driver supports the Xilinx Video PHY
* IP core.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 vkd 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
#ifndef XVPHY_DP_H_
/* Prevent circular inclusions by using protection macros. */
#define XVPHY_DP_H_
/************************** Constant Definitions ******************************/
/* GTXE2. */
#define XVPHY_GTXE2_DIFF_SWING_DP_L0 0x03
#define XVPHY_GTXE2_DIFF_SWING_DP_L1 0x06
#define XVPHY_GTXE2_DIFF_SWING_DP_L2 0x09
#define XVPHY_GTXE2_DIFF_SWING_DP_L3 0x0F
#define XVPHY_GTXE2_PREEMP_DP_L0 0x00
#define XVPHY_GTXE2_PREEMP_DP_L1 0x0E
#define XVPHY_GTXE2_PREEMP_DP_L2 0x14
#define XVPHY_GTXE2_PREEMP_DP_L3 0x14
/* GTHE3. */
#define XVPHY_GTHE3_DIFF_SWING_DP_L0 0x03
#define XVPHY_GTHE3_DIFF_SWING_DP_L1 0x06
#define XVPHY_GTHE3_DIFF_SWING_DP_L2 0x09
#define XVPHY_GTHE3_DIFF_SWING_DP_L3 0x0F
#define XVPHY_GTHE3_PREEMP_DP_L0 0x00
#define XVPHY_GTHE3_PREEMP_DP_L1 0x0E
#define XVPHY_GTHE3_PREEMP_DP_L2 0x14
#define XVPHY_GTHE3_PREEMP_DP_L3 0x14
/* DP line rate coding. */
#define XVPHY_DP_LINK_BW_SET_162GBPS 0x06
#define XVPHY_DP_LINK_BW_SET_270GBPS 0x0A
#define XVPHY_DP_LINK_BW_SET_540GBPS 0x14
#define XVPHY_DP_LINK_RATE_HZ_162GBPS 1620000000LL
#define XVPHY_DP_LINK_RATE_HZ_270GBPS 2700000000LL
#define XVPHY_DP_LINK_RATE_HZ_540GBPS 5400000000LL
#define XVPHY_DP_REF_CLK_FREQ_HZ_162 162000000LL
#define XVPHY_DP_REF_CLK_FREQ_HZ_135 135000000LL
#define XVPHY_DP_REF_CLK_FREQ_HZ_81 81000000LL
#define XVPHY_DP_REF_CLK_FREQ_HZ_270 270000000LL
#endif /* XVPHY_HDMI_H_ */

View file

@ -0,0 +1,64 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-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 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.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xvphy.h"
/*
* The configuration table for devices
*/
XVphy_Config XVphy_ConfigTable[] =
{
{
XPAR_VID_PHY_CONTROLLER_0_DEVICE_ID,
XPAR_VID_PHY_CONTROLLER_0_BASEADDR,
XPAR_VID_PHY_CONTROLLER_0_TRANSCEIVER,
XPAR_VID_PHY_CONTROLLER_0_TX_NO_OF_CHANNELS,
XPAR_VID_PHY_CONTROLLER_0_RX_NO_OF_CHANNELS,
XPAR_VID_PHY_CONTROLLER_0_TX_PROTOCOL,
XPAR_VID_PHY_CONTROLLER_0_RX_PROTOCOL,
XPAR_VID_PHY_CONTROLLER_0_TX_REFCLK_SEL,
XPAR_VID_PHY_CONTROLLER_0_RX_REFCLK_SEL,
XPAR_VID_PHY_CONTROLLER_0_TX_PLL_SELECTION,
XPAR_VID_PHY_CONTROLLER_0_RX_PLL_SELECTION,
XPAR_VID_PHY_CONTROLLER_0_NIDRU,
XPAR_VID_PHY_CONTROLLER_0_NIDRU_REFCLK_SEL
}
};

View file

@ -0,0 +1,107 @@
/*******************************************************************************
*
* 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 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 xvphy_gt.h
*
* The Xilinx Video PHY (VPHY) driver. This driver supports the Xilinx Video PHY
* IP core.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
#ifndef XVPHY_GT_H_
/* Prevent circular inclusions by using protection macros. */
#define XVPHY_GT_H_
/******************************* Include Files ********************************/
#include "xvphy.h"
#include "xil_assert.h"
/****************************** Type Definitions ******************************/
typedef struct {
const u8 *M;
const u8 *N1;
const u8 *N2;
const u8 *D;
} XVphy_GtPllDivs;
typedef struct XVphy_GtConfigS {
u32 (*CfgSetCdr)(XVphy *, u8, XVphy_ChannelId);
u32 (*CheckPllOpRange)(XVphy *, u8, XVphy_ChannelId, u64);
u32 (*OutDivChReconfig)(XVphy *, u8, XVphy_ChannelId,
XVphy_DirectionType);
u32 (*ClkChReconfig)(XVphy *, u8, XVphy_ChannelId);
u32 (*ClkCmnReconfig)(XVphy *, u8, XVphy_ChannelId);
u32 (*RxChReconfig)(XVphy *, u8, XVphy_ChannelId);
u32 (*TxPllRefClkDiv1Reconfig)(XVphy *, u8, XVphy_ChannelId);
XVphy_GtPllDivs CpllDivs;
XVphy_GtPllDivs QpllDivs;
} XVphy_GtConfig;
/******************* Macros (Inline Functions) Definitions ********************/
#define XVphy_CfgSetCdr(Ip, ...) \
((Ip)->GtAdaptor->CfgSetCdr(Ip, __VA_ARGS__))
#define XVphy_CheckPllOpRange(Ip, ...) \
((Ip)->GtAdaptor->CheckPllOpRange(Ip, __VA_ARGS__))
#define XVphy_OutDivChReconfig(Ip, ...) \
((Ip)->GtAdaptor->OutDivChReconfig(Ip, __VA_ARGS__))
#define XVphy_ClkChReconfig(Ip, ...) \
((Ip)->GtAdaptor->ClkChReconfig(Ip, __VA_ARGS__))
#define XVphy_ClkCmnReconfig(Ip, ...) \
((Ip)->GtAdaptor->ClkCmnReconfig(Ip, __VA_ARGS__))
#define XVphy_RxChReconfig(Ip, ...) \
((Ip)->GtAdaptor->RxChReconfig(Ip, __VA_ARGS__))
#define XVphy_TxPllRefClkDiv1Reconfig(Ip, ...) \
((Ip)->GtAdaptor->TxPllRefClkDiv1Reconfig(Ip, __VA_ARGS__))
/*************************** Variable Declarations ****************************/
const XVphy_GtConfig Gtxe2Config;
const XVphy_GtConfig Gthe2Config;
const XVphy_GtConfig Gthe3Config;
#endif /* XVPHY_GT_H_ */

View file

@ -0,0 +1,686 @@
/*******************************************************************************
*
* 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 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 xvphy_gthe2.c
*
* Contains a minimal set of functions for the XVphy driver that allow access
* to all of the Video PHY core's functionality. See xvphy.h for a detailed
* description of the driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xvphy_gt.h"
#include "xstatus.h"
/**************************** Function Prototypes *****************************/
static u8 XVphy_MToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
static u16 XVphy_NToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 NId);
static u8 XVphy_DToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
static u8 XVphy_DrpEncodeQpllMCpllMN2(u8 AttrEncode);
static u8 XVphy_DrpEncodeCpllN1(u8 AttrEncode);
static u8 XVphy_DrpEncodeCpllTxRxD(u8 AttrEncode);
static u16 XVphy_DrpEncodeQpllN(u8 AttrEncode);
u32 XVphy_Gthe2CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
u32 XVphy_Gthe2CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u64 PllClkOutFreqHz);
u32 XVphy_Gthe2OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
u32 XVphy_Gthe2ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
u32 XVphy_Gthe2ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId CmnId);
u32 XVphy_Gthe2RxChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
/************************** Constant Definitions ******************************/
/* DRP register space. */
#define XVPHY_DRP_RXCDR_CFG(n) (0xA8 + n)
#define XVPHY_DRP_CPLL_PROG 0x5E
#define XVPHY_DRP_OUT_DIV_PROG 0x88
#define XVPHY_DRP_QPLL_CFG 0x32
#define XVPHY_DRP_QPLL_REFCLK_DIV_PROG 0x33
#define XVPHY_DRP_QPLL_FBDIV_PROG 0x36
#define XVPHY_DRP_QPLL_FBDIV_RATIO_PROG 0x37
#define XVPHY_DRP_RXCDR_CFG_WORD0 0xA8
#define XVPHY_DRP_RXCDR_CFG_WORD1 0xA9
#define XVPHY_DRP_RXCDR_CFG_WORD2 0xAA
#define XVPHY_DRP_RXCDR_CFG_WORD3 0xAB
#define XVPHY_DRP_RXCDR_CFG_WORD4 0xAC
/* PLL operating ranges. */
#define XVPHY_QPLL_LB_MIN 8000000000LL
#define XVPHY_QPLL_LB_MAX 13100000000LL
#define XVPHY_QPLL_UB_MIN 8000000000LL
#define XVPHY_QPLL_UB_MAX 13100000000LL
#define XVPHY_CPLL_MIN 1600000000LL
#define XVPHY_CPLL_MAX 5160000000LL
#define XVPHY_DIFF_SWING_DP_L0 0x03
#define XVPHY_DIFF_SWING_DP_L1 0x06
#define XVPHY_DIFF_SWING_DP_L2 0x09
#define XVPHY_DIFF_SWING_DP_L3 0x0F
#define XVPHY_PREEMP_DP_L0 0x00
#define XVPHY_PREEMP_DP_L1 0x0E
#define XVPHY_PREEMP_DP_L2 0x14
#define XVPHY_PREEMP_DP_L3 0x14
const u8 Gthe2CpllDivsM[] = {1, 2, 0};
const u8 Gthe2CpllDivsN1[] = {4, 5, 0};
const u8 Gthe2CpllDivsN2[] = {1, 2, 3, 4, 5, 0};
const u8 Gthe2CpllDivsD[] = {1, 2, 4, 8, 0};
const u8 Gthe2QpllDivsM[] = {4, 3, 2, 1, 0};
const u8 Gthe2QpllDivsN1[] = {16, 20, 32, 40, 64, 66, 80, 100, 0};
const u8 Gthe2QpllDivsN2[] = {1, 0};
const u8 Gthe2QpllDivsD[] = {8, 4, 2, 1, 0};
const XVphy_GtConfig Gthe2Config = {
.CfgSetCdr = XVphy_Gthe2CfgSetCdr,
.CheckPllOpRange = XVphy_Gthe2CheckPllOpRange,
.OutDivChReconfig = XVphy_Gthe2OutDivChReconfig,
.ClkChReconfig = XVphy_Gthe2ClkChReconfig,
.ClkCmnReconfig = XVphy_Gthe2ClkCmnReconfig,
.RxChReconfig = XVphy_Gthe2RxChReconfig,
.TxPllRefClkDiv1Reconfig = NULL,
.CpllDivs = {
.M = Gthe2CpllDivsM,
.N1 = Gthe2CpllDivsN1,
.N2 = Gthe2CpllDivsN2,
.D = Gthe2CpllDivsD,
},
.QpllDivs = {
.M = Gthe2QpllDivsM,
.N1 = Gthe2QpllDivsN1,
.N2 = Gthe2QpllDivsN2,
.D = Gthe2QpllDivsD,
},
};
/**************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* This function will set the clock and data recovery (CDR) values for a given
* channel.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe2CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
XVphy_Channel *ChPtr;
/* Set CDR values only for CPLLs. */
if ((ChId < XVPHY_CHANNEL_ID_CH1) || (ChId > XVPHY_CHANNEL_ID_CH4)) {
return XST_FAILURE;
}
ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
/* Update the RXCDR_CFG2 settings. */
ChPtr->PllParams.Cdr[0] = 0x0020;
ChPtr->PllParams.Cdr[1] = 0x07FE;
ChPtr->PllParams.Cdr[3] = (ChPtr->RxOutDiv == 1) ? 0xC208 : 0xC220;
ChPtr->PllParams.Cdr[4] = 0x0018;
/* RxOutDiv = 1 => Cdr[2] = 0x2000
* RxOutDiv = 2 => Cdr[2] = 0x1000
* RxOutDiv = 4 => Cdr[2] = 0x0800
* RxOutDiv = 8 => Cdr[2] = 0x0400 */
u8 RxOutDiv = ChPtr->RxOutDiv;
ChPtr->PllParams.Cdr[2] = 0x2000;
while (RxOutDiv >>= 1) {
ChPtr->PllParams.Cdr[2] >>= 1;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will check if a given PLL output frequency is within the
* operating range of the PLL for the GT type.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param PllClkOutFreqHz is the frequency to check.
*
* @return
* - XST_SUCCESS if the frequency resides within the PLL's range.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe2CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u64 PllClkOutFreqHz)
{
u32 Status = XST_FAILURE;
if ((ChId == XVPHY_CHANNEL_ID_CMN0) &&
(XVPHY_QPLL_LB_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_QPLL_LB_MAX)) {
Status = XST_SUCCESS;
}
else if ((ChId >= XVPHY_CHANNEL_ID_CH1) &&
(ChId <= XVPHY_CHANNEL_ID_CH4) &&
(XVPHY_CPLL_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_CPLL_MAX)) {
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
* This function will set the output divider logic for a given channel.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param Dir is an indicator for RX or TX.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe2OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for TX/RX dividers. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x88);
if (Dir == XVPHY_DIR_RX) {
/* Mask out RX_OUT_DIV. */
DrpVal &= ~0x07;
/* Set RX_OUT_DIV. */
WriteVal = XVphy_DToDrpEncoding(InstancePtr, QuadId, ChId,
XVPHY_DIR_RX);
DrpVal |= WriteVal;
}
else {
/* Mask out TX_OUT_DIV. */
DrpVal &= ~0x70;
/* Set TX_OUT_DIV. */
WriteVal = XVphy_DToDrpEncoding(InstancePtr, QuadId, ChId,
XVPHY_DIR_TX);
DrpVal |= (WriteVal << 4);
}
/* Write new DRP register value for TX/RX dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x88, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel clock settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe2ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for PLL dividers. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x5E);
/* Mask out clock divider bits. */
DrpVal &= ~(0x1FFF);
/* Set CPLL_FBDIV. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 2);
DrpVal |= WriteVal;
/* Set CPLL_FBDIV_45. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 1);
DrpVal |= (WriteVal << 7);
/* Set CPLL_REFCLKDIV. */
WriteVal = XVphy_MToDrpEncoding(InstancePtr, QuadId, ChId);
DrpVal |= (WriteVal << 8);
/* Write new DRP register value for PLL dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x5E, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the common channel clock settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param CmnId is the common channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe2ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId CmnId)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for QPLL_CFG. */
DrpVal = 0x01C1;
/* Mask out QPLL_CFG. */
DrpVal &= ~(1 << 6);
/* Set QPLL_CFG lower/upper band setting to hardware. */
WriteVal = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
PllParams.IsLowerBand;
DrpVal |= (WriteVal << 6);
/* Write new DRP register value for QPLL_CFG. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x32, DrpVal);
/* Obtain current DRP register value for QPLL_REFCLK_DIV. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x33);
DrpVal |= 0x0068;
/* Mask out QPLL_REFCLK_DIV. */
DrpVal &= ~(0xF800);
/* Set QPLL_REFCLK_DIV. */
WriteVal = XVphy_MToDrpEncoding(InstancePtr, QuadId, CmnId);
DrpVal |= (WriteVal << 11);
/* Write new DRP register value for QPLL_REFCLK_DIV. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x33, DrpVal);
/* Obtain current DRP register value for QPLL_FBDIV. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x36);
/* Mask out QPLL_FBDIV. */
DrpVal &= ~(0x3FFF);
/* Set QPLL_FBDIV. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, CmnId, 0);
DrpVal |= WriteVal;
/* Write new DRP register value for QPLL_FBDIV. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x36, DrpVal);
/* Obtain current DRP register value for QPLL_FBDIV_RATIO. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x37);
/* Mask out QPLL_FBDIV_RATIO. */
DrpVal &= ~(1 << 6);
/* Set QPLL_FBDIV_RATIO. */
if (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].PllParams.
NFbDiv != 66) {
DrpVal |= (1 << 6);
}
/* Write new DRP register value for QPLL_FBDIV_RATIO. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x37, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel's RX settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe2RxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
XVphy_Channel *ChPtr;
u16 DrpVal;
u8 CfgIndex;
ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
/* RXCDR_CFG(CfgIndex) */
for (CfgIndex = 0; CfgIndex < 5; CfgIndex++) {
DrpVal = ChPtr->PllParams.Cdr[CfgIndex];
if (!DrpVal) {
/* Don't modify RX_CDR configuration. */
continue;
}
XVphy_DrpWrite(InstancePtr, QuadId, ChId,
XVPHY_DRP_RXCDR_CFG(CfgIndex), DrpVal);
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will translate the configured M value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return The DRP encoding for M.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_MToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u8 MRefClkDiv;
u8 DrpEncode;
if ((ChId >= XVPHY_CHANNEL_ID_CH1) && (ChId <= XVPHY_CHANNEL_ID_CH4)) {
MRefClkDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)]
.PllParams.MRefClkDiv;
}
else if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
(ChId == XVPHY_CHANNEL_ID_CMN1)) {
MRefClkDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)]
.PllParams.MRefClkDiv;
}
else {
MRefClkDiv = 0;
}
DrpEncode = XVphy_DrpEncodeQpllMCpllMN2(MRefClkDiv);
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured D value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param Dir is an indicator for RX or TX.
*
* @return The DRP encoding for D.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir)
{
u8 OutDiv;
u8 DrpEncode;
OutDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
OutDiv[Dir];
DrpEncode = XVphy_DrpEncodeCpllTxRxD(OutDiv);
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured N1/N2 value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param NId specified to operate on N1 (if == 1) or N2 (if == 2).
*
* @return The DRP encoding for N1/N2.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_NToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 NId)
{
u8 NFbDiv;
u16 DrpEncode;
if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
(ChId == XVPHY_CHANNEL_ID_CMN1)) {
NFbDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
PllParams.NFbDiv;
DrpEncode = XVphy_DrpEncodeQpllN(NFbDiv);
}
else if (NId == 1) {
NFbDiv = InstancePtr->Quads[QuadId].Plls[
XVPHY_CH2IDX(ChId)].PllParams.N1FbDiv;
DrpEncode = XVphy_DrpEncodeCpllN1(NFbDiv);
}
else {
NFbDiv = InstancePtr->Quads[QuadId].Plls[
XVPHY_CH2IDX(ChId)].PllParams.N2FbDiv;
DrpEncode = XVphy_DrpEncodeQpllMCpllMN2(NFbDiv);
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured QPLL's M or CPLL's M or N2
* values to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the QPLL's M or CPLL's M or N2 values.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeQpllMCpllMN2(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 1:
DrpEncode = 16;
break;
case 6:
DrpEncode = 5;
break;
case 10:
DrpEncode = 7;
break;
case 12:
DrpEncode = 13;
break;
case 20:
DrpEncode = 15;
break;
case 2:
case 3:
case 4:
case 5:
case 8:
case 16:
DrpEncode = (AttrEncode - 2);
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CPLL's N1 value to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CPLL's N1 value.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeCpllN1(u8 AttrEncode)
{
u8 DrpEncode;
DrpEncode = AttrEncode - 4;
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CPLL's D values to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CPLL's D value.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeCpllTxRxD(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 1:
DrpEncode = 0;
break;
case 2:
DrpEncode = 1;
break;
case 4:
DrpEncode = 2;
break;
case 8:
DrpEncode = 3;
break;
case 16:
DrpEncode = 4;
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured QPLL's N value to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the QPLL's N value.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_DrpEncodeQpllN(u8 AttrEncode)
{
u16 DrpEncode;
switch (AttrEncode) {
case 16:
DrpEncode = 0x020;
break;
case 20:
DrpEncode = 0x030;
break;
case 32:
DrpEncode = 0x060;
break;
case 40:
DrpEncode = 0x080;
break;
case 64:
DrpEncode = 0x0E0;
break;
case 66:
DrpEncode = 0x140;
break;
case 80:
DrpEncode = 0x120;
break;
case 100:
DrpEncode = 0x170;
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}

View file

@ -0,0 +1,865 @@
/*******************************************************************************
*
* 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 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 xvphy_gthe3.c
*
* Contains a minimal set of functions for the XVphy driver that allow access
* to all of the Video PHY core's functionality. See xvphy.h for a detailed
* description of the driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xvphy_gt.h"
#include "xstatus.h"
/**************************** Function Prototypes *****************************/
static u8 XVphy_MToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
static u16 XVphy_NToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 NId);
static u8 XVphy_DToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
static u8 XVphy_DrpEncodeQpllMCpllMN2(u8 AttrEncode);
static u8 XVphy_DrpEncodeCpllN1(u8 AttrEncode);
static u8 XVphy_DrpEncodeCpllTxRxD(u8 AttrEncode);
static u16 XVphy_DrpEncodeQpllN(u8 AttrEncode);
static u8 Xvphy_DrpEncodeRxDataWidth(u8 AttrEncode);
static u8 Xvphy_DrpEncodeRxIntDataWidth(u8 AttrEncode);
static u16 XVphy_DrpEncodeClk25(u32 RefClkFreqHz);
u32 XVphy_Gthe3CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
u32 XVphy_Gthe3CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u64 PllClkOutFreqHz);
u32 XVphy_Gthe3OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
u32 XVphy_Gthe3ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
u32 XVphy_Gthe3ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId CmnId);
u32 XVphy_Gthe3RxChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
u32 XVphy_Gthe3TxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
/************************** Constant Definitions ******************************/
/* DRP register space. */
#define XVPHY_DRP_RXCDR_CFG(n) (0x0E + n)
#define XVPHY_DRP_CPLL_FBDIV 0x28
#define XVPHY_DRP_CPLL_REFCLK_DIV 0x2A
#define XVPHY_DRP_RXOUT_DIV 0x63
#define XVPHY_DRP_TXCLK25 0x7A
#define XVPHY_DRP_TXOUT_DIV 0x7C
#define XVPHY_DRP_QPLL1_FBDIV 0x94
#define XVPHY_DRP_QPLL1_REFCLK_DIV 0x98
#define XVPHY_DRP_RXCDR_CFG_WORD0 0x0E
#define XVPHY_DRP_RXCDR_CFG_WORD1 0x0F
#define XVPHY_DRP_RXCDR_CFG_WORD2 0x10
#define XVPHY_DRP_RXCDR_CFG_WORD3 0x11
#define XVPHY_DRP_RXCDR_CFG_WORD4 0x12
/* PLL operating ranges. */
#define XVPHY_QPLL0_MIN 9800000000LL
#define XVPHY_QPLL0_MAX 16300000000LL
#define XVPHY_QPLL1_MIN 8000000000LL
#define XVPHY_QPLL1_MAX 13000000000LL
#define XVPHY_CPLL_MIN 2000000000LL
#define XVPHY_CPLL_MAX 6250000000LL
const u8 Gthe3CpllDivsM[] = {1, 2, 0};
const u8 Gthe3CpllDivsN1[] = {4, 5, 0};
const u8 Gthe3CpllDivsN2[] = {1, 2, 3, 4, 5, 0};
const u8 Gthe3CpllDivsD[] = {1, 2, 4, 8, 0};
const u8 Gthe3QpllDivsM[] = {4, 3, 2, 1, 0};
const u8 Gthe3QpllDivsN1[] = {16, 20, 32, 40, 64, 66, 80, 100, 160, 0};
const u8 Gthe3QpllDivsN2[] = {1, 0};
const u8 Gthe3QpllDivsD[] = {16, 8, 4, 2, 1, 0};
const XVphy_GtConfig Gthe3Config = {
.CfgSetCdr = XVphy_Gthe3CfgSetCdr,
.CheckPllOpRange = XVphy_Gthe3CheckPllOpRange,
.OutDivChReconfig = XVphy_Gthe3OutDivChReconfig,
.ClkChReconfig = XVphy_Gthe3ClkChReconfig,
.ClkCmnReconfig = XVphy_Gthe3ClkCmnReconfig,
.RxChReconfig = XVphy_Gthe3RxChReconfig,
.TxPllRefClkDiv1Reconfig = XVphy_Gthe3TxPllRefClkDiv1Reconfig,
.CpllDivs = {
.M = Gthe3CpllDivsM,
.N1 = Gthe3CpllDivsN1,
.N2 = Gthe3CpllDivsN2,
.D = Gthe3CpllDivsD,
},
.QpllDivs = {
.M = Gthe3QpllDivsM,
.N1 = Gthe3QpllDivsN1,
.N2 = Gthe3QpllDivsN2,
.D = Gthe3QpllDivsD,
},
};
/**************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* This function will set the clock and data recovery (CDR) values for a given
* channel.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
u32 PllClkInFreqHz;
XVphy_Channel *ChPtr;
u32 Status = XST_SUCCESS;
/* Set CDR values only for CPLLs. */
if ((ChId < XVPHY_CHANNEL_ID_CH1) || (ChId > XVPHY_CHANNEL_ID_CH4)) {
return XST_FAILURE;
}
/* This is DP specific. */
ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
ChPtr->PllParams.Cdr[0] = 0x0000;
ChPtr->PllParams.Cdr[1] = 0x0000;
ChPtr->PllParams.Cdr[3] = 0x0000;
ChPtr->PllParams.Cdr[4] = 0x0000;
if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_DP) {
PllClkInFreqHz = XVphy_GetQuadRefClkFreq(InstancePtr, QuadId,
ChPtr->CpllRefClkSel);
if ((ChPtr->RxOutDiv == 1) && (PllClkInFreqHz == 270000000)) {
ChPtr->PllParams.Cdr[2] = 0x0766;
}
else if ((ChPtr->RxOutDiv == 2) &&
(PllClkInFreqHz == 135000000)) {
ChPtr->PllParams.Cdr[2] = 0x0756;
}
/* RBR does not use DP159 forwarded clock and expects 162MHz. */
else if (ChPtr->RxOutDiv == 2) {
ChPtr->PllParams.Cdr[2] = 0x0721;
}
else {
Status = XST_FAILURE;
}
}
else if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
/* RxOutDiv = 1 => Cdr[2] = 0x07E4
* RxOutDiv = 2 => Cdr[2] = 0x07D4
* RxOutDiv = 4 => Cdr[2] = 0x07C4
* RxOutDiv = 8 => Cdr[2] = 0x07B4
* RxOutDiv = 16 => Cdr[2] = 0x07A4 */
ChPtr->PllParams.Cdr[2] = 0x07E4;
while (ChPtr->RxOutDiv >>= 1) {
ChPtr->PllParams.Cdr[2] -= 0x10;
}
/* Restore RxOutDiv. */
ChPtr->RxOutDiv = 1 << ((0x7E4 - ChPtr->PllParams.Cdr[2]) >> 4);
}
else {
Status = XST_FAILURE;
}
return Status;
}
/*****************************************************************************/
/**
* This function will check if a given PLL output frequency is within the
* operating range of the PLL for the GT type.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param PllClkOutFreqHz is the frequency to check.
*
* @return
* - XST_SUCCESS if the frequency resides within the PLL's range.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u64 PllClkOutFreqHz)
{
u32 Status = XST_FAILURE;
if (((ChId == XVPHY_CHANNEL_ID_CMN0) &&
(XVPHY_QPLL0_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_QPLL0_MAX)) ||
((ChId == XVPHY_CHANNEL_ID_CMN1) &&
(XVPHY_QPLL1_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_QPLL1_MAX)) ||
((ChId >= XVPHY_CHANNEL_ID_CH1) &&
(ChId <= XVPHY_CHANNEL_ID_CH4) &&
(XVPHY_CPLL_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_CPLL_MAX))) {
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
* This function will set the output divider logic for a given channel.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param Dir is an indicator for RX or TX.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir)
{
u16 DrpVal;
u16 WriteVal;
if (Dir == XVPHY_DIR_RX) {
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x63);
/* Mask out RX_OUT_DIV. */
DrpVal &= ~0x07;
/* Set RX_OUT_DIV. */
WriteVal = XVphy_DToDrpEncoding(InstancePtr, QuadId, ChId,
XVPHY_DIR_RX);
DrpVal |= WriteVal;
/* Write new DRP register value for RX dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x63, DrpVal);
}
else {
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x7C);
/* Mask out TX_OUT_DIV. */
DrpVal &= ~0x700;
/* Set TX_OUT_DIV. */
WriteVal = XVphy_DToDrpEncoding(InstancePtr, QuadId, ChId,
XVPHY_DIR_TX);
DrpVal |= (WriteVal << 8);
/* Write new DRP register value for RX dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x7C, DrpVal);
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel clock settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for PLL dividers. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x28);
/* Mask out clock divider bits. */
DrpVal &= ~(0xFF80);
/* Set CPLL_FBDIV. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 2);
DrpVal |= (WriteVal << 8);
/* Set CPLL_FBDIV_45. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 1);
DrpVal |= (WriteVal << 7);
/* Write new DRP register value for PLL dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x28, DrpVal);
/* Write CPLL Ref Clk Div. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x2A);
/* Mask out clock divider bits. */
DrpVal &= ~(0xF800);
/* Set CPLL_REFCLKDIV. */
WriteVal = XVphy_MToDrpEncoding(InstancePtr, QuadId, ChId);
DrpVal |= (WriteVal << 11);
/* Write new DRP register value for PLL dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x2A, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the common channel clock settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param CmnId is the common channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId CmnId)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for QPLLx_FBDIV. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x14 : 0x94);
/* Mask out QPLLx_FBDIV. */
DrpVal &= ~(0xFF);
/* Set QPLLx_FBDIV. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, CmnId, 0);
DrpVal |= WriteVal;
/* Write new DRP register value for QPLLx_FBDIV. */
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x14 : 0x94, DrpVal);
/* Obtain current DRP register value for QPLLx_REFCLK_DIV. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x18 : 0x98);
/* Mask out QPLLx_REFCLK_DIV. */
DrpVal &= ~(0xF80);
/* Set QPLLx_REFCLK_DIV. */
WriteVal = XVphy_MToDrpEncoding(InstancePtr, QuadId, CmnId);
DrpVal |= (WriteVal << 7);
/* Write new DRP register value for QPLLx_REFCLK_DIV. */
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x18 : 0x98, DrpVal);
if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
/* QPLLx_LPF */
switch (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
PllParams.NFbDiv) {
case 40:
DrpVal = 0x3FF;
break;
case 80:
DrpVal = 0x3F4;
break;
case 160:
DrpVal = 0x3FC;
break;
default:
DrpVal = 0x3FE;
break;
}
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x19 : 0x99, DrpVal);
/* QPLLx_CP */
switch (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
PllParams.NFbDiv) {
case 160:
DrpVal = 0x1FF;
break;
default:
DrpVal = (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x1F : 0x7F;
break;
}
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x16 : 0x96, DrpVal);
/* QPLLx_CFG4 */
DrpVal = 0x1B;
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x30 : 0xB0, DrpVal);
/* QPLLx_LOCK_CFG */
DrpVal = 0x25E8;
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x12 : 0x92, DrpVal);
/* QPLLx_LOCK_CFG_G3 */
XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
(CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x1D : 0x9D, DrpVal);
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel's RX settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3RxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
XVphy_Channel *ChPtr;
u16 DrpVal;
u16 WriteVal;
u8 CfgIndex;
ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
/* RXCDR_CFG(CfgIndex) */
for (CfgIndex = 0; CfgIndex < 5; CfgIndex++) {
DrpVal = ChPtr->PllParams.Cdr[CfgIndex];
if (!DrpVal) {
/* Don't modify RX_CDR configuration. */
continue;
}
XVphy_DrpWrite(InstancePtr, QuadId, ChId,
XVPHY_DRP_RXCDR_CFG(CfgIndex), DrpVal);
}
if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x66);
DrpVal &= ~(0x3);
WriteVal = Xvphy_DrpEncodeRxIntDataWidth(ChPtr->RxIntDataWidth);
DrpVal |= WriteVal;
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x66, DrpVal);
/* RX_DATA_WIDTH */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x03);
DrpVal &= ~(0x1E0);
WriteVal = Xvphy_DrpEncodeRxDataWidth(ChPtr->RxDataWidth);
WriteVal <<= 5;
DrpVal |= WriteVal;
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x03, DrpVal);
}
return (XST_SUCCESS);
}
/*****************************************************************************/
/**
* This function will configure the channel's TX CLKDIV1 settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gthe3TxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u16 DrpVal;
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, XVPHY_DRP_TXCLK25);
DrpVal &= ~(0xF800);
DrpVal |= XVphy_DrpEncodeClk25(InstancePtr->HdmiTxRefClkHz) << 11;
return XVphy_DrpWrite(InstancePtr, QuadId, ChId, XVPHY_DRP_TXCLK25,
DrpVal);
}
/*****************************************************************************/
/**
* This function will translate the configured M value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return The DRP encoding for M.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_MToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u8 MRefClkDiv;
u8 DrpEncode;
if ((ChId >= XVPHY_CHANNEL_ID_CH1) && (ChId <= XVPHY_CHANNEL_ID_CH4)) {
MRefClkDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)]
.PllParams.MRefClkDiv;
}
else if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
(ChId == XVPHY_CHANNEL_ID_CMN1)) {
MRefClkDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)]
.PllParams.MRefClkDiv;
}
else {
MRefClkDiv = 0;
}
DrpEncode = XVphy_DrpEncodeQpllMCpllMN2(MRefClkDiv);
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured D value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param Dir is an indicator for RX or TX.
*
* @return The DRP encoding for D.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir)
{
u8 OutDiv;
u8 DrpEncode;
OutDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
OutDiv[Dir];
DrpEncode = XVphy_DrpEncodeCpllTxRxD(OutDiv);
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured N1/N2 value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param NId specified to operate on N1 (if == 1) or N2 (if == 2).
*
* @return The DRP encoding for N1/N2.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_NToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 NId)
{
u8 NFbDiv;
u16 DrpEncode;
if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
(ChId == XVPHY_CHANNEL_ID_CMN1)) {
NFbDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
PllParams.NFbDiv;
DrpEncode = XVphy_DrpEncodeQpllN(NFbDiv);
}
else if (NId == 1) {
NFbDiv = InstancePtr->Quads[QuadId].Plls[
XVPHY_CH2IDX(ChId)].PllParams.N1FbDiv;
DrpEncode = XVphy_DrpEncodeCpllN1(NFbDiv);
}
else {
NFbDiv = InstancePtr->Quads[QuadId].Plls[
XVPHY_CH2IDX(ChId)].PllParams.N2FbDiv;
DrpEncode = XVphy_DrpEncodeQpllMCpllMN2(NFbDiv);
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured QPLL's M or CPLL's M or N2
* values to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the QPLL's M or CPLL's M or N2 values.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeQpllMCpllMN2(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 1:
DrpEncode = 16;
break;
case 6:
DrpEncode = 5;
break;
case 10:
DrpEncode = 7;
break;
case 12:
DrpEncode = 13;
break;
case 20:
DrpEncode = 15;
break;
case 2:
case 3:
case 4:
case 5:
case 8:
case 16:
DrpEncode = (AttrEncode - 2);
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CPLL's N1 value to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CPLL's N1 value.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeCpllN1(u8 AttrEncode)
{
u8 DrpEncode;
DrpEncode = AttrEncode - 4;
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CPLL's D values to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CPLL's D value.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeCpllTxRxD(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 1:
DrpEncode = 0;
break;
case 2:
DrpEncode = 1;
break;
case 4:
DrpEncode = 2;
break;
case 8:
DrpEncode = 3;
break;
case 16:
DrpEncode = 4;
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured QPLL's N value to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the QPLL's N value.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_DrpEncodeQpllN(u8 AttrEncode)
{
u16 DrpEncode;
if ((16 <= AttrEncode) && (AttrEncode <= 160)) {
DrpEncode = AttrEncode - 2;
}
else {
DrpEncode = 0xFF;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured RXDATAWIDTH to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the RXDATAWIDTH value.
*
* @note None.
*
******************************************************************************/
static u8 Xvphy_DrpEncodeRxDataWidth(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 16:
DrpEncode = 2;
break;
case 20:
DrpEncode = 3;
break;
case 32:
DrpEncode = 4;
break;
case 40:
DrpEncode = 5;
break;
case 64:
DrpEncode = 6;
break;
case 80:
DrpEncode = 7;
break;
case 128:
DrpEncode = 8;
break;
case 160:
DrpEncode = 9;
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured RXINTDATAWIDTH to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the RXINTDATAWIDTH value.
*
* @note None.
*
******************************************************************************/
static u8 Xvphy_DrpEncodeRxIntDataWidth(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 2:
DrpEncode = 0;
break;
case 4:
DrpEncode = 1;
break;
default:
DrpEncode = 2;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CLK25 to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CLK25 value.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_DrpEncodeClk25(u32 RefClkFreqHz)
{
u16 DrpEncode;
u32 RefClkFreqMHz = RefClkFreqHz / 1000000;
DrpEncode = ((RefClkFreqMHz / 25) +
(((RefClkFreqMHz % 25) > 0) ? 1 : 0)) - 1;
return DrpEncode;
}

View file

@ -0,0 +1,768 @@
/*******************************************************************************
*
* 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 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 xvphy_gtxe2.c
*
* Contains a minimal set of functions for the XVphy driver that allow access
* to all of the Video PHY core's functionality. See xvphy.h for a detailed
* description of the driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xvphy_gt.h"
#include "xstatus.h"
/**************************** Function Prototypes *****************************/
static u8 XVphy_MToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
static u16 XVphy_NToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 NId);
static u8 XVphy_DToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
static u8 XVphy_DrpEncodeQpllMCpllMN2(u8 AttrEncode);
static u8 XVphy_DrpEncodeCpllN1(u8 AttrEncode);
static u8 XVphy_DrpEncodeCpllTxRxD(u8 AttrEncode);
static u16 XVphy_DrpEncodeQpllN(u8 AttrEncode);
static u16 XVphy_DrpEncodeClk25(u32 RefClkFreqHz);
u32 XVphy_Gtxe2CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
u32 XVphy_Gtxe2CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u64 PllClkOutFreqHz);
u32 XVphy_Gtxe2OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir);
u32 XVphy_Gtxe2ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
u32 XVphy_Gtxe2ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId CmnId);
u32 XVphy_Gtxe2RxChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
u32 XVphy_Gtxe2TxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
/************************** Constant Definitions ******************************/
/* DRP register space. */
#define XVPHY_DRP_RXCDR_CFG(n) (0xA8 + n)
#define XVPHY_DRP_RXDATAWIDTH 0x11
#define XVPHY_DRP_CPLL_PROG 0x5E
#define XVPHY_DRP_OUT_DIV_PROG 0x88
#define XVPHY_DRP_QPLL_CFG 0x32
#define XVPHY_DRP_QPLL_REFCLK_DIV_PROG 0x33
#define XVPHY_DRP_QPLL_FBDIV_PROG 0x36
#define XVPHY_DRP_QPLL_FBDIV_RATIO_PROG 0x37
#define XVPHY_DRP_TXCLK25 0x6A
#define XVPHY_DRP_RXCDR_CFG_WORD0 0xA8
#define XVPHY_DRP_RXCDR_CFG_WORD1 0xA9
#define XVPHY_DRP_RXCDR_CFG_WORD2 0xAA
#define XVPHY_DRP_RXCDR_CFG_WORD3 0xAB
#define XVPHY_DRP_RXCDR_CFG_WORD4 0xAC
/* PLL operating ranges. */
#define XVPHY_QPLL_LB_MIN 5930000000LL
#define XVPHY_QPLL_LB_MAX 8000000000LL
#define XVPHY_QPLL_UB_MIN 9800000000LL
#define XVPHY_QPLL_UB_MAX 12500000000LL
#define XVPHY_CPLL_MIN 1600000000LL
#define XVPHY_CPLL_MAX 3300000000LL
const u8 Gtxe2CpllDivsM[] = {1, 2, 0};
const u8 Gtxe2CpllDivsN1[] = {4, 5, 0};
const u8 Gtxe2CpllDivsN2[] = {1, 2, 3, 4, 5, 0};
const u8 Gtxe2CpllDivsD[] = {1, 2, 4, 8, 0};
const u8 Gtxe2QpllDivsM[] = {4, 3, 2, 1, 0};
const u8 Gtxe2QpllDivsN1[] = {16, 20, 32, 40, 64, 66, 80, 100, 0};
const u8 Gtxe2QpllDivsN2[] = {1, 0};
const u8 Gtxe2QpllDivsD[] = {8, 4, 2, 1, 0};
const XVphy_GtConfig Gtxe2Config = {
.CfgSetCdr = XVphy_Gtxe2CfgSetCdr,
.CheckPllOpRange = XVphy_Gtxe2CheckPllOpRange,
.OutDivChReconfig = XVphy_Gtxe2OutDivChReconfig,
.ClkChReconfig = XVphy_Gtxe2ClkChReconfig,
.ClkCmnReconfig = XVphy_Gtxe2ClkCmnReconfig,
.RxChReconfig = XVphy_Gtxe2RxChReconfig,
.TxPllRefClkDiv1Reconfig = XVphy_Gtxe2TxPllRefClkDiv1Reconfig,
.CpllDivs = {
.M = Gtxe2CpllDivsM,
.N1 = Gtxe2CpllDivsN1,
.N2 = Gtxe2CpllDivsN2,
.D = Gtxe2CpllDivsD,
},
.QpllDivs = {
.M = Gtxe2QpllDivsM,
.N1 = Gtxe2QpllDivsN1,
.N2 = Gtxe2QpllDivsN2,
.D = Gtxe2QpllDivsD,
},
};
/**************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* This function will set the clock and data recovery (CDR) values for a given
* channel.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
XVphy_Channel *ChPtr;
/* Set CDR values only for CPLLs. */
if ((ChId < XVPHY_CHANNEL_ID_CH1) || (ChId > XVPHY_CHANNEL_ID_CH4)) {
return XST_FAILURE;
}
ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
ChPtr->PllParams.Cdr[0] = 0x0020;
ChPtr->PllParams.Cdr[2] = 0x23FF;
ChPtr->PllParams.Cdr[3] =
(InstancePtr->Config.RxProtocol != XVPHY_PROTOCOL_HDMI) ?
0x0000 : 0x8000;
ChPtr->PllParams.Cdr[4] = 0x0003;
/* Update the RXCDR_CFG2 settings. */
switch (ChPtr->RxOutDiv) {
case 1:
ChPtr->PllParams.Cdr[1] = (InstancePtr->Config.RxProtocol ==
XVPHY_PROTOCOL_DP) ? 0x2040 : 0x1040;
break;
case 2:
ChPtr->PllParams.Cdr[1] = 0x4020;
break;
case 4:
ChPtr->PllParams.Cdr[1] = 0x4010;
break;
case 8:
ChPtr->PllParams.Cdr[1] = 0x4008;
break;
default:
ChPtr->PllParams.Cdr[1] = 0x4010;
break;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will check if a given PLL output frequency is within the
* operating range of the PLL for the GT type.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param PllClkOutFreqHz is the frequency to check.
*
* @return
* - XST_SUCCESS if the frequency resides within the PLL's range.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u64 PllClkOutFreqHz)
{
u32 Status = XST_FAILURE;
if ((ChId == XVPHY_CHANNEL_ID_CMN0) &&
((XVPHY_QPLL_LB_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_QPLL_LB_MAX))) {
InstancePtr->Quads[QuadId].Cmn0.PllParams.IsLowerBand = 1;
Status = XST_SUCCESS;
}
else if ((ChId == XVPHY_CHANNEL_ID_CMN0) &&
((XVPHY_QPLL_UB_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_QPLL_UB_MAX) &&
(InstancePtr->Config.RxProtocol !=
XVPHY_PROTOCOL_HDMI))) {
InstancePtr->Quads[QuadId].Cmn0.PllParams.IsLowerBand = 0;
Status = XST_SUCCESS;
}
else if ((ChId >= XVPHY_CHANNEL_ID_CH1) &&
(ChId <= XVPHY_CHANNEL_ID_CH4) &&
(XVPHY_CPLL_MIN <= PllClkOutFreqHz) &&
(PllClkOutFreqHz <= XVPHY_CPLL_MAX)) {
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
* This function will set the output divider logic for a given channel.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param Dir is an indicator for RX or TX.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for TX/RX dividers. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x88);
if (Dir == XVPHY_DIR_RX) {
/* Mask out RX_OUT_DIV. */
DrpVal &= ~0x07;
/* Set RX_OUT_DIV. */
WriteVal = XVphy_DToDrpEncoding(InstancePtr, QuadId, ChId,
XVPHY_DIR_RX);
DrpVal |= WriteVal;
}
else {
/* Mask out TX_OUT_DIV. */
DrpVal &= ~0x70;
/* Set TX_OUT_DIV. */
WriteVal = XVphy_DToDrpEncoding(InstancePtr, QuadId, ChId,
XVPHY_DIR_TX);
DrpVal |= (WriteVal << 4);
}
/* Write new DRP register value for TX/RX dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x88, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel clock settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for PLL dividers. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x5E);
/* Mask out clock divider bits. */
DrpVal &= ~(0x1FFF);
/* Set CPLL_FBDIV. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 2);
DrpVal |= WriteVal;
/* Set CPLL_FBDIV_45. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 1);
DrpVal |= (WriteVal << 7);
/* Set CPLL_REFCLKDIV. */
WriteVal = XVphy_MToDrpEncoding(InstancePtr, QuadId, ChId);
DrpVal |= (WriteVal << 8);
/* Write new DRP register value for PLL dividers. */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x5E, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the common channel clock settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param CmnId is the common channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId CmnId)
{
u16 DrpVal;
u16 WriteVal;
/* Obtain current DRP register value for QPLL_CFG. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x32);
/* Mask out QPLL_CFG. */
DrpVal &= ~(1 << 6);
/* Set QPLL_CFG lower/upper band setting to hardware. */
WriteVal = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
PllParams.IsLowerBand;
DrpVal |= (WriteVal << 6);
/* Write new DRP register value for QPLL_CFG. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x32, DrpVal);
/* Obtain current DRP register value for QPLL_REFCLK_DIV. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x33);
/* Mask out QPLL_REFCLK_DIV. */
DrpVal &= ~(0xF800);
/* Set QPLL_REFCLK_DIV. */
WriteVal = XVphy_MToDrpEncoding(InstancePtr, QuadId, CmnId);
DrpVal |= (WriteVal << 11);
/* Write new DRP register value for QPLL_REFCLK_DIV. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x33, DrpVal);
/* Obtain current DRP register value for QPLL_FBDIV. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x36);
/* Mask out QPLL_FBDIV. */
DrpVal &= ~(0x3FFF);
/* Set QPLL_FBDIV. */
WriteVal = XVphy_NToDrpEncoding(InstancePtr, QuadId, CmnId, 0);
DrpVal |= WriteVal;
/* Write new DRP register value for QPLL_FBDIV. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x36, DrpVal);
/* Obtain current DRP register value for QPLL_FBDIV_RATIO. */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, CmnId, 0x37);
/* Mask out QPLL_FBDIV_RATIO. */
DrpVal &= ~(1 << 6);
/* Set QPLL_FBDIV_RATIO. */
if (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].PllParams.
NFbDiv != 66) {
DrpVal |= (1 << 6);
}
/* Write new DRP register value for QPLL_FBDIV_RATIO. */
XVphy_DrpWrite(InstancePtr, QuadId, CmnId, 0x37, DrpVal);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel's RX settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2RxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
{
/* Missing: RXCDR_LOCK_CFG, RX_LPM_*_CFG, RX_DFE_*_CFG */
XVphy_Channel *ChPtr;
u16 DrpVal;
u8 CfgIndex;
ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
/* RXCDR_CFG(CfgIndex) */
for (CfgIndex = 0; CfgIndex < 5; CfgIndex++) {
DrpVal = ChPtr->PllParams.Cdr[CfgIndex];
if (!DrpVal) {
/* Don't modify RX_CDR configuration. */
continue;
}
XVphy_DrpWrite(InstancePtr, QuadId, ChId,
XVPHY_DRP_RXCDR_CFG(CfgIndex), DrpVal);
}
if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
/* Set internal Data width */
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId,
XVPHY_DRP_RXDATAWIDTH);
DrpVal &= ~(0x7800);
if (InstancePtr->HdmiRxDruIsEnabled) {
/* Set internal Data width of the RX GT to 2-byte */
DrpVal |= (0 << 14);
/* Set RX Data width of the RX GT to 20 bits */
DrpVal |= (3 << 11);
}
else {
/* Set internal Data width of the RX GT to 4-byte */
DrpVal |= (1 << 14);
/* Set RX Data width of the RX GT to 40 bits */
DrpVal |= (5 << 11);
}
XVphy_DrpWrite(InstancePtr, QuadId, ChId, XVPHY_DRP_RXDATAWIDTH,
DrpVal);
/* Set QPLL Lower Band */
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x99, 0x8480);
XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x9A, 0x1);
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function will configure the channel's TX CLKDIV1 settings.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return
* - XST_SUCCESS if the configuration was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
u32 XVphy_Gtxe2TxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u16 DrpVal;
DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, XVPHY_DRP_TXCLK25);
DrpVal &= ~(0x1F);
DrpVal |= XVphy_DrpEncodeClk25(InstancePtr->HdmiTxRefClkHz);
return XVphy_DrpWrite(InstancePtr, QuadId, ChId, XVPHY_DRP_TXCLK25,
DrpVal);
}
/*****************************************************************************/
/**
* This function will translate the configured M value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
*
* @return The DRP encoding for M.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_MToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId)
{
u8 MRefClkDiv;
u8 DrpEncode;
if ((ChId >= XVPHY_CHANNEL_ID_CH1) && (ChId <= XVPHY_CHANNEL_ID_CH4)) {
MRefClkDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)]
.PllParams.MRefClkDiv;
}
else if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
(ChId == XVPHY_CHANNEL_ID_CMN1)) {
MRefClkDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)]
.PllParams.MRefClkDiv;
}
else {
MRefClkDiv = 0;
}
DrpEncode = XVphy_DrpEncodeQpllMCpllMN2(MRefClkDiv);
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured D value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param Dir is an indicator for RX or TX.
*
* @return The DRP encoding for D.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, XVphy_DirectionType Dir)
{
u8 OutDiv;
u8 DrpEncode;
OutDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
OutDiv[Dir];
DrpEncode = XVphy_DrpEncodeCpllTxRxD(OutDiv);
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured N1/N2 value to DRP encoding.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param QuadId is the GT quad ID to operate on.
* @param ChId is the channel ID to operate on.
* @param NId specified to operate on N1 (if == 1) or N2 (if == 2).
*
* @return The DRP encoding for N1/N2.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_NToDrpEncoding(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId, u8 NId)
{
u8 NFbDiv;
u16 DrpEncode;
if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
(ChId == XVPHY_CHANNEL_ID_CMN1)) {
NFbDiv = InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
PllParams.NFbDiv;
DrpEncode = XVphy_DrpEncodeQpllN(NFbDiv);
}
else if (NId == 1) {
NFbDiv = InstancePtr->Quads[QuadId].Plls[
XVPHY_CH2IDX(ChId)].PllParams.N1FbDiv;
DrpEncode = XVphy_DrpEncodeCpllN1(NFbDiv);
}
else {
NFbDiv = InstancePtr->Quads[QuadId].Plls[
XVPHY_CH2IDX(ChId)].PllParams.N2FbDiv;
DrpEncode = XVphy_DrpEncodeQpllMCpllMN2(NFbDiv);
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured QPLL's M or CPLL's M or N2
* values to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the QPLL's M or CPLL's M or N2 values.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeQpllMCpllMN2(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 1:
DrpEncode = 16;
break;
case 6:
DrpEncode = 5;
break;
case 10:
DrpEncode = 7;
break;
case 12:
DrpEncode = 13;
break;
case 20:
DrpEncode = 15;
break;
case 2:
case 3:
case 4:
case 5:
case 8:
case 16:
DrpEncode = (AttrEncode - 2);
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CPLL's N1 value to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CPLL's N1 value.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeCpllN1(u8 AttrEncode)
{
u8 DrpEncode;
DrpEncode = AttrEncode - 4;
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured CPLL's D values to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the CPLL's D value.
*
* @note None.
*
******************************************************************************/
static u8 XVphy_DrpEncodeCpllTxRxD(u8 AttrEncode)
{
u8 DrpEncode;
switch (AttrEncode) {
case 1:
DrpEncode = 0;
break;
case 2:
DrpEncode = 1;
break;
case 4:
DrpEncode = 2;
break;
case 8:
DrpEncode = 3;
break;
case 16:
DrpEncode = 4;
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
/*****************************************************************************/
/**
* This function will translate the configured QPLL's N value to DRP encoding.
*
* @param AttrEncode is the attribute to encode.
*
* @return The DRP encoding for the QPLL's N value.
*
* @note None.
*
******************************************************************************/
static u16 XVphy_DrpEncodeQpllN(u8 AttrEncode)
{
u16 DrpEncode;
switch (AttrEncode) {
case 16:
DrpEncode = 0x020;
break;
case 20:
DrpEncode = 0x030;
break;
case 32:
DrpEncode = 0x060;
break;
case 40:
DrpEncode = 0x080;
break;
case 64:
DrpEncode = 0x0E0;
break;
case 66:
DrpEncode = 0x140;
break;
case 80:
DrpEncode = 0x120;
break;
case 100:
DrpEncode = 0x170;
break;
default:
DrpEncode = 0xFF;
break;
}
return DrpEncode;
}
static u16 XVphy_DrpEncodeClk25(u32 RefClkFreqHz)
{
u16 DrpEncode;
u32 RefClkFreqMHz = RefClkFreqHz / 1000000;
DrpEncode = ((RefClkFreqMHz / 25) +
(((RefClkFreqMHz % 25) > 0) ? 1 : 0)) - 1;
return DrpEncode;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,120 @@
/*******************************************************************************
*
* 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 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 xvphy_hdmi.h
*
* The Xilinx Video PHY (VPHY) driver. This driver supports the Xilinx Video PHY
* IP core.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 gm 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
#ifndef XVPHY_HDMI_H_
/* Prevent circular inclusions by using protection macros. */
#define XVPHY_HDMI_H_
/************************** Constant Definitions ******************************/
#define XVPHY_HDMI_GTHE3_DRU_LRATE 2500000000U
#define XVPHY_HDMI_GTHE3_PLL_SCALE 1000
#define XVPHY_HDMI_GTHE3_QPLL0_REFCLK_MIN 61250000LL
#define XVPHY_HDMI_GTHE3_QPLL1_REFCLK_MIN 50000000LL
#define XVPHY_HDMI_GTHE3_CPLL_REFCLK_MIN 100000000LL
#define XVPHY_HDMI_GTHE3_TX_MMCM_SCALE 1
#define XVPHY_HDMI_GTHE3_TX_MMCM_FVCO_MIN 600000000U
#define XVPHY_HDMI_GTHE3_TX_MMCM_FVCO_MAX 1200000000U
#define XVPHY_HDMI_GTHE3_RX_MMCM_SCALE 1
#define XVPHY_HDMI_GTHE3_RX_MMCM_FVCO_MIN 600000000U
#define XVPHY_HDMI_GTHE3_RX_MMCM_FVCO_MAX 1200000000U
#define XVPHY_HDMI_GTHE2_DRU_LRATE 2500000000U
#define XVPHY_HDMI_GTHE2_PLL_SCALE 1000
#define XVPHY_HDMI_GTHE2_QPLL_REFCLK_MIN 61250000LL
#define XVPHY_HDMI_GTHE2_CPLL_REFCLK_MIN 80000000LL
#define XVPHY_HDMI_GTHE2_TX_MMCM_SCALE 1
#define XVPHY_HDMI_GTHE2_TX_MMCM_FVCO_MIN 600000000U
#define XVPHY_HDMI_GTHE2_TX_MMCM_FVCO_MAX 1200000000U
#define XVPHY_HDMI_GTHE2_RX_MMCM_SCALE 1
#define XVPHY_HDMI_GTHE2_RX_MMCM_FVCO_MIN 600000000U
#define XVPHY_HDMI_GTHE2_RX_MMCM_FVCO_MAX 1200000000U
#define XVPHY_HDMI_GTXE2_DRU_LRATE 2000000000U
#define XVPHY_HDMI_GTXE2_PLL_SCALE 1000
#define XVPHY_HDMI_GTXE2_QPLL_REFCLK_MIN 74125000LL
#define XVPHY_HDMI_GTXE2_CPLL_REFCLK_MIN 80000000LL
#define XVPHY_HDMI_GTXE2_TX_MMCM_SCALE 1
#define XVPHY_HDMI_GTXE2_TX_MMCM_FVCO_MIN 800000000U
#define XVPHY_HDMI_GTXE2_TX_MMCM_FVCO_MAX 1866000000U
#define XVPHY_HDMI_GTXE2_RX_MMCM_SCALE 1
#define XVPHY_HDMI_GTXE2_RX_MMCM_FVCO_MIN 600000000U
#define XVPHY_HDMI_GTXE2_RX_MMCM_FVCO_MAX 1200000000U
/**************************** Function Prototypes *****************************/
u32 XVphy_HdmiQpllParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir);
u32 XVphy_HdmiCpllParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
XVphy_DirectionType Dir);
void XVphy_TxAlignReset(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Reset);
void XVphy_TxAlignStart(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Start);
void XVphy_ClkDetEnable(XVphy *InstancePtr, u8 Enable);
void XVphy_ClkDetTimerClear(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir);
void XVphy_ClkDetSetFreqLockThreshold(XVphy *InstancePtr, u16 ThresholdVal);
u8 XVphy_ClkDetCheckFreqZero(XVphy *InstancePtr, XVphy_DirectionType Dir);
void XVphy_ClkDetSetFreqTimeout(XVphy *InstancePtr, u32 TimeoutVal);
void XVphy_ClkDetTimerLoad(XVphy *InstancePtr, u8 QuadId,
XVphy_DirectionType Dir, u32 TimeoutVal);
void XVphy_DruReset(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Reset);
void XVphy_DruEnable(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Enable);
u16 XVphy_DruGetVersion(XVphy *InstancePtr);
void XVphy_DruSetCenterFreqHz(XVphy *InstancePtr, XVphy_ChannelId ChId,
u64 CenterFreqHz);
void XVphy_DruSetGain(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 G1, u8 G1_P,
u8 G2);
u64 XVphy_DruCalcCenterFreqHz(XVphy *InstancePtr, u8 QuadId,
XVphy_ChannelId ChId);
void XVphy_HdmiGtDruModeEnable(XVphy *InstancePtr, u8 Enable);
void XVphy_HdmiIntrHandlerCallbackInit(XVphy *InstancePtr);
#endif /* XVPHY_HDMI_H_ */

View file

@ -0,0 +1,954 @@
/*******************************************************************************
*
* 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 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 xvphy_hdmi_intr.c
*
* This file contains video PHY functionality specific to the HDMI protocol
* related to interrupts.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 gm 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xparameters.h"
#include "xintc.h"
#include "xstatus.h"
#include "xvphy.h"
#include "xvphy_hdmi.h"
# include "xvphy_gt.h"
/************************** Function Prototypes ******************************/
extern void XVphy_Ch2Ids(XVphy *InstancePtr, XVphy_ChannelId ChId,
u8 *Id0, u8 *Id1);
static void XVphy_HdmiGtHandler(XVphy *InstancePtr);
static void XVphy_ClkDetHandler(XVphy *InstancePtr);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function installs an HDMI callback function for the specified handler
* type
*
* @param InstancePtr is a pointer to the XVPhy instance.
* @param HandlerType is the interrupt handler type which specifies which
* interrupt event to attach the callback for.
* @param CallbackFunc is the address to the callback function.
* @param CallbackRef is the user data item that will be passed to the
* callback function when it is invoked.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XVphy_SetHdmiCallback(XVphy *InstancePtr,
XVphy_HdmiHandlerType HandlerType,
void *CallbackFunc, void *CallbackRef)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((HandlerType == XVPHY_HDMI_HANDLER_TXINIT) ||
(HandlerType == XVPHY_HDMI_HANDLER_TXREADY) ||
(HandlerType == XVPHY_HDMI_HANDLER_RXINIT) ||
(HandlerType == XVPHY_HDMI_HANDLER_RXREADY));
Xil_AssertVoid(CallbackFunc != NULL);
Xil_AssertVoid(CallbackRef != NULL);
switch (HandlerType) {
case XVPHY_HDMI_HANDLER_TXINIT:
InstancePtr->HdmiTxInitCallback = CallbackFunc;
InstancePtr->HdmiTxInitRef = CallbackRef;
break;
case XVPHY_HDMI_HANDLER_TXREADY:
InstancePtr->HdmiTxReadyCallback = CallbackFunc;
InstancePtr->HdmiTxReadyRef = CallbackRef;
break;
case XVPHY_HDMI_HANDLER_RXINIT:
InstancePtr->HdmiRxInitCallback = CallbackFunc;
InstancePtr->HdmiRxInitRef = CallbackRef;
break;
case XVPHY_HDMI_HANDLER_RXREADY:
InstancePtr->HdmiRxReadyCallback = CallbackFunc;
InstancePtr->HdmiRxReadyRef = CallbackRef;
break;
default:
break;
}
}
/*****************************************************************************/
/**
* This function sets the appropriate HDMI interupt handlers.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiIntrHandlerCallbackInit(XVphy *InstancePtr)
{
/* GT Interrupts */
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE,
(XVphy_IntrHandler)XVphy_HdmiGtHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE,
(XVphy_IntrHandler)XVphy_HdmiGtHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK,
(XVphy_IntrHandler)XVphy_HdmiGtHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_QPLL_LOCK,
(XVphy_IntrHandler)XVphy_HdmiGtHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE,
(XVphy_IntrHandler)XVphy_HdmiGtHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK,
(XVphy_IntrHandler)XVphy_HdmiGtHandler, InstancePtr);
/* Clock Detector Interrupts */
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE,
(XVphy_IntrHandler)XVphy_ClkDetHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE,
(XVphy_IntrHandler)XVphy_ClkDetHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT,
(XVphy_IntrHandler)XVphy_ClkDetHandler, InstancePtr);
XVphy_SetIntrHandler(InstancePtr,
XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT,
(XVphy_IntrHandler)XVphy_ClkDetHandler, InstancePtr);
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by QPLL lock done.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiQpllLockHandler(XVphy *InstancePtr)
{
XVphy_GtState *TxStatePtr;
XVphy_GtState *RxStatePtr;
XVphy_PllType TxPllType;
XVphy_PllType RxPllType;
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_QPLL_LOCK, 1);
TxStatePtr = &InstancePtr->Quads[0].Plls[0].TxState;
RxStatePtr = &InstancePtr->Quads[0].Plls[0].RxState;
/* Determine PLL type. */
TxPllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_TX,
XVPHY_CHANNEL_ID_CH1);
RxPllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
XVPHY_CHANNEL_ID_CH1);
/* Check if we are really waiting for a QPLL lock. */
if (!((((RxPllType == XVPHY_PLL_TYPE_QPLL) ||
(RxPllType == XVPHY_PLL_TYPE_QPLL0) ||
(RxPllType == XVPHY_PLL_TYPE_QPLL1)) &&
(*RxStatePtr == XVPHY_GT_STATE_LOCK)) ||
(((TxPllType == XVPHY_PLL_TYPE_QPLL) ||
(TxPllType == XVPHY_PLL_TYPE_QPLL0) ||
(TxPllType == XVPHY_PLL_TYPE_QPLL1)) &&
(*TxStatePtr == XVPHY_GT_STATE_LOCK)))) {
return;
}
/* RX is using QPLL. */
if ((RxPllType == XVPHY_PLL_TYPE_QPLL) ||
(RxPllType == XVPHY_PLL_TYPE_QPLL0) ||
(RxPllType == XVPHY_PLL_TYPE_QPLL1)) {
/* GT RX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, FALSE);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].RxState =
XVPHY_GT_STATE_RESET;
}
/* If the GT TX and RX are coupled, then update the GT TX state
* as well. */
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
/* GT TX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, TRUE);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA,
&Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].
TxState = XVPHY_GT_STATE_RESET;
}
}
}
/* TX is using QPLL. */
else {
/* GT TX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, FALSE);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_RESET;
}
}
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by CPLL lock done.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiCpllLockHandler(XVphy *InstancePtr)
{
XVphy_GtState *TxStatePtr;
XVphy_GtState *RxStatePtr;
XVphy_PllType TxPllType;
XVphy_PllType RxPllType;
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_CPLL_LOCK, 1);
TxStatePtr = &InstancePtr->Quads[0].Plls[0].TxState;
RxStatePtr = &InstancePtr->Quads[0].Plls[0].RxState;
/* Determine PLL type. */
TxPllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_TX,
XVPHY_CHANNEL_ID_CH1);
RxPllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
XVPHY_CHANNEL_ID_CH1);
/* Check if we are really waiting for a CPLL lock. */
if (!(((RxPllType == XVPHY_PLL_TYPE_CPLL) &&
(*RxStatePtr == XVPHY_GT_STATE_LOCK)) ||
((TxPllType == XVPHY_PLL_TYPE_CPLL) &&
(*TxStatePtr == XVPHY_GT_STATE_LOCK)))) {
return;
}
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
/* RX is using CPLL. */
if (RxPllType == XVPHY_PLL_TYPE_CPLL) {
/* GT RX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, FALSE);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].RxState =
XVPHY_GT_STATE_RESET;
}
/* If the GT TX and RX are coupled, then update the GT TX state
* as well. */
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
/* GT TX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, TRUE);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].
TxState = XVPHY_GT_STATE_RESET;
}
}
}
/* TX is using CPLL. */
else {
/* GT TX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, FALSE);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_RESET;
}
}
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by GT TX reset lock done.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiGtTxResetDoneLockHandler(XVphy *InstancePtr)
{
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_TX_RST_DONE, 0);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
XVphy_TxAlignReset(InstancePtr, XVPHY_CHANNEL_ID_CHA, TRUE);
XVphy_TxAlignReset(InstancePtr, XVPHY_CHANNEL_ID_CHA, FALSE);
}
/* GT alignment. */
XVphy_TxAlignStart(InstancePtr, XVPHY_CHANNEL_ID_CHA, TRUE);
XVphy_TxAlignStart(InstancePtr, XVPHY_CHANNEL_ID_CHA, FALSE);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_ALIGN;
}
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by GT TX alignment done.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiGtTxAlignDoneLockHandler(XVphy *InstancePtr)
{
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_TX_ALIGN, 1);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_READY;
}
/* TX ready callback. */
if (InstancePtr->HdmiTxReadyCallback) {
InstancePtr->HdmiTxReadyCallback(InstancePtr->HdmiTxReadyRef);
}
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by GT RX reset lock done.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiGtRxResetDoneLockHandler(XVphy *InstancePtr)
{
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_RX_RST_DONE, 0);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].RxState =
XVPHY_GT_STATE_READY;
}
/* If DRU is use/d, release its reset. */
if (InstancePtr->HdmiRxDruIsEnabled) {
XVphy_DruReset(InstancePtr, XVPHY_CHANNEL_ID_CHA, FALSE);
}
/* RX ready callback. */
if (InstancePtr->HdmiRxReadyCallback) {
InstancePtr->HdmiRxReadyCallback(InstancePtr->HdmiRxReadyRef);
}
/* If the GT TX and RX are coupled, then update the GT TX state
* as well. */
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
/* GT TX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, FALSE);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_RESET;
}
}
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by a change in TX frequency
* as detected by the HDMI clock detector logic.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiTxClkDetFreqChangeHandler(XVphy *InstancePtr)
{
XVphy_PllType PllType;
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_TX_FREQ, 0);
/* Determine PLL type. */
PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_TX,
XVPHY_CHANNEL_ID_CH1);
/* Assert GT TX reset. */
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, TRUE);
}
/* If the TX frequency has changed, the PLL is always disabled. */
XVphy_PowerDownGtPll(InstancePtr, 0, (PllType == XVPHY_PLL_TYPE_CPLL) ?
XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA, TRUE);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
XVphy_BufgGtReset(InstancePtr, XVPHY_DIR_TX,TRUE);
}
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,
TRUE);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_GtUserRdyEnable(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, FALSE);
}
/* Disable TX MMCM. */
XVphy_MmcmPowerDown(InstancePtr, 0, XVPHY_DIR_TX, TRUE);
/* Clear TX timer. */
XVphy_ClkDetTimerClear(InstancePtr, 0, XVPHY_DIR_TX);
/* Clear GT alignment. */
XVphy_TxAlignStart(InstancePtr, XVPHY_CHANNEL_ID_CHA, FALSE);
/* De-assert GT TX reset. */
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, FALSE);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_IDLE;
}
/* If there is no reference clock, load TX timer in usec. */
if (XVphy_ClkDetGetRefClkFreqHz(InstancePtr, XVPHY_DIR_TX)) {
XVphy_ClkDetTimerLoad(InstancePtr, 0, XVPHY_DIR_TX, 100000);
}
/* Callback to re-initialize. */
if (InstancePtr->HdmiTxInitCallback) {
InstancePtr->HdmiTxInitCallback(InstancePtr->HdmiTxInitRef);
}
}
/*****************************************************************************/
/**
* This function is the handler for events triggered by a change in RX frequency
* as detected by the HDMI clock detector logic.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiRxClkDetFreqChangeHandler(XVphy *InstancePtr)
{
XVphy_PllType PllType;
u32 RxRefClkHz;
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_RX_FREQ, 0);
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].RxState =
XVPHY_GT_STATE_IDLE;
}
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, TRUE);
}
/* Determine PLL type and RX reference clock selection. */
PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
XVPHY_CHANNEL_ID_CH1);
/* Fetch New RX Reference Clock Frequency */
RxRefClkHz = XVphy_ClkDetGetRefClkFreqHz(InstancePtr, XVPHY_DIR_RX);
/* Round input frequency to 10 kHz. */
RxRefClkHz = RxRefClkHz / 10000;
RxRefClkHz = RxRefClkHz * 10000;
/* Store RX reference clock. */
InstancePtr->HdmiRxRefClkHz = RxRefClkHz;
/* If the RX frequency has changed, the PLL is always disabled. */
XVphy_PowerDownGtPll(InstancePtr, 0, (PllType == XVPHY_PLL_TYPE_CPLL) ?
XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA, TRUE);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, 1);
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, FALSE);
XVphy_BufgGtReset(InstancePtr, XVPHY_DIR_RX,TRUE);
}
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_GtUserRdyEnable(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, FALSE);
}
/* When the GT TX and RX are coupled, then disable the QPLL. */
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
XVphy_PowerDownGtPll(InstancePtr, 0,
(PllType == XVPHY_PLL_TYPE_CPLL) ?
XVPHY_CHANNEL_ID_CMNA : XVPHY_CHANNEL_ID_CHA, TRUE);
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, 1);
}
/* Disable RX MMCM */
XVphy_MmcmPowerDown(InstancePtr, 0, XVPHY_DIR_RX, TRUE);
/* When the GT TX and RX are coupled, then disable the TX MMCM. */
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
XVphy_MmcmPowerDown(InstancePtr, 0, XVPHY_DIR_TX, TRUE);
}
/* If DRU is present, disable it and assert reset. */
if (InstancePtr->Config.DruIsPresent) {
XVphy_DruReset(InstancePtr, XVPHY_CHANNEL_ID_CHA, TRUE);
XVphy_DruEnable(InstancePtr, XVPHY_CHANNEL_ID_CHA, FALSE);
}
/* Clear RX timer. */
XVphy_ClkDetTimerClear(InstancePtr, 0, XVPHY_DIR_RX);
/* If there is reference clock, load RX timer in usec. */
if (XVphy_ClkDetGetRefClkFreqHz(InstancePtr, XVPHY_DIR_RX)) {
XVphy_ClkDetTimerLoad(InstancePtr, 0, XVPHY_DIR_RX, 100000);
}
else {
return;
}
/* Callback to re-initialize. */
if (InstancePtr->HdmiRxInitCallback) {
InstancePtr->HdmiRxInitCallback(InstancePtr->HdmiRxInitRef);
}
}
/*****************************************************************************/
/**
* This function is the handler for TX timer timeout events.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiTxTimerTimeoutHandler(XVphy *InstancePtr)
{
XVphy_ChannelId ChId;
XVphy_PllType PllType;
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_TX_TMR, 1);
/* Determine PLL type. */
PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_TX,
XVPHY_CHANNEL_ID_CH1);
/* Determine which channel(s) to operate on. */
switch (PllType) {
case XVPHY_PLL_TYPE_QPLL:
case XVPHY_PLL_TYPE_QPLL0:
ChId = XVPHY_CHANNEL_ID_CMN0;
break;
case XVPHY_PLL_TYPE_QPLL1:
ChId = XVPHY_CHANNEL_ID_CMN1;
break;
default:
ChId = XVPHY_CHANNEL_ID_CHA;
break;
}
/* Start TX MMCM. */
XVphy_MmcmStart(InstancePtr, 0, XVPHY_DIR_TX);
/* Enable PLL. */
XVphy_PowerDownGtPll(InstancePtr, 0, (PllType == XVPHY_PLL_TYPE_CPLL) ?
XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA, FALSE);
if (PllType != XVPHY_PLL_TYPE_CPLL) {
/* Set QPLL Selection in PIO. */
XVphy_WriteCfgRefClkSelReg(InstancePtr, 0);
}
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_GtUserRdyEnable(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, TRUE);
}
XVphy_ClkReconfig(InstancePtr, 0, ChId);
XVphy_OutDivReconfig(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
XVphy_SetBufgGtDiv(InstancePtr, XVPHY_DIR_TX,
(PllType == XVPHY_PLL_TYPE_CPLL) ?
InstancePtr->Quads[0].Plls[0].TxOutDiv :
InstancePtr->Quads[0].Plls[0].TxOutDiv / 2);
}
XVphy_DirReconfig(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX);
/* Assert PLL reset. */
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, TRUE);
/* Assert GT TX reset. */
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, TRUE);
}
/* De-assert PLL reset. */
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, FALSE);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
XVphy_BufgGtReset(InstancePtr, XVPHY_DIR_TX,FALSE);
/* Clear GT alignment. */
XVphy_TxAlignStart(InstancePtr, ChId, FALSE);
}
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
XVPHY_GT_STATE_LOCK;
}
}
/*****************************************************************************/
/**
* This function is the handler for RX timer timeout events.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiRxTimerTimeoutHandler(XVphy *InstancePtr)
{
XVphy_ChannelId ChId;
XVphy_PllType PllType;
u32 Status;
u8 Id, Id0, Id1;
XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_RX_TMR, 1);
/* Determine PLL type. */
PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
XVPHY_CHANNEL_ID_CH1);
/* Determine which channel(s) to operate on. */
switch (PllType) {
case XVPHY_PLL_TYPE_QPLL:
case XVPHY_PLL_TYPE_QPLL0:
ChId = XVPHY_CHANNEL_ID_CMN0;
break;
case XVPHY_PLL_TYPE_QPLL1:
ChId = XVPHY_CHANNEL_ID_CMN1;
break;
default:
ChId = XVPHY_CHANNEL_ID_CHA;
break;
}
XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
/* Set RX parameters. */
Status = XVphy_SetHdmiRxParam(InstancePtr, 0, ChId);
if (Status != XST_SUCCESS) {
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
xil_printf("\n\rCouldn't find the correct GT "
"parameters for this video resolution.\n\r");
xil_printf("Try another GT PLL layout.\n\r");
}
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].RxState =
XVPHY_GT_STATE_IDLE;
if (XVphy_IsBonded(InstancePtr, 0,
XVPHY_CHANNEL_ID_CH1)) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].
TxState = XVPHY_GT_STATE_IDLE;
}
}
return;
}
/* Enable PLL. */
XVphy_PowerDownGtPll(InstancePtr, 0, (PllType == XVPHY_PLL_TYPE_CPLL) ?
XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA, FALSE);
/* Enable DRU to set the clock muxes. */
XVphy_DruEnable(InstancePtr, XVPHY_CHANNEL_ID_CHA,
InstancePtr->HdmiRxDruIsEnabled);
/* Update reference clock election. */
XVphy_CfgPllRefClkSel(InstancePtr, 0,
((PllType == XVPHY_PLL_TYPE_CPLL) ?
XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA),
((InstancePtr->HdmiRxDruIsEnabled) ?
InstancePtr->Config.DruRefClkSel :
InstancePtr->Config.RxRefClkSel));
/* Update GT DRU mode. */
XVphy_HdmiGtDruModeEnable(InstancePtr, InstancePtr->HdmiRxDruIsEnabled);
/* Update RefClk selection. */
XVphy_WriteCfgRefClkSelReg(InstancePtr, 0);
XVphy_ClkReconfig(InstancePtr, 0, ChId);
XVphy_OutDivReconfig(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX);
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
XVphy_OutDivReconfig(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX);
}
XVphy_DirReconfig(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
XVphy_BufgGtReset(InstancePtr, XVPHY_DIR_RX,FALSE);
}
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_GtUserRdyEnable(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, TRUE);
}
/* Assert RX PLL reset. */
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,
TRUE);
if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, TRUE);
}
/* De-assert RX PLL reset. */
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_RX, FALSE);
/* When the TX and RX are coupled, clear GT alignment. */
if (XVphy_IsBonded(InstancePtr, 0, XVPHY_CHANNEL_ID_CH1)) {
if (InstancePtr->HdmiRxDruIsEnabled) {
xil_printf("WARNING: "
"Transmitter cannot be used on\r\n");
xil_printf(" "
"bonded mode when DRU is enabled\r\n");
xil_printf("Switch to unbonded PLL layout\r\n");
}
XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
XVPHY_DIR_TX, 0);
XVphy_TxAlignStart(InstancePtr, ChId, FALSE);
}
for (Id = Id0; Id <= Id1; Id++) {
InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].RxState =
XVPHY_GT_STATE_LOCK;
}
}
/*****************************************************************************/
/**
* This function is the interrupt handler for the GT events.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_HdmiGtHandler(XVphy *InstancePtr)
{
u32 Event;
u32 EventMask;
u32 EventAck;
XVphy_GtState *TxStatePtr;
XVphy_GtState *RxStatePtr;
EventMask = XVPHY_INTR_QPLL0_LOCK_MASK | XVPHY_INTR_CPLL_LOCK_MASK |
XVPHY_INTR_QPLL1_LOCK_MASK | XVPHY_INTR_TXRESETDONE_MASK |
XVPHY_INTR_TXALIGNDONE_MASK | XVPHY_INTR_RXRESETDONE_MASK;
u8 QuadId = 0;
/* Read Interrupt Status register */
Event = XVphy_ReadReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_STS_REG);
EventAck = EventMask & Event;
/* Read States for Quad=0 Ch1 */
TxStatePtr = &InstancePtr->Quads[QuadId].Ch1.TxState;
RxStatePtr = &InstancePtr->Quads[QuadId].Ch1.RxState;
if ((Event & XVPHY_INTR_QPLL0_LOCK_MASK) ||
(Event & XVPHY_INTR_QPLL1_LOCK_MASK)){
XVphy_WaitUs(InstancePtr, 10 * 1000); //de-bounce lock
XVphy_HdmiQpllLockHandler(InstancePtr);
}
if (Event & XVPHY_INTR_CPLL_LOCK_MASK) {
XVphy_WaitUs(InstancePtr, 10 * 1000); //de-bounce lock
XVphy_HdmiCpllLockHandler(InstancePtr);
}
if ((Event & XVPHY_INTR_TXRESETDONE_MASK)
&& (*TxStatePtr == XVPHY_GT_STATE_RESET)) {
XVphy_HdmiGtTxResetDoneLockHandler(InstancePtr);
}
if ((Event & XVPHY_INTR_TXALIGNDONE_MASK)
&& (*TxStatePtr == XVPHY_GT_STATE_ALIGN)) {
XVphy_HdmiGtTxAlignDoneLockHandler(InstancePtr);
}
if ((Event & XVPHY_INTR_RXRESETDONE_MASK)
&& (*RxStatePtr == XVPHY_GT_STATE_RESET)) {
XVphy_HdmiGtRxResetDoneLockHandler(InstancePtr);
}
/* Clear event flags by writing to Interrupt Status register */
XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_STS_REG,
EventAck);
}
/*****************************************************************************/
/**
* This function is the interrupt handler for the clock detector events.
*
* @param InstancePtr is a pointer to the VPHY instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_ClkDetHandler(XVphy *InstancePtr)
{
u32 Event;
u32 EventMask;
u32 EventAck;
EventMask = XVPHY_INTR_TXCLKDETFREQCHANGE_MASK |
XVPHY_INTR_RXCLKDETFREQCHANGE_MASK |
XVPHY_INTR_TXTMRTIMEOUT_MASK |
XVPHY_INTR_RXTMRTIMEOUT_MASK;
/* Read Interrupt Status register */
Event = XVphy_ReadReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_STS_REG);
EventAck = EventMask & Event;
if (Event & XVPHY_INTR_TXCLKDETFREQCHANGE_MASK) {
XVphy_HdmiTxClkDetFreqChangeHandler(InstancePtr);
}
if (Event & XVPHY_INTR_RXCLKDETFREQCHANGE_MASK) {
XVphy_HdmiRxClkDetFreqChangeHandler(InstancePtr);
}
if (Event & XVPHY_INTR_TXTMRTIMEOUT_MASK) {
XVphy_HdmiTxTimerTimeoutHandler(InstancePtr);
}
if (Event & XVPHY_INTR_RXTMRTIMEOUT_MASK) {
XVphy_HdmiRxTimerTimeoutHandler(InstancePtr);
}
/* Clear event flags by writing to Interrupt Status register */
XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_STS_REG,
EventAck);
}

View file

@ -0,0 +1,560 @@
/*******************************************************************************
*
* 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 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 xvphy_hw.h
*
* This header file contains the identifiers and low-level driver functions (or
* macros) that can be used to access the device. High-level driver functions
* are defined in xvphy.h.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
#ifndef XVPHY_HW_H_
/* Prevent circular inclusions by using protection macros. */
#define XVPHY_HW_H_
/***************************** Include Files **********************************/
#include "xil_io.h"
#include "xil_types.h"
/************************** Constant Definitions ******************************/
/******************************************************************************/
/**
* Address mapping for the Video PHY core.
*
*******************************************************************************/
/** @name VPHY core registers: General registers.
* @{
*/
#define XVPHY_VERSION_REG 0x000
#define XVPHY_BANK_SELECT_REG 0x00C
#define XVPHY_REF_CLK_SEL_REG 0x010
#define XVPHY_PLL_RESET_REG 0x014
#define XVPHY_PLL_LOCK_STATUS_REG 0x018
#define XVPHY_TX_INIT_REG 0x01C
#define XVPHY_TX_INIT_STATUS_REG 0x020
#define XVPHY_RX_INIT_REG 0x024
#define XVPHY_RX_INIT_STATUS_REG 0x028
#define XVPHY_IBUFDS_GTXX_CTRL_REG 0x02C
#define XVPHY_POWERDOWN_CONTROL_REG 0x030
#define XVPHY_LOOPBACK_CONTROL_REG 0x038
/* @} */
/** @name VPHY core registers: Dynamic reconfiguration port (DRP) registers.
* @{
*/
#define XVPHY_DRP_CONTROL_CH1_REG 0x040
#define XVPHY_DRP_CONTROL_CH2_REG 0x044
#define XVPHY_DRP_CONTROL_CH3_REG 0x048
#define XVPHY_DRP_CONTROL_CH4_REG 0x04C
#define XVPHY_DRP_STATUS_CH1_REG 0x050
#define XVPHY_DRP_STATUS_CH2_REG 0x054
#define XVPHY_DRP_STATUS_CH3_REG 0x058
#define XVPHY_DRP_STATUS_CH4_REG 0x05C
#define XVPHY_DRP_CONTROL_COMMON_REG 0x060
#define XVPHY_DRP_STATUS_COMMON_REG 0x064
/* @} */
/** @name VPHY core registers: Transmitter function registers.
* @{
*/
#define XVPHY_TX_CONTROL_REG 0x070
#define XVPHY_TX_BUFFER_BYPASS_REG 0x074
#define XVPHY_TX_STATUS_REG 0x078
#define XVPHY_TX_DRIVER_CH12_REG 0x07C
#define XVPHY_TX_DRIVER_CH34_REG 0x080
/* @} */
/** @name VPHY core registers: Receiver function registers.
* @{
*/
#define XVPHY_RX_CONTROL_REG 0x100
#define XVPHY_RX_STATUS_REG 0x104
#define XVPHY_RX_EQ_CDR_REG 0x108
#define XVPHY_RX_TDLOCK_REG 0x10C
/* @} */
/** @name VPHY core registers: Interrupt registers.
* @{
*/
#define XVPHY_INTR_EN_REG 0x110
#define XVPHY_INTR_DIS_REG 0x114
#define XVPHY_INTR_MASK_REG 0x118
#define XVPHY_INTR_STS_REG 0x11C
/* @} */
/** @name User clocking registers: MMCM and BUFGGT registers.
* @{
*/
#define XVPHY_MMCM_TXUSRCLK_CTRL_REG 0x0120
#define XVPHY_MMCM_TXUSRCLK_REG1 0x0124
#define XVPHY_MMCM_TXUSRCLK_REG2 0x0128
#define XVPHY_MMCM_TXUSRCLK_REG3 0x012C
#define XVPHY_MMCM_TXUSRCLK_REG4 0x0130
#define XVPHY_BUFGGT_TXUSRCLK_REG 0x0134
#define XVPHY_MISC_TXUSRCLK_REG 0x0138
#define XVPHY_MMCM_RXUSRCLK_CTRL_REG 0x0140
#define XVPHY_MMCM_RXUSRCLK_REG1 0x0144
#define XVPHY_MMCM_RXUSRCLK_REG2 0x0148
#define XVPHY_MMCM_RXUSRCLK_REG3 0x014C
#define XVPHY_MMCM_RXUSRCLK_REG4 0x0150
#define XVPHY_BUFGGT_RXUSRCLK_REG 0x0154
#define XVPHY_MISC_RXUSRCLK_REG 0x0158
/* @} */
/** @name Clock detector (HDMI) registers.
* @{
*/
#define XVPHY_CLKDET_CTRL_REG 0x0200
#define XVPHY_CLKDET_STAT_REG 0x0204
#define XVPHY_CLKDET_FREQ_TMR_TO_REG 0x0208
#define XVPHY_CLKDET_FREQ_TX_REG 0x020C
#define XVPHY_CLKDET_FREQ_RX_REG 0x0210
#define XVPHY_CLKDET_TMR_TX_REG 0x0214
#define XVPHY_CLKDET_TMR_RX_REG 0x0218
#define XVPHY_CLKDET_FREQ_DRU_REG 0x021C
/* @} */
/** @name Data recovery unit registers (HDMI).
* @{
*/
#define XVPHY_DRU_CTRL_REG 0x0300
#define XVPHY_DRU_STAT_REG 0x0304
#define XVPHY_DRU_CFREQ_L_REG(Ch) (0x0308 + (12 * (Ch - 1)))
#define XVPHY_DRU_CFREQ_H_REG(Ch) (0x030C + (12 * (Ch - 1)))
#define XVPHY_DRU_GAIN_REG(Ch) (0x0310 + (12 * (Ch - 1)))
/* @} */
/******************************************************************************/
/** @name VPHY core masks, shifts, and register values.
* @{
*/
/* 0x0F8: VERSION */
#define XVPHY_VERSION_INTER_REV_MASK \
0x000000FF /**< Internal revision. */
#define XVPHY_VERSION_CORE_PATCH_MASK \
0x00000F00 /**< Core patch details. */
#define XVPHY_VERSION_CORE_PATCH_SHIFT 8 /**< Shift bits for core patch
details. */
#define XVPHY_VERSION_CORE_VER_REV_MASK \
0x0000F000 /**< Core version revision. */
#define XVPHY_VERSION_CORE_VER_REV_SHIFT 12 /**< Shift bits for core version
revision. */
#define XVPHY_VERSION_CORE_VER_MNR_MASK \
0x00FF0000 /**< Core minor version. */
#define XVPHY_VERSION_CORE_VER_MNR_SHIFT 16 /**< Shift bits for core minor
version. */
#define XVPHY_VERSION_CORE_VER_MJR_MASK \
0xFF000000 /**< Core major version. */
#define XVPHY_VERSION_CORE_VER_MJR_SHIFT 24 /**< Shift bits for core major
version. */
/* 0x00C: BANK_SELECT_REG */
#define XVPHY_BANK_SELECT_TX_MASK 0x00F
#define XVPHY_BANK_SELECT_RX_MASK 0xF00
#define XVPHY_BANK_SELECT_RX_SHIFT 8
/* 0x010: REF_CLK_SEL */
#define XVPHY_REF_CLK_SEL_QPLL0_MASK 0x0000000F
#define XVPHY_REF_CLK_SEL_CPLL_MASK 0x000000F0
#define XVPHY_REF_CLK_SEL_CPLL_SHIFT 4
#define XVPHY_REF_CLK_SEL_QPLL1_MASK 0x00000F00
#define XVPHY_REF_CLK_SEL_QPLL1_SHIFT 8
#define XVPHY_REF_CLK_SEL_XPLL_GTREFCLK0 1
#define XVPHY_REF_CLK_SEL_XPLL_GTREFCLK1 2
#define XVPHY_REF_CLK_SEL_XPLL_GTNORTHREFCLK0 3
#define XVPHY_REF_CLK_SEL_XPLL_GTNORTHREFCLK1 4
#define XVPHY_REF_CLK_SEL_XPLL_GTSOUTHREFCLK0 5
#define XVPHY_REF_CLK_SEL_XPLL_GTSOUTHREFCLK1 6
#define XVPHY_REF_CLK_SEL_XPLL_GTGREFCLK 7
#define XVPHY_REF_CLK_SEL_SYSCLKSEL_MASK 0x0F000000
#define XVPHY_REF_CLK_SEL_SYSCLKSEL_SHIFT 24
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_CPLL 0
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_QPLL 1
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_QPLL0 3
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_QPLL1 2
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CH 0
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN 1
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN0 2
#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN1 3
#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_MASK(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 0x03000000 : 0x02000000)
#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_MASK(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 0x0C000000 : 0x08000000)
#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_MASK(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 0x30000000 : 0x01000000)
#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_MASK(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 0xC0000000 : 0x04000000)
#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_SHIFT(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 24 : 25)
#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_SHIFT(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 26 : 27)
#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_SHIFT(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 28 : 24)
#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_SHIFT(G) \
(((G) == XVPHY_GT_TYPE_GTHE3) ? 30 : 26)
/* 0x014: PLL_RESET */
#define XVPHY_PLL_RESET_CPLL_MASK 0x1
#define XVPHY_PLL_RESET_QPLL0_MASK 0x2
#define XVPHY_PLL_RESET_QPLL1_MASK 0x4
/* 0x018: PLL_LOCK_STATUS */
#define XVPHY_PLL_LOCK_STATUS_CPLL_MASK(Ch) \
(0x01 << (Ch - 1))
#define XVPHY_PLL_LOCK_STATUS_QPLL0_MASK 0x10
#define XVPHY_PLL_LOCK_STATUS_QPLL1_MASK 0x20
#define XVPHY_PLL_LOCK_STATUS_CPLL_ALL_MASK \
(XVPHY_PLL_LOCK_STATUS_CPLL_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_PLL_LOCK_STATUS_CPLL_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_PLL_LOCK_STATUS_CPLL_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_PLL_LOCK_STATUS_CPLL_MASK(XVPHY_CHANNEL_ID_CH4))
/* 0x01C, 0x024: TX_INIT, RX_INIT */
#define XVPHY_TXRX_INIT_GTRESET_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_PMARESET_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_PCSRESET_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_TX_INIT_USERRDY_MASK(Ch) \
(0x08 << (8 * (Ch - 1)))
#define XVPHY_RX_INIT_USERRDY_MASK(Ch) \
(0x40 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_PLLGTRESET_MASK(Ch) \
(0x80 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_GTRESET_ALL_MASK \
(XVPHY_TXRX_INIT_GTRESET_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_TXRX_INIT_GTRESET_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_TXRX_INIT_GTRESET_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_TXRX_INIT_GTRESET_MASK(XVPHY_CHANNEL_ID_CH4))
#define XVPHY_TX_INIT_USERRDY_ALL_MASK \
(XVPHY_TX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_TX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_TX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_TX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH4))
#define XVPHY_RX_INIT_USERRDY_ALL_MASK \
(XVPHY_RX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_RX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_RX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_RX_INIT_USERRDY_MASK(XVPHY_CHANNEL_ID_CH4))
#define XVPHY_TXRX_INIT_PLLGTRESET_ALL_MASK \
(XVPHY_TXRX_INIT_PLLGTRESET_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_TXRX_INIT_PLLGTRESET_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_TXRX_INIT_PLLGTRESET_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_TXRX_INIT_PLLGTRESET_MASK(XVPHY_CHANNEL_ID_CH4))
/* 0x020, 0x028: TX_STATUS, RX_STATUS */
#define XVPHY_TXRX_INIT_STATUS_RESETDONE_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_STATUS_PMARESETDONE_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_STATUS_POWERGOOD_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_TXRX_INIT_STATUS_RESETDONE_ALL_MASK \
(XVPHY_TXRX_INIT_STATUS_RESETDONE_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_TXRX_INIT_STATUS_RESETDONE_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_TXRX_INIT_STATUS_RESETDONE_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_TXRX_INIT_STATUS_RESETDONE_MASK(XVPHY_CHANNEL_ID_CH4))
#define XVPHY_TXRX_INIT_STATUS_PMARESETDONE_ALL_MASK \
(XVPHY_TXRX_INIT_STATUS_PMARESETDONE_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_TXRX_INIT_STATUS_PMARESETDONE_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_TXRX_INIT_STATUS_PMARESETDONE_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_TXRX_INIT_STATUS_PMARESETDONE_MASK(XVPHY_CHANNEL_ID_CH4))
/* 0x02C: IBUFDS_GTXX_CTRL */
#define XVPHY_IBUFDS_GTXX_CTRL_GTREFCLK0_CEB_MASK 0x1
#define XVPHY_IBUFDS_GTXX_CTRL_GTREFCLK1_CEB_MASK 0x2
/* 0x030: POWERDOWN_CONTROL */
#define XVPHY_POWERDOWN_CONTROL_CPLLPD_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_POWERDOWN_CONTROL_QPLL0PD_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_POWERDOWN_CONTROL_QPLL1PD_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_POWERDOWN_CONTROL_RXPD_MASK(Ch) \
(0x18 << (8 * (Ch - 1)))
#define XVPHY_POWERDOWN_CONTROL_RXPD_SHIFT(Ch) \
(3 + (8 * (Ch - 1)))
#define XVPHY_POWERDOWN_CONTROL_TXPD_MASK(Ch) \
(0x60 << (8 * (Ch - 1)))
#define XVPHY_POWERDOWN_CONTROL_TXPD_SHIFT(Ch) \
(5 + (8 * (Ch - 1)))
/* 0x038: LOOPBACK_CONTROL */
#define XVPHY_LOOPBACK_CONTROL_CH_MASK(Ch) \
(0x03 << (8 * (Ch - 1)))
#define XVPHY_LOOPBACK_CONTROL_CH_SHIFT(Ch) \
(8 * (Ch - 1))
/* 0x040, 0x044, 0x048, 0x04C, 0x060: DRP_CONTROL_CH[1-4], DRP_CONTROL_COMMON */
#define XVPHY_DRP_CONTROL_DRPADDR_MASK 0x00000FFF
#define XVPHY_DRP_CONTROL_DRPEN_MASK 0x00001000
#define XVPHY_DRP_CONTROL_DRPWE_MASK 0x00002000
#define XVPHY_DRP_CONTROL_DRPRESET_MASK 0x00004000
#define XVPHY_DRP_CONTROL_DRPDI_MASK 0xFFFF0000
#define XVPHY_DRP_CONTROL_DRPDI_SHIFT 16
/* 0x050, 0x054, 0x058, 0x05C, 0x064: DRP_STATUS_CH[1-4], DRP_STATUS_COMMON */
#define XVPHY_DRP_STATUS_DRPO_MASK 0x0FFFF
#define XVPHY_DRP_STATUS_DRPRDY_MASK 0x10000
#define XVPHY_DRP_STATUS_DRPBUSY_MASK 0x20000
/* 0x070: TX_CONTROL */
#define XVPHY_TX_CONTROL_TX8B10BEN_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_TX_CONTROL_TX8B10BEN_ALL_MASK \
(XVPHY_TX_CONTROL_TX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_TX_CONTROL_TX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_TX_CONTROL_TX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_TX_CONTROL_TX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH4))
#define XVPHY_TX_CONTROL_TXPOLARITY_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_TX_CONTROL_TXPRBSSEL_MASK(Ch) \
(0x1C << (8 * (Ch - 1)))
#define XVPHY_TX_CONTROL_TXPRBSSEL_SHIFT(Ch) \
(2 + (8 * (Ch - 1)))
#define XVPHY_TX_CONTROL_TXPRBSFORCEERR_MASK(Ch) \
(0x20 << (8 * (Ch - 1)))
/* 0x074: TX_BUFFER_BYPASS */
#define XVPHY_TX_BUFFER_BYPASS_TXPHDLYRESET_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXPHALIGN_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXPHALIGNEN_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXPHDLYPD_MASK(Ch) \
(0x08 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXPHINIT_MASK(Ch) \
(0x10 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXDLYRESET_MASK(Ch) \
(0x20 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXDLYBYPASS_MASK(Ch) \
(0x40 << (8 * (Ch - 1)))
#define XVPHY_TX_BUFFER_BYPASS_TXDLYEN_MASK(Ch) \
(0x80 << (8 * (Ch - 1)))
/* 0x078: TX_STATUS */
#define XVPHY_TX_STATUS_TXPHALIGNDONE_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_TX_STATUS_TXPHINITDONE_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_TX_STATUS_TXDLYRESETDONE_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_TX_STATUS_TXBUFSTATUS_MASK(Ch) \
(0x18 << (8 * (Ch - 1)))
#define XVPHY_TX_STATUS_TXBUFSTATUS_SHIFT(Ch) \
(3 + (8 * (Ch - 1)))
/* 0x07C, 0x080: TX_DRIVER_CH12, TX_DRIVER_CH34 */
#define XVPHY_TX_DRIVER_TXDIFFCTRL_MASK(Ch) \
(0x000F << (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXDIFFCTRL_SHIFT(Ch) \
(16 * ((Ch - 1) % 2))
#define XVPHY_TX_DRIVER_TXELECIDLE_MASK(Ch) \
(0x0010 << (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXELECIDLE_SHIFT(Ch) \
(4 + (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXINHIBIT_MASK(Ch) \
(0x0020 << (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXINHIBIT_SHIFT(Ch) \
(5 + (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXPOSTCURSOR_MASK(Ch) \
(0x07C0 << (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXPOSTCURSOR_SHIFT(Ch) \
(6 + (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXPRECURSOR_MASK(Ch) \
(0xF800 << (16 * ((Ch - 1) % 2)))
#define XVPHY_TX_DRIVER_TXPRECURSOR_SHIFT(Ch) \
(11 + (16 * ((Ch - 1) % 2)))
/* 0x100: RX_CONTROL */
#define XVPHY_RX_CONTROL_RX8B10BEN_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_RX_CONTROL_RX8B10BEN_ALL_MASK \
(XVPHY_RX_CONTROL_RX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_RX_CONTROL_RX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_RX_CONTROL_RX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_RX_CONTROL_RX8B10BEN_MASK(XVPHY_CHANNEL_ID_CH4))
#define XVPHY_RX_CONTROL_RXPOLARITY_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_RX_CONTROL_RXPRBSCNTRESET_MASK(Ch) \
(0x08 << (8 * (Ch - 1)))
#define XVPHY_RX_CONTROL_RXPRBSSEL_MASK(Ch) \
(0x70 << (8 * (Ch - 1)))
#define XVPHY_RX_CONTROL_RXPRBSSEL_SHIFT(Ch) \
(4 + (8 * (Ch - 1)))
/* 0x104: RX_STATUS */
#define XVPHY_RX_STATUS_RXCDRLOCK_MASK(Ch) \
(0x1 << (8 * (Ch - 1)))
#define XVPHY_RX_STATUS_RXBUFSTATUS_MASK(Ch) \
(0xE << (8 * (Ch - 1)))
#define XVPHY_RX_STATUS_RXBUFSTATUS_SHIFT(Ch) \
(1 + (8 * (Ch - 1)))
/* 0x104: RX_EQ_CDR */
#define XVPHY_RX_CONTROL_RXLPMEN_MASK(Ch) \
(0x01 << (8 * (Ch - 1)))
#define XVPHY_RX_STATUS_RXCDRHOLD_MASK(Ch) \
(0x02 << (8 * (Ch - 1)))
#define XVPHY_RX_STATUS_RXOSOVRDEN_MASK(Ch) \
(0x04 << (8 * (Ch - 1)))
#define XVPHY_RX_STATUS_RXLPMLFKLOVRDEN_MASK(Ch) \
(0x08 << (8 * (Ch - 1)))
#define XVPHY_RX_STATUS_RXLPMHFOVRDEN_MASK(Ch) \
(0x10 << (8 * (Ch - 1)))
#define XVPHY_RX_CONTROL_RXLPMEN_ALL_MASK \
(XVPHY_RX_CONTROL_RXLPMEN_MASK(XVPHY_CHANNEL_ID_CH1) | \
XVPHY_RX_CONTROL_RXLPMEN_MASK(XVPHY_CHANNEL_ID_CH2) | \
XVPHY_RX_CONTROL_RXLPMEN_MASK(XVPHY_CHANNEL_ID_CH3) | \
XVPHY_RX_CONTROL_RXLPMEN_MASK(XVPHY_CHANNEL_ID_CH4))
/* 0x110, 0x114, 0x118, 0x11C: INTR_EN, INTR_DIS, INTR_MASK, INTR_STS */
#define XVPHY_INTR_TXRESETDONE_MASK 0x00000001
#define XVPHY_INTR_RXRESETDONE_MASK 0x00000002
#define XVPHY_INTR_CPLL_LOCK_MASK 0x00000004
#define XVPHY_INTR_QPLL0_LOCK_MASK 0x00000008
#define XVPHY_INTR_TXALIGNDONE_MASK 0x00000010
#define XVPHY_INTR_QPLL1_LOCK_MASK 0x00000020
#define XVPHY_INTR_TXCLKDETFREQCHANGE_MASK 0x00000040
#define XVPHY_INTR_RXCLKDETFREQCHANGE_MASK 0x00000080
#define XVPHY_INTR_TXTMRTIMEOUT_MASK 0x40000000
#define XVPHY_INTR_RXTMRTIMEOUT_MASK 0x80000000
#define XVPHY_INTR_QPLL_LOCK_MASK XVPHY_INTR_QPLL0_LOCK_MASK
/* 0x120, 0x140: MMCM_TXUSRCLK_CTRL, MMCM_RXUSRCLK_CTRL */
#define XVPHY_MMCM_USRCLK_CTRL_CFG_NEW_MASK 0x01
#define XVPHY_MMCM_USRCLK_CTRL_RST_MASK 0x02
#define XVPHY_MMCM_USRCLK_CTRL_CFG_SUCCESS_MASK 0x10
#define XVPHY_MMCM_USRCLK_CTRL_LOCKED_MASK 0x20
#define XVPHY_MMCM_USRCLK_CTRL_PWRDWN_MASK 0x400
/* 0x124, 0x144: MMCM_TXUSRCLK_REG1, MMCM_RXUSRCLK_REG1 */
#define XVPHY_MMCM_USRCLK_REG1_DIVCLK_MASK \
0x00000FF
#define XVPHY_MMCM_USRCLK_REG1_CLKFBOUT_MULT_MASK \
0x000FF00
#define XVPHY_MMCM_USRCLK_REG1_CLKFBOUT_MULT_SHIFT \
8
#define XVPHY_MMCM_USRCLK_REG1_CLKFBOUT_FRAC_MASK \
0x3FF0000
#define XVPHY_MMCM_USRCLK_REG1_CLKFBOUT_FRAC_SHIFT \
16
/* 0x128, 0x148: MMCM_TXUSRCLK_REG2, MMCM_RXUSRCLK_REG2 */
#define XVPHY_MMCM_USRCLK_REG2_DIVCLK_MASK \
0x00000FF
#define XVPHY_MMCM_USRCLK_REG2_CLKOUT0_FRAC_MASK \
0x3FF0000
#define XVPHY_MMCM_USRCLK_REG2_CLKOUT0_FRAC_SHIFT \
16
/* 0x12C, 0x130, 0x14C, 0x150: MMCM_TXUSRCLK_REG[3,4], MMCM_RXUSRCLK_REG[3,4] */
#define XVPHY_MMCM_USRCLK_REG34_DIVCLK_MASK \
0x00000FF
/* 0x134, 0x154: BUFGT_TXUSRCLK, BUFGT_RXUSRCLK */
#define XVPHY_BUFGGT_XXUSRCLK_CLR_MASK 0x1
#define XVPHY_BUFGGT_XXUSRCLK_DIV_MASK 0xE
#define XVPHY_BUFGGT_XXUSRCLK_DIV_SHIFT 1
/* 0x138, 0x158: MISC_TXUSRCLK_REG, MISC_RXUSERCLK_REG */
#define XVPHY_MISC_XXUSRCLK_CKOUT1_OEN_MASK 0x1
/* 0x200: CLKDET_CTRL */
#define XVPHY_CLKDET_CTRL_RUN_MASK 0x1
#define XVPHY_CLKDET_CTRL_TX_TMR_CLR_MASK 0x2
#define XVPHY_CLKDET_CTRL_RX_TMR_CLR_MASK 0x4
#define XVPHY_CLKDET_CTRL_TX_FREQ_RST_MASK 0x8
#define XVPHY_CLKDET_CTRL_RX_FREQ_RST_MASK 0x10
#define XVPHY_CLKDET_CTRL_FREQ_LOCK_THRESH_MASK 0x1FE0
#define XVPHY_CLKDET_CTRL_FREQ_LOCK_THRESH_SHIFT 5
/* 0x204: CLKDET_STAT */
#define XVPHY_CLKDET_STAT_TX_FREQ_ZERO_MASK 0x1
#define XVPHY_CLKDET_STAT_RX_FREQ_ZERO_MASK 0x2
#define XVPHY_CLKDET_STAT_TX_REFCLK_LOCK_MASK 0x3
#define XVPHY_CLKDET_STAT_TX_REFCLK_LOCK_CAP_MASK 0x4
/* 0x300: DRU_CTRL */
#define XVPHY_DRU_CTRL_RST_MASK(Ch) (0x01 << (8 * (Ch - 1)))
#define XVPHY_DRU_CTRL_EN_MASK(Ch) (0x02 << (8 * (Ch - 1)))
/* 0x304: DRU_STAT */
#define XVPHY_DRU_STAT_ACTIVE_MASK(Ch) (0x01 << (8 * (Ch - 1)))
#define XVPHY_DRU_STAT_VERSION_MASK 0xFF000000
#define XVPHY_DRU_STAT_VERSION_SHIFT 24
/* 0x30C, 0x318, 0x324, 0x330: DRU_CFREQ_H_CH[1-4] */
#define XVPHY_DRU_CFREQ_H_MASK 0x1F
/* 0x310, 0x31C, 0x328, 0x334: DRU_GAIN_CH[1-4] */
#define XVPHY_DRU_GAIN_G1_MASK 0x00001F
#define XVPHY_DRU_GAIN_G1_SHIFT 0
#define XVPHY_DRU_GAIN_G1_P_MASK 0x001F00
#define XVPHY_DRU_GAIN_G1_P_SHIFT 8
#define XVPHY_DRU_GAIN_G2_MASK 0x1F0000
#define XVPHY_DRU_GAIN_G2_SHIFT 16
/* @} */
/******************* Macros (Inline Functions) Definitions ********************/
/** @name Register access macro definitions.
* @{
*/
#define XVphy_In32 Xil_In32
#define XVphy_Out32 Xil_Out32
/* @} */
/******************************************************************************/
/**
* This is a low-level function that reads from the specified register.
*
* @param BaseAddress is the base address of the device.
* @param RegOffset is the register offset to be read from.
*
* @return The 32-bit value of the specified register.
*
* @note C-style signature:
* u32 XVphy_ReadReg(u32 BaseAddress, u32 RegOffset)
*
*******************************************************************************/
#define XVphy_ReadReg(BaseAddress, RegOffset) \
XVphy_In32((BaseAddress) + (RegOffset))
/******************************************************************************/
/**
* This is a low-level function that writes to the specified register.
*
* @param BaseAddress is the base address of the device.
* @param RegOffset is the register offset to write to.
* @param Data is the 32-bit data to write to the specified register.
*
* @return None.
*
* @note C-style signature:
* void XVphy_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
*
*******************************************************************************/
#define XVphy_WriteReg(BaseAddress, RegOffset, Data) \
XVphy_Out32((BaseAddress) + (RegOffset), (Data))
#endif /* XVPHY_HW_H_ */

View file

@ -0,0 +1,253 @@
/*******************************************************************************
*
* 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 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 xvphy_intr.c
*
* This file contains functions related to XVphy interrupt handling.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xvphy.h"
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function enables interrupts associated with the specified interrupt type.
*
* @param InstancePtr is a pointer to the XVphy instance.
* @param Intr is the interrupt type/mask to enable.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XVphy_IntrEnable(XVphy *InstancePtr, XVphy_IntrHandlerType Intr)
{
u32 RegVal;
RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_EN_REG);
RegVal |= Intr;
XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_EN_REG, RegVal);
}
/******************************************************************************/
/**
* This function disabled interrupts associated with the specified interrupt
* type.
*
* @param InstancePtr is a pointer to the XVphy instance.
* @param Intr is the interrupt type/mask to disable.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XVphy_IntrDisable(XVphy *InstancePtr, XVphy_IntrHandlerType Intr)
{
u32 RegVal;
RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
XVPHY_INTR_DIS_REG);
RegVal |= Intr;
XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_DIS_REG,
RegVal);
}
/******************************************************************************/
/**
* This function installs a callback function for the specified handler type.
*
* @param InstancePtr is a pointer to the XVPhy instance.
* @param HandlerType is the interrupt handler type which specifies which
* interrupt event to attach the callback for.
* @param CallbackFunc is the address to the callback function.
* @param CallbackRef is the user data item that will be passed to the
* callback function when it is invoked.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XVphy_SetIntrHandler(XVphy *InstancePtr, XVphy_IntrHandlerType HandlerType,
XVphy_IntrHandler CallbackFunc, void *CallbackRef)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((HandlerType == XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_QPLL_LOCK) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK) ||
(HandlerType ==
XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE) ||
(HandlerType ==
XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT) ||
(HandlerType == XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT));
Xil_AssertVoid(CallbackFunc != NULL);
Xil_AssertVoid(CallbackRef != NULL);
switch (HandlerType) {
case XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE:
InstancePtr->IntrTxResetDoneHandler = CallbackFunc;
InstancePtr->IntrTxResetDoneCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE:
InstancePtr->IntrRxResetDoneHandler = CallbackFunc;
InstancePtr->IntrRxResetDoneCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK:
InstancePtr->IntrCpllLockHandler = CallbackFunc;
InstancePtr->IntrCpllLockCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_QPLL_LOCK:
InstancePtr->IntrQpllLockHandler = CallbackFunc;
InstancePtr->IntrQpllLockCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE:
InstancePtr->IntrTxAlignDoneHandler = CallbackFunc;
InstancePtr->IntrTxAlignDoneCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK:
InstancePtr->IntrQpll1LockHandler = CallbackFunc;
InstancePtr->IntrQpll1LockCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE:
InstancePtr->IntrTxClkDetFreqChangeHandler =
CallbackFunc;
InstancePtr->IntrTxClkDetFreqChangeCallbackRef =
CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE:
InstancePtr->IntrRxClkDetFreqChangeHandler =
CallbackFunc;
InstancePtr->IntrRxClkDetFreqChangeCallbackRef =
CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT:
InstancePtr->IntrTxTmrTimeoutHandler = CallbackFunc;
InstancePtr->IntrTxTmrTimeoutCallbackRef = CallbackRef;
break;
case XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT:
InstancePtr->IntrRxTmrTimeoutHandler = CallbackFunc;
InstancePtr->IntrRxTmrTimeoutCallbackRef = CallbackRef;
break;
default:
break;
}
}
/******************************************************************************/
/**
* This function is the interrupt handler for the XVphy driver. It will detect
* what kind of interrupt has happened, and will invoke the appropriate callback
* function.
*
* @param InstancePtr is a pointer to the XVphy instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XVphy_InterruptHandler(XVphy *InstancePtr)
{
u32 IntrStatus;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/* Determine what kind of interrupts have occurred. */
IntrStatus = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
XVPHY_INTR_STS_REG);
if (IntrStatus & XVPHY_INTR_CPLL_LOCK_MASK) {
InstancePtr->IntrCpllLockHandler(
InstancePtr->IntrCpllLockCallbackRef);
}
if (IntrStatus & XVPHY_INTR_QPLL_LOCK_MASK) {
InstancePtr->IntrQpllLockHandler(
InstancePtr->IntrQpllLockCallbackRef);
}
if (IntrStatus & XVPHY_INTR_QPLL1_LOCK_MASK) {
InstancePtr->IntrQpll1LockHandler(
InstancePtr->IntrQpll1LockCallbackRef);
}
if (IntrStatus & XVPHY_INTR_TXRESETDONE_MASK) {
InstancePtr->IntrTxResetDoneHandler(
InstancePtr->IntrTxResetDoneCallbackRef);
}
if (IntrStatus & XVPHY_INTR_TXALIGNDONE_MASK) {
InstancePtr->IntrTxAlignDoneHandler(
InstancePtr->IntrTxAlignDoneCallbackRef);
}
if (IntrStatus & XVPHY_INTR_RXRESETDONE_MASK) {
InstancePtr->IntrRxResetDoneHandler(
InstancePtr->IntrRxResetDoneCallbackRef);
}
if (IntrStatus & XVPHY_INTR_TXCLKDETFREQCHANGE_MASK) {
InstancePtr->IntrTxClkDetFreqChangeHandler(
InstancePtr->IntrTxClkDetFreqChangeCallbackRef);
}
if (IntrStatus & XVPHY_INTR_RXCLKDETFREQCHANGE_MASK) {
InstancePtr->IntrRxClkDetFreqChangeHandler(
InstancePtr->IntrRxClkDetFreqChangeCallbackRef);
}
if (IntrStatus & XVPHY_INTR_TXTMRTIMEOUT_MASK) {
InstancePtr->IntrTxTmrTimeoutHandler(
InstancePtr->IntrTxTmrTimeoutCallbackRef);
}
if (IntrStatus & XVPHY_INTR_RXTMRTIMEOUT_MASK) {
InstancePtr->IntrRxTmrTimeoutHandler(
InstancePtr->IntrRxTmrTimeoutCallbackRef);
}
}

View file

@ -0,0 +1,362 @@
/*******************************************************************************
*
* 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 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 xvphy.c
*
* Contains a minimal set of functions for the XVphy driver that allow access
* to all of the Video PHY core's functionality. See xvphy.h for a detailed
* description of the driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xvphy.h"
/**************************** Function Prototypes *****************************/
/**************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* This function will reset the driver's logginc mechanism.
*
* @param InstancePtr is a pointer to the XVphy core instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_LogReset(XVphy *InstancePtr)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
InstancePtr->Log.HeadIndex = 0;
InstancePtr->Log.TailIndex = 0;
}
/*****************************************************************************/
/**
* This function will insert an event in the driver's logginc mechanism.
*
* @param InstancePtr is a pointer to the XVphy core instance.
* @param Evt is the event type to log.
* @param Data is the associated data for the event.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_LogWrite(XVphy *InstancePtr, XVphy_LogEvent Evt, u8 Data)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(Evt <= (XVPHY_LOG_EVT_RX_FREQ));
Xil_AssertVoid(Data < 0xFF);
/* Write data and event into log buffer */
InstancePtr->Log.DataBuffer[InstancePtr->Log.HeadIndex] =
(Data << 8) | Evt;
/* Update head pointer if reached to end of the buffer */
if (InstancePtr->Log.HeadIndex ==
(u8)((sizeof(InstancePtr->Log.DataBuffer) / 2) - 1)) {
/* Clear pointer */
InstancePtr->Log.HeadIndex = 0;
}
else {
/* Increment pointer */
InstancePtr->Log.HeadIndex++;
}
/* Check tail pointer. When the two pointer are equal, then the buffer
* is full. In this case then increment the tail pointer as well to
* remove the oldest entry from the buffer. */
if (InstancePtr->Log.TailIndex == InstancePtr->Log.HeadIndex) {
if (InstancePtr->Log.TailIndex ==
(u8)((sizeof(InstancePtr->Log.DataBuffer) / 2) - 1)) {
InstancePtr->Log.TailIndex = 0;
}
else {
InstancePtr->Log.TailIndex++;
}
}
}
/*****************************************************************************/
/**
* This function will read the last event from the log.
*
* @param InstancePtr is a pointer to the XVphy core instance.
*
* @return The log data.
*
* @note None.
*
******************************************************************************/
u16 XVphy_LogRead(XVphy *InstancePtr)
{
u16 Log;
/* Verify argument. */
Xil_AssertNonvoid(InstancePtr != NULL);
/* Check if there is any data in the log */
if (InstancePtr->Log.TailIndex == InstancePtr->Log.HeadIndex) {
Log = 0;
}
else {
Log = InstancePtr->Log.DataBuffer[InstancePtr->Log.TailIndex];
/* Increment tail pointer */
if (InstancePtr->Log.TailIndex ==
(u8)((sizeof(InstancePtr->Log.DataBuffer) / 2) - 1)) {
InstancePtr->Log.TailIndex = 0;
}
else {
InstancePtr->Log.TailIndex++;
}
}
return Log;
}
/*****************************************************************************/
/**
* This function will print the entire log.
*
* @param InstancePtr is a pointer to the XVphy core instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XVphy_LogDisplay(XVphy *InstancePtr)
{
u16 Log;
u8 Evt;
u8 Data;
/* Verify argument. */
Xil_AssertVoid(InstancePtr != NULL);
xil_printf("\r\n\n\nVPHY log\r\n");
xil_printf("------\r\n");
do {
/* Read log data */
Log = XVphy_LogRead(InstancePtr);
/* Event */
Evt = Log & 0xff;
/* Data */
Data = (Log >> 8) & 0xFF;
switch (Evt) {
case (XVPHY_LOG_EVT_NONE):
xil_printf("GT log end\r\n-------\r\n");
break;
case (XVPHY_LOG_EVT_QPLL_EN):
xil_printf("QPLL enable (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_QPLL_RST):
xil_printf("QPLL reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_CPLL_EN):
xil_printf("CPLL enable (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_CPLL_RST):
xil_printf("CPLL reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_TXPLL_EN):
xil_printf("TX MMCM enable (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_TXPLL_RST):
xil_printf("TX MMCM reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_RXPLL_EN):
xil_printf("RX MMCM enable (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_RXPLL_RST):
xil_printf("RX MMCM reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_GTRX_RST):
xil_printf("GT RX reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_GTTX_RST):
xil_printf("GT TX reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_VID_TX_RST):
xil_printf("Video TX reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_VID_RX_RST):
xil_printf("Video RX reset (%0d)\r\n", Data);
break;
case (XVPHY_LOG_EVT_TX_ALIGN):
if (Data == 1) {
xil_printf("done\r\n");
}
else {
xil_printf("TX alignment start.\r\n.");
}
break;
case (XVPHY_LOG_EVT_TX_TMR):
if (Data == 1) {
xil_printf("TX timer event\r\n");
}
else {
xil_printf("TX timer load\r\n");
}
break;
case (XVPHY_LOG_EVT_RX_TMR):
if (Data == 1) {
xil_printf("RX timer event\r\n");
}
else {
xil_printf("RX timer load\r\n");
}
break;
case (XVPHY_LOG_EVT_CPLL_RECONFIG):
if (Data == 1) {
xil_printf("done\r\n");
}
else {
xil_printf("CPLL reconfig start\r\n");
}
break;
case (XVPHY_LOG_EVT_GT_RECONFIG):
if (Data == 1) {
xil_printf("done\r\n");
}
else {
xil_printf("GT reconfig start\r\n");
}
break;
case (XVPHY_LOG_EVT_QPLL_RECONFIG):
if (Data == 1) {
xil_printf("done\r\n");
}
else {
xil_printf("QPLL reconfig start\r\n");
}
break;
case (XVPHY_LOG_EVT_INIT):
if (Data == 1) {
xil_printf("GT init done\r\n");
}
else {
xil_printf("GT Init start\r\n");
}
break;
case (XVPHY_LOG_EVT_TXPLL_RECONFIG):
if (Data == 1) {
xil_printf("done\r\n");
}
else {
xil_printf("TX MMCM reconfig start\r\n");
}
break;
case (XVPHY_LOG_EVT_RXPLL_RECONFIG):
if (Data == 1) {
xil_printf("done\r\n");
}
else {
xil_printf("RX MMCM reconfig start\r\n");
}
break;
case (XVPHY_LOG_EVT_QPLL_LOCK):
if (Data == 1) {
xil_printf("QPLL lock\r\n");
}
else {
xil_printf("QPLL lost lock\r\n");
}
break;
case (XVPHY_LOG_EVT_CPLL_LOCK):
if (Data == 1) {
xil_printf("CPLL lock\r\n");
}
else {
xil_printf("CPLL lost lock\r\n");
}
break;
case (XVPHY_LOG_EVT_RXPLL_LOCK):
if (Data == 1) {
xil_printf("RX MMCM lock\r\n");
}
else {
xil_printf("RX MMCM lost lock\r\n");
}
break;
case (XVPHY_LOG_EVT_TXPLL_LOCK):
if (Data == 1) {
xil_printf("TX MMCM lock\r\n");
}
else {
xil_printf("TX MMCM lost lock\r\n");
}
break;
case (XVPHY_LOG_EVT_TX_RST_DONE):
xil_printf("TX reset done\r\n");
break;
case (XVPHY_LOG_EVT_RX_RST_DONE):
xil_printf("RX reset done\r\n");
break;
case (XVPHY_LOG_EVT_TX_FREQ):
xil_printf("TX frequency event\r\n");
break;
case (XVPHY_LOG_EVT_RX_FREQ):
xil_printf("RX frequency event\r\n");
break;
default:
xil_printf("Unknown event\r\n");
break;
}
} while (Log != 0);
}

View file

@ -0,0 +1,102 @@
/*******************************************************************************
*
* 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 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 xvphy_selftest.c
*
* This file contains a diagnostic self-test function for the XVphy driver. It
* will check many of the Video PHY's register values against the default
* reset values as a sanity-check that the core is ready to be used.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xvphy.h"
#include "xstatus.h"
/**************************** Variable Definitions ****************************/
/**
* This table contains the default values for the Video PHY core's registers.
*/
static u32 ResetValues[1][2] =
{
{XVPHY_VERSION_REG, 0}
};
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function runs a self-test on the XVphy driver/device. The sanity test
* checks whether or not all tested registers hold their default reset values.
*
* @param InstancePtr is a pointer to the XVphy instance.
*
* @return
* - XST_SUCCESS if the self-test passed - all tested registers
* hold their default reset values.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 XVphy_SelfTest(XVphy *InstancePtr)
{
u8 Index;
u32 Val;
/* Compare general usage registers with their default values. */
for (Index = 0; Index < 1; Index++) {
Val = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
ResetValues[Index][0]);
/* Fail if register does not hold default value. */
if (Val != ResetValues[Index][1]) {
return XST_FAILURE;
}
}
/* All tested registers hold their default reset values. */
return XST_SUCCESS;
}

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 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 xvphy_sinit.c
*
* This file contains static initialization methods for the XVphy driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 10/19/15 Initial release.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xparameters.h"
#include "xvphy.h"
/*************************** Variable Declarations ****************************/
#ifndef XPAR_XVPHY_NUM_INSTANCES
#define XPAR_XVPHY_NUM_INSTANCES 0
#endif
/**
* A table of configuration structures containing the configuration information
* for each Video PHY core in the system.
*/
extern XVphy_Config XVphy_ConfigTable[XPAR_XVPHY_NUM_INSTANCES];
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function looks for the device configuration based on the unique device
* ID. The table XVphy_ConfigTable[] contains the configuration information for
* each 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.
*
* @note None.
*
*******************************************************************************/
XVphy_Config *XVphy_LookupConfig(u16 DeviceId)
{
XVphy_Config *CfgPtr = NULL;
u32 Index;
for (Index = 0; Index < XPAR_XVPHY_NUM_INSTANCES; Index++) {
if (XVphy_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XVphy_ConfigTable[Index];
break;
}
}
return CfgPtr;
}