aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRohit Consul <rohitco@xilinx.com>2017-05-05 11:44:18 -0700
committerJeffrey Mouroux <jmouroux@xilinx.com>2017-06-28 11:16:02 -0700
commit7290bf423f13ec6a996b443160bfd4a1f9629deb (patch)
treeebe589e94ab073df1ac419b09a52cb75cabdeef1
parentd38208141cf2590ac864ff58afd18e3e8a417cd5 (diff)
downloadlinux-7290bf423f13ec6a996b443160bfd4a1f9629deb.tar.gz
phy: xilinx-vphy: Initial release of xilinx video phy soft IP driver
Xilinx Video Phy implements the physical layer for enabling the plug-and-play connectivity with HDMI MAC transmit and receive subsystems. Driver is being released in staging area and is in experimental state. Signed-off-by: Rohit Consul <rohitco@xilinx.com>
-rw-r--r--drivers/staging/xilinx/hdmi/include/linux/phy/phy-vphy.h52
-rw-r--r--drivers/staging/xilinx/hdmi/include/linux/phy/xvphy.h846
-rw-r--r--drivers/staging/xilinx/hdmi/include/linux/phy/xvphy_hw.h567
-rw-r--r--drivers/staging/xilinx/hdmi/phy-vphy.c633
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/sleep.h34
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xdebug.h32
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_assert.h90
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_io.h72
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_printf.h50
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_types.h200
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xstatus.h519
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.c1013
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.h542
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.c691
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.h468
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_timings_table.c435
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.c1342
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.h846
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gt.h117
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gthe4.c1277
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.c2384
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.h149
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi_intr.c1153
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hw.h567
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.c1441
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.h126
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_intr.c274
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_log.c467
-rw-r--r--drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_sinit.c81
29 files changed, 16468 insertions, 0 deletions
diff --git a/drivers/staging/xilinx/hdmi/include/linux/phy/phy-vphy.h b/drivers/staging/xilinx/hdmi/include/linux/phy/phy-vphy.h
new file mode 100644
index 00000000000000..e6681f9a9e6a99
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/include/linux/phy/phy-vphy.h
@@ -0,0 +1,52 @@
+/*
+ * Xilinx VPHY header
+ *
+ * Copyright (C) 2016-2017 Xilinx, Inc.
+ *
+ * Author: Leon Woestenberg <leon@sidebranch.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _PHY_VPHY_H_
+#define _PHY_VPHY_H_
+
+/* @TODO change directory name on production release */
+#include "xvphy.h"
+
+struct phy;
+
+/* VPHY is built (either as module or built-in) */
+#if defined(CONFIG_PHY_XILINX_VPHY)
+
+extern XVphy *xvphy_get_xvphy(struct phy *phy);
+extern void xvphy_mutex_lock(struct phy *phy);
+extern void xvphy_mutex_unlock(struct phy *phy);
+extern int xvphy_do_something(struct phy *phy);
+
+/* VPHY is not compiled in, make sure RX and TX fail */
+#else
+
+static inline XVphy *xvphy_get_xvphy(struct phy *phy)
+{
+ return NULL;
+}
+
+static inline void xvphy_mutex_lock(struct phy *phy) {}
+static inline void xvphy_mutex_unlock(struct phy *phy) {}
+
+static inline int xvphy_do_something(struct phy *phy)
+{
+ return -ENODEV;
+}
+
+#endif /* (defined(CONFIG_PHY_XILINX_VPHY)) */
+
+#endif /* _PHY_VPHY_H_ */
diff --git a/drivers/staging/xilinx/hdmi/include/linux/phy/xvphy.h b/drivers/staging/xilinx/hdmi/include/linux/phy/xvphy.h
new file mode 100644
index 00000000000000..ac3647b0771ea3
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/include/linux/phy/xvphy.h
@@ -0,0 +1,846 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added EAST, WEST, PLL0 and PLL1 definitions
+ * for GTPE2.
+ * Added more events to XVphy_LogEvent definitions
+ * Added TxBufferBypass in XVphy_Config structure
+ * Added XVphy_SetDefaultPpc and XVphy_SetPpc functions
+ * als Added XVphy_GetLineRateHz function.
+ * 1.2 gm Added HdmiFastSwitch in XVphy_Config
+ * Changed EffectiveAddr datatype in XVphy_CfgInitialize
+ * to UINTPTR
+ * Added log events for debugging
+ * 1.2 gm 11/11/19 Added TransceiverWidth in XVphy_Config
+ * 1.4 gm 29/11/16 Moved internally used APIs to xvphy_i.c/h
+ * Added preprocessor directives for sw footprint reduction
+ * Made debug log optional (can be disabled via makefile)
+ * Added ERR_IRQ type_defs (not for official use for
+ * Xilinx debugging)
+ * Added transceiver width, AXIlite clk frequency and
+ * err_irq in XVphy_Config
+ * </pre>
+ *
+*******************************************************************************/
+
+#ifndef XVPHY_H_
+/* Prevent circular inclusions by using protection macros. */
+#define XVPHY_H_
+
+#if !defined(XV_CONFIG_LOG_VPHY_DISABLE) && !defined(XV_CONFIG_LOG_DISABLE_ALL)
+#define XV_VPHY_LOG_ENABLE
+#endif
+
+/******************************* Include Files ********************************/
+
+#include "xil_assert.h"
+#include "xvphy_hw.h"
+#include "xil_printf.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_GTEASTREFCLK0 =
+ XVPHY_REF_CLK_SEL_XPLL_GTEASTREFCLK0,
+ XVPHY_PLL_REFCLKSEL_TYPE_GTEASTREFCLK1 =
+ XVPHY_REF_CLK_SEL_XPLL_GTEASTREFCLK1,
+ XVPHY_PLL_REFCLKSEL_TYPE_GTWESTREFCLK0 =
+ XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK0,
+ XVPHY_PLL_REFCLKSEL_TYPE_GTWESTREFCLK1 =
+ XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK1,
+ 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_PLL0_OUTCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_PLL0,
+ XVPHY_SYSCLKSELDATA_TYPE_PLL1_OUTCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_PLL1,
+ 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_SYSCLKSELOUT_TYPE_PLL0_REFCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CH,
+ XVPHY_SYSCLKSELOUT_TYPE_PLL1_REFCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN,
+} 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;
+
+#ifdef XV_VPHY_LOG_ENABLE
+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_ALIGN_TMOUT, /**< Log event TX align Timeout. */
+ 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_GT_TX_RECONFIG, /**< Log event GT reconfig. */
+ XVPHY_LOG_EVT_GT_RX_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_LOG_EVT_DRU_EN, /**< Log event DRU enable/disable. */
+ XVPHY_LOG_EVT_GT_PLL_LAYOUT,/**< Log event GT PLL Layout Change. */
+ XVPHY_LOG_EVT_GT_UNBONDED, /**< Log event GT Unbonded Change. */
+ XVPHY_LOG_EVT_1PPC_ERR, /**< Log event 1 PPC Error. */
+ XVPHY_LOG_EVT_PPC_MSMTCH_ERR,/**< Log event PPC MismatchError. */
+ XVPHY_LOG_EVT_VDCLK_HIGH_ERR,/**< Log event VidClk more than 148.5 MHz. */
+ XVPHY_LOG_EVT_NO_DRU, /**< Log event Vid not supported no DRU. */
+ XVPHY_LOG_EVT_GT_QPLL_CFG_ERR,/**< Log event QPLL Config not found. */
+ XVPHY_LOG_EVT_GT_CPLL_CFG_ERR,/**< Log event QPLL Config not found. */
+ XVPHY_LOG_EVT_VD_NOT_SPRTD_ERR,/**< Log event Vid format not supported. */
+ XVPHY_LOG_EVT_MMCM_ERR, /**< Log event MMCM Config not found. */
+ XVPHY_LOG_EVT_DUMMY, /**< Dummy Event should be last */
+} XVphy_LogEvent;
+#endif
+
+/* This typedef enumerates the possible error conditions. */
+typedef enum {
+ XVPHY_ERRIRQ_QPLL_CFG = 0x1, /**< QPLL CFG not found. */
+ XVPHY_ERRIRQ_CPLL_CFG = 0x2, /**< CPLL CFG not found. */
+ XVPHY_ERRIRQ_NO_DRU = 0x4, /**< No DRU in design. */
+ XVPHY_ERRIRQ_VD_NOT_SPRTD= 0x8, /**< Video Not Supported. */
+ XVPHY_ERRIRQ_MMCM_CFG = 0x10,/**< MMCM CFG not found. */
+ XVPHY_ERRIRQ_PLL_LAYOUT = 0x20,/**< PLL Error. */
+} XVphy_ErrIrqType;
+
+/******************************************************************************/
+/**
+ * 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. */
+ u8 TxDataWidth; /**< In bits. */
+ u8 TxIntDataWidth; /**< 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;
+
+#ifdef XV_VPHY_LOG_ENABLE
+/**
+ * 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;
+#endif
+
+/**
+ * This typedef contains configuration information for the Video PHY core.
+ */
+typedef struct {
+ u16 DeviceId; /**< Device instance ID. */
+ UINTPTR 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. */
+ XVidC_PixelsPerClock Ppc; /**< Number of input pixels per
+ clock. */
+ u8 TxBufferBypass; /**< TX Buffer Bypass is enabled in the
+ design. */
+ u8 HdmiFastSwitch; /**< HDMI fast switching is enabled in the
+ design. */
+ u8 TransceiverWidth; /**< Transceiver Width seeting in the design */
+ u32 ErrIrq; /**< Error IRQ is enalbed in design */
+ u32 AxiLiteClkFreq; /**< AXI Lite Clock Frequency in Hz */
+} 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;
+#ifdef XV_VPHY_LOG_ENABLE
+ XVphy_Log Log; /**< A log of events. */
+#endif
+ 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,
+ UINTPTR EffectiveAddr);
+u32 XVphy_PllInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_PllRefClkSelType QpllRefClkSel,
+ XVphy_PllRefClkSelType CpllxRefClkSel,
+ XVphy_PllType TxPllSelect, XVphy_PllType RxPllSelect);
+#if defined (XPAR_XDP_0_DEVICE_ID)
+u32 XVphy_ClkInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir);
+#endif
+u32 XVphy_GetVersion(XVphy *InstancePtr);
+void XVphy_WaitUs(XVphy *InstancePtr, u32 MicroSeconds);
+void XVphy_SetUserTimerHandler(XVphy *InstancePtr,
+ XVphy_TimerHandler CallbackFunc, void *CallbackRef);
+
+/* xvphy.c: Channel configuration functions - setters. */
+u32 XVphy_CfgLineRate(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u64 LineRateHz);
+#if defined (XPAR_XDP_0_DEVICE_ID)
+u32 XVphy_CfgQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
+ XVphy_PllRefClkSelType RefClkType, u32 FreqHz);
+#endif
+
+/* xvphy.c: Channel configuration functions - getters. */
+XVphy_PllType XVphy_GetPllType(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_ChannelId ChId);
+u64 XVphy_GetLineRateHz(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+
+/* xvphy.c: Reset functions. */
+#if defined (XPAR_XDP_0_DEVICE_ID)
+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);
+#endif
+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);
+
+/* 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_MmcmPowerDown(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Hold);
+void XVphy_MmcmStart(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir);
+void XVphy_IBufDsEnable(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Enable);
+void XVphy_Clkout1OBufTdsEnable(XVphy *InstancePtr, XVphy_DirectionType Dir,
+ u8 Enable);
+#if defined (XPAR_XDP_0_DEVICE_ID)
+void XVphy_BufgGtReset(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Reset);
+
+/* xvphy.c Miscellaneous control. */
+void XVphy_Set8b10b(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Enable);
+#endif
+u32 XVphy_IsBonded(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+
+/* xvphy_log.c: Logging functions. */
+void XVphy_LogDisplay(XVphy *InstancePtr);
+void XVphy_LogReset(XVphy *InstancePtr);
+u16 XVphy_LogRead(XVphy *InstancePtr);
+#ifdef XV_VPHY_LOG_ENABLE
+void XVphy_LogWrite(XVphy *InstancePtr, XVphy_LogEvent Evt, u8 Data);
+#else
+#define XVphy_LogWrite(...)
+#endif
+
+/* xvphy_intr.c: Interrupt handling functions. */
+void XVphy_InterruptHandler(XVphy *InstancePtr);
+
+/* 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)) || \
+ (XVPHY_PLL_TYPE_PLL0 == \
+ XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId)) || \
+ (XVPHY_PLL_TYPE_PLL1 == \
+ 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)) || \
+ (XVPHY_PLL_TYPE_PLL0 == \
+ XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId)) || \
+ (XVPHY_PLL_TYPE_PLL1 == \
+ 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))
+
+#define XVPHY_GTXE2 1
+#define XVPHY_GTHE2 2
+#define XVPHY_GTPE2 3
+#define XVPHY_GTHE3 4
+#define XVPHY_GTHE4 5
+
+#endif /* XVPHY_H_ */
diff --git a/drivers/staging/xilinx/hdmi/include/linux/phy/xvphy_hw.h b/drivers/staging/xilinx/hdmi/include/linux/phy/xvphy_hw.h
new file mode 100644
index 00000000000000..6e06e8dc902ae2
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/include/linux/phy/xvphy_hw.h
@@ -0,0 +1,567 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added GTPE2 and GTHE4 support
+ * 1.4 gm 29/11/16 Added ERR_IRQ register offset
+ * </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_ERR_IRQ 0x03C
+#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_GTEASTREFCLK0 3
+#define XVPHY_REF_CLK_SEL_XPLL_GTEASTREFCLK1 4
+#define XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK0 5
+#define XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK1 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_PLL0 0
+#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_PLL1 1
+#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) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0x03000000 : 0x02000000)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_MASK(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0x0C000000 : 0x08000000)
+#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_MASK(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0x30000000 : 0x01000000)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_MASK(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0xC0000000 : 0x04000000)
+#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 24 : 25)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 26 : 27)
+#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 28 : 24)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 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))
+#define XVPHY_PLL_LOCK_STATUS_CPLL_HDMI_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))
+/* 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
+#define XVPHY_MMCM_USRCLK_CTRL_LOCKED_MASK_MASK 0x800
+/* 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
+#define XVPHY_MISC_XXUSRCLK_REFCLK_CEB_MASK 0x2
+/* 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_ */
diff --git a/drivers/staging/xilinx/hdmi/phy-vphy.c b/drivers/staging/xilinx/hdmi/phy-vphy.c
new file mode 100644
index 00000000000000..58c951f3ff07cb
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-vphy.c
@@ -0,0 +1,633 @@
+/*
+ * Xilinx VPHY driver
+ *
+ * The Video Phy is a high-level wrapper around the GT to configure it
+ * for video applications. The driver also provides common functionality
+ * for its tightly-bound video protocol drivers such as HDMI RX/TX.
+ *
+ * Copyright (C) 2016, 2017 Leon Woestenberg <leon@sidebranch.com>
+ * Copyright (C) 2014, 2015, 2017 Xilinx, Inc.
+ *
+ * Authors: Leon Woestenberg <leon@sidebranch.com>
+ * Rohit Consul <rohitco@xilinx.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* if both both DEBUG and DEBUG_TRACE are defined, trace_printk() is used */
+//#define DEBUG
+//#define DEBUG_TRACE
+
+//#define DEBUG_MUTEX
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <dt-bindings/phy/phy.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include "linux/phy/phy-vphy.h"
+
+/* baseline driver includes */
+#include "phy-xilinx-vphy/xvphy.h"
+#include "phy-xilinx-vphy/xvphy_i.h"
+#include "phy-xilinx-vphy/xil_printf.h"
+#include "phy-xilinx-vphy/xstatus.h"
+
+/* common RX/TX */
+#include "phy-xilinx-vphy/xvidc.h"
+#include "phy-xilinx-vphy/xvidc_edid.h"
+
+#define XVPHY_DRU_REF_CLK_HZ 156250000
+
+
+/* select either trace or printk logging */
+#ifdef DEBUG_TRACE
+#define do_hdmi_dbg(format, ...) do { \
+ trace_printk("xlnx-hdmi-vphy: " format, ##__VA_ARGS__); \
+} while(0)
+#else
+#define do_hdmi_dbg(format, ...) do { \
+ printk(KERN_DEBUG "xlnx-hdmi-vphy: " format, ##__VA_ARGS__); \
+} while(0)
+#endif
+
+/* either enable or disable debugging */
+#ifdef DEBUG
+# define hdmi_dbg(x...) do_hdmi_dbg(x)
+#else
+# define hdmi_dbg(x...)
+#endif
+
+#if (defined(DEBUG_MUTEX) && defined(DEBUG))
+/* storage for source code line number where mutex was last locked, -1 otherwise */
+static int hdmi_mutex_line = -1;
+/* If mutex is locked, print the line number of where it was locked. lock the mutex.
+ * Please keep this macro on a single line, so that the C __LINE__ macro is correct.
+ */
+# define hdmi_mutex_lock(x) do { if (mutex_is_locked(x)) { hdmi_dbg("@line %d waiting for mutex owner @line %d\n", __LINE__, hdmi_mutex_line); } mutex_lock(x); hdmi_mutex_line = __LINE__; } while(0)
+# define hdmi_mutex_unlock(x) do { hdmi_mutex_line = -1; mutex_unlock(x); } while(0)
+/* non-debug variant */
+#else
+# define hdmi_mutex_lock(x) mutex_lock(x)
+# define hdmi_mutex_unlock(x) mutex_unlock(x)
+#endif
+
+/**
+ * struct xvphy_lane - representation of a lane
+ * @phy: pointer to the kernel PHY device
+ *
+ * @type: controller which uses this lane
+ * @lane: lane number
+ * @protocol: protocol in which the lane operates
+ * @ref_clk: enum of allowed ref clock rates for this lane PLL
+ * @pll_lock: PLL status
+ * @data: pointer to hold private data
+ * @direction: 0=rx, 1=tx
+ * @share_laneclk: lane number of the clock to be shared
+ */
+struct xvphy_lane {
+ struct phy *phy;
+ u8 type;
+ u8 lane;
+ u8 protocol;
+ bool pll_lock;
+ /* data is pointer to parent xvphy_dev */
+ void *data;
+ bool direction_tx;
+ u32 share_laneclk;
+};
+
+/**
+ * struct xvphy_dev - representation of a Xilinx Video PHY
+ * @dev: pointer to device
+ * @iomem: serdes base address
+ */
+struct xvphy_dev {
+ struct device *dev;
+ /* virtual remapped I/O memory */
+ void __iomem *iomem;
+ int irq;
+ /* protects the XVphy baseline against concurrent access */
+ struct mutex xvphy_mutex;
+ struct xvphy_lane *lanes[4];
+ /* bookkeeping for the baseline subsystem driver instance */
+ XVphy xvphy;
+ /* AXI Lite clock drives the clock detector */
+ struct clk *axi_lite_clk;
+ /* NI-DRU clock input */
+ struct clk *clkp;
+};
+
+/* given the (Linux) phy handle, return the xvphy */
+XVphy *xvphy_get_xvphy(struct phy *phy)
+{
+ struct xvphy_lane *vphy_lane = phy_get_drvdata(phy);
+ struct xvphy_dev *vphy_dev = vphy_lane->data;
+ return &vphy_dev->xvphy;
+}
+EXPORT_SYMBOL_GPL(xvphy_get_xvphy);
+
+/* given the (Linux) phy handle, enter critical section of xvphy baseline code
+ * XVphy functions must be called with mutex acquired to prevent concurrent access
+ * by XVphy and upper-layer video protocol drivers */
+void xvphy_mutex_lock(struct phy *phy)
+{
+ struct xvphy_lane *vphy_lane = phy_get_drvdata(phy);
+ struct xvphy_dev *vphy_dev = vphy_lane->data;
+ hdmi_mutex_lock(&vphy_dev->xvphy_mutex);
+}
+EXPORT_SYMBOL_GPL(xvphy_mutex_lock);
+
+void xvphy_mutex_unlock(struct phy *phy)
+{
+ struct xvphy_lane *vphy_lane = phy_get_drvdata(phy);
+ struct xvphy_dev *vphy_dev = vphy_lane->data;
+ hdmi_mutex_unlock(&vphy_dev->xvphy_mutex);
+}
+EXPORT_SYMBOL_GPL(xvphy_mutex_unlock);
+
+/* XVphy functions must be called with mutex acquired to prevent concurrent access
+ * by XVphy and upper-layer video protocol drivers */
+EXPORT_SYMBOL_GPL(XVphy_GetPllType);
+EXPORT_SYMBOL_GPL(XVphy_IBufDsEnable);
+EXPORT_SYMBOL_GPL(XVphy_SetHdmiCallback);
+EXPORT_SYMBOL_GPL(XVphy_HdmiCfgCalcMmcmParam);
+EXPORT_SYMBOL_GPL(XVphy_MmcmStart);
+
+/* exclusively required by TX */
+EXPORT_SYMBOL_GPL(XVphy_Clkout1OBufTdsEnable);
+EXPORT_SYMBOL_GPL(XVphy_SetHdmiTxParam);
+EXPORT_SYMBOL_GPL(XVphy_IsBonded);
+
+static irqreturn_t xvphy_irq_handler(int irq, void *dev_id)
+{
+ struct xvphy_dev *vphydev;
+ BUG_ON(!dev_id);
+ vphydev = (struct xvphy_dev *)dev_id;
+ BUG_ON(!vphydev);
+ if (!vphydev)
+ return IRQ_NONE;
+
+ /* disable interrupts in the VPHY, they are re-enabled once serviced */
+ XVphy_IntrDisable(&vphydev->xvphy, XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE |
+ XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE |
+ XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK |
+ XVPHY_INTR_HANDLER_TYPE_QPLL0_LOCK |
+ XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE |
+ XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK |
+ XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE |
+ XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE |
+ XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT |
+ XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t xvphy_irq_thread(int irq, void *dev_id)
+{
+ struct xvphy_dev *vphydev;
+ u32 IntrStatus;
+ BUG_ON(!dev_id);
+ vphydev = (struct xvphy_dev *)dev_id;
+ BUG_ON(!vphydev);
+ if (!vphydev)
+ return IRQ_NONE;
+
+ /* call baremetal interrupt handler with mutex locked */
+ hdmi_mutex_lock(&vphydev->xvphy_mutex);
+
+ IntrStatus = XVphy_ReadReg(vphydev->xvphy.Config.BaseAddr, XVPHY_INTR_STS_REG);
+ printk(KERN_DEBUG "XVphy IntrStatus = 0x%08x\n", IntrStatus);
+
+ /* handle pending interrupts */
+ XVphy_InterruptHandler(&vphydev->xvphy);
+ hdmi_mutex_unlock(&vphydev->xvphy_mutex);
+
+ /* enable interrupt requesting in the VPHY */
+ XVphy_IntrEnable(&vphydev->xvphy, XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE |
+ XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE |
+ XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK |
+ XVPHY_INTR_HANDLER_TYPE_QPLL0_LOCK |
+ XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE |
+ XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK |
+ XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE |
+ XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE |
+ XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT |
+ XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT);
+
+#ifdef DEBUG
+ XVphy_LogDisplay(&vphydev->xvphy);
+#endif
+ return IRQ_HANDLED;
+}
+
+/**
+ * xvphy_phy_init - initializes a lane
+ * @phy: pointer to kernel PHY device
+ *
+ * Return: 0 on success or error on failure
+ */
+static int xvphy_phy_init(struct phy *phy)
+{
+ BUG_ON(!phy);
+ printk(KERN_INFO "xvphy_phy_init(%p).\n", phy);
+
+ return 0;
+}
+
+/**
+ * xvphy_xlate - provides a PHY specific to a controller
+ * @dev: pointer to device
+ * @args: arguments from dts
+ *
+ * Return: pointer to kernel PHY device or error on failure
+ *
+ *
+ */
+static struct phy *xvphy_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct xvphy_dev *vphydev = dev_get_drvdata(dev);
+ struct xvphy_lane *vphy_lane = NULL;
+ struct device_node *phynode = args->np;
+ int index;
+ u8 controller;
+ u8 instance_num;
+
+ if (args->args_count != 4) {
+ dev_err(dev, "Invalid number of cells in 'phy' property\n");
+ return ERR_PTR(-EINVAL);
+ }
+ if (!of_device_is_available(phynode)) {
+ dev_warn(dev, "requested PHY is disabled\n");
+ return ERR_PTR(-ENODEV);
+ }
+ for (index = 0; index < of_get_child_count(dev->of_node); index++) {
+ if (phynode == vphydev->lanes[index]->phy->dev.of_node) {
+ vphy_lane = vphydev->lanes[index];
+ break;
+ }
+ }
+ if (!vphy_lane) {
+ dev_err(dev, "failed to find appropriate phy\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* get type of controller from lanes */
+ controller = args->args[0];
+
+ /* get controller instance number */
+ instance_num = args->args[1];
+
+ /* Check if lane sharing is required */
+ vphy_lane->share_laneclk = args->args[2];
+
+ /* get the direction for controller from lanes */
+ vphy_lane->direction_tx = args->args[3];
+
+ BUG_ON(!vphy_lane->phy);
+ return vphy_lane->phy;
+}
+
+/* Local Global table for phy instance(s) configuration settings */
+XVphy_Config XVphy_ConfigTable[XPAR_XVPHY_NUM_INSTANCES];
+
+static struct phy_ops xvphy_phyops = {
+ .init = xvphy_phy_init,
+ .owner = THIS_MODULE,
+};
+
+static int instance = 0;
+/* TX uses [1, 127] and RX uses [128, 254], VPHY uses [256, ...] */
+#define VPHY_DEVICE_ID_BASE 256
+
+static int vphy_parse_of(struct xvphy_dev *vphydev, XVphy_Config *c)
+{
+ struct device *dev = vphydev->dev;
+ struct device_node *node = dev->of_node;
+ int rc;
+ u32 val;
+ bool has_err_irq;
+
+ rc = of_property_read_u32(node, "xlnx,transceiver-type", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->XcvrType = val;
+
+ rc = of_property_read_u32(node, "xlnx,tx-buffer-bypass", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->TxBufferBypass = val;
+
+ rc = of_property_read_u32(node, "xlnx,input-pixels-per-clock", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->Ppc = val;
+
+ rc = of_property_read_u32(node, "xlnx,nidru", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->DruIsPresent = val;
+
+ rc = of_property_read_u32(node, "xlnx,nidru-refclk-sel", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->DruRefClkSel = val;
+
+ rc = of_property_read_u32(node, "xlnx,rx-no-of-channels", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->RxChannels = val;
+
+ rc = of_property_read_u32(node, "xlnx,tx-no-of-channels", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->TxChannels = val;
+
+ rc = of_property_read_u32(node, "xlnx,rx-protocol", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->RxProtocol = val;
+
+ rc = of_property_read_u32(node, "xlnx,tx-protocol", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->TxProtocol = val;
+
+ rc = of_property_read_u32(node, "xlnx,rx-refclk-sel", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->RxRefClkSel = val;
+
+ rc = of_property_read_u32(node, "xlnx,tx-refclk-sel", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->TxRefClkSel = val;
+
+ rc = of_property_read_u32(node, "xlnx,rx-pll-selection", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->RxSysPllClkSel = val;
+
+ rc = of_property_read_u32(node, "xlnx,tx-pll-selection", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->TxSysPllClkSel = val;
+
+ rc = of_property_read_u32(node, "xlnx,hdmi-fast-switch", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->HdmiFastSwitch = val;
+
+ rc = of_property_read_u32(node, "xlnx,transceiver-width", &val);
+ if (rc < 0)
+ goto error_dt;
+ c->TransceiverWidth = val;
+
+ has_err_irq = false;
+ has_err_irq = of_property_read_bool(node, "xlnx,err-irq-en");
+ c->ErrIrq = has_err_irq;
+ return 0;
+
+error_dt:
+ dev_err(vphydev->dev, "Error parsing device tree");
+ return -EINVAL;
+}
+
+/**
+ * xvphy_probe - The device probe function for driver initialization.
+ * @pdev: pointer to the platform device structure.
+ *
+ * Return: 0 for success and error value on failure
+ */
+static int xvphy_probe(struct platform_device *pdev)
+{
+ struct device_node *child, *np = pdev->dev.of_node;
+ struct xvphy_dev *vphydev;
+ struct phy_provider *provider;
+ struct phy *phy;
+ unsigned long axi_lite_rate;
+ unsigned long dru_clk_rate;
+
+ struct resource *res;
+ int port = 0, index = 0;
+ int ret;
+ u32 Status;
+ u32 Data;
+ u16 DrpVal;
+
+ hdmi_dbg("xvphy probed\n");
+ vphydev = devm_kzalloc(&pdev->dev, sizeof(*vphydev), GFP_KERNEL);
+ if (!vphydev)
+ return -ENOMEM;
+
+ /* mutex that protects against concurrent access */
+ mutex_init(&vphydev->xvphy_mutex);
+
+ vphydev->dev = &pdev->dev;
+ /* set a pointer to our driver data */
+ platform_set_drvdata(pdev, vphydev);
+
+ BUG_ON(!np);
+
+ XVphy_ConfigTable[instance].DeviceId = VPHY_DEVICE_ID_BASE + instance;
+
+ hdmi_dbg("xvphy_probe DT parse start\n");
+ ret = vphy_parse_of(vphydev, &XVphy_ConfigTable[instance]);
+ if (ret) return ret;
+ hdmi_dbg("xvphy_probe DT parse done\n");
+
+ for_each_child_of_node(np, child) {
+ struct xvphy_lane *vphy_lane;
+
+ vphy_lane = devm_kzalloc(&pdev->dev, sizeof(*vphy_lane),
+ GFP_KERNEL);
+ if (!vphy_lane)
+ return -ENOMEM;
+
+ /* Assign lane number to gtr_phy instance */
+ vphy_lane->lane = index;
+
+ /* Disable lane sharing as default */
+ vphy_lane->share_laneclk = -1;
+
+ BUG_ON(port >= 4);
+ /* array of pointer to vphy_lane structs */
+ vphydev->lanes[port] = vphy_lane;
+
+ /* create phy device for each lane */
+ phy = devm_phy_create(&pdev->dev, child, &xvphy_phyops);
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ if (ret == -EPROBE_DEFER)
+ hdmi_dbg("xvphy probe deferred\n");
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to create PHY\n");
+ return ret;
+ }
+ /* array of pointer to phy */
+ vphydev->lanes[port]->phy = phy;
+ /* where each phy device has vphy_lane as driver data */
+ phy_set_drvdata(phy, vphydev->lanes[port]);
+ /* and each vphy_lane points back to parent device */
+ vphy_lane->data = vphydev;
+ port++;
+ index++;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ vphydev->iomem = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(vphydev->iomem))
+ return PTR_ERR(vphydev->iomem);
+
+ /* set address in configuration data */
+ XVphy_ConfigTable[instance].BaseAddr = (uintptr_t)vphydev->iomem;
+
+ vphydev->irq = platform_get_irq(pdev, 0);
+ if (vphydev->irq <= 0) {
+ dev_err(&pdev->dev, "platform_get_irq() failed\n");
+ return vphydev->irq;
+ }
+
+ /* the AXI lite clock is used for the clock rate detector */
+ vphydev->axi_lite_clk = devm_clk_get(&pdev->dev, "axi-lite");
+ if (IS_ERR(vphydev->axi_lite_clk)) {
+ ret = PTR_ERR(vphydev->axi_lite_clk);
+ vphydev->axi_lite_clk = NULL;
+ if (ret == -EPROBE_DEFER)
+ hdmi_dbg("axi-lite-clk not ready -EPROBE_DEFER\n");
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to get the axi lite clk.\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(vphydev->axi_lite_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable axi-lite clk\n");
+ return ret;
+ }
+ axi_lite_rate = clk_get_rate(vphydev->axi_lite_clk);
+ hdmi_dbg("AXI Lite clock rate = %lu Hz\n", axi_lite_rate);
+
+ /* set axi-lite clk in configuration data */
+ XVphy_ConfigTable[instance].AxiLiteClkFreq = axi_lite_rate;
+
+ /* dru-clk is used for the nidru block for low res support */
+ vphydev->clkp = devm_clk_get(&pdev->dev, "dru-clk");
+ if (IS_ERR(vphydev->clkp)) {
+ ret = PTR_ERR(vphydev->clkp);
+ vphydev->clkp = NULL;
+ if (ret == -EPROBE_DEFER)
+ hdmi_dbg("dru-clk not ready -EPROBE_DEFER\n");
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to get the nidru clk.\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(vphydev->clkp);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable nidru clk\n");
+ return ret;
+ }
+
+ dru_clk_rate = clk_get_rate(vphydev->clkp);
+ hdmi_dbg("default dru-clk rate = %lu\n", dru_clk_rate);
+ if (dru_clk_rate != XVPHY_DRU_REF_CLK_HZ) {
+ ret = clk_set_rate(vphydev->clkp, XVPHY_DRU_REF_CLK_HZ);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Cannot set rate : %d\n", ret);
+ }
+ dru_clk_rate = clk_get_rate(vphydev->clkp);
+ hdmi_dbg("ref dru-clk rate = %lu\n", dru_clk_rate);
+ }
+
+ provider = devm_of_phy_provider_register(&pdev->dev, xvphy_xlate);
+ if (IS_ERR(provider)) {
+ dev_err(&pdev->dev, "registering provider failed\n");
+ return PTR_ERR(provider);
+ }
+
+
+ /* Initialize HDMI VPHY */
+ Status = XVphy_HdmiInitialize(&vphydev->xvphy, 0/*QuadID*/,
+ &XVphy_ConfigTable[instance], axi_lite_rate);
+ if (Status != XST_SUCCESS) {
+ printk(KERN_INFO "HDMI VPHY initialization error\n");
+ return XST_FAILURE;
+ }
+
+ Data = XVphy_GetVersion(&vphydev->xvphy);
+ printk(KERN_INFO "VPhy version : %02d.%02d (%04x)\n", ((Data >> 24) & 0xFF), ((Data >> 16) & 0xFF), (Data & 0xFFFF));
+
+ DrpVal = XVphy_DrpRead(&vphydev->xvphy, 0/*QuadId*/, 1/*ChId*/, 0x7C);
+ hdmi_dbg("DrpVal @0x7C : 0x%08x%s\n", DrpVal, DrpVal & 0x2000?" GEARBOX ENABLED(?!)":" GEARBOX DISABLED");
+
+ ret = devm_request_threaded_irq(&pdev->dev, vphydev->irq, xvphy_irq_handler, xvphy_irq_thread,
+ IRQF_TRIGGER_HIGH /*IRQF_SHARED*/, "xilinx-vphy", vphydev/*dev_id*/);
+
+ if (ret) {
+ dev_err(&pdev->dev, "unable to request IRQ %d\n", vphydev->irq);
+ return ret;
+ }
+
+ hdmi_dbg("config.DruIsPresent = %d\n", XVphy_ConfigTable[instance].DruIsPresent);
+ if (vphydev->xvphy.Config.DruIsPresent == (TRUE)) {
+ hdmi_dbg("DRU reference clock frequency %0d Hz\n\r",
+ XVphy_DruGetRefClkFreqHz(&vphydev->xvphy));
+ }
+ hdmi_dbg("HDMI VPHY initialization completed\n");
+ /* probe has succeeded for this instance, increment instance index */
+ instance++;
+ return 0;
+}
+
+/* Match table for of_platform binding */
+static const struct of_device_id xvphy_of_match[] = {
+ { .compatible = "xlnx,vid-phy-controller-2.0" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, xvphy_of_match);
+
+static struct platform_driver xvphy_driver = {
+ .probe = xvphy_probe,
+ .driver = {
+ .name = "xilinx-vphy",
+ .of_match_table = xvphy_of_match,
+ },
+};
+module_platform_driver(xvphy_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Leon Woestenberg <leon@sidebranch.com>");
+MODULE_DESCRIPTION("Xilinx Vphy driver");
+
+/* common functionality shared between RX and TX */
+EXPORT_SYMBOL_GPL(XVidC_ReportTiming);
+EXPORT_SYMBOL_GPL(XVidC_SetVideoStream);
+EXPORT_SYMBOL_GPL(XVidC_ReportStreamInfo);
+EXPORT_SYMBOL_GPL(XVidC_EdidGetManName);
+EXPORT_SYMBOL_GPL(XVidC_Set3DVideoStream);
+EXPORT_SYMBOL_GPL(XVidC_GetPixelClockHzByVmId);
+EXPORT_SYMBOL_GPL(XVidC_GetVideoModeId);
+EXPORT_SYMBOL_GPL(XVidC_GetPixelClockHzByHVFr);
+
+
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/sleep.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/sleep.h
new file mode 100644
index 00000000000000..363ab8b051fb22
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/sleep.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+*
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+*
+******************************************************************************/
+
+#ifndef SLEEP_H
+#define SLEEP_H
+
+#include "xil_types.h"
+#include "xil_io.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int usleep(unsigned long useconds);
+unsigned sleep(unsigned int seconds);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xdebug.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xdebug.h
new file mode 100644
index 00000000000000..650946bd01f455
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xdebug.h
@@ -0,0 +1,32 @@
+#ifndef XDEBUG /* prevent circular inclusions */
+#define XDEBUG /* by using protection macros */
+
+#if defined(DEBUG) && !defined(NDEBUG)
+
+#ifndef XDEBUG_WARNING
+#define XDEBUG_WARNING
+#warning DEBUG is enabled
+#endif
+
+int printf(const char *format, ...);
+
+#define XDBG_DEBUG_ERROR 0x00000001U /* error condition messages */
+#define XDBG_DEBUG_GENERAL 0x00000002U /* general debug messages */
+#define XDBG_DEBUG_ALL 0xFFFFFFFFU /* all debugging data */
+
+#define xdbg_current_types (XDBG_DEBUG_GENERAL)
+
+#define xdbg_stmnt(x) x
+
+#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0)
+
+
+#else /* defined(DEBUG) && !defined(NDEBUG) */
+
+#define xdbg_stmnt(x)
+
+#define xdbg_printf(...)
+
+#endif /* defined(DEBUG) && !defined(NDEBUG) */
+
+#endif /* XDEBUG */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_assert.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_assert.h
new file mode 100644
index 00000000000000..c9c84757713d8b
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_assert.h
@@ -0,0 +1,90 @@
+/******************************************************************************
+*
+* Copyright (C) 2009 - 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
+* 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 xil_assert.h
+*
+* This file contains assert related functions.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm 07/14/09 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIL_ASSERT_H /* prevent circular inclusions */
+#define XIL_ASSERT_H /* by using protection macros */
+
+#include "xil_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+
+/************************** Constant Definitions *****************************/
+
+#define XIL_ASSERT_NONE 0U
+#define XIL_ASSERT_OCCURRED 1U
+#define XNULL NULL
+
+/**
+ * This data type defines a callback to be invoked when an
+ * assert occurs. The callback is invoked only when asserts are enabled
+ */
+//typedef void (*Xil_AssertCallback) (const char8 *File, s32 Line);
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+//#define Xil_Assert(const char8 *File, s32 Line)
+//#define Xil_AssertSetCallback(Xil_AssertCallback Routine)
+
+#define Xil_AssertVoid(Expression)
+#define Xil_AssertVoidAlways()
+#define Xil_AssertNonvoid(Expression)
+#define Xil_AssertNonvoidAlways()
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_io.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_io.h
new file mode 100644
index 00000000000000..3b24af4346411d
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_io.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+*
+* Copyright (C) 2014 - 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
+* 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 xil_io.h
+*
+* This file contains the interface for the general IO component, which
+* encapsulates the Input/Output functions for processors that do not
+* require any special I/O handling.
+*
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 pkp 05/29/14 First release
+* </pre>
+******************************************************************************/
+
+#ifndef XIL_IO_H /* prevent circular inclusions */
+#define XIL_IO_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xil_types.h"
+#include <linux/io.h>
+
+static inline void Xil_Out32(INTPTR Addr, u32 Value)
+{
+ iowrite32(Value, (volatile void *)Addr);
+}
+static inline u32 Xil_In32(INTPTR Addr)
+{
+ return ioread32((const volatile void *)Addr);
+}
+
+#endif /* end of protection macro */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_printf.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_printf.h
new file mode 100644
index 00000000000000..a90679ed2daecc
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_printf.h
@@ -0,0 +1,50 @@
+ #ifndef XIL_PRINTF_H
+ #define XIL_PRINTF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __KERNEL__
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#endif
+#include "xil_types.h"
+
+
+/*----------------------------------------------------*/
+/* Use the following parameter passing structure to */
+/* make xil_printf re-entrant. */
+/*----------------------------------------------------*/
+
+struct params_s;
+
+
+/*---------------------------------------------------*/
+/* The purpose of this routine is to output data the */
+/* same as the standard printf function without the */
+/* overhead most run-time libraries involve. Usually */
+/* the printf brings in many kilobytes of code and */
+/* that is unacceptable in most embedded systems. */
+/*---------------------------------------------------*/
+
+typedef char8* charptr;
+typedef s32 (*func_ptr)(int c);
+
+/* */
+
+void xil_printf( const char8 *ctrl1, ...);
+void print( const char8 *ptr);
+extern void outbyte (char8 c);
+extern char8 inbyte(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <linux/module.h>
+#define xil_printf(format, ...) printk(KERN_INFO format, ## __VA_ARGS__)
+#define print(format) printk(KERN_INFO format)
+
+#endif /* end of protection macro */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_types.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_types.h
new file mode 100644
index 00000000000000..f1dc072a378149
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xil_types.h
@@ -0,0 +1,200 @@
+/******************************************************************************
+*
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xil_types.h
+*
+* @addtogroup common_types Basic Data types for Xilinx&reg; Software IP
+*
+* The xil_types.h file contains basic types for Xilinx software IP. These data types
+* are applicable for all processors supported by Xilinx.
+* @{
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm 07/14/09 First release
+* 3.03a sdm 05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros
+* 5.00 pkp 05/29/14 Made changes for 64 bit architecture
+* srt 07/14/14 Use standard definitions from stdint.h and stddef.h
+* Define LONG and ULONG datatypes and mask values
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIL_TYPES_H /* prevent circular inclusions */
+#define XIL_TYPES_H /* by using protection macros */
+
+#ifndef __KERNEL__
+#include <stdint.h>
+#include <stddef.h>
+#endif
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+# define TRUE 1U
+#endif
+
+#ifndef FALSE
+# define FALSE 0U
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define XIL_COMPONENT_IS_READY 0x11111111U /**< In device drivers, This macro will be
+ assigend to "IsReady" member of driver
+ instance to indicate that driver
+ instance is initialized and ready to use. */
+#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< In device drivers, This macro will be assigend to
+ "IsStarted" member of driver instance
+ to indicate that driver instance is
+ started and it can be enabled. */
+
+/* @name New types
+ * New simple types.
+ * @{
+ */
+#ifndef __KERNEL__
+#ifndef XBASIC_TYPES_H
+/*
+ * guarded against xbasic_types.h.
+ */
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+/** @}*/
+#define __XUINT64__
+typedef struct
+{
+ u32 Upper;
+ u32 Lower;
+} Xuint64;
+
+
+/*****************************************************************************/
+/**
+* @brief Return the most significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return The upper 32 bits of the 64 bit word.
+*
+******************************************************************************/
+#define XUINT64_MSW(x) ((x).Upper)
+
+/*****************************************************************************/
+/**
+* @brief Return the least significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return The lower 32 bits of the 64 bit word.
+*
+******************************************************************************/
+#define XUINT64_LSW(x) ((x).Lower)
+
+#endif /* XBASIC_TYPES_H */
+
+/*
+ * xbasic_types.h does not typedef s* or u64
+ */
+/** @{ */
+typedef char char8;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef int sint32;
+
+typedef intptr_t INTPTR;
+typedef uintptr_t UINTPTR;
+typedef ptrdiff_t PTRDIFF;
+/** @}*/
+#if !defined(LONG) || !defined(ULONG)
+typedef long LONG;
+typedef unsigned long ULONG;
+#endif
+
+#define ULONG64_HI_MASK 0xFFFFFFFF00000000U
+#define ULONG64_LO_MASK ~ULONG64_HI_MASK
+
+#else
+#include <linux/types.h>
+// Used by xil_io.h
+typedef char char8;
+typedef long INTPTR;
+typedef uintptr_t UINTPTR;
+typedef ptrdiff_t PTRDIFF;
+#endif
+
+/** @{ */
+/**
+ * This data type defines an interrupt handler for a device.
+ * The argument points to the instance of the component
+ */
+typedef void (*XInterruptHandler) (void *InstancePtr);
+
+/**
+ * This data type defines an exception handler for a processor.
+ * The argument points to the instance of the component
+ */
+typedef void (*XExceptionHandler) (void *InstancePtr);
+
+/**
+ * @brief Returns 32-63 bits of a number.
+ * @param n : Number being accessed.
+ * @return Bits 32-63 of number.
+ *
+ * @note A basic shift-right of a 64- or 32-bit quantity.
+ * Use this to suppress the "right shift count >= width of type"
+ * warning when that quantity is 32-bits.
+ */
+#define UPPER_32_BITS(n) ((u32)(((n) >> 16) >> 16))
+
+/**
+ * @brief Returns 0-31 bits of a number
+ * @param n : Number being accessed.
+ * @return Bits 0-31 of number
+ */
+#define LOWER_32_BITS(n) ((u32)(n))
+
+
+
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+#define TRUE 1U
+#endif
+
+#ifndef FALSE
+#define FALSE 0U
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#endif /* end of protection macro */
+/**
+* @} End of "addtogroup common_types".
+*/
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xstatus.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xstatus.h
new file mode 100644
index 00000000000000..5f4835fa66094a
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xstatus.h
@@ -0,0 +1,519 @@
+/******************************************************************************
+*
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xstatus.h
+*
+* @addtogroup common_status_codes Xilinx&reg; software status codes
+*
+* The xstatus.h file contains the Xilinx&reg; software status codes.These codes are
+* used throughout the Xilinx device drivers.
+*
+* @{
+******************************************************************************/
+
+#ifndef XSTATUS_H /* prevent circular inclusions */
+#define XSTATUS_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xil_types.h"
+#include "xil_assert.h"
+
+/************************** Constant Definitions *****************************/
+
+/*********************** Common statuses 0 - 500 *****************************/
+/**
+@name Common Status Codes for All Device Drivers
+@{
+*/
+#define XST_SUCCESS 0L
+#define XST_FAILURE 1L
+#define XST_DEVICE_NOT_FOUND 2L
+#define XST_DEVICE_BLOCK_NOT_FOUND 3L
+#define XST_INVALID_VERSION 4L
+#define XST_DEVICE_IS_STARTED 5L
+#define XST_DEVICE_IS_STOPPED 6L
+#define XST_FIFO_ERROR 7L /*!< An error occurred during an
+ operation with a FIFO such as
+ an underrun or overrun, this
+ error requires the device to
+ be reset */
+#define XST_RESET_ERROR 8L /*!< An error occurred which requires
+ the device to be reset */
+#define XST_DMA_ERROR 9L /*!< A DMA error occurred, this error
+ typically requires the device
+ using the DMA to be reset */
+#define XST_NOT_POLLED 10L /*!< The device is not configured for
+ polled mode operation */
+#define XST_FIFO_NO_ROOM 11L /*!< A FIFO did not have room to put
+ the specified data into */
+#define XST_BUFFER_TOO_SMALL 12L /*!< The buffer is not large enough
+ to hold the expected data */
+#define XST_NO_DATA 13L /*!< There was no data available */
+#define XST_REGISTER_ERROR 14L /*!< A register did not contain the
+ expected value */
+#define XST_INVALID_PARAM 15L /*!< An invalid parameter was passed
+ into the function */
+#define XST_NOT_SGDMA 16L /*!< The device is not configured for
+ scatter-gather DMA operation */
+#define XST_LOOPBACK_ERROR 17L /*!< A loopback test failed */
+#define XST_NO_CALLBACK 18L /*!< A callback has not yet been
+ registered */
+#define XST_NO_FEATURE 19L /*!< Device is not configured with
+ the requested feature */
+#define XST_NOT_INTERRUPT 20L /*!< Device is not configured for
+ interrupt mode operation */
+#define XST_DEVICE_BUSY 21L /*!< Device is busy */
+#define XST_ERROR_COUNT_MAX 22L /*!< The error counters of a device
+ have maxed out */
+#define XST_IS_STARTED 23L /*!< Used when part of device is
+ already started i.e.
+ sub channel */
+#define XST_IS_STOPPED 24L /*!< Used when part of device is
+ already stopped i.e.
+ sub channel */
+#define XST_DATA_LOST 26L /*!< Driver defined error */
+#define XST_RECV_ERROR 27L /*!< Generic receive error */
+#define XST_SEND_ERROR 28L /*!< Generic transmit error */
+#define XST_NOT_ENABLED 29L /*!< A requested service is not
+ available because it has not
+ been enabled */
+/** @} */
+/***************** Utility Component statuses 401 - 500 *********************/
+/**
+@name Utility Component Status Codes 401 - 500
+@{
+*/
+#define XST_MEMTEST_FAILED 401L /*!< Memory test failed */
+
+/** @} */
+/***************** Common Components statuses 501 - 1000 *********************/
+/**
+@name Packet Fifo Status Codes 501 - 510
+@{
+*/
+/********************* Packet Fifo statuses 501 - 510 ************************/
+
+#define XST_PFIFO_LACK_OF_DATA 501L /*!< Not enough data in FIFO */
+#define XST_PFIFO_NO_ROOM 502L /*!< Not enough room in FIFO */
+#define XST_PFIFO_BAD_REG_VALUE 503L /*!< Self test, a register value
+ was invalid after reset */
+#define XST_PFIFO_ERROR 504L /*!< Generic packet FIFO error */
+#define XST_PFIFO_DEADLOCK 505L /*!< Packet FIFO is reporting
+ * empty and full simultaneously
+ */
+/** @} */
+/**
+@name DMA Status Codes 511 - 530
+@{
+*/
+/************************** DMA statuses 511 - 530 ***************************/
+
+#define XST_DMA_TRANSFER_ERROR 511L /*!< Self test, DMA transfer
+ failed */
+#define XST_DMA_RESET_REGISTER_ERROR 512L /*!< Self test, a register value
+ was invalid after reset */
+#define XST_DMA_SG_LIST_EMPTY 513L /*!< Scatter gather list contains
+ no buffer descriptors ready
+ to be processed */
+#define XST_DMA_SG_IS_STARTED 514L /*!< Scatter gather not stopped */
+#define XST_DMA_SG_IS_STOPPED 515L /*!< Scatter gather not running */
+#define XST_DMA_SG_LIST_FULL 517L /*!< All the buffer desciptors of
+ the scatter gather list are
+ being used */
+#define XST_DMA_SG_BD_LOCKED 518L /*!< The scatter gather buffer
+ descriptor which is to be
+ copied over in the scatter
+ list is locked */
+#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /*!< No buffer descriptors have been
+ put into the scatter gather
+ list to be commited */
+#define XST_DMA_SG_COUNT_EXCEEDED 521L /*!< The packet count threshold
+ specified was larger than the
+ total # of buffer descriptors
+ in the scatter gather list */
+#define XST_DMA_SG_LIST_EXISTS 522L /*!< The scatter gather list has
+ already been created */
+#define XST_DMA_SG_NO_LIST 523L /*!< No scatter gather list has
+ been created */
+#define XST_DMA_SG_BD_NOT_COMMITTED 524L /*!< The buffer descriptor which was
+ being started was not committed
+ to the list */
+#define XST_DMA_SG_NO_DATA 525L /*!< The buffer descriptor to start
+ has already been used by the
+ hardware so it can't be reused
+ */
+#define XST_DMA_SG_LIST_ERROR 526L /*!< General purpose list access
+ error */
+#define XST_DMA_BD_ERROR 527L /*!< General buffer descriptor
+ error */
+/** @} */
+/**
+@name IPIF Status Codes Codes 531 - 550
+@{
+*/
+/************************** IPIF statuses 531 - 550 ***************************/
+
+#define XST_IPIF_REG_WIDTH_ERROR 531L /*!< An invalid register width
+ was passed into the function */
+#define XST_IPIF_RESET_REGISTER_ERROR 532L /*!< The value of a register at
+ reset was not valid */
+#define XST_IPIF_DEVICE_STATUS_ERROR 533L /*!< A write to the device interrupt
+ status register did not read
+ back correctly */
+#define XST_IPIF_DEVICE_ACK_ERROR 534L /*!< The device interrupt status
+ register did not reset when
+ acked */
+#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /*!< The device interrupt enable
+ register was not updated when
+ other registers changed */
+#define XST_IPIF_IP_STATUS_ERROR 536L /*!< A write to the IP interrupt
+ status register did not read
+ back correctly */
+#define XST_IPIF_IP_ACK_ERROR 537L /*!< The IP interrupt status register
+ did not reset when acked */
+#define XST_IPIF_IP_ENABLE_ERROR 538L /*!< IP interrupt enable register was
+ not updated correctly when other
+ registers changed */
+#define XST_IPIF_DEVICE_PENDING_ERROR 539L /*!< The device interrupt pending
+ register did not indicate the
+ expected value */
+#define XST_IPIF_DEVICE_ID_ERROR 540L /*!< The device interrupt ID register
+ did not indicate the expected
+ value */
+#define XST_IPIF_ERROR 541L /*!< Generic ipif error */
+/** @} */
+
+/****************** Device specific statuses 1001 - 4095 *********************/
+/**
+@name Ethernet Status Codes 1001 - 1050
+@{
+*/
+/********************* Ethernet statuses 1001 - 1050 *************************/
+
+#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /*!< Memory space is not big enough
+ * to hold the minimum number of
+ * buffers or descriptors */
+#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /*!< Memory allocation failed */
+#define XST_EMAC_MII_READ_ERROR 1003L /*!< MII read error */
+#define XST_EMAC_MII_BUSY 1004L /*!< An MII operation is in progress */
+#define XST_EMAC_OUT_OF_BUFFERS 1005L /*!< Driver is out of buffers */
+#define XST_EMAC_PARSE_ERROR 1006L /*!< Invalid driver init string */
+#define XST_EMAC_COLLISION_ERROR 1007L /*!< Excess deferral or late
+ * collision on polled send */
+/** @} */
+/**
+@name UART Status Codes 1051 - 1075
+@{
+*/
+/*********************** UART statuses 1051 - 1075 ***************************/
+#define XST_UART
+
+#define XST_UART_INIT_ERROR 1051L
+#define XST_UART_START_ERROR 1052L
+#define XST_UART_CONFIG_ERROR 1053L
+#define XST_UART_TEST_FAIL 1054L
+#define XST_UART_BAUD_ERROR 1055L
+#define XST_UART_BAUD_RANGE 1056L
+
+/** @} */
+/**
+@name IIC Status Codes 1076 - 1100
+@{
+*/
+/************************ IIC statuses 1076 - 1100 ***************************/
+
+#define XST_IIC_SELFTEST_FAILED 1076 /*!< self test failed */
+#define XST_IIC_BUS_BUSY 1077 /*!< bus found busy */
+#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /*!< mastersend attempted with */
+ /* general call address */
+#define XST_IIC_STAND_REG_RESET_ERROR 1079 /*!< A non parameterizable reg */
+ /* value after reset not valid */
+#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /*!< Tx fifo included in design */
+ /* value after reset not valid */
+#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /*!< Rx fifo included in design */
+ /* value after reset not valid */
+#define XST_IIC_TBA_REG_RESET_ERROR 1082 /*!< 10 bit addr incl in design */
+ /* value after reset not valid */
+#define XST_IIC_CR_READBACK_ERROR 1083 /*!< Read of the control register */
+ /* didn't return value written */
+#define XST_IIC_DTR_READBACK_ERROR 1084 /*!< Read of the data Tx reg */
+ /* didn't return value written */
+#define XST_IIC_DRR_READBACK_ERROR 1085 /*!< Read of the data Receive reg */
+ /* didn't return value written */
+#define XST_IIC_ADR_READBACK_ERROR 1086 /*!< Read of the data Tx reg */
+ /* didn't return value written */
+#define XST_IIC_TBA_READBACK_ERROR 1087 /*!< Read of the 10 bit addr reg */
+ /* didn't return written value */
+#define XST_IIC_NOT_SLAVE 1088 /*!< The device isn't a slave */
+/** @} */
+/**
+@name ATMC Status Codes 1101 - 1125
+@{
+*/
+/*********************** ATMC statuses 1101 - 1125 ***************************/
+
+#define XST_ATMC_ERROR_COUNT_MAX 1101L /*!< the error counters in the ATM
+ controller hit the max value
+ which requires the statistics
+ to be cleared */
+/** @} */
+/**
+@name Flash Status Codes 1126 - 1150
+@{
+*/
+/*********************** Flash statuses 1126 - 1150 **************************/
+
+#define XST_FLASH_BUSY 1126L /*!< Flash is erasing or programming
+ */
+#define XST_FLASH_READY 1127L /*!< Flash is ready for commands */
+#define XST_FLASH_ERROR 1128L /*!< Flash had detected an internal
+ error. Use XFlash_DeviceControl
+ to retrieve device specific codes
+ */
+#define XST_FLASH_ERASE_SUSPENDED 1129L /*!< Flash is in suspended erase state
+ */
+#define XST_FLASH_WRITE_SUSPENDED 1130L /*!< Flash is in suspended write state
+ */
+#define XST_FLASH_PART_NOT_SUPPORTED 1131L /*!< Flash type not supported by
+ driver */
+#define XST_FLASH_NOT_SUPPORTED 1132L /*!< Operation not supported */
+#define XST_FLASH_TOO_MANY_REGIONS 1133L /*!< Too many erase regions */
+#define XST_FLASH_TIMEOUT_ERROR 1134L /*!< Programming or erase operation
+ aborted due to a timeout */
+#define XST_FLASH_ADDRESS_ERROR 1135L /*!< Accessed flash outside its
+ addressible range */
+#define XST_FLASH_ALIGNMENT_ERROR 1136L /*!< Write alignment error */
+#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /*!< Couldn't return immediately from
+ write/erase function with
+ XFL_NON_BLOCKING_WRITE/ERASE
+ option cleared */
+#define XST_FLASH_CFI_QUERY_ERROR 1138L /*!< Failed to query the device */
+/** @} */
+/**
+@name SPI Status Codes 1151 - 1175
+@{
+*/
+/*********************** SPI statuses 1151 - 1175 ****************************/
+
+#define XST_SPI_MODE_FAULT 1151 /*!< master was selected as slave */
+#define XST_SPI_TRANSFER_DONE 1152 /*!< data transfer is complete */
+#define XST_SPI_TRANSMIT_UNDERRUN 1153 /*!< slave underruns transmit register */
+#define XST_SPI_RECEIVE_OVERRUN 1154 /*!< device overruns receive register */
+#define XST_SPI_NO_SLAVE 1155 /*!< no slave has been selected yet */
+#define XST_SPI_TOO_MANY_SLAVES 1156 /*!< more than one slave is being
+ * selected */
+#define XST_SPI_NOT_MASTER 1157 /*!< operation is valid only as master */
+#define XST_SPI_SLAVE_ONLY 1158 /*!< device is configured as slave-only
+ */
+#define XST_SPI_SLAVE_MODE_FAULT 1159 /*!< slave was selected while disabled */
+#define XST_SPI_SLAVE_MODE 1160 /*!< device has been addressed as slave */
+#define XST_SPI_RECEIVE_NOT_EMPTY 1161 /*!< device received data in slave mode */
+
+#define XST_SPI_COMMAND_ERROR 1162 /*!< unrecognised command - qspi only */
+#define XST_SPI_POLL_DONE 1163 /*!< controller completed polling the
+ device for status */
+/** @} */
+/**
+@name OPB Arbiter Status Codes 1176 - 1200
+@{
+*/
+/********************** OPB Arbiter statuses 1176 - 1200 *********************/
+
+#define XST_OPBARB_INVALID_PRIORITY 1176 /*!< the priority registers have either
+ * one master assigned to two or more
+ * priorities, or one master not
+ * assigned to any priority
+ */
+#define XST_OPBARB_NOT_SUSPENDED 1177 /*!< an attempt was made to modify the
+ * priority levels without first
+ * suspending the use of priority
+ * levels
+ */
+#define XST_OPBARB_PARK_NOT_ENABLED 1178 /*!< bus parking by id was enabled but
+ * bus parking was not enabled
+ */
+#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /*!< the arbiter must be in fixed
+ * priority mode to allow the
+ * priorities to be changed
+ */
+/** @} */
+/**
+@name INTC Status Codes 1201 - 1225
+@{
+*/
+/************************ Intc statuses 1201 - 1225 **************************/
+
+#define XST_INTC_FAIL_SELFTEST 1201 /*!< self test failed */
+#define XST_INTC_CONNECT_ERROR 1202 /*!< interrupt already in use */
+/** @} */
+/**
+@name TmrCtr Status Codes 1226 - 1250
+@{
+*/
+/********************** TmrCtr statuses 1226 - 1250 **************************/
+
+#define XST_TMRCTR_TIMER_FAILED 1226 /*!< self test failed */
+/** @} */
+/**
+@name WdtTb Status Codes 1251 - 1275
+@{
+*/
+/********************** WdtTb statuses 1251 - 1275 ***************************/
+
+#define XST_WDTTB_TIMER_FAILED 1251L
+/** @} */
+/**
+@name PlbArb status Codes 1276 - 1300
+@{
+*/
+/********************** PlbArb statuses 1276 - 1300 **************************/
+
+#define XST_PLBARB_FAIL_SELFTEST 1276L
+/** @} */
+/**
+@name Plb2Opb Status Codes 1301 - 1325
+@{
+*/
+/********************** Plb2Opb statuses 1301 - 1325 *************************/
+
+#define XST_PLB2OPB_FAIL_SELFTEST 1301L
+/** @} */
+/**
+@name Opb2Plb Status 1326 - 1350
+@{
+*/
+/********************** Opb2Plb statuses 1326 - 1350 *************************/
+
+#define XST_OPB2PLB_FAIL_SELFTEST 1326L
+/** @} */
+/**
+@name SysAce Status Codes 1351 - 1360
+@{
+*/
+/********************** SysAce statuses 1351 - 1360 **************************/
+
+#define XST_SYSACE_NO_LOCK 1351L /*!< No MPU lock has been granted */
+/** @} */
+/**
+@name PCI Bridge Status Codes 1361 - 1375
+@{
+*/
+/********************** PCI Bridge statuses 1361 - 1375 **********************/
+
+#define XST_PCI_INVALID_ADDRESS 1361L
+/** @} */
+/**
+@name FlexRay Constants 1400 - 1409
+@{
+*/
+/********************** FlexRay constants 1400 - 1409 *************************/
+
+#define XST_FR_TX_ERROR 1400
+#define XST_FR_TX_BUSY 1401
+#define XST_FR_BUF_LOCKED 1402
+#define XST_FR_NO_BUF 1403
+/** @} */
+/**
+@name USB constants 1410 - 1420
+@{
+*/
+/****************** USB constants 1410 - 1420 *******************************/
+
+#define XST_USB_ALREADY_CONFIGURED 1410
+#define XST_USB_BUF_ALIGN_ERROR 1411
+#define XST_USB_NO_DESC_AVAILABLE 1412
+#define XST_USB_BUF_TOO_BIG 1413
+#define XST_USB_NO_BUF 1414
+/** @} */
+/**
+@name HWICAP constants 1421 - 1429
+@{
+*/
+/****************** HWICAP constants 1421 - 1429 *****************************/
+
+#define XST_HWICAP_WRITE_DONE 1421
+
+/** @} */
+/**
+@name AXI VDMA constants 1430 - 1440
+@{
+*/
+/****************** AXI VDMA constants 1430 - 1440 *****************************/
+
+#define XST_VDMA_MISMATCH_ERROR 1430
+/** @} */
+/**
+@name NAND Flash Status Codes 1441 - 1459
+@{
+*/
+/*********************** NAND Flash statuses 1441 - 1459 *********************/
+
+#define XST_NAND_BUSY 1441L /*!< Flash is erasing or
+ * programming
+ */
+#define XST_NAND_READY 1442L /*!< Flash is ready for commands
+ */
+#define XST_NAND_ERROR 1443L /*!< Flash had detected an
+ * internal error.
+ */
+#define XST_NAND_PART_NOT_SUPPORTED 1444L /*!< Flash type not supported by
+ * driver
+ */
+#define XST_NAND_OPT_NOT_SUPPORTED 1445L /*!< Operation not supported
+ */
+#define XST_NAND_TIMEOUT_ERROR 1446L /*!< Programming or erase
+ * operation aborted due to a
+ * timeout
+ */
+#define XST_NAND_ADDRESS_ERROR 1447L /*!< Accessed flash outside its
+ * addressible range
+ */
+#define XST_NAND_ALIGNMENT_ERROR 1448L /*!< Write alignment error
+ */
+#define XST_NAND_PARAM_PAGE_ERROR 1449L /*!< Failed to read parameter
+ * page of the device
+ */
+#define XST_NAND_CACHE_ERROR 1450L /*!< Flash page buffer error
+ */
+
+#define XST_NAND_WRITE_PROTECTED 1451L /*!< Flash is write protected
+ */
+/** @} */
+
+/**************************** Type Definitions *******************************/
+
+typedef s32 XStatus;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
+/**
+* @} End of "addtogroup common_status_codes".
+*/
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.c
new file mode 100644
index 00000000000000..318bf7f926e3cd
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.c
@@ -0,0 +1,1013 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvidc.c
+ * @addtogroup video_common_v4_0
+ * @{
+ *
+ * Contains common utility functions that are typically used by video-related
+ * drivers and applications.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 rc, 01/10/15 Initial release.
+ * als
+ * 2.2 als 02/01/16 Functions with pointer arguments that don't modify
+ * contents now const.
+ * Added ability to insert a custom video timing table.
+ * yh Added 3D support.
+ * 3.0 aad 05/13/16 Added API to search for RB video modes.
+ * 3.1 rco 07/26/16 Added extern definition for timing table array
+ * Added video-in-memory color formats
+ * Updated XVidC_RegisterCustomTimingModes API signature
+ * 4.1 rco 11/23/16 Added new memory formats
+ * Added new API to get video mode id that matches exactly
+ * with provided timing information
+ * Fix c++ warnings
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include "xil_assert.h"
+#include "xstatus.h"
+#include "xvidc.h"
+
+/*************************** Variable Declarations ****************************/
+extern const XVidC_VideoTimingMode XVidC_VideoTimingModes[XVIDC_VM_NUM_SUPPORTED];
+
+const XVidC_VideoTimingMode *XVidC_CustomTimingModes = NULL;
+int XVidC_NumCustomModes = 0;
+
+/**************************** Function Prototypes *****************************/
+
+static const XVidC_VideoTimingMode *XVidC_GetCustomVideoModeData(
+ XVidC_VideoMode VmId);
+static u8 XVidC_IsVtmRb(const char *VideoModeStr, u8 RbN);
+
+/*************************** Function Definitions *****************************/
+
+/******************************************************************************/
+/**
+ * This function registers a user-defined custom video mode timing table with
+ * video_common. Functions which search the available video modes, or take VmId
+ * as an input, will operate on or check the custom video mode timing table in
+ * addition to the pre-defined video mode timing table (XVidC_VideoTimingModes).
+ *
+ * @param CustomTable is a pointer to the user-defined custom vide mode
+ * timing table to register.
+ * @param NumElems is the number of video modes supported by CustomTable.
+ *
+ * @return
+ * - XST_SUCCESS if the custom table was successfully registered.
+ * - XST_FAILURE if an existing custom table is already present.
+ *
+ * @note IDs in the custom table may not conflict with IDs reserved by
+ * the XVidC_VideoMode enum.
+ *
+*******************************************************************************/
+u32 XVidC_RegisterCustomTimingModes(const XVidC_VideoTimingMode *CustomTable,
+ u16 NumElems)
+{
+ u16 Index;
+
+ /* Verify arguments. */
+ Xil_AssertNonvoid(CustomTable != NULL);
+ for (Index = 0; Index < NumElems; Index++) {
+ Xil_AssertNonvoid((CustomTable[Index].VmId > XVIDC_VM_CUSTOM));
+ /* The IDs of each video mode in the custom table must not
+ * conflict with IDs reserved by video_common. */
+ }
+
+ /* Fail if a custom table is currently already registered. */
+ if (XVidC_CustomTimingModes) {
+ return XST_FAILURE;
+ }
+
+ XVidC_CustomTimingModes = CustomTable;
+ XVidC_NumCustomModes = NumElems;
+
+ return XST_SUCCESS;
+}
+
+/******************************************************************************/
+/**
+ * This function unregisters the user-defined custom video mode timing table
+ * previously registered by XVidC_RegisterCustomTimingModes().
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+void XVidC_UnregisterCustomTimingModes(void)
+{
+ XVidC_CustomTimingModes = NULL;
+ XVidC_NumCustomModes = 0;
+}
+
+/******************************************************************************/
+/**
+ * This function calculates pixel clock based on the inputs.
+ *
+ * @param HTotal specifies horizontal total.
+ * @param VTotal specifies vertical total.
+ * @param FrameRate specifies rate at which frames are generated.
+ *
+ * @return Pixel clock in Hz.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u32 XVidC_GetPixelClockHzByHVFr(u32 HTotal, u32 VTotal, u8 FrameRate)
+{
+ return (HTotal * VTotal * FrameRate);
+}
+
+/******************************************************************************/
+/**
+ * This function calculates pixel clock from video mode.
+ *
+ * @param VmId specifies the resolution id.
+ *
+ * @return Pixel clock in Hz.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u32 XVidC_GetPixelClockHzByVmId(XVidC_VideoMode VmId)
+{
+ u32 ClkHz;
+ const XVidC_VideoTimingMode *VmPtr;
+
+ VmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VmPtr) {
+ return 0;
+ }
+
+ if (XVidC_IsInterlaced(VmId)) {
+ /* For interlaced mode, use both frame 0 and frame 1 vertical
+ * totals. */
+ ClkHz = VmPtr->Timing.F0PVTotal + VmPtr->Timing.F1VTotal;
+
+ /* Multiply the number of pixels by the frame rate of each
+ * individual frame (half of the total frame rate). */
+ ClkHz *= VmPtr->FrameRate / 2;
+ }
+ else {
+ /* For progressive mode, use only frame 0 vertical total. */
+ ClkHz = VmPtr->Timing.F0PVTotal;
+
+ /* Multiply the number of pixels by the frame rate. */
+ ClkHz *= VmPtr->FrameRate;
+ }
+
+ /* Multiply the vertical total by the horizontal total for number of
+ * pixels. */
+ ClkHz *= VmPtr->Timing.HTotal;
+
+ return ClkHz;
+}
+
+/******************************************************************************/
+/**
+ * This function checks if the input video mode is interlaced/progressive based
+ * on its ID from the video timings table.
+ *
+ * @param VmId specifies the resolution ID from the video timings table.
+ *
+ * @return Video format.
+ * - XVIDC_VF_PROGRESSIVE
+ * - XVIDC_VF_INTERLACED
+ *
+ * @note None.
+ *
+*******************************************************************************/
+XVidC_VideoFormat XVidC_GetVideoFormat(XVidC_VideoMode VmId)
+{
+ const XVidC_VideoTimingMode *VmPtr;
+
+ VmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VmPtr) {
+ return XVIDC_VF_UNKNOWN;
+ }
+
+ if (VmPtr->Timing.F1VTotal == 0) {
+ return (XVIDC_VF_PROGRESSIVE);
+ }
+
+ return (XVIDC_VF_INTERLACED);
+}
+
+/******************************************************************************/
+/**
+ * This function checks if the input video mode is interlaced based on its ID
+ * from the video timings table.
+ *
+ * @param VmId specifies the resolution ID from the video timings table.
+ *
+ * @return
+ * - 1 if the video timing with the supplied table ID is
+ * interlaced.
+ * - 0 if the video timing is progressive.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u8 XVidC_IsInterlaced(XVidC_VideoMode VmId)
+{
+ if (XVidC_GetVideoFormat(VmId) == XVIDC_VF_INTERLACED) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+/**
+ * This function returns the Video Mode ID that matches the detected input
+ * timing, frame rate and I/P flag
+ *
+ * @param Timing is the pointer to timing parameters to match
+ * @param FrameRate specifies refresh rate in HZ
+ * @param IsInterlaced is flag.
+ * - 0 = Progressive
+ * - 1 = Interlaced.
+ *
+ * @return Id of a supported video mode.
+ *
+ * @note This is an extension of XVidC_GetVideoModeId API to include
+ * blanking information in match process. No attempt is made to
+ * search for reduced blanking entries, if any.
+ *
+*******************************************************************************/
+XVidC_VideoMode XVidC_GetVideoModeIdWBlanking(const XVidC_VideoTiming *Timing,
+ u32 FrameRate, u8 IsInterlaced)
+{
+ XVidC_VideoMode VmId;
+ XVidC_VideoTiming const *StdTiming = NULL;
+
+ /* First search for ID with matching Width & Height */
+ VmId = XVidC_GetVideoModeId(Timing->HActive, Timing->VActive, FrameRate,
+ IsInterlaced);
+
+ if(VmId == XVIDC_VM_NOT_SUPPORTED) {
+ return(VmId);
+ } else {
+
+ /* Get standard timing info from default timing table */
+ StdTiming = XVidC_GetTimingInfo(VmId);
+
+ /* Match against detected timing parameters */
+ if((Timing->HActive == StdTiming->HActive) &&
+ (Timing->VActive == StdTiming->VActive) &&
+ (Timing->HTotal == StdTiming->HTotal) &&
+ (Timing->F0PVTotal == StdTiming->F0PVTotal) &&
+ (Timing->HFrontPorch == StdTiming->HFrontPorch) &&
+ (Timing->HSyncWidth == StdTiming->HSyncWidth) &&
+ (Timing->HBackPorch == StdTiming->HBackPorch) &&
+ (Timing->F0PVFrontPorch == StdTiming->F0PVFrontPorch) &&
+ (Timing->F0PVSyncWidth == StdTiming->F0PVSyncWidth) &&
+ (Timing->F0PVBackPorch == StdTiming->F0PVBackPorch)) {
+ return(VmId);
+ } else {
+ return(XVIDC_VM_NOT_SUPPORTED);
+ }
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function returns the Video Mode ID that matches the detected input
+ * width, height, frame rate and I/P flag
+ *
+ * @param Width specifies the number pixels per scanline.
+ * @param Height specifies the number of scanline's.
+ * @param FrameRate specifies refresh rate in HZ
+ * @param IsInterlaced is flag.
+ * - 0 = Progressive
+ * - 1 = Interlaced.
+ *
+ * @return Id of a supported video mode.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+XVidC_VideoMode XVidC_GetVideoModeId(u32 Width, u32 Height, u32 FrameRate,
+ u8 IsInterlaced)
+{
+ u32 Low;
+ u32 High;
+ u32 Mid;
+ u32 HActive;
+ u32 VActive;
+ u32 Rate;
+ u32 ResFound = (FALSE);
+ XVidC_VideoMode Mode;
+ u16 Index;
+
+ /* First, attempt a linear search on the custom video timing table. */
+ if(XVidC_CustomTimingModes) {
+ for (Index = 0; Index < XVidC_NumCustomModes; Index++) {
+ HActive = XVidC_CustomTimingModes[Index].Timing.HActive;
+ VActive = XVidC_CustomTimingModes[Index].Timing.VActive;
+ Rate = XVidC_CustomTimingModes[Index].FrameRate;
+ if ((Width == HActive) &&
+ (Height == VActive) &&
+ (FrameRate == Rate)) {
+ return XVidC_CustomTimingModes[Index].VmId;
+ }
+ }
+ }
+
+ if (IsInterlaced) {
+ Low = (XVIDC_VM_INTL_START);
+ High = (XVIDC_VM_INTL_END);
+ }
+ else {
+ Low = (XVIDC_VM_PROG_START);
+ High = (XVIDC_VM_PROG_END);
+ }
+
+ HActive = VActive = Rate = 0;
+
+ /* Binary search finds item in sorted array.
+ * And returns index (zero based) of item
+ * If item is not found returns flag remains
+ * FALSE. Search key is "width or HActive"
+ */
+ while (Low <= High) {
+ Mid = (Low + High) / 2;
+ HActive = XVidC_VideoTimingModes[Mid].Timing.HActive;
+ if (Width == HActive) {
+ ResFound = (TRUE);
+ break;
+ }
+ else if (Width < HActive) {
+ if (Mid == 0) {
+ break;
+ }
+ else {
+ High = Mid - 1;
+ }
+ }
+ else {
+ Low = Mid + 1;
+ }
+ }
+
+ /* HActive matched at middle */
+ if (ResFound) {
+ /* Rewind to start index of mode with matching width */
+ while ((Mid > 0) &&
+ (XVidC_VideoTimingModes[Mid - 1].Timing.HActive ==
+ Width)) {
+ --Mid;
+ }
+
+ ResFound = (FALSE);
+ VActive = XVidC_VideoTimingModes[Mid].Timing.VActive;
+ Rate = XVidC_VideoTimingModes[Mid].FrameRate;
+
+ /* Now do a linear search for matching VActive and Frame
+ * Rate
+ */
+ while (HActive == Width) {
+ /* check current entry */
+ if ((VActive == Height) && (Rate == FrameRate)) {
+ ResFound = (TRUE);
+ break;
+ }
+ /* Check next entry */
+ else {
+ Mid = Mid + 1;
+ HActive =
+ XVidC_VideoTimingModes[Mid].Timing.HActive;
+ VActive =
+ XVidC_VideoTimingModes[Mid].Timing.VActive;
+ Rate = XVidC_VideoTimingModes[Mid].FrameRate;
+ }
+ }
+ Mode =
+ (ResFound) ? (XVidC_VideoMode)Mid : (XVIDC_VM_NOT_SUPPORTED);
+ }
+ else {
+ Mode = (XVIDC_VM_NOT_SUPPORTED);
+ }
+
+ return (Mode);
+}
+
+/******************************************************************************/
+/**
+ * This function returns the video mode ID that matches the detected input
+ * width, height, frame rate, interlaced or progressive, and reduced blanking.
+ *
+ * @param Width specifies the number pixels per scanline.
+ * @param Height specifies the number of scanline's.
+ * @param FrameRate specifies refresh rate in HZ
+ * @param IsInterlaced specifies interlaced or progressive mode:
+ * - 0 = Progressive
+ * - 1 = Interlaced.
+ * @param RbN specifies the type of reduced blanking:
+ * - 0 = No reduced blanking
+ * - 1 = RB
+ * - 2 = RB2
+ *
+ * @return ID of a supported video mode.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+XVidC_VideoMode XVidC_GetVideoModeIdRb(u32 Width, u32 Height,
+ u32 FrameRate, u8 IsInterlaced, u8 RbN)
+{
+ XVidC_VideoMode VmId;
+ const XVidC_VideoTimingMode *VtmPtr;
+ u8 Found = 0;
+
+ VmId = XVidC_GetVideoModeId(Width, Height, FrameRate,
+ IsInterlaced);
+
+ VtmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VtmPtr) {
+ return XVIDC_VM_NOT_SUPPORTED;
+ }
+
+ while (!Found) {
+ VtmPtr = XVidC_GetVideoModeData(VmId);
+ if ((Height != VtmPtr->Timing.VActive) ||
+ (Width != VtmPtr->Timing.HActive) ||
+ (FrameRate != VtmPtr->FrameRate) ||
+ (IsInterlaced && !XVidC_IsInterlaced(VmId))) {
+ VmId = XVIDC_VM_NOT_SUPPORTED;
+ break;
+ }
+ Found = XVidC_IsVtmRb(XVidC_GetVideoModeStr(VmId), RbN);
+ if (Found) {
+ break;
+ }
+ VmId = (XVidC_VideoMode)((int)VmId + 1);
+ }
+
+ return VmId;
+}
+
+/******************************************************************************/
+/**
+ * This function returns the pointer to video mode data at index provided.
+ *
+ * @param VmId specifies the resolution id.
+ *
+ * @return Pointer to XVidC_VideoTimingMode structure based on the given
+ * video mode.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+const XVidC_VideoTimingMode *XVidC_GetVideoModeData(XVidC_VideoMode VmId)
+{
+ if (VmId < XVIDC_VM_NUM_SUPPORTED) {
+ return &XVidC_VideoTimingModes[VmId];
+ }
+
+ return XVidC_GetCustomVideoModeData(VmId);
+}
+
+/******************************************************************************/
+/**
+ *
+ * This function returns the resolution name for index specified.
+ *
+ * @param VmId specifies the resolution id.
+ *
+ * @return Pointer to a resolution name string.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+const char *XVidC_GetVideoModeStr(XVidC_VideoMode VmId)
+{
+ const XVidC_VideoTimingMode *VmPtr;
+
+ if (VmId == XVIDC_VM_CUSTOM) {
+ return ("Custom video mode");
+ }
+
+ VmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VmPtr) {
+ return ("Video mode not supported");
+ }
+
+ return VmPtr->Name;
+}
+
+/******************************************************************************/
+/**
+ * This function returns the frame rate name for index specified.
+ *
+ * @param VmId specifies the resolution id.
+ *
+ * @return Pointer to a frame rate name string.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+const char *XVidC_GetFrameRateStr(XVidC_VideoMode VmId)
+{
+ const XVidC_VideoTimingMode *VmPtr;
+
+ VmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VmPtr) {
+ return ("Video mode not supported");
+ }
+
+ switch (VmPtr->FrameRate) {
+ case (XVIDC_FR_24HZ): return ("24Hz");
+ case (XVIDC_FR_25HZ): return ("25Hz");
+ case (XVIDC_FR_30HZ): return ("30Hz");
+ case (XVIDC_FR_50HZ): return ("50Hz");
+ case (XVIDC_FR_56HZ): return ("56Hz");
+ case (XVIDC_FR_60HZ): return ("60Hz");
+ case (XVIDC_FR_65HZ): return ("65Hz");
+ case (XVIDC_FR_67HZ): return ("67Hz");
+ case (XVIDC_FR_70HZ): return ("70Hz");
+ case (XVIDC_FR_72HZ): return ("72Hz");
+ case (XVIDC_FR_75HZ): return ("75Hz");
+ case (XVIDC_FR_85HZ): return ("85Hz");
+ case (XVIDC_FR_87HZ): return ("87Hz");
+ case (XVIDC_FR_88HZ): return ("88Hz");
+ case (XVIDC_FR_100HZ): return ("100Hz");
+ case (XVIDC_FR_120HZ): return ("120Hz");
+
+ default:
+ return ("Frame rate not supported");
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function returns a string representation of the enumerated type,
+ * XVidC_3DFormat.
+ *
+ * @param Format specifies the value to convert.
+ *
+ * @return Pointer to the converted string.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+const char *XVidC_Get3DFormatStr(XVidC_3DFormat Format)
+{
+ switch (Format) {
+ case XVIDC_3D_FRAME_PACKING:
+ return ("Frame Packing");
+
+ case XVIDC_3D_FIELD_ALTERNATIVE:
+ return ("Field Alternative");
+
+ case XVIDC_3D_LINE_ALTERNATIVE:
+ return ("Line Alternative");
+
+ case XVIDC_3D_SIDE_BY_SIDE_FULL:
+ return ("Side-by-Side(full)");
+
+ case XVIDC_3D_TOP_AND_BOTTOM_HALF:
+ return ("Top-and-Bottom(half)");
+
+ case XVIDC_3D_SIDE_BY_SIDE_HALF:
+ return ("Side-by-Side(half)");
+
+ default:
+ return ("Unknown");
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function returns the color format name for index specified.
+ *
+ * @param ColorFormatId specifies the index of color format space.
+ *
+ * @return Pointer to a color space name string.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+const char *XVidC_GetColorFormatStr(XVidC_ColorFormat ColorFormatId)
+{
+ switch (ColorFormatId) {
+ case XVIDC_CSF_RGB: return ("RGB");
+ case XVIDC_CSF_YCRCB_444: return ("YUV_444");
+ case XVIDC_CSF_YCRCB_422: return ("YUV_422");
+ case XVIDC_CSF_YCRCB_420: return ("YUV_420");
+ case XVIDC_CSF_YONLY: return ("Y_ONLY");
+ case XVIDC_CSF_MEM_RGBX8: return ("RGBX8");
+ case XVIDC_CSF_MEM_YUVX8: return ("YUVX8");
+ case XVIDC_CSF_MEM_YUYV8: return ("YUYV8");
+ case XVIDC_CSF_MEM_RGBA8: return ("RGBA8");
+ case XVIDC_CSF_MEM_YUVA8: return ("YUVA8");
+ case XVIDC_CSF_MEM_RGBX10: return ("RGBX10");
+ case XVIDC_CSF_MEM_YUVX10: return ("YUVX10");
+ case XVIDC_CSF_MEM_RGB565: return ("RGB565");
+ case XVIDC_CSF_MEM_Y_UV8: return ("Y_UV8");
+ case XVIDC_CSF_MEM_Y_UV8_420: return ("Y_UV8_420");
+ case XVIDC_CSF_MEM_RGB8: return ("RGB8");
+ case XVIDC_CSF_MEM_YUV8: return ("YUV8");
+ case XVIDC_CSF_MEM_Y_UV10: return ("Y_UV10");
+ case XVIDC_CSF_MEM_Y_UV10_420: return ("Y_UV10_420");
+ case XVIDC_CSF_MEM_Y8: return ("Y8");
+ case XVIDC_CSF_MEM_Y10: return ("Y10");
+ case XVIDC_CSF_MEM_BGRA8: return ("BGRA8");
+
+ default:
+ return ("Color space format not supported");
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function returns the frame rate for index specified.
+ *
+ * @param VmId specifies the resolution id.
+ *
+ * @return Frame rate in Hz.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+XVidC_FrameRate XVidC_GetFrameRate(XVidC_VideoMode VmId)
+{
+ const XVidC_VideoTimingMode *VmPtr;
+
+ VmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VmPtr) {
+ return XVIDC_FR_NUM_SUPPORTED;
+ }
+
+ return VmPtr->FrameRate;
+}
+
+/******************************************************************************/
+/**
+ * This function returns the timing parameters for specified resolution.
+ *
+ * @param VmId specifies the resolution id.
+ *
+ * @return Pointer to a XVidC_VideoTiming structure.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+const XVidC_VideoTiming *XVidC_GetTimingInfo(XVidC_VideoMode VmId)
+{
+ const XVidC_VideoTimingMode *VmPtr;
+
+ VmPtr = XVidC_GetVideoModeData(VmId);
+ if (!VmPtr) {
+ return NULL;
+ }
+
+ return &VmPtr->Timing;
+}
+
+/******************************************************************************/
+/**
+ * This function sets the VideoStream structure for the specified video format.
+ *
+ * @param VidStrmPtr is a pointer to the XVidC_VideoStream structure to be
+ * set.
+ * @param VmId specifies the resolution ID.
+ * @param ColorFormat specifies the color format type.
+ * @param Bpc specifies the color depth/bits per color component.
+ * @param Ppc specifies the pixels per clock.
+ *
+ * @return
+ * - XST_SUCCESS if the timing for the supplied ID was found.
+ * - XST_FAILURE, otherwise.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u32 XVidC_SetVideoStream(XVidC_VideoStream *VidStrmPtr, XVidC_VideoMode VmId,
+ XVidC_ColorFormat ColorFormat, XVidC_ColorDepth Bpc,
+ XVidC_PixelsPerClock Ppc)
+{
+ const XVidC_VideoTiming *TimingPtr;
+
+ /* Verify arguments. */
+ Xil_AssertNonvoid(VidStrmPtr != NULL);
+ Xil_AssertNonvoid((ColorFormat == XVIDC_CSF_RGB) ||
+ (ColorFormat == XVIDC_CSF_YCRCB_444) ||
+ (ColorFormat == XVIDC_CSF_YCRCB_422) ||
+ (ColorFormat == XVIDC_CSF_YCRCB_420) ||
+ (ColorFormat == XVIDC_CSF_UNKNOWN));
+ Xil_AssertNonvoid((Bpc == XVIDC_BPC_6) ||
+ (Bpc == XVIDC_BPC_8) ||
+ (Bpc == XVIDC_BPC_10) ||
+ (Bpc == XVIDC_BPC_12) ||
+ (Bpc == XVIDC_BPC_14) ||
+ (Bpc == XVIDC_BPC_16) ||
+ (Bpc == XVIDC_BPC_UNKNOWN));
+ Xil_AssertNonvoid((Ppc == XVIDC_PPC_1) ||
+ (Ppc == XVIDC_PPC_2) ||
+ (Ppc == XVIDC_PPC_4));
+
+ /* Get the timing from the video timing table. */
+ if (VmId != XVIDC_VM_CUSTOM) {
+ TimingPtr = XVidC_GetTimingInfo(VmId);
+ if (!TimingPtr) {
+ return XST_FAILURE;
+ }
+
+ VidStrmPtr->Timing = *TimingPtr;
+ VidStrmPtr->FrameRate = XVidC_GetFrameRate(VmId);
+ VidStrmPtr->IsInterlaced = XVidC_IsInterlaced(VmId);
+
+ } else { //Custom Timing - use as-is
+ VidStrmPtr->IsInterlaced = FALSE;
+ }
+ VidStrmPtr->VmId = VmId;
+ VidStrmPtr->ColorFormatId = ColorFormat;
+ VidStrmPtr->ColorDepth = Bpc;
+ VidStrmPtr->PixPerClk = Ppc;
+
+ /* Set stream to 2D. */
+ VidStrmPtr->Is3D = FALSE;
+ VidStrmPtr->Info_3D.Format = XVIDC_3D_UNKNOWN;
+ VidStrmPtr->Info_3D.Sampling.Method = XVIDC_3D_SAMPLING_UNKNOWN;
+ VidStrmPtr->Info_3D.Sampling.Position = XVIDC_3D_SAMPPOS_UNKNOWN;
+
+ return XST_SUCCESS;
+}
+
+/******************************************************************************/
+/**
+ * This function sets the VideoStream structure for the specified 3D video
+ * format.
+ *
+ * @param VidStrmPtr is a pointer to the XVidC_VideoStream structure to be
+ * set.
+ * @param VmId specifies the resolution ID.
+ * @param ColorFormat specifies the color format type.
+ * @param Bpc specifies the color depth/bits per color component.
+ * @param Ppc specifies the pixels per clock.
+ * @param Info3DPtr is a pointer to a XVidC_3DInfo structure.
+ *
+ * @return
+ * - XST_SUCCESS if the timing for the supplied ID was found.
+ * - XST_FAILURE, otherwise.
+ *
+ * @return
+ * - XST_SUCCESS
+ * - XST_FAILURE
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u32 XVidC_Set3DVideoStream(XVidC_VideoStream *VidStrmPtr, XVidC_VideoMode VmId,
+ XVidC_ColorFormat ColorFormat, XVidC_ColorDepth Bpc,
+ XVidC_PixelsPerClock Ppc, XVidC_3DInfo *Info3DPtr)
+{
+ u32 Status;
+ u16 Vblank0;
+ u16 Vblank1;
+
+ /* Verify arguments */
+ Xil_AssertNonvoid(Info3DPtr != NULL);
+
+ /* Initialize with info for 2D frame. */
+ Status = XVidC_SetVideoStream(VidStrmPtr, VmId, ColorFormat, Bpc, Ppc);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /* Set stream to 3D. */
+ VidStrmPtr->Is3D = TRUE;
+ VidStrmPtr->Info_3D = *Info3DPtr;
+
+ /* Only 3D format supported is frame packing. */
+ if (Info3DPtr->Format != XVIDC_3D_FRAME_PACKING) {
+ return XST_FAILURE;
+ }
+
+ /* Update the timing based on the 3D format. */
+
+ /* An interlaced format is converted to a progressive frame: */
+ /* 3D VActive = (2D VActive * 4) + (2D VBlank field0) +
+ (2D Vblank field1 * 2) */
+ if (VidStrmPtr->IsInterlaced) {
+ Vblank0 = VidStrmPtr->Timing.F0PVTotal -
+ VidStrmPtr->Timing.VActive;
+ Vblank1 = VidStrmPtr->Timing.F1VTotal -
+ VidStrmPtr->Timing.VActive;
+ VidStrmPtr->Timing.VActive = (VidStrmPtr->Timing.VActive * 4) +
+ Vblank0 + (Vblank1 * 2);
+
+ /* Set VTotal */
+ VidStrmPtr->Timing.F0PVTotal *= 2;
+ VidStrmPtr->Timing.F0PVTotal += VidStrmPtr->Timing.F1VTotal * 2;
+
+ /* Clear field 1 values. */
+ VidStrmPtr->Timing.F1VFrontPorch = 0;
+ VidStrmPtr->Timing.F1VSyncWidth = 0;
+ VidStrmPtr->Timing.F1VBackPorch = 0;
+ VidStrmPtr->Timing.F1VTotal = 0;
+
+ /* Set format to progressive */
+ VidStrmPtr->IsInterlaced = FALSE;
+ }
+ /* Progressive */
+ else {
+ /* 3D Vactive = (2D VActive * 2) + (2D VBlank) */
+ Vblank0 = VidStrmPtr->Timing.F0PVTotal -
+ VidStrmPtr->Timing.VActive;
+ VidStrmPtr->Timing.VActive = (VidStrmPtr->Timing.VActive * 2) +
+ Vblank0;
+
+ /* Set VTotal. */
+ VidStrmPtr->Timing.F0PVTotal = VidStrmPtr->Timing.F0PVTotal * 2;
+ }
+
+ return XST_SUCCESS;
+}
+
+/******************************************************************************/
+/**
+ * This function prints the stream information on STDIO/UART console.
+ *
+ * @param Stream is a pointer to video stream.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+void XVidC_ReportStreamInfo(const XVidC_VideoStream *Stream)
+{
+ if (!XVidC_GetVideoModeData(Stream->VmId) &&
+ (Stream->VmId != XVIDC_VM_CUSTOM)) {
+ xil_printf("\tThe stream ID (%d) is not supported.\r\n",
+ Stream->VmId);
+ return;
+ }
+
+ xil_printf("\tColor Format: %s\r\n",
+ XVidC_GetColorFormatStr(Stream->ColorFormatId));
+ xil_printf("\tColor Depth: %d\r\n", Stream->ColorDepth);
+ xil_printf("\tPixels Per Clock: %d\r\n", Stream->PixPerClk);
+ xil_printf("\tMode: %s\r\n",
+ Stream->IsInterlaced ? "Interlaced" : "Progressive");
+
+ if (Stream->Is3D) {
+ xil_printf("\t3D Format: %s\r\n",
+ XVidC_Get3DFormatStr(Stream->Info_3D.Format));
+ }
+
+ if (Stream->VmId == XVIDC_VM_CUSTOM) {
+ xil_printf("\tFrame Rate: %dHz\r\n",
+ Stream->FrameRate);
+ xil_printf("\tResolution: %dx%d [Custom Mode]\r\n",
+ Stream->Timing.HActive, Stream->Timing.VActive);
+ xil_printf("\tPixel Clock: %d\r\n",
+ XVidC_GetPixelClockHzByHVFr(
+ Stream->Timing.HTotal,
+ Stream->Timing.F0PVTotal,
+ Stream->FrameRate));
+ }
+ else {
+ xil_printf("\tFrame Rate: %s\r\n",
+ XVidC_GetFrameRateStr(Stream->VmId));
+ xil_printf("\tResolution: %s\r\n",
+ XVidC_GetVideoModeStr(Stream->VmId));
+ xil_printf("\tPixel Clock: %d\r\n",
+ XVidC_GetPixelClockHzByVmId(Stream->VmId));
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function prints timing information on STDIO/Uart console.
+ *
+ * @param Timing is a pointer to Video Timing structure of the stream.
+ * @param IsInterlaced is a TRUE/FALSE flag that denotes the timing
+ * parameter is for interlaced/progressive stream.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+void XVidC_ReportTiming(const XVidC_VideoTiming *Timing, u8 IsInterlaced)
+{
+ xil_printf("\r\n\tHSYNC Timing: hav=%04d, hfp=%02d, hsw=%02d(hsp=%d), "
+ "hbp=%03d, htot=%04d \n\r", Timing->HActive,
+ Timing->HFrontPorch, Timing->HSyncWidth,
+ Timing->HSyncPolarity,
+ Timing->HBackPorch, Timing->HTotal);
+
+ /* Interlaced */
+ if (IsInterlaced) {
+ xil_printf("\tVSYNC Timing (Field 0): vav=%04d, vfp=%02d, "
+ "vsw=%02d(vsp=%d), vbp=%03d, vtot=%04d\n\r",
+ Timing->VActive, Timing->F0PVFrontPorch,
+ Timing->F0PVSyncWidth, Timing->VSyncPolarity,
+ Timing->F0PVBackPorch, Timing->F0PVTotal);
+ xil_printf("\tVSYNC Timing (Field 1): vav=%04d, vfp=%02d, "
+ "vsw=%02d(vsp=%d), vbp=%03d, vtot=%04d\n\r",
+ Timing->VActive, Timing->F1VFrontPorch,
+ Timing->F1VSyncWidth, Timing->VSyncPolarity,
+ Timing->F1VBackPorch, Timing->F1VTotal);
+ }
+ /* Progressive */
+ else {
+ xil_printf("\tVSYNC Timing: vav=%04d, vfp=%02d, "
+ "vsw=%02d(vsp=%d), vbp=%03d, vtot=%04d\n\r",
+ Timing->VActive, Timing->F0PVFrontPorch,
+ Timing->F0PVSyncWidth, Timing->VSyncPolarity,
+ Timing->F0PVBackPorch, Timing->F0PVTotal);
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function returns the pointer to video mode data at the provided index
+ * of the custom video mode table.
+ *
+ * @param VmId specifies the resolution ID.
+ *
+ * @return Pointer to XVidC_VideoTimingMode structure based on the given
+ * video mode.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static const XVidC_VideoTimingMode *XVidC_GetCustomVideoModeData(
+ XVidC_VideoMode VmId)
+{
+ u16 Index;
+
+ for (Index = 0; Index < XVidC_NumCustomModes; Index++) {
+ if (VmId == (XVidC_CustomTimingModes[Index].VmId)) {
+ return &(XVidC_CustomTimingModes[Index]);
+ }
+ }
+
+ /* ID not found within the custom video mode table. */
+ return NULL;
+}
+
+/******************************************************************************/
+/**
+ * This function returns whether or not the video timing mode is a reduced
+ * blanking mode or not.
+ *
+ * @param VideoModeStr specifies the resolution name string.
+ * @param RbN specifies the type of reduced blanking:
+ * - 0 = No Reduced Blanking
+ * - 1 = RB
+ * - 2 = RB2
+ *
+ * @return If the reduced blanking type is compatible with the video mode:
+ * - 0 = Not supported
+ * - 1 = Video mode supports the RB type
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static u8 XVidC_IsVtmRb(const char *VideoModeStr, u8 RbN)
+{
+ while ((*VideoModeStr !='\0') && (*VideoModeStr != 'R')) {
+ VideoModeStr++;
+ }
+
+ if (*(VideoModeStr + 2) == ')') {
+ return RbN == 1;
+ }
+ if (*(VideoModeStr + 2) == '2') {
+ return RbN == 2;
+ }
+ return 0;
+}
+/** @} */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.h
new file mode 100644
index 00000000000000..e566881d78c306
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc.h
@@ -0,0 +1,542 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvidc.h
+ * @addtogroup video_common_v4_0
+ * @{
+ * @details
+ *
+ * Contains common structures, definitions, macros, and utility functions that
+ * are typically used by video-related drivers and applications.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 rc, 01/10/15 Initial release.
+ * als
+ * 2.0 als 08/14/15 Added new video timings.
+ * 2.2 als 02/01/16 Functions with pointer arguments that don't modify
+ * contents now const.
+ * Added ability to insert a custom video timing table:
+ * XVidC_RegisterCustomTimingModes
+ * XVidC_UnregisterCustomTimingMode
+ * yh Added 3D support.
+ * 3.0 aad 05/13/16 Added API to search for RB video modes.
+ * als 05/16/16 Added Y-only to color format enum.
+ * 3.1 rco 07/26/17 Moved timing table extern definition to xvidc.c
+ * Added video-in-memory color formats
+ * Updated XVidC_RegisterCustomTimingModes API signature
+ * 4.1 rco 11/23/17 Added new memory formats
+ * Added xil_printf include statement
+ * Added new API XVidC_GetVideoModeIdWBlanking
+ * Fix C++ warnings
+ * </pre>
+ *
+*******************************************************************************/
+
+#ifndef XVIDC_H_ /* Prevent circular inclusions by using protection macros. */
+#define XVIDC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************* Include Files ********************************/
+
+#include "xil_types.h"
+#include "xil_printf.h"
+
+/************************** Constant Definitions ******************************/
+
+/**
+ * This typedef enumerates the list of available standard display monitor
+ * timings as specified in the xvidc_timings_table.c file. The naming format is:
+ *
+ * XVIDC_VM_<RESOLUTION>_<REFRESH RATE (HZ)>_<P|I>(_RB)
+ *
+ * Where RB stands for reduced blanking.
+ */
+typedef enum {
+ /* Interlaced modes. */
+ XVIDC_VM_720x480_60_I = 0,
+ XVIDC_VM_720x576_50_I,
+ XVIDC_VM_1440x480_60_I,
+ XVIDC_VM_1440x576_50_I,
+ XVIDC_VM_1920x1080_50_I,
+ XVIDC_VM_1920x1080_60_I,
+
+ /* Progressive modes. */
+ XVIDC_VM_640x350_85_P,
+ XVIDC_VM_640x480_60_P,
+ XVIDC_VM_640x480_72_P,
+ XVIDC_VM_640x480_75_P,
+ XVIDC_VM_640x480_85_P,
+ XVIDC_VM_720x400_85_P,
+ XVIDC_VM_720x480_60_P,
+ XVIDC_VM_720x576_50_P,
+ XVIDC_VM_800x600_56_P,
+ XVIDC_VM_800x600_60_P,
+ XVIDC_VM_800x600_72_P,
+ XVIDC_VM_800x600_75_P,
+ XVIDC_VM_800x600_85_P,
+ XVIDC_VM_800x600_120_P_RB,
+ XVIDC_VM_848x480_60_P,
+ XVIDC_VM_1024x768_60_P,
+ XVIDC_VM_1024x768_70_P,
+ XVIDC_VM_1024x768_75_P,
+ XVIDC_VM_1024x768_85_P,
+ XVIDC_VM_1024x768_120_P_RB,
+ XVIDC_VM_1152x864_75_P,
+ XVIDC_VM_1280x720_50_P,
+ XVIDC_VM_1280x720_60_P,
+ XVIDC_VM_1280x768_60_P,
+ XVIDC_VM_1280x768_60_P_RB,
+ XVIDC_VM_1280x768_75_P,
+ XVIDC_VM_1280x768_85_P,
+ XVIDC_VM_1280x768_120_P_RB,
+ XVIDC_VM_1280x800_60_P,
+ XVIDC_VM_1280x800_60_P_RB,
+ XVIDC_VM_1280x800_75_P,
+ XVIDC_VM_1280x800_85_P,
+ XVIDC_VM_1280x800_120_P_RB,
+ XVIDC_VM_1280x960_60_P,
+ XVIDC_VM_1280x960_85_P,
+ XVIDC_VM_1280x960_120_P_RB,
+ XVIDC_VM_1280x1024_60_P,
+ XVIDC_VM_1280x1024_75_P,
+ XVIDC_VM_1280x1024_85_P,
+ XVIDC_VM_1280x1024_120_P_RB,
+ XVIDC_VM_1360x768_60_P,
+ XVIDC_VM_1360x768_120_P_RB,
+ XVIDC_VM_1366x768_60_P,
+ XVIDC_VM_1400x1050_60_P,
+ XVIDC_VM_1400x1050_60_P_RB,
+ XVIDC_VM_1400x1050_75_P,
+ XVIDC_VM_1400x1050_85_P,
+ XVIDC_VM_1400x1050_120_P_RB,
+ XVIDC_VM_1440x240_60_P,
+ XVIDC_VM_1440x900_60_P,
+ XVIDC_VM_1440x900_60_P_RB,
+ XVIDC_VM_1440x900_75_P,
+ XVIDC_VM_1440x900_85_P,
+ XVIDC_VM_1440x900_120_P_RB,
+ XVIDC_VM_1600x1200_60_P,
+ XVIDC_VM_1600x1200_65_P,
+ XVIDC_VM_1600x1200_70_P,
+ XVIDC_VM_1600x1200_75_P,
+ XVIDC_VM_1600x1200_85_P,
+ XVIDC_VM_1600x1200_120_P_RB,
+ XVIDC_VM_1680x720_50_P,
+ XVIDC_VM_1680x720_60_P,
+ XVIDC_VM_1680x720_100_P,
+ XVIDC_VM_1680x720_120_P,
+ XVIDC_VM_1680x1050_50_P,
+ XVIDC_VM_1680x1050_60_P,
+ XVIDC_VM_1680x1050_60_P_RB,
+ XVIDC_VM_1680x1050_75_P,
+ XVIDC_VM_1680x1050_85_P,
+ XVIDC_VM_1680x1050_120_P_RB,
+ XVIDC_VM_1792x1344_60_P,
+ XVIDC_VM_1792x1344_75_P,
+ XVIDC_VM_1792x1344_120_P_RB,
+ XVIDC_VM_1856x1392_60_P,
+ XVIDC_VM_1856x1392_75_P,
+ XVIDC_VM_1856x1392_120_P_RB,
+ XVIDC_VM_1920x1080_24_P,
+ XVIDC_VM_1920x1080_25_P,
+ XVIDC_VM_1920x1080_30_P,
+ XVIDC_VM_1920x1080_50_P,
+ XVIDC_VM_1920x1080_60_P,
+ XVIDC_VM_1920x1080_100_P,
+ XVIDC_VM_1920x1080_120_P,
+ XVIDC_VM_1920x1200_60_P,
+ XVIDC_VM_1920x1200_60_P_RB,
+ XVIDC_VM_1920x1200_75_P,
+ XVIDC_VM_1920x1200_85_P,
+ XVIDC_VM_1920x1200_120_P_RB,
+ XVIDC_VM_1920x1440_60_P,
+ XVIDC_VM_1920x1440_75_P,
+ XVIDC_VM_1920x1440_120_P_RB,
+ XVIDC_VM_1920x2160_60_P,
+ XVIDC_VM_2560x1080_50_P,
+ XVIDC_VM_2560x1080_60_P,
+ XVIDC_VM_2560x1080_100_P,
+ XVIDC_VM_2560x1080_120_P,
+ XVIDC_VM_2560x1600_60_P,
+ XVIDC_VM_2560x1600_60_P_RB,
+ XVIDC_VM_2560x1600_75_P,
+ XVIDC_VM_2560x1600_85_P,
+ XVIDC_VM_2560x1600_120_P_RB,
+ XVIDC_VM_3840x2160_24_P,
+ XVIDC_VM_3840x2160_25_P,
+ XVIDC_VM_3840x2160_30_P,
+ XVIDC_VM_3840x2160_50_P,
+ XVIDC_VM_3840x2160_60_P,
+ XVIDC_VM_4096x2160_24_P,
+ XVIDC_VM_4096x2160_25_P,
+ XVIDC_VM_4096x2160_30_P,
+ XVIDC_VM_4096x2160_50_P,
+ XVIDC_VM_4096x2160_60_P,
+ XVIDC_VM_4096x2160_60_P_RB,
+
+ XVIDC_VM_NUM_SUPPORTED,
+ XVIDC_VM_USE_EDID_PREFERRED,
+ XVIDC_VM_NO_INPUT,
+ XVIDC_VM_NOT_SUPPORTED,
+ XVIDC_VM_CUSTOM,
+
+ /* Marks beginning/end of interlaced/progressive modes in the table. */
+ XVIDC_VM_INTL_START = XVIDC_VM_720x480_60_I,
+ XVIDC_VM_PROG_START = XVIDC_VM_640x350_85_P,
+ XVIDC_VM_INTL_END = (XVIDC_VM_PROG_START - 1),
+ XVIDC_VM_PROG_END = (XVIDC_VM_NUM_SUPPORTED - 1),
+
+ /* Common naming. */
+ XVIDC_VM_480_60_I = XVIDC_VM_720x480_60_I,
+ XVIDC_VM_576_50_I = XVIDC_VM_720x576_50_I,
+ XVIDC_VM_1080_50_I = XVIDC_VM_1920x1080_50_I,
+ XVIDC_VM_1080_60_I = XVIDC_VM_1920x1080_60_I,
+ XVIDC_VM_VGA_60_P = XVIDC_VM_640x480_60_P,
+ XVIDC_VM_480_60_P = XVIDC_VM_720x480_60_P,
+ XVIDC_VM_SVGA_60_P = XVIDC_VM_800x600_60_P,
+ XVIDC_VM_XGA_60_P = XVIDC_VM_1024x768_60_P,
+ XVIDC_VM_720_50_P = XVIDC_VM_1280x720_50_P,
+ XVIDC_VM_720_60_P = XVIDC_VM_1280x720_60_P,
+ XVIDC_VM_WXGA_60_P = XVIDC_VM_1366x768_60_P,
+ XVIDC_VM_UXGA_60_P = XVIDC_VM_1600x1200_60_P,
+ XVIDC_VM_WSXGA_60_P = XVIDC_VM_1680x1050_60_P,
+ XVIDC_VM_1080_24_P = XVIDC_VM_1920x1080_24_P,
+ XVIDC_VM_1080_25_P = XVIDC_VM_1920x1080_25_P,
+ XVIDC_VM_1080_30_P = XVIDC_VM_1920x1080_30_P,
+ XVIDC_VM_1080_50_P = XVIDC_VM_1920x1080_50_P,
+ XVIDC_VM_1080_60_P = XVIDC_VM_1920x1080_60_P,
+ XVIDC_VM_WUXGA_60_P = XVIDC_VM_1920x1200_60_P,
+ XVIDC_VM_UHD2_60_P = XVIDC_VM_1920x2160_60_P,
+ XVIDC_VM_UHD_24_P = XVIDC_VM_3840x2160_24_P,
+ XVIDC_VM_UHD_25_P = XVIDC_VM_3840x2160_25_P,
+ XVIDC_VM_UHD_30_P = XVIDC_VM_3840x2160_30_P,
+ XVIDC_VM_UHD_60_P = XVIDC_VM_3840x2160_60_P,
+ XVIDC_VM_4K2K_60_P = XVIDC_VM_4096x2160_60_P,
+ XVIDC_VM_4K2K_60_P_RB = XVIDC_VM_4096x2160_60_P_RB,
+} XVidC_VideoMode;
+
+/**
+ * Progressive/interlaced video format.
+ */
+typedef enum {
+ XVIDC_VF_PROGRESSIVE = 0,
+ XVIDC_VF_INTERLACED,
+ XVIDC_VF_UNKNOWN
+} XVidC_VideoFormat;
+
+/**
+ * Frame rate.
+ */
+typedef enum {
+ XVIDC_FR_24HZ = 24,
+ XVIDC_FR_25HZ = 25,
+ XVIDC_FR_30HZ = 30,
+ XVIDC_FR_50HZ = 50,
+ XVIDC_FR_56HZ = 56,
+ XVIDC_FR_60HZ = 60,
+ XVIDC_FR_65HZ = 65,
+ XVIDC_FR_67HZ = 67,
+ XVIDC_FR_70HZ = 70,
+ XVIDC_FR_72HZ = 72,
+ XVIDC_FR_75HZ = 75,
+ XVIDC_FR_85HZ = 85,
+ XVIDC_FR_87HZ = 87,
+ XVIDC_FR_88HZ = 88,
+ XVIDC_FR_100HZ = 100,
+ XVIDC_FR_120HZ = 120,
+ XVIDC_FR_NUM_SUPPORTED = 16,
+ XVIDC_FR_UNKNOWN
+} XVidC_FrameRate;
+
+/**
+ * Color depth - bits per color component.
+ */
+typedef enum {
+ XVIDC_BPC_6 = 6,
+ XVIDC_BPC_8 = 8,
+ XVIDC_BPC_10 = 10,
+ XVIDC_BPC_12 = 12,
+ XVIDC_BPC_14 = 14,
+ XVIDC_BPC_16 = 16,
+ XVIDC_BPC_NUM_SUPPORTED = 6,
+ XVIDC_BPC_UNKNOWN
+} XVidC_ColorDepth;
+
+/**
+ * Pixels per clock.
+ */
+typedef enum {
+ XVIDC_PPC_1 = 1,
+ XVIDC_PPC_2 = 2,
+ XVIDC_PPC_4 = 4,
+ XVIDC_PPC_8 = 8,
+ XVIDC_PPC_NUM_SUPPORTED = 4,
+} XVidC_PixelsPerClock;
+
+/**
+ * Color space format.
+ */
+typedef enum {
+ /* Streaming video formats */
+ XVIDC_CSF_RGB = 0,
+ XVIDC_CSF_YCRCB_444,
+ XVIDC_CSF_YCRCB_422,
+ XVIDC_CSF_YCRCB_420,
+ XVIDC_CSF_YONLY,
+
+ /* 6 empty slots reserved for video formats for future
+ * extension
+ */
+
+ /* Video in memory formats */
+ XVIDC_CSF_MEM_RGBX8 = 10, // [31:0] x:B:G:R 8:8:8:8
+ XVIDC_CSF_MEM_YUVX8, // [31:0] x:V:U:Y 8:8:8:8
+ XVIDC_CSF_MEM_YUYV8, // [31:0] V:Y:U:Y 8:8:8:8
+ XVIDC_CSF_MEM_RGBA8, // [31:0] A:B:G:R 8:8:8:8
+ XVIDC_CSF_MEM_YUVA8, // [31:0] A:V:U:Y 8:8:8:8
+ XVIDC_CSF_MEM_RGBX10, // [31:0] x:B:G:R 2:10:10:10
+ XVIDC_CSF_MEM_YUVX10, // [31:0] x:V:U:Y 2:10:10:10
+ XVIDC_CSF_MEM_RGB565, // [15:0] B:G:R 5:6:5
+ XVIDC_CSF_MEM_Y_UV8, // [15:0] Y:Y 8:8, [15:0] V:U 8:8
+ XVIDC_CSF_MEM_Y_UV8_420, // [15:0] Y:Y 8:8, [15:0] V:U 8:8
+ XVIDC_CSF_MEM_RGB8, // [23:0] B:G:R 8:8:8
+ XVIDC_CSF_MEM_YUV8, // [24:0] V:U:Y 8:8:8
+ XVIDC_CSF_MEM_Y_UV10, // [31:0] x:Y:Y:Y 2:10:10:10 [31:0] x:U:V:U 2:10:10:10
+ XVIDC_CSF_MEM_Y_UV10_420, // [31:0] x:Y:Y:Y 2:10:10:10 [31:0] x:U:V:U 2:10:10:10
+ XVIDC_CSF_MEM_Y8, // [31:0] Y:Y:Y:Y 8:8:8:8
+ XVIDC_CSF_MEM_Y10, // [31:0] x:Y:Y:Y 2:10:10:10
+ XVIDC_CSF_MEM_BGRA8, // [31:0] A:R:G:B 8:8:8:8
+
+ XVIDC_CSF_NUM_SUPPORTED, // includes the reserved slots
+ XVIDC_CSF_UNKNOWN,
+ XVIDC_CSF_STRM_START = XVIDC_CSF_RGB,
+ XVIDC_CSF_STRM_END = XVIDC_CSF_YONLY,
+ XVIDC_CSF_MEM_START = XVIDC_CSF_MEM_RGBX8,
+ XVIDC_CSF_MEM_END = (XVIDC_CSF_NUM_SUPPORTED - 1),
+ XVIDC_CSF_NUM_STRM = (XVIDC_CSF_STRM_END - XVIDC_CSF_STRM_START + 1),
+ XVIDC_CSF_NUM_MEM = (XVIDC_CSF_MEM_END - XVIDC_CSF_MEM_START + 1)
+} XVidC_ColorFormat;
+
+/**
+ * Color space conversion standard.
+ */
+typedef enum {
+ XVIDC_BT_2020 = 0,
+ XVIDC_BT_709,
+ XVIDC_BT_601,
+ XVIDC_BT_NUM_SUPPORTED,
+ XVIDC_BT_UNKNOWN
+} XVidC_ColorStd;
+
+/**
+ * Color conversion output range.
+ */
+typedef enum {
+ XVIDC_CR_16_235 = 0,
+ XVIDC_CR_16_240,
+ XVIDC_CR_0_255,
+ XVIDC_CR_NUM_SUPPORTED,
+ XVIDC_CR_UNKNOWN_RANGE
+} XVidC_ColorRange;
+
+/**
+ * 3D formats.
+ */
+typedef enum {
+ XVIDC_3D_FRAME_PACKING = 0, /**< Frame packing. */
+ XVIDC_3D_FIELD_ALTERNATIVE, /**< Field alternative. */
+ XVIDC_3D_LINE_ALTERNATIVE, /**< Line alternative. */
+ XVIDC_3D_SIDE_BY_SIDE_FULL, /**< Side-by-side (full). */
+ XVIDC_3D_TOP_AND_BOTTOM_HALF, /**< Top-and-bottom (half). */
+ XVIDC_3D_SIDE_BY_SIDE_HALF, /**< Side-by-side (half). */
+ XVIDC_3D_UNKNOWN
+} XVidC_3DFormat;
+
+/**
+ * 3D Sub-sampling methods.
+ */
+typedef enum {
+ XVIDC_3D_SAMPLING_HORIZONTAL = 0, /**< Horizontal sub-sampling. */
+ XVIDC_3D_SAMPLING_QUINCUNX, /**< Quincunx matrix. */
+ XVIDC_3D_SAMPLING_UNKNOWN
+} XVidC_3DSamplingMethod;
+
+/**
+ * 3D Sub-sampling positions.
+ */
+typedef enum {
+ XVIDC_3D_SAMPPOS_OLOR = 0, /**< Odd/Left, Odd/Right. */
+ XVIDC_3D_SAMPPOS_OLER, /**< Odd/Left, Even/Right. */
+ XVIDC_3D_SAMPPOS_ELOR, /**< Even/Left, Odd/Right. */
+ XVIDC_3D_SAMPPOS_ELER, /**< Even/Left, Even/Right. */
+ XVIDC_3D_SAMPPOS_UNKNOWN
+} XVidC_3DSamplingPosition;
+
+/****************************** Type Definitions ******************************/
+
+/**
+ * Video timing structure.
+ */
+typedef struct {
+ u16 HActive;
+ u16 HFrontPorch;
+ u16 HSyncWidth;
+ u16 HBackPorch;
+ u16 HTotal;
+ u8 HSyncPolarity;
+ u16 VActive;
+ u16 F0PVFrontPorch;
+ u16 F0PVSyncWidth;
+ u16 F0PVBackPorch;
+ u16 F0PVTotal;
+ u16 F1VFrontPorch;
+ u16 F1VSyncWidth;
+ u16 F1VBackPorch;
+ u16 F1VTotal;
+ u8 VSyncPolarity;
+} XVidC_VideoTiming;
+
+/**
+ * 3D Sampling info structure.
+ */
+typedef struct {
+ XVidC_3DSamplingMethod Method;
+ XVidC_3DSamplingPosition Position;
+} XVidC_3DSamplingInfo;
+
+/**
+ * 3D info structure.
+ */
+typedef struct {
+ XVidC_3DFormat Format;
+ XVidC_3DSamplingInfo Sampling;
+} XVidC_3DInfo;
+
+/**
+ * Video stream structure.
+ */
+typedef struct {
+ XVidC_ColorFormat ColorFormatId;
+ XVidC_ColorDepth ColorDepth;
+ XVidC_PixelsPerClock PixPerClk;
+ XVidC_FrameRate FrameRate;
+ u8 IsInterlaced;
+ u8 Is3D;
+ XVidC_3DInfo Info_3D;
+ XVidC_VideoMode VmId;
+ XVidC_VideoTiming Timing;
+} XVidC_VideoStream;
+
+/**
+ * Video window structure.
+ */
+typedef struct {
+ u32 StartX;
+ u32 StartY;
+ u32 Width;
+ u32 Height;
+} XVidC_VideoWindow;
+
+/**
+ * Video timing mode from the video timing table.
+ */
+typedef struct {
+ XVidC_VideoMode VmId;
+ const char Name[21];
+ XVidC_FrameRate FrameRate;
+ XVidC_VideoTiming Timing;
+} XVidC_VideoTimingMode;
+
+/**
+ * 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. Therefore a custom timer
+ * handler is used, the user may implement their own wait implementation.
+ *
+ * @param TimerPtr is a pointer to the timer instance.
+ * @param Delay is the duration (msec/usec) to be passed to the timer
+ * function.
+ *
+*******************************************************************************/
+typedef void (*XVidC_DelayHandler)(void *TimerPtr, u32 Delay);
+
+/**************************** Function Prototypes *****************************/
+
+u32 XVidC_RegisterCustomTimingModes(const XVidC_VideoTimingMode *CustomTable,
+ u16 NumElems);
+void XVidC_UnregisterCustomTimingModes(void);
+u32 XVidC_GetPixelClockHzByHVFr(u32 HTotal, u32 VTotal, u8 FrameRate);
+u32 XVidC_GetPixelClockHzByVmId(XVidC_VideoMode VmId);
+XVidC_VideoFormat XVidC_GetVideoFormat(XVidC_VideoMode VmId);
+u8 XVidC_IsInterlaced(XVidC_VideoMode VmId);
+const XVidC_VideoTimingMode* XVidC_GetVideoModeData(XVidC_VideoMode VmId);
+const char *XVidC_GetVideoModeStr(XVidC_VideoMode VmId);
+const char *XVidC_GetFrameRateStr(XVidC_VideoMode VmId);
+const char *XVidC_GetColorFormatStr(XVidC_ColorFormat ColorFormatId);
+XVidC_FrameRate XVidC_GetFrameRate(XVidC_VideoMode VmId);
+const XVidC_VideoTiming* XVidC_GetTimingInfo(XVidC_VideoMode VmId);
+void XVidC_ReportStreamInfo(const XVidC_VideoStream *Stream);
+void XVidC_ReportTiming(const XVidC_VideoTiming *Timing, u8 IsInterlaced);
+const char *XVidC_Get3DFormatStr(XVidC_3DFormat Format);
+u32 XVidC_SetVideoStream(XVidC_VideoStream *VidStrmPtr, XVidC_VideoMode VmId,
+ XVidC_ColorFormat ColorFormat, XVidC_ColorDepth Bpc,
+ XVidC_PixelsPerClock Ppc);
+u32 XVidC_Set3DVideoStream(XVidC_VideoStream *VidStrmPtr, XVidC_VideoMode VmId,
+ XVidC_ColorFormat ColorFormat, XVidC_ColorDepth Bpc,
+ XVidC_PixelsPerClock Ppc, XVidC_3DInfo *Info3DPtr);
+XVidC_VideoMode XVidC_GetVideoModeId(u32 Width, u32 Height, u32 FrameRate,
+ u8 IsInterlaced);
+XVidC_VideoMode XVidC_GetVideoModeIdRb(u32 Width, u32 Height, u32 FrameRate,
+ u8 IsInterlaced, u8 RbN);
+XVidC_VideoMode XVidC_GetVideoModeIdWBlanking(const XVidC_VideoTiming *Timing,
+ u32 FrameRate, u8 IsInterlaced);
+
+/******************* Macros (Inline Functions) Definitions ********************/
+
+/*****************************************************************************/
+/**
+ * This macro check if video stream is 3D or 2D.
+ *
+ * @param VidStreamPtr is a pointer to the XVidC_VideoStream structure.
+ *
+ * @return 3D(1)/2D(0)
+ *
+ * @note C-style signature:
+ * u8 XDp_IsStream3D(XVidC_VideoStream *VidStreamPtr)
+ *
+ *****************************************************************************/
+#define XVidC_IsStream3D(VidStreamPtr) ((VidStreamPtr)->Is3D)
+
+/*************************** Variable Declarations ****************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XVIDC_H_ */
+/** @} */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.c
new file mode 100644
index 00000000000000..c28dccedfc5395
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.c
@@ -0,0 +1,691 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvidc_edid.c
+ * @addtogroup video_common_v4_0
+ * @{
+ *
+ * Contains function definitions related to the Extended Display Identification
+ * Data (EDID) structure which is present in all monitors. All content in this
+ * file is agnostic of communication interface protocol.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 als 11/09/14 Initial release.
+ * 2.2 als 02/01/16 Functions with pointer arguments that don't modify
+ * contents now const.
+ * 4.0 aad 10/26/16 Added API for colormetry which returns fixed point
+ * in Q0.10 format instead of float.
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include "xvidc_edid.h"
+
+/**************************** Function Prototypes *****************************/
+
+static u32 XVidC_EdidIsVideoTimingSupportedPreferredTiming(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode);
+static u32 XVidC_EdidIsVideoTimingSupportedEstablishedTimings(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode);
+static u32 XVidC_EdidIsVideoTimingSupportedStandardTimings(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode);
+static int XVidC_CalculatePower(u8 Base, u8 Power);
+static int XVidC_CalculateBinaryFraction_QFormat(u16 Val, u8 DecPtIndex);
+
+/**************************** Function Definitions ****************************/
+
+/******************************************************************************/
+/**
+ * Get the manufacturer name as specified in the vendor and product ID field of
+ * the supplied base Extended Display Identification Data (EDID).
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve the manufacturer
+ * name from.
+ * @param ManName is the string that will be modified to hold the
+ * retrieved manufacturer name.
+ *
+ * @return None.
+ *
+ * @note The ManName argument is modified with the manufacturer name.
+ *
+*******************************************************************************/
+void XVidC_EdidGetManName(const u8 *EdidRaw, char ManName[4])
+{
+ ManName[0] = 0x40 + ((EdidRaw[XVIDC_EDID_VPI_ID_MAN_NAME0] &
+ XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR0_MASK) >>
+ XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR0_SHIFT);
+ ManName[1] = 0x40 + (((EdidRaw[XVIDC_EDID_VPI_ID_MAN_NAME0] &
+ XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR1_MASK) <<
+ XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR1_POS) |
+ (EdidRaw[XVIDC_EDID_VPI_ID_MAN_NAME1] >>
+ XVIDC_EDID_VPI_ID_MAN_NAME1_CHAR1_SHIFT));
+ ManName[2] = 0x40 + (EdidRaw[XVIDC_EDID_VPI_ID_MAN_NAME1] &
+ XVIDC_EDID_VPI_ID_MAN_NAME1_CHAR2_MASK);
+ ManName[3] = '\0';
+}
+
+/******************************************************************************/
+/**
+ * Get the color bit depth (bits per primary color) as specified in the basic
+ * display parameters and features, video input definition field of the supplied
+ * base Extended Display Identification Data (EDID).
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve color depth
+ * information from.
+ *
+ * @return The number of bits per primary color as specified by the
+ * supplied base EDID.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+XVidC_ColorDepth XVidC_EdidGetColorDepth(const u8 *EdidRaw)
+{
+ XVidC_ColorDepth Bpc;
+
+ switch (((EdidRaw[XVIDC_EDID_BDISP_VID] &
+ XVIDC_EDID_BDISP_VID_DIG_BPC_MASK) >>
+ XVIDC_EDID_BDISP_VID_DIG_BPC_SHIFT)) {
+ case XVIDC_EDID_BDISP_VID_DIG_BPC_6:
+ Bpc = XVIDC_BPC_6;
+ break;
+
+ case XVIDC_EDID_BDISP_VID_DIG_BPC_8:
+ Bpc = XVIDC_BPC_8;
+ break;
+
+ case XVIDC_EDID_BDISP_VID_DIG_BPC_10:
+ Bpc = XVIDC_BPC_10;
+ break;
+
+ case XVIDC_EDID_BDISP_VID_DIG_BPC_12:
+ Bpc = XVIDC_BPC_12;
+ break;
+
+ case XVIDC_EDID_BDISP_VID_DIG_BPC_14:
+ Bpc = XVIDC_BPC_14;
+ break;
+
+ case XVIDC_EDID_BDISP_VID_DIG_BPC_16:
+ Bpc = XVIDC_BPC_16;
+ break;
+
+ default:
+ Bpc = XVIDC_BPC_UNKNOWN;
+ break;
+ }
+
+ return Bpc;
+}
+
+/******************************************************************************/
+/**
+ * Calculates the x chromaticity coordinate for red by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The x chromatacity coordinate for red.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcRedX(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_REDX_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | (EdidRaw[XVIDC_EDID_CC_RG_LOW] >>
+ XVIDC_EDID_CC_RBX_LOW_SHIFT), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the y chromaticity coordinate for red by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The y chromatacity coordinate for red.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcRedY(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_REDY_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | ((EdidRaw[XVIDC_EDID_CC_RG_LOW] &
+ XVIDC_EDID_CC_RBY_LOW_MASK) >>
+ XVIDC_EDID_CC_RBY_LOW_SHIFT), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the x chromaticity coordinate for green by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The x chromatacity coordinate for green.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcGreenX(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_GREENX_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | ((EdidRaw[XVIDC_EDID_CC_RG_LOW] &
+ XVIDC_EDID_CC_GWX_LOW_MASK) >>
+ XVIDC_EDID_CC_GWX_LOW_SHIFT), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the y chromaticity coordinate for green by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The y chromatacity coordinate for green.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcGreenY(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_GREENY_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | (EdidRaw[XVIDC_EDID_CC_RG_LOW] &
+ XVIDC_EDID_CC_GWY_LOW_MASK), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the x chromaticity coordinate for blue by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The x chromatacity coordinate for blue.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcBlueX(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_BLUEX_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | (EdidRaw[XVIDC_EDID_CC_BW_LOW] >>
+ XVIDC_EDID_CC_RBX_LOW_SHIFT), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the y chromaticity coordinate for blue by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The y chromatacity coordinate for blue.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcBlueY(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_BLUEY_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | ((EdidRaw[XVIDC_EDID_CC_BW_LOW] &
+ XVIDC_EDID_CC_RBY_LOW_MASK) >>
+ XVIDC_EDID_CC_RBY_LOW_SHIFT), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the x chromaticity coordinate for white by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to a integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The x chromatacity coordinate for white.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcWhiteX(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_WHITEX_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | ((EdidRaw[XVIDC_EDID_CC_BW_LOW] &
+ XVIDC_EDID_CC_GWX_LOW_MASK) >> XVIDC_EDID_CC_GWX_LOW_SHIFT), 10);
+}
+
+/******************************************************************************/
+/**
+ * Calculates the y chromaticity coordinate for white by converting a 10 bit
+ * binary fraction representation from the supplied base Extended Display
+ * Identification Data (EDID) to an integer in Q0.10 Format. To convert back
+ * to float divide the fixed point value by 2^10.
+ *
+ * @param EdidRaw is the supplied base EDID to retrieve chromaticity
+ * information from.
+ *
+ * @return The y chromatacity coordinate for white.
+ *
+ * @note All values will be accurate to +/-0.0005.
+ *
+*******************************************************************************/
+int XVidC_EdidGetCcWhiteY(const u8 *EdidRaw)
+{
+ return XVidC_CalculateBinaryFraction_QFormat(
+ (EdidRaw[XVIDC_EDID_CC_WHITEY_HIGH] <<
+ XVIDC_EDID_CC_HIGH_SHIFT) | (EdidRaw[XVIDC_EDID_CC_BW_LOW] &
+ XVIDC_EDID_CC_GWY_LOW_MASK), 10);
+}
+
+/******************************************************************************/
+/**
+ * Retrieves the active vertical resolution from the standard timings field of
+ * the supplied base Extended Display Identification Data (EDID).
+ *
+ * @param EdidRaw is the supplied base EDID to check the timing against.
+ * @param StdTimingsNum specifies which one of the standard timings to
+ * retrieve from the standard timings field.
+ *
+ * @return The vertical active resolution of the specified standard timing
+ * from the supplied base EDID.
+ *
+ * @note StdTimingsNum is an index 1-8.
+ *
+*******************************************************************************/
+u16 XVidC_EdidGetStdTimingsV(const u8 *EdidRaw, u8 StdTimingsNum)
+{
+ u16 V;
+
+ switch (XVidC_EdidGetStdTimingsAr(EdidRaw, StdTimingsNum)) {
+ case XVIDC_EDID_STD_TIMINGS_AR_16_10:
+ V = (10 * XVidC_EdidGetStdTimingsH(EdidRaw,
+ StdTimingsNum)) / 16;
+ break;
+
+ case XVIDC_EDID_STD_TIMINGS_AR_4_3:
+ V = (3 * XVidC_EdidGetStdTimingsH(EdidRaw,
+ StdTimingsNum)) / 4;
+ break;
+
+ case XVIDC_EDID_STD_TIMINGS_AR_5_4:
+ V = (4 * XVidC_EdidGetStdTimingsH(EdidRaw,
+ StdTimingsNum)) / 5;
+ break;
+
+ case XVIDC_EDID_STD_TIMINGS_AR_16_9:
+ V = (9 * XVidC_EdidGetStdTimingsH(EdidRaw,
+ StdTimingsNum)) / 16;
+ break;
+ default:
+ V = 0;
+ break;
+ }
+
+ return V;
+}
+
+/******************************************************************************/
+/**
+ * Checks whether or not a specified video timing mode is supported as specified
+ * in the supplied base Extended Display Identification Data (EDID). The
+ * preferred timing, established timings (I, II, II), and the standard timings
+ * fields are checked for support.
+ *
+ * @param EdidRaw is the supplied base EDID to check the timing against.
+ * @param VtMode is the video timing mode to check for support.
+ *
+ * @return
+ * - XST_SUCCESS if the video timing mode is supported as specified
+ * in the supplied base EDID.
+ * - XST_FAILURE otherwise.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u32 XVidC_EdidIsVideoTimingSupported(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode)
+{
+ u32 Status;
+
+ /* Check if the video mode is the preferred timing. */
+ Status = XVidC_EdidIsVideoTimingSupportedPreferredTiming(EdidRaw,
+ VtMode);
+ if (Status == XST_SUCCESS) {
+ return Status;
+ }
+
+ /* Check established timings I, II, and III. */
+ Status = XVidC_EdidIsVideoTimingSupportedEstablishedTimings(EdidRaw,
+ VtMode);
+ if (Status == XST_SUCCESS) {
+ return Status;
+ }
+
+ /* Check in standard timings support. */
+ Status = XVidC_EdidIsVideoTimingSupportedStandardTimings(EdidRaw,
+ VtMode);
+
+ return Status;
+}
+
+/******************************************************************************/
+/**
+ * Checks whether or not a specified video timing mode is the preferred timing
+ * of the supplied base Extended Display Identification Data (EDID).
+ *
+ * @param EdidRaw is the supplied base EDID to check the timing against.
+ * @param VtMode is the video timing mode to check for support.
+ *
+ * @return
+ * - XST_SUCCESS if the video timing mode is the preferred timing
+ * as specified in the base EDID.
+ * - XST_FAILURE otherwise.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static u32 XVidC_EdidIsVideoTimingSupportedPreferredTiming(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode)
+{
+ const u8 *Ptm;
+
+ Ptm = &EdidRaw[XVIDC_EDID_PTM];
+
+ u32 HActive = (((Ptm[XVIDC_EDID_DTD_PTM_HRES_HBLANK_U4] &
+ XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XRES_MASK) >>
+ XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XRES_SHIFT) << 8) |
+ Ptm[XVIDC_EDID_DTD_PTM_HRES_LSB];
+
+ u32 VActive = (((Ptm[XVIDC_EDID_DTD_PTM_VRES_VBLANK_U4] &
+ XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XRES_MASK) >>
+ XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XRES_SHIFT) << 8) |
+ Ptm[XVIDC_EDID_DTD_PTM_VRES_LSB];
+
+ if (VtMode->Timing.F1VTotal != XVidC_EdidIsDtdPtmInterlaced(EdidRaw)) {
+ return (XST_FAILURE);
+ }
+ else if ((VtMode->Timing.HActive == HActive) &&
+ (VtMode->Timing.VActive == VActive)) {
+ return (XST_SUCCESS);
+ }
+
+ return XST_FAILURE;
+}
+
+/******************************************************************************/
+/**
+ * Checks whether or not a specified video timing mode is supported in the
+ * established timings field of the supplied base Extended Display
+ * Identification Data (EDID).
+ *
+ * @param EdidRaw is the supplied base EDID to check the timing against.
+ * @param VtMode is the video timing mode to check for support.
+ *
+ * @return
+ * - XST_SUCCESS if the video timing mode is supported in the
+ * base EDID's established timings field.
+ * - XST_FAILURE otherwise.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static u32 XVidC_EdidIsVideoTimingSupportedEstablishedTimings(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode)
+{
+ u32 Status = XST_FAILURE;
+
+ /* Check established timings I, II, and III. */
+ if ((VtMode->Timing.HActive == 800) &&
+ (VtMode->Timing.VActive == 640) &&
+ (VtMode->FrameRate == XVIDC_FR_56HZ) &&
+ XVidC_EdidSuppEstTimings800x600_56(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 640) &&
+ (VtMode->Timing.VActive == 480) &&
+ (VtMode->FrameRate == XVIDC_FR_60HZ) &&
+ XVidC_EdidSuppEstTimings640x480_60(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 800) &&
+ (VtMode->Timing.VActive == 600) &&
+ (VtMode->FrameRate == XVIDC_FR_60HZ) &&
+ XVidC_EdidSuppEstTimings800x600_60(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 1024) &&
+ (VtMode->Timing.VActive == 768) &&
+ (VtMode->FrameRate == XVIDC_FR_60HZ) &&
+ XVidC_EdidSuppEstTimings1024x768_60(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 640) &&
+ (VtMode->Timing.VActive == 480) &&
+ (VtMode->FrameRate == XVIDC_FR_67HZ) &&
+ XVidC_EdidSuppEstTimings640x480_67(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 720) &&
+ (VtMode->Timing.VActive == 400) &&
+ (VtMode->FrameRate == XVIDC_FR_70HZ) &&
+ XVidC_EdidSuppEstTimings720x400_70(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 1024) &&
+ (VtMode->Timing.VActive == 768) &&
+ (VtMode->FrameRate == XVIDC_FR_70HZ) &&
+ XVidC_EdidSuppEstTimings1024x768_70(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 640) &&
+ (VtMode->Timing.VActive == 480) &&
+ (VtMode->FrameRate == XVIDC_FR_72HZ) &&
+ XVidC_EdidSuppEstTimings640x480_72(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 800) &&
+ (VtMode->Timing.VActive == 600) &&
+ (VtMode->FrameRate == XVIDC_FR_72HZ) &&
+ XVidC_EdidSuppEstTimings800x600_72(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 640) &&
+ (VtMode->Timing.VActive == 480) &&
+ (VtMode->FrameRate == XVIDC_FR_75HZ) &&
+ XVidC_EdidSuppEstTimings640x480_75(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 800) &&
+ (VtMode->Timing.VActive == 600) &&
+ (VtMode->FrameRate == XVIDC_FR_75HZ) &&
+ XVidC_EdidSuppEstTimings800x600_75(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 832) &&
+ (VtMode->Timing.VActive == 624) &&
+ (VtMode->FrameRate == XVIDC_FR_75HZ) &&
+ XVidC_EdidSuppEstTimings832x624_75(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 1024) &&
+ (VtMode->Timing.VActive == 768) &&
+ (VtMode->FrameRate == XVIDC_FR_75HZ) &&
+ XVidC_EdidSuppEstTimings1024x768_75(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 1152) &&
+ (VtMode->Timing.VActive == 870) &&
+ (VtMode->FrameRate == XVIDC_FR_75HZ) &&
+ XVidC_EdidSuppEstTimings1152x870_75(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 1280) &&
+ (VtMode->Timing.VActive == 1024) &&
+ (VtMode->FrameRate == XVIDC_FR_75HZ) &&
+ XVidC_EdidSuppEstTimings1280x1024_75(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 1024) &&
+ (VtMode->Timing.VActive == 768) &&
+ (VtMode->FrameRate == XVIDC_FR_87HZ) &&
+ XVidC_EdidSuppEstTimings1024x768_87(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+ else if ((VtMode->Timing.HActive == 720) &&
+ (VtMode->Timing.VActive == 400) &&
+ (VtMode->FrameRate == XVIDC_FR_88HZ) &&
+ XVidC_EdidSuppEstTimings720x400_88(EdidRaw)) {
+ Status = XST_SUCCESS;
+ }
+
+ return Status;
+}
+
+/******************************************************************************/
+/**
+ * Checks whether or not a specified video timing mode is supported in the
+ * standard timings field of the supplied base Extended Display Identification
+ * Data (EDID).
+ *
+ * @param EdidRaw is the supplied base EDID to check the timing against.
+ * @param VtMode is the video timing mode to check for support.
+ *
+ * @return
+ * - XST_SUCCESS if the video timing mode is supported in the
+ * base EDID's standard timings fields.
+ * - XST_FAILURE otherwise.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static u32 XVidC_EdidIsVideoTimingSupportedStandardTimings(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode)
+{
+ u8 Index;
+
+ for (Index = 0; Index < 8; Index++) {
+ if ((VtMode->Timing.HActive ==
+ XVidC_EdidGetStdTimingsH(EdidRaw, Index + 1)) &&
+ (VtMode->Timing.VActive ==
+ XVidC_EdidGetStdTimingsV(EdidRaw, Index + 1)) &&
+ (VtMode->FrameRate == (u8)XVidC_EdidGetStdTimingsFrr(
+ EdidRaw, Index + 1))) {
+ return XST_SUCCESS;
+ }
+ }
+
+ return XST_FAILURE;
+}
+
+/******************************************************************************/
+/**
+ * Perform a power operation.
+ *
+ * @param Base is b in the power operation, b^n.
+ * @param Power is n in the power operation, b^n.
+ *
+ * @return Base^Power (Base to the power of Power).
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static int XVidC_CalculatePower(u8 Base, u8 Power)
+{
+ u8 Index;
+ u32 Res = 1;
+
+ for (Index = 0; Index < Power; Index++) {
+ Res *= Base;
+ }
+
+ return Res;
+}
+
+
+/******************************************************************************/
+/**
+ * Convert a fractional binary number into a fixed point Q0.DecPtIndex number
+ * Binary digits to the right of the decimal point represent 2^-1 to
+ * 2^-(DecPtIndex+1). Binary digits to the left of the decimal point represent
+ * 2^0, 2^1, etc. For a given Q format, using an unsigned integer container with
+ * n fractional bits:
+ * its range is [0, 2^-n]
+ * its resolution is 2^n
+ *
+ * @param Val is the binary representation of the fraction.
+ * @param DecPtIndex is the index of the decimal point in the binary
+ * number. The decimal point is between the binary digits at Val's
+ * indices (DecPtIndex -1) and (DecPtIndex). DecPtIndex will
+ * determine the Q format resolution.
+ *
+ * @return Fixed point representation of the fractional part of the binary
+ * number in Q format.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+static int XVidC_CalculateBinaryFraction_QFormat(u16 Val, u8 DecPtIndex)
+{
+ int Index;
+ u32 Res;
+
+ for (Index = DecPtIndex - 1, Res = 0; Index >= 0; Index--) {
+ if (((Val >> Index) & 0x1) == 1) {
+ Res += XVidC_CalculatePower(2 , Index);
+ }
+ }
+
+ return Res;
+}
+/** @} */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.h
new file mode 100644
index 00000000000000..e18f36623830db
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_edid.h
@@ -0,0 +1,468 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvidc_edid.h
+ * @addtogroup video_common_v4_0
+ * @{
+ *
+ * Contains macros, definitions, and function declarations related to the
+ * Extended Display Identification Data (EDID) structure which is present in all
+ * monitors. All content in this file is agnostic of communication interface
+ * protocol.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 als 11/09/14 Initial release.
+ * 2.2 als 02/01/16 Functions with pointer arguments that don't modify
+ * contents now const.
+ * 4.0 aad 10/26/16 Functions which return fixed point values instead of
+ * float
+ * </pre>
+ *
+*******************************************************************************/
+
+#ifndef XVIDC_EDID_H_
+/* Prevent circular inclusions by using protection macros. */
+#define XVIDC_EDID_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************* Include Files ********************************/
+
+#include "xstatus.h"
+#include "xvidc.h"
+
+/************************** Constant Definitions ******************************/
+
+/** @name Address mapping for the base EDID block.
+ * @{
+ */
+#define XVIDC_EDID_HEADER 0x00
+/* Vendor and product identification. */
+#define XVIDC_EDID_VPI_ID_MAN_NAME0 0x08
+#define XVIDC_EDID_VPI_ID_MAN_NAME1 0x09
+#define XVIDC_EDID_VPI_ID_PROD_CODE_LSB 0x0A
+#define XVIDC_EDID_VPI_ID_PROD_CODE_MSB 0x0B
+#define XVIDC_EDID_VPI_ID_SN0 0x0C
+#define XVIDC_EDID_VPI_ID_SN1 0x0D
+#define XVIDC_EDID_VPI_ID_SN2 0x0E
+#define XVIDC_EDID_VPI_ID_SN3 0x0F
+#define XVIDC_EDID_VPI_WEEK_MAN 0x10
+#define XVIDC_EDID_VPI_YEAR 0x11
+/* EDID structure version and revision. */
+#define XVIDC_EDID_STRUCT_VER 0x12
+#define XVIDC_EDID_STRUCT_REV 0x13
+/* Basic display parameters and features. */
+#define XVIDC_EDID_BDISP_VID 0x14
+#define XVIDC_EDID_BDISP_H_SSAR 0x15
+#define XVIDC_EDID_BDISP_V_SSAR 0x16
+#define XVIDC_EDID_BDISP_GAMMA 0x17
+#define XVIDC_EDID_BDISP_FEATURE 0x18
+/* Color characteristics (display x,y chromaticity coordinates). */
+#define XVIDC_EDID_CC_RG_LOW 0x19
+#define XVIDC_EDID_CC_BW_LOW 0x1A
+#define XVIDC_EDID_CC_REDX_HIGH 0x1B
+#define XVIDC_EDID_CC_REDY_HIGH 0x1C
+#define XVIDC_EDID_CC_GREENX_HIGH 0x1D
+#define XVIDC_EDID_CC_GREENY_HIGH 0x1E
+#define XVIDC_EDID_CC_BLUEX_HIGH 0x1F
+#define XVIDC_EDID_CC_BLUEY_HIGH 0x20
+#define XVIDC_EDID_CC_WHITEX_HIGH 0x21
+#define XVIDC_EDID_CC_WHITEY_HIGH 0x22
+/* Established timings. */
+#define XVIDC_EDID_EST_TIMINGS_I 0x23
+#define XVIDC_EDID_EST_TIMINGS_II 0x24
+#define XVIDC_EDID_EST_TIMINGS_MAN 0x25
+/* Standard timings. */
+#define XVIDC_EDID_STD_TIMINGS_H(N) (0x26 + 2 * (N - 1))
+#define XVIDC_EDID_STD_TIMINGS_AR_FRR(N) (0x27 + 2 * (N - 1))
+/* 18 byte descriptors. */
+#define XVIDC_EDID_18BYTE_DESCRIPTOR(N) (0x36 + 18 * (N - 1))
+#define XVIDC_EDID_PTM (XVIDC_EDID_18BYTE_DESCRIPTOR(1))
+/* - Detailed timing descriptor (DTD) / Preferred timing mode (PTM). */
+#define XVIDC_EDID_DTD_PTM_PIXEL_CLK_KHZ_LSB 0x00
+#define XVIDC_EDID_DTD_PTM_PIXEL_CLK_KHZ_MSB 0x01
+#define XVIDC_EDID_DTD_PTM_HRES_LSB 0x02
+#define XVIDC_EDID_DTD_PTM_HBLANK_LSB 0x03
+#define XVIDC_EDID_DTD_PTM_HRES_HBLANK_U4 0x04
+#define XVIDC_EDID_DTD_PTM_VRES_LSB 0x05
+#define XVIDC_EDID_DTD_PTM_VBLANK_LSB 0x06
+#define XVIDC_EDID_DTD_PTM_VRES_VBLANK_U4 0x07
+#define XVIDC_EDID_DTD_PTM_HFPORCH_LSB 0x08
+#define XVIDC_EDID_DTD_PTM_HSPW_LSB 0x09
+#define XVIDC_EDID_DTD_PTM_VFPORCH_VSPW_L4 0x0A
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2 0x0B
+#define XVIDC_EDID_DTD_PTM_HIMGSIZE_MM_LSB 0x0C
+#define XVIDC_EDID_DTD_PTM_VIMGSIZE_MM_LSB 0x0D
+#define XVIDC_EDID_DTD_PTM_XIMGSIZE_MM_U4 0x0E
+#define XVIDC_EDID_DTD_PTM_HBORDER 0x0F
+#define XVIDC_EDID_DTD_PTM_VBORDER 0x10
+#define XVIDC_EDID_DTD_PTM_SIGNAL 0x11
+
+/* Extension block count. */
+#define XVIDC_EDID_EXT_BLK_COUNT 0x7E
+/* Checksum. */
+#define XVIDC_EDID_CHECKSUM 0x7F
+/* @} */
+
+/******************************************************************************/
+
+/** @name Extended Display Identification Data: Masks, shifts, and values.
+ * @{
+ */
+#define XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR0_SHIFT 2
+#define XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR0_MASK (0x1F << 2)
+#define XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR1_MASK 0x03
+#define XVIDC_EDID_VPI_ID_MAN_NAME0_CHAR1_POS 3
+#define XVIDC_EDID_VPI_ID_MAN_NAME1_CHAR1_SHIFT 5
+#define XVIDC_EDID_VPI_ID_MAN_NAME1_CHAR2_MASK 0x1F
+
+/* Basic display parameters and features: Video input definition. */
+#define XVIDC_EDID_BDISP_VID_VSI_SHIFT 7
+#define XVIDC_EDID_BDISP_VID_VSI_MASK (0x01 << 7)
+#define XVIDC_EDID_BDISP_VID_ANA_SLS_SHIFT 5
+#define XVIDC_EDID_BDISP_VID_ANA_SLS_MASK (0x03 << 5)
+#define XVIDC_EDID_BDISP_VID_ANA_SLS_0700_0300_1000 0x0
+#define XVIDC_EDID_BDISP_VID_ANA_SLS_0714_0286_1000 0x1
+#define XVIDC_EDID_BDISP_VID_ANA_SLS_1000_0400_1400 0x2
+#define XVIDC_EDID_BDISP_VID_ANA_SLS_0700_0000_0700 0x3
+#define XVIDC_EDID_BDISP_VID_ANA_VID_SETUP_MASK (0x01 << 4)
+#define XVIDC_EDID_BDISP_VID_ANA_SEP_SYNC_HV_MASK (0x01 << 3)
+#define XVIDC_EDID_BDISP_VID_ANA_COMP_SYNC_H_MASK (0x01 << 2)
+#define XVIDC_EDID_BDISP_VID_ANA_COMP_SYNC_G_MASK (0x01 << 1)
+#define XVIDC_EDID_BDISP_VID_ANA_SERR_V_SYNC_MASK (0x01)
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_SHIFT 4
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_MASK (0x7 << 4)
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_UNDEF 0x0
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_6 0x1
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_8 0x2
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_10 0x3
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_12 0x4
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_14 0x5
+#define XVIDC_EDID_BDISP_VID_DIG_BPC_16 0x6
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_MASK 0xF
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_UNDEF 0x0
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_DVI 0x1
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_HDMIA 0x2
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_HDMIB 0x3
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_MDDI 0x4
+#define XVIDC_EDID_BDISP_VID_DIG_VIS_DP 0x5
+
+/* Basic display parameters and features: Feature support. */
+#define XVIDC_EDID_BDISP_FEATURE_PM_STANDBY_MASK (0x1 << 7)
+#define XVIDC_EDID_BDISP_FEATURE_PM_SUSPEND_MASK (0x1 << 6)
+#define XVIDC_EDID_BDISP_FEATURE_PM_OFF_VLP_MASK (0x1 << 5)
+#define XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_SHIFT 3
+#define XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_MASK (0x3 << 3)
+#define XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_MCG 0x0
+#define XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_RGB 0x1
+#define XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_NRGB 0x2
+#define XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_UNDEF 0x3
+#define XVIDC_EDID_BDISP_FEATURE_DIG_COLORENC_YCRCB444_MASK (0x1 << 3)
+#define XVIDC_EDID_BDISP_FEATURE_DIG_COLORENC_YCRCB422_MASK (0x1 << 4)
+#define XVIDC_EDID_BDISP_FEATURE_SRGB_DEF_MASK (0x1 << 2)
+#define XVIDC_EDID_BDISP_FEATURE_PTM_INC_MASK (0x1 << 1)
+#define XVIDC_EDID_BDISP_FEATURE_CONTFREQ_MASK (0x1)
+
+/* Color characteristics (display x,y chromaticity coordinates). */
+#define XVIDC_EDID_CC_HIGH_SHIFT 2
+#define XVIDC_EDID_CC_RBX_LOW_SHIFT 6
+#define XVIDC_EDID_CC_RBY_LOW_SHIFT 4
+#define XVIDC_EDID_CC_RBY_LOW_MASK (0x3 << 4)
+#define XVIDC_EDID_CC_GWX_LOW_SHIFT 2
+#define XVIDC_EDID_CC_GWX_LOW_MASK (0x3 << 2)
+#define XVIDC_EDID_CC_GWY_LOW_MASK (0x3)
+#define XVIDC_EDID_CC_GREENY_HIGH 0x1E
+#define XVIDC_EDID_CC_BLUEX_HIGH 0x1F
+#define XVIDC_EDID_CC_BLUEY_HIGH 0x20
+#define XVIDC_EDID_CC_WHITEX_HIGH 0x21
+#define XVIDC_EDID_CC_WHITEY_HIGH 0x22
+
+/* Established timings. */
+#define XVIDC_EDID_EST_TIMINGS_I_720x400_70_MASK (0x1 << 7)
+#define XVIDC_EDID_EST_TIMINGS_I_720x400_88_MASK (0x1 << 6)
+#define XVIDC_EDID_EST_TIMINGS_I_640x480_60_MASK (0x1 << 5)
+#define XVIDC_EDID_EST_TIMINGS_I_640x480_67_MASK (0x1 << 4)
+#define XVIDC_EDID_EST_TIMINGS_I_640x480_72_MASK (0x1 << 3)
+#define XVIDC_EDID_EST_TIMINGS_I_640x480_75_MASK (0x1 << 2)
+#define XVIDC_EDID_EST_TIMINGS_I_800x600_56_MASK (0x1 << 1)
+#define XVIDC_EDID_EST_TIMINGS_I_800x600_60_MASK (0x1)
+#define XVIDC_EDID_EST_TIMINGS_II_800x600_72_MASK (0x1 << 7)
+#define XVIDC_EDID_EST_TIMINGS_II_800x600_75_MASK (0x1 << 6)
+#define XVIDC_EDID_EST_TIMINGS_II_832x624_75_MASK (0x1 << 5)
+#define XVIDC_EDID_EST_TIMINGS_II_1024x768_87_MASK (0x1 << 4)
+#define XVIDC_EDID_EST_TIMINGS_II_1024x768_60_MASK (0x1 << 3)
+#define XVIDC_EDID_EST_TIMINGS_II_1024x768_70_MASK (0x1 << 2)
+#define XVIDC_EDID_EST_TIMINGS_II_1024x768_75_MASK (0x1 << 1)
+#define XVIDC_EDID_EST_TIMINGS_II_1280x1024_75_MASK (0x1)
+#define XVIDC_EDID_EST_TIMINGS_MAN_1152x870_75_MASK (0x1 << 7)
+#define XVIDC_EDID_EST_TIMINGS_MAN_MASK (0x7F)
+
+/* Standard timings. */
+#define XVIDC_EDID_STD_TIMINGS_AR_SHIFT 6
+#define XVIDC_EDID_STD_TIMINGS_AR_16_10 0x0
+#define XVIDC_EDID_STD_TIMINGS_AR_4_3 0x1
+#define XVIDC_EDID_STD_TIMINGS_AR_5_4 0x2
+#define XVIDC_EDID_STD_TIMINGS_AR_16_9 0x3
+#define XVIDC_EDID_STD_TIMINGS_FRR_MASK (0x3F)
+
+/* Detailed timing descriptor (DTD) / Preferred timing mode (PTM). */
+#define XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XBLANK_MASK 0x0F
+#define XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XRES_MASK 0xF0
+#define XVIDC_EDID_DTD_PTM_XRES_XBLANK_U4_XRES_SHIFT 4
+#define XVIDC_EDID_DTD_PTM_VFPORCH_VSPW_L4_VSPW_MASK 0x0F
+#define XVIDC_EDID_DTD_PTM_VFPORCH_VSPW_L4_VFPORCH_MASK 0xF0
+#define XVIDC_EDID_DTD_PTM_VFPORCH_VSPW_L4_VFPORCH_SHIFT 4
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_HFPORCH_MASK 0xC0
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_HSPW_MASK 0x30
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_VFPORCH_MASK 0x0C
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_VSPW_MASK 0x03
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_HFPORCH_SHIFT 6
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_HSPW_SHIFT 4
+#define XVIDC_EDID_DTD_PTM_XFPORCH_XSPW_U2_VFPORCH_SHIFT 2
+#define XVIDC_EDID_DTD_PTM_XIMGSIZE_MM_U4_VIMGSIZE_MM_MASK 0x0F
+#define XVIDC_EDID_DTD_PTM_XIMGSIZE_MM_U4_HIMGSIZE_MM_MASK 0xF0
+#define XVIDC_EDID_DTD_PTM_XIMGSIZE_MM_U4_HIMGSIZE_MM_SHIFT 4
+#define XVIDC_EDID_DTD_PTM_SIGNAL_INTERLACED_MASK 0x80
+#define XVIDC_EDID_DTD_PTM_SIGNAL_INTERLACED_SHIFT 7
+#define XVIDC_EDID_DTD_PTM_SIGNAL_HPOLARITY_MASK 0x02
+#define XVIDC_EDID_DTD_PTM_SIGNAL_VPOLARITY_MASK 0x04
+#define XVIDC_EDID_DTD_PTM_SIGNAL_HPOLARITY_SHIFT 1
+#define XVIDC_EDID_DTD_PTM_SIGNAL_VPOLARITY_SHIFT 2
+/* @} */
+
+/******************* Macros (Inline Functions) Definitions ********************/
+
+#define XVidC_EdidIsHeaderValid(E) \
+ !memcmp(E, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8)
+
+/* Vendor and product identification: ID manufacturer name. */
+/* void XVidC_EdidGetManName(const u8 *EdidRaw, char ManName[4]); */
+
+/* Vendor and product identification: ID product code. */
+#define XVidC_EdidGetIdProdCode(E) \
+ ((u16)((E[XVIDC_EDID_VPI_ID_PROD_CODE_MSB] << 8) | \
+ E[XVIDC_EDID_VPI_ID_PROD_CODE_LSB]))
+
+/* Vendor and product identification: ID serial number. */
+#define XVidC_EdidGetIdSn(E) \
+ ((u32)((E[XVIDC_EDID_VPI_ID_SN3] << 24) | \
+ (E[XVIDC_EDID_VPI_ID_SN2] << 16) | (E[XVIDC_EDID_VPI_ID_SN1] << 8) | \
+ E[XVIDC_EDID_VPI_ID_SN0]))
+
+/* Vendor and product identification: Week and year of manufacture or model
+ * year. */
+#define XVidC_EdidGetManWeek(E) (E[XVIDC_EDID_VPI_WEEK_MAN])
+#define XVidC_EdidGetModManYear(E) (E[XVIDC_EDID_VPI_YEAR] + 1990)
+#define XVidC_EdidIsYearModel(E) (XVidC_EdidGetManWeek(E) == 0xFF)
+#define XVidC_EdidIsYearMan(E) (XVidC_EdidGetManWeek(E) != 0xFF)
+
+/* EDID structure version and revision. */
+#define XVidC_EdidGetStructVer(E) (E[XVIDC_EDID_STRUCT_VER])
+#define XVidC_EdidGetStructRev(E) (E[XVIDC_EDID_STRUCT_REV])
+
+/* Basic display parameters and features: Video input definition. */
+#define XVidC_EdidIsDigitalSig(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & XVIDC_EDID_BDISP_VID_VSI_MASK) != 0)
+#define XVidC_EdidIsAnalogSig(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & XVIDC_EDID_BDISP_VID_VSI_MASK) == 0)
+#define XVidC_EdidGetAnalogSigLvlStd(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & XVIDC_EDID_BDISP_VID_ANA_SLS_MASK) >> \
+ XVIDC_EDID_BDISP_VID_ANA_SLS_SHIFT)
+#define XVidC_EdidGetAnalogSigVidSetup(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & \
+ XVIDC_EDID_BDISP_VID_ANA_VID_SETUP_MASK) != 0)
+#define XVidC_EdidSuppAnalogSigSepSyncHv(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & \
+ XVIDC_EDID_BDISP_VID_ANA_SEP_SYNC_HV_MASK) != 0)
+#define XVidC_EdidSuppAnalogSigCompSyncH(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & \
+ XVIDC_EDID_BDISP_VID_ANA_COMP_SYNC_H_MASK) != 0)
+#define XVidC_EdidSuppAnalogSigCompSyncG(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & \
+ XVIDC_EDID_BDISP_VID_ANA_COMP_SYNC_G_MASK) != 0)
+#define XVidC_EdidSuppAnalogSigSerrVsync(E) \
+ ((E[XVIDC_EDID_BDISP_VID] & \
+ XVIDC_EDID_BDISP_VID_ANA_SERR_V_SYNC_MASK) != 0)
+/* XVidC_ColorDepth XVidC_EdidGetColorDepth(const u8 *EdidRaw); */
+#define XVidC_EdidGetDigitalSigIfaceStd(E) \
+ (E[XVIDC_EDID_BDISP_VID] & XVIDC_EDID_BDISP_VID_DIG_VIS_MASK)
+
+/* Basic display parameters and features: Horizontal and vertical screen size or
+ * aspect ratio. */
+#define XVidC_EdidIsSsArDefined(E) \
+ ((E[XVIDC_EDID_BDISP_H_SSAR] | E[XVIDC_EDID_BDISP_V_SSAR]) != 0)
+#define XVidC_EdidGetSsArH(E) E[XVIDC_EDID_BDISP_H_SSAR]
+#define XVidC_EdidGetSsArV(E) E[XVIDC_EDID_BDISP_V_SSAR]
+#define XVidC_EdidIsSsArSs(E) \
+ ((XVidC_EdidGetSsArH(E) != 0) && (XVidC_EdidGetSsArV(E) != 0))
+#define XVidC_EdidIsSsArArL(E) \
+ ((XVidC_EdidGetSsArH(E) != 0) && (XVidC_EdidGetSsArV(E) == 0))
+#define XVidC_EdidIsSsArArP(E) \
+ ((XVidC_EdidGetSsArH(E) == 0) && (XVidC_EdidGetSsArV(E) != 0))
+#define XVidC_EdidGetSsArArL(E) \
+ ((float)((XVidC_EdidGetSsArH(E) + 99.0) / 100.0))
+#define XVidC_EdidGetSsArArP(E) \
+ ((float)(100.0 / (XVidC_EdidGetSsArV(E) + 99.0)))
+
+/* Basic display parameters and features: Gamma. */
+#define XVidC_EdidIsGammaInExt(E) (E[XVIDC_EDID_BDISP_GAMMA] == 0xFF)
+#define XVidC_EdidGetGamma(E) \
+ ((float)((E[XVIDC_EDID_BDISP_GAMMA] + 100.0) / 100.0))
+
+/* Basic display parameters and features: Feature support. */
+#define XVidC_EdidSuppFeaturePmStandby(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_PM_STANDBY_MASK) != 0)
+#define XVidC_EdidSuppFeaturePmSuspend(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_PM_SUSPEND_MASK) != 0)
+#define XVidC_EdidSuppFeaturePmOffVlp(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_PM_OFF_VLP_MASK) != 0)
+#define XVidC_EdidGetFeatureAnaColorType(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_MASK) >> \
+ XVIDC_EDID_BDISP_FEATURE_ANA_COLORTYPE_SHIFT)
+#define XVidC_EdidSuppFeatureDigColorEncYCrCb444(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_DIG_COLORENC_YCRCB444_MASK) != 0)
+#define XVidC_EdidSuppFeatureDigColorEncYCrCb422(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_DIG_COLORENC_YCRCB422_MASK) != 0)
+#define XVidC_EdidIsFeatureSrgbDef(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_SRGB_DEF_MASK) != 0)
+#define XVidC_EdidIsFeaturePtmInc(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_PTM_INC_MASK) != 0)
+#define XVidC_EdidIsFeatureContFreq(E) \
+ ((E[XVIDC_EDID_BDISP_FEATURE] & \
+ XVIDC_EDID_BDISP_FEATURE_CONTFREQ_MASK) != 0)
+
+/* Established timings. */
+#define XVidC_EdidSuppEstTimings720x400_70(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_720x400_70_MASK) != 0)
+#define XVidC_EdidSuppEstTimings720x400_88(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_720x400_88_MASK) != 0)
+#define XVidC_EdidSuppEstTimings640x480_60(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_640x480_60_MASK) != 0)
+#define XVidC_EdidSuppEstTimings640x480_67(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_640x480_67_MASK) != 0)
+#define XVidC_EdidSuppEstTimings640x480_72(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_640x480_72_MASK) != 0)
+#define XVidC_EdidSuppEstTimings640x480_75(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_640x480_75_MASK) != 0)
+#define XVidC_EdidSuppEstTimings800x600_56(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_800x600_56_MASK) != 0)
+#define XVidC_EdidSuppEstTimings800x600_60(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_I] & \
+ XVIDC_EDID_EST_TIMINGS_I_800x600_60_MASK) != 0)
+#define XVidC_EdidSuppEstTimings800x600_72(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_800x600_72_MASK) != 0)
+#define XVidC_EdidSuppEstTimings800x600_75(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_800x600_75_MASK) != 0)
+#define XVidC_EdidSuppEstTimings832x624_75(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_832x624_75_MASK) != 0)
+#define XVidC_EdidSuppEstTimings1024x768_87(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_1024x768_87_MASK) != 0)
+#define XVidC_EdidSuppEstTimings1024x768_60(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_1024x768_60_MASK) != 0)
+#define XVidC_EdidSuppEstTimings1024x768_70(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_1024x768_70_MASK) != 0)
+#define XVidC_EdidSuppEstTimings1024x768_75(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_1024x768_75_MASK) != 0)
+#define XVidC_EdidSuppEstTimings1280x1024_75(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_II] & \
+ XVIDC_EDID_EST_TIMINGS_II_1280x1024_75_MASK) != 0)
+#define XVidC_EdidSuppEstTimings1152x870_75(E) \
+ ((E[XVIDC_EDID_EST_TIMINGS_MAN] & \
+ XVIDC_EDID_EST_TIMINGS_MAN_1152x870_75_MASK) != 0)
+#define XVidC_EdidGetTimingsMan(E) \
+ (E[XVIDC_EDID_EST_TIMINGS_MAN] & XVIDC_EDID_EST_TIMINGS_MAN_MASK)
+
+/* Standard timings. */
+#define XVidC_EdidGetStdTimingsH(E, N) \
+ ((E[XVIDC_EDID_STD_TIMINGS_H(N)] + 31) * 8)
+#define XVidC_EdidGetStdTimingsAr(E, N) \
+ (E[XVIDC_EDID_STD_TIMINGS_AR_FRR(N)] >> XVIDC_EDID_STD_TIMINGS_AR_SHIFT)
+#define XVidC_EdidGetStdTimingsFrr(E, N) \
+ ((E[XVIDC_EDID_STD_TIMINGS_AR_FRR(N)] & \
+ XVIDC_EDID_STD_TIMINGS_FRR_MASK) + 60)
+/* u16 XVidC_EdidGetStdTimingsV(const u8 *EdidRaw, u8 StdTimingsNum); */
+#define XVidC_EdidIsDtdPtmInterlaced(E) \
+ ((E[XVIDC_EDID_PTM + XVIDC_EDID_DTD_PTM_SIGNAL] & \
+ XVIDC_EDID_DTD_PTM_SIGNAL_INTERLACED_MASK) >> \
+ XVIDC_EDID_DTD_PTM_SIGNAL_INTERLACED_SHIFT)
+
+/* Extension block count. */
+#define XVidC_EdidGetExtBlkCount(E) (E[XVIDC_EDID_EXT_BLK_COUNT])
+
+/* Checksum. */
+#define XVidC_EdidGetChecksum(E) (E[XVIDC_EDID_CHECKSUM])
+
+/**************************** Function Prototypes *****************************/
+
+/* Vendor and product identification: ID manufacturer name. */
+void XVidC_EdidGetManName(const u8 *EdidRaw, char ManName[4]);
+
+/* Basic display parameters and features: Video input definition. */
+XVidC_ColorDepth XVidC_EdidGetColorDepth(const u8 *EdidRaw);
+
+/* Color characteristics (display x,y chromaticity coordinates). */
+int XVidC_EdidGetCcRedX(const u8 *EdidRaw);
+int XVidC_EdidGetCcRedY(const u8 *EdidRaw);
+int XVidC_EdidGetCcGreenX(const u8 *EdidRaw);
+int XVidC_EdidGetCcGreenY(const u8 *EdidRaw);
+int XVidC_EdidGetCcBlueX(const u8 *EdidRaw);
+int XVidC_EdidGetCcBlueY(const u8 *EdidRaw);
+int XVidC_EdidGetCcWhiteX(const u8 *EdidRaw);
+int XVidC_EdidGetCcWhiteY(const u8 *EdidRaw);
+
+/* Standard timings. */
+u16 XVidC_EdidGetStdTimingsV(const u8 *EdidRaw, u8 StdTimingsNum);
+
+/* Utility functions. */
+u32 XVidC_EdidIsVideoTimingSupported(const u8 *EdidRaw,
+ const XVidC_VideoTimingMode *VtMode);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* XVIDC_EDID_H_ */
+/** @} */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_timings_table.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_timings_table.c
new file mode 100644
index 00000000000000..872367a5ab9f93
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvidc_timings_table.c
@@ -0,0 +1,435 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvidc_timings_table.c
+ * @addtogroup video_common_v4_0
+ * @{
+ *
+ * Contains video timings for various standard resolutions.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 als, 01/10/15 Initial release.
+ * rc
+ * 2.0 als 08/14/15 Added new video timings.
+ * 2.1 als 11/04/15 Fixed video timings for some resolutions.
+ * rco 02/09/17 Fix c++ compilation warnings
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include "xvidc.h"
+
+/**************************** Variable Definitions ****************************/
+
+/**
+ * This table contains the main stream attributes for various standard
+ * resolutions. Each entry is of the format:
+ * 1) ID: XVIDC_VM_<HRES>x<VRES>_<FRAME RATE (HZ)>_<P|I>(_RB = Reduced Blanking)
+ * 2) Resolution naming: "<HRES>x<VRES>@<FRAME RATE (HZ)>"
+ * 3) Frame rate: XVIDC_FR_<FRAME RATE (HZ)>
+ * 4) Video timing structure:
+ * 1) Horizontal active resolution (pixels)
+ * 2) Horizontal front porch (pixels)
+ * 3) Horizontal sync width (pixels)
+ * 4) Horizontal back porch (pixels)
+ * 5) Horizontal total (pixels)
+ * 6) Horizontal sync polarity (0=negative|1=positive)
+ * 7) Vertical active resolution (lines)
+ * 8) Frame 0: Vertical front porch (lines)
+ * 9) Frame 0: Vertical sync width (lines)
+ * 10) Frame 0: Vertical back porch (lines)
+ * 11) Frame 0: Vertical total (lines)
+ * 12) Frame 1: Vertical front porch (lines)
+ * 13) Frame 1: Vertical sync width (lines)
+ * 14) Frame 1: Vertical back porch (lines)
+ * 15) Frame 1: Vertical total (lines)
+ * 16) Vertical sync polarity (0=negative|1=positive)
+ */
+#ifdef __cplusplus
+extern "C"
+#endif
+const XVidC_VideoTimingMode XVidC_VideoTimingModes[XVIDC_VM_NUM_SUPPORTED] =
+{
+ /* Interlaced modes. */
+ { XVIDC_VM_720x480_60_I, "720x480@60Hz (I)", XVIDC_FR_60HZ,
+ {720, 19, 62, 57, 858, 0,
+ 240, 4, 3, 15, 262, 5, 3, 15, 263, 0} },
+ { XVIDC_VM_720x576_50_I, "720x576@50Hz (I)", XVIDC_FR_50HZ,
+ {720, 12, 63, 69, 864, 0,
+ 288, 2, 3, 19, 312, 3, 3, 19, 313, 0} },
+ { XVIDC_VM_1440x480_60_I, "1440x480@60Hz (I)", XVIDC_FR_60HZ,
+ {1440, 38, 124, 114, 1716, 0,
+ 240, 4, 3, 15, 262, 5, 3, 15, 263, 0} },
+ { XVIDC_VM_1440x576_50_I, "1440x576@50Hz (I)", XVIDC_FR_50HZ,
+ {1440, 24, 126, 138, 1728, 0,
+ 288, 2, 3, 19, 312, 3, 3, 19, 313, 0} },
+ { XVIDC_VM_1920x1080_50_I, "1920x1080@50Hz (I)", XVIDC_FR_50HZ,
+ {1920, 528, 44, 148, 2640, 1,
+ 540, 2, 5, 15, 562, 3, 5, 15, 563, 1} },
+ { XVIDC_VM_1920x1080_60_I, "1920x1080@60Hz (I)", XVIDC_FR_60HZ,
+ {1920, 88, 44, 148, 2200, 1,
+ 540, 2, 5, 15, 562, 3, 5, 15, 563, 1} },
+
+ /* Progressive modes. */
+ { XVIDC_VM_640x350_85_P, "640x350@85Hz", XVIDC_FR_85HZ,
+ {640, 32, 64, 96, 832, 1,
+ 350, 32, 3, 60, 445, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_640x480_60_P, "640x480@60Hz", XVIDC_FR_60HZ,
+ {640, 8+8, 96, 40+8, 800, 0,
+ 480, 2+8, 2, 25+8, 525, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_640x480_72_P, "640x480@72Hz", XVIDC_FR_72HZ,
+ {640, 8+16, 40, 120+8, 832, 0,
+ 480, 8+1, 3, 20+8, 520, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_640x480_75_P, "640x480@75Hz", XVIDC_FR_75HZ,
+ {640, 16, 64, 120, 840, 0,
+ 480, 1, 3, 16, 500, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_640x480_85_P, "640x480@85Hz", XVIDC_FR_85HZ,
+ {640, 56, 56, 80, 832, 0,
+ 480, 1, 3, 25, 509, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_720x400_85_P, "720x400@85Hz", XVIDC_FR_85HZ,
+ {720, 36, 72, 108, 936, 0,
+ 400, 1, 3, 42, 446, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_720x480_60_P, "720x480@60Hz", XVIDC_FR_60HZ,
+ {720, 16, 62, 60, 858, 0,
+ 480, 9, 6, 30, 525, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_720x576_50_P, "720x576@50Hz", XVIDC_FR_50HZ,
+ {720, 12, 64, 68, 864, 0,
+ 576, 5, 5, 39, 625, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_800x600_56_P, "800x600@56Hz", XVIDC_FR_56HZ,
+ {800, 24, 72, 128, 1024, 1,
+ 600, 1, 2, 22, 625, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_800x600_60_P, "800x600@60Hz", XVIDC_FR_60HZ,
+ {800, 40, 128, 88, 1056, 1,
+ 600, 1, 4, 23, 628, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_800x600_72_P, "800x600@72Hz", XVIDC_FR_72HZ,
+ {800, 56, 120, 64, 1040, 1,
+ 600, 37, 6, 23, 666, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_800x600_75_P, "800x600@75Hz", XVIDC_FR_75HZ,
+ {800, 16, 80, 160, 1056, 1,
+ 600, 1, 3, 21, 625, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_800x600_85_P, "800x600@85Hz", XVIDC_FR_85HZ,
+ {800, 32, 64, 152, 1048, 1,
+ 600, 1, 3, 27, 631, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_800x600_120_P_RB, "800x600@120Hz (RB)", XVIDC_FR_120HZ,
+ {800, 48, 32, 80, 960, 1,
+ 600, 3, 4, 29, 636, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_848x480_60_P, "848x480@60Hz", XVIDC_FR_60HZ,
+ {848, 16, 112, 112, 1088, 1,
+ 480, 6, 8, 23, 517, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1024x768_60_P, "1024x768@60Hz", XVIDC_FR_60HZ,
+ {1024, 24, 136, 160, 1344, 0,
+ 768, 3, 6, 29, 806, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1024x768_70_P, "1024x768@70Hz", XVIDC_FR_70HZ,
+ {1024, 24, 136, 144, 1328, 0,
+ 768, 3, 6, 29, 806, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1024x768_75_P, "1024x768@75Hz", XVIDC_FR_75HZ,
+ {1024, 16, 96, 176, 1312, 1,
+ 768, 1, 3, 28, 800, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1024x768_85_P, "1024x768@85Hz", XVIDC_FR_85HZ,
+ {1024, 48, 96, 208, 1376, 1,
+ 768, 1, 3, 36, 808, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1024x768_120_P_RB, "1024x768@120Hz (RB)", XVIDC_FR_120HZ,
+ {1024, 48, 32, 80, 1184, 1,
+ 768, 3, 4, 38, 813, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1152x864_75_P, "1152x864@75Hz", XVIDC_FR_75HZ,
+ {1152, 64, 128, 256, 1600, 1,
+ 864, 1, 3, 32, 900, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x720_50_P, "1280x720@50Hz", XVIDC_FR_50HZ,
+ {1280, 440, 40, 220, 1980, 1,
+ 720, 5, 5, 20, 750, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x720_60_P, "1280x720@60Hz", XVIDC_FR_60HZ,
+ {1280, 110, 40, 220, 1650, 1,
+ 720, 5, 5, 20, 750, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x768_60_P, "1280x768@60Hz", XVIDC_FR_60HZ,
+ {1280, 64, 128, 192, 1664, 0,
+ 768, 3, 7, 20, 798, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x768_60_P_RB, "1280x768@60Hz (RB)", XVIDC_FR_60HZ,
+ {1280, 48, 32, 80, 1440, 1,
+ 768, 3, 7, 12, 790, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1280x768_75_P, "1280x768@75Hz", XVIDC_FR_75HZ,
+ {1280, 80, 128, 208, 1696, 0,
+ 768, 3, 7, 27, 805, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x768_85_P, "1280x768@85Hz", XVIDC_FR_85HZ,
+ {1280, 80, 136, 216, 1712, 0,
+ 768, 3, 7, 31, 809, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x768_120_P_RB, "1280x768@120Hz (RB)", XVIDC_FR_120HZ,
+ {1280, 48, 32, 80, 1440, 1,
+ 768, 3, 7, 35, 813, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1280x800_60_P, "1280x800@60Hz", XVIDC_FR_60HZ,
+ {1280, 72, 128, 200, 1680, 0,
+ 800, 3, 6, 22, 831, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x800_60_P_RB, "1280x800@60Hz (RB)", XVIDC_FR_60HZ,
+ {1280, 48, 32, 80, 1440, 1,
+ 800, 3, 6, 14, 823, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1280x800_75_P, "1280x800@75Hz", XVIDC_FR_75HZ,
+ {1280, 80, 128, 208, 1696, 0,
+ 800, 3, 6, 29, 838, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x800_85_P, "1280x800@85Hz", XVIDC_FR_85HZ,
+ {1280, 80, 136, 216, 1712, 0,
+ 800, 3, 6, 34, 843, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x800_120_P_RB, "1280x800@120Hz (RB)", XVIDC_FR_120HZ,
+ {1280, 48, 32, 80, 1440, 1,
+ 800, 3, 6, 38, 847, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1280x960_60_P, "1280x960@60Hz", XVIDC_FR_60HZ,
+ {1280, 96, 112, 312, 1800, 1,
+ 960, 1, 3, 36, 1000, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x960_85_P, "1280x960@85Hz", XVIDC_FR_85HZ,
+ {1280, 64, 160, 224, 1728, 1,
+ 960, 1, 3, 47, 1011, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x960_120_P_RB, "1280x960@120Hz (RB)", XVIDC_FR_120HZ,
+ {1280, 48, 32, 80, 1440, 1,
+ 960, 3, 4, 50, 1017, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1280x1024_60_P, "1280x1024@60Hz", XVIDC_FR_60HZ,
+ {1280, 48, 112, 248, 1688, 1,
+ 1024, 1, 3, 38, 1066, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x1024_75_P, "1280x1024@75Hz", XVIDC_FR_75HZ,
+ {1280, 16, 144, 248, 1688, 1,
+ 1024, 1, 3, 38, 1066, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x1024_85_P, "1280x1024@85Hz", XVIDC_FR_85HZ,
+ {1280, 64, 160, 224, 1728, 1,
+ 1024, 1, 3, 44, 1072, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1280x1024_120_P_RB, "1280x1024@120Hz (RB)", XVIDC_FR_120HZ,
+ {1280, 48, 32, 80, 1440, 1,
+ 1024, 3, 7, 50, 1084, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1360x768_60_P, "1360x768@60Hz", XVIDC_FR_60HZ,
+ {1360, 64, 112, 256, 1792, 1,
+ 768, 3, 6, 18, 795, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1360x768_120_P_RB, "1360x768@120Hz (RB)", XVIDC_FR_120HZ,
+ {1360, 48, 32, 80, 1520, 1,
+ 768, 3, 5, 37, 813, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1366x768_60_P, "1366x768@60Hz", XVIDC_FR_60HZ,
+ {1366, 14, 56, 64, 1500, 1,
+ 768, 1, 3, 28, 800, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1400x1050_60_P, "1400x1050@60Hz", XVIDC_FR_60HZ,
+ {1400, 88, 144, 232, 1864, 0,
+ 1050, 3, 4, 32, 1089, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1400x1050_60_P_RB, "1400x1050@60Hz (RB)", XVIDC_FR_60HZ,
+ {1400, 48, 32, 80, 1560, 1,
+ 1050, 3, 4, 23, 1080, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1400x1050_75_P, "1400x1050@75Hz", XVIDC_FR_75HZ,
+ {1400, 104, 144, 248, 1896, 0,
+ 1050, 3, 4, 42, 1099, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1400x1050_85_P, "1400x1050@85Hz", XVIDC_FR_85HZ,
+ {1400, 104, 152, 256, 1912, 0,
+ 1050, 3, 4, 48, 1105, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1400x1050_120_P_RB, "1400x1050@120Hz (RB)", XVIDC_FR_120HZ,
+ {1400, 48, 32, 80, 1560, 1,
+ 1050, 3, 4, 55, 1112, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1440x240_60_P, "1440x240@60Hz", XVIDC_FR_60HZ,
+ {1440, 38, 124, 114, 1716, 0,
+ 240, 14, 3, 4, 262, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1440x900_60_P, "1440x900@60Hz", XVIDC_FR_60HZ,
+ {1440, 80, 152, 232, 1904, 0,
+ 900, 3, 6, 25, 934, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1440x900_60_P_RB, "1440x900@60Hz (RB)", XVIDC_FR_60HZ,
+ {1440, 48, 32, 80, 1600, 1,
+ 900, 3, 6, 17, 926, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1440x900_75_P, "1440x900@75Hz", XVIDC_FR_75HZ,
+ {1440, 96, 152, 248, 1936, 0,
+ 900, 3, 6, 33, 942, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1440x900_85_P, "1440x900@85Hz", XVIDC_FR_85HZ,
+ {1440, 104, 152, 256, 1952, 0,
+ 900, 3, 6, 39, 948, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1440x900_120_P_RB, "1440x900@120Hz (RB)", XVIDC_FR_120HZ,
+ {1440, 48, 32, 80, 1600, 1,
+ 900, 3, 6, 44, 953, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1600x1200_60_P, "1600x1200@60Hz", XVIDC_FR_60HZ,
+ {1600, 64, 192, 304, 2160, 1,
+ 1200, 1, 3, 46, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1600x1200_65_P, "1600x1200@65Hz", XVIDC_FR_65HZ,
+ {1600, 64, 192, 304, 2160, 1,
+ 1200, 1, 3, 46, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1600x1200_70_P, "1600x1200@70Hz", XVIDC_FR_70HZ,
+ {1600, 64, 192, 304, 2160, 1,
+ 1200, 1, 3, 46, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1600x1200_75_P, "1600x1200@75Hz", XVIDC_FR_75HZ,
+ {1600, 64, 192, 304, 2160, 1,
+ 1200, 1, 3, 46, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1600x1200_85_P, "1600x1200@85Hz", XVIDC_FR_85HZ,
+ {1600, 64, 192, 304, 2160, 1,
+ 1200, 1, 3, 46, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1600x1200_120_P_RB, "1600x1200@120Hz (RB)", XVIDC_FR_120HZ,
+ {1600, 48, 32, 80, 1760, 1,
+ 1200, 3, 4, 64, 1271, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1680x720_50_P, "1680x720@50Hz", XVIDC_FR_50HZ,
+ {1680, 260, 40, 220, 2200, 1,
+ 720, 5, 5, 20, 750, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x720_60_P, "1680x720@60Hz", XVIDC_FR_60HZ,
+ {1680, 260, 40, 220, 2200, 1,
+ 720, 5, 5, 20, 750, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x720_100_P, "1680x720@100Hz", XVIDC_FR_100HZ,
+ {1680, 60, 40, 220, 2000, 1,
+ 720, 5, 5, 95, 825, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x720_120_P, "1680x720@120Hz", XVIDC_FR_120HZ,
+ {1680, 60, 40, 220, 2000, 1,
+ 720, 5, 5, 95, 825, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x1050_50_P, "1680x1050@50Hz", XVIDC_FR_50HZ,
+ {1680, 88, 176, 264, 2208, 0,
+ 1050, 3, 6, 24, 1083, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x1050_60_P, "1680x1050@60Hz", XVIDC_FR_60HZ,
+ {1680, 104, 176, 280, 2240, 0,
+ 1050, 3, 6, 30, 1089, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x1050_60_P_RB, "1680x1050@60Hz (RB)", XVIDC_FR_60HZ,
+ {1680, 48, 32, 80, 1840, 1,
+ 1050, 3, 6, 21, 1080, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1680x1050_75_P, "1680x1050@75Hz", XVIDC_FR_75HZ,
+ {1680, 120, 176, 296, 2272, 0,
+ 1050, 3, 6, 40, 1099, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x1050_85_P, "1680x1050@85Hz", XVIDC_FR_85HZ,
+ {1680, 128, 176, 304, 2288, 0,
+ 1050, 3, 6, 46, 1105, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1680x1050_120_P_RB, "1680x1050@120Hz (RB)", XVIDC_FR_120HZ,
+ {1680, 48, 32, 80, 1840, 1,
+ 1050, 3, 6, 53, 1112, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1792x1344_60_P, "1792x1344@60Hz", XVIDC_FR_60HZ,
+ {1792, 128, 200, 328, 2448, 0,
+ 1344, 1, 3, 46, 1394, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1792x1344_75_P, "1792x1344@75Hz", XVIDC_FR_75HZ,
+ {1792, 96, 216, 352, 2456, 0,
+ 1344, 1, 3, 69, 1417, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1792x1344_120_P_RB, "1792x1344@120Hz (RB)", XVIDC_FR_120HZ,
+ {1792, 48, 32, 80, 1952, 1,
+ 1344, 3, 4, 72, 1423, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1856x1392_60_P, "1856x1392@60Hz", XVIDC_FR_60HZ,
+ {1856, 96, 224, 352, 2528, 0,
+ 1392, 1, 3, 43, 1439, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1856x1392_75_P, "1856x1392@75Hz", XVIDC_FR_75HZ,
+ {1856, 128, 224, 352, 2560, 0,
+ 1392, 1, 3, 104, 1500, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1856x1392_120_P_RB, "1856x1392@120Hz (RB)", XVIDC_FR_120HZ,
+ {1856, 48, 32, 80, 2016, 1,
+ 1392, 3, 4, 75, 1474, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1920x1080_24_P, "1920x1080@24Hz", XVIDC_FR_24HZ,
+ {1920, 638, 44, 148, 2750, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1080_25_P, "1920x1080@25Hz", XVIDC_FR_25HZ,
+ {1920, 528, 44, 148, 2640, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1080_30_P, "1920x1080@30Hz", XVIDC_FR_30HZ,
+ {1920, 88, 44, 148, 2200, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1080_50_P, "1920x1080@50Hz", XVIDC_FR_50HZ,
+ {1920, 528, 44, 148, 2640, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1080_60_P, "1920x1080@60Hz", XVIDC_FR_60HZ,
+ {1920, 88, 44, 148, 2200, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1080_100_P, "1920x1080@100Hz", XVIDC_FR_100HZ,
+ {1920, 528, 44, 148, 2640, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1080_120_P, "1920x1080@120Hz", XVIDC_FR_120HZ,
+ {1920, 88, 44, 148, 2200, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1200_60_P, "1920x1200@60Hz", XVIDC_FR_60HZ,
+ {1920, 136, 200, 336, 2592, 0,
+ 1200, 3, 6, 36, 1245, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1200_60_P_RB, "1920x1200@60Hz (RB)", XVIDC_FR_60HZ,
+ {1920, 48, 32, 80, 2080, 1,
+ 1200, 3, 6, 26, 1235, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1920x1200_75_P, "1920x1200@75Hz", XVIDC_FR_75HZ,
+ {1920, 136, 208, 344, 2608, 0,
+ 1200, 3, 6, 46, 1255, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1200_85_P, "1920x1200@85Hz", XVIDC_FR_85HZ,
+ {1920, 144, 208, 352, 2624, 0,
+ 1200, 3, 6, 53, 1262, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1200_120_P_RB, "1920x1200@120Hz (RB)", XVIDC_FR_120HZ,
+ {1920, 48, 32, 80, 2080, 1,
+ 1200, 3, 6, 62, 1271, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1920x1440_60_P, "1920x1440@60Hz", XVIDC_FR_60HZ,
+ {1920, 128, 208, 344, 2600, 0,
+ 1440, 1, 3, 56, 1500, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1440_75_P, "1920x1440@75Hz", XVIDC_FR_75HZ,
+ {1920, 144, 224, 352, 2640, 0,
+ 1440, 1, 3, 56, 1500, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_1920x1440_120_P_RB, "1920x1440@120Hz (RB)", XVIDC_FR_120HZ,
+ {1920, 48, 32, 80, 2080, 1,
+ 1440, 3, 4, 78, 1525, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_1920x2160_60_P, "1920x2160@60Hz", XVIDC_FR_60HZ,
+ {1920, 88, 44, 148, 2200, 1,
+ 2160, 20, 10, 60, 2250, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_2560x1080_50_P, "2560x1080@50Hz", XVIDC_FR_50HZ,
+ {2560, 548, 44, 148, 3300, 1,
+ 1080, 4, 5, 36, 1125, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1080_60_P, "2560x1080@60Hz", XVIDC_FR_60HZ,
+ {2560, 248, 44, 148, 3000, 1,
+ 1080, 4, 5, 11, 1100, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1080_100_P, "2560x1080@100Hz", XVIDC_FR_100HZ,
+ {2560, 218, 44, 148, 2970, 1,
+ 1080, 4, 5, 161, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1080_120_P, "2560x1080@120Hz", XVIDC_FR_120HZ,
+ {2560, 548, 44, 148, 3300, 1,
+ 1080, 4, 5, 161, 1250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1600_60_P, "2560x1600@60Hz", XVIDC_FR_60HZ,
+ {2560, 192, 280, 472, 3504, 0,
+ 1600, 3, 6, 49, 1658, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1600_60_P_RB, "2560x1600@60Hz (RB)", XVIDC_FR_60HZ,
+ {2560, 48, 32, 80, 2720, 1,
+ 1600, 3, 6, 37, 1646, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_2560x1600_75_P, "2560x1600@75Hz", XVIDC_FR_75HZ,
+ {2560, 208, 280, 488, 3536, 0,
+ 1600, 3, 6, 63, 1672, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1600_85_P, "2560x1600@85Hz", XVIDC_FR_85HZ,
+ {2560, 208, 280, 488, 3536, 0,
+ 1600, 3, 6, 73, 1682, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_2560x1600_120_P_RB, "2560x1600@120Hz (RB)", XVIDC_FR_120HZ,
+ {2560, 48, 32, 80, 2720, 1,
+ 1600, 3, 6, 85, 1694, 0, 0, 0, 0, 0} },
+ { XVIDC_VM_3840x2160_24_P, "3840x2160@24Hz", XVIDC_FR_24HZ,
+ {3840, 1276, 88, 296, 5500, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_3840x2160_25_P, "3840x2160@25Hz", XVIDC_FR_25HZ,
+ {3840, 1056, 88, 296, 5280, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_3840x2160_30_P, "3840x2160@30Hz", XVIDC_FR_30HZ,
+ {3840, 176, 88, 296, 4400, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_3840x2160_50_P, "3840x2160@50Hz", XVIDC_FR_50HZ,
+ {3840, 1056, 88, 296, 5280, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_3840x2160_60_P, "3840x2160@60Hz", XVIDC_FR_60HZ,
+ {3840, 176, 88, 296, 4400, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_4096x2160_24_P, "4096x2160@24Hz", XVIDC_FR_24HZ,
+ {4096, 1020, 88, 296, 5500, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_4096x2160_25_P, "4096x2160@25Hz", XVIDC_FR_25HZ,
+ {4096, 968, 88, 128, 5280, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_4096x2160_30_P, "4096x2160@30Hz", XVIDC_FR_30HZ,
+ {4096, 88, 88, 128, 4400, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_4096x2160_50_P, "4096x2160@50Hz", XVIDC_FR_50HZ,
+ {4096, 968, 88, 128, 5280, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_4096x2160_60_P, "4096x2160@60Hz", XVIDC_FR_60HZ,
+ {4096, 88, 88, 128, 4400, 1,
+ 2160, 8, 10, 72, 2250, 0, 0, 0, 0, 1} },
+ { XVIDC_VM_4096x2160_60_P_RB, "4096x2160@60Hz (RB)", XVIDC_FR_60HZ,
+ {4096, 8, 32, 40, 4176, 1,
+ 2160, 48, 8, 6, 2222, 0, 0, 0, 0, 0} },
+};
+
+/** @} */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.c
new file mode 100644
index 00000000000000..2048f3eb4eb0bf
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.c
@@ -0,0 +1,1342 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * gm
+ * 1.1 gm 02/01/16 Added GTPE2 and GTHE4 support
+ * Added more events to XVphy_LogEvent definitions.
+ * Added TxBufferBypass in XVphy_Config structure.
+ * Added XVphy_SetDefaultPpc and XVphy_SetPpc functions.
+ * als Added XVphy_GetLineRateHz function.
+ * gm 20/04/16 Added XVphy_GetRcfgChId function
+ * 1.2 gm Added HdmiFastSwitch in XVphy_Config
+ * Fixed bug in XVphy_IsPllLocked function
+ * Changed EffectiveAddr datatype in XVphy_CfgInitialize
+ * to UINTPTR
+ * Used usleep API instead of MB_Sleep API
+ * Fixed Null pointer dereference in XVphy_IBufDsEnable
+ * Suppressed warning messages due to unused arguments
+ * 1.4 gm 29/11/16 Moved internally used APIs to xvphy_i.c/h
+ * Added preprocessor directives for sw footprint reduction
+ * Fixed c++ compiler warnings
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include <linux/string.h>
+#include "xstatus.h"
+#include "xvphy.h"
+#include "xvphy_i.h"
+#include "xvphy_hdmi.h"
+#include <linux/delay.h>
+#include "xvphy_gt.h"
+
+/**************************** Function Prototypes *****************************/
+static u32 XVphy_MmcmWriteParameters(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir);
+static u32 XVphy_DrpAccess(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u16 Addr, u16 *Val);
+
+/**************************** Function Definitions ****************************/
+
+/******************************************************************************/
+/**
+ * This function retrieves the configuration for this Video PHY instance and
+ * fills in the InstancePtr->Config structure.
+ *
+ * @param InstancePtr is a pointer to the XVphy instance.
+ * @param ConfigPtr is a pointer to the configuration structure that will
+ * be used to copy the settings from.
+ * @param EffectiveAddr is the device base address in the virtual memory
+ * space. If the address translation is not used, then the physical
+ * address is passed.
+ *
+ * @return None.
+ *
+ * @note Unexpected errors may occur if the address mapping is changed
+ * after this function is invoked.
+ *
+*******************************************************************************/
+void XVphy_CfgInitialize(XVphy *InstancePtr, XVphy_Config *ConfigPtr,
+ UINTPTR EffectiveAddr)
+{
+ u8 Sel;
+
+ /* Verify arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(ConfigPtr != NULL);
+ Xil_AssertVoid(EffectiveAddr != 0x0);
+
+ (void)memset((void *)InstancePtr, 0, sizeof(XVphy));
+ InstancePtr->IsReady = 0;
+
+ InstancePtr->Config = *ConfigPtr;
+ InstancePtr->Config.BaseAddr = EffectiveAddr;
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+ InstancePtr->GtAdaptor = &Gtxe2Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE2)
+ InstancePtr->GtAdaptor = &Gthe2Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTPE2)
+ InstancePtr->GtAdaptor = &Gtpe2Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE3)
+ InstancePtr->GtAdaptor = &Gthe3Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE4)
+ InstancePtr->GtAdaptor = &Gthe4Config;
+#endif
+
+ const XVphy_SysClkDataSelType SysClkCfg[7][2] = {
+ {(XVphy_SysClkDataSelType)0, XVPHY_SYSCLKSELDATA_TYPE_CPLL_OUTCLK},
+ {(XVphy_SysClkDataSelType)1, XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK},
+ {(XVphy_SysClkDataSelType)2, XVPHY_SYSCLKSELDATA_TYPE_QPLL1_OUTCLK},
+ {(XVphy_SysClkDataSelType)3, XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK},
+ {(XVphy_SysClkDataSelType)4, XVPHY_SYSCLKSELDATA_TYPE_PLL0_OUTCLK},
+ {(XVphy_SysClkDataSelType)5, XVPHY_SYSCLKSELDATA_TYPE_PLL1_OUTCLK},
+ {(XVphy_SysClkDataSelType)6, XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK},
+ };
+ for (Sel = 0; Sel < 7; Sel++) {
+ if (InstancePtr->Config.TxSysPllClkSel == SysClkCfg[Sel][0]) {
+ InstancePtr->Config.TxSysPllClkSel = SysClkCfg[Sel][1];
+ }
+ if (InstancePtr->Config.RxSysPllClkSel == SysClkCfg[Sel][0]) {
+ InstancePtr->Config.RxSysPllClkSel = SysClkCfg[Sel][1];
+ }
+ }
+
+ InstancePtr->Config.TxRefClkSel = (XVphy_PllRefClkSelType)
+ (InstancePtr->Config.TxRefClkSel +
+ XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0);
+ InstancePtr->Config.RxRefClkSel = (XVphy_PllRefClkSelType)
+ (InstancePtr->Config.RxRefClkSel +
+ XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0);
+ InstancePtr->Config.DruRefClkSel = (XVphy_PllRefClkSelType)
+ (InstancePtr->Config.DruRefClkSel +
+ XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0);
+
+ /* Correct RefClkSel offsets for GTPE2 EAST and WEST RefClks */
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ if (InstancePtr->Config.TxRefClkSel > 6) {
+ InstancePtr->Config.TxRefClkSel = (XVphy_PllRefClkSelType)
+ (InstancePtr->Config.TxRefClkSel - 4);
+ }
+ if (InstancePtr->Config.RxRefClkSel > 6) {
+ InstancePtr->Config.RxRefClkSel = (XVphy_PllRefClkSelType)
+ (InstancePtr->Config.RxRefClkSel - 4);
+ }
+ if (InstancePtr->Config.DruRefClkSel > 6) {
+ InstancePtr->Config.DruRefClkSel = (XVphy_PllRefClkSelType)
+ (InstancePtr->Config.DruRefClkSel - 4);
+ }
+ }
+
+ InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
+}
+
+/*****************************************************************************/
+/**
+* This function will initialize the PLL selection 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 QpllRefClkSel is the QPLL reference clock selection for the
+* quad.
+* - In GTP, this is used to hold PLL0 refclk selection.
+* @param CpllRefClkSel is the CPLL reference clock selection for the
+* quad.
+* - In GTP, this is used to hold PLL1 refclk selection.
+* @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.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_PllInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_PllRefClkSelType QpllRefClkSel,
+ XVphy_PllRefClkSelType CpllRefClkSel,
+ XVphy_PllType TxPllSelect, XVphy_PllType RxPllSelect)
+{
+ /* Suppress Warning Messages */
+ ChId = ChId;
+
+ /* Set configuration in software. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ XVphy_CfgPllRefClkSel(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA, QpllRefClkSel);
+ XVphy_CfgPllRefClkSel(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CHA, CpllRefClkSel);
+ }
+ /* GTP. */
+ else {
+ XVphy_CfgPllRefClkSel(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMN0, QpllRefClkSel);
+ XVphy_CfgPllRefClkSel(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMN1, CpllRefClkSel);
+ }
+ XVphy_CfgSysClkDataSel(InstancePtr, QuadId, XVPHY_DIR_TX,
+ Pll2SysClkData(TxPllSelect));
+ XVphy_CfgSysClkDataSel(InstancePtr, QuadId, XVPHY_DIR_RX,
+ Pll2SysClkData(RxPllSelect));
+ XVphy_CfgSysClkOutSel(InstancePtr, QuadId, XVPHY_DIR_TX,
+ Pll2SysClkOut(TxPllSelect));
+ XVphy_CfgSysClkOutSel(InstancePtr, QuadId, XVPHY_DIR_RX,
+ Pll2SysClkOut(RxPllSelect));
+
+ /* Write configuration to hardware at once. */
+ XVphy_WriteCfgRefClkSelReg(InstancePtr, QuadId);
+
+ return XST_SUCCESS;
+}
+
+/******************************************************************************/
+/*
+* This function installs a custom delay/sleep function to be used by the XVphy
+* driver.
+*
+* @param InstancePtr is a pointer to the XVphy instance.
+* @param CallbackFunc is the address to the callback function.
+* @param CallbackRef is the user data item (microseconds to delay) that
+* will be passed to the custom sleep/delay function when it is
+* invoked.
+*
+* @return None.
+*
+* @note None.
+*
+*******************************************************************************/
+void XVphy_SetUserTimerHandler(XVphy *InstancePtr,
+ XVphy_TimerHandler CallbackFunc, void *CallbackRef)
+{
+ /* Verify arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(CallbackFunc != NULL);
+ Xil_AssertVoid(CallbackRef != NULL);
+
+ InstancePtr->UserTimerWaitUs = CallbackFunc;
+ InstancePtr->UserTimerPtr = CallbackRef;
+}
+
+/******************************************************************************/
+/**
+* This function is the delay/sleep function for the XVphy driver. For the Zynq
+* family, there exists native sleep functionality. For MicroBlaze however,
+* there does not exist such functionality. In the MicroBlaze case, the default
+* method for delaying is to use a predetermined amount of loop iterations. This
+* method is prone to inaccuracy and dependent on system configuration; for
+* greater accuracy, the user may supply their own delay/sleep handler, pointed
+* to by InstancePtr->UserTimerWaitUs, which may have better accuracy if a
+* hardware timer is used.
+*
+* @param InstancePtr is a pointer to the XVphy instance.
+* @param MicroSeconds is the number of microseconds to delay/sleep for.
+*
+* @return None.
+*
+* @note None.
+*
+*******************************************************************************/
+void XVphy_WaitUs(XVphy *InstancePtr, u32 MicroSeconds)
+{
+ /* Verify arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ if (MicroSeconds == 0) {
+ return;
+ }
+
+ if (InstancePtr->UserTimerWaitUs != NULL) {
+ /* Use the timer handler specified by the user for better
+ * accuracy. */
+ InstancePtr->UserTimerWaitUs(InstancePtr, MicroSeconds);
+ }
+ else {
+ /* Wait the requested amount of time. */
+ usleep_range(MicroSeconds, MicroSeconds + MicroSeconds/10);
+ }
+}
+
+#if defined (XPAR_XDP_0_DEVICE_ID)
+/*****************************************************************************/
+/**
+* This function will initialize the clocking 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 TX or RX.
+*
+* @return
+* - XST_SUCCESS if the configuration was successful.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_ClkInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir)
+{
+ u32 Status;
+
+ Status = XVphy_ClkCalcParams(InstancePtr, QuadId, ChId, Dir, 0);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+
+ Status = XVphy_ClkReconfig(InstancePtr, QuadId, ChId);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+
+ Status = XVphy_OutDivReconfig(InstancePtr, QuadId, ChId, Dir);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+
+ Status = XVphy_DirReconfig(InstancePtr, QuadId, ChId, Dir);
+
+ return Status;
+}
+#endif
+
+/*****************************************************************************/
+/**
+* This function will obtian the IP version.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+*
+* @return The IP version of the Video PHY core.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_GetVersion(XVphy *InstancePtr)
+{
+ return XVphy_ReadReg(InstancePtr->Config.BaseAddr, XVPHY_VERSION_REG);
+}
+
+/*****************************************************************************/
+/**
+* Configure the channel's line rate. This is a software only configuration and
+* this value is used in the PLL calculator.
+*
+* @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 LineRate is the line rate to configure software.
+*
+* @return
+* - XST_SUCCESS if the reference clock type is valid.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_CfgLineRate(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u64 LineRateHz)
+{
+ u8 Id;
+ u8 Id0;
+ u8 Id1;
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].LineRateHz =
+ LineRateHz;
+ }
+
+ return XST_SUCCESS;
+}
+
+#if defined (XPAR_XDP_0_DEVICE_ID)
+/*****************************************************************************/
+/**
+* Configure the quad's reference clock frequency. This is a software only
+* configuration and this value is used in the PLL calculator.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param RefClkType is the reference clock type to operate on.
+* @param FreqHz is the reference clock frequency to configure software.
+*
+* @return
+* - XST_SUCCESS if the reference clock type is valid.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_CfgQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
+ XVphy_PllRefClkSelType RefClkType, u32 FreqHz)
+{
+ u8 RefClkIndex = RefClkType - XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0;
+
+ if (RefClkType > XVPHY_PLL_REFCLKSEL_TYPE_GTGREFCLK) {
+ return XST_FAILURE;
+ }
+ InstancePtr->Quads[QuadId].RefClkHz[RefClkIndex] = FreqHz;
+
+ return XST_SUCCESS;
+}
+#endif
+
+/*****************************************************************************/
+/**
+* Obtain the channel's PLL reference clock selection.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param ChId is the channel ID which to operate on.
+*
+* @return The PLL type being used by the channel.
+*
+* @note None.
+*
+******************************************************************************/
+XVphy_PllType XVphy_GetPllType(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_ChannelId ChId)
+{
+ XVphy_SysClkDataSelType SysClkDataSel;
+ XVphy_SysClkOutSelType SysClkOutSel;
+ XVphy_PllType PllType;
+
+ SysClkDataSel = XVphy_GetSysClkDataSel(InstancePtr, QuadId, Dir, ChId);
+ SysClkOutSel = XVphy_GetSysClkOutSel(InstancePtr, QuadId, Dir, ChId);
+
+ /* The sysclk data and output reference clocks should match. */
+
+ if ((SysClkDataSel == XVPHY_SYSCLKSELDATA_TYPE_CPLL_OUTCLK) &&
+ (SysClkOutSel == XVPHY_SYSCLKSELOUT_TYPE_CPLL_REFCLK)) {
+ PllType = XVPHY_PLL_TYPE_CPLL;
+ }
+ else if ((SysClkDataSel == XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK) &&
+ (SysClkOutSel == XVPHY_SYSCLKSELOUT_TYPE_QPLL_REFCLK)) {
+ PllType = XVPHY_PLL_TYPE_QPLL;
+ }
+ else if ((SysClkDataSel == XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK) &&
+ (SysClkOutSel == XVPHY_SYSCLKSELOUT_TYPE_QPLL0_REFCLK)) {
+ PllType = XVPHY_PLL_TYPE_QPLL0;
+ }
+ else if ((SysClkDataSel == XVPHY_SYSCLKSELDATA_TYPE_QPLL1_OUTCLK) &&
+ (SysClkOutSel == XVPHY_SYSCLKSELOUT_TYPE_QPLL1_REFCLK)) {
+ PllType = XVPHY_PLL_TYPE_QPLL1;
+ }
+ else {
+ PllType = XVPHY_PLL_TYPE_UNKNOWN;
+ }
+ /* For GTHE2, GTHE3, GTHE4, and GTXE2. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ return PllType;
+ }
+
+ if ((SysClkDataSel == XVPHY_SYSCLKSELDATA_TYPE_PLL0_OUTCLK) &&
+ (SysClkOutSel == XVPHY_SYSCLKSELOUT_TYPE_PLL0_REFCLK)) {
+ PllType = XVPHY_PLL_TYPE_PLL0;
+ }
+ else if ((SysClkDataSel == XVPHY_SYSCLKSELDATA_TYPE_PLL1_OUTCLK) &&
+ (SysClkOutSel == XVPHY_SYSCLKSELOUT_TYPE_PLL1_REFCLK)) {
+ PllType = XVPHY_PLL_TYPE_PLL1;
+ }
+ else {
+ PllType = XVPHY_PLL_TYPE_UNKNOWN;
+ }
+ /* For GTPE2. */
+ return PllType;
+}
+
+/*****************************************************************************/
+/**
+* This function will return the line rate in Hz for a given channel / quad.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to check.
+* @param ChId is the channel ID for which to retrieve the line rate.
+*
+* @return The line rate in Hz.
+*
+* @note None.
+*
+******************************************************************************/
+u64 XVphy_GetLineRateHz(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid((XVPHY_CHANNEL_ID_CH1 <= ChId) &&
+ (ChId <= XVPHY_CHANNEL_ID_CMN1));
+
+ return InstancePtr->Quads[QuadId].Plls[ChId -
+ XVPHY_CHANNEL_ID_CH1].LineRateHz;
+}
+
+#if defined (XPAR_XDP_0_DEVICE_ID)
+/*****************************************************************************/
+/**
+* This function will wait for a PMA reset done on the specified channel(s) or
+* time out.
+*
+* @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 which to operate on.
+* @param Dir is an indicator for TX or RX.
+*
+* @return
+* - XST_SUCCESS if the PMA reset has finalized.
+* - XST_FAILURE otherwise; waiting for the reset done timed out.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_WaitForPmaResetDone(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+ u8 Retry = 0;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_TX_INIT_STATUS_REG;
+ }
+ else {
+ RegOffset = XVPHY_RX_INIT_STATUS_REG;
+ }
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_TXRX_INIT_STATUS_PMARESETDONE_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_TXRX_INIT_STATUS_PMARESETDONE_MASK(ChId);
+ }
+ do {
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ if (!(RegVal & MaskVal)){
+ XVphy_WaitUs(InstancePtr, 1000);
+ Retry++;
+ }
+ } while ((!(RegVal & MaskVal)) && (Retry < 15));
+
+ if (Retry == 15){
+ return XST_FAILURE;
+ }
+ else {
+ return XST_SUCCESS;
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function will wait for a reset done on the specified channel(s) or time
+* out.
+*
+* @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 which to operate on.
+* @param Dir is an indicator for TX or RX.
+*
+* @return
+* - XST_SUCCESS if the reset has finalized.
+* - XST_FAILURE otherwise; waiting for the reset done timed out.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_WaitForResetDone(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+ u8 Retry = 0;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_TX_INIT_STATUS_REG;
+ }
+ else {
+ RegOffset = XVPHY_RX_INIT_STATUS_REG;
+ }
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_TXRX_INIT_STATUS_RESETDONE_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_TXRX_INIT_STATUS_RESETDONE_MASK(ChId);
+ }
+ do {
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ if (!(RegVal & MaskVal)){
+ XVphy_WaitUs(InstancePtr, 1000);
+ Retry++;
+ }
+ } while ((!(RegVal & MaskVal)) && (Retry < 15));
+
+ if (Retry == 15){
+ return XST_FAILURE;
+ }
+ else {
+ return XST_SUCCESS;
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function will wait for a PLL lock on the specified channel(s) or time
+* out.
+*
+* @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 which to operate on.
+*
+* @return
+* - XST_SUCCESS if the PLL(s) have locked.
+* - XST_FAILURE otherwise; waiting for the lock timed out.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_WaitForPllLock(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ u32 Status = XST_FAILURE;
+ u8 Retry = 0;
+
+ do {
+ XVphy_WaitUs(InstancePtr, 1000);
+ Status = XVphy_IsPllLocked(InstancePtr, QuadId, ChId);
+ Retry++;
+ } while ((Status != XST_SUCCESS) && (Retry < 15));
+
+ return Status;
+}
+#endif
+
+/*****************************************************************************/
+/**
+* This function will reset the GT's PLL logic.
+*
+* @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 which to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param Hold is an indicator whether to "hold" the reset if set to 1.
+* If set to 0: reset, then enable.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_ResetGtPll(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Hold)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_TX_INIT_REG;
+ }
+ else {
+ RegOffset = XVPHY_RX_INIT_REG;
+ }
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_TXRX_INIT_PLLGTRESET_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_TXRX_INIT_PLLGTRESET_MASK(ChId);
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ /* Assert reset. */
+ RegVal |= MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+
+ if (!Hold) {
+ /* De-assert reset. */
+ RegVal &= ~MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function will reset the GT's TX/RX logic.
+*
+* @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 which to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param Hold is an indicator whether to "hold" the reset if set to 1.
+* If set to 0: reset, then enable.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_ResetGtTxRx(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Hold)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_TX_INIT_REG;
+ }
+ else {
+ RegOffset = XVPHY_RX_INIT_REG;
+ }
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_TXRX_INIT_GTRESET_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_TXRX_INIT_GTRESET_MASK(ChId);
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ /* Assert reset. */
+ RegVal |= MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+
+ if (!Hold) {
+ /* De-assert reset. */
+ RegVal &= ~MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function will initiate a write DRP transaction. It is a wrapper around
+* XVphy_DrpAccess.
+*
+* @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 on which to direct the DRP access.
+* @param Dir is an indicator for write (TX) or read (RX).
+* @param Addr is the DRP address to issue the DRP access to.
+* @param Val is the value to write to the DRP address.
+*
+* @return
+* - XST_SUCCESS if the DRP access was successful.
+* - XST_FAILURE otherwise, if the busy bit did not go low, or if
+* the ready bit did not go high.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_DrpWrite(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u16 Addr, u16 Val)
+{
+ return XVphy_DrpAccess(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_TX, /* Write. */
+ Addr, &Val);
+}
+
+/*****************************************************************************/
+/**
+* This function will initiate a read DRP transaction. It is a wrapper around
+* XVphy_DrpAccess.
+*
+* @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 on which to direct the DRP access.
+* @param Dir is an indicator for write (TX) or read (RX).
+* @param Addr is the DRP address to issue the DRP access to.
+*
+* @return
+* - XST_SUCCESS if the DRP access was successful.
+* - XST_FAILURE otherwise, if the busy bit did not go low, or if
+* the ready bit did not go high.
+*
+* @note None.
+*
+******************************************************************************/
+u16 XVphy_DrpRead(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId, u16 Addr)
+{
+ u32 Status;
+ u16 Val;
+
+ Status = XVphy_DrpAccess(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_RX, /* Read. */
+ Addr, &Val);
+
+ return (Status == XST_SUCCESS) ? Val : 0;
+}
+
+/*****************************************************************************/
+/**
+* This function will power down the mixed-mode clock manager (MMCM) core.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param Hold is an indicator whether to "hold" the power down if set
+* to 1. If set to 0: power down, then power back up.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_MmcmPowerDown(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Hold)
+{
+ u32 RegOffsetCtrl;
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffsetCtrl = XVPHY_MMCM_TXUSRCLK_CTRL_REG;
+ }
+ else {
+ RegOffsetCtrl = XVPHY_MMCM_RXUSRCLK_CTRL_REG;
+ }
+
+ /* Power down. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl);
+ RegVal |= XVPHY_MMCM_USRCLK_CTRL_PWRDWN_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl, RegVal);
+
+ if (!Hold) {
+ /* Power up. */
+ RegVal &= ~XVPHY_MMCM_USRCLK_CTRL_PWRDWN_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl,
+ RegVal);
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function will start the mixed-mode clock manager (MMCM) core.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_MmcmStart(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir)
+{
+#if defined (XPAR_XDP_0_DEVICE_ID)
+ u32 Status;
+ u8 Retry;
+
+ /* Enable MMCM. */
+ XVphy_MmcmPowerDown(InstancePtr, QuadId, Dir, FALSE);
+
+ XVphy_WaitUs(InstancePtr, 10000);
+
+ /* Toggle MMCM reset. */
+ XVphy_MmcmReset(InstancePtr, QuadId, Dir, FALSE);
+
+ XVphy_WaitUs(InstancePtr, 10000);
+
+ /* Configure MMCM. */
+ Retry = 0;
+ do {
+ XVphy_WaitUs(InstancePtr, 10000);
+ Status = XVphy_MmcmWriteParameters(InstancePtr, QuadId, Dir);
+ Retry++;
+ } while ((Status != XST_SUCCESS) && (Retry < 3));
+
+ XVphy_WaitUs(InstancePtr, 10000);
+
+ /* Toggle MMCM reset. */
+ XVphy_MmcmReset(InstancePtr, QuadId, Dir, FALSE);
+#else
+ /* Toggle MMCM reset. */
+ XVphy_MmcmReset(InstancePtr, QuadId, Dir, FALSE);
+
+ /* Configure MMCM. */
+ XVphy_MmcmWriteParameters(InstancePtr, QuadId, Dir);
+
+ /* Unmask the MMCM Lock */
+ XVphy_MmcmLockedMaskEnable(InstancePtr, 0, Dir, FALSE);
+#endif
+
+ XVphy_LogWrite(InstancePtr, (Dir == XVPHY_DIR_TX) ?
+ XVPHY_LOG_EVT_TXPLL_RECONFIG : XVPHY_LOG_EVT_RXPLL_RECONFIG, 1);
+}
+
+/*****************************************************************************/
+/**
+* This function enables the TX or RX IBUFDS peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Dir is an indicator for TX or RX.
+* @param Enable specifies TRUE/FALSE value to either enable or disable
+* the IBUFDS, respectively.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_IBufDsEnable(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Enable)
+{
+ XVphy_PllRefClkSelType *TypePtr, *DruTypePtr, DruTypeDummy;
+ u32 RegAddr = XVPHY_IBUFDS_GTXX_CTRL_REG;
+ u32 RegVal;
+ u32 MaskVal = 0;
+ DruTypeDummy = XVPHY_PLL_REFCLKSEL_TYPE_GTGREFCLK;
+ DruTypePtr = &DruTypeDummy;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ TypePtr = &InstancePtr->Config.TxRefClkSel;
+ }
+ else {
+ TypePtr = &InstancePtr->Config.RxRefClkSel;
+ if (InstancePtr->Config.DruIsPresent) {
+ DruTypePtr = &InstancePtr->Config.DruRefClkSel;
+ }
+ }
+
+ if ((*TypePtr == XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0) ||
+ ((InstancePtr->Config.DruIsPresent) &&
+ (*DruTypePtr == XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0))) {
+ MaskVal = XVPHY_IBUFDS_GTXX_CTRL_GTREFCLK0_CEB_MASK;
+ }
+ else if ((*TypePtr == XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK1) ||
+ ((InstancePtr->Config.DruIsPresent) &&
+ (*DruTypePtr == XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK1))) {
+ MaskVal = XVPHY_IBUFDS_GTXX_CTRL_GTREFCLK1_CEB_MASK;
+ }
+ else {
+ if (Dir == XVPHY_DIR_TX) {
+ RegAddr = XVPHY_MISC_TXUSRCLK_REG;
+ }
+ else {
+ RegAddr = XVPHY_MISC_RXUSRCLK_REG;
+ }
+ MaskVal = XVPHY_MISC_XXUSRCLK_REFCLK_CEB_MASK;
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegAddr);
+
+ if (Enable) {
+ RegVal &= ~MaskVal;
+ }
+ else {
+ RegVal |= MaskVal;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegAddr, RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function enables the TX or RX CLKOUT1 OBUFTDS peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Dir is an indicator for TX or RX.
+* @param Enable specifies TRUE/FALSE value to either enable or disable
+* the OBUFTDS, respectively.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_Clkout1OBufTdsEnable(XVphy *InstancePtr, XVphy_DirectionType Dir,
+ u8 Enable)
+{
+ u32 RegVal;
+ u32 RegOffset;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_MISC_TXUSRCLK_REG;
+ }
+ else {
+ RegOffset = XVPHY_MISC_RXUSRCLK_REG;
+ }
+
+ /* Read XXUSRCLK MISC register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+
+ /* Write new value to XXUSRCLK MISC register. */
+ if (Enable) {
+ RegVal |= XVPHY_MISC_XXUSRCLK_CKOUT1_OEN_MASK;
+ }
+ else {
+ RegVal &= ~XVPHY_MISC_XXUSRCLK_CKOUT1_OEN_MASK;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+}
+
+#if defined (XPAR_XDP_0_DEVICE_ID)
+/*****************************************************************************/
+/**
+* This function resets the BUFG_GT peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Dir is an indicator for TX or RX
+* @param Reset specifies TRUE/FALSE value to either assert or deassert
+* reset on the BUFG_GT, respectively.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_BufgGtReset(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Reset)
+{
+ u32 RegVal;
+ u32 RegOffset;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_BUFGGT_TXUSRCLK_REG;
+ }
+ else {
+ RegOffset = XVPHY_BUFGGT_RXUSRCLK_REG;
+ }
+
+ /* Read BUFG_GT register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+
+ /* Write new value to BUFG_GT register. */
+ if (Reset) {
+ RegVal |= XVPHY_BUFGGT_XXUSRCLK_CLR_MASK;
+ }
+ else {
+ RegVal &= ~XVPHY_BUFGGT_XXUSRCLK_CLR_MASK;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function will set 8b10b encoding for the specified GT PLL.
+*
+* @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 TX or RX.
+* @param Enable is an indicator to enable/disable 8b10b encoding.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_Set8b10b(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Enable)
+{
+ u32 RegOffset;
+ u32 MaskVal;
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_TX_CONTROL_REG;
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_TX_CONTROL_TX8B10BEN_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_TX_CONTROL_TX8B10BEN_MASK(ChId);
+ }
+ }
+ else {
+ RegOffset = XVPHY_RX_CONTROL_REG;
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_RX_CONTROL_RX8B10BEN_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_RX_CONTROL_RX8B10BEN_MASK(ChId);
+ }
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ if (Enable) {
+ RegVal |= MaskVal;
+ }
+ else {
+ RegVal &= ~MaskVal;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+}
+#endif
+
+/*****************************************************************************/
+/**
+* This function returns true when the RX and TX are bonded and are running
+* from the same (RX) reference clock.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+*
+* @return TRUE if the RX and TX are using the same PLL, FALSE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_IsBonded(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ XVphy_SysClkDataSelType RxSysClkDataSel;
+ XVphy_SysClkOutSelType RxSysClkOutSel;
+ XVphy_SysClkDataSelType TxSysClkDataSel;
+ XVphy_SysClkOutSelType TxSysClkOutSel;
+
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ ChId = XVPHY_CHANNEL_ID_CH1;
+ }
+
+ RxSysClkDataSel = XVphy_GetSysClkDataSel(InstancePtr, QuadId,
+ XVPHY_DIR_RX, ChId);
+ RxSysClkOutSel = XVphy_GetSysClkOutSel(InstancePtr, QuadId,
+ XVPHY_DIR_RX, ChId);
+ TxSysClkDataSel = XVphy_GetSysClkDataSel(InstancePtr, QuadId,
+ XVPHY_DIR_TX, ChId);
+ TxSysClkOutSel = XVphy_GetSysClkOutSel(InstancePtr, QuadId,
+ XVPHY_DIR_TX, ChId);
+
+ if ((RxSysClkDataSel == TxSysClkDataSel) &&
+ (RxSysClkOutSel == TxSysClkOutSel)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/**
+* This function will write the mixed-mode clock manager (MMCM) values currently
+* stored in the driver's instance structure to hardware .
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+*
+* @return
+* - XST_SUCCESS if the MMCM write was successful.
+* - XST_FAILURE otherwise, if the configuration success bit did
+* not go low.
+*
+* @note None.
+*
+******************************************************************************/
+static u32 XVphy_MmcmWriteParameters(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir)
+{
+ u32 RegOffsetCtrl;
+ u32 RegOffsetClk;
+ u32 RegVal;
+ XVphy_Mmcm *MmcmParams;
+#if defined (XPAR_XDP_0_DEVICE_ID)
+ u8 Retry;
+#endif
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffsetCtrl = XVPHY_MMCM_TXUSRCLK_CTRL_REG;
+ RegOffsetClk = XVPHY_MMCM_TXUSRCLK_REG1;
+ }
+ else {
+ RegOffsetCtrl = XVPHY_MMCM_RXUSRCLK_CTRL_REG;
+ RegOffsetClk = XVPHY_MMCM_RXUSRCLK_REG1;
+ }
+ MmcmParams = &InstancePtr->Quads[QuadId].Mmcm[Dir];
+
+ /* Check Parameters if has been Initialized */
+ if (!MmcmParams->DivClkDivide && !MmcmParams->ClkFbOutMult &&
+ !MmcmParams->ClkFbOutFrac && !MmcmParams->ClkOut0Frac &&
+ !MmcmParams->ClkOut0Div && !MmcmParams->ClkOut1Div &&
+ !MmcmParams->ClkOut2Div) {
+ return XST_FAILURE;
+ }
+
+ /* MMCM_[TX|RX]USRCLK_REG1 */
+ RegVal = MmcmParams->DivClkDivide;
+ RegVal |= (MmcmParams->ClkFbOutMult <<
+ XVPHY_MMCM_USRCLK_REG1_CLKFBOUT_MULT_SHIFT);
+ RegVal |= (MmcmParams->ClkFbOutFrac <<
+ XVPHY_MMCM_USRCLK_REG1_CLKFBOUT_FRAC_SHIFT);
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetClk, RegVal);
+
+ /* MMCM_[TX|RX]USRCLK_REG2 */
+ RegOffsetClk += 4;
+ RegVal = MmcmParams->ClkOut0Div;
+ RegVal |= (MmcmParams->ClkOut0Frac <<
+ XVPHY_MMCM_USRCLK_REG2_CLKOUT0_FRAC_SHIFT);
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetClk, RegVal);
+
+ /* MMCM_[TX|RX]USRCLK_REG3 */
+ RegOffsetClk += 4;
+ RegVal = MmcmParams->ClkOut1Div;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetClk, RegVal);
+
+ /* MMCM_[TX|RX]USRCLK_REG4 */
+ RegOffsetClk += 4;
+ RegVal = MmcmParams->ClkOut2Div;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetClk, RegVal);
+
+ /* Update the MMCM. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl);
+ RegVal |= XVPHY_MMCM_USRCLK_CTRL_CFG_NEW_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl, RegVal);
+
+#if defined (XPAR_XDP_0_DEVICE_ID)
+ /* Wait until the MMCM indicates configuration has succeeded. */
+ Retry = 0;
+ do {
+ XVphy_WaitUs(InstancePtr, 1000);
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ RegOffsetCtrl);
+ if (Retry > 15) {
+ return XST_FAILURE;
+ }
+ Retry++;
+ } while (!(RegVal & XVPHY_MMCM_USRCLK_CTRL_CFG_SUCCESS_MASK));
+#endif
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function will initiate a DRP transaction (either read or write).
+*
+* @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 on which to direct the DRP access.
+* @param Dir is an indicator for write (TX) or read (RX).
+* @param Addr is the DRP address to issue the DRP access to.
+* @param Val is a pointer to the data value. In write mode, this pointer
+* will hold the value to write. In read mode, this pointer will
+* be populated with the read value.
+*
+* @return
+* - XST_SUCCESS if the DRP access was successful.
+* - XST_FAILURE otherwise, if the busy bit did not go low, or if
+* the ready bit did not go high.
+*
+* @note In read mode (Dir == XVPHY_DIR_RX), the data pointed to by Val
+* will be populated with the u16 value that was read._
+*
+******************************************************************************/
+static u32 XVphy_DrpAccess(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u16 Addr, u16 *Val)
+{
+ u32 RegOffsetCtrl;
+ u32 RegOffsetSts;
+ u32 RegVal;
+ u8 Retry;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ /* Determine which DRP registers to use based on channel. */
+ if (XVPHY_ISCMN(ChId)) {
+ RegOffsetCtrl = XVPHY_DRP_CONTROL_COMMON_REG;
+ RegOffsetSts = XVPHY_DRP_STATUS_COMMON_REG;
+ }
+ else {
+ RegOffsetCtrl = XVPHY_DRP_CONTROL_CH1_REG +
+ (4 * XVPHY_CH2IDX(ChId));
+ RegOffsetSts = XVPHY_DRP_STATUS_CH1_REG +
+ (4 * (XVPHY_CH2IDX(ChId)));
+ }
+
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) &&
+ ((InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_DP) ||
+ (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_DP))) {
+ ChId = XVPHY_CHANNEL_ID_CHA;
+ XVphy_WaitUs(InstancePtr, 3000);
+ }
+
+ /* Wait until the DRP status indicates that it is not busy.*/
+ Retry = 0;
+ do {
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ RegOffsetSts);
+ if (Retry > 150) {
+ return XST_FAILURE;
+ }
+ Retry++;
+ } while (RegVal & XVPHY_DRP_STATUS_DRPBUSY_MASK);
+
+ /* Write the command to the channel's DRP. */
+ RegVal = (Addr & XVPHY_DRP_CONTROL_DRPADDR_MASK);
+ RegVal |= XVPHY_DRP_CONTROL_DRPEN_MASK;
+ if (Dir == XVPHY_DIR_TX) {
+ /* Enable write. */
+ RegVal |= XVPHY_DRP_CONTROL_DRPWE_MASK;
+ RegVal |= ((*Val << XVPHY_DRP_CONTROL_DRPDI_SHIFT) &
+ XVPHY_DRP_CONTROL_DRPDI_MASK);
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl, RegVal);
+
+ /* Wait until the DRP status indicates ready.*/
+ Retry = 0;
+ do {
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ RegOffsetSts);
+ if (Retry > 150) {
+ return XST_FAILURE;
+ }
+ Retry++;
+ } while (!(RegVal & XVPHY_DRP_STATUS_DRPRDY_MASK));
+
+ if (Dir == XVPHY_DIR_RX) {
+ /* Mask non-data out for read. */
+ RegVal &= XVPHY_DRP_STATUS_DRPO_MASK;
+ /* Populate Val with read contents. */
+ *Val = RegVal;
+ }
+ return XST_SUCCESS;
+}
+
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.h
new file mode 100644
index 00000000000000..ac3647b0771ea3
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy.h
@@ -0,0 +1,846 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added EAST, WEST, PLL0 and PLL1 definitions
+ * for GTPE2.
+ * Added more events to XVphy_LogEvent definitions
+ * Added TxBufferBypass in XVphy_Config structure
+ * Added XVphy_SetDefaultPpc and XVphy_SetPpc functions
+ * als Added XVphy_GetLineRateHz function.
+ * 1.2 gm Added HdmiFastSwitch in XVphy_Config
+ * Changed EffectiveAddr datatype in XVphy_CfgInitialize
+ * to UINTPTR
+ * Added log events for debugging
+ * 1.2 gm 11/11/19 Added TransceiverWidth in XVphy_Config
+ * 1.4 gm 29/11/16 Moved internally used APIs to xvphy_i.c/h
+ * Added preprocessor directives for sw footprint reduction
+ * Made debug log optional (can be disabled via makefile)
+ * Added ERR_IRQ type_defs (not for official use for
+ * Xilinx debugging)
+ * Added transceiver width, AXIlite clk frequency and
+ * err_irq in XVphy_Config
+ * </pre>
+ *
+*******************************************************************************/
+
+#ifndef XVPHY_H_
+/* Prevent circular inclusions by using protection macros. */
+#define XVPHY_H_
+
+#if !defined(XV_CONFIG_LOG_VPHY_DISABLE) && !defined(XV_CONFIG_LOG_DISABLE_ALL)
+#define XV_VPHY_LOG_ENABLE
+#endif
+
+/******************************* Include Files ********************************/
+
+#include "xil_assert.h"
+#include "xvphy_hw.h"
+#include "xil_printf.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_GTEASTREFCLK0 =
+ XVPHY_REF_CLK_SEL_XPLL_GTEASTREFCLK0,
+ XVPHY_PLL_REFCLKSEL_TYPE_GTEASTREFCLK1 =
+ XVPHY_REF_CLK_SEL_XPLL_GTEASTREFCLK1,
+ XVPHY_PLL_REFCLKSEL_TYPE_GTWESTREFCLK0 =
+ XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK0,
+ XVPHY_PLL_REFCLKSEL_TYPE_GTWESTREFCLK1 =
+ XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK1,
+ 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_PLL0_OUTCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_PLL0,
+ XVPHY_SYSCLKSELDATA_TYPE_PLL1_OUTCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_PLL1,
+ 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_SYSCLKSELOUT_TYPE_PLL0_REFCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CH,
+ XVPHY_SYSCLKSELOUT_TYPE_PLL1_REFCLK =
+ XVPHY_REF_CLK_SEL_XXSYSCLKSEL_OUT_CMN,
+} 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;
+
+#ifdef XV_VPHY_LOG_ENABLE
+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_ALIGN_TMOUT, /**< Log event TX align Timeout. */
+ 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_GT_TX_RECONFIG, /**< Log event GT reconfig. */
+ XVPHY_LOG_EVT_GT_RX_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_LOG_EVT_DRU_EN, /**< Log event DRU enable/disable. */
+ XVPHY_LOG_EVT_GT_PLL_LAYOUT,/**< Log event GT PLL Layout Change. */
+ XVPHY_LOG_EVT_GT_UNBONDED, /**< Log event GT Unbonded Change. */
+ XVPHY_LOG_EVT_1PPC_ERR, /**< Log event 1 PPC Error. */
+ XVPHY_LOG_EVT_PPC_MSMTCH_ERR,/**< Log event PPC MismatchError. */
+ XVPHY_LOG_EVT_VDCLK_HIGH_ERR,/**< Log event VidClk more than 148.5 MHz. */
+ XVPHY_LOG_EVT_NO_DRU, /**< Log event Vid not supported no DRU. */
+ XVPHY_LOG_EVT_GT_QPLL_CFG_ERR,/**< Log event QPLL Config not found. */
+ XVPHY_LOG_EVT_GT_CPLL_CFG_ERR,/**< Log event QPLL Config not found. */
+ XVPHY_LOG_EVT_VD_NOT_SPRTD_ERR,/**< Log event Vid format not supported. */
+ XVPHY_LOG_EVT_MMCM_ERR, /**< Log event MMCM Config not found. */
+ XVPHY_LOG_EVT_DUMMY, /**< Dummy Event should be last */
+} XVphy_LogEvent;
+#endif
+
+/* This typedef enumerates the possible error conditions. */
+typedef enum {
+ XVPHY_ERRIRQ_QPLL_CFG = 0x1, /**< QPLL CFG not found. */
+ XVPHY_ERRIRQ_CPLL_CFG = 0x2, /**< CPLL CFG not found. */
+ XVPHY_ERRIRQ_NO_DRU = 0x4, /**< No DRU in design. */
+ XVPHY_ERRIRQ_VD_NOT_SPRTD= 0x8, /**< Video Not Supported. */
+ XVPHY_ERRIRQ_MMCM_CFG = 0x10,/**< MMCM CFG not found. */
+ XVPHY_ERRIRQ_PLL_LAYOUT = 0x20,/**< PLL Error. */
+} XVphy_ErrIrqType;
+
+/******************************************************************************/
+/**
+ * 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. */
+ u8 TxDataWidth; /**< In bits. */
+ u8 TxIntDataWidth; /**< 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;
+
+#ifdef XV_VPHY_LOG_ENABLE
+/**
+ * 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;
+#endif
+
+/**
+ * This typedef contains configuration information for the Video PHY core.
+ */
+typedef struct {
+ u16 DeviceId; /**< Device instance ID. */
+ UINTPTR 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. */
+ XVidC_PixelsPerClock Ppc; /**< Number of input pixels per
+ clock. */
+ u8 TxBufferBypass; /**< TX Buffer Bypass is enabled in the
+ design. */
+ u8 HdmiFastSwitch; /**< HDMI fast switching is enabled in the
+ design. */
+ u8 TransceiverWidth; /**< Transceiver Width seeting in the design */
+ u32 ErrIrq; /**< Error IRQ is enalbed in design */
+ u32 AxiLiteClkFreq; /**< AXI Lite Clock Frequency in Hz */
+} 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;
+#ifdef XV_VPHY_LOG_ENABLE
+ XVphy_Log Log; /**< A log of events. */
+#endif
+ 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,
+ UINTPTR EffectiveAddr);
+u32 XVphy_PllInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_PllRefClkSelType QpllRefClkSel,
+ XVphy_PllRefClkSelType CpllxRefClkSel,
+ XVphy_PllType TxPllSelect, XVphy_PllType RxPllSelect);
+#if defined (XPAR_XDP_0_DEVICE_ID)
+u32 XVphy_ClkInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir);
+#endif
+u32 XVphy_GetVersion(XVphy *InstancePtr);
+void XVphy_WaitUs(XVphy *InstancePtr, u32 MicroSeconds);
+void XVphy_SetUserTimerHandler(XVphy *InstancePtr,
+ XVphy_TimerHandler CallbackFunc, void *CallbackRef);
+
+/* xvphy.c: Channel configuration functions - setters. */
+u32 XVphy_CfgLineRate(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u64 LineRateHz);
+#if defined (XPAR_XDP_0_DEVICE_ID)
+u32 XVphy_CfgQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
+ XVphy_PllRefClkSelType RefClkType, u32 FreqHz);
+#endif
+
+/* xvphy.c: Channel configuration functions - getters. */
+XVphy_PllType XVphy_GetPllType(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_ChannelId ChId);
+u64 XVphy_GetLineRateHz(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+
+/* xvphy.c: Reset functions. */
+#if defined (XPAR_XDP_0_DEVICE_ID)
+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);
+#endif
+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);
+
+/* 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_MmcmPowerDown(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Hold);
+void XVphy_MmcmStart(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir);
+void XVphy_IBufDsEnable(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Enable);
+void XVphy_Clkout1OBufTdsEnable(XVphy *InstancePtr, XVphy_DirectionType Dir,
+ u8 Enable);
+#if defined (XPAR_XDP_0_DEVICE_ID)
+void XVphy_BufgGtReset(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Reset);
+
+/* xvphy.c Miscellaneous control. */
+void XVphy_Set8b10b(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Enable);
+#endif
+u32 XVphy_IsBonded(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+
+/* xvphy_log.c: Logging functions. */
+void XVphy_LogDisplay(XVphy *InstancePtr);
+void XVphy_LogReset(XVphy *InstancePtr);
+u16 XVphy_LogRead(XVphy *InstancePtr);
+#ifdef XV_VPHY_LOG_ENABLE
+void XVphy_LogWrite(XVphy *InstancePtr, XVphy_LogEvent Evt, u8 Data);
+#else
+#define XVphy_LogWrite(...)
+#endif
+
+/* xvphy_intr.c: Interrupt handling functions. */
+void XVphy_InterruptHandler(XVphy *InstancePtr);
+
+/* 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)) || \
+ (XVPHY_PLL_TYPE_PLL0 == \
+ XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId)) || \
+ (XVPHY_PLL_TYPE_PLL1 == \
+ 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)) || \
+ (XVPHY_PLL_TYPE_PLL0 == \
+ XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId)) || \
+ (XVPHY_PLL_TYPE_PLL1 == \
+ 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))
+
+#define XVPHY_GTXE2 1
+#define XVPHY_GTHE2 2
+#define XVPHY_GTPE2 3
+#define XVPHY_GTHE3 4
+#define XVPHY_GTHE4 5
+
+#endif /* XVPHY_H_ */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gt.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gt.h
new file mode 100644
index 00000000000000..5c18a8ee76c117
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gt.h
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added Gtpe2Config and Gtpe4Config variables.
+ * 1.4 gm 29/11/16 Added preprocessor directives for sw footprint reduction
+ * Changed TX reconfig hook from TxPllRefClkDiv1Reconfig to
+ * TxChReconfig
+ * Fixed c++ compiler warnings
+ * Added xcvr adaptor functions for C++ compilations
+ * </pre>
+ *
+*******************************************************************************/
+
+#ifndef XVPHY_GT_H_
+/* Prevent circular inclusions by using protection macros. */
+#define XVPHY_GT_H_
+
+/******************************* Include Files ********************************/
+
+#include "xvphy.h"
+#include "xvphy_i.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 (*TxChReconfig)(XVphy *, u8, XVphy_ChannelId);
+
+ XVphy_GtPllDivs CpllDivs;
+ XVphy_GtPllDivs QpllDivs;
+} XVphy_GtConfig;
+
+/******************* Macros (Inline Functions) Definitions ********************/
+#ifdef __cplusplus
+u32 XVphy_CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+u32 XVphy_CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, u64 PllClkOutFreqHz);
+u32 XVphy_OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir);
+u32 XVphy_ClkChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+u32 XVphy_ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+u32 XVphy_RxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+u32 XVphy_TxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+#else
+#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_TxChReconfig(Ip, ...) \
+ ((Ip)->GtAdaptor->TxChReconfig(Ip, __VA_ARGS__))
+#endif
+
+/*************************** Variable Declarations ****************************/
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+extern const XVphy_GtConfig Gtxe2Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE2)
+extern const XVphy_GtConfig Gthe2Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTPE2)
+extern const XVphy_GtConfig Gtpe2Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE3)
+extern const XVphy_GtConfig Gthe3Config;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE4)
+extern const XVphy_GtConfig Gthe4Config;
+#endif
+
+#endif /* XVPHY_GT_H_ */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gthe4.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gthe4.c
new file mode 100644
index 00000000000000..ac18b77cde9660
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_gthe4.c
@@ -0,0 +1,1277 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvphy_gthe4.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.
+ * 1.1 gm 03/18/16 Added XVphy_Gthe4RxPllRefClkDiv1Reconfig function
+ * Added XVphy_Gthe4TxChReconfig function
+ * Corrected RXCDRCFG2 values
+ * 1.2 gm 08/26/16 Suppressed warning messages due to unused arguments
+ * 1.4 gm 29/11/16 Added preprocessor directives for sw footprint reduction
+ * Changed TX reconfig hook from TxPllRefClkDiv1Reconfig to
+ * TxChReconfig
+ * Added TX datawidth dynamic reconfiguration
+ * Added N2=8 divider for CPLL for DP
+ * Added CPLL_CFGx reconfiguration in
+ * XVphy_Gthe4ClkChReconfig API
+ * Corrected the default return value of DRP encoding
+ * APIs to prevent overwritting the reserved bits
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include "xvphy_gt.h"
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE4)
+#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_DrpEncodeDataWidth(u8 AttrEncode);
+static u8 Xvphy_DrpEncodeIntDataWidth(u8 AttrEncode);
+static u16 XVphy_DrpEncodeClk25(u32 RefClkFreqHz);
+
+u32 XVphy_Gthe4CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+u32 XVphy_Gthe4CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, u64 PllClkOutFreqHz);
+u32 XVphy_Gthe4OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir);
+u32 XVphy_Gthe4ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId);
+u32 XVphy_Gthe4ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId CmnId);
+u32 XVphy_Gthe4RxChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId);
+u32 XVphy_Gthe4TxChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId);
+u32 XVphy_Gthe4TxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId);
+u32 XVphy_Gthe4RxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId);
+
+/************************** Constant Definitions ******************************/
+
+/* DRP register space. */
+#define XVPHY_DRP_RXCDR_CFG(n) (0x0E + n)
+#define XVPHY_DRP_RXCDR_CFG_GEN3(n) (0xA2 + n)
+#define XVPHY_DRP_RXCDR_CFG_GEN4(n) (0x119 + n)
+
+#define XVPHY_DRP_CPLL_FBDIV 0x28
+#define XVPHY_DRP_CPLL_REFCLK_DIV 0x2A
+#define XVPHY_DRP_RXOUT_DIV 0x63
+#define XVPHY_DRP_RXCLK25 0x6D
+#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 Gthe4CpllDivsM[] = {1, 2, 0};
+const u8 Gthe4CpllDivsN1[] = {4, 5, 0};
+#if (XPAR_VPHY_0_TX_PROTOCOL == 0 || XPAR_VPHY_0_RX_PROTOCOL == 0)
+const u8 Gthe4CpllDivsN2[] = {1, 2, 3, 4, 5, 8, 0};
+#else
+const u8 Gthe4CpllDivsN2[] = {1, 2, 3, 4, 5, 0};
+#endif
+const u8 Gthe4CpllDivsD[] = {1, 2, 4, 8, 0};
+
+const u8 Gthe4QpllDivsM[] = {4, 3, 2, 1, 0};
+const u8 Gthe4QpllDivsN1[] = {16, 20, 32, 40, 60, 64, 66, 75, 80, 84, 90,
+ 96, 100, 112, 120, 125, 150, 160, 0};
+const u8 Gthe4QpllDivsN2[] = {1, 0};
+const u8 Gthe4QpllDivsD[] = {16, 8, 4, 2, 1, 0};
+
+const XVphy_GtConfig Gthe4Config = {
+ .CfgSetCdr = XVphy_Gthe4CfgSetCdr,
+ .CheckPllOpRange = XVphy_Gthe4CheckPllOpRange,
+ .OutDivChReconfig = XVphy_Gthe4OutDivChReconfig,
+ .ClkChReconfig = XVphy_Gthe4ClkChReconfig,
+ .ClkCmnReconfig = XVphy_Gthe4ClkCmnReconfig,
+ .RxChReconfig = XVphy_Gthe4RxChReconfig,
+ .TxChReconfig = XVphy_Gthe4TxChReconfig,
+
+ .CpllDivs = {
+ .M = Gthe4CpllDivsM,
+ .N1 = Gthe4CpllDivsN1,
+ .N2 = Gthe4CpllDivsN2,
+ .D = Gthe4CpllDivsD,
+ },
+ .QpllDivs = {
+ .M = Gthe4QpllDivsM,
+ .N1 = Gthe4QpllDivsN1,
+ .N2 = Gthe4QpllDivsN2,
+ .D = Gthe4QpllDivsD,
+ },
+};
+
+/**************************** 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_Gthe4CfgSetCdr(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 (PllClkInFreqHz == 270000000) {
+ ChPtr->PllParams.Cdr[2] = 0x01B4;
+ }
+ else if (PllClkInFreqHz == 135000000) {
+ ChPtr->PllParams.Cdr[2] = 0x01C4;
+ }
+ /* RBR does not use DP159 forwarded clock and expects 162MHz. */
+ else {
+ ChPtr->PllParams.Cdr[2] = 0x01A3;
+ }
+ }
+ else if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
+ /* RxOutDiv = 1 => Cdr[2] = 0x0269
+ * RxOutDiv = 2 => Cdr[2] = 0x0259
+ * RxOutDiv = 4 => Cdr[2] = 0x0249
+ * RxOutDiv = 8 => Cdr[2] = 0x0239
+ * RxOutDiv = 16 => Cdr[2] = 0x0229 */
+ ChPtr->PllParams.Cdr[2] = 0x0269;
+ while (ChPtr->RxOutDiv >>= 1) {
+ ChPtr->PllParams.Cdr[2] -= 0x10;
+ }
+ /* Restore RxOutDiv. */
+ ChPtr->RxOutDiv = 1 << ((0x0269 - 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_Gthe4CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, u64 PllClkOutFreqHz)
+{
+ u32 Status = XST_FAILURE;
+
+ /* Suppress Warning Messages */
+ InstancePtr = InstancePtr;
+ QuadId = QuadId;
+
+ 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_Gthe4OutDivChReconfig(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) & 0x7);
+ 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) & 0x7);
+ 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_Gthe4ClkChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId)
+{
+ u16 DrpVal;
+ u16 WriteVal;
+ u32 CpllxVcoRateMHz;
+
+ /* 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) & 0xFF);
+ DrpVal |= (WriteVal << 8);
+ /* Set CPLL_FBDIV_45. */
+ WriteVal = (XVphy_NToDrpEncoding(InstancePtr, QuadId, ChId, 1) & 0x1);
+ 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) & 0x1F);
+ DrpVal |= (WriteVal << 11);
+ /* Write new DRP register value for PLL dividers. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x2A, DrpVal);
+
+ CpllxVcoRateMHz = XVphy_GetPllVcoFreqHz(InstancePtr, QuadId, ChId,
+ XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId) ?
+ XVPHY_DIR_TX : XVPHY_DIR_RX) / 1000000;
+
+ /* CPLL_CFG0 */
+ if (CpllxVcoRateMHz <= 3000) {
+ DrpVal = 0x01FA;
+ }
+ else if (CpllxVcoRateMHz <= 4250) {
+ DrpVal = 0x0FFA;
+ }
+ else {
+ DrpVal = 0x03FE;
+ }
+ /* Write new DRP register value for CPLL_CFG0. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0xCB, DrpVal);
+
+ /* CPLL_CFG1 */
+ if (CpllxVcoRateMHz <= 3000) {
+ DrpVal = 0x0023;
+ }
+ else {
+ DrpVal = 0x0021;
+ }
+ /* Write new DRP register value for CPLL_CFG1. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0xCC, DrpVal);
+
+ /* CPLL_CFG2 */
+ if (CpllxVcoRateMHz <= 3000) {
+ DrpVal = 0x0002;
+ }
+ else if (CpllxVcoRateMHz <= 4250) {
+ DrpVal = 0x0202;
+ }
+ else {
+ DrpVal = 0x0203;
+ }
+ /* Write new DRP register value for CPLL_CFG2. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0xBC, 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_Gthe4ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId CmnId)
+{
+ u16 DrpVal;
+ u16 WriteVal;
+ u32 QpllxVcoRateMHz;
+ u32 QpllxClkOutMHz;
+
+ /* 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) & 0xFF);
+ 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) & 0x1F);
+ 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.TxProtocol == XVPHY_PROTOCOL_HDMI) ||
+ (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI)) {
+
+ QpllxVcoRateMHz = XVphy_GetPllVcoFreqHz(InstancePtr, QuadId, CmnId,
+ XVphy_IsTxUsingQpll(InstancePtr, QuadId, CmnId) ?
+ XVPHY_DIR_TX : XVPHY_DIR_RX) / 1000000;
+ QpllxClkOutMHz = QpllxVcoRateMHz / 2;
+
+ /* PPFx_CFG */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x0D : 0x8D);
+ DrpVal &= ~(0x0FC0);
+ /* PPF_MUX_CRNT_CTRL0 */
+ if (QpllxVcoRateMHz >= 15000) {
+ DrpVal |= 0x0E00;
+ }
+ else if (QpllxVcoRateMHz >= 11000) {
+ DrpVal |= 0x0800;
+ }
+ else if (QpllxVcoRateMHz >= 7000) {
+ DrpVal |= 0x0600;
+ }
+ else {
+ DrpVal |= 0x0400;
+ }
+ /* PPF_MUX_TERM_CTRL0 */
+ if (QpllxVcoRateMHz >= 13000) {
+ DrpVal |= 0x0100;
+ }
+ else {
+ DrpVal |= 0x0000;
+ }
+ /* Write new DRP register value for PPFx_CFG. */
+ XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x0D : 0x8D, DrpVal);
+
+ /* QPLLx_CP */
+ if (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.NFbDiv <= 40) {
+ DrpVal = 0x007F;
+ }
+ else {
+ DrpVal = 0x03FF;
+ }
+ /* Write new DRP register value for QPLLx_CP. */
+ XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x16 : 0x96, DrpVal);
+
+ /* QPLLx_LPF */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x19 : 0x99);
+ DrpVal &= ~(0x0003);
+ if (InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.NFbDiv <= 40) {
+ DrpVal |= 0x3;
+ }
+ else {
+ DrpVal |= 0x1;
+ }
+ /* Write new DRP register value for QPLLx_LPF. */
+ XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x19 : 0x99, DrpVal);
+
+ /* QPLLx_CFG4 */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x30 : 0xB0);
+ DrpVal &= ~(0x00E7);
+ /* Q_TERM_CLK */
+ if (QpllxClkOutMHz >= 7500) {
+ DrpVal |= 0x2 << 5;
+ }
+ else if (QpllxClkOutMHz >= 3500) {
+ DrpVal |= 0x0 << 5;
+ }
+ else {
+ DrpVal |= 0x6 << 5;
+ }
+ /* Q_DCRNT_CLK */
+ if (QpllxClkOutMHz >= 7500) {
+ DrpVal |= 0x5;
+ }
+ else if (QpllxClkOutMHz >= 5500) {
+ DrpVal |= 0x4;
+ }
+ else {
+ DrpVal |= 0x3;
+ }
+ /* Write new DRP register value for QPLLx_CFG4. */
+ XVphy_DrpWrite(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMN,
+ (CmnId == XVPHY_CHANNEL_ID_CMN0) ? 0x30 : 0xB0, 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_Gthe4RxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ XVphy_Channel *ChPtr;
+ u16 DrpVal;
+ u16 WriteVal;
+ u8 CfgIndex;
+ XVphy_ChannelId ChIdPll;
+ XVphy_PllType PllType;
+ u32 PllxVcoRateMHz;
+ u32 PllxClkOutMHz;
+ u32 PllxClkOutDiv;
+
+ 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 (CfgIndex == 2) {
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId,
+ XVPHY_DRP_RXCDR_CFG_GEN3(CfgIndex), DrpVal);
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId,
+ XVPHY_DRP_RXCDR_CFG_GEN4(CfgIndex), DrpVal);
+
+ }
+ }
+
+ if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
+ /* RX_INT_DATAWIDTH */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x66);
+ DrpVal &= ~(0x3);
+ WriteVal = (Xvphy_DrpEncodeIntDataWidth(ChPtr->RxIntDataWidth) & 0x3);
+ DrpVal |= WriteVal;
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x66, DrpVal);
+
+ /* RX_DATA_WIDTH */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x03);
+ DrpVal &= ~(0x1E0);
+ WriteVal = (Xvphy_DrpEncodeDataWidth(ChPtr->RxDataWidth) & 0xF);
+ WriteVal <<= 5;
+ DrpVal |= WriteVal;
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x03, DrpVal);
+
+ /* Determine PLL type. */
+ PllType = XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_RX, ChId);
+ /* Determine which channel(s) to operate on. */
+ switch (PllType) {
+ case XVPHY_PLL_TYPE_QPLL:
+ case XVPHY_PLL_TYPE_QPLL0:
+ case XVPHY_PLL_TYPE_PLL0:
+ ChIdPll = XVPHY_CHANNEL_ID_CMN0;
+ PllxClkOutDiv = 2;
+ break;
+ case XVPHY_PLL_TYPE_QPLL1:
+ case XVPHY_PLL_TYPE_PLL1:
+ ChIdPll = XVPHY_CHANNEL_ID_CMN1;
+ PllxClkOutDiv = 2;
+ break;
+ default:
+ ChIdPll = ChId;
+ PllxClkOutDiv = 1;
+ break;
+ }
+
+ PllxVcoRateMHz = XVphy_GetPllVcoFreqHz(InstancePtr, QuadId, ChIdPll,
+ XVPHY_DIR_RX) / 1000000;
+ PllxClkOutMHz = PllxVcoRateMHz / PllxClkOutDiv;
+
+ /* CH_HSPMUX_RX */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x116);
+ DrpVal &= ~(0x00FF);
+ if (PllxClkOutMHz >= 7500) {
+ DrpVal |= 0x68;
+ }
+ else if (PllxClkOutMHz >= 5500) {
+ DrpVal |= 0x44;
+ }
+ else if (PllxClkOutMHz >= 3500) {
+ DrpVal |= 0x24;
+ }
+ else {
+ DrpVal |= 0x3C;
+ }
+ /* Write new DRP register value for CH_HSPMUX_RX. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x116, DrpVal);
+
+ /* PREIQ_FREQ_BST */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0xFB);
+ DrpVal &= ~(0x0030);
+ if (PllxClkOutMHz > 14110) {
+ DrpVal |= 3 << 4;
+ }
+ else if (PllxClkOutMHz >= 14000) {
+ DrpVal |= 2 << 4; /* LPM Mode */
+ }
+ else if (PllxClkOutMHz >= 10000) {
+ DrpVal |= 2 << 4;
+ }
+ else if (PllxClkOutMHz >= 6000) {
+ DrpVal |= 1 << 4;
+ }
+ /* Write new DRP register value for PREIQ_FREQ_BST. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0xFB, DrpVal);
+
+ /* RXPI_CFG0 */
+ if (PllxClkOutMHz >= 8500) {
+ DrpVal = 0x0004;
+ }
+ else if (PllxClkOutMHz >= 7500) {
+ DrpVal = 0x0104;
+ }
+ else if (PllxClkOutMHz >= 6500) {
+ DrpVal = 0x0204;
+ }
+ else if (PllxClkOutMHz >= 5500) {
+ DrpVal = 0x2304;
+ }
+ else if (PllxClkOutMHz >= 4500) {
+ DrpVal = 0x0002;
+ }
+ else if (PllxClkOutMHz >= 3500) {
+ DrpVal = 0x2202;
+ }
+ else if (PllxClkOutMHz >= 3000) {
+ DrpVal = 0x0000;
+ }
+ else if (PllxClkOutMHz >= 2500) {
+ DrpVal = 0x1200;
+ }
+ else {
+ DrpVal = 0x3300;
+ }
+ /* Write new DRP register value for RXPI_CFG0. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x9D, DrpVal);
+
+ /* RXPI_CFG1 */
+ if (PllxClkOutMHz >= 5500) {
+ DrpVal = 0x0000;
+ }
+ else if (PllxClkOutMHz >= 4500) {
+ DrpVal = 0x0015;
+ }
+ else if (PllxClkOutMHz >= 3500) {
+ DrpVal = 0x0045;
+ }
+ else if (PllxClkOutMHz >= 2000) {
+ DrpVal = 0x00FD;
+ }
+ else {
+ DrpVal = 0x00FF;
+ }
+ /* Write new DRP register value for RXPI_CFG1. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x100, DrpVal);
+ }
+
+ XVphy_Gthe4RxPllRefClkDiv1Reconfig(InstancePtr, QuadId, ChId);
+
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+* This function will configure the channel's TX 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_Gthe4TxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ XVphy_Channel *ChPtr;
+ u32 ReturnVal;
+ u16 DrpVal;
+ u16 WriteVal;
+ XVphy_ChannelId ChIdPll;
+ XVphy_PllType PllType;
+ u32 PllxVcoRateMHz;
+ u32 PllxClkOutMHz;
+ u32 PllxClkOutDiv;
+
+ ReturnVal = XVphy_Gthe4TxPllRefClkDiv1Reconfig(InstancePtr, QuadId, ChId);
+ if (InstancePtr->Config.TxProtocol != XVPHY_PROTOCOL_HDMI) {
+ return ReturnVal;
+ }
+
+ /* Determine PLL type. */
+ PllType = XVphy_GetPllType(InstancePtr, QuadId, XVPHY_DIR_TX, ChId);
+ /* Determine which channel(s) to operate on. */
+ switch (PllType) {
+ case XVPHY_PLL_TYPE_QPLL:
+ case XVPHY_PLL_TYPE_QPLL0:
+ case XVPHY_PLL_TYPE_PLL0:
+ ChIdPll = XVPHY_CHANNEL_ID_CMN0;
+ PllxClkOutDiv = 2;
+ break;
+ case XVPHY_PLL_TYPE_QPLL1:
+ case XVPHY_PLL_TYPE_PLL1:
+ ChIdPll = XVPHY_CHANNEL_ID_CMN1;
+ PllxClkOutDiv = 2;
+ break;
+ default:
+ ChIdPll = ChId;
+ PllxClkOutDiv = 1;
+ break;
+ }
+
+ if (InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_HDMI) {
+
+ ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
+ /* TX_INT_DATAWIDTH */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x85);
+ DrpVal &= ~(0x3 << 10);
+ WriteVal = ((Xvphy_DrpEncodeIntDataWidth(ChPtr->
+ TxIntDataWidth) & 0x3) << 10);
+ DrpVal |= WriteVal;
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x85, DrpVal);
+
+ /* TX_DATA_WIDTH */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x7A);
+ DrpVal &= ~(0xF);
+ WriteVal = (Xvphy_DrpEncodeDataWidth(ChPtr->TxDataWidth) & 0xF);
+ DrpVal |= WriteVal;
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x7A, DrpVal);
+
+ /* TX_PROGDIV_CFG */
+ /* XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x3E, 0xE062); */
+
+ PllxVcoRateMHz = XVphy_GetPllVcoFreqHz(InstancePtr, QuadId, ChIdPll,
+ XVPHY_DIR_TX) / 1000000;
+ PllxClkOutMHz = PllxVcoRateMHz / PllxClkOutDiv;
+
+ /* TXPI_CFG */
+ if (PllxClkOutMHz >= 5500) {
+ DrpVal = 0x0000;
+ }
+ else if (PllxClkOutMHz >= 3500) {
+ DrpVal = 0x0054;
+ }
+ else {
+ DrpVal = 0x03DF;
+ }
+ /* Write new DRP register value for TXPI_CFG. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0xFF, DrpVal);
+
+ /* TXPI_CFG3 */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x9C);
+ DrpVal &= ~(0x0040);
+ if (PllxClkOutMHz < 7500 && PllxClkOutMHz >= 5500) {
+ DrpVal |= 1 << 6;
+ }
+ /* Write new DRP register value for TXPI_CFG3. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x9C, DrpVal);
+
+ /* TX_PI_BIASSET */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0xFB);
+ DrpVal &= ~(0x0006);
+ if (PllxClkOutMHz >= 7500) {
+ DrpVal |= 3 << 1;
+ }
+ else if (PllxClkOutMHz >= 5500) {
+ DrpVal |= 2 << 1;
+ }
+ else if (PllxClkOutMHz >= 3500) {
+ DrpVal |= 1 << 1;
+ }
+ /* Write new DRP register value for TX_PI_BIASSET. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0xFB, DrpVal);
+
+ /* CH_HSPMUX_TX */
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, 0x116);
+ DrpVal &= ~(0xFF00);
+ if (PllxClkOutMHz >= 7500) {
+ DrpVal |= 0x68 << 8;
+ }
+ else if (PllxClkOutMHz >= 5500) {
+ DrpVal |= 0x44 << 8;
+ }
+ else if (PllxClkOutMHz >= 3500) {
+ DrpVal |= 0x24 << 8;
+ }
+ else {
+ DrpVal |= 0x3C << 8;
+ }
+ /* Write new DRP register value for CH_HSPMUX_TX. */
+ XVphy_DrpWrite(InstancePtr, QuadId, ChId, 0x116, 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_Gthe4TxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId)
+{
+ u16 DrpVal;
+ u32 TxRefClkHz;
+ XVphy_Channel *PllPtr = &InstancePtr->Quads[QuadId].
+ Plls[XVPHY_CH2IDX(ChId)];
+
+ if (InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_HDMI) {
+ TxRefClkHz = InstancePtr->HdmiTxRefClkHz;
+ }
+ else {
+ TxRefClkHz = XVphy_GetQuadRefClkFreq(InstancePtr, QuadId,
+ PllPtr->PllRefClkSel);
+ }
+
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, XVPHY_DRP_TXCLK25);
+ DrpVal &= ~(0xF800);
+ DrpVal |= XVphy_DrpEncodeClk25(TxRefClkHz) << 11;
+
+ return XVphy_DrpWrite(InstancePtr, QuadId, ChId, XVPHY_DRP_TXCLK25,
+ DrpVal);
+}
+
+/*****************************************************************************/
+/**
+* This function will configure the channel's RX 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_Gthe4RxPllRefClkDiv1Reconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId)
+{
+ u16 DrpVal;
+ u32 RxRefClkHz;
+ XVphy_Channel *PllPtr = &InstancePtr->Quads[QuadId].
+ Plls[XVPHY_CH2IDX(ChId)];
+
+ if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
+ RxRefClkHz = InstancePtr->HdmiRxRefClkHz;
+ }
+ else {
+ RxRefClkHz = XVphy_GetQuadRefClkFreq(InstancePtr, QuadId,
+ PllPtr->PllRefClkSel);
+ }
+
+ DrpVal = XVphy_DrpRead(InstancePtr, QuadId, ChId, XVPHY_DRP_RXCLK25);
+ DrpVal &= ~(0x00F8);
+ DrpVal |= XVphy_DrpEncodeClk25(RxRefClkHz) << 3;
+
+ return XVphy_DrpWrite(InstancePtr, QuadId, ChId, XVPHY_DRP_RXCLK25,
+ 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 = 0xF;
+ 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) & 0x1;
+
+ 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 = 0x4;
+ 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_DrpEncodeDataWidth(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 = 0xF;
+ 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_DrpEncodeIntDataWidth(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 & 0x1F);
+}
+#endif
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.c
new file mode 100644
index 00000000000000..145224026d7c3e
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.c
@@ -0,0 +1,2384 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvphy_hdmi.c
+ *
+ * This file contains video PHY functionality specific to the HDMI protocol.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 gm 10/19/15 Initial release.
+ * 1.1 gm 02/01/16 Added GTPE2 and GTHE4 support.
+ * MG 03/08/16 Fixed issue in function XVphy_HdmiCfgCalcMmcmParam
+ * for single pixel calculation.
+ * 1.2 gm Added XVphy_HdmiMmcmStart and
+ * XVphy_HdmiMmcmWriteParameters functions
+ * Replaced xil_printf with log events
+ * Modified XVphy_DruGetRefClkFreqHz
+ * Suppressed warning messages due to unused arguments
+ * 1.3 gm 01/11/16 Added error message in XVphy_HdmiCpllParam when DRU is
+ * enabled and RX TMDS ratio is 1/40
+ * Fixed rounding of DRU refclk frequency
+ * Fixed a bug in XVphy_SetHdmiRxParam to update the ChId
+ * when DRU is enabled
+ * 1.4 gm 29/11/16 Added preprocessor directives for sw footprint reduction
+ * Added TX datawidth dynamic reconfiguration
+ * Incorporated AXIlite Freq auto extraction
+ * Added extra routine for 2/4 byte tranceiver modes
+ * Added logging and register access for ERR_IRQ impl
+ * Removed XVphy_HdmiMmcmStart API
+ * Fixed c++ compiler warnings
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#if defined (XPAR_XV_HDMITX_0_DEVICE_ID) || defined (XPAR_XV_HDMIRX_0_DEVICE_ID)
+#include "xstatus.h"
+#include "xvphy.h"
+#include "xvphy_i.h"
+#include "xvphy_hdmi.h"
+
+/****************************** Type Definitions ******************************/
+
+typedef struct {
+ u64 DruLineRate;
+ u16 PllScale;
+ u32 Qpll0RefClkMin;
+ u32 Qpll1RefClkMin;
+ u32 CpllRefClkMin;
+ u16 TxMmcmScale;
+ u32 TxMmcmFvcoMin;
+ u32 TxMmcmFvcoMax;
+ u16 RxMmcmScale;
+ u32 RxMmcmFvcoMin;
+ u32 RxMmcmFvcoMax;
+} XVphy_GtHdmiChars;
+
+/**************************** Function Prototypes *****************************/
+
+extern void XVphy_Ch2Ids(XVphy *InstancePtr, XVphy_ChannelId ChId,
+ u8 *Id0, u8 *Id1);
+static const XVphy_GtHdmiChars *GetGtHdmiPtr(XVphy *InstancePtr);
+static void XVphy_HdmiSetSystemClockSelection(XVphy *InstancePtr, u8 QuadId);
+
+/**************************** Function Definitions ****************************/
+
+/******************************************************************************/
+/**
+ * This function initializes the Video PHY for HDMI.
+ *
+ * @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 SystemFrequency is the system frequency for the HDMI logic
+ * to be based on.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+u32 XVphy_HdmiInitialize(XVphy *InstancePtr, u8 QuadId, XVphy_Config *CfgPtr,
+ u32 SystemFrequency)
+{
+ u8 Id, Id0, Id1;
+
+ /* Verify arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(CfgPtr != NULL);
+
+ /* Init done. */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_INIT, 0);
+
+ /* Setup the instance. */
+ XVphy_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddr);
+
+ /* Set default. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].TxState =
+ XVPHY_GT_STATE_IDLE;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].RxState =
+ XVPHY_GT_STATE_IDLE;
+ //Initialize Transceiver Width values
+ if (InstancePtr->Config.TransceiverWidth == 2) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ TxDataWidth = 20;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ TxIntDataWidth = 2;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxDataWidth = 20;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 2;
+ }
+ else {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ TxDataWidth = 40;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ TxIntDataWidth = 4;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxDataWidth = 40;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 4;
+ }
+ }
+ /* Interrupt Disable. */
+ 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_QPLL0_LOCK);
+ XVphy_IntrDisable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE);
+ XVphy_IntrDisable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK);
+ 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);
+
+ /* Setup HDMI interrupt handler callback*/
+ XVphy_HdmiIntrHandlerCallbackInit(InstancePtr);
+
+ /* Configure clock detector. */
+ XVphy_ClkDetEnable(InstancePtr, FALSE);
+ XVphy_ClkDetSetFreqTimeout(InstancePtr, SystemFrequency);
+ XVphy_ClkDetSetFreqLockThreshold(InstancePtr, 40);
+
+ /* Start capturing logs. */
+ XVphy_LogReset(InstancePtr);
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_INIT, 0);
+
+ XVphy_HdmiSetSystemClockSelection(InstancePtr, QuadId);
+
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE4)) {
+ XVphy_SetBufgGtDiv(InstancePtr, XVPHY_DIR_TX, 1);
+ XVphy_SetBufgGtDiv(InstancePtr, XVPHY_DIR_RX, 1);
+ }
+ XVphy_ResetGtPll(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_RX, TRUE);
+ XVphy_ResetGtPll(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_TX, TRUE);
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ XVphy_ResetGtTxRx(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_RX, TRUE);
+ XVphy_ResetGtTxRx(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_TX, TRUE);
+ }
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ XVphy_PowerDownGtPll(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMNA,
+ TRUE);
+ XVphy_PowerDownGtPll(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ TRUE);
+ }
+ XVphy_MmcmReset(InstancePtr, QuadId, XVPHY_DIR_TX, TRUE);
+ XVphy_MmcmReset(InstancePtr, QuadId, XVPHY_DIR_RX, TRUE);
+ XVphy_IBufDsEnable(InstancePtr, QuadId, XVPHY_DIR_TX, (FALSE));
+ XVphy_IBufDsEnable(InstancePtr, QuadId, XVPHY_DIR_RX, (FALSE));
+
+
+ /* DRU Settings. */
+ if (InstancePtr->Config.DruIsPresent) {
+ XVphy_IBufDsEnable(InstancePtr, QuadId, XVPHY_DIR_RX, TRUE);
+ XVphy_DruReset(InstancePtr, XVPHY_CHANNEL_ID_CHA, TRUE);
+ XVphy_DruEnable(InstancePtr, XVPHY_CHANNEL_ID_CHA, FALSE);
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ XVphy_DruSetGain(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ 9, 16, 5);
+ }
+ else {
+ XVphy_DruSetGain(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ 9, 16, 4);
+ }
+ }
+
+ XVphy_SetRxLpm(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,
+ 1);
+
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ XVphy_SetTxVoltageSwing(InstancePtr, QuadId, (XVphy_ChannelId)Id, 0x1);
+ XVphy_SetTxPreEmphasis(InstancePtr, QuadId, (XVphy_ChannelId)Id, 0x1);
+ }
+
+ /* Clear Interrupt Register */
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_INTR_STS_REG,
+ 0xFFFFFFFF);
+
+ /* Interrupt Enable. */
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_TXRESET_DONE);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_RXRESET_DONE);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_CPLL_LOCK);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_QPLL0_LOCK);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_TXALIGN_DONE);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_QPLL1_LOCK);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_TX_CLKDET_FREQ_CHANGE);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_RX_CLKDET_FREQ_CHANGE);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_TX_TMR_TIMEOUT);
+ XVphy_IntrEnable(InstancePtr,
+ XVPHY_INTR_HANDLER_TYPE_RX_TMR_TIMEOUT);
+ XVphy_ClkDetEnable(InstancePtr, TRUE);
+
+ /* Set the flag to indicate the driver is. */
+ InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
+
+ /* Init done. */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_INIT, 1);
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function Sets the System Clock Selection
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+static void XVphy_HdmiSetSystemClockSelection(XVphy *InstancePtr, u8 QuadId)
+{
+ XVphy_PllType XVphy_QPllType;
+
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
+ XVphy_QPllType = XVPHY_PLL_TYPE_QPLL;
+ }
+ else {
+ XVphy_QPllType = XVPHY_PLL_TYPE_QPLL0;
+ }
+
+ /* Set system clock selections */
+ if (InstancePtr->Config.TxSysPllClkSel ==
+ InstancePtr->Config.RxSysPllClkSel) {
+ if (InstancePtr->Config.RxSysPllClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_CPLL_OUTCLK) {
+ XVphy_PllInitialize(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CHA,
+ InstancePtr->Config.RxRefClkSel,
+ InstancePtr->Config.RxRefClkSel,
+ XVPHY_PLL_TYPE_CPLL,
+ XVPHY_PLL_TYPE_CPLL);
+ }
+ else {
+ XVphy_PllInitialize(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMN0,
+ InstancePtr->Config.RxRefClkSel,
+ InstancePtr->Config.RxRefClkSel,
+ XVphy_QPllType,
+ XVphy_QPllType);
+ }
+ }
+ else if (InstancePtr->Config.TxSysPllClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_CPLL_OUTCLK) {
+ XVphy_PllInitialize(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CHA,
+ InstancePtr->Config.RxRefClkSel,
+ InstancePtr->Config.TxRefClkSel,
+ XVPHY_PLL_TYPE_CPLL,
+ XVphy_QPllType);
+ }
+ else {
+ XVphy_PllInitialize(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMN0,
+ InstancePtr->Config.TxRefClkSel,
+ InstancePtr->Config.RxRefClkSel,
+ XVphy_QPllType,
+ XVPHY_PLL_TYPE_CPLL);
+ }
+ }
+ /* GTPE2 */
+ else {
+ if (InstancePtr->Config.TxSysPllClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_PLL0_OUTCLK) {
+ XVphy_PllInitialize(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMN0,
+ InstancePtr->Config.TxRefClkSel,
+ InstancePtr->Config.RxRefClkSel,
+ XVPHY_PLL_TYPE_PLL0,
+ XVPHY_PLL_TYPE_PLL1);
+ }
+ else {
+ XVphy_PllInitialize(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMN0,
+ InstancePtr->Config.RxRefClkSel,
+ InstancePtr->Config.TxRefClkSel,
+ XVPHY_PLL_TYPE_PLL1,
+ XVPHY_PLL_TYPE_PLL0);
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function Updates the VPHY clocking.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param TxSysPllClkSel is the SYSCLKDATA selection for TX.
+* @param RxSysPllClkSel is the SYSCLKDATA selection for RX.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_HdmiUpdateClockSelection(XVphy *InstancePtr, u8 QuadId,
+ XVphy_SysClkDataSelType TxSysPllClkSel,
+ XVphy_SysClkDataSelType RxSysPllClkSel)
+{
+ u8 Id, Id0, Id1;
+
+ /* Reset PLL */
+ XVphy_ResetGtPll(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_RX, TRUE);
+ XVphy_ResetGtPll(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_TX, TRUE);
+
+ /* Set default. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].TxState =
+ XVPHY_GT_STATE_IDLE;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].RxState =
+ XVPHY_GT_STATE_IDLE;
+ }
+
+ /* Update VPhy Clocking */
+ InstancePtr->Config.TxSysPllClkSel = TxSysPllClkSel;
+ InstancePtr->Config.RxSysPllClkSel = RxSysPllClkSel;
+ XVphy_HdmiSetSystemClockSelection(InstancePtr, QuadId);
+}
+
+/*****************************************************************************/
+/**
+* This function resets the GT TX alignment module.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId is the channel ID to operate on.
+* @param Reset specifies TRUE/FALSE value to either assert or deassert
+* reset on the TX alignment module, respectively.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_TxAlignReset(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Reset)
+{
+ u32 RegVal;
+ u32 MaskVal = 0;
+ u8 Id, Id0, Id1;
+
+ /* Read TX align register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_TX_BUFFER_BYPASS_REG);
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ MaskVal |= XVPHY_TX_BUFFER_BYPASS_TXPHDLYRESET_MASK(Id);
+ }
+
+ /* Write new value to BUFG_GT register. */
+ if (Reset) {
+ RegVal |= MaskVal;
+ }
+ else {
+ RegVal &= ~MaskVal;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_TX_BUFFER_BYPASS_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function resets the GT TX alignment module.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId is the channel ID to operate on.
+* @param Start specifies TRUE/FALSE value to either start or ttop the TX
+* alignment module, respectively.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_TxAlignStart(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Start)
+{
+ u32 RegVal;
+ u32 MaskVal = 0;
+ u8 Id, Id0, Id1;
+
+ /* Read TX align register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_TX_BUFFER_BYPASS_REG);
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ MaskVal |= XVPHY_TX_BUFFER_BYPASS_TXPHALIGN_MASK(Id);
+ }
+
+ /* Write new value to BUFG_GT register. */
+ if (Start) {
+ RegVal |= MaskVal;
+ }
+ else {
+ RegVal &= ~MaskVal;
+ }
+
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_TX_BUFFER_BYPASS_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function enables the VPHY's detector peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Enable specifies TRUE/FALSE value to either enable or disable
+* the clock detector respectively.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_ClkDetEnable(XVphy *InstancePtr, u8 Enable)
+{
+ u32 RegVal;
+
+ /* Read clkdet ctrl register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_CLKDET_CTRL_REG);
+
+ /* Write new value to clkdet ctrl register. */
+ if (Enable) {
+ RegVal |= XVPHY_CLKDET_CTRL_RUN_MASK;
+ }
+ else {
+ RegVal &= ~XVPHY_CLKDET_CTRL_RUN_MASK;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_CLKDET_CTRL_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function clears the clock detector TX/RX timer.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for RX or TX.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_ClkDetTimerClear(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir)
+{
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ /* Read the clock detector control register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_CLKDET_CTRL_REG);
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegVal |= XVPHY_CLKDET_CTRL_TX_TMR_CLR_MASK;
+ }
+ else {
+ RegVal |= XVPHY_CLKDET_CTRL_RX_TMR_CLR_MASK;
+ }
+
+ /* Write new value to clkdet ctrl register. */
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_CLKDET_CTRL_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function resets clock detector TX/RX frequency.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for RX or TX.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_ClkDetFreqReset(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir)
+{
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ /* Read clkdet ctrl register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_CLKDET_CTRL_REG);
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegVal |= XVPHY_CLKDET_CTRL_TX_FREQ_RST_MASK;
+ }
+ else {
+ RegVal |= XVPHY_CLKDET_CTRL_RX_FREQ_RST_MASK;
+ }
+
+ /* Write new value to clkdet ctrl register. */
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_CLKDET_CTRL_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function sets the clock detector frequency lock counter threshold value.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ThresholdVal is the threshold value to be set.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_ClkDetSetFreqLockThreshold(XVphy *InstancePtr, u16 ThresholdVal)
+{
+ u32 RegVal;
+
+ /* Read clkdet ctrl register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_CLKDET_CTRL_REG);
+ RegVal &= ~XVPHY_CLKDET_CTRL_RX_FREQ_RST_MASK;
+
+ /* Update with new threshold. */
+ RegVal |= (ThresholdVal << XVPHY_CLKDET_CTRL_FREQ_LOCK_THRESH_SHIFT);
+
+ /* Write new value to clkdet ctrl register. */
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_CLKDET_CTRL_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function checks clock detector RX/TX frequency zero indicator bit.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Dir is an indicator for RX or TX.
+*
+* @return - TRUE if zero frequency.
+* - FALSE otherwise, if non-zero frequency.
+*
+* @note None.
+*
+******************************************************************************/
+u8 XVphy_ClkDetCheckFreqZero(XVphy *InstancePtr, XVphy_DirectionType Dir)
+{
+ u32 MaskVal = 0;
+ u32 RegVal;
+
+ if (Dir == XVPHY_DIR_TX) {
+ MaskVal = XVPHY_CLKDET_STAT_TX_FREQ_ZERO_MASK;
+ }
+ else {
+ MaskVal = XVPHY_CLKDET_STAT_RX_FREQ_ZERO_MASK;
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_STAT_REG);
+ RegVal &= MaskVal;
+
+ if (RegVal) {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/*****************************************************************************/
+/**
+* This function sets clock detector frequency lock counter threshold value.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param TimeoutVal is the timeout value and is normally the system clock
+* frequency.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_ClkDetSetFreqTimeout(XVphy *InstancePtr, u32 TimeoutVal)
+{
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr,
+ XVPHY_CLKDET_FREQ_TMR_TO_REG, TimeoutVal);
+}
+
+/*****************************************************************************/
+/**
+* This function loads the timer to TX/RX in the clock detector.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for RX or TX.
+* @param TimeoutVal is the timeout value to store in the clock detector.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_ClkDetTimerLoad(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, u32 TimeoutVal)
+{
+ u32 RegOffset;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_CLKDET_TMR_TX_REG;
+ }
+ else {
+ RegOffset = XVPHY_CLKDET_TMR_RX_REG;
+ }
+
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, TimeoutVal);
+}
+
+/*****************************************************************************/
+/**
+* This function returns the frequency of the RX/TX reference clock as
+* measured by the clock detector peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Dir is an indicator for RX or TX.
+*
+* @return The measured frequency of the RX/TX reference clock.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_ClkDetGetRefClkFreqHz(XVphy *InstancePtr, XVphy_DirectionType Dir)
+{
+ u32 RegOffset;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_CLKDET_FREQ_TX_REG;
+ }
+ else {
+ RegOffset = XVPHY_CLKDET_FREQ_RX_REG;
+ }
+
+ return XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+}
+
+/*****************************************************************************/
+/**
+* This function returns the frequency of the DRU reference clock as measured by
+* the clock detector peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+*
+* @return The measured frequency of the DRU reference clock.
+*
+* @note The design must have a DRU for this function to return a valid
+* value.
+*
+******************************************************************************/
+u32 XVphy_DruGetRefClkFreqHz(XVphy *InstancePtr)
+{
+ u32 DruFreqHz = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_CLKDET_FREQ_DRU_REG);
+
+
+
+ /* Verify argument. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
+ if (DruFreqHz > XVPHY_HDMI_GTXE2_DRU_REFCLK_MIN &&
+ DruFreqHz < XVPHY_HDMI_GTXE2_DRU_REFCLK_MAX){
+ return XVPHY_HDMI_GTXE2_DRU_REFCLK;
+ }
+ }
+ else if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE2) {
+ if (DruFreqHz > XVPHY_HDMI_GTHE2_DRU_REFCLK_MIN &&
+ DruFreqHz < XVPHY_HDMI_GTHE2_DRU_REFCLK_MAX){
+ return XVPHY_HDMI_GTHE2_DRU_REFCLK;
+ }
+ }
+ else if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ if (DruFreqHz > XVPHY_HDMI_GTPE2_DRU_REFCLK_MIN &&
+ DruFreqHz < XVPHY_HDMI_GTPE2_DRU_REFCLK_MAX){
+ return XVPHY_HDMI_GTPE2_DRU_REFCLK;
+ }
+ }
+ else if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) {
+ if (DruFreqHz > XVPHY_HDMI_GTHE3_DRU_REFCLK_MIN &&
+ DruFreqHz < XVPHY_HDMI_GTHE3_DRU_REFCLK_MAX){
+ return XVPHY_HDMI_GTHE3_DRU_REFCLK;
+ }
+ }
+ else {
+ if (DruFreqHz > XVPHY_HDMI_GTHE4_DRU_REFCLK_MIN &&
+ DruFreqHz < XVPHY_HDMI_GTHE4_DRU_REFCLK_MAX){
+ return XVPHY_HDMI_GTHE4_DRU_REFCLK;
+ }
+ }
+ /* Return Failure */
+ return XST_FAILURE;
+}
+
+/*****************************************************************************/
+/**
+* This function resets the DRU in the VPHY.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId is the channel ID to operate on.
+* @param Reset specifies TRUE/FALSE value to either enable or disable
+* the DRU respectively.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_DruReset(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Reset)
+{
+ u32 RegVal;
+ u32 MaskVal = 0;
+ u8 Id, Id0, Id1;
+
+ /* Read DRU ctrl register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_CTRL_REG);
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ MaskVal |= XVPHY_DRU_CTRL_RST_MASK(Id);
+ }
+
+ /* Write DRU ctrl register. */
+ if (Reset) {
+ RegVal |= MaskVal;
+ }
+ else {
+ RegVal &= ~MaskVal;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_DRU_CTRL_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function enabled/disables the DRU in the VPHY.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId is the channel ID to operate on.
+* @param Enable specifies TRUE/FALSE value to either enable or disable
+* the DRU, respectively.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_DruEnable(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 Enable)
+{
+ u32 RegVal;
+ u32 MaskVal = 0;
+ u8 Id, Id0, Id1;
+
+ /* Read DRU ctrl register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_CTRL_REG);
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ MaskVal |= XVPHY_DRU_CTRL_EN_MASK(Id);
+ }
+
+ /* Write DRU ctrl register. */
+ if (Enable) {
+ RegVal |= MaskVal;
+ }
+ else {
+ RegVal &= ~MaskVal;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_DRU_CTRL_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function gets the DRU version
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+*
+* @return None.
+*
+******************************************************************************/
+u16 XVphy_DruGetVersion(XVphy *InstancePtr)
+{
+ u32 RegVal;
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_STAT_REG);
+ RegVal &= XVPHY_DRU_STAT_VERSION_MASK;
+ RegVal >>= XVPHY_DRU_STAT_VERSION_SHIFT;
+
+ return ((u16)RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function sets the DRU center frequency.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId specifies the channel ID.
+* @param CenterFreqHz is the frequency value to set.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_DruSetCenterFreqHz(XVphy *InstancePtr, XVphy_ChannelId ChId,
+ u64 CenterFreqHz)
+{
+ u32 CenterFreqL;
+ u32 CenterFreqH;
+ u32 RegOffset;
+ u8 Id, Id0, Id1;
+
+ /* Split the 64-bit input into 2 32-bit values. */
+ CenterFreqL = (u32)CenterFreqHz;
+ CenterFreqHz >>= 32;
+ CenterFreqHz &= XVPHY_DRU_CFREQ_H_MASK;;
+ CenterFreqH = (u32)CenterFreqHz;
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ RegOffset = XVPHY_DRU_CFREQ_L_REG(Id);
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset,
+ CenterFreqL);
+
+ RegOffset = XVPHY_DRU_CFREQ_H_REG(Id);
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset,
+ CenterFreqH);
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function sets the DRU gain.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId is the channel ID to operate on.
+* @param G1 gain value.
+* @param G1_P gain value.
+* @param G2 gain value.
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_DruSetGain(XVphy *InstancePtr, XVphy_ChannelId ChId, u8 G1, u8 G1_P,
+ u8 G2)
+{
+ u32 RegVal;
+ u32 RegOffset;
+ u8 Id, Id0, Id1;
+
+ RegVal = G1 & XVPHY_DRU_GAIN_G1_MASK;
+ RegVal |= (G1_P << XVPHY_DRU_GAIN_G1_P_SHIFT) &
+ XVPHY_DRU_GAIN_G1_P_MASK;
+ RegVal |= (G2 << XVPHY_DRU_GAIN_G2_SHIFT) & XVPHY_DRU_GAIN_G2_MASK;
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ RegOffset = XVPHY_DRU_GAIN_REG(Id);
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function calculates the center frequency value for the DRU.
+*
+* @param InstancePtr is a pointer to the XVphy GT core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param ChId is the channel ID to operate on.
+*
+* @return The calculated DRU Center frequency value.
+*
+* @note According to XAPP875:
+* Center_f = fDIN * (2^32)/fdruclk
+* The DRU clock is derived from the measured reference clock and
+* the current QPLL settings.
+*
+******************************************************************************/
+u64 XVphy_DruCalcCenterFreqHz(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId)
+{
+ XVphy_Channel *ChPtr, *CmnPtr;
+ u64 DruRefClk;
+ u64 ClkDetRefClk;
+ u64 DataRate;
+ u64 FDin;
+ u64 FDruClk;
+
+ DruRefClk = XVphy_DruGetRefClkFreqHz(InstancePtr);
+ ClkDetRefClk = XVphy_ClkDetGetRefClkFreqHz(InstancePtr, XVPHY_DIR_RX);
+
+ /* Take the master channel (channel 1). */
+ ChPtr = &InstancePtr->Quads[QuadId].Ch1;
+
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ CmnPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)];
+ FDruClk = (DruRefClk * CmnPtr->PllParams.N1FbDiv *
+ CmnPtr->PllParams.N2FbDiv * 2) /
+ (CmnPtr->PllParams.MRefClkDiv * ChPtr->RxOutDiv * 20);
+ }
+ else if ((ChId == XVPHY_CHANNEL_ID_CMN0) ||
+ (ChId == XVPHY_CHANNEL_ID_CMN1)) {
+ FDruClk = (DruRefClk * InstancePtr->Quads[QuadId].Plls[
+ XVPHY_CH2IDX(ChId)].PllParams.NFbDiv) /
+ (ChPtr->RxOutDiv * 20);
+ }
+ else {
+ FDruClk = (DruRefClk * ChPtr->PllParams.N1FbDiv *
+ ChPtr->PllParams.N2FbDiv * 2) /
+ (ChPtr->PllParams.MRefClkDiv * ChPtr->RxOutDiv * 20);
+ }
+
+ DataRate = 10 * ClkDetRefClk;
+ FDin = DataRate * ((u64)1 << 32);
+
+ /* Check for divide by zero. */
+ if (FDin && FDruClk) {
+ return (FDin / FDruClk);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/**
+* This function sets the GT RX CDR and Equalization for DRU mode.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Enable enables the DRU logic (when 1), or disables (when 0).
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_HdmiGtDruModeEnable(XVphy *InstancePtr, u8 Enable)
+{
+ u32 RegVal;
+ u32 RegMask = 0;
+ u8 Id, Id0, Id1;
+
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_DRU_EN, Enable);
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_RX_EQ_CDR_REG);
+
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ RegMask |= XVPHY_RX_STATUS_RXCDRHOLD_MASK(Id) |
+ XVPHY_RX_STATUS_RXOSOVRDEN_MASK(Id) |
+ XVPHY_RX_STATUS_RXLPMLFKLOVRDEN_MASK(Id) |
+ XVPHY_RX_STATUS_RXLPMHFOVRDEN_MASK(Id);
+ }
+
+ if (Enable) {
+ RegVal |= RegMask;
+ }
+ else {
+ RegVal &= ~RegMask;
+ }
+
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_RX_EQ_CDR_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function calculates the HDMI MMCM parameters.
+*
+* @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.
+* @param Dir is an indicator for RX or TX.
+* @param Ppc specifies the total number of pixels per clock.
+* - 1 = XVIDC_PPC_1
+* - 2 = XVIDC_PPC_2
+* - 4 = XVIDC_PPC_4
+* @param Bpc specifies the color depth/bits per color component.
+* - 6 = XVIDC_BPC_6
+* - 8 = XVIDC_BPC_8
+* - 10 = XVIDC_BPC_10
+* - 12 = XVIDC_BPC_12
+* - 16 = XVIDC_BPC_16
+*
+* @return
+* - XST_SUCCESS if calculated PLL parameters updated successfully.
+* - XST_FAILURE if parameters not updated.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_HdmiCfgCalcMmcmParam(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir,
+ XVidC_PixelsPerClock Ppc, XVidC_ColorDepth Bpc)
+{
+ u32 RefClk;
+ u8 Div;
+ u8 Mult;
+ u8 Valid;
+ u64 LineRate = 0;
+ XVphy_Mmcm *MmcmPtr;
+ XVphy_PllType PllType;
+
+ /* Suppress Warning Messages */
+ ChId = ChId;
+
+ if (Dir == XVPHY_DIR_RX) {
+ RefClk = InstancePtr->HdmiRxRefClkHz;
+ MmcmPtr= &InstancePtr->Quads[QuadId].RxMmcm;
+
+ RefClk = RefClk / (GetGtHdmiPtr(InstancePtr))->RxMmcmScale;
+ Mult = (GetGtHdmiPtr(InstancePtr))->RxMmcmFvcoMax / RefClk;
+ }
+ else {
+ RefClk = InstancePtr->HdmiTxRefClkHz;
+ MmcmPtr= &InstancePtr->Quads[QuadId].TxMmcm;
+
+ RefClk = RefClk / (GetGtHdmiPtr(InstancePtr))->TxMmcmScale;
+ Mult = (GetGtHdmiPtr(InstancePtr))->TxMmcmFvcoMax / RefClk;
+
+ /* Get line rate. */
+ PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_TX,
+ XVPHY_CHANNEL_ID_CH1);
+
+ switch (PllType) {
+ case XVPHY_PLL_TYPE_QPLL:
+ case XVPHY_PLL_TYPE_QPLL0:
+ case XVPHY_PLL_TYPE_PLL0:
+ LineRate = InstancePtr->Quads[QuadId].Cmn0.LineRateHz;
+ break;
+ case XVPHY_PLL_TYPE_QPLL1:
+ case XVPHY_PLL_TYPE_PLL1:
+ LineRate = InstancePtr->Quads[QuadId].Cmn1.LineRateHz;
+ break;
+ default:
+ LineRate = InstancePtr->Quads[QuadId].Ch1.LineRateHz;
+ break;
+ }
+ }
+
+ Div = 1;
+
+ if (((LineRate / 1000000) > 2970) && (Ppc == XVIDC_PPC_1)) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_1PPC_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_MMCM_CFG, 1);
+ return (XST_FAILURE);
+ }
+
+ /* In case of 4 pixels per clock, the M must be a multiple of four. */
+ if (Ppc == XVIDC_PPC_4) {
+ Mult = Mult / 4;
+ Mult = Mult * 4;
+ }
+ /* Else the M must be a multiple of two. */
+ else if (Ppc == XVIDC_PPC_2) {
+ Mult = Mult / 2;
+ Mult = Mult * 2;
+ }
+
+ if (!((Mult >= 1) && (Mult < 65))) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_MMCM_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_MMCM_CFG, 1);
+ return (XST_FAILURE); /* Mult is out of range. */
+ }
+
+ Valid = (FALSE);
+ do {
+ MmcmPtr->ClkFbOutMult = Mult;
+ MmcmPtr->DivClkDivide = Div;
+
+ if (InstancePtr->Config.TransceiverWidth == 4) {
+ /* Link clock: TMDS clock ratio 1/40. */
+ if ((LineRate / 1000000) >= 3400) {
+ MmcmPtr->ClkOut0Div = Mult;
+ }
+ /* Link clock: TMDS clock ratio 1/10. */
+ else {
+ MmcmPtr->ClkOut0Div = Mult * 4;
+ }
+ }
+ else {//2 Byte Mode
+ /* Link clock: TMDS clock ratio 1/40. */
+ if ((LineRate / 1000000) >= 3400) {
+ MmcmPtr->ClkOut0Div = Mult / 2;
+ }
+ /* Link clock: TMDS clock ratio 1/10. */
+ else {
+ MmcmPtr->ClkOut0Div = Mult * 2;
+ }
+ }
+
+ /* TMDS Clock */
+ MmcmPtr->ClkOut1Div = Mult * ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1);
+
+ /* Video clock. */
+ MmcmPtr->ClkOut2Div = 0;
+
+ switch (Bpc) {
+ case XVIDC_BPC_10:
+ /* Quad pixel. */
+ if (Ppc == (XVIDC_PPC_4)) {
+ MmcmPtr->ClkOut2Div = (Mult * 5 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Dual pixel. */
+ else if (Ppc == (XVIDC_PPC_2)) {
+ /* The clock ratio is 2.5 */
+ /* The PLL only supports integer values */
+ /* The mult must be dividable by two (2 * 2.5 = 5)
+ to get an integer number */
+ if ((Mult % 2) == 0) {
+ MmcmPtr->ClkOut2Div = (Mult * 5 / 2 *
+ ((Dir == XVPHY_DIR_TX)?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ }
+ /* Single pixel. */
+ else {
+ /* The clock ratio is 1.25 */
+ /* The PLL only supports integer values */
+ /* The mult must be dividable by four (4 * 1.25 = 5)
+ to get an integer number */
+ if ((Mult % 4) == 0) {
+ MmcmPtr->ClkOut2Div = (Mult * 5 / 4 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ }
+ break;
+ case XVIDC_BPC_12:
+ /* Quad pixel. */
+ if (Ppc == (XVIDC_PPC_4)) {
+ MmcmPtr->ClkOut2Div = (Mult * 6 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Dual pixel. */
+ else if (Ppc == (XVIDC_PPC_2)) {
+ MmcmPtr->ClkOut2Div = (Mult * 3 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Single pixel. */
+ else {
+ /* The clock ratio is 1.5 */
+ /* The PLL only supports integer values */
+ /* The mult must be dividable by two (2 * 1.5 = 3)
+ to get an integer number */
+ if ((Mult % 2) == 0) {
+ MmcmPtr->ClkOut2Div = (Mult * 3 / 2 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ }
+ break;
+ case XVIDC_BPC_16 :
+ /* Quad pixel. */
+ if (Ppc == (XVIDC_PPC_4)) {
+ MmcmPtr->ClkOut2Div = (Mult * 8 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Dual pixel. */
+ else if (Ppc == (XVIDC_PPC_2)) {
+ MmcmPtr->ClkOut2Div = (Mult * 4 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Single pixel. */
+ else {
+ MmcmPtr->ClkOut2Div = (Mult * 2 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ break;
+ case XVIDC_BPC_8:
+ default:
+ /* Quad pixel. */
+ if (Ppc == (XVIDC_PPC_4)) {
+ MmcmPtr->ClkOut2Div = (Mult * 4 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Dual pixel. */
+ else if (Ppc == (XVIDC_PPC_2)) {
+ MmcmPtr->ClkOut2Div = (Mult * 2 *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ /* Single pixel. */
+ else {
+ MmcmPtr->ClkOut2Div = (Mult *
+ ((Dir == XVPHY_DIR_TX) ?
+ (InstancePtr->HdmiTxSampleRate) : 1));
+ }
+ break;
+ }
+
+ /* Only do this when the ClkOut2Div has been set */
+ if (MmcmPtr->ClkOut2Div) {
+ if (Dir == XVPHY_DIR_RX) {
+ /* Correct divider value if TMDS clock ratio is 1/40. */
+ if (InstancePtr->HdmiRxTmdsClockRatio) {
+ if ((MmcmPtr->ClkOut2Div % 4) == 0) {
+ MmcmPtr->ClkOut2Div =
+ MmcmPtr->ClkOut2Div / 4;
+ }
+ /* Not divisible by 4: repeat loop with a lower
+ * multiply value. */
+ else {
+ MmcmPtr->ClkOut2Div = 255;
+ }
+ }
+ }
+ /* TX. */
+ else if ((LineRate / 1000000) >= 3400) {
+ if ((MmcmPtr->ClkOut2Div % 4) == 0) {
+ MmcmPtr->ClkOut2Div =
+ MmcmPtr->ClkOut2Div / 4;
+ }
+ /* Not divisible by 4: repeat loop with a lower
+ * multiply value. */
+ else {
+ MmcmPtr->ClkOut2Div = 255;
+ }
+ }
+ }
+
+ /* Check values. */
+ if ((MmcmPtr->ClkOut0Div <= 128) &&
+ (MmcmPtr->ClkOut1Div <= 128) &&
+ (MmcmPtr->ClkOut2Div <= 128) &&
+ (MmcmPtr->ClkOut2Div > 0)) {
+ Valid = (TRUE);
+ }
+ else {
+ /* 4 pixels per clock. */
+ if (Ppc == (XVIDC_PPC_4)) {
+ /* Decrease Mult value. */
+ Mult -= 4;
+ }
+ /* 2 pixels per clock. */
+ else if (Ppc == (XVIDC_PPC_2)) {
+ /* Decrease M value. */
+ Mult -= 2;
+ }
+ /* 1 pixel per clock */
+ else {
+ /* Decrease M value */
+ Mult -= 1;
+ }
+ }
+ } while (!Valid);
+
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) &&
+ (((RefClk/1000)*(Mult/MmcmPtr->ClkOut2Div)) > 148500)) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_VDCLK_HIGH_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_MMCM_CFG, 1);
+ return (XST_FAILURE);
+ }
+
+ if (Valid) {
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_MMCM_CFG, 0);
+ return (XST_SUCCESS);
+ }
+ else {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_MMCM_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_MMCM_CFG, 1);
+ return (XST_FAILURE);
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function calculates the QPLL parameters.
+*
+* @param InstancePtr is a pointer to the HDMI GT 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 calculated QPLL parameters updated
+* successfully.
+* - XST_FAILURE if parameters not updated.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_HdmiQpllParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir)
+{
+ u32 Status;
+ u64 RefClk = 0;
+ u32 *RefClkPtr;
+ u64 TxLineRate = 0;
+ u8 Id, Id0, Id1;
+
+ u8 SRArray[] = {1, 3, 5};
+ u8 SRIndex;
+ u8 SRValue;
+
+ /* Suppress Warning Messages */
+ ChId = ChId;
+
+ XVphy_SysClkDataSelType SysClkDataSel = (XVphy_SysClkDataSelType) 0;
+ XVphy_SysClkOutSelType SysClkOutSel = (XVphy_SysClkOutSelType) 0;
+ XVphy_ChannelId ActiveCmnId = XVPHY_CHANNEL_ID_CMN0;
+
+ u32 QpllRefClk;
+ u32 QpllClkMin = 0;
+
+ /* Determine QPLL reference clock from the first (master) channel. */
+ if (Dir == XVPHY_DIR_RX) {
+ QpllRefClk = InstancePtr->HdmiRxRefClkHz;
+ RefClkPtr = &InstancePtr->HdmiRxRefClkHz;
+ }
+ else {
+ QpllRefClk = InstancePtr->HdmiTxRefClkHz;
+ RefClkPtr = &InstancePtr->HdmiTxRefClkHz;
+ }
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE3)
+ /* Determine which QPLL to use. */
+ if (((101875000 <= QpllRefClk) && (QpllRefClk <= 122500000)) ||
+ ((203750000 <= QpllRefClk) &&
+ (QpllRefClk <= 245000000)) ||
+ ((407000000 <= QpllRefClk) &&
+ (QpllRefClk <= 490000000))) {
+ SysClkDataSel = XVPHY_SYSCLKSELDATA_TYPE_QPLL1_OUTCLK;
+ SysClkOutSel = XVPHY_SYSCLKSELOUT_TYPE_QPLL1_REFCLK;
+ ActiveCmnId = XVPHY_CHANNEL_ID_CMN1;
+ QpllClkMin = (u32) XVPHY_HDMI_GTHE3_QPLL1_REFCLK_MIN;
+ }
+ else {
+ SysClkDataSel = XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK;
+ SysClkOutSel = XVPHY_SYSCLKSELOUT_TYPE_QPLL0_REFCLK;
+ ActiveCmnId = XVPHY_CHANNEL_ID_CMN0;
+ QpllClkMin = (u32) XVPHY_HDMI_GTHE3_QPLL0_REFCLK_MIN;
+ }
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE4)
+ /* Determine which QPLL to use. */
+ if (((101875000 <= QpllRefClk) && (QpllRefClk <= 122500000)) ||
+ ((203750000 <= QpllRefClk) && (QpllRefClk <= 245000000)) ||
+ ((407000000 <= QpllRefClk) && (QpllRefClk <= 490000000))) {
+ SysClkDataSel = XVPHY_SYSCLKSELDATA_TYPE_QPLL1_OUTCLK;
+ SysClkOutSel = XVPHY_SYSCLKSELOUT_TYPE_QPLL1_REFCLK;
+ ActiveCmnId = XVPHY_CHANNEL_ID_CMN1;
+ QpllClkMin = (u32) XVPHY_HDMI_GTHE4_QPLL1_REFCLK_MIN;
+ }
+ else {
+ SysClkDataSel = XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK;
+ SysClkOutSel = XVPHY_SYSCLKSELOUT_TYPE_QPLL0_REFCLK;
+ ActiveCmnId = XVPHY_CHANNEL_ID_CMN0;
+ QpllClkMin = (u32) XVPHY_HDMI_GTHE4_QPLL0_REFCLK_MIN;
+ }
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE2)
+ SysClkDataSel = XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK;
+ SysClkOutSel = XVPHY_SYSCLKSELOUT_TYPE_QPLL_REFCLK;
+ ActiveCmnId = XVPHY_CHANNEL_ID_CMN;
+ QpllClkMin = (GetGtHdmiPtr(InstancePtr))->Qpll0RefClkMin;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+ SysClkDataSel = XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK;
+ SysClkOutSel = XVPHY_SYSCLKSELOUT_TYPE_QPLL_REFCLK;
+ ActiveCmnId = XVPHY_CHANNEL_ID_CMN;
+ QpllClkMin = (GetGtHdmiPtr(InstancePtr))->Qpll0RefClkMin;
+#endif
+
+ /* Update QPLL clock selections. */
+ XVphy_CfgSysClkDataSel(InstancePtr, QuadId, Dir, SysClkDataSel);
+ XVphy_CfgSysClkOutSel(InstancePtr, QuadId, Dir, SysClkOutSel);
+
+ /* RX is using QPLL. */
+ if (Dir == XVPHY_DIR_RX) {
+ /* Check if the reference clock is not below the minimum QPLL
+ * input frequency. */
+ if (QpllRefClk >= QpllClkMin) {
+ RefClk = QpllRefClk;
+
+ /* Scaled line rate. */
+ if (InstancePtr->HdmiRxTmdsClockRatio) {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA, (RefClk * 40));
+ }
+ else {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA, (RefClk * 10));
+ }
+
+ /* Clear DRU is enabled flag. */
+ InstancePtr->HdmiRxDruIsEnabled = 0;
+
+ /* Set RX data width. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ if (InstancePtr->Config.TransceiverWidth == 2) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxDataWidth = 20;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 2;
+ }
+ else {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxDataWidth = 40;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 4;
+ }
+ }
+
+ }
+ /* The reference clock is below the minimum frequency thus
+ * select the DRU. */
+ else if (InstancePtr->Config.DruIsPresent) {
+ RefClk = XVphy_DruGetRefClkFreqHz(InstancePtr);
+
+ /* Round input frequency to 10 kHz. */
+ RefClk = (RefClk+5000) / 10000;
+ RefClk = RefClk * 10000;
+
+ /* Set the DRU to operate at a linerate of 2.5 Gbps. */
+ XVphy_CfgLineRate(InstancePtr,
+ QuadId, XVPHY_CHANNEL_ID_CMNA,
+ (GetGtHdmiPtr(InstancePtr))->DruLineRate);
+
+ /* Set DRU is enabled flag. */
+ InstancePtr->HdmiRxDruIsEnabled = 1;
+
+ /* Set RX data width to 40 and 4 bytes. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[
+ XVPHY_CH2IDX(Id)].RxDataWidth = 20;
+ InstancePtr->Quads[QuadId].Plls[
+ XVPHY_CH2IDX(Id)].RxIntDataWidth = 2;
+ }
+ }
+ else {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_NO_DRU, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_NO_DRU, 1);
+ return (XST_FAILURE);
+ }
+ }
+
+ /* TX is using QPLL. */
+ else {
+ /* Update TX line rates. */
+ XVphy_CfgLineRate(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CMNA,
+ (u64)((*RefClkPtr) * 10));
+ TxLineRate = (*RefClkPtr) / 100000;;
+
+ /* Set default TX sample rate. */
+ InstancePtr->HdmiTxSampleRate = 1;
+
+ /* Check if the linerate is above the 340 Mcsc. */
+ if ((TxLineRate) >= 3400) {
+ (*RefClkPtr) = (*RefClkPtr) / 4;
+ }
+ }
+
+ /* Calculate QPLL values. */
+ for (SRIndex = 0; SRIndex < sizeof(SRArray); SRIndex++) {
+ /* Only use oversampling when then TX is using the QPLL. */
+ if (Dir == XVPHY_DIR_TX) {
+ SRValue = SRArray[SRIndex];
+
+ /* TX reference clock is below the minimum QPLL clock
+ * input frequency. */
+ if ((*RefClkPtr) < QpllClkMin) {
+ RefClk = ((*RefClkPtr) * SRValue);
+
+ /* Calculate scaled line rate. */
+ if (TxLineRate >= 3400) {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA,
+ (u64)(RefClk * 40));
+ }
+ else {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA,
+ (u64)(RefClk * 10));
+ }
+ }
+ /* TX reference clock is in QPLL clock input range.
+ * In this case don't increase the reference clock, but
+ * increase the line rate. */
+ else {
+ RefClk = (*RefClkPtr);
+
+ /* Calculate scaled line rate. */
+ if (TxLineRate >= 3400) {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA,
+ (u64)(RefClk * 40 *SRValue));
+ }
+
+ else {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CMNA,
+ (u64)(RefClk * 10 *SRValue));
+ }
+ }
+ }
+ /* For all other reference clocks force sample rate to one. */
+ else {
+ SRValue = 1;
+ }
+
+ Status = XVphy_ClkCalcParams(InstancePtr, QuadId, ActiveCmnId,
+ Dir, RefClk);
+ if (Status == (XST_SUCCESS)) {
+ /* Only execute when the TX is using the QPLL. */
+ if (Dir == XVPHY_DIR_TX) {
+ /* Set TX sample rate. */
+ InstancePtr->HdmiTxSampleRate = SRValue;
+
+ /* Update reference clock only when the
+ * reference clock is below the minimum QPLL
+ * input frequency. */
+ if ((*RefClkPtr) < QpllClkMin) {
+ (*RefClkPtr) = (*RefClkPtr) * SRValue;
+ }
+ else if (SRValue > 1) {
+ XVphy_LogWrite(InstancePtr,
+ XVPHY_LOG_EVT_GT_PLL_LAYOUT, 1);
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_QPLL_CFG, 1);
+ return (XST_FAILURE);
+ }
+ }
+ if (Dir == XVPHY_DIR_RX) {
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_NO_DRU, 0);
+ }
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_QPLL_CFG, 0);
+ return (XST_SUCCESS);
+ }
+ }
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_GT_QPLL_CFG_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_QPLL_CFG, 1);
+ return (XST_FAILURE);
+}
+
+/*****************************************************************************/
+/**
+* This function calculates the CPLL parameters.
+*
+* @param InstancePtr is a pointer to the HDMI GT 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 calculated CPLL parameters updated
+* successfully.
+* - XST_FAILURE if parameters not updated.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_HdmiCpllParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir)
+{
+ u32 Status;
+ u64 RefClk = 0;
+ u32 *RefClkPtr;
+ u32 TxLineRate = 0;
+ XVphy_ChannelId ChannelId = XVPHY_CHANNEL_ID_CHA;
+ u8 Id, Id0, Id1;
+
+ u8 SRArray[] = {1, 3, 5};
+ u8 SRIndex;
+ u8 SRValue;
+
+ XVphy_PllType PllType;
+
+ /* Suppress Warning Messages */
+ ChId = ChId;
+
+ /* Change Channel ID to Common if GTPE2 */
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ PllType = XVphy_GetPllType(InstancePtr, QuadId, Dir,
+ XVPHY_CHANNEL_ID_CH1);
+ if (PllType == XVPHY_PLL_TYPE_PLL0) {
+ ChannelId = XVPHY_CHANNEL_ID_CMN0;
+ }
+ else {
+ ChannelId = XVPHY_CHANNEL_ID_CMN1;
+ }
+ }
+
+ /* TX is using CPLL. */
+ if ((Dir == XVPHY_DIR_TX) && (!XVphy_IsBonded(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CH1))) {
+
+ /* Set default TX sample rate. */
+ InstancePtr->HdmiTxSampleRate = 1;
+
+ /* Set line rate. */
+ RefClkPtr = &InstancePtr->HdmiTxRefClkHz;
+ XVphy_CfgLineRate(InstancePtr, QuadId, ChannelId,
+ (u64)((*RefClkPtr) * 10));
+ TxLineRate = (*RefClkPtr) / 100000;
+
+ /* Check if the line rate is above the 340 Mcsc. */
+ if (TxLineRate >= 3400) {
+ (*RefClkPtr) = (*RefClkPtr) / 4;
+ }
+ }
+ /* RX is using CPLL. */
+ else {
+ RefClkPtr = &InstancePtr->HdmiRxRefClkHz;
+
+ /* Check if the reference clock is not below the minimum CPLL
+ * input frequency. */
+ if ((*RefClkPtr) >=
+ (GetGtHdmiPtr(InstancePtr))->CpllRefClkMin) {
+ RefClk = (*RefClkPtr);
+
+ /* Scaled linerate */
+ if (InstancePtr->HdmiRxTmdsClockRatio) {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ ChannelId, (RefClk * 40));
+ }
+ else {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ ChannelId, (RefClk * 10));
+ }
+
+ /* Clear DRU is enabled flag. */
+ InstancePtr->HdmiRxDruIsEnabled = 0;
+
+ /* Set RX data width. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ if ((InstancePtr->Config.TransceiverWidth == 2) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxDataWidth = 20;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 2;
+ }
+ else {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxDataWidth = 40;
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 4;
+ }
+ }
+
+ }
+ /* The reference clock is below the minimum frequency thus
+ * select the DRU. */
+ else {
+ if (InstancePtr->Config.DruIsPresent) {
+ /* Return config not found error when TMDS ratio is 1/40 */
+ if (InstancePtr->HdmiRxTmdsClockRatio) {
+ XVphy_LogWrite(InstancePtr,
+ XVPHY_LOG_EVT_GT_CPLL_CFG_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_CPLL_CFG, 1);
+ return (XST_FAILURE);
+ }
+
+ RefClk = XVphy_DruGetRefClkFreqHz(InstancePtr);
+
+ /* Round input frequency to 10 kHz. */
+ RefClk = (RefClk+5000) / 10000;
+ RefClk = RefClk * 10000;
+
+ /* Set the DRU to operate at a linerate of
+ * 2.5 Gbps. */
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ ChannelId,
+ (GetGtHdmiPtr(InstancePtr))->
+ DruLineRate);
+
+ /* Set DRU is enabled flag. */
+ InstancePtr->HdmiRxDruIsEnabled = 1;
+
+ /* Set RX data width. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[
+ XVPHY_CH2IDX(Id)].
+ RxDataWidth = 20;
+ InstancePtr->Quads[QuadId].Plls[
+ XVPHY_CH2IDX(Id)].
+ RxIntDataWidth = 2;
+ }
+
+ if (TxLineRate > (((GetGtHdmiPtr(InstancePtr))
+ ->DruLineRate) / 1000000)) {
+ XVphy_LogWrite(InstancePtr,
+ XVPHY_LOG_EVT_VD_NOT_SPRTD_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_CPLL_CFG, 1);
+ return (XST_FAILURE);
+ }
+ }
+ else {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_NO_DRU, 1);
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_NO_DRU, 1);
+ return (XST_FAILURE);
+ }
+ }
+ }
+
+ /* Try different sample rates. */
+ for (SRIndex = 0; SRIndex < sizeof(SRArray); SRIndex++) {
+ /* Only use oversampling when then TX is using the CPLL. */
+ if ((Dir == XVPHY_DIR_TX) && (!XVphy_IsBonded(InstancePtr,
+ QuadId, XVPHY_CHANNEL_ID_CH1))) {
+ SRValue = SRArray[SRIndex];
+
+ /* Multiply the reference clock with the sample rate
+ * value. */
+ RefClk = ((*RefClkPtr) * SRValue);
+
+ /* Calculate scaled line rate. */
+ if (TxLineRate >= 3400) {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ ChannelId, (RefClk * 40));
+ }
+ else {
+ XVphy_CfgLineRate(InstancePtr, QuadId,
+ ChannelId, (RefClk * 10));
+ }
+ }
+ /* For all other reference clocks force sample rate to one. */
+ else {
+ SRValue = 1;
+ }
+
+ Status = XVphy_ClkCalcParams(InstancePtr, QuadId,
+ ChannelId, Dir, RefClk);
+ if (Status == (XST_SUCCESS)) {
+ /* Only execute when the TX is using the QPLL. */
+ if ((Dir == XVPHY_DIR_TX) && (!XVphy_IsBonded(
+ InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CH1))) {
+ InstancePtr->HdmiTxSampleRate = SRValue;
+
+ (*RefClkPtr) = (*RefClkPtr) * SRValue;
+ }
+ if (Dir == XVPHY_DIR_RX) {
+ XVphy_CfgErrIntr(InstancePtr,
+ XVPHY_ERRIRQ_NO_DRU, 0);
+ }
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_CPLL_CFG, 0);
+ return (XST_SUCCESS);
+ }
+ }
+
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_GT_CPLL_CFG_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_CPLL_CFG, 1);
+ return (XST_FAILURE);
+}
+
+/*****************************************************************************/
+/**
+* This function update/set the HDMI TX parameter.
+*
+* @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.
+* @param Ppc is the pixels per clock to set.
+* @param Bpc is the bits per color to set.
+* @param ColorFormat is the color format to set.
+*
+* @return
+* - XST_SUCCESS if TX parameters set/updated.
+* - XST_FAILURE if low resolution video not supported.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_SetHdmiTxParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVidC_PixelsPerClock Ppc, XVidC_ColorDepth Bpc,
+ XVidC_ColorFormat ColorFormat)
+{
+ u32 Status;
+
+ /* Verify arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid((Ppc == (XVIDC_PPC_1)) || (Ppc == (XVIDC_PPC_2)) ||
+ (Ppc == (XVIDC_PPC_4)));
+ Xil_AssertNonvoid((Bpc == (XVIDC_BPC_8)) || (Bpc == (XVIDC_BPC_10)) ||
+ (Bpc == (XVIDC_BPC_12)) || (Bpc == (XVIDC_BPC_16)));
+ Xil_AssertNonvoid((ColorFormat == (XVIDC_CSF_RGB)) ||
+ (ColorFormat == (XVIDC_CSF_YCRCB_444)) ||
+ (ColorFormat == (XVIDC_CSF_YCRCB_422)) ||
+ (ColorFormat == (XVIDC_CSF_YCRCB_420)));
+
+ /* Only calculate the QPLL/CPLL parameters when the GT TX and RX are not
+ * coupled. */
+ if (!XVphy_IsBonded(InstancePtr, QuadId, ChId)) {
+ if (XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId)) {
+ Status = XVphy_HdmiCpllParam(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_TX);
+ }
+ else if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ Status = XVphy_HdmiQpllParam(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_TX);
+ /* Update SysClk and PLL Clk registers immediately. */
+ XVphy_WriteCfgRefClkSelReg(InstancePtr, QuadId);
+ }
+ else {
+ /* GTP divider calculation is same with CPLL */
+ Status = XVphy_HdmiCpllParam(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_TX);
+ }
+
+ if (Status == XST_FAILURE) {
+ return Status;
+ }
+ }
+ /* Bonded mode. */
+ else {
+ /* Copy reference clock. */
+ InstancePtr->HdmiTxRefClkHz = InstancePtr->HdmiRxRefClkHz;
+
+ /* Copy the line rate. */
+ if (XVphy_IsRxUsingQpll(InstancePtr, QuadId,
+ XVPHY_CHANNEL_ID_CH1)) {
+ InstancePtr->Quads[QuadId].Ch1.LineRateHz =
+ InstancePtr->Quads[QuadId].Cmn0.LineRateHz;
+ }
+ else {
+ InstancePtr->Quads[QuadId].Cmn0.LineRateHz =
+ InstancePtr->Quads[QuadId].Ch1.LineRateHz;
+ }
+
+ InstancePtr->HdmiTxSampleRate = 1;
+
+ Status = (XST_SUCCESS);
+ }
+
+ /* Is HDMITXSS PPC match with VPHY PPC? */
+ if (Ppc == InstancePtr->Config.Ppc) {
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_VD_NOT_SPRTD, 0);
+ Status = (XST_SUCCESS);
+ }
+ else {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_PPC_MSMTCH_ERR, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_VD_NOT_SPRTD, 1);
+ Status = (XST_FAILURE);
+ }
+ if (Status == (XST_SUCCESS)) {
+ /* Calculate TXPLL parameters.
+ * In HDMI the colordepth in YUV422 is always 12 bits,
+ * although on the link itself it is being transmitted as
+ * 8-bits. Therefore if the colorspace is YUV422, then force the
+ * colordepth to 8 bits. */
+ if (ColorFormat == XVIDC_CSF_YCRCB_422) {
+ Status = XVphy_HdmiCfgCalcMmcmParam(InstancePtr, QuadId,
+ ChId, XVPHY_DIR_TX, Ppc, XVIDC_BPC_8);
+ }
+ /* Other colorspaces. */
+ else {
+ Status = XVphy_HdmiCfgCalcMmcmParam(InstancePtr, QuadId,
+ ChId, XVPHY_DIR_TX, Ppc, Bpc);
+ }
+ }
+ else {
+ Status = (XST_FAILURE);
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function update/set the HDMI RX parameter.
+*
+* @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
+* - XST_SUCCESS if RX parameters set/updated.
+* - XST_FAILURE if low resolution video not supported.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_SetHdmiRxParam(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ XVphy_ChannelId ChanId = ChId;
+ XVphy_PllType PllType;
+ u32 Status;
+ u64 DruCenterFreq;
+ u8 Id, Id0, Id1;
+
+ /* Verify arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+ if (XVphy_IsRxUsingCpll(InstancePtr, QuadId, ChId)) {
+ Status = XVphy_HdmiCpllParam(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_RX);
+ }
+ else if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ Status = XVphy_HdmiQpllParam(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_RX);
+ /* Update SysClk and PLL Clk registers immediately */
+ XVphy_WriteCfgRefClkSelReg(InstancePtr, QuadId);
+ }
+ else {
+ /* GTP divider calculation is same with CPLL */
+ Status = XVphy_HdmiCpllParam(InstancePtr, QuadId, ChId,
+ XVPHY_DIR_RX);
+ }
+
+ if (XVphy_IsBonded(InstancePtr, QuadId, XVPHY_CHANNEL_ID_CH1)) {
+ /* Same divisor value for all channels. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].
+ TxOutDiv = InstancePtr->Quads[QuadId].
+ Plls[XVPHY_CH2IDX(Id)].RxOutDiv;
+ }
+ }
+
+ if (InstancePtr->HdmiRxDruIsEnabled) {
+ /* Determine PLL type. */
+ PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
+ XVPHY_CHANNEL_ID_CH1);
+ /* Update the ChId */
+ ChanId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_RX, PllType);
+
+ DruCenterFreq = XVphy_DruCalcCenterFreqHz(InstancePtr, QuadId,
+ ChanId);
+ XVphy_DruSetCenterFreqHz(InstancePtr, XVPHY_CHANNEL_ID_CHA,
+ DruCenterFreq);
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function prints Video PHY debug information related to HDMI.
+*
+* @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_HdmiDebugInfo(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ u32 RegValue;
+ XVphy_Channel *ChPtr;
+ XVphy_ChannelId CmnId = XVPHY_CHANNEL_ID_CMN0;
+ u8 CpllDVal;
+ u8 QpllDVal;
+ u8 UsesQpll0 = 0;
+ u8 TxUsesPll0 = 0;
+
+ ChPtr = &InstancePtr->Quads[QuadId].Plls[0];
+
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ UsesQpll0 = (FALSE);
+ if (ChPtr->TxDataRefClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_PLL0_OUTCLK) {
+ TxUsesPll0 = 1;
+ xil_printf("TX => PLL0 / ");
+ }
+ else {
+ xil_printf("TX => PLL1 / ");
+ }
+ }
+ else if (XVphy_IsTxUsingCpll(InstancePtr, QuadId, ChId)) {
+ xil_printf("TX => CPLL / ");
+ }
+ else {
+ if ((ChPtr->TxDataRefClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK) ||
+ (ChPtr->TxDataRefClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK)) {
+ UsesQpll0 = (TRUE);
+ CmnId = XVPHY_CHANNEL_ID_CMN0;
+ }
+ else {
+ UsesQpll0 = (FALSE);
+ CmnId = XVPHY_CHANNEL_ID_CMN1;
+ }
+ xil_printf("TX => QPLL%d / ", (UsesQpll0 ? 0 : 1));
+ }
+
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ xil_printf("RX => PLL%d\n\r", (TxUsesPll0 ? 1 : 0));
+ }
+ else if (XVphy_IsRxUsingCpll(InstancePtr, QuadId, ChId)) {
+ xil_printf("RX => CPLL\n\r");
+ }
+ else {
+ if ((ChPtr->RxDataRefClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK) ||
+ (ChPtr->RxDataRefClkSel ==
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK)) {
+ UsesQpll0 = (TRUE);
+ CmnId = XVPHY_CHANNEL_ID_CMN0;
+ }
+ else {
+ UsesQpll0 = (FALSE);
+ CmnId = XVPHY_CHANNEL_ID_CMN1;
+ }
+ xil_printf("RX => QPLL%d\n\r", (UsesQpll0 ? 0 : 1));
+ }
+
+ 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 (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ xil_printf("PLL%d lock\n\r", (TxUsesPll0 ? 1 : 0));
+ }
+ else 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 (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ xil_printf("PLL%d lock\n\r", (TxUsesPll0 ? 0 : 1));
+ }
+ else 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");
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ xil_printf("QPLL%d settings\n\r", (UsesQpll0 ? 0 : 1));
+ 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");
+ }
+ else {
+ CmnId = XVPHY_CHANNEL_ID_CMN0;
+ xil_printf("PLL0 settings\n\r");
+ xil_printf("-------------\n\r");
+ xil_printf("M : %d - N1 : %d - N2 : %d - D : %d\n\r",
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.MRefClkDiv,
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.N1FbDiv,
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.N2FbDiv,
+ (TxUsesPll0 ? ChPtr->TxOutDiv : ChPtr->RxOutDiv));
+ xil_printf("\n\r");
+
+ CmnId = XVPHY_CHANNEL_ID_CMN1;
+ xil_printf("PLL1 settings\n\r");
+ xil_printf("-------------\n\r");
+ xil_printf("M : %d - N1 : %d - N2 : %d - D : %d\n\r",
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.MRefClkDiv,
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.N1FbDiv,
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(CmnId)].
+ PllParams.N2FbDiv,
+ (TxUsesPll0 ? ChPtr->RxOutDiv : ChPtr->TxOutDiv));
+ xil_printf("\n\r");
+ }
+
+ xil_printf("RX MMCM settings\n\r");
+ xil_printf("-------------\n\r");
+ xil_printf("Mult : %d - Div : %d - Clk0Div : %d - Clk1Div : %d - "
+ "Clk2Div : %d\n\r",
+ InstancePtr->Quads[QuadId].RxMmcm.ClkFbOutMult,
+ InstancePtr->Quads[QuadId].RxMmcm.DivClkDivide,
+ InstancePtr->Quads[QuadId].RxMmcm.ClkOut0Div,
+ InstancePtr->Quads[QuadId].RxMmcm.ClkOut1Div,
+ InstancePtr->Quads[QuadId].RxMmcm.ClkOut2Div);
+ xil_printf("\n\r");
+
+ xil_printf("TX MMCM settings\n\r");
+ xil_printf("-------------\n\r");
+ xil_printf("Mult : %d - Div : %d - Clk0Div : %d - Clk1Div : %d - "
+ "Clk2Div : %d\n\r",
+ InstancePtr->Quads[QuadId].TxMmcm.ClkFbOutMult,
+ InstancePtr->Quads[QuadId].TxMmcm.DivClkDivide,
+ InstancePtr->Quads[QuadId].TxMmcm.ClkOut0Div,
+ InstancePtr->Quads[QuadId].TxMmcm.ClkOut1Div,
+ InstancePtr->Quads[QuadId].TxMmcm.ClkOut2Div);
+ xil_printf("\n\r");
+
+ if (InstancePtr->Config.DruIsPresent) {
+ xil_printf("DRU Settings\n\r");
+ xil_printf("-------------\n\r");
+ RegValue = XVphy_DruGetVersion(InstancePtr);
+ xil_printf("Version : %d\n\r", RegValue);
+
+ if (InstancePtr->HdmiRxDruIsEnabled) {
+ RegValue = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_GAIN_REG(ChId));
+
+ xil_printf("G1 : %d\n\rG1_P : %d\n\r"
+ "G2 : %d\n\r",
+ ((RegValue & XVPHY_DRU_GAIN_G1_MASK)),
+ ((RegValue & XVPHY_DRU_GAIN_G1_P_MASK) >>
+ XVPHY_DRU_GAIN_G1_P_SHIFT),
+ ((RegValue & XVPHY_DRU_GAIN_G2_MASK) >>
+ XVPHY_DRU_GAIN_G2_SHIFT));
+
+ RegValue = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_CFREQ_H_REG(ChId));
+ xil_printf("Center_F : %x", RegValue);
+
+ RegValue = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_DRU_CFREQ_L_REG(ChId));
+ xil_printf("%x\n\r", RegValue);
+ }
+ else {
+ xil_printf("DRU is disabled\n\r");
+ }
+
+ xil_printf(" \n\r");
+ }
+}
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE3)
+static const XVphy_GtHdmiChars Gthe3HdmiChars = {
+ .DruLineRate = XVPHY_HDMI_GTHE3_DRU_LRATE,
+ .PllScale = XVPHY_HDMI_GTHE3_PLL_SCALE,
+ .Qpll0RefClkMin = XVPHY_HDMI_GTHE3_QPLL0_REFCLK_MIN,
+ .Qpll1RefClkMin = XVPHY_HDMI_GTHE3_QPLL1_REFCLK_MIN,
+ .CpllRefClkMin = XVPHY_HDMI_GTHE3_CPLL_REFCLK_MIN,
+ .TxMmcmScale = XVPHY_HDMI_GTHE3_TX_MMCM_SCALE,
+ .TxMmcmFvcoMin = XVPHY_HDMI_GTHE3_TX_MMCM_FVCO_MIN,
+ .TxMmcmFvcoMax = XVPHY_HDMI_GTHE3_TX_MMCM_FVCO_MAX,
+ .RxMmcmScale = XVPHY_HDMI_GTHE3_RX_MMCM_SCALE,
+ .RxMmcmFvcoMin = XVPHY_HDMI_GTHE3_RX_MMCM_FVCO_MIN,
+ .RxMmcmFvcoMax = XVPHY_HDMI_GTHE3_RX_MMCM_FVCO_MAX,
+};
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE4)
+static const XVphy_GtHdmiChars Gthe4HdmiChars = {
+ .DruLineRate = XVPHY_HDMI_GTHE4_DRU_LRATE,
+ .PllScale = XVPHY_HDMI_GTHE4_PLL_SCALE,
+ .Qpll0RefClkMin = XVPHY_HDMI_GTHE4_QPLL0_REFCLK_MIN,
+ .Qpll1RefClkMin = XVPHY_HDMI_GTHE4_QPLL1_REFCLK_MIN,
+ .CpllRefClkMin = XVPHY_HDMI_GTHE4_CPLL_REFCLK_MIN,
+ .TxMmcmScale = XVPHY_HDMI_GTHE4_TX_MMCM_SCALE,
+ .TxMmcmFvcoMin = XVPHY_HDMI_GTHE4_TX_MMCM_FVCO_MIN,
+ .TxMmcmFvcoMax = XVPHY_HDMI_GTHE4_TX_MMCM_FVCO_MAX,
+ .RxMmcmScale = XVPHY_HDMI_GTHE4_RX_MMCM_SCALE,
+ .RxMmcmFvcoMin = XVPHY_HDMI_GTHE4_RX_MMCM_FVCO_MIN,
+ .RxMmcmFvcoMax = XVPHY_HDMI_GTHE4_RX_MMCM_FVCO_MAX,
+};
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE2)
+static const XVphy_GtHdmiChars Gthe2HdmiChars = {
+ .DruLineRate = XVPHY_HDMI_GTHE2_DRU_LRATE,
+ .PllScale = XVPHY_HDMI_GTHE2_PLL_SCALE,
+ .Qpll0RefClkMin = XVPHY_HDMI_GTHE2_QPLL_REFCLK_MIN,
+ .Qpll1RefClkMin = 0,
+ .CpllRefClkMin = XVPHY_HDMI_GTHE2_CPLL_REFCLK_MIN,
+ .TxMmcmScale = XVPHY_HDMI_GTHE2_TX_MMCM_SCALE,
+ .TxMmcmFvcoMin = XVPHY_HDMI_GTHE2_TX_MMCM_FVCO_MIN,
+ .TxMmcmFvcoMax = XVPHY_HDMI_GTHE2_TX_MMCM_FVCO_MAX,
+ .RxMmcmScale = XVPHY_HDMI_GTHE2_RX_MMCM_SCALE,
+ .RxMmcmFvcoMin = XVPHY_HDMI_GTHE2_RX_MMCM_FVCO_MIN,
+ .RxMmcmFvcoMax = XVPHY_HDMI_GTHE2_RX_MMCM_FVCO_MAX,
+};
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTPE2)
+static const XVphy_GtHdmiChars Gtpe2HdmiChars = {
+ .DruLineRate = XVPHY_HDMI_GTPE2_DRU_LRATE,
+ .PllScale = XVPHY_HDMI_GTPE2_PLL_SCALE,
+ .Qpll0RefClkMin = XVPHY_HDMI_GTPE2_QPLL_REFCLK_MIN,
+ .Qpll1RefClkMin = 0,
+ .CpllRefClkMin = XVPHY_HDMI_GTPE2_CPLL_REFCLK_MIN,
+ .TxMmcmScale = XVPHY_HDMI_GTPE2_TX_MMCM_SCALE,
+ .TxMmcmFvcoMin = XVPHY_HDMI_GTPE2_TX_MMCM_FVCO_MIN,
+ .TxMmcmFvcoMax = XVPHY_HDMI_GTPE2_TX_MMCM_FVCO_MAX,
+ .RxMmcmScale = XVPHY_HDMI_GTPE2_RX_MMCM_SCALE,
+ .RxMmcmFvcoMin = XVPHY_HDMI_GTPE2_RX_MMCM_FVCO_MIN,
+ .RxMmcmFvcoMax = XVPHY_HDMI_GTPE2_RX_MMCM_FVCO_MAX,
+};
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+static const XVphy_GtHdmiChars Gtxe2HdmiChars = {
+ .DruLineRate = XVPHY_HDMI_GTXE2_DRU_LRATE,
+ .PllScale = XVPHY_HDMI_GTXE2_PLL_SCALE,
+ .Qpll0RefClkMin = XVPHY_HDMI_GTXE2_QPLL_REFCLK_MIN,
+ .Qpll1RefClkMin = 0,
+ .CpllRefClkMin = XVPHY_HDMI_GTXE2_CPLL_REFCLK_MIN,
+ .TxMmcmScale = XVPHY_HDMI_GTXE2_TX_MMCM_SCALE,
+ .TxMmcmFvcoMin = XVPHY_HDMI_GTXE2_TX_MMCM_FVCO_MIN,
+ .TxMmcmFvcoMax = XVPHY_HDMI_GTXE2_TX_MMCM_FVCO_MAX,
+ .RxMmcmScale = XVPHY_HDMI_GTXE2_RX_MMCM_SCALE,
+ .RxMmcmFvcoMin = XVPHY_HDMI_GTXE2_RX_MMCM_FVCO_MIN,
+ .RxMmcmFvcoMax = XVPHY_HDMI_GTXE2_RX_MMCM_FVCO_MAX,
+};
+#endif
+
+/*****************************************************************************/
+/**
+* This function returns a pointer to the HDMI parameters based on the GT type.
+*
+* @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
+* - A pointer to the HDMI GT characteristics.
+* - NULL if the GT type is unsupported.
+*
+* @note None.
+*
+******************************************************************************/
+static const XVphy_GtHdmiChars *GetGtHdmiPtr(XVphy *InstancePtr)
+{
+ /* Suppress Warning Messages */
+ InstancePtr = InstancePtr;
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+ return &Gtxe2HdmiChars;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE2)
+ return &Gthe2HdmiChars;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTPE2)
+ return &Gtpe2HdmiChars;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE3)
+ return &Gthe3HdmiChars;
+#elif (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTHE4)
+ return &Gthe4HdmiChars;
+#endif
+
+ return NULL;
+}
+
+
+#endif
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.h
new file mode 100644
index 00000000000000..23fe59346b2e74
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi.h
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added GTPE2 and GTHE4 constants
+ * 1.2 gm Added XVphy_HdmiMmcmStart function
+ * 1.4 gm 29/11/16 Added preprocessor directives for sw footprint reduction
+ * Removed XVphy_HdmiMmcmStart API
+ * Corrected GTPE2 DRU REFCLK range
+ * </pre>
+ *
+*******************************************************************************/
+#if defined (XPAR_XV_HDMITX_0_DEVICE_ID) || defined (XPAR_XV_HDMIRX_0_DEVICE_ID)
+
+#ifndef XVPHY_HDMI_H_
+/* Prevent circular inclusions by using protection macros. */
+#define XVPHY_HDMI_H_
+
+/************************** Constant Definitions ******************************/
+
+#define XVPHY_HDMI_GTHE4_DRU_LRATE 2500000000U
+#define XVPHY_HDMI_GTHE4_DRU_REFCLK 156250000LL
+#define XVPHY_HDMI_GTHE4_DRU_REFCLK_MIN 156240000LL
+#define XVPHY_HDMI_GTHE4_DRU_REFCLK_MAX 156260000LL
+#define XVPHY_HDMI_GTHE4_PLL_SCALE 1000
+#define XVPHY_HDMI_GTHE4_QPLL0_REFCLK_MIN 61250000LL
+#define XVPHY_HDMI_GTHE4_QPLL1_REFCLK_MIN 50000000LL
+#define XVPHY_HDMI_GTHE4_CPLL_REFCLK_MIN 100000000LL
+#define XVPHY_HDMI_GTHE4_TX_MMCM_SCALE 1
+#define XVPHY_HDMI_GTHE4_TX_MMCM_FVCO_MIN 600000000U
+#define XVPHY_HDMI_GTHE4_TX_MMCM_FVCO_MAX 1200000000U
+#define XVPHY_HDMI_GTHE4_RX_MMCM_SCALE 1
+#define XVPHY_HDMI_GTHE4_RX_MMCM_FVCO_MIN 600000000U
+#define XVPHY_HDMI_GTHE4_RX_MMCM_FVCO_MAX 1200000000U
+
+#define XVPHY_HDMI_GTHE3_DRU_LRATE 2500000000U
+#define XVPHY_HDMI_GTHE3_DRU_REFCLK 156250000LL
+#define XVPHY_HDMI_GTHE3_DRU_REFCLK_MIN 156240000LL
+#define XVPHY_HDMI_GTHE3_DRU_REFCLK_MAX 156260000LL
+#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_DRU_REFCLK 125000000LL
+#define XVPHY_HDMI_GTHE2_DRU_REFCLK_MIN 124990000LL
+#define XVPHY_HDMI_GTHE2_DRU_REFCLK_MAX 125010000LL
+#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_DRU_REFCLK 125000000LL
+#define XVPHY_HDMI_GTXE2_DRU_REFCLK_MIN 124990000LL
+#define XVPHY_HDMI_GTXE2_DRU_REFCLK_MAX 125010000LL
+#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
+
+#define XVPHY_HDMI_GTPE2_DRU_LRATE 2500000000U
+#define XVPHY_HDMI_GTPE2_DRU_REFCLK 100000000LL
+#define XVPHY_HDMI_GTPE2_DRU_REFCLK_MIN 99990000LL
+#define XVPHY_HDMI_GTPE2_DRU_REFCLK_MAX 100010000LL
+#define XVPHY_HDMI_GTPE2_PLL_SCALE 1000
+#define XVPHY_HDMI_GTPE2_QPLL_REFCLK_MIN 80000000LL
+#define XVPHY_HDMI_GTPE2_CPLL_REFCLK_MIN 80000000LL
+#define XVPHY_HDMI_GTPE2_TX_MMCM_SCALE 1
+#define XVPHY_HDMI_GTPE2_TX_MMCM_FVCO_MIN 800000000U
+#define XVPHY_HDMI_GTPE2_TX_MMCM_FVCO_MAX 1866000000U
+#define XVPHY_HDMI_GTPE2_RX_MMCM_SCALE 1
+#define XVPHY_HDMI_GTPE2_RX_MMCM_FVCO_MIN 600000000U
+#define XVPHY_HDMI_GTPE2_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_ */
+#endif
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi_intr.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi_intr.c
new file mode 100644
index 00000000000000..9ba7e4bf65ff08
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hdmi_intr.c
@@ -0,0 +1,1153 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added GTPE2 and GTHE4 support
+ * Added XVphy_HdmiGtpPllLockHandler for GTPE2
+ * 1.2 gm Replaced xil_printf with log events for debugging
+ * 1.3 gm 01/11/16 Fixed rounding of RX refclk frequency
+ * Fixed race condition in
+ * XVphy_HdmiRxClkDetFreqChangeHandler when storing
+ * RxRefClkHz value
+ * 1.4 gm 29/11/16 Added preprocessor directives for sw footprint reduction
+ * Incorporated AXIlite Freq auto extraction
+ * Added logging and register access for ERR_IRQ impl
+ * Added mechanism to re-trigger GT TX reset when TX align
+ * get stuck
+ * Fixed c++ compiler warnings
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#if defined (XPAR_XV_HDMITX_0_DEVICE_ID) || defined (XPAR_XV_HDMIRX_0_DEVICE_ID)
+#include "xstatus.h"
+#include "xvphy.h"
+#include "xvphy_i.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 = (XVphy_Callback)CallbackFunc;
+ InstancePtr->HdmiTxInitRef = CallbackRef;
+ break;
+
+ case XVPHY_HDMI_HANDLER_TXREADY:
+ InstancePtr->HdmiTxReadyCallback = (XVphy_Callback)CallbackFunc;
+ InstancePtr->HdmiTxReadyRef = CallbackRef;
+ break;
+
+ case XVPHY_HDMI_HANDLER_RXINIT:
+ InstancePtr->HdmiRxInitCallback = (XVphy_Callback)CallbackFunc;
+ InstancePtr->HdmiRxInitRef = CallbackRef;
+ break;
+
+ case XVPHY_HDMI_HANDLER_RXREADY:
+ InstancePtr->HdmiRxReadyCallback = (XVphy_Callback)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);
+}
+
+#if (XPAR_VPHY_0_TRANSCEIVER != XVPHY_GTPE2)
+/*****************************************************************************/
+/**
+* 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_PllType TxPllType;
+ XVphy_PllType RxPllType;
+ u8 Id, Id0, Id1;
+ XVphy_ChannelId ChId;
+
+ /* 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);
+
+ /* RX is using QPLL. */
+ if ((RxPllType == XVPHY_PLL_TYPE_QPLL) ||
+ (RxPllType == XVPHY_PLL_TYPE_QPLL0) ||
+ (RxPllType == XVPHY_PLL_TYPE_QPLL1) ||
+ (RxPllType == XVPHY_PLL_TYPE_PLL0) ||
+ (RxPllType == XVPHY_PLL_TYPE_PLL1)) {
+
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_RX, RxPllType);
+
+ if (XVphy_IsPllLocked(InstancePtr, 0, ChId) == XST_SUCCESS) {
+ /* Log, lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_QPLL_LOCK, 1);
+
+ /* 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;
+ }
+ }
+ }
+ else {
+ /* Log, Lost lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_QPLL_LOCK, 0);
+ }
+ }
+ /* TX is using QPLL. */
+ else {
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_TX, TxPllType);
+
+ if (XVphy_IsPllLocked(InstancePtr, 0, ChId) == XST_SUCCESS) {
+ /* Log, lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_QPLL_LOCK, 1);
+
+ /* 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;
+ }
+ }
+ else {
+ /* Log, Lost lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_QPLL_LOCK, 0);
+ }
+ }
+}
+#endif
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTPE2)
+/*****************************************************************************/
+/**
+* This function is the handler for events triggered by GTP PLL0/1 lock done.
+*
+* @param InstancePtr is a pointer to the VPHY instance.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_HdmiGtpPllLockHandler(XVphy *InstancePtr, u8 Pll)
+{
+ XVphy_PllType TxPllType;
+ XVphy_PllType RxPllType;
+ u8 Id, Id0, Id1;
+ XVphy_ChannelId ChId;
+
+ /* 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);
+
+ /* RX is using QPLL. */
+ if (((RxPllType == XVPHY_PLL_TYPE_PLL0) && (Pll == 0)) ||
+ ((RxPllType == XVPHY_PLL_TYPE_PLL1) && (Pll == 1))) {
+
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_RX, RxPllType);
+
+ if (XVphy_IsPllLocked(InstancePtr, 0, ChId) == XST_SUCCESS) {
+ /* Log, lock */
+ XVphy_LogWrite(InstancePtr, (Pll == 0) ?
+ XVPHY_LOG_EVT_PLL0_LOCK :
+ XVPHY_LOG_EVT_PLL1_LOCK, 1);
+
+ /* 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;
+ }
+ }
+ }
+ else {
+ /* Log, Lost lock */
+ XVphy_LogWrite(InstancePtr, (Pll == 0) ?
+ XVPHY_LOG_EVT_PLL0_LOCK :
+ XVPHY_LOG_EVT_PLL1_LOCK, 0);
+ }
+ }
+ /* TX is using QPLL. */
+ else {
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_TX, TxPllType);
+
+ if (XVphy_IsPllLocked(InstancePtr, 0, ChId) == XST_SUCCESS) {
+ /* Log, lock */
+ XVphy_LogWrite(InstancePtr, (Pll == 0) ?
+ XVPHY_LOG_EVT_PLL0_LOCK :
+ XVPHY_LOG_EVT_PLL1_LOCK, 1);
+
+ /* 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;
+ }
+ }
+ else {
+ /* Log, Lost lock */
+ XVphy_LogWrite(InstancePtr, (Pll == 0) ?
+ XVPHY_LOG_EVT_PLL0_LOCK :
+ XVPHY_LOG_EVT_PLL1_LOCK, 0);
+ }
+ }
+}
+#endif
+
+#if (XPAR_VPHY_0_TRANSCEIVER != XVPHY_GTPE2)
+/*****************************************************************************/
+/**
+* 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_PllType TxPllType;
+ XVphy_PllType RxPllType;
+ u8 Id, Id0, Id1;
+ XVphy_ChannelId ChId;
+
+ /* 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);
+
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+
+ /* RX is using CPLL. */
+ if (RxPllType == XVPHY_PLL_TYPE_CPLL) {
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_RX, RxPllType);
+
+ if (XVphy_IsPllLocked(InstancePtr, 0, ChId) == XST_SUCCESS) {
+ /* Log, lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_CPLL_LOCK, 1);
+ /* 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;
+ }
+ }
+ }
+ else {
+ /* Log, Lost lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_CPLL_LOCK, 0);
+ }
+ }
+ /* TX is using CPLL. */
+ else {
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_TX, TxPllType);
+
+ if (XVphy_IsPllLocked(InstancePtr, 0, ChId) == XST_SUCCESS) {
+ /* Log, lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_CPLL_LOCK, 1);
+ /* 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;
+ }
+ }
+ else {
+ /* Log, Lost lock */
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_CPLL_LOCK, 0);
+ }
+ }
+}
+#endif
+
+/*****************************************************************************/
+/**
+* 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) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE4)) {
+ 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++) {
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id)].TxState =
+ XVPHY_GT_STATE_READY;
+
+ /* TX ready callback. */
+ if (InstancePtr->HdmiTxReadyCallback) {
+ InstancePtr->HdmiTxReadyCallback(
+ InstancePtr->HdmiTxReadyRef);
+ }
+ } else {
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+ XVphy_ClkDetTimerLoad(InstancePtr, 0, XVPHY_DIR_TX,
+ InstancePtr->Config.AxiLiteClkFreq/100);
+#endif
+
+ 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);
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+ /* Clear TX timer. */
+ XVphy_ClkDetTimerClear(InstancePtr, 0, XVPHY_DIR_TX);
+#endif
+
+
+ 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) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_TX, TRUE);
+ }
+
+ /* If the TX frequency has changed, the PLL is always disabled. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ XVphy_PowerDownGtPll(InstancePtr, 0,
+ (PllType == XVPHY_PLL_TYPE_CPLL) ?
+ XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA, 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);
+ }
+
+ /* Mask the MMCM Lock */
+ XVphy_MmcmLockedMaskEnable(InstancePtr, 0, XVPHY_DIR_TX, TRUE);
+
+ /* 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. */
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ 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,
+ InstancePtr->Config.AxiLiteClkFreq/1000);
+ }
+
+ /* 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;
+ }
+
+ /* Mask the MMCM Lock */
+ XVphy_MmcmLockedMaskEnable(InstancePtr, 0, 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+5000) / 10000;
+ RxRefClkHz = RxRefClkHz * 10000;
+
+ /* Store RX reference clock. */
+ InstancePtr->HdmiRxRefClkHz = RxRefClkHz;
+
+ /* If the RX frequency has changed, the PLL is always disabled. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ XVphy_PowerDownGtPll(InstancePtr, 0,
+ (PllType == XVPHY_PLL_TYPE_CPLL) ?
+ XVPHY_CHANNEL_ID_CHA : XVPHY_CHANNEL_ID_CMNA, TRUE);
+ }
+
+ XVphy_ResetGtPll(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,
+ TRUE);
+
+ /* 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);
+// if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) {
+// XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
+// XVPHY_DIR_TX, TRUE);
+// }
+
+ }
+
+ /* 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);
+ //}
+
+ /* Assert GT RX reset */
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTXE2) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_RX, FALSE);
+ }
+
+ /* 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.
+ * The reference clock should be larger than 25Mhz. We are using a 20Mhz
+ * instead to keep some margin for errors. */
+ if (RxRefClkHz > 20000000) {
+ XVphy_ClkDetTimerLoad(InstancePtr, 0, XVPHY_DIR_RX,
+ InstancePtr->Config.AxiLiteClkFreq/1000);
+
+ /* 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;
+
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTXE2)
+ /* Check if timer timed out while waiting for TX Alignment
+ * If yes, reset the GT TX
+ */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ if (InstancePtr->Quads[0].Plls[XVPHY_CH2IDX(Id0)].TxState ==
+ XVPHY_GT_STATE_ALIGN) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_TX_ALIGN_TMOUT, 1);
+ /* 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;
+ }
+ return;
+ }
+#endif
+
+ 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. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_TX, PllType);
+
+ /* Start TX MMCM. */
+ XVphy_MmcmStart(InstancePtr, 0, XVPHY_DIR_TX);
+
+ /* Enable PLL. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ 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);
+ }
+
+ XVphy_ClkReconfig(InstancePtr, 0, ChId);
+ XVphy_OutDivReconfig(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_TX);
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE4)) {
+ 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) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2)) {
+ 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) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE4)) {
+ /* 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. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_RX, PllType);
+
+ 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) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_GT_PLL_LAYOUT, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_PLL_LAYOUT, 1);
+ }
+
+ 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;
+ }
+ else {
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_PLL_LAYOUT, 0);
+ }
+
+ /* Enable PLL. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ 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. */
+ if (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2) {
+ 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));
+ }
+ /* GTP */
+ else {
+ XVphy_CfgPllRefClkSel(InstancePtr, 0,
+ ((PllType == XVPHY_PLL_TYPE_PLL0) ?
+ XVPHY_CHANNEL_ID_CMN0 : XVPHY_CHANNEL_ID_CMN1),
+ ((InstancePtr->HdmiRxDruIsEnabled) ?
+ InstancePtr->Config.DruRefClkSel :
+ InstancePtr->Config.RxRefClkSel));
+ }
+
+ /* Update GT DRU mode. */
+ XVphy_HdmiGtDruModeEnable(InstancePtr, InstancePtr->HdmiRxDruIsEnabled);
+
+ /* Update RefClk selection. */
+ XVphy_WriteCfgRefClkSelReg(InstancePtr, 0);
+
+ if (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) {
+ XVphy_ResetGtTxRx(InstancePtr, 0, XVPHY_CHANNEL_ID_CHA,
+ XVPHY_DIR_RX, TRUE);
+ /* GTP Wizard locks the DRP access to its internal FSM during reset */
+ /* Wait for reset sequence to release DRP port. */
+ XVphy_WaitUs(InstancePtr, 5000);
+ }
+
+ /* Determine PLL type. */
+ PllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
+ XVPHY_CHANNEL_ID_CH1);
+ /* Determine which channel(s) to operate on. */
+ ChId = XVphy_GetRcfgChId(InstancePtr, 0, XVPHY_DIR_RX, PllType);
+
+ 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);
+
+ /* 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) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_GT_UNBONDED, 1);
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_PLL_LAYOUT, 1);
+ }
+ else {
+ XVphy_CfgErrIntr(InstancePtr, XVPHY_ERRIRQ_PLL_LAYOUT, 0);
+ }
+ 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)) {
+#if (XPAR_VPHY_0_TRANSCEIVER == XVPHY_GTPE2)
+ if (Event & XVPHY_INTR_QPLL0_LOCK_MASK) { /* PLL0. */
+ XVphy_HdmiGtpPllLockHandler(InstancePtr, 0);
+ }
+ if (Event & XVPHY_INTR_QPLL1_LOCK_MASK) { /* PLL1. */
+ XVphy_HdmiGtpPllLockHandler(InstancePtr, 1);
+ }
+#else
+ XVphy_HdmiQpllLockHandler(InstancePtr);
+#endif
+ }
+#if (XPAR_VPHY_0_TRANSCEIVER != XVPHY_GTPE2)
+ if (Event & XVPHY_INTR_CPLL_LOCK_MASK) {
+ XVphy_HdmiCpllLockHandler(InstancePtr);
+ }
+#endif
+ 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);
+}
+#endif
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hw.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hw.h
new file mode 100644
index 00000000000000..6e06e8dc902ae2
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_hw.h
@@ -0,0 +1,567 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Added GTPE2 and GTHE4 support
+ * 1.4 gm 29/11/16 Added ERR_IRQ register offset
+ * </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_ERR_IRQ 0x03C
+#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_GTEASTREFCLK0 3
+#define XVPHY_REF_CLK_SEL_XPLL_GTEASTREFCLK1 4
+#define XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK0 5
+#define XVPHY_REF_CLK_SEL_XPLL_GTWESTREFCLK1 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_PLL0 0
+#define XVPHY_REF_CLK_SEL_XXSYSCLKSEL_DATA_PLL1 1
+#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) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0x03000000 : 0x02000000)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_MASK(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0x0C000000 : 0x08000000)
+#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_MASK(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0x30000000 : 0x01000000)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_MASK(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 0xC0000000 : 0x04000000)
+#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 24 : 25)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 26 : 27)
+#define XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 28 : 24)
+#define XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_SHIFT(G) \
+ ((((G) == XVPHY_GT_TYPE_GTHE3) || \
+ ((G) == XVPHY_GT_TYPE_GTHE4)) ? 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))
+#define XVPHY_PLL_LOCK_STATUS_CPLL_HDMI_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))
+/* 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
+#define XVPHY_MMCM_USRCLK_CTRL_LOCKED_MASK_MASK 0x800
+/* 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
+#define XVPHY_MISC_XXUSRCLK_REFCLK_CEB_MASK 0x2
+/* 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_ */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.c
new file mode 100644
index 00000000000000..99ba00e53f07df
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.c
@@ -0,0 +1,1441 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvphy_i.c
+ *
+ * Contains generic APIs that are locally called or used within the
+ * VPHY driver.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 gm, 11/09/16 Initial release.
+ * 1.4 gm 29/11/16 Fixed c++ compiler warnings
+ * Added xcvr adaptor functions for C++ compilations
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include <linux/string.h>
+#include "xstatus.h"
+#include "xvphy.h"
+#include "xvphy_i.h"
+#include "xvphy_hdmi.h"
+#include <linux/delay.h>
+#include "xvphy_gt.h"
+
+/**************************** Function Prototypes *****************************/
+
+
+/**************************** Function Definitions ****************************/
+
+/*****************************************************************************/
+/**
+* This function will enable or disable the LPM logic in the Video PHY core.
+*
+* @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 TX or RX.
+* @param Enable will enable (if 1) or disable (if 0) the LPM logic.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_SetRxLpm(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Enable)
+{
+ u32 RegVal;
+ u32 MaskVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+ Dir = Dir;
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_RX_EQ_CDR_REG);
+
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_RX_CONTROL_RXLPMEN_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_RX_CONTROL_RXLPMEN_MASK(ChId);
+ }
+
+ if (Enable) {
+ RegVal |= MaskVal;
+ }
+ else {
+ RegVal &= ~MaskVal;
+ }
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_RX_EQ_CDR_REG,
+ RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function will set the TX voltage swing value 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 Vs is the voltage swing value to write.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_SetTxVoltageSwing(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, u8 Vs)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if ((ChId == XVPHY_CHANNEL_ID_CH1) || (ChId == XVPHY_CHANNEL_ID_CH2)) {
+ RegOffset = XVPHY_TX_DRIVER_CH12_REG;
+ }
+ else {
+ RegOffset = XVPHY_TX_DRIVER_CH34_REG;
+ }
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+
+ MaskVal = XVPHY_TX_DRIVER_TXDIFFCTRL_MASK(ChId);
+ RegVal &= ~MaskVal;
+ RegVal |= (Vs << XVPHY_TX_DRIVER_TXDIFFCTRL_SHIFT(ChId));
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function will set the TX pre-emphasis value 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 Pe is the pre-emphasis value to write.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_SetTxPreEmphasis(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u8 Pe)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if ((ChId == XVPHY_CHANNEL_ID_CH1) || (ChId == XVPHY_CHANNEL_ID_CH2)) {
+ RegOffset = XVPHY_TX_DRIVER_CH12_REG;
+ }
+ else {
+ RegOffset = XVPHY_TX_DRIVER_CH34_REG;
+ }
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+
+ MaskVal = XVPHY_TX_DRIVER_TXPRECURSOR_MASK(ChId);
+ RegVal &= ~MaskVal;
+ RegVal |= (Pe << XVPHY_TX_DRIVER_TXPRECURSOR_SHIFT(ChId));
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function writes the current software configuration for the reference
+* clock selections to hardware for the specified quad on all channels.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_WriteCfgRefClkSelReg(XVphy *InstancePtr, u8 QuadId)
+{
+ u32 RegVal = 0;
+ XVphy_Channel *ChPtr;
+ XVphy_GtType GtType = InstancePtr->Config.XcvrType;
+
+ /* Point to the first channel since settings apply to all channels. */
+ ChPtr = &InstancePtr->Quads[QuadId].Ch1;
+
+ /* PllRefClkSel. */
+ /* - QPLL0. */
+ RegVal &= ~XVPHY_REF_CLK_SEL_QPLL0_MASK;
+ RegVal = InstancePtr->Quads[QuadId].Cmn0.PllRefClkSel;
+ /* - CPLL. */
+ RegVal &= ~XVPHY_REF_CLK_SEL_CPLL_MASK;
+ RegVal |= (ChPtr->CpllRefClkSel << XVPHY_REF_CLK_SEL_CPLL_SHIFT);
+ if ((GtType == XVPHY_GT_TYPE_GTHE3) ||
+ (GtType == XVPHY_GT_TYPE_GTHE4) ||
+ (GtType == XVPHY_GT_TYPE_GTPE2)) {
+ /* - QPLL1. */
+ RegVal &= ~XVPHY_REF_CLK_SEL_QPLL1_MASK;
+ RegVal |= (InstancePtr->Quads[QuadId].Cmn1.PllRefClkSel <<
+ XVPHY_REF_CLK_SEL_QPLL1_SHIFT);
+ }
+
+ /* SysClkDataSel. PLLCLKSEL */
+ RegVal &= ~XVPHY_REF_CLK_SEL_SYSCLKSEL_MASK;
+ /* - TXSYSCLKSEL[0]. TXPLLCLKSEL*/
+ RegVal |= (ChPtr->TxDataRefClkSel <<
+ XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_SHIFT(GtType)) &
+ XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_MASK(GtType);
+ /* - RXSYSCLKSEL[0]. RXPLLCLKSEL*/
+ RegVal |= (ChPtr->RxDataRefClkSel <<
+ XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_SHIFT(GtType)) &
+ XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_MASK(GtType);
+
+ /* SysClkOutSel. */
+ /* - TXSYSCLKSEL[1]. */
+ RegVal |= (ChPtr->TxOutRefClkSel <<
+ XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_SHIFT(GtType)) &
+ XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_MASK(GtType);
+ /* - RXSYSCLKSEL[1]. */
+ RegVal |= (ChPtr->RxOutRefClkSel <<
+ XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_SHIFT(GtType)) &
+ XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_MASK(GtType);
+
+ /* Write to hardware. */
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, XVPHY_REF_CLK_SEL_REG,
+ RegVal);
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* Configure the PLL reference clock selection for the specified channel(s).
+* This is applied to both direction to the software configuration only.
+*
+* @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 SysClkDataSel is the reference clock selection to configure.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_CfgPllRefClkSel(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_PllRefClkSelType RefClkSel)
+{
+ u8 Id, Id0, Id1;
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].PllRefClkSel =
+ RefClkSel;
+ }
+}
+
+/*****************************************************************************/
+/**
+* Configure the SYSCLKDATA reference clock selection for the direction. Same
+* configuration applies to all channels in the quad. This is applied to the
+* software configuration only.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param SysClkDataSel is the reference clock selection to configure.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_CfgSysClkDataSel(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_SysClkDataSelType SysClkDataSel)
+{
+ XVphy_Channel *ChPtr;
+ u8 Id, Id0, Id1;
+
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ /* Select in software - same for all channels. */
+ for (Id = Id0; Id <= Id1; Id++) {
+ ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)];
+ ChPtr->DataRefClkSel[Dir] = SysClkDataSel;
+ }
+}
+
+/*****************************************************************************/
+/**
+* Configure the SYSCLKOUT reference clock selection for the direction. Same
+* configuration applies to all channels in the quad. This is applied to the
+* software configuration only.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param SysClkOutSel is the reference clock selection to configure.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_CfgSysClkOutSel(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_SysClkOutSelType SysClkOutSel)
+{
+ XVphy_Channel *ChPtr;
+ u8 Id, Id0, Id1;
+
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ /* Select in software - same for all channels. */
+ for (Id = Id0; Id <= Id1; Id++) {
+ ChPtr = &InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)];
+ ChPtr->OutRefClkSel[Dir] = SysClkOutSel;
+ }
+}
+
+/*****************************************************************************/
+/**
+* Obtain the reconfiguration channel ID for given PLL type
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param PllType is the PLL type being used by the channel.
+*
+* @return The Channel ID to be used for reconfiguration
+*
+* @note None.
+*
+******************************************************************************/
+XVphy_ChannelId XVphy_GetRcfgChId(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_PllType PllType)
+{
+ XVphy_ChannelId ChId;
+
+ /* Suppress Warning Messages */
+ InstancePtr = InstancePtr;
+ QuadId = QuadId;
+ Dir = Dir;
+
+ /* Determine which channel(s) to operate on. */
+ switch (PllType) {
+ case XVPHY_PLL_TYPE_QPLL:
+ case XVPHY_PLL_TYPE_QPLL0:
+ case XVPHY_PLL_TYPE_PLL0:
+ ChId = XVPHY_CHANNEL_ID_CMN0;
+ break;
+ case XVPHY_PLL_TYPE_QPLL1:
+ case XVPHY_PLL_TYPE_PLL1:
+ ChId = XVPHY_CHANNEL_ID_CMN1;
+ break;
+ default:
+ ChId = XVPHY_CHANNEL_ID_CHA;
+ break;
+ }
+
+ return ChId;
+}
+
+/*****************************************************************************/
+/**
+* Obtain the current reference clock frequency for the quad based on the
+* reference clock type.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param RefClkType is the type to obtain the clock selection for.
+*
+* @return The current reference clock frequency for the quad for the
+* specified type selection.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_GetQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
+ XVphy_PllRefClkSelType RefClkType)
+{
+ u32 FreqHz;
+
+ u8 RefClkIndex = RefClkType - XVPHY_PLL_REFCLKSEL_TYPE_GTREFCLK0;
+
+ FreqHz = (RefClkType > XVPHY_PLL_REFCLKSEL_TYPE_GTGREFCLK) ? 0 :
+ InstancePtr->Quads[QuadId].RefClkHz[RefClkIndex];
+
+ return FreqHz;
+}
+
+/*****************************************************************************/
+/**
+* Obtain the current [RT]XSYSCLKSEL[0] configuration.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param ChId is the channel ID which to operate on.
+*
+* @return The current [RT]XSYSCLKSEL[0] selection.
+*
+* @note None.
+*
+******************************************************************************/
+XVphy_SysClkDataSelType XVphy_GetSysClkDataSel(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_ChannelId ChId)
+{
+ u32 Sel;
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+ ChId = ChId;
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_REF_CLK_SEL_REG);
+
+ if (Dir == XVPHY_DIR_TX) {
+ /* Synchronize software configuration to hardware. */
+ Sel = RegVal & XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_MASK(
+ InstancePtr->Config.XcvrType);
+ Sel >>= XVPHY_REF_CLK_SEL_TXSYSCLKSEL_DATA_SHIFT(
+ InstancePtr->Config.XcvrType);
+ }
+ else {
+ /* Synchronize software configuration to hardware. */
+ Sel = RegVal & XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_MASK(
+ InstancePtr->Config.XcvrType);
+ Sel >>= XVPHY_REF_CLK_SEL_RXSYSCLKSEL_DATA_SHIFT(
+ InstancePtr->Config.XcvrType);
+ }
+
+ return (XVphy_SysClkDataSelType) Sel;
+}
+
+/*****************************************************************************/
+/**
+* Obtain the current [RT]XSYSCLKSEL[1] configuration.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param ChId is the channel ID which to operate on.
+*
+* @return The current [RT]XSYSCLKSEL[1] selection.
+*
+* @note None.
+*
+******************************************************************************/
+XVphy_SysClkOutSelType XVphy_GetSysClkOutSel(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_ChannelId ChId)
+{
+ u32 Sel;
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+ ChId = ChId;
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_REF_CLK_SEL_REG);
+
+ if (Dir == XVPHY_DIR_TX) {
+ /* Synchronize software configuration to hardware. */
+ Sel = RegVal & XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_MASK(
+ InstancePtr->Config.XcvrType);
+ Sel >>= XVPHY_REF_CLK_SEL_TXSYSCLKSEL_OUT_SHIFT(
+ InstancePtr->Config.XcvrType);
+ }
+ else {
+ /* Synchronize software configuration to hardware. */
+ Sel = RegVal & XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_MASK(
+ InstancePtr->Config.XcvrType);
+ Sel >>= XVPHY_REF_CLK_SEL_RXSYSCLKSEL_OUT_SHIFT(
+ InstancePtr->Config.XcvrType);
+ }
+
+ return (XVphy_SysClkOutSelType)Sel;
+}
+
+/*****************************************************************************/
+/**
+* This function will check the status of a PLL lock on the specified 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 which to operate on.
+*
+* @return
+* - XST_SUCCESS if the specified PLL is locked.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_IsPllLocked(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ XVphy_PllType TxPllType;
+ XVphy_PllType RxPllType;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (ChId == XVPHY_CHANNEL_ID_CMN0) {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_QPLL0_MASK;
+ }
+ else if (ChId == XVPHY_CHANNEL_ID_CMN1) {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_QPLL1_MASK;
+ }
+ else if (ChId == XVPHY_CHANNEL_ID_CMNA) {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_QPLL0_MASK |
+ XVPHY_PLL_LOCK_STATUS_QPLL1_MASK;
+ }
+ else if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ TxPllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_TX,
+ XVPHY_CHANNEL_ID_CH1);
+ RxPllType = XVphy_GetPllType(InstancePtr, 0, XVPHY_DIR_RX,
+ XVPHY_CHANNEL_ID_CH1);
+ if (RxPllType == XVPHY_PLL_TYPE_CPLL &&
+ InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_CPLL_HDMI_MASK;
+ }
+ else if (TxPllType == XVPHY_PLL_TYPE_CPLL &&
+ InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_HDMI) {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_CPLL_HDMI_MASK;
+ }
+ else {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_CPLL_ALL_MASK;
+ }
+ }
+ else {
+ MaskVal = XVPHY_PLL_LOCK_STATUS_CPLL_MASK(ChId);
+ }
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_PLL_LOCK_STATUS_REG);
+
+ if ((RegVal & MaskVal) == MaskVal) {
+ return XST_SUCCESS;
+ }
+
+ return XST_FAILURE;
+}
+
+/*****************************************************************************/
+/**
+* This function will reset and enable the Video PHY's user core logic.
+*
+* @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 which to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param Hold is an indicator whether to "hold" the reset if set to 1.
+* If set to 0: reset, then enable.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_GtUserRdyEnable(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Hold)
+{
+ u32 RegVal;
+ u32 MaskVal;
+ u32 RegOffset;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_TX_INIT_REG;
+
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_TX_INIT_USERRDY_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_TX_INIT_USERRDY_MASK(ChId);
+ }
+ }
+ else {
+ RegOffset = XVPHY_RX_INIT_REG;
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ MaskVal = XVPHY_RX_INIT_USERRDY_ALL_MASK;
+ }
+ else {
+ MaskVal = XVPHY_RX_INIT_USERRDY_MASK(ChId);
+ }
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ /* Assert reset. */
+ RegVal |= MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+
+ if (!Hold) {
+ /* De-assert reset. */
+ RegVal &= ~MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function will reset the mixed-mode clock manager (MMCM) core.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param Hold is an indicator whether to "hold" the reset if set to 1.
+* If set to 0: reset, then enable.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_MmcmReset(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Hold)
+{
+ u32 RegOffsetCtrl;
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffsetCtrl = XVPHY_MMCM_TXUSRCLK_CTRL_REG;
+ }
+ else {
+ RegOffsetCtrl = XVPHY_MMCM_RXUSRCLK_CTRL_REG;
+ }
+
+ /* Assert reset. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl);
+ RegVal |= XVPHY_MMCM_USRCLK_CTRL_RST_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl, RegVal);
+
+ if (!Hold) {
+ /* De-assert reset. */
+ RegVal &= ~XVPHY_MMCM_USRCLK_CTRL_RST_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl,
+ RegVal);
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function will reset the mixed-mode clock manager (MMCM) core.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+* @param Enable is an indicator whether to "Enable" the locked mask
+* if set to 1. If set to 0: reset, then disable.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XVphy_MmcmLockedMaskEnable(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, u8 Enable)
+{
+ u32 RegOffsetCtrl;
+ u32 RegVal;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffsetCtrl = XVPHY_MMCM_TXUSRCLK_CTRL_REG;
+ }
+ else {
+ RegOffsetCtrl = XVPHY_MMCM_RXUSRCLK_CTRL_REG;
+ }
+
+ /* Assert reset. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl);
+ RegVal |= XVPHY_MMCM_USRCLK_CTRL_LOCKED_MASK_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl, RegVal);
+
+ if (!Enable) {
+ /* De-assert reset. */
+ RegVal &= ~XVPHY_MMCM_USRCLK_CTRL_LOCKED_MASK_MASK;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffsetCtrl,
+ RegVal);
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function obtains the divider value of the BUFG_GT peripheral.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param Dir is an indicator for TX or RX
+* @param Div 3-bit divider value
+*
+* @return None.
+*
+******************************************************************************/
+void XVphy_SetBufgGtDiv(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Div)
+{
+ u32 RegVal;
+ u32 RegOffset;
+ u8 Divider = Div;
+
+ if (Divider == 0) {
+ Divider = 1;
+ }
+ else {
+ Divider = Divider - 1;
+ }
+
+
+ if (Dir == XVPHY_DIR_TX) {
+ RegOffset = XVPHY_BUFGGT_TXUSRCLK_REG;
+ }
+ else {
+ RegOffset = XVPHY_BUFGGT_RXUSRCLK_REG;
+ }
+
+ /* Read BUFG_GT register. */
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr, RegOffset);
+ RegVal &= ~XVPHY_BUFGGT_XXUSRCLK_DIV_MASK;
+
+ /* Shift divider value to correct position. */
+ Divider <<= XVPHY_BUFGGT_XXUSRCLK_DIV_SHIFT;
+ Divider &= XVPHY_BUFGGT_XXUSRCLK_DIV_MASK;
+ RegVal |= Divider;
+
+ /* Write new value to BUFG_GT ctrl register. */
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr, RegOffset, RegVal);
+}
+
+/*****************************************************************************/
+/**
+* This function will power down the specified GT PLL.
+*
+* @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 power down the PLL for.
+* @param Dir is an indicator for TX or RX.
+* @param Hold is an indicator whether to "hold" the power down if set
+* to 1. If set to 0: power down, then power back up.
+*
+* @return
+* - XST_SUCCESS.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_PowerDownGtPll(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u8 Hold)
+{
+ u32 MaskVal = 0;
+ u32 RegVal;
+ u8 Id, Id0, Id1;
+
+ /* Suppress Warning Messages */
+ QuadId = QuadId;
+
+ if (XVPHY_ISCH(ChId)) {
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ }
+ else {
+ /* When powering down a QPLL, power down for all channels. */
+ XVphy_Ch2Ids(InstancePtr, XVPHY_CHANNEL_ID_CHA, &Id0, &Id1);
+ }
+ for (Id = Id0; Id <= Id1; Id++) {
+ if (ChId == XVPHY_CHANNEL_ID_CMN0) {
+ MaskVal |= XVPHY_POWERDOWN_CONTROL_QPLL0PD_MASK(Id);
+ }
+ else if (ChId == XVPHY_CHANNEL_ID_CMN1) {
+ MaskVal |= XVPHY_POWERDOWN_CONTROL_QPLL1PD_MASK(Id);
+ }
+ else if (ChId == XVPHY_CHANNEL_ID_CMNA) {
+ MaskVal |= XVPHY_POWERDOWN_CONTROL_QPLL0PD_MASK(Id) |
+ XVPHY_POWERDOWN_CONTROL_QPLL1PD_MASK(Id);
+ }
+ else {
+ MaskVal |= XVPHY_POWERDOWN_CONTROL_CPLLPD_MASK(Id);
+ }
+ }
+
+ RegVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_POWERDOWN_CONTROL_REG);
+ RegVal |= MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr,
+ XVPHY_POWERDOWN_CONTROL_REG, RegVal);
+
+ if (!Hold) {
+ RegVal &= ~MaskVal;
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr,
+ XVPHY_POWERDOWN_CONTROL_REG, RegVal);
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function will try to find the necessary PLL divisor values to produce
+* the configured line rate given the specified PLL input frequency. This will
+* be done for all channels specified by ChId.
+* This function is a wrapper for XVphy_PllCalculator.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to calculate the PLL values for.
+* @param ChId is the channel ID to calculate the PLL values for.
+* @param Dir is an indicator for TX or RX.
+* @param PllClkInFreqHz is the PLL input frequency on which to base the
+* calculations on. A value of 0 indicates to use the currently
+* configured quad PLL reference clock. A non-zero value indicates
+* to ignore what is currently configured in SW, and use a custom
+* frequency instead.
+*
+* @return
+* - XST_SUCCESS if valid PLL values were found to satisfy the
+* constraints.
+* - XST_FAILURE otherwise.
+*
+* @note If successful, the channel's PllParams structure will be
+* modified with the valid PLL parameters.
+*
+******************************************************************************/
+u32 XVphy_ClkCalcParams(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u32 PllClkInFreqHz)
+{
+ u32 Status = XST_SUCCESS;
+ u8 Id, Id0, Id1;
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ Status = XVphy_PllCalculator(InstancePtr, QuadId,
+ (XVphy_ChannelId)Id, Dir, PllClkInFreqHz);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function will set the current output divider configuration over DRP.
+*
+* @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 for which to write the settings for.
+* @param Dir is an indicator for RX or TX.
+*
+* @return
+* - XST_SUCCESS if the configuration was successful.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_OutDivReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir)
+{
+ u32 Status;
+ u8 Id;
+ u8 Id0;
+ u8 Id1;
+
+ if (!XVPHY_ISCH(ChId)) {
+ ChId = XVPHY_CHANNEL_ID_CHA;
+ }
+
+ XVphy_LogWrite(InstancePtr, (Dir == XVPHY_DIR_TX) ?
+ XVPHY_LOG_EVT_GT_TX_RECONFIG : XVPHY_LOG_EVT_GT_RX_RECONFIG, 0);
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ Status = XVphy_OutDivChReconfig(InstancePtr, QuadId,
+ (XVphy_ChannelId)Id, Dir);
+ if (Status != XST_SUCCESS) {
+ break;
+ }
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function will set the current RX/TX configuration over DRP.
+*
+* @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 for which to write the settings for.
+* @param Dir is an indicator for RX or TX.
+*
+* @return
+* - XST_SUCCESS if the configuration was successful.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_DirReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir)
+{
+ u32 Status = XST_SUCCESS;
+ u8 Id, Id0, Id1;
+
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE2) &&
+ (Dir == XVPHY_DIR_TX)) {
+ return XST_SUCCESS;
+ }
+
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) &&
+ ((InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_DP) ||
+ (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_DP))) {
+ ChId = XVPHY_CHANNEL_ID_CHA;
+ }
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ if (Dir == XVPHY_DIR_TX) {
+ Status = XVphy_TxChReconfig(InstancePtr, QuadId,
+ (XVphy_ChannelId)Id);
+ }
+ else {
+ Status = XVphy_RxChReconfig(InstancePtr, QuadId,
+ (XVphy_ChannelId)Id);
+ }
+ if (Status != XST_SUCCESS) {
+ break;
+ }
+ }
+
+ XVphy_LogWrite(InstancePtr, (Dir == XVPHY_DIR_TX) ?
+ XVPHY_LOG_EVT_GT_TX_RECONFIG : XVPHY_LOG_EVT_GT_RX_RECONFIG, 1);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function will set the current clocking settings for each channel to
+* hardware based on the configuration stored in the driver's instance.
+*
+* @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 for which to write the settings for.
+*
+* @return
+* - XST_SUCCESS if the configuration was successful.
+* - XST_FAILURE otherwise.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XVphy_ClkReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ u32 Status;
+ u8 Id;
+ u8 Id0;
+ u8 Id1;
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ if (XVPHY_ISCH(Id)) {
+ Status = XVphy_ClkChReconfig(InstancePtr, QuadId,
+ (XVphy_ChannelId)Id);
+ }
+ else if (XVPHY_ISCMN(ChId)) {
+ Status = XVphy_ClkCmnReconfig(InstancePtr, QuadId,
+ (XVphy_ChannelId)Id);
+ }
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+ }
+
+ if (XVPHY_ISCH(Id)) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_CPLL_RECONFIG, 1);
+ }
+ else if (XVPHY_ISCMN(ChId) &&
+ (InstancePtr->Config.XcvrType != XVPHY_GT_TYPE_GTPE2)) {
+ XVphy_LogWrite(InstancePtr, XVPHY_LOG_EVT_QPLL_RECONFIG, 1);
+ }
+ else if (XVPHY_ISCMN(ChId)) { /* GTPE2. */
+ XVphy_LogWrite(InstancePtr, (ChId == XVPHY_CHANNEL_ID_CMN0) ?
+ XVPHY_LOG_EVT_PLL0_RECONFIG :
+ XVPHY_LOG_EVT_PLL1_RECONFIG, 1);
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function will set the channel IDs to correspond with the supplied
+* channel ID based on the protocol. HDMI uses 3 channels; DP uses 4. This ID
+* translation is done to allow other functions to operate iteratively over
+* multiple channels.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param ChId is the channel ID used to determine the indices.
+* @param Id0 is a pointer to the start channel ID to set.
+* @param Id1 is a pointer to the end channel ID to set.
+*
+* @return None.
+*
+* @note The contents of Id0 and Id1 will be set according to ChId.
+*
+******************************************************************************/
+void XVphy_Ch2Ids(XVphy *InstancePtr, XVphy_ChannelId ChId,
+ u8 *Id0, u8 *Id1)
+{
+ u8 Channels = 4;
+
+ if (ChId == XVPHY_CHANNEL_ID_CHA) {
+ *Id0 = XVPHY_CHANNEL_ID_CH1;
+ if ((InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_HDMI) ||
+ (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI)) {
+ *Id1 = XVPHY_CHANNEL_ID_CH3;
+ }
+ else {
+ Channels = ((InstancePtr->Config.TxChannels >=
+ InstancePtr->Config.RxChannels) ?
+ InstancePtr->Config.TxChannels :
+ InstancePtr->Config.RxChannels);
+
+ if (Channels == 1) {
+ *Id1 = XVPHY_CHANNEL_ID_CH1;
+ }
+ else if (Channels == 2) {
+ *Id1 = XVPHY_CHANNEL_ID_CH2;
+ }
+ else if (Channels == 3) {
+ *Id1 = XVPHY_CHANNEL_ID_CH3;
+ }
+ else {
+ *Id1 = XVPHY_CHANNEL_ID_CH4;
+ }
+ }
+ }
+ else if (ChId == XVPHY_CHANNEL_ID_CMNA) {
+ *Id0 = XVPHY_CHANNEL_ID_CMN0;
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE3) ||
+ (InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTHE4)) {
+ *Id1 = XVPHY_CHANNEL_ID_CMN1;
+ }
+ else {
+ *Id1 = XVPHY_CHANNEL_ID_CMN0;
+ }
+ }
+ else {
+ *Id0 = *Id1 = ChId;
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function will translate from XVphy_PllType to XVphy_SysClkDataSelType.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+*
+* @return The reference clock type based on the PLL selection.
+*
+* @note None.
+*
+******************************************************************************/
+XVphy_SysClkDataSelType Pll2SysClkData(XVphy_PllType PllSelect)
+{
+ return (PllSelect == XVPHY_PLL_TYPE_CPLL) ?
+ XVPHY_SYSCLKSELDATA_TYPE_CPLL_OUTCLK :
+ (PllSelect == XVPHY_PLL_TYPE_QPLL) ?
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL_OUTCLK :
+ (PllSelect == XVPHY_PLL_TYPE_QPLL0) ?
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL0_OUTCLK :
+ (PllSelect == XVPHY_PLL_TYPE_QPLL1) ?
+ XVPHY_SYSCLKSELDATA_TYPE_QPLL1_OUTCLK :
+ (PllSelect == XVPHY_PLL_TYPE_PLL0) ?
+ XVPHY_SYSCLKSELDATA_TYPE_PLL0_OUTCLK :
+ XVPHY_SYSCLKSELDATA_TYPE_PLL1_OUTCLK;
+}
+
+/*****************************************************************************/
+/**
+* This function will translate from XVphy_PllType to XVphy_SysClkOutSelType.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+*
+* @return The reference clock type based on the PLL selection.
+*
+* @note None.
+*
+******************************************************************************/
+XVphy_SysClkOutSelType Pll2SysClkOut(XVphy_PllType PllSelect)
+{
+ return (PllSelect == XVPHY_PLL_TYPE_CPLL) ?
+ XVPHY_SYSCLKSELOUT_TYPE_CPLL_REFCLK :
+ (PllSelect == XVPHY_PLL_TYPE_QPLL) ?
+ XVPHY_SYSCLKSELOUT_TYPE_QPLL_REFCLK :
+ (PllSelect == XVPHY_PLL_TYPE_QPLL0) ?
+ XVPHY_SYSCLKSELOUT_TYPE_QPLL0_REFCLK :
+ (PllSelect == XVPHY_PLL_TYPE_QPLL1) ?
+ XVPHY_SYSCLKSELOUT_TYPE_QPLL1_REFCLK :
+ (PllSelect == XVPHY_PLL_TYPE_PLL0) ?
+ XVPHY_SYSCLKSELOUT_TYPE_PLL0_REFCLK :
+ XVPHY_SYSCLKSELOUT_TYPE_PLL1_REFCLK;
+}
+
+/*****************************************************************************/
+/**
+* This function will try to find the necessary PLL divisor values to produce
+* the configured line rate given the specified PLL input frequency.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to calculate the PLL values for.
+* @param ChId is the channel ID to calculate the PLL values for.
+* @param Dir is an indicator for TX or RX.
+* @param PllClkInFreqHz is the PLL input frequency on which to base the
+* calculations on. A value of 0 indicates to use the currently
+* configured quad PLL reference clock. A non-zero value indicates
+* to ignore what is currently configured in SW, and use a custom
+* frequency instead.
+*
+* @return
+* - XST_SUCCESS if valid PLL values were found to satisfy the
+* constraints.
+* - XST_FAILURE otherwise.
+*
+* @note If successful, the channel's PllParams structure will be
+* modified with the valid PLL parameters.
+*
+******************************************************************************/
+u32 XVphy_PllCalculator(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir,
+ u32 PllClkInFreqHz)
+{
+ u32 Status;
+ u64 PllClkOutFreqHz;
+ u64 CalcLineRateFreqHz;
+ u8 Id, Id0, Id1;
+ u64 PllClkInFreqHzIn = PllClkInFreqHz;
+ XVphy_Channel *PllPtr = &InstancePtr->Quads[QuadId].
+ Plls[XVPHY_CH2IDX(ChId)];
+
+ if (!PllClkInFreqHzIn) {
+ PllClkInFreqHzIn = XVphy_GetQuadRefClkFreq(InstancePtr, QuadId,
+ PllPtr->PllRefClkSel);
+ }
+
+ /* Select PLL value table offsets. */
+ const XVphy_GtPllDivs *GtPllDivs;
+ if (XVPHY_ISCH(ChId)) {
+ GtPllDivs = &InstancePtr->GtAdaptor->CpllDivs;
+ }
+ else {
+ GtPllDivs = &InstancePtr->GtAdaptor->QpllDivs;
+ }
+
+ const u8 *M, *N1, *N2, *D;
+ for (N2 = GtPllDivs->N2; *N2 != 0; N2++) {
+ for (N1 = GtPllDivs->N1; *N1 != 0; N1++) {
+ for (M = GtPllDivs->M; *M != 0; M++) {
+ PllClkOutFreqHz = (PllClkInFreqHzIn * *N1 * *N2) / *M;
+
+ /* Test if the calculated PLL clock is in the VCO range. */
+ Status = XVphy_CheckPllOpRange(InstancePtr, QuadId, ChId,
+ PllClkOutFreqHz);
+ if (Status != XST_SUCCESS) {
+ continue;
+ }
+
+ if ((InstancePtr->Config.XcvrType == XVPHY_GT_TYPE_GTPE2) ||
+ (XVPHY_ISCH(ChId))) {
+ PllClkOutFreqHz *= 2;
+ }
+ /* Apply TX/RX divisor. */
+ for (D = GtPllDivs->D; *D != 0; D++) {
+ CalcLineRateFreqHz = PllClkOutFreqHz / *D;
+ if (CalcLineRateFreqHz == PllPtr->LineRateHz) {
+ goto calc_done;
+ }
+ }
+ }
+ }
+ }
+ /* Calculation failed, don't change divisor settings. */
+ return XST_FAILURE;
+
+calc_done:
+ /* Found the multiplier and divisor values for requested line rate. */
+ PllPtr->PllParams.MRefClkDiv = *M;
+ PllPtr->PllParams.NFbDiv = *N1;
+ PllPtr->PllParams.N2FbDiv = *N2; /* Won't be used for QPLL.*/
+ PllPtr->PllParams.IsLowerBand = 1; /* Won't be used for CPLL. */
+
+ if (XVPHY_ISCMN(ChId)) {
+ /* Same divisor value for all channels if using a QPLL. */
+ ChId = XVPHY_CHANNEL_ID_CHA;
+ }
+
+ XVphy_Ch2Ids(InstancePtr, ChId, &Id0, &Id1);
+ for (Id = Id0; Id <= Id1; Id++) {
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(Id)].OutDiv[Dir] =
+ *D;
+ if (Dir == XVPHY_DIR_RX) {
+ XVphy_CfgSetCdr(InstancePtr, QuadId, (XVphy_ChannelId)Id);
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function calculates the PLL VCO operating frequency.
+*
+* @param InstancePtr is a pointer to the XVphy core instance.
+* @param QuadId is the GT quad ID to operate on.
+* @param Dir is an indicator for TX or RX.
+*
+* @return PLL VCO frequency in Hz
+*
+* @note None.
+*
+******************************************************************************/
+u64 XVphy_GetPllVcoFreqHz(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir)
+{
+ u64 PllxVcoRateHz;
+ u64 PllRefClkHz;
+ XVphy_Channel *PllPtr = &InstancePtr->Quads[QuadId].
+ Plls[XVPHY_CH2IDX(ChId)];
+
+ if (Dir == XVPHY_DIR_TX) {
+ if (InstancePtr->Config.TxProtocol == XVPHY_PROTOCOL_HDMI) {
+ PllRefClkHz = InstancePtr->HdmiTxRefClkHz;
+ }
+ else {
+ PllRefClkHz = XVphy_GetQuadRefClkFreq(InstancePtr, QuadId,
+ PllPtr->PllRefClkSel);
+ }
+ }
+ else {
+ if (InstancePtr->Config.RxProtocol == XVPHY_PROTOCOL_HDMI) {
+#if defined (XPAR_XV_HDMITX_0_DEVICE_ID) || defined (XPAR_XV_HDMIRX_0_DEVICE_ID)
+ if (InstancePtr->HdmiRxDruIsEnabled) {
+ PllRefClkHz = XVphy_DruGetRefClkFreqHz(InstancePtr);
+ }
+ else {
+ PllRefClkHz = InstancePtr->HdmiRxRefClkHz;
+ }
+#else
+ PllRefClkHz = 0;
+#endif
+ }
+ else {
+ PllRefClkHz = XVphy_GetQuadRefClkFreq(InstancePtr, QuadId,
+ PllPtr->PllRefClkSel);
+ }
+ }
+
+ PllxVcoRateHz = (PllRefClkHz *
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
+ PllParams.N1FbDiv *
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
+ PllParams.N2FbDiv) /
+ InstancePtr->Quads[QuadId].Plls[XVPHY_CH2IDX(ChId)].
+ PllParams.MRefClkDiv;
+
+ return PllxVcoRateHz;
+}
+
+#ifdef __cplusplus
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to 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_CfgSetCdr(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ return InstancePtr->GtAdaptor->CfgSetCdr(InstancePtr, QuadId, ChId);
+}
+
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to 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_CheckPllOpRange(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, u64 PllClkOutFreqHz)
+{
+ return InstancePtr->GtAdaptor->CheckPllOpRange(InstancePtr, QuadId, ChId,
+ PllClkOutFreqHz);
+}
+
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to 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_OutDivChReconfig(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir)
+{
+ return InstancePtr->GtAdaptor->OutDivChReconfig(InstancePtr, QuadId,
+ ChId, Dir);
+}
+
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to 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_ClkChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ return InstancePtr->GtAdaptor->ClkChReconfig(InstancePtr, QuadId, ChId);
+}
+
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to 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_ClkCmnReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ return InstancePtr->GtAdaptor->ClkCmnReconfig(InstancePtr, QuadId, ChId);
+}
+
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to 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_RxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ return InstancePtr->GtAdaptor->RxChReconfig(InstancePtr, QuadId, ChId);
+}
+
+/*****************************************************************************/
+/**
+* This function is a transceiver adaptor to configure the channel's
+* TX 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_TxChReconfig(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId)
+{
+ return InstancePtr->GtAdaptor->TxChReconfig(InstancePtr, QuadId, ChId);
+}
+#endif
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.h b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.h
new file mode 100644
index 00000000000000..ec6d424cf1a470
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_i.h
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @file xvphy_i.h
+ *
+ * Contains generic APIs that are locally called or used within the
+ * VPHY driver.
+ *
+ * @note None.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * Ver Who Date Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0 gm, 11/09/16 Initial release.
+ * 1.4 gm 11/24/16 Made debug log optional (can be disabled via makefile)
+ * </pre>
+ *
+*******************************************************************************/
+
+#ifndef XVPHY_I_H_
+/* Prevent circular inclusions by using protection macros. */
+#define XVPHY_I_H_
+
+/******************************* Include Files ********************************/
+
+#include "xil_assert.h"
+#include "xvphy.h"
+#include "xvphy_hw.h"
+#include "xvidc.h"
+//#include "xvphy_dp.h"
+
+/****************************** Type Definitions ******************************/
+
+
+/**************************** Function Prototypes *****************************/
+
+
+void XVphy_Ch2Ids(XVphy *InstancePtr, XVphy_ChannelId ChId,
+ u8 *Id0, u8 *Id1);
+XVphy_SysClkDataSelType Pll2SysClkData(XVphy_PllType PllSelect);
+XVphy_SysClkOutSelType Pll2SysClkOut(XVphy_PllType PllSelect);
+u32 XVphy_PllCalculator(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir,
+ u32 PllClkInFreqHz);
+
+/* 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);
+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_ChannelId XVphy_GetRcfgChId(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, XVphy_PllType PllType);
+u32 XVphy_GetQuadRefClkFreq(XVphy *InstancePtr, u8 QuadId,
+ XVphy_PllRefClkSelType RefClkType);
+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);
+u32 XVphy_IsPllLocked(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId);
+u32 XVphy_GtUserRdyEnable(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ XVphy_DirectionType Dir, u8 Hold);
+
+/* xvphy.c: GT/MMCM DRP access. */
+void XVphy_MmcmReset(XVphy *InstancePtr, u8 QuadId, XVphy_DirectionType Dir,
+ u8 Hold);
+void XVphy_MmcmLockedMaskEnable(XVphy *InstancePtr, u8 QuadId,
+ XVphy_DirectionType Dir, u8 Enable);
+void XVphy_SetBufgGtDiv(XVphy *InstancePtr, XVphy_DirectionType Dir, u8 Div);
+/* xvphy.c Miscellaneous control. */
+u32 XVphy_PowerDownGtPll(XVphy *InstancePtr, u8 QuadId, XVphy_ChannelId ChId,
+ u8 Hold);
+
+
+/* xvphy_intr.c: Interrupt handling functions. */
+void XVphy_SetIntrHandler(XVphy *InstancePtr, XVphy_IntrHandlerType HandlerType,
+ XVphy_IntrHandler CallbackFunc, void *CallbackRef);
+void XVphy_IntrEnable(XVphy *InstancePtr, XVphy_IntrHandlerType Intr);
+void XVphy_IntrDisable(XVphy *InstancePtr, XVphy_IntrHandlerType Intr);
+void XVphy_CfgErrIntr(XVphy *InstancePtr, XVphy_ErrIrqType ErrIrq, u8 Set);
+
+u64 XVphy_GetPllVcoFreqHz(XVphy *InstancePtr, u8 QuadId,
+ XVphy_ChannelId ChId, XVphy_DirectionType Dir);
+
+/******************* Macros (Inline Functions) Definitions ********************/
+
+#endif /* XVPHY_I_H_ */
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_intr.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_intr.c
new file mode 100644
index 00000000000000..11f2b55dd4c271
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_intr.c
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.4 gm 29/11/16 Added XVphy_CfgErrIntr for ERR_IRQ impl
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include "xvphy.h"
+#include "xvphy_i.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);
+ }
+}
+
+/******************************************************************************/
+/**
+ * This function configures the error IRQ register based on the condition
+ * to generate an ERR_IRQ event
+ *
+ * @param InstancePtr is a pointer to the XVphy instance.
+ * ErrIrq is the IRQ type as define in XVphy_ErrIrqType
+ * Set is the flag to set or clear the ErrIrq param
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+*******************************************************************************/
+void XVphy_CfgErrIntr(XVphy *InstancePtr, XVphy_ErrIrqType ErrIrq, u8 Set)
+{
+ u32 ErrIrqVal;
+ u32 WriteVal;
+
+ ErrIrqVal = XVphy_ReadReg(InstancePtr->Config.BaseAddr,
+ XVPHY_ERR_IRQ);
+
+ WriteVal = (u32)ErrIrq;
+
+ if (Set) {
+ ErrIrqVal |= WriteVal;
+ }
+ else {
+ ErrIrqVal &= ~WriteVal;
+ }
+
+ XVphy_WriteReg(InstancePtr->Config.BaseAddr,
+ XVPHY_ERR_IRQ, ErrIrqVal);
+}
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_log.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_log.c
new file mode 100644
index 00000000000000..4c256198eb1c28
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_log.c
@@ -0,0 +1,467 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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.
+ * 1.1 gm 02/01/16 Additional events for event log printout
+ * 1.2 gm Added log events for debugging
+ * 1.4 gm 11/24/16 Made debug log optional (can be disabled via makefile)
+ * Added XVPHY_LOG_EVT_TX_ALIGN_TMOUT log event
+ * </pre>
+ *
+*******************************************************************************/
+
+/******************************* Include Files ********************************/
+
+#include "xvphy.h"
+#include "xvphy_i.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)
+{
+#ifdef XV_VPHY_LOG_ENABLE
+ /* Verify arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+
+ InstancePtr->Log.HeadIndex = 0;
+ InstancePtr->Log.TailIndex = 0;
+#endif
+}
+
+#ifdef XV_VPHY_LOG_ENABLE
+/*****************************************************************************/
+/**
+* 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_DUMMY));
+ 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++;
+ }
+ }
+}
+#endif
+
+/*****************************************************************************/
+/**
+* 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)
+{
+#ifdef XV_VPHY_LOG_ENABLE
+ 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;
+#endif
+}
+
+/*****************************************************************************/
+/**
+* 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)
+{
+#ifdef XV_VPHY_LOG_ENABLE
+ 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");
+
+ /* Read log data */
+ Log = XVphy_LogRead(InstancePtr);
+
+ while (Log != 0) {
+ /* 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("TX alignment done\r\n");
+ }
+ else {
+ xil_printf("TX alignment start.\r\n.");
+ }
+ break;
+ case (XVPHY_LOG_EVT_TX_ALIGN_TMOUT):
+ xil_printf("TX alignment watchdog timed out.\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("CPLL reconfig done\r\n");
+ }
+ else {
+ xil_printf("CPLL reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_GT_RECONFIG):
+ if (Data == 1) {
+ xil_printf("GT reconfig done\r\n");
+ }
+ else {
+ xil_printf("GT reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_GT_TX_RECONFIG):
+ if (Data == 1) {
+ xil_printf("GT TX reconfig done\r\n");
+ }
+ else {
+ xil_printf("GT TX reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_GT_RX_RECONFIG):
+ if (Data == 1) {
+ xil_printf("GT RX reconfig done\r\n");
+ }
+ else {
+ xil_printf("GT RX reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_QPLL_RECONFIG):
+ if (Data == 1) {
+ xil_printf("QPLL reconfig done\r\n");
+ }
+ else {
+ xil_printf("QPLL reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_PLL0_RECONFIG):
+ if (Data == 1) {
+ xil_printf("PLL0 reconfig done\r\n");
+ }
+ else {
+ xil_printf("PLL0 reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_PLL1_RECONFIG):
+ if (Data == 1) {
+ xil_printf("PLL1 reconfig done\r\n");
+ }
+ else {
+ xil_printf("PLL1 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("TX MMCM reconfig done\r\n");
+ }
+ else {
+ xil_printf("TX MMCM reconfig start\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_RXPLL_RECONFIG):
+ if (Data == 1) {
+ xil_printf("RX MMCM reconfig 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_PLL0_LOCK):
+ if (Data == 1) {
+ xil_printf("PLL0 lock\r\n");
+ }
+ else {
+ xil_printf("PLL0 lost lock\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_PLL1_LOCK):
+ if (Data == 1) {
+ xil_printf("PLL1 lock\r\n");
+ }
+ else {
+ xil_printf("PLL1 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;
+ case (XVPHY_LOG_EVT_DRU_EN):
+ if (Data == 1) {
+ xil_printf("DRU enable\r\n");
+ }
+ else {
+ xil_printf("DRU disable\r\n");
+ }
+ break;
+ case (XVPHY_LOG_EVT_GT_PLL_LAYOUT):
+ xil_printf("Error! Couldn't find the correct GT "
+ "parameters for this video resolution.\n\r");
+ xil_printf("Try another GT PLL layout.\n\r");
+ break;
+ case (XVPHY_LOG_EVT_GT_UNBONDED):
+ 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");
+ break;
+ case (XVPHY_LOG_EVT_1PPC_ERR):
+ xil_printf("Error! The Video PHY cannot support this video ");
+ xil_printf("format at PPC = 1\r\n");
+ break;
+ case (XVPHY_LOG_EVT_PPC_MSMTCH_ERR):
+ xil_printf("Warning: HDMI TX SS PPC value, doesn't match with"
+ " VPhy PPC value\r\n");
+ break;
+ case (XVPHY_LOG_EVT_VDCLK_HIGH_ERR):
+ xil_printf("Error! GTPE2 Video PHY cannot"
+ "support resolutions");
+ xil_printf("\r\n\twith video clock > 148.5 MHz.\r\n");
+ break;
+ case (XVPHY_LOG_EVT_NO_DRU):
+ xil_printf("Low resolution video isn't supported in "
+ "this version.\r\n No DRU instance found.\r\n");
+ break;
+ case (XVPHY_LOG_EVT_GT_QPLL_CFG_ERR):
+ xil_printf("QPLL config not found!\r\n");
+ break;
+ case (XVPHY_LOG_EVT_GT_CPLL_CFG_ERR):
+ xil_printf("CPLL config not found!\r\n");
+ break;
+ case (XVPHY_LOG_EVT_VD_NOT_SPRTD_ERR):
+ xil_printf("Warning: This video format is not "
+ "supported by this device\r\n");
+ xil_printf(" "
+ "Change to another format\r\n");
+ break;
+ case (XVPHY_LOG_EVT_MMCM_ERR):
+ xil_printf("MMCM config not found!\r\n");
+ break;
+ default:
+ xil_printf("Unknown event\r\n");
+ break;
+ }
+
+ /* Read log data */
+ Log = XVphy_LogRead(InstancePtr);
+ }
+#else
+ xil_printf("\r\nINFO:: VPHY Log Feature is Disabled \r\n");
+#endif
+}
diff --git a/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_sinit.c b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_sinit.c
new file mode 100644
index 00000000000000..3b45d098236c72
--- /dev/null
+++ b/drivers/staging/xilinx/hdmi/phy-xilinx-vphy/xvphy_sinit.c
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ *
+ *
+ * Copyright (C) 2015, 2016, 2017 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+*******************************************************************************/
+/******************************************************************************/
+/**
+ *
+ * @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 "xvphy.h"
+#include "xvphy_i.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;
+}