blob: 11832f00d73b6f8f12f927a4e3ff7fc2b98a6edf [file] [log] [blame]
#include <Copyright.h>
/*******************************************************************************
* gtPTP.c
*
* DESCRIPTION:
* API definitions for Precise Time Protocol logic
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*******************************************************************************/
#include <msApi.h>
#include <gtSem.h>
#include <gtHwCntl.h>
#include <gtDrvSwRegs.h>
#ifdef CONFIG_AVB_FPGA
#undef USE_SINGLE_READ
#define AVB_SMI_ADDR 0xC
#define QD_REG_PTP_INT_OFFSET 0
#define QD_REG_PTP_INTEN_OFFSET 1
#define QD_REG_PTP_FREQ_OFFSET 4
#define QD_REG_PTP_PHASE_OFFSET 6
#define QD_REG_PTP_CLK_CTRL_OFFSET 4
#define QD_REG_PTP_CYCLE_INTERVAL_OFFSET 5
#define QD_REG_PTP_CYCLE_ADJ_OFFSET 6
#define QD_REG_PTP_PLL_CTRL_OFFSET 7
#define QD_REG_PTP_CLK_SRC_OFFSET 0x9
#define QD_REG_PTP_P9_MODE_OFFSET 0xA
#define QD_REG_PTP_RESET_OFFSET 0xB
#define GT_PTP_MERGE_32BIT(_high16,_low16) (((_high16)<<16)|(_low16))
#define GT_PTP_GET_HIGH16(_data) ((_data) >> 16) & 0xFFFF
#define GT_PTP_GET_LOW16(_data) (_data) & 0xFFFF
#if 0
#define AVB_FPGA_READ_REG gprtGetPhyReg
#define AVB_FPGA_WRITE_REG gprtSetPhyReg
unsigned int (*avbFpgaReadReg)(void* unused, unsigned int port, unsigned int reg, unsigned int* data);
unsigned int (*avbFpgaWriteReg)(void* unused, unsigned int port, unsigned int reg, unsigned int data);
#else
/* for RMGMT access and can be controlled by <sw_apps -rmgmt 0/1> */
unsigned int (*avbFpgaReadReg)(void* unused, unsigned int port, unsigned int reg, GT_U32* data)=gprtGetPhyReg;
unsigned int (*avbFpgaWriteReg)(void* unused, unsigned int port, unsigned int reg, GT_U32 data)=gprtSetPhyReg;
#define AVB_FPGA_READ_REG avbFpgaReadReg
#define AVB_FPGA_WRITE_REG avbFpgaWriteReg
#endif /* 0 */
#endif
#if 0
#define GT_PTP_BUILD_TIME(_time1, _time2) (((_time1) << 16) | (_time2))
#define GT_PTP_L16_TIME(_time1) ((_time1) & 0xFFFF)
#define GT_PTP_H16_TIME(_time1) (((_time1) >> 16) & 0xFFFF)
#endif
/****************************************************************************/
/* PTP operation function declaration. */
/****************************************************************************/
extern GT_STATUS ptpOperationPerform
(
IN GT_QD_DEV *dev,
IN GT_PTP_OPERATION ptpOp,
INOUT GT_PTP_OP_DATA *opData
);
/*******************************************************************************
* gptpSetConfig
*
* DESCRIPTION:
* This routine writes PTP configuration parameters.
*
* INPUTS:
* ptpData - PTP configuration parameters.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetConfig
(
IN GT_QD_DEV *dev,
IN GT_PTP_CONFIG *ptpData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_LPORT port;
GT_PTP_PORT_CONFIG ptpPortData;
DBG_INFO(("gptpSetConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_WRITE_DATA;
/* setting PTPEType, offset 0 */
opData.ptpAddr = 0;
opData.ptpData = ptpData->ptpEType;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
/* setting MsgIDTSEn, offset 1 */
opData.ptpAddr = 1;
opData.ptpData = ptpData->msgIdTSEn;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing MsgIDTSEn.\n"));
return GT_FAIL;
}
/* setting TSArrPtr, offset 2 */
opData.ptpAddr = 2;
opData.ptpData = ptpData->tsArrPtr;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TSArrPtr.\n"));
return GT_FAIL;
}
#ifndef CONFIG_AVB_FPGA
if (IS_IN_DEV_GROUP(dev,DEV_PTP_2))
#endif
{
ptpPortData.transSpec = ptpData->transSpec;
ptpPortData.disTSpec = 1; /* default value */
ptpPortData.disTSOverwrite = ptpData->disTSOverwrite;
ptpPortData.ipJump = 2; /* default value */
ptpPortData.etJump = 12; /* default value */
/* per port configuration */
for(port=0; port<dev->numOfPorts; port++)
{
ptpPortData.ptpArrIntEn = (ptpData->ptpArrIntEn & (1 << port))? GT_TRUE : GT_FALSE;
ptpPortData.ptpDepIntEn = (ptpData->ptpDepIntEn & (1 << port))? GT_TRUE : GT_FALSE;
if((retVal = gptpSetPortConfig(dev, port, &ptpPortData)) != GT_OK)
{
DBG_INFO(("Failed gptpSetPortConfig.\n"));
return GT_FAIL;
}
if (IS_IN_DEV_GROUP(dev, DEV_ARRV_TS_MODE))
{
if(!((ptpData->ptpPortConfig[port].arrTSMode==GT_PTP_TS_MODE_IN_REG)||(ptpData->ptpPortConfig[port].arrTSMode==GT_PTP_TS_MODE_IN_RESERVED_2)||(ptpData->ptpPortConfig[port].arrTSMode==GT_PTP_TS_MODE_IN_FRAME_END)))
ptpData->ptpPortConfig[port].arrTSMode=GT_PTP_TS_MODE_IN_REG;
if((retVal = gptpSetPortTsMode(dev, port, ptpData->ptpPortConfig[port].arrTSMode)) != GT_OK)
{
DBG_INFO(("Failed gptpSetPortConfig.\n"));
return GT_FAIL;
}
}
}
return GT_OK;
}
/* old PTP block */
/* setting PTPArrIntEn, offset 3 */
opData.ptpAddr = 3;
opData.ptpData = GT_LPORTVEC_2_PORTVEC(ptpData->ptpArrIntEn);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPArrIntEn.\n"));
return GT_FAIL;
}
/* setting PTPDepIntEn, offset 4 */
opData.ptpAddr = 4;
opData.ptpData = GT_LPORTVEC_2_PORTVEC(ptpData->ptpDepIntEn);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPDepIntEn.\n"));
return GT_FAIL;
}
/* TransSpec, MsgIDStartBit, DisTSOverwrite bit, offset 5 */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
op = PTP_WRITE_DATA;
#ifdef CONFIG_AVB_FPGA
opData.ptpData = ((ptpData->transSpec&0xF) << 12) | ((ptpData->msgIdStartBit&0x7) << 9) |
(opData.ptpData & 0x1) | ((ptpData->disTSOverwrite?1:0) << 1);
#else
opData.ptpData = ((ptpData->transSpec&0xF) << 12) | (opData.ptpData & 0x1) | ((ptpData->disTSOverwrite?1:0) << 1);
#endif
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing MsgIDStartBit & DisTSOverwrite.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetConfig
*
* DESCRIPTION:
* This routine reads PTP configuration parameters.
*
* INPUTS:
* None.
*
* OUTPUTS:
* ptpData - PTP configuration parameters.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetConfig
(
IN GT_QD_DEV *dev,
OUT GT_PTP_CONFIG *ptpData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_LPORT port;
GT_PTP_PORT_CONFIG ptpPortData;
DBG_INFO(("gptpGetConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
ptpData->ptpEType = opData.ptpData;
/* getting MsgIDTSEn, offset 1 */
opData.ptpAddr = 1;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading MsgIDTSEn.\n"));
return GT_FAIL;
}
ptpData->msgIdTSEn = opData.ptpData;
/* getting TSArrPtr, offset 2 */
opData.ptpAddr = 2;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TSArrPtr.\n"));
return GT_FAIL;
}
ptpData->tsArrPtr = opData.ptpData;
#ifndef CONFIG_AVB_FPGA
if (IS_IN_DEV_GROUP(dev,DEV_PTP_2))
#endif
{
ptpData->ptpArrIntEn = 0;
ptpData->ptpDepIntEn = 0;
/* per port configuration */
for(port=0; port<dev->numOfPorts; port++)
{
if((retVal = gptpGetPortConfig(dev, port, &ptpPortData)) != GT_OK)
{
DBG_INFO(("Failed gptpGetPortConfig.\n"));
return GT_FAIL;
}
ptpData->ptpArrIntEn |= (ptpPortData.ptpArrIntEn ? (1 << port) : 0);
ptpData->ptpDepIntEn |= (ptpPortData.ptpDepIntEn ? (1 << port) : 0);
ptpData->ptpPortConfig[port].ptpArrIntEn = ptpPortData.ptpArrIntEn;
ptpData->ptpPortConfig[port].ptpDepIntEn = ptpPortData.ptpDepIntEn;
if (IS_IN_DEV_GROUP(dev, DEV_ARRV_TS_MODE))
{
ptpData->ptpPortConfig[port].transSpec = ptpPortData.transSpec;
ptpData->ptpPortConfig[port].disTSOverwrite = ptpPortData.disTSOverwrite;
if((retVal = gptpGetPortTsMode(dev, port, &ptpData->ptpPortConfig[port].arrTSMode)) != GT_OK)
{
DBG_INFO(("Failed gptpGetPortConfig.\n"));
return GT_FAIL;
}
}
}
ptpData->transSpec = ptpPortData.transSpec;
ptpData->disTSOverwrite = ptpPortData.disTSOverwrite;
ptpData->msgIdStartBit = 4;
return GT_OK;
}
/* old PTP block */
/* getting PTPArrIntEn, offset 3 */
opData.ptpAddr = 3;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPArrIntEn.\n"));
return GT_FAIL;
}
opData.ptpData &= dev->validPortVec;
ptpData->ptpArrIntEn = GT_PORTVEC_2_LPORTVEC(opData.ptpData);
/* getting PTPDepIntEn, offset 4 */
opData.ptpAddr = 4;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPDepIntEn.\n"));
return GT_FAIL;
}
opData.ptpData &= dev->validPortVec;
ptpData->ptpDepIntEn = GT_PORTVEC_2_LPORTVEC(opData.ptpData);
/* MsgIDStartBit, DisTSOverwrite bit, offset 5 */
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
ptpData->transSpec = (opData.ptpData >> 12) & 0xF;
#ifdef CONFIG_AVB_FPGA
ptpData->msgIdStartBit = (opData.ptpData >> 9) & 0x7;
#else
ptpData->msgIdStartBit = 0;
#endif
ptpData->disTSOverwrite = ((opData.ptpData >> 1) & 0x1) ? GT_TRUE : GT_FALSE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetGlobalConfig
*
* DESCRIPTION:
* This routine writes PTP global configuration parameters.
*
* INPUTS:
* ptpData - PTP global configuration parameters.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetGlobalConfig
(
IN GT_QD_DEV *dev,
IN GT_PTP_GLOBAL_CONFIG *ptpData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpSetGlobalConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_WRITE_DATA;
/* setting PTPEType, offset 0 */
opData.ptpAddr = 0;
opData.ptpData = ptpData->ptpEType;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
/* setting MsgIDTSEn, offset 1 */
opData.ptpAddr = 1;
opData.ptpData = ptpData->msgIdTSEn;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing MsgIDTSEn.\n"));
return GT_FAIL;
}
/* setting TSArrPtr, offset 2 */
opData.ptpAddr = 2;
opData.ptpData = ptpData->tsArrPtr;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TSArrPtr.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGlobalGetConfig
*
* DESCRIPTION:
* This routine reads PTP global configuration parameters.
*
* INPUTS:
* None.
*
* OUTPUTS:
* ptpData - PTP global configuration parameters.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetGlobalConfig
(
IN GT_QD_DEV *dev,
OUT GT_PTP_GLOBAL_CONFIG *ptpData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpGetGlobalConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
ptpData->ptpEType = opData.ptpData;
/* getting MsgIDTSEn, offset 1 */
opData.ptpAddr = 1;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading MsgIDTSEn.\n"));
return GT_FAIL;
}
ptpData->msgIdTSEn = opData.ptpData;
/* getting TSArrPtr, offset 2 */
opData.ptpAddr = 2;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TSArrPtr.\n"));
return GT_FAIL;
}
ptpData->tsArrPtr = opData.ptpData;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetPortConfig
*
* DESCRIPTION:
* This routine writes PTP port configuration parameters.
*
* INPUTS:
* ptpData - PTP port configuration parameters.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetPortConfig
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_PTP_PORT_CONFIG *ptpData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 hwPort; /* the physical port number */
DBG_INFO(("gptpSetPortConfig Called.\n"));
/* translate LPORT to hardware port */
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_PTP_2))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
if (ptpData->transSpec > 0xF) /* 4 bits */
return GT_BAD_PARAM;
if (ptpData->etJump > 0x1F) /* 5 bits */
return GT_BAD_PARAM;
if (ptpData->ipJump > 0x3F) /* 6 bits */
return GT_BAD_PARAM;
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = hwPort;
/* TransSpec, DisTSpecCheck, DisTSOverwrite bit, offset 0 */
op = PTP_READ_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
op = PTP_WRITE_DATA;
opData.ptpData = (ptpData->transSpec << 12) | (opData.ptpData & 0x1) |
((ptpData->disTSpec?1:0) << 11) |
((ptpData->disTSOverwrite?1:0) << 1);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TransSpec,DisTSpecCheck,DisTSOverwrite.\n"));
return GT_FAIL;
}
/* setting etJump and ipJump, offset 1 */
opData.ptpAddr = 1;
opData.ptpData = (ptpData->ipJump << 8) | ptpData->etJump;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing MsgIDTSEn.\n"));
return GT_FAIL;
}
/* setting Int, offset 2 */
opData.ptpAddr = 2;
opData.ptpData = (ptpData->ptpArrIntEn?1:0) |
((ptpData->ptpDepIntEn?1:0) << 1);
if (IS_IN_DEV_GROUP(dev, DEV_ARRV_TS_MODE))
{
opData.ptpData |= ((ptpData->arrTSMode&0xff) << 8); /* from Agate to set ArrTSMode */
}
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TSArrPtr.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPortConfig
*
* DESCRIPTION:
* This routine reads PTP configuration parameters for a port.
*
* INPUTS:
* None.
*
* OUTPUTS:
* ptpData - PTP port configuration parameters.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetPortConfig
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
OUT GT_PTP_PORT_CONFIG *ptpData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 hwPort; /* the physical port number */
DBG_INFO(("gptpGetPortConfig Called.\n"));
/* translate LPORT to hardware port */
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_PTP_2))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = hwPort;
op = PTP_READ_DATA;
/* TransSpec, DisTSpecCheck, DisTSOverwrite bit, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
ptpData->transSpec = opData.ptpData >> 12;
ptpData->disTSpec = ((opData.ptpData >> 11) & 0x1) ? GT_TRUE : GT_FALSE;
ptpData->disTSOverwrite = ((opData.ptpData >> 1) & 0x1) ? GT_TRUE : GT_FALSE;
/* getting MsgIDTSEn, offset 1 */
opData.ptpAddr = 1;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading MsgIDTSEn.\n"));
return GT_FAIL;
}
ptpData->ipJump = (opData.ptpData >> 8) & 0x3F;
ptpData->etJump = opData.ptpData & 0x1F;
/* getting TSArrPtr, offset 2 */
opData.ptpAddr = 2;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TSArrPtr.\n"));
return GT_FAIL;
}
ptpData->ptpDepIntEn = ((opData.ptpData >> 1) & 0x1) ? GT_TRUE : GT_FALSE;
ptpData->ptpArrIntEn = (opData.ptpData & 0x1) ? GT_TRUE : GT_FALSE;
if (IS_IN_DEV_GROUP(dev, DEV_ARRV_TS_MODE))
{
ptpData->arrTSMode = (opData.ptpData &0xff00) >> 8; /* from Agate to get ArrTSMode */
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetPTPEn
*
* DESCRIPTION:
* This routine enables or disables PTP.
*
* INPUTS:
* en - GT_TRUE to enable PTP, GT_FALSE to disable PTP
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetPTPEn
(
IN GT_QD_DEV *dev,
IN GT_BOOL en
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_LPORT port;
DBG_INFO(("gptpSetPTPEn Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
#ifndef CONFIG_AVB_FPGA
if (IS_IN_DEV_GROUP(dev,DEV_PTP_2))
#endif
{
/* per port configuration */
for(port=0; port<dev->numOfPorts; port++)
{
if((retVal = gptpSetPortPTPEn(dev, port, en)) != GT_OK)
{
DBG_INFO(("Failed gptpSetPortPTPEn.\n"));
return GT_FAIL;
}
}
return GT_OK;
}
/* old PTP block */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
op = PTP_WRITE_DATA;
opData.ptpData &= ~0x1;
opData.ptpData |= (en ? 0 : 1);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing MsgIDStartBit & DisTSOverwrite.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPTPEn
*
* DESCRIPTION:
* This routine checks if PTP is enabled.
*
* INPUTS:
* None.
*
* OUTPUTS:
* en - GT_TRUE if enabled, GT_FALSE otherwise
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetPTPEn
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *en
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpGetPTPEn Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
#ifndef CONFIG_AVB_FPGA
if (IS_IN_DEV_GROUP(dev,DEV_PTP_2))
#endif
{
if((retVal = gptpGetPortPTPEn(dev, 0, en)) != GT_OK)
{
DBG_INFO(("Failed gptpGetPortPTPEn.\n"));
return GT_FAIL;
}
return GT_OK;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*en = (opData.ptpData & 0x1) ? GT_FALSE : GT_TRUE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetPortPTPEn
*
* DESCRIPTION:
* This routine enables or disables PTP on a port.
*
* INPUTS:
* en - GT_TRUE to enable PTP, GT_FALSE to disable PTP
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetPortPTPEn
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_BOOL en
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 hwPort;
DBG_INFO(("gptpSetPortPTPEn Called.\n"));
/* translate LPORT to hardware port */
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP_2))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpAddr = 0;
opData.ptpPort = hwPort;
op = PTP_READ_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
op = PTP_WRITE_DATA;
if (en)
opData.ptpData &= ~0x1;
else
opData.ptpData |= 0x1;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TransSpec,DisTSpecCheck,DisTSOverwrite.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPortPTPEn
*
* DESCRIPTION:
* This routine checks if PTP is enabled on a port.
*
* INPUTS:
* None.
*
* OUTPUTS:
* en - GT_TRUE if enabled, GT_FALSE otherwise
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetPortPTPEn
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
OUT GT_BOOL *en
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 hwPort;
DBG_INFO(("gptpGetPortPTPEn Called.\n"));
/* translate LPORT to hardware port */
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP_2))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpAddr = 0;
opData.ptpPort = hwPort;
op = PTP_READ_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*en = (opData.ptpData & 0x1) ? GT_FALSE : GT_TRUE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetPortTsMode
*
* DESCRIPTION:
* This routine set PTP arrive 0 TS mode on a port.
*
* INPUTS:
* tsMod - GT_PTP_TS_MODE_IN_REG
* GT_PTP_TS_MODE_IN_RESERVED_2
* GT_PTP_TS_MODE_IN_FRAME_END
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetPortTsMode
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_PTP_TS_MODE tsMode
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 hwPort;
DBG_INFO(("gptpSetPortTsMode Called.\n"));
/* translate LPORT to hardware port */
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP_2))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
if (!(IS_IN_DEV_GROUP(dev, DEV_ARRV_TS_MODE)))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpAddr = 2;
opData.ptpPort = hwPort;
op = PTP_READ_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TsMode.\n"));
return GT_FAIL;
}
op = PTP_WRITE_DATA;
opData.ptpData &= 0xff;
switch (tsMode)
{
case GT_PTP_TS_MODE_IN_REG:
break;
case GT_PTP_TS_MODE_IN_RESERVED_2:
opData.ptpData |= (PTP_TS_LOC_RESERVED_2<<8); /* set TS in reserved 1 */
break;
case GT_PTP_TS_MODE_IN_FRAME_END:
opData.ptpData |= (PTP_FRAME_SIZE<<8); /* set TS in end of PTP frame */
break;
default:
DBG_INFO(("GT_NOT_SUPPORTED the TS mode\n"));
return GT_NOT_SUPPORTED;
}
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing Ts Mode.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPortTsMode
*
* DESCRIPTION:
* This routine get PTP arrive 0 TS mode on a port.
*
* INPUTS:
* None.
*
* OUTPUTS:
* tsMod - GT_PTP_TS_MODE_IN_REG
* GT_PTP_TS_MODE_IN_RESERVED_2
* GT_PTP_TS_MODE_IN_FRAME_END
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetPortTsMode
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
OUT GT_PTP_TS_MODE *tsMode
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 hwPort;
GT_U16 tmpData;
DBG_INFO(("gptpGetPortTsMode Called.\n"));
/* translate LPORT to hardware port */
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP_2))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
if (!(IS_IN_DEV_GROUP(dev, DEV_ARRV_TS_MODE)))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpAddr = 2;
opData.ptpPort = hwPort;
op = PTP_READ_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TsMode.\n"));
return GT_FAIL;
}
tmpData = qdLong2Short(opData.ptpData >>8);
if (tmpData>=PTP_FRAME_SIZE)
*tsMode = GT_PTP_TS_MODE_IN_FRAME_END;
else if (tmpData == PTP_TS_LOC_RESERVED_2)
*tsMode = GT_PTP_TS_MODE_IN_RESERVED_2;
else
*tsMode = GT_PTP_TS_MODE_IN_REG;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPTPInt
*
* DESCRIPTION:
* This routine gets PTP interrupt status for each port.
* The PTP Interrupt bit gets set for a given port when an incoming PTP
* frame is time stamped and PTPArrIntEn for that port is set to 0x1.
* Similary PTP Interrupt bit gets set for a given port when an outgoing
* PTP frame is time stamped and PTPDepIntEn for that port is set to 0x1.
* This bit gets cleared upon software reading and clearing the corresponding
* time counter valid bits that are valid for that port.
*
* INPUTS:
* None.
*
* OUTPUTS:
* ptpInt - interrupt status for each port (bit 0 for port 0, bit 1 for port 1, etc.)
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetPTPInt
(
IN GT_QD_DEV *dev,
OUT GT_U32 *ptpInt
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpGetPTPInt Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xF; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 8;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
opData.ptpData &= (1 << dev->maxPorts) - 1;
*ptpInt = GT_PORTVEC_2_LPORTVEC(opData.ptpData);
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPTPGlobalTime
*
* DESCRIPTION:
* This routine gets the global timer value that is running off of the free
* running switch core clock.
*
* INPUTS:
* None.
*
* OUTPUTS:
* ptpTime - PTP global time
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetPTPGlobalTime
(
IN GT_QD_DEV *dev,
OUT GT_U32 *ptpTime
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpGetPTPGlobalTime Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
#ifndef USE_SINGLE_READ
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = IS_IN_DEV_GROUP(dev,DEV_TAI)?0xE:0xF; /* Global register */
op = PTP_READ_MULTIPLE_DATA;
opData.ptpAddr = IS_IN_DEV_GROUP(dev,DEV_TAI)?0xE:9;
opData.nData = 2;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*ptpTime = GT_PTP_BUILD_TIME(opData.ptpMultiData[1],opData.ptpMultiData[0]);
#else
{
GT_U32 data[2];
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = IS_IN_DEV_GROUP(dev,DEV_TAI)?0xE:0xF; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = IS_IN_DEV_GROUP(dev,DEV_TAI)?0xE:9;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
op = PTP_READ_DATA;
opData.ptpAddr++;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
*ptpTime = GT_PTP_BUILD_TIME(data[1],data[0]);
}
#endif
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetTimeStamped
*
* DESCRIPTION:
* This routine retrieves the PTP port status that includes time stamp value
* and sequce Id that are captured by PTP logic for a PTP frame that needs
* to be time stamped.
*
* INPUTS:
* port - logical port number.
* timeToRead - Arr0, Arr1, or Dep time (GT_PTP_TIME enum type)
*
* OUTPUTS:
* ptpStatus - PTP port status
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetTimeStamped
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_PTP_TIME timeToRead,
OUT GT_PTP_TS_STATUS *ptpStatus
)
{
GT_STATUS retVal;
GT_U32 hwPort;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 baseReg;
DBG_INFO(("gptpGetTimeStamped Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
if (hwPort == GT_INVALID_PORT)
{
DBG_INFO(("Invalid port number\n"));
return GT_BAD_PARAM;
}
#ifndef CONFIG_AVB_FPGA
if (IS_IN_DEV_GROUP(dev,DEV_PTP_2))
baseReg = 8;
else
baseReg = 0;
#else
baseReg = 8;
#endif
switch (timeToRead)
{
case PTP_ARR0_TIME:
opData.ptpAddr = baseReg + 0;
break;
case PTP_ARR1_TIME:
opData.ptpAddr = baseReg + 4;
break;
case PTP_DEP_TIME:
opData.ptpAddr = baseReg + 8;
break;
default:
DBG_INFO(("Invalid time to be read\n"));
return GT_BAD_PARAM;
}
opData.ptpPort = hwPort;
opData.ptpBlock = 0;
#ifndef USE_SINGLE_READ
op = PTP_READ_TIMESTAMP_DATA;
opData.nData = 4;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
ptpStatus->isValid = (opData.ptpMultiData[0] & 0x1) ? GT_TRUE : GT_FALSE;
ptpStatus->status = (GT_PTP_INT_STATUS)((opData.ptpMultiData[0] >> 1) & 0x3);
ptpStatus->timeStamped = GT_PTP_BUILD_TIME(opData.ptpMultiData[2],opData.ptpMultiData[1]);
ptpStatus->ptpSeqId = opData.ptpMultiData[3];
#else
{
GT_U32 data[4], i;
op = PTP_READ_DATA;
for (i=0; i<4; i++)
{
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
data[i] = opData.ptpData;
opData.ptpAddr++;
}
ptpStatus->isValid = (data[0] & 0x1) ? GT_TRUE : GT_FALSE;
ptpStatus->status = (GT_PTP_INT_STATUS)((data[0] >> 1) & 0x3);
ptpStatus->timeStamped = GT_PTP_BUILD_TIME(data[2],data[1]);
ptpStatus->ptpSeqId = data[3];
}
#endif
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpResetTimeStamp
*
* DESCRIPTION:
* This routine resets PTP Time valid bit so that PTP logic can time stamp
* a next PTP frame that needs to be time stamped.
*
* INPUTS:
* port - logical port number.
* timeToReset - Arr0, Arr1, or Dep time (GT_PTP_TIME enum type)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpResetTimeStamp
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_PTP_TIME timeToReset
)
{
GT_STATUS retVal;
GT_U32 hwPort;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 baseReg;
DBG_INFO(("gptpResetTimeStamp Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
hwPort = (GT_U32)GT_LPORT_2_PORT(port);
if (hwPort == GT_INVALID_PORT)
{
DBG_INFO(("Invalid port number\n"));
return GT_BAD_PARAM;
}
#ifndef CONFIG_AVB_FPGA
if (IS_IN_DEV_GROUP(dev,DEV_PTP_2))
baseReg = 8;
else
baseReg = 0;
#else
baseReg = 8;
#endif
switch (timeToReset)
{
case PTP_ARR0_TIME:
opData.ptpAddr = baseReg + 0;
break;
case PTP_ARR1_TIME:
opData.ptpAddr = baseReg + 4;
break;
case PTP_DEP_TIME:
opData.ptpAddr = baseReg + 8;
break;
default:
DBG_INFO(("Invalid time to reset\n"));
return GT_BAD_PARAM;
}
opData.ptpPort = hwPort;
opData.ptpData = 0;
opData.ptpBlock = 0;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing Port Status.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetReg
*
* DESCRIPTION:
* This routine reads PTP register.
*
* INPUTS:
* port - logical port number.
* regOffset - register to read
*
* OUTPUTS:
* data - register data
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetReg
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_U32 regOffset,
OUT GT_U32 *data
)
{
GT_STATUS retVal;
GT_U32 hwPort;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpGetReg Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
hwPort = (GT_U32)port;
if (regOffset > 0x1F)
{
DBG_INFO(("Invalid reg offset\n"));
return GT_BAD_PARAM;
}
op = PTP_READ_DATA;
opData.ptpPort = hwPort;
opData.ptpAddr = regOffset;
opData.ptpBlock = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*data = opData.ptpData;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetReg
*
* DESCRIPTION:
* This routine writes data to PTP register.
*
* INPUTS:
* port - logical port number
* regOffset - register to be written
* data - data to be written
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetReg
(
IN GT_QD_DEV *dev,
IN GT_LPORT port,
IN GT_U32 regOffset,
IN GT_U32 data
)
{
GT_STATUS retVal;
GT_U32 hwPort;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gptpSetReg Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_PTP))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
hwPort = (GT_U32)port;
if ((regOffset > 0x1F) || (data > 0xFFFF))
{
DBG_INFO(("Invalid reg offset/data\n"));
return GT_BAD_PARAM;
}
op = PTP_WRITE_DATA;
opData.ptpPort = hwPort;
opData.ptpAddr = regOffset;
opData.ptpData = data;
opData.ptpBlock = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/* TAI functions */
/*******************************************************************************
* gtaiSetEventConfig
*
* DESCRIPTION:
* This routine sets TAI Event Capture configuration parameters.
*
* INPUTS:
* eventData - TAI Event Capture configuration parameters.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetEventConfig
(
IN GT_QD_DEV *dev,
IN GT_TAI_EVENT_CONFIG *eventData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetEventConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
opData.ptpData &= ~((3<<14)|(1<<8));
if (eventData->intEn)
opData.ptpData |= (1 << 8);
if (eventData->eventOverwrite)
opData.ptpData |= (1 << 15);
if (eventData->eventCtrStart)
opData.ptpData |= (1 << 14);
if (IS_IN_DEV_GROUP(dev,DEV_TAI_EXT_CLK))
{
opData.ptpData &= ~(1<<13);
if (eventData->eventPhase)
opData.ptpData |= (1 << 13);
}
if (IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN)) /* after 6320 */
{
}
op = PTP_WRITE_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
if(IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN))
{
/* getting Capture trigger, offset 9 */
op = PTP_READ_DATA;
opData.ptpAddr = 9;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
opData.ptpData &= ~(1<<14);
opData.ptpData |= (eventData->captTrigEvent==GT_TRUE)?0x4000:0x0;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetEventConfig
*
* DESCRIPTION:
* This routine gets TAI Event Capture configuration parameters.
*
* INPUTS:
* None.
*
* OUTPUTS:
* eventData - TAI Event Capture configuration parameters.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetEventConfig
(
IN GT_QD_DEV *dev,
OUT GT_TAI_EVENT_CONFIG *eventData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetEventConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
eventData->intEn = (opData.ptpData & (1<<8))?GT_TRUE:GT_FALSE;
eventData->eventOverwrite = (opData.ptpData & (1<<15))?GT_TRUE:GT_FALSE;
eventData->eventCtrStart = (opData.ptpData & (1<<14))?GT_TRUE:GT_FALSE;
if (IS_IN_DEV_GROUP(dev,DEV_TAI_EXT_CLK))
{
eventData->eventPhase = (opData.ptpData & (1<<13))?GT_TRUE:GT_FALSE;
}
if(IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN))
{
/* getting Capture trigger, offset 9 */
op = PTP_READ_DATA;
opData.ptpAddr = 9;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
eventData->captTrigEvent = (opData.ptpData & (1<<14))?GT_TRUE:GT_FALSE;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetEventStatus
*
* DESCRIPTION:
* This routine gets TAI Event Capture status.
*
* INPUTS:
* None.
*
* OUTPUTS:
* eventData - TAI Event Capture configuration parameters.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetEventStatus
(
IN GT_QD_DEV *dev,
OUT GT_TAI_EVENT_STATUS *status
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 data[2];
DBG_INFO(("gtaiGetEventStatus Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 9;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
status->isValid = (opData.ptpData & (1<<8))?GT_TRUE:GT_FALSE;
status->eventCtr = opData.ptpData & 0xFF;
status->eventErr = (opData.ptpData & (1<<9))?GT_TRUE:GT_FALSE;
if (status->isValid == GT_FALSE)
{
return GT_OK;
}
opData.ptpAddr = 10;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
opData.ptpAddr = 11;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
status->eventTime = GT_PTP_BUILD_TIME(data[1],data[0]);
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetEventInt
*
* DESCRIPTION:
* This routine gets TAI Event Capture Interrupt status.
*
* INPUTS:
* None.
*
* OUTPUTS:
* intStatus - interrupt status for TAI Event capture
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetEventInt
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *intStatus
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetEventInt Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpPort = 0xE; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 9;
opData.ptpBlock = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*intStatus = (opData.ptpData & 0x8000)?GT_TRUE:GT_FALSE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiClearEventInt
*
* DESCRIPTION:
* This routine clear TAI Event Capture Interrupt status.
*
* INPUTS:
* None.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiClearEventInt
(
IN GT_QD_DEV *dev
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiClearEventInt Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpPort = 0xE; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 9;
opData.ptpBlock = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading eventInt.\n"));
return GT_FAIL;
}
opData.ptpData &= 0x7EFF;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing eventInt.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetClockSelect
*
* DESCRIPTION:
* This routine sets several clock select in TAI.
*
* INPUTS:
* clkSelect - TAI clock select configuration parameters.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetClockSelect
(
IN GT_QD_DEV *dev,
IN GT_TAI_CLOCK_SELECT *clkSelect
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetClockSelect Called.\n"));
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI_EXT_CLK))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting Tai clock select, offset 8 */
opData.ptpAddr = 8;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
opData.ptpData &= ~(0x4077);
opData.ptpData |= (((clkSelect->priRecClkSel)&7) << 0);
opData.ptpData |= (((clkSelect->syncRecClkSel)&7) << 4);
opData.ptpData |= (((clkSelect->ptpExtClk)&1) << 14);
op = PTP_WRITE_DATA;
opData.ptpAddr = 8;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetClockSelect
*
* DESCRIPTION:
* This routine gets several clock select in TAI.
*
* INPUTS:
* None.
*
* OUTPUTS:
* clkSelect - TAI clock select configuration parameters.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetClockSelect
(
IN GT_QD_DEV *dev,
OUT GT_TAI_CLOCK_SELECT *clkSelect
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetClockSelect Called.\n"));
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI_EXT_CLK))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting Tai clock select, offset 8 */
opData.ptpAddr = 8;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
clkSelect->priRecClkSel = qdLong2Char(opData.ptpData&7);
clkSelect->syncRecClkSel = qdLong2Char((opData.ptpData >> 4) & 7);
clkSelect->ptpExtClk = (opData.ptpData>> 14) & 1;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetTrigInt
*
* DESCRIPTION:
* This routine gets TAI Trigger Interrupt status.
*
* INPUTS:
* None.
*
* OUTPUTS:
* intStatus - interrupt status for TAI Trigger
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetTrigInt
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *intStatus
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetTrigInt Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpPort = 0xE; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 8;
opData.ptpBlock = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*intStatus = (opData.ptpData & 0x8000)?GT_TRUE:GT_FALSE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiClearTrigInt
*
* DESCRIPTION:
* This routine clear TAI Trigger Interrupt status.
*
* INPUTS:
* None.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiClearTrigInt
(
IN GT_QD_DEV *dev
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiClearTrigInt Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpPort = 0xE; /* Global register */
op = PTP_READ_DATA;
opData.ptpAddr = 8;
opData.ptpBlock = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpData &= 0x7fff;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTrigConfig
*
* DESCRIPTION:
* This routine sets TAI Trigger configuration parameters.
*
* INPUTS:
* trigEn - enable/disable TAI Trigger.
* trigData - TAI Trigger configuration parameters (valid only if trigEn is GT_TRUE).
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTrigConfig
(
IN GT_QD_DEV *dev,
IN GT_BOOL trigEn,
IN GT_TAI_TRIGGER_CONFIG *trigData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTrigConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
if (IS_IN_DEV_GROUP(dev,DEV_TAI_EXT_CLK))
{
if (trigData->trigPhase)
opData.ptpData |= (1 << 12);
}
opData.ptpData &= ~(3|(1<<9));
if (trigEn == GT_FALSE)
{
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
return GT_OK;
}
opData.ptpData |= 1;
if (trigData->intEn)
opData.ptpData |= (1 << 9);
if (trigData->mode == GT_TAI_TRIG_ON_GIVEN_TIME)
opData.ptpData |= (1 << 1);
op = PTP_WRITE_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 2;
opData.ptpData = GT_PTP_L16_TIME(trigData->trigGenAmt);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 3;
opData.ptpData = GT_PTP_H16_TIME(trigData->trigGenAmt);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
if (trigData->mode == GT_TAI_TRIG_ON_GIVEN_TIME)
{
if ((trigData->pulseWidth >= 0) && (trigData->pulseWidth <= 0xF))
{
op = PTP_READ_DATA;
opData.ptpAddr = 5; /* PulseWidth */
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
op = PTP_WRITE_DATA;
opData.ptpAddr = 5; /* PulseWidth */
opData.ptpData &= (~0xF000);
opData.ptpData |= (GT_U16)(trigData->pulseWidth << 12);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
}
}
else
{
op = PTP_WRITE_DATA;
opData.ptpAddr = 4; /* TrigClkComp */
opData.ptpData = (GT_U16)trigData->trigClkComp;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
}
if (IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN)) /* after 6320 */
{
op = PTP_WRITE_DATA;
opData.ptpAddr = 0x10;
opData.ptpData = GT_PTP_L16_TIME(trigData->trigGenTime);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x11;
opData.ptpData = GT_PTP_H16_TIME(trigData->trigGenTime);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x13;
opData.ptpData = GT_PTP_L16_TIME(trigData->trigGenDelay);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x12;
opData.ptpData = 0xF & GT_PTP_L16_TIME(trigData->lockCorrect);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x14;
opData.ptpData = GT_PTP_L16_TIME(trigData->trigGen2Time);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x15;
opData.ptpData = GT_PTP_H16_TIME(trigData->trigGen2Time);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x17;
opData.ptpData = GT_PTP_L16_TIME(trigData->trigGen2Delay);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
opData.ptpAddr = 0x16;
opData.ptpData = 0xF & GT_PTP_L16_TIME(trigData->lockCorrect2);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetTrigConfig
*
* DESCRIPTION:
* This routine gets TAI Trigger configuration parameters.
*
* INPUTS:
* None.
*
* OUTPUTS:
* trigEn - enable/disable TAI Trigger.
* trigData - TAI Trigger configuration parameters (valid only if trigEn is GT_TRUE).
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetTrigConfig
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *trigEn,
OUT GT_TAI_TRIGGER_CONFIG *trigData
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 data[2];
DBG_INFO(("gtaiGetTrigConfig Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
if (!(opData.ptpData & 1))
{
*trigEn = GT_FALSE;
return GT_OK;
}
if (trigData == NULL)
{
return GT_BAD_PARAM;
}
*trigEn = GT_TRUE;
trigData->mode = (opData.ptpData >> 1) & 1;
trigData->intEn = (opData.ptpData >> 9) & 1;
if (IS_IN_DEV_GROUP(dev,DEV_TAI_EXT_CLK))
{
trigData->trigPhase = (opData.ptpData >>12) & 1;
}
opData.ptpAddr = 2;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
opData.ptpAddr = 3;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
trigData->trigGenAmt = GT_PTP_BUILD_TIME(data[1],data[0]);
opData.ptpAddr = 5; /* PulseWidth */
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
trigData->pulseWidth = (GT_U32)((opData.ptpData >> 12) & 0xF);
/* getting TrigClkComp, offset 4 */
opData.ptpAddr = 4;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
trigData->trigClkComp = (GT_U32)opData.ptpData;
if (IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN)) /* after 6320 */
{
op = PTP_READ_DATA;
opData.ptpAddr = 0x10;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
opData.ptpAddr = 0x11;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
trigData->trigGenTime = GT_PTP_BUILD_TIME(data[1],data[0]);
opData.ptpAddr = 0x13;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
trigData->trigGenDelay = opData.ptpData;
opData.ptpAddr = 0x12;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
trigData->lockCorrect = 0xF & opData.ptpData;
opData.ptpAddr = 0x14;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
opData.ptpAddr = 0x15;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
trigData->trigGen2Time = GT_PTP_BUILD_TIME(data[1],data[0]);
opData.ptpAddr = 0x17;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
trigData->trigGen2Delay = opData.ptpData;
opData.ptpAddr = 0x16;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
trigData->lockCorrect2 = 0xF & opData.ptpData;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTrigLock
*
* DESCRIPTION:
* This routine sets TAI Trigger lock.
*
* INPUTS:
* trigLock - trigger lock set.
* trigLockRange - trigger lock range.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTrigLock
(
IN GT_QD_DEV *dev,
IN GT_BOOL trigLock,
IN GT_U8 trigLockRange
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTrigLock Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
if (!IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
opData.ptpData &= ~(0xf<<4);
opData.ptpData |= (trigLock==GT_TRUE) ?0x80:0;
opData.ptpData |= ((trigLockRange&0x7)<<4);
op = PTP_WRITE_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing PTPEType.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetTrigLock
*
* DESCRIPTION:
* This routine gets TAI Trigger lock and trigger lock range.
*
* INPUTS:
* None.
*
* OUTPUTS:
* trigLock - trigger lock set.
* trigLockRange - trigger lock range.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetTrigLock
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *trigLock,
OUT GT_U8 *trigLockRange
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetTrigLock Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
if (!IS_IN_DEV_GROUP(dev,DEV_TAI_TRIG_GEN))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
trigLock = (opData.ptpData&0x80)?GT_TRUE:GT_FALSE;
trigLockRange = (opData.ptpData&0x70)>>4;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetTSClkPer
*
* DESCRIPTION:
* Time Stamping Clock Period in pico seconds.
* This routine specifies the clock period for the time stamping clock supplied
* to the PTP hardware logic.
* This is the clock that is used by the hardware logic to update the PTP
* Global Time Counter.
*
* INPUTS:
* None.
*
* OUTPUTS:
* clk - time stamping clock period
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetTSClkPer
(
IN GT_QD_DEV *dev,
OUT GT_U32 *clk
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetTSClkPer Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 1;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*clk = (GT_U32)opData.ptpData;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTSClkPer
*
* DESCRIPTION:
* Time Stamping Clock Period in pico seconds.
* This routine specifies the clock period for the time stamping clock supplied
* to the PTP hardware logic.
* This is the clock that is used by the hardware logic to update the PTP
* Global Time Counter.
*
* INPUTS:
* clk - time stamping clock period
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTSClkPer
(
IN GT_QD_DEV *dev,
IN GT_U32 clk
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTSClkPer Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_WRITE_DATA;
opData.ptpAddr = 1;
opData.ptpData = (GT_U16)clk;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetMultiPTPSync
*
* DESCRIPTION:
* This routine sets Multiple PTP device sync mode and sync time (TrigGenAmt).
* When enabled, the hardware logic detects a low to high transition on the
* EventRequest(GPIO) and transfers the sync time into the PTP Global Time
* register. The EventCapTime is also updated at that instant.
*
* INPUTS:
* multiEn - enable/disable Multiple PTP device sync mode
* syncTime - sync time (valid only if multiEn is GT_TRUE)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* When enabled, gtaiSetTrigConfig, gtaiSetEventConfig, gtaiSetTimeInc,
* and gtaiSetTimeDec APIs are not operational.
*
*******************************************************************************/
GT_STATUS gtaiSetMultiPTPSync
(
IN GT_QD_DEV *dev,
IN GT_BOOL multiEn,
IN GT_32 syncTime
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetMultiPTPSync Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI_MULTI_PTP_SYNC))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
opData.ptpData &= ~(1 << 2);
if (multiEn == GT_FALSE)
{
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
return GT_OK;
}
opData.ptpData |= (1 << 2);
op = PTP_WRITE_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
opData.ptpAddr = 2;
opData.ptpData = GT_PTP_L16_TIME(syncTime);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
opData.ptpAddr = 3;
opData.ptpData = GT_PTP_H16_TIME(syncTime);
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetMultiPTPSync
*
* DESCRIPTION:
* This routine sets Multiple PTP device sync mode and sync time (TrigGenAmt).
* When enabled, the hardware logic detects a low to high transition on the
* EventRequest(GPIO) and transfers the sync time into the PTP Global Time
* register. The EventCapTime is also updated at that instant.
*
* INPUTS:
* None.
*
* OUTPUTS:
* multiEn - enable/disable Multiple PTP device sync mode
* syncTime - sync time (valid only if multiEn is GT_TRUE)
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_BAD_PARAM - if invalid parameter is given
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* When enabled, gtaiSetTrigConfig, gtaiSetEventConfig, gtaiSetTimeInc,
* and gtaiSetTimeDec APIs are not operational.
*
*******************************************************************************/
GT_STATUS gtaiGetMultiPTPSync
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *multiEn,
OUT GT_32 *syncTime
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 data[2];
DBG_INFO(("gtaiGetMultiPTPSync Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev,DEV_TAI_MULTI_PTP_SYNC))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
/* getting PTPEType, offset 0 */
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
if(!(opData.ptpData & (1 << 2)))
{
*multiEn = GT_FALSE;
*syncTime = 0;
return GT_OK;
}
opData.ptpAddr = 2;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
opData.ptpAddr = 3;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
*syncTime = GT_PTP_BUILD_TIME(data[1],data[0]);
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetTimeIncDec
*
* DESCRIPTION:
* This routine retrieves Time increment/decrement setup.
* This amount specifies the number of units of PTP Global Time that need to be
* incremented or decremented. This is used for adjusting the PTP Global Time
* counter value by a certain amount.
*
* INPUTS:
* None.
*
* OUTPUTS:
* expired - GT_TRUE if inc/dec occurred, GT_FALSE otherwise
* inc - GT_TRUE if increment, GT_FALSE if decrement
* amount - increment/decrement amount
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* Time increment or decrement will be excuted once.
*
*******************************************************************************/
GT_STATUS gtaiGetTimeIncDec
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *expired,
OUT GT_BOOL *inc,
OUT GT_U32 *amount
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiGetTimeIncDec Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*inc = (opData.ptpData & 0x800)?GT_FALSE:GT_TRUE;
*amount = (GT_U32)(opData.ptpData & 0x7FF);
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
*expired = (opData.ptpData & 0x8)?GT_FALSE:GT_TRUE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTimeInc
*
* DESCRIPTION:
* This routine enables time increment by the specifed time increment amount.
* The amount specifies the number of units of PTP Global Time that need to be
* incremented. This is used for adjusting the PTP Global Time counter value by
* a certain amount.
* Increment occurs just once.
*
* INPUTS:
* amount - time increment amount (0 ~ 0x7FF)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTimeInc
(
IN GT_QD_DEV *dev,
IN GT_U32 amount
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTimeInc Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
/* set TimeIncAmt */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
opData.ptpData &= 0xF000;
opData.ptpData |= amount;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
/* set TimeIncEn */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
opData.ptpData |= 0x8;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading DisPTP.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTimeDec
*
* DESCRIPTION:
* This routine enables time decrement by the specifed time decrement amount.
* The amount specifies the number of units of PTP Global Time that need to be
* decremented. This is used for adjusting the PTP Global Time counter value by
* a certain amount.
* Decrement occurs just once.
*
* INPUTS:
* amount - time decrement amount (0 ~ 0x7FF)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTimeDec
(
IN GT_QD_DEV *dev,
IN GT_U32 amount
)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTimeInc Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev,DEV_TAI))
{
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
/* set TimeIncAmt */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
opData.ptpData &= 0xF000;
opData.ptpData |= amount;
opData.ptpData |= 0x800; /* decrement */
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
/* set TimeIncEn */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 0;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
opData.ptpData |= 0x8;
op = PTP_WRITE_DATA;
if((retVal = ptpOperationPerform(dev, op, &opData)) != GT_OK)
{
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTimeIncDecAmt
*
* DESCRIPTION:
* This routine sets time decrement or increment amount.
* The amount specifies the number of units of PTP Global Time that need to be
* decremented or increased. This is used for adjusting the PTP Global Time counter value by
* a certain amount.
*
* INPUTS:
* amount - time decrement amount (0 ~ 0x7FF)
* dec - 0: increase, 1: descrease
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTimeIncDecAmt(IN GT_QD_DEV * dev, IN GT_BOOL dec, IN GT_U32 amount)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTimeIncDecAmt Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev, DEV_TAI)) {
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
/* set TimeIncAmt */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 5;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
opData.ptpData &= 0xF000;
opData.ptpData |= amount;
opData.ptpData |= (dec & 0x1) << 11; /* decrement */
op = PTP_WRITE_DATA;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiIncDecTimeEnable
*
* DESCRIPTION:
* This routine enables time decrement or increment by the specifed time decrement amount.
* The amount specifies the number of units of PTP Global Time that need to be
* decremented. This is used for adjusting the PTP Global Time counter value by
* a certain amount.
* Decrement occurs just once.
*
* INPUTS:
* None.
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiIncDecTimeEnable(IN GT_QD_DEV * dev)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiIncDecTimeEnable Called.\n"));
#ifndef CONFIG_AVB_FPGA
/* check if device supports this feature */
if (!IS_IN_DEV_GROUP(dev, DEV_TAI)) {
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
/* set TimeIncEn */
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 0;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed reading TAI register.\n"));
return GT_FAIL;
}
opData.ptpData |= 0x8;
op = PTP_WRITE_DATA;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed writing TAI register.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiSetTrigGenAmt
*
* DESCRIPTION:
* This routine sets the TrigGenAmt
*
* INPUTS:
* amount - Trigger Generation Time Amount (U32)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiSetTrigGenAmt(IN GT_QD_DEV * dev, IN GT_U32 amount)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiSetTrigGenAmt Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev, DEV_TAI)) {
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_WRITE_DATA;
opData.ptpAddr = 2;
opData.ptpData = GT_PTP_L16_TIME(amount);
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed writing TrigGenAmt.\n"));
return GT_FAIL;
}
opData.ptpAddr = 3;
opData.ptpData = GT_PTP_H16_TIME(amount);
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed writing TrigGenAmt.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiGetTrigGenAmt
*
* DESCRIPTION:
* This routine gets the TrigGenAmt
*
* OUTPUTS:
* amount - Trigger Generation Time Amount (U32)
*
* INPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiGetTrigGenAmt(IN GT_QD_DEV * dev, IN GT_U32 * amount)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
GT_U32 data[2];
DBG_INFO(("gtaiGetTrigGenAmt Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev, DEV_TAI)) {
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 2;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
data[0] = opData.ptpData;
opData.ptpAddr = 3;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
data[1] = opData.ptpData;
*amount = GT_PTP_BUILD_TIME(data[1], data[0]);
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gtaiTrigGenRequest
*
* DESCRIPTION:
* This routine requests TrigGen
*
* OUTPUTS:
* None.
*
* INPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gtaiTrigGenRequest(IN GT_QD_DEV * dev, IN GT_BOOL enable)
{
GT_STATUS retVal;
GT_PTP_OPERATION op;
GT_PTP_OP_DATA opData;
DBG_INFO(("gtaiTrigGenRequest Called.\n"));
/* check if device supports this feature */
#ifndef CONFIG_AVB_FPGA
if (!IS_IN_DEV_GROUP(dev, DEV_TAI)) {
DBG_INFO(("GT_NOT_SUPPORTED\n"));
return GT_NOT_SUPPORTED;
}
#endif
opData.ptpBlock = 0x0; /* PTP register space */
opData.ptpPort = 0xE; /* TAI register */
op = PTP_READ_DATA;
opData.ptpAddr = 0;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
opData.ptpData &= ~0x1;
opData.ptpData |= enable & 0x1;
op = PTP_WRITE_DATA;
retVal = ptpOperationPerform(dev, op, &opData);
if (retVal != GT_OK) {
DBG_INFO(("Failed reading PTPEType.\n"));
return GT_FAIL;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/****************************************************************************/
/* Internal functions. */
/****************************************************************************/
/*******************************************************************************
* ptpOperationPerform
*
* DESCRIPTION:
* This function accesses PTP Command Register and Data Register.
*
* INPUTS:
* ptpOp - The stats operation bits to be written into the stats
* operation register.
*
* OUTPUTS:
* ptpData - points to the data storage that the operation requires.
*
* RETURNS:
* GT_OK on success,
* GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS ptpOperationPerform
(
IN GT_QD_DEV *dev,
IN GT_PTP_OPERATION ptpOp,
INOUT GT_PTP_OP_DATA *opData
)
{
GT_STATUS retVal; /* Functions return value */
GT_U32 i;
#ifdef CONFIG_AVB_FPGA
GT_U32 tmpData;
#endif
gtSemTake(dev,dev->ptpRegsSem,OS_WAIT_FOREVER);
/* Wait until the ptp in ready. */
#ifndef CONFIG_AVB_FPGA
#ifdef GT_RMGMT_ACCESS
{
HW_DEV_REG_ACCESS regAccess;
regAccess.entries = 1;
regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[0].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[0].data = 15;
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
}
#else
{
GT_U16 data = 1;
while(data == 1)
{
retVal = hwGetGlobal2RegField(dev,QD_REG_PTP_COMMAND,15,1,&data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
}
#endif
#else /* CONFIG_AVB_FPGA */
{
GT_U16 data = 1;
while(data == 1)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,&tmpData);
data = (GT_U16)tmpData;
data = (data >> 15) & 0x1;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
}
#endif
/* Set the PTP Operation register */
switch (ptpOp)
{
case PTP_WRITE_DATA:
#ifndef CONFIG_AVB_FPGA
#ifdef GT_RMGMT_ACCESS
{
HW_DEV_REG_ACCESS regAccess;
regAccess.entries = 2;
regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[0].reg = QD_REG_PTP_DATA;
regAccess.rw_reg_list[0].data = (GT_U16)opData->ptpData;
regAccess.rw_reg_list[1].cmd = HW_REG_WRITE;
regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[1].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[1].data = (GT_U16)((1 << 15) | (PTP_WRITE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
}
#else
{
GT_U16 data;
data = (GT_U16)opData->ptpData;
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_DATA,data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = (GT_U16)((1 << 15) | (PTP_WRITE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_COMMAND,data);
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
#endif
#else /* CONFIG_AVB_FPGA */
{
GT_U16 data;
data = (GT_U16)opData->ptpData;
tmpData = (GT_U32)data;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_DATA,tmpData);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = (GT_U16)((1 << 15) | (PTP_WRITE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
tmpData = (GT_U32)data;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,tmpData);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
#endif
break;
case PTP_READ_DATA:
#ifndef CONFIG_AVB_FPGA
#ifdef GT_RMGMT_ACCESS
{
HW_DEV_REG_ACCESS regAccess;
regAccess.entries = 3;
regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
#ifndef CONFIG_AVB_FPGA
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
#else
regAccess.rw_reg_list[0].addr = AVB_SMI_ADDR;
#endif
regAccess.rw_reg_list[0].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[0].data = (GT_U16)((1 << 15) | (PTP_READ_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
regAccess.rw_reg_list[1].cmd = HW_REG_WAIT_TILL_0;
#ifndef CONFIG_AVB_FPGA
regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
#else
regAccess.rw_reg_list[1].addr = AVB_SMI_ADDR;
#endif
regAccess.rw_reg_list[1].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[1].data = 15;
regAccess.rw_reg_list[2].cmd = HW_REG_READ;
#ifndef CONFIG_AVB_FPGA
regAccess.rw_reg_list[2].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
#else
regAccess.rw_reg_list[2].addr = AVB_SMI_ADDR;
#endif
regAccess.rw_reg_list[2].reg = QD_REG_PTP_DATA;
regAccess.rw_reg_list[2].data = 0;
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
opData->ptpData = (GT_U32) regAccess.rw_reg_list[2].data;
}
#else
{
GT_U16 data;
data = (GT_U16)((1 << 15) | (PTP_READ_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_COMMAND,data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = 1;
while(data == 1)
{
retVal = hwGetGlobal2RegField(dev,QD_REG_PTP_COMMAND,15,1,&data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
retVal = hwReadGlobal2Reg(dev,QD_REG_PTP_DATA,&data);
opData->ptpData = (GT_U32)data;
}
#endif
#else /*CONFIG_AVB_FPGA */
{
GT_U16 data;
data = (GT_U16)((1 << 15) | (PTP_READ_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
tmpData = (GT_U32)data;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,tmpData);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = 1;
while(data == 1)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,&tmpData);
data = (GT_U32)tmpData;
data = (data >> 15) & 0x1;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_DATA,&tmpData);
data = (GT_U32)tmpData;
opData->ptpData = (GT_U32)data;
}
#endif
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
case PTP_READ_MULTIPLE_DATA:
#ifndef CONFIG_AVB_FPGA
#ifdef GT_RMGMT_ACCESS
{
HW_DEV_REG_ACCESS regAccess;
regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[0].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[0].data = (GT_U16)((1 << 15) | (PTP_READ_MULTIPLE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
regAccess.rw_reg_list[1].cmd = HW_REG_WAIT_TILL_0;
regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[1].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[1].data = 15;
for(i=0; i<opData->nData; i++)
{
regAccess.rw_reg_list[2+i].cmd = HW_REG_READ;
regAccess.rw_reg_list[2+i].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[2+i].reg = QD_REG_PTP_DATA;
regAccess.rw_reg_list[2+i].data = 0;
}
regAccess.entries = 2+i;
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
for(i=0; i<opData->nData; i++)
{
opData->ptpMultiData[i] = (GT_U32) regAccess.rw_reg_list[2+i].data;
}
}
#else
{
GT_U16 data;
data = (GT_U16)((1 << 15) | (PTP_READ_MULTIPLE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_COMMAND,data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = 1;
while(data == 1)
{
retVal = hwGetGlobal2RegField(dev,QD_REG_PTP_COMMAND,15,1,&data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
for(i=0; i<opData->nData; i++)
{
retVal = hwReadGlobal2Reg(dev,QD_REG_PTP_DATA,&data);
opData->ptpMultiData[i] = (GT_U32)data;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
}
#endif
#else /* CONFIG_AVB_FPGA */
{
GT_U16 data;
data = (GT_U16)((1 << 15) | (PTP_READ_MULTIPLE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
tmpData = (GT_U32)data;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,tmpData);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = 1;
while(data == 1)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,&tmpData);
data = (GT_U32)tmpData;
data = (data >> 15) & 0x1;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
for(i=0; i<opData->nData; i++)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_DATA,&tmpData);
data = (GT_U32)tmpData;
opData->ptpMultiData[i] = (GT_U32)data;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
}
#endif
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
case PTP_READ_TIMESTAMP_DATA:
#ifndef CONFIG_AVB_FPGA
#ifdef GT_RMGMT_ACCESS
{
HW_DEV_REG_ACCESS regAccess;
regAccess.entries = 3;
regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[0].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[0].data = (GT_U16)((1 << 15) | (PTP_READ_MULTIPLE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
regAccess.rw_reg_list[1].cmd = HW_REG_WAIT_TILL_0;
regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[1].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[1].data = 15;
regAccess.rw_reg_list[2].cmd = HW_REG_READ;
regAccess.rw_reg_list[2].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[2].reg = QD_REG_PTP_DATA;
regAccess.rw_reg_list[2].data = 0;
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
opData->ptpMultiData[0] = (GT_U32) regAccess.rw_reg_list[2].data;
if (!(opData->ptpMultiData[0] & 0x1))
{
/* valid bit is not set */
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
for(i=0; i<(opData->nData-1); i++)
{
regAccess.rw_reg_list[i].cmd = HW_REG_READ;
regAccess.rw_reg_list[i].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[i].reg = QD_REG_PTP_DATA;
regAccess.rw_reg_list[i].data = 0;
}
regAccess.entries = i;
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
for(i=0; i<(opData->nData-1); i++)
{
opData->ptpMultiData[i+1] = (GT_U32) regAccess.rw_reg_list[i].data;
}
regAccess.entries = 2;
regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[0].reg = QD_REG_PTP_DATA;
regAccess.rw_reg_list[0].data = (GT_U16)0;
regAccess.rw_reg_list[1].cmd = HW_REG_WRITE;
regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[1].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[1].data = (GT_U16)((1 << 15) | (PTP_WRITE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
}
#else
{
GT_U16 data;
data = (GT_U16)((1 << 15) | (PTP_READ_MULTIPLE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_COMMAND,data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = 1;
while(data == 1)
{
retVal = hwGetGlobal2RegField(dev,QD_REG_PTP_COMMAND,15,1,&data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
retVal = hwReadGlobal2Reg(dev,QD_REG_PTP_DATA,&data);
opData->ptpMultiData[0] = (GT_U32)data;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
if (!(data & 0x1))
{
/* valid bit is not set */
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
for(i=1; i<opData->nData; i++)
{
retVal = hwReadGlobal2Reg(dev,QD_REG_PTP_DATA,&data);
opData->ptpMultiData[i] = (GT_U32)data;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_DATA,0);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = (GT_U16)((1 << 15) | (PTP_WRITE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
retVal = hwWriteGlobal2Reg(dev,QD_REG_PTP_COMMAND,data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
#endif
#else /* CONFIG_AVB_FPGA */
{
GT_U16 data;
data = (GT_U16)((1 << 15) | (PTP_READ_MULTIPLE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
tmpData = (GT_U32)data;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,tmpData);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = 1;
while(data == 1)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,&tmpData);
data = (GT_U32)tmpData;
data = (data >> 15) & 0x1;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_DATA,&tmpData);
data = (GT_U32)tmpData;
opData->ptpMultiData[0] = (GT_U32)data;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
if (!(data & 0x1))
{
/* valid bit is not set */
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
for(i=1; i<opData->nData; i++)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_DATA,&tmpData);
data = (GT_U32)tmpData;
opData->ptpMultiData[i] = (GT_U32)data;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_DATA,0);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
data = (GT_U16)((1 << 15) | (PTP_WRITE_DATA << 12) |
(opData->ptpPort << 8) |
(opData->ptpBlock << 5) |
(opData->ptpAddr & 0x1F));
tmpData = (GT_U32)data;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,tmpData);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
#endif
gtSemGive(dev,dev->ptpRegsSem);
break;
default:
gtSemGive(dev,dev->ptpRegsSem);
return GT_FAIL;
}
/* Wait until the ptp is ready. */
#ifndef CONFIG_AVB_FPGA
#ifdef GT_RMGMT_ACCESS
{
HW_DEV_REG_ACCESS regAccess;
regAccess.entries = 1;
regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
regAccess.rw_reg_list[0].reg = QD_REG_PTP_COMMAND;
regAccess.rw_reg_list[0].data = 15;
retVal = hwAccessMultiRegs(dev, &regAccess);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->tblRegsSem);
return retVal;
}
}
#else
{
GT_U16 data;
data = 1;
while(data == 1)
{
retVal = hwGetGlobal2RegField(dev,QD_REG_PTP_COMMAND,15,1,&data);
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
}
#endif
#else /* CONFIG_AVB_FPGA */
{
GT_U16 data;
data = 1;
while(data == 1)
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_COMMAND,&tmpData);
data = (GT_U16)tmpData;
data = (data >> 15) & 0x1;
if(retVal != GT_OK)
{
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
}
}
#endif
gtSemGive(dev,dev->ptpRegsSem);
return retVal;
}
#ifdef CONFIG_AVB_FPGA
/*******************************************************************************
* gptpGetFPGAIntStatus
*
* DESCRIPTION:
* This routine gets interrupt status of PTP logic.
*
* INPUTS:
* None.
*
* OUTPUTS:
* ptpInt - PTP Int Status
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetFPGAIntStatus
(
IN GT_QD_DEV *dev,
OUT GT_U32 *ptpInt
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetPTPIntStatus Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_INT_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
*ptpInt = (GT_U32)data & 0x1;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetFPGAIntStatus
*
* DESCRIPTION:
* This routine sets interrupt status of PTP logic.
*
* INPUTS:
* ptpInt - PTP Int Status
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetFPGAIntStatus
(
IN GT_QD_DEV *dev,
OUT GT_U32 ptpInt
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpSetPTPIntStatus Called.\n"));
data = ptpInt?1:0;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_INT_OFFSET,ptpInt);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetFPGAIntEn
*
* DESCRIPTION:
* This routine enables PTP interrupt.
*
* INPUTS:
* ptpInt - PTP Int Status (1 to enable, 0 to disable)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetFPGAIntEn
(
IN GT_QD_DEV *dev,
IN GT_U32 ptpInt
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetPTPIntEn Called.\n"));
data = (ptpInt == 0)?0:1;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_INTEN_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetClockSource
*
* DESCRIPTION:
* This routine gets PTP Clock source setup.
*
* INPUTS:
* None.
*
* OUTPUTS:
* clkSrc - PTP clock source (A/D Device or FPGA)
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetClockSource
(
IN GT_QD_DEV *dev,
OUT GT_PTP_CLOCK_SRC *clkSrc
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetClockSource Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_SRC_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
*clkSrc = (GT_PTP_CLOCK_SRC)(data & 0x1);
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetClockSource
*
* DESCRIPTION:
* This routine sets PTP Clock source setup.
*
* INPUTS:
* clkSrc - PTP clock source (A/D Device or FPGA)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetClockSource
(
IN GT_QD_DEV *dev,
IN GT_PTP_CLOCK_SRC clkSrc
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpSetClockSource Called.\n"));
data = (GT_U32)clkSrc;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_SRC_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetP9Mode
*
* DESCRIPTION:
* This routine gets Port 9 Mode.
*
* INPUTS:
* None.
*
* OUTPUTS:
* mode - Port 9 mode (GT_PTP_P9_MODE enum type)
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetP9Mode
(
IN GT_QD_DEV *dev,
OUT GT_PTP_P9_MODE *mode
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetP9Mode Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_P9_MODE_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
if (data & 0x1)
{
switch (data & 0x6)
{
case 0:
*mode = PTP_P9_MODE_GMII;
break;
case 2:
*mode = PTP_P9_MODE_MII;
break;
case 4:
*mode = PTP_P9_MODE_MII_CONNECTOR;
break;
default:
return GT_BAD_PARAM;
}
}
else
{
*mode = PTP_P9_MODE_JUMPER;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetP9Mode
*
* DESCRIPTION:
* This routine sets Port 9 Mode.
*
* INPUTS:
* mode - Port 9 mode (GT_PTP_P9_MODE enum type)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetP9Mode
(
IN GT_QD_DEV *dev,
IN GT_PTP_P9_MODE mode
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpSetP9Mode Called.\n"));
switch (mode)
{
case PTP_P9_MODE_GMII:
data = 1;
break;
case PTP_P9_MODE_MII:
data = 3;
break;
case PTP_P9_MODE_MII_CONNECTOR:
data = 5;
break;
case PTP_P9_MODE_JUMPER:
data = 0;
break;
default:
return GT_BAD_PARAM;
}
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_P9_MODE_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpReset
*
* DESCRIPTION:
* This routine performs software reset for PTP logic.
*
* INPUTS:
* None.
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpReset
(
IN GT_QD_DEV *dev
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpReset Called.\n"));
data = 1;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_RESET_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetCycleAdjustEn
*
* DESCRIPTION:
* This routine checks if PTP Duty Cycle Adjustment is enabled.
*
* INPUTS:
* None.
*
* OUTPUTS:
* adjEn - GT_TRUE if enabled, GT_FALSE otherwise
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetCycleAdjustEn
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *adjEn
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetCycleAdjustEn Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
*adjEn = (data & 0x2)?GT_TRUE:GT_FALSE;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetCycleAdjustEn
*
* DESCRIPTION:
* This routine enables/disables PTP Duty Cycle Adjustment.
*
* INPUTS:
* adjEn - GT_TRUE to enable, GT_FALSE to disable
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetCycleAdjustEn
(
IN GT_QD_DEV *dev,
IN GT_BOOL adjEn
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetCycleAdjustEn Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
if (adjEn == GT_FALSE)
data &= ~0x3; /* clear both Enable bit and Valid bit */
else
data |= 0x2;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetCycleAdjust
*
* DESCRIPTION:
* This routine gets clock duty cycle adjustment value.
*
* INPUTS:
* None.
*
* OUTPUTS:
* adj - adjustment value (GT_PTP_CLOCK_ADJUSTMENT structure)
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetCycleAdjust
(
IN GT_QD_DEV *dev,
OUT GT_PTP_CLOCK_ADJUSTMENT *adj
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetCycleAdjust Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
adj->adjSign = (data & 0x4)?GT_PTP_SIGN_PLUS:GT_PTP_SIGN_NEGATIVE;
adj->cycleStep = (data >> 3) & 0x7;
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CYCLE_INTERVAL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
adj->cycleInterval = data;
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CYCLE_ADJ_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
adj->cycleAdjust = data;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetCycleAdjust
*
* DESCRIPTION:
* This routine sets clock duty cycle adjustment value.
*
* INPUTS:
* adj - adjustment value (GT_PTP_CLOCK_ADJUSTMENT structure)
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetCycleAdjust
(
IN GT_QD_DEV *dev,
IN GT_PTP_CLOCK_ADJUSTMENT *adj
)
{
GT_STATUS retVal;
GT_U32 data;
GT_U32 data1;
DBG_INFO(("gptpSetCycleAdjust Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
data &= ~0x1; /* clear Valid bit */
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
/* Setup the Cycle Interval */
data1 = adj->cycleInterval & 0xFFFF;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CYCLE_INTERVAL_OFFSET,data1);
if(retVal != GT_OK)
{
return retVal;
}
/* Setup the Cycle Adjustment */
data1 = adj->cycleAdjust & 0xFFFF;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CYCLE_ADJ_OFFSET,data1);
if(retVal != GT_OK)
{
return retVal;
}
/* clear Sign bit and Cycle Step bits on QD_REG_PTP_CLK_CTRL_OFFSET value */
data &= ~0x3C;
switch (adj->adjSign)
{
case GT_PTP_SIGN_PLUS:
data |= 0x4;
break;
case GT_PTP_SIGN_NEGATIVE:
break;
default:
return GT_BAD_PARAM;
}
data |= ((adj->cycleStep & 0x7) << 3); /* setup Step bits */
data |= 0x1; /* set Valid bit */
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_CLK_CTRL_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetPLLEn
*
* DESCRIPTION:
* This routine checks if PLL is enabled.
*
* INPUTS:
* None.
*
* OUTPUTS:
* en - GT_TRUE if enabled, GT_FALSE otherwise
* freqSel - PLL Frequency Selection (default 0x3 - 22.368MHz)
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* PLL Frequence selection is based on the Clock Recovery PLL device.
* IDT MK1575-01 is the default PLL device.
*
*******************************************************************************/
GT_STATUS gptpGetPLLEn
(
IN GT_QD_DEV *dev,
OUT GT_BOOL *en,
OUT GT_U32 *freqSel
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpGetPLLEn Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_PLL_CTRL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
*en = (data & 0x1)?GT_TRUE:GT_FALSE;
*freqSel = (data >> 1) & 0x7;
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetPLLEn
*
* DESCRIPTION:
* This routine enables/disables PLL device.
*
* INPUTS:
* en - GT_TRUE to enable, GT_FALSE to disable
* freqSel - PLL Frequency Selection (default 0x3 - 22.368MHz)
* Meaningful only when enabling PLL device
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* PLL Frequence selection is based on the Clock Recovery PLL device.
* IDT MK1575-01 is the default PLL device.
*
*******************************************************************************/
GT_STATUS gptpSetPLLEn
(
IN GT_QD_DEV *dev,
IN GT_BOOL en,
IN GT_U32 freqSel
)
{
GT_STATUS retVal;
GT_U32 data;
DBG_INFO(("gptpSetPPLEn Called.\n"));
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_PLL_CTRL_OFFSET,&data);
if(retVal != GT_OK)
{
return retVal;
}
if(en == GT_FALSE)
{
data |= 0x1;
}
else
{
data &= ~0x1;
data |= (freqSel & 0x7) << 1;
}
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,QD_REG_PTP_PLL_CTRL_OFFSET,data);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpGetDDSReg
*
* DESCRIPTION:
* This routine gets DDS register data.
*
* INPUTS:
* ddsReg - DDS Register
*
* OUTPUTS:
* ddsData - register data
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpGetDDSReg
(
IN GT_QD_DEV *dev,
IN GT_U32 ddsReg,
OUT GT_U32 *ddsData
)
{
GT_STATUS retVal;
GT_U32 data;
GT_U32 timeout = 0x100000;
DBG_INFO(("gptpGetDDSReg Called.\n"));
if (ddsReg > 0x3f)
return GT_BAD_PARAM;
do
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,12,&data);
if (retVal != GT_OK)
return retVal;
timeout--;
if (timeout == 0)
return GT_FAIL;
} while (data & 0x8000);
data = 0x8000 | 0x4000 | (ddsReg << 8);
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,12,data);
if(retVal != GT_OK)
{
return retVal;
}
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,12,&data);
if (retVal != GT_OK)
return retVal;
*ddsData = data & 0xFF;
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,12,0);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetDDSReg
*
* DESCRIPTION:
* This routine sets DDS register data.
* DDS register data written by this API are not affected until gptpUpdateDDSReg API is called.
*
* INPUTS:
* ddsReg - DDS Register
* ddsData - register data
*
* OUTPUTS:
* none
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetDDSReg
(
IN GT_QD_DEV *dev,
IN GT_U32 ddsReg,
IN GT_U32 ddsData
)
{
GT_STATUS retVal;
GT_U32 data;
GT_U32 timeout = 0x100000;
DBG_INFO(("gptpSetDDSReg Called.\n"));
if ((ddsReg > 0x3f) || (ddsData > 0xff))
return GT_BAD_PARAM;
do
{
retVal = AVB_FPGA_READ_REG(dev,AVB_SMI_ADDR,12,&data);
if (retVal != GT_OK)
return retVal;
timeout--;
if (timeout == 0)
return GT_FAIL;
} while (data & 0x8000);
data = 0x8000 | (ddsReg << 8) | (ddsData);
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,12,data);
if(retVal != GT_OK)
{
return retVal;
}
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,12,0);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpUpdateDDSReg
*
* DESCRIPTION:
* This routine updates DDS register data.
* DDS register data written by gptpSetDDSReg are not affected until this API is called.
*
* INPUTS:
* none
*
* OUTPUTS:
* none
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpUpdateDDSReg
(
IN GT_QD_DEV *dev
)
{
GT_STATUS retVal;
DBG_INFO(("gptpUpdateDDSReg Called.\n"));
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,13,0x0);
if(retVal != GT_OK)
{
return retVal;
}
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,13,0x1);
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
/*******************************************************************************
* gptpSetADFReg
*
* DESCRIPTION:
* This routine sets ADF4156 register data.
*
* INPUTS:
* adfData - register data
*
* OUTPUTS:
* none
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
* GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
* None
*
*******************************************************************************/
GT_STATUS gptpSetADFReg
(
IN GT_QD_DEV *dev,
IN GT_U32 adfData
)
{
GT_STATUS retVal;
DBG_INFO(("gptpSetADFReg Called.\n"));
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,14,(adfData & 0xFFFF));
if(retVal != GT_OK)
{
return retVal;
}
retVal = AVB_FPGA_WRITE_REG(dev,AVB_SMI_ADDR,15,((adfData>>16) & 0xFFFF));
if(retVal != GT_OK)
{
return retVal;
}
DBG_INFO(("OK.\n"));
return GT_OK;
}
#endif /* CONFIG_AVB_FPGA */