/*  ============================================================================
 *   Copyright (c) Texas Instruments Inc 2013
 *
 *   Use of this software is controlled by the terms and conditions found in the
 *   license agreement under which this software has been supplied.
 *   ===========================================================================
 */
/** ============================================================================
 Serdes configuration on K2 DSP
 * =============================================================================
 *  Revision History
 *  ===============
 *  June 1, 2013 Brighton Feng  file created
 * =============================================================================
 */

#ifndef _K2_SERDES_INIT_H_
#define _K2_SERDES_INIT_H_

#include <tistdtypes.h>
#include <stdint.h>
#include <csl_serdes.h>
#include <csl_aif2.h>
#include "K2_common.h"

/**
 * This structure is used for configuring the parameters of a Serdes module.*/
typedef struct
{
	CSL_SERDES_REF_CLOCK inputRefClock;

	float linkSpeed_GHz; 	/*the max link speed of all lanes at GHz*/

	/*bit 0~3 control the endable/disable of 4 lanes. 0: disable; 1: enable*/
	Uint32 laneEnableMask; 

	CSL_SERDES_LANE_CTRL_RATE laneRateScale[4]; /*rate scale for up to four lanes*/

	CSL_SERDES_LOOPBACK  loopBackMode;

} K2_SerdesConfig;
typedef struct
{
	CSL_SERDES_REF_CLOCK inputRefClock;

	float linkSpeed_GHz; 	/*the max link speed of all lanes at GHz*/

	/*bit 0~5 control the endable/disable of 6 lanes. 0: disable; 1: enable*/
	Uint32 laneEnableMask; 

	CSL_Aif2LinkRate laneRateScale[6]; /*rate scale for up to six lanes*/

	/*bit 0~5 control the endable/disable of loopback on 6 lanes. 0: disable; 1: enable*/
	Uint32  loopBackMask;

} K2_AIF2_SerdesConfig;
typedef struct
{
	CSL_SERDES_REF_CLOCK inputRefClock;

	float linkSpeed_GHz; 	/*the max link speed of all lanes at GHz*/

	/*bit 0~3 control the endable/disable of 4 lanes. 0: disable; 1: enable*/
	Uint32 laneEnableMask; 

	CSL_SERDES_LOOPBACK  loopBackMode;

} K2_GE_SerdesConfig;
typedef struct
{
	CSL_SERDES_REF_CLOCK inputRefClock;

	float linkSpeed_GHz; 	/*the max link speed of all lanes at GHz*/

	/*number of lanes be used*/
	Uint32 numLanes; 

	CSL_SERDES_LOOPBACK  loopBackMode;

} K2_HyperLinkSerdesConfig;
typedef struct
{
	CSL_SERDES_REF_CLOCK inputRefClock;

	float linkSpeed_GHz; 	/*the max link speed of all lanes at GHz*/

	/*number of lanes be used*/
	Uint32 numLanes; 

	CSL_SERDES_LOOPBACK  loopBackMode;

} K2_PCIE_SerdesConfig;

/** ============================================================================
 *   @n This API returns the status of the Serdes PLL lock
 *   @b Arguments   base_addr of the Serdes configuration registers
 *   <b> Return Value  </b>  CSL_SERDES_STATUS
 *   @b Example
     K2_SerdesPLLGetStatus(CSL_SRIO_SERDES_CFG_REGS);
 * ===========================================================================
 */
static inline CSL_SERDES_STATUS K2_SerdesPLLGetStatus
(
 uint32_t base_addr
)
{
    CSL_SERDES_STATUS retval;

    /* Check PLL OK Status Bit */
    retval = (CSL_SERDES_STATUS)CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1ff4), 28, 28);

    return retval;
}


/** ============================================================================
 *   @n This API returns the status of the Serdes lane status
 *   @b Arguments   base_addr, lane_num
 *   <b> Return Value  </b>  CSL_SERDES_STATUS
 *   @b Example
     CSL_SrioSerdesGetStatus(CSL_SRIO_SERDES_CFG_REGS, 0);
 * ===========================================================================
 */
static inline CSL_SERDES_STATUS K2_SerdesLaneGetStatus
(
 uint32_t base_addr,
 uint32_t lane_num
)
{
    CSL_SERDES_STATUS retval;

    /* Check Lane # OK Status Bits */
    retval = (CSL_SERDES_STATUS)CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1ff4), (8 + lane_num), (8 + lane_num));
    retval &= (CSL_SERDES_STATUS)CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1ff4), (0 + lane_num), (0 + lane_num));

    return retval;
}

static inline CSL_SERDES_STATUS K2_PCIE_SerdesLaneGetStatus
(
 uint32_t base_addr,
 uint32_t lane_num
)
{
    CSL_SERDES_STATUS retval;

    /* Check Lane # OK Status Bits */
    retval = (CSL_SERDES_STATUS)CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1ff4), (0 + lane_num), (0 + lane_num));

    return retval;
}

/*Serdes initialization for SRIO*/
extern void K2_SRIO_Serdes_init(K2_SerdesConfig * serdes_cfg);

/*Serdes initialization for AIF2*/
extern void K2_AIF2_Serdes_init(K2_AIF2_SerdesConfig * serdes_cfg);

/*Serdes initialization for HyperLink*/
extern void K2_HyperLink_Serdes_Init(Uint32 uiBase_addr, 
	K2_HyperLinkSerdesConfig * serdes_cfg);

/*Serdes initialization for Giga bit ethernet*/
extern void K2_GE_Serdes_init(K2_GE_SerdesConfig * serdes_cfg);

/*Serdes initialization for Giga bit ethernet*/
extern void K2_PCIE_Serdes_init(K2_PCIE_SerdesConfig * serdes_cfg);

#endif 

