/***************************************************************************//**
* @file jesd_core.c
* @brief Implementation of JESD Core Driver.
* @author DBogdan (
[email protected])
********************************************************************************
* Copyright 2017(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <inttypes.h>
#include <stdio.h>
#include "mykonos.h"
#include "jesd_core.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define XCVR_REG_RESETN 0x0010
#define XCVR_RESETN (1 << 0)
#define XCVR_REG_STATUS 0x0014
#define XCVR_STATUS (1 << 0)
#define XCVR_REG_CONTROL 0x0020
#define XCVR_LPM_DFE_N (1 << 12)
#define XCVR_RATE(x) (((x) & 0x7) << 8)
#define XCVR_SYSCLK_SEL(x) (((x) & 0x3) << 4)
#define XCVR_OUTCLK_SEL(x) (((x) & 0x7) << 0)
#define XCVR_REG_SYNTH 0x24
#define XCVR_REG_DRP_SEL(x) (0x0040 + (x))
#define XCVR_REG_DRP_CTRL(x) (0x0044 + (x))
#define XCVR_DRP_CTRL_WR (1 << 28)
#define XCVR_DRP_CTRL_ADDR(x) (((x) & 0xFFF) << 16)
#define XCVR_DRP_CTRL_WDATA(x) (((x) & 0xFFFF) << 0)
#define XCVR_REG_DRP_STATUS(x) (0x0048 + (x))
#define XCVR_DRP_STATUS_BUSY (1 << 16)
#define XCVR_DRP_STATUS_RDATA(x) (((x) & 0xFFFF) << 0)
#define XCVR_DRP_PORT_ADDR_COMMON 0x00
#define XCVR_DRP_PORT_ADDR_CHANNEL 0x20
#define XCVR_DRP_PORT_COMMON 0x00
#define XCVR_DRP_PORT_CHANNEL(x) (0x1 + x)
#define XCVR_DRP_PORT_CHANNEL_BCAST 0xff
#define XCVR_BROADCAST 0xff
#define OUT_DIV_ADDR 0x88
#define OUT_DIV_TX_OFFSET 0x4
#define OUT_DIV_RX_OFFSET 0x0
#define RXCDR_CFG0_ADDR 0xa8
#define RXCDR_CFG0_MASK 0xffff
#define RXCDR_CFG1_ADDR 0xa9
#define RXCDR_CFG1_MASK 0xffff
#define RXCDR_CFG2_ADDR 0xaa
#define RXCDR_CFG2_MASK 0xffff
#define RXCDR_CFG3_ADDR 0xab
#define RXCDR_CFG3_MASK 0xffff
#define RXCDR_CFG4_ADDR 0xac
#define RXCDR_CFG4_MASK 0x00ff
#define RX_DFE_LPM_CFG_ADDR 0x29
#define RX_DFE_LPM_CFG_MASK 0xffff
#define QPLL_CFG0_ADDR 0x32
#define QPLL_CFG0_LOWBAND_MASK 0x0040
#define QPLL_CFG1_ADDR 0x33
#define QPLL_REFCLK_DIV_M_MASK 0xf800
#define QPLL_REFCLK_DIV_M_OFFSET 11
#define QPLL_REFCLK_DIV_M(x) ((x) << 11)
#define QPLL_FBDIV_N_ADDR 0x36
#define QPLL_FBDIV_N_MASK 0x03ff
#define QPLL_FBDIV_RATIO_ADDR 0x37
#define QPLL_FBDIV_RATIO_MASK 0x0040
#define CPLL_CFG0_ADDR 0x5c
#define CPLL_CFG0_MASK 0xff00
#define CPLL_CFG1_ADDR 0x5d
#define CPLL_CFG1_MASK 0xffff
#define CPLL_REFCLK_DIV_M_ADDR 0x5e
#define CPLL_REFCLK_DIV_M_MASK 0x1f00
#define CPLL_FB_DIV_45_N1_MASK 0x0080
#define CPLL_FBDIV_N2_MASK 0x007f
#define RX_CLK25_DIV 0x11
#define RX_CLK25_DIV_OFFSET 6
#define RX_CLK25_DIV_MASK 0x07c0
#define TX_CLK25_DIV 0x6a
#define TX_CLK25_DIV_MASK 0x1f
#define QPLL_FBDIV(x) (0x14 + (x) * 0x80)
#define QPLL_REFCLK_DIV(x) (0x18 + (x) * 0x80)
#define ENC_8B10B 810
#define JESD204_REG_LINK_DISABLE 0xc0
#define JESD204_REG_LINK_CONF0 0x210
#define DIV_ROUND_CLOSEST(x, y) (uint32_t)(((double)x / y) + 0.5)
static const char *adxcvr_gt_names[] = {
[XILINX_XCVR_TYPE_S7_GTX2] = "GTX2",
[XILINX_XCVR_TYPE_US_GTH3] = "GTH3",
[XILINX_XCVR_TYPE_US_GTH4] = "GTH4",
};
/***************************************************************************//**
* @brief xcvr_write
*******************************************************************************/
void xcvr_write(xcvr_device *dev,
uint32_t reg_addr,
uint32_t reg_val)
{
Xil_Out32((dev->base_addr + reg_addr), reg_val);
}
/***************************************************************************//**
* @brief xcvr_read
*******************************************************************************/
int32_t xcvr_read(xcvr_device *dev,
uint32_t reg_addr)
{
return Xil_In32(dev->base_addr + reg_addr);
}
/***************************************************************************//**
* @brief xcvr_drp_wait_idle
*******************************************************************************/
int32_t xcvr_drp_wait_idle(xcvr_device *dev,
uint32_t drp_addr)
{
uint32_t val;
int32_t timeout = 20;
do {
val = xcvr_read(dev, XCVR_REG_DRP_STATUS(drp_addr));
if (!(val & XCVR_DRP_STATUS_BUSY))
return XCVR_DRP_STATUS_RDATA(val);
mdelay(1);
} while (timeout--);
printf("%s: Timeout!", __func__);
return -1;
}
/***************************************************************************//**
* @brief xcvr_drp_read
*******************************************************************************/
int32_t xcvr_drp_read(xcvr_device *dev,
uint32_t drp_port,
uint32_t reg)
{
uint32_t drp_sel = XCVR_BROADCAST;
uint32_t drp_addr;
int32_t ret;
if (drp_port == XCVR_DRP_PORT_COMMON) {
drp_addr = XCVR_DRP_PORT_ADDR_COMMON;
} else {
drp_addr = XCVR_DRP_PORT_ADDR_CHANNEL;
if (drp_port != XCVR_DRP_PORT_CHANNEL_BCAST)
drp_sel = drp_port - 1;
}
xcvr_write(dev, XCVR_REG_DRP_SEL(drp_addr), drp_sel);
xcvr_write(dev, XCVR_REG_DRP_CTRL(drp_addr), XCVR_DRP_CTRL_ADDR(reg));
ret = xcvr_drp_wait_idle(dev, drp_addr);
if (ret < 0)
return ret;
return ret & 0xffff;
}
/***************************************************************************//**
* @brief xcvr_drp_write
*******************************************************************************/
int32_t xcvr_drp_write(xcvr_device *dev,
uint32_t drp_port,
uint32_t reg,
uint32_t val)
{
uint32_t drp_sel = X
评论0