/******************************************************************************

  Copyright (C), 2001-2012, Texas Instrument.

 ******************************************************************************
  File Name     : SRIO_Init.c
  Version       : Initial Draft
  Author        : Zhan
  Created       : 2012/10/24
  Last Modified :
  Description   : This file is used to initialize the SRIO for memory prote-
                  ction test
  Function List :
  History       :
  1.Date        : 2012/10/24
    Author      : Zhan
    Modification: Created file

******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "KeyStone_SRIO_init_drv.h"
#include "Robust_SRIO_Init.h"
/*----------------------------------------------*
 * external variables                           *
 *----------------------------------------------*/

/*----------------------------------------------*
 * external routine prototypes                  *
 *----------------------------------------------*/

/*----------------------------------------------*
 * internal routine prototypes                  *
 *----------------------------------------------*/

/*----------------------------------------------*
 * project-wide global variables                *
 *----------------------------------------------*/

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
/*up to 16 deviceID can be setup here*/
SRIO_Device_ID_Routing_Config dsp0_device_ID_routing_config[]=
{
     /*idPattern 	idMatchMask 	routeMaintenance*/
	{DSP0_SRIO_BASE_ID+0, 	0xFFFF, 	1}
};

SRIO_Loopback_Mode loopback_mode= SRIO_DIGITAL_LOOPBACK;

SerdesSetup_4links serdes_cfg;
SerdesLinkSetup serdesLinkSetup;
SRIO_Message_Cfg msg_cfg;
SRIO_Config srio_cfg;
/*----------------------------------------------*
 * constants                                    *
 *----------------------------------------------*/
/*path configuration strings*/
char * path_str[]=
{
	"1xLaneA_1xLaneB_1xLaneC_1xLaneD",  
	"2xLaneAB_1xLaneC_1xLaneD       ",
	"1xLaneA_1xLaneB_2xLaneCD       ",
	"2xLaneAB_2xLaneCD              ",
	"4xLaneABCD                     "
};
/*----------------------------------------------*
 * macros                                       *
 *----------------------------------------------*/

/*----------------------------------------------*
 * routines' implementations                    *
 *----------------------------------------------*/

/*****************************************************************************
 Prototype    : get_path_string
 Description  : Get SRIO path string
 Input        : SRIO_1x2x4x_Path_Control srio_1x2x4x_path_control  
 Output       : None
 Return Value : char
 
  History        :
  1.Date         : 2012/10/24
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
char * get_path_string(SRIO_1x2x4x_Path_Control srio_1x2x4x_path_control)
{
  	if(SRIO_PATH_CTL_1xLaneA_1xLaneB_1xLaneC_1xLaneD== srio_1x2x4x_path_control) return path_str[0];
	else if(SRIO_PATH_CTL_2xLaneAB_1xLaneC_1xLaneD       == srio_1x2x4x_path_control) return path_str[1];
	else if(SRIO_PATH_CTL_1xLaneA_1xLaneB_2xLaneCD       == srio_1x2x4x_path_control) return path_str[2];
	else if(SRIO_PATH_CTL_2xLaneAB_2xLaneCD              == srio_1x2x4x_path_control) return path_str[3];
	else if(SRIO_PATH_CTL_4xLaneABCD                     == srio_1x2x4x_path_control) return path_str[4];
	else return NULL;
}
/*****************************************************************************
 Prototype    : srio_identify_used_ports_lanes
 Description  : identify used ports lanes according to 1x 2x 4x path config-
                uration
 Input        : SRIO_1x2x4x_Path_Control srio_1x2x4x_path_control  
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/30
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
/* identify used ports lanes according to 1x 2x 4x path configuration*/
void srio_identify_used_ports_lanes(
	SRIO_1x2x4x_Path_Control srio_1x2x4x_path_control)
{
	int i;
	Uint32 uiPathMode;
	Uint32 uiLaneEnableMask=0, uiLogicPortEnableMask=0;

	/* SRIO 1x 2x 4x path mode configuration:

	In Configuration 4, a maximum of 4 active ports and 4 lanes per path are supported as follows:
	 Mode 0: Four independent 1x ports in lanes A, B, C, and D
	 Mode 1: One independent 2x port in lanes {A,B}, and two independent 1x ports in lanes C and D
	 Mode 2: Two independent 1x ports in lanes A and B, and one independent 2x port in lanes {C,D}
	 Mode 3: Two independent 2x ports, occupying lanes {A,B} and {C,D} respectively
	 Mode 4: One independent 4x port in lanes {A,B,C,D}*/

	uiPathMode= (srio_1x2x4x_path_control&
		CSL_SRIO_RIO_PLM_SP_PATH_CTL_PATH_MODE_MASK)>>
		CSL_SRIO_RIO_PLM_SP_PATH_CTL_PATH_MODE_SHIFT;

	uiLaneEnableMask= 0xF; 	/*1111*/

	if(0==uiPathMode)
		uiLogicPortEnableMask= 0xF; 	/*1111*/
	else if(1==uiPathMode)
		uiLogicPortEnableMask= 0xD; 	/*1101*/
	else if(2==uiPathMode)
		uiLogicPortEnableMask= 0x7; 	/*0111*/
	else if(3==uiPathMode)
		uiLogicPortEnableMask= 0x5; 	/*0101*/
	else if(4==uiPathMode)
		uiLogicPortEnableMask= 0x1; 	/*0001*/


	/*enable ports data path according to 1x 2x 4x path configuration*/
	srio_cfg.blockEn.bBLK5_8_Port_Datapath_EN[0]= uiLaneEnableMask&1;
	srio_cfg.blockEn.bBLK5_8_Port_Datapath_EN[1]= (uiLaneEnableMask>>1)&1;
	srio_cfg.blockEn.bBLK5_8_Port_Datapath_EN[2]= (uiLaneEnableMask>>2)&1;
	srio_cfg.blockEn.bBLK5_8_Port_Datapath_EN[3]= (uiLaneEnableMask>>3)&1;

	/*disable Serdes according to 1x 2x 4x path configuration*/
	for(i= 0; i<4; i++ )
	{
		if(uiLaneEnableMask&(1<<i))
			srio_cfg.serdes_cfg->linkSetup[i]= &serdesLinkSetup;
		else
			srio_cfg.serdes_cfg->linkSetup[i]= NULL;
	}

	/*enable loggical ports according to 1x 2x 4x path configuration*/
	srio_cfg.blockEn.bLogic_Port_EN[0]= uiLogicPortEnableMask&1;
	srio_cfg.blockEn.bLogic_Port_EN[1]= (uiLogicPortEnableMask>>1)&1;
	srio_cfg.blockEn.bLogic_Port_EN[2]= (uiLogicPortEnableMask>>2)&1;
	srio_cfg.blockEn.bLogic_Port_EN[3]= (uiLogicPortEnableMask>>3)&1;

	printf("SRIO path configuration %s\n", 
		get_path_string(srio_1x2x4x_path_control));
}
/*****************************************************************************
 Prototype    : InitLsuTransfer
 Description  : Initialize SRIO transfer parameter
 Input        : SRIO_LSU_Transfer * lsuTransfer      
                SRIO_Transfer_Param * transferParam  
                Uint32 uiLsuNum                      
                Uint32 uiDstID                       
                Uint32 uiSrcIDMap                    
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/24
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
void InitLsuTransfer(SRIO_LSU_Transfer * lsuTransfer, 
	SRIO_Transfer_Param * transferParam, Uint32 uiLsuNum, 
	Uint32 uiDstID, Uint32 uiSrcIDMap)
{
    lsuTransfer->rioAddressMSB=0;
	/*swap source/dest for READ*/
	if(SRIO_PKT_TYPE_NREAD==transferParam->packet_type)
	{
	    lsuTransfer->rioAddressLSB_ConfigOffset= transferParam->source;
	    lsuTransfer->localDspAddress= transferParam->dest;
	}
	else
	{
	    lsuTransfer->rioAddressLSB_ConfigOffset= transferParam->dest;
	    lsuTransfer->localDspAddress= transferParam->source;
	}
    lsuTransfer->bytecount= transferParam->byteCount; 	
    lsuTransfer->packetType= transferParam->packet_type;
    lsuTransfer->dstID= uiDstID;
    lsuTransfer->doorbellInfo= 0;
    lsuTransfer->waitLsuReady= TRUE;
    lsuTransfer->lsuNum= uiLsuNum;
    lsuTransfer->doorbellValid = 0;
    lsuTransfer->intrRequest = 0;
    lsuTransfer->supGoodInt = 0;
    lsuTransfer->priority = 0;
    lsuTransfer->outPortID = uiLsuNum;
    lsuTransfer->idSize = 0;
    lsuTransfer->srcIDMap = uiSrcIDMap;
    lsuTransfer->hopCount = 0;

}
/*****************************************************************************
 Prototype    : SRIO_Init
 Description  : SRIO initialization for memory protection test
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/24
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
void SRIO_Init()
{
	TDSP_Board_Type DSP_Board_Type;

	/*clear configuration structrue to make sure unused field is 0*/
	memset(&srio_cfg, 0, sizeof(srio_cfg)); 

	DSP_Board_Type= KeyStone_Get_dsp_board_type();
	if(C6678_EVM==DSP_Board_Type)
		serdes_cfg.commonSetup.inputRefClock_MHz = 312.5;
	else if(C6670_EVM==DSP_Board_Type || C6657_EVM==DSP_Board_Type)
		serdes_cfg.commonSetup.inputRefClock_MHz = 250;
	else if(DUAL_NYQUIST_EVM==DSP_Board_Type)
		serdes_cfg.commonSetup.inputRefClock_MHz = 156.25;
	else if(TCI6614_EVM==DSP_Board_Type)
		serdes_cfg.commonSetup.inputRefClock_MHz = 312.5;
	else
	{
		puts("Unknown DSP board type!");
		return;
	}
	
	srio_cfg.blockEn.bBLK1_LSU_EN= 1;
	srio_cfg.blockEn.bBLK2_MAU_EN= 1;
	srio_cfg.blockEn.bBLK3_TXU_EN= 1;
	srio_cfg.blockEn.bBLK4_RXU_EN= 1;

	srio_cfg.loopback_mode= loopback_mode;
	
	srio_cfg.device_ID_routing_config= dsp0_device_ID_routing_config;
	srio_cfg.uiNumDeviceId= 
		sizeof(dsp0_device_ID_routing_config)/sizeof(SRIO_Device_ID_Routing_Config);

	serdes_cfg.commonSetup.loopBandwidth= SERDES_PLL_LOOP_BAND_MID;
	srio_cfg.serdes_cfg= &serdes_cfg;

	serdesLinkSetup.txOutputSwing    = 15; /*0~15 represents between 100 and 850 mVdfpp  */
	serdesLinkSetup.testPattern      = SERDES_TEST_DISABLED; 
	serdesLinkSetup.rxAlign          = SERDES_RX_COMMA_ALIGNMENT_ENABLE; 
	serdesLinkSetup.rxInvertPolarity = SERDES_RX_NORMAL_POLARITY; 
	serdesLinkSetup.rxTermination    = SERDES_RX_TERM_COMMON_POINT_AC_COUPLE; 
	serdesLinkSetup.rxEqualizerConfig= SERDES_RX_EQ_ADAPTIVE; 
    serdesLinkSetup.rxCDR            = 5;
	serdesLinkSetup.txInvertPolarity = SERDES_TX_NORMAL_POLARITY; 
    serdesLinkSetup.linkSpeed_GHz = 5;

    srio_cfg.srio_1x2x4x_path_control = SRIO_PATH_CTL_4xLaneABCD;
    
	srio_cfg.msg_cfg= NULL;

    srio_identify_used_ports_lanes(srio_cfg.srio_1x2x4x_path_control);

	KeyStone_SRIO_Init(&srio_cfg);
    
}
