blob: 089189d0b27f016a4087ce4ec1ce25f355a69738 [file] [log] [blame]
/*******************************************************************************
* Copyright 2001, Marvell International Ltd.
* This code contains confidential information of Marvell semiconductor, inc.
* no rights are granted herein under any patent, mask work right or copyright
* of Marvell or any third party.
* Marvell reserves the right at its sole discretion to request that this code
* be immediately returned to Marvell. This code is provided "as is".
* Marvell makes no warranties, express, implied or otherwise, regarding its
* accuracy, completeness or performance.
********************************************************************************
* mvHwsDdr3BobK.c
*
* DESCRIPTION: DDR3 BobK configuration
*
* DEPENDENCIES:
******************************************************************************/
#define DEFINE_GLOBALS
#include "ddr3_msys_bobk.h"
#include "mvHwsDdr3BobK.h"
#include "mvDdr3TrainingIpStatic.h"
#include "mvDdr3TrainingIpFlow.h"
#include "mvDdrTrainingIpDb.h"
#include "mvDdr3TrainingIp.h"
#include "mvDdr3TrainingIpDef.h"
#include "mvDdr3TrainingIpPrvIf.h"
#include "mvDdr3LoggingDef.h"
/************************** definitions ******************************/
#define BOBK_NUM_BYTES (3)
#define BOBK_CLIENT_FIELD(client) (client << 15)
#define BOBK_GET_CLIENT_FIELD(interfaceAccess,interfaceId) ((interfaceAccess == ACCESS_TYPE_MULTICAST) ? BOBK_CLIENT_FIELD(MULTICAST_ID):BOBK_CLIENT_FIELD(interfaceId))
#define BOBK_XSB_MAPPING(interfaceId, interfaceAccess, regaddr) (regaddr+ XSB_BASE_ADDR + BOBK_GET_CLIENT_FIELD(interfaceAccess,interfaceMap[interfaceId].client))
#if 0
#define CS_CBE_VALUE(csNum) (csCbeReg[csNum])
#endif
#define BOBK_CLIENT_MAPPING(interfaceId, regaddr) ((regaddr << 2)+ CLIENT_BASE_ADDR + BOBK_CLIENT_FIELD(interfaceMap[interfaceId].client))
#define TM_PLL_REG_DATA(a,b,c) ((a << 12) + (b << 8) + (c << 2))
#define R_MOD_W(writeData,readData,mask) ((writeData & mask) | (readData & (~mask)))
/************************** pre-declaration ******************************/
static GT_STATUS ddr3TipBobKGetMediumFreq
(
GT_U32 devNum,
GT_U32 interfaceId,
MV_HWS_DDR_FREQ *freq
);
GT_STATUS ddr3TipBobKSetDivider
(
GT_U8 devNum,
GT_U32 interfaceId,
MV_HWS_DDR_FREQ freq
);
static GT_STATUS ddr3TipTmSetDivider
(
GT_U8 devNum,
GT_U8 interfaceId,
MV_HWS_DDR_FREQ frequency
);
static GT_STATUS ddr3TipCpuSetDivider
(
GT_U8 devNum,
GT_U8 interfaceId,
MV_HWS_DDR_FREQ frequency
);
GT_STATUS ddr3BobKUpdateTopologyMap
(
GT_U32 devNum,
MV_HWS_TOPOLOGY_MAP* topologyMap
);
GT_STATUS ddr3TipBobKGetInitFreq
(
GT_U8 devNum,
GT_U32 interfaceId,
MV_HWS_DDR_FREQ* freq
);
GT_STATUS ddr3TipTmGetInitFreq
(
GT_STATUS devNum,
MV_HWS_DDR_FREQ *freq
);
static GT_STATUS ddr3TipCpuGetInitFreq
(
GT_STATUS devNum,
MV_HWS_DDR_FREQ *freq
);
GT_STATUS ddr3TipBobKRead
(
GT_U8 devNum,
GT_U32 regAddr,
GT_U32 *data,
GT_U32 mask
);
GT_STATUS ddr3TipBobKWrite
(
GT_U8 devNum,
GT_U32 regAddr,
GT_U32 dataValue,
GT_U32 mask
);
GT_STATUS ddr3TipBobKIFRead
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 *data,
GT_U32 mask
);
GT_STATUS ddr3TipBobKIFWrite
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 dataValue,
GT_U32 mask
);
GT_STATUS ddr3TipBobKIsfAccessDone
(
GT_U32 devNum,
GT_U32 interfaceId
);
GT_STATUS ddr3TipBobKGetDeviceInfo
(
GT_U8 devNum,
MV_DDR3_DEVICE_INFO * infoPtr
);
/************************** Globals ******************************/
extern GT_U32 maskTuneFunc;
extern GT_U32 freqVal[];
extern MV_HWS_DDR_FREQ mediumFreq;
extern MV_HWS_TOPOLOGY_MAP *topologyMap;
extern GT_U32 firstActiveIf;
extern MV_HWS_DDR_FREQ initFreq;
extern GT_U32 dfsLowFreq;
extern GT_U32 dfsLowPhy1;
extern GT_U32 PhyReg1Val;
extern GT_U32 isPllBeforeInit;
extern GT_U32 useBroadcast;
extern GT_U32 isCbeRequired;
extern GT_U32 delayEnable, ckDelay,caDelay;
extern GT_U8 debugTrainingAccess;
extern GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
extern GT_U32 dfsLowFreq;
GT_U32 debugBobK = 0;
GT_U32 pipeMulticastMask;
#if 0
static GT_U32 csCbeReg[]=
{
0xE , 0xD, 0xB, 0x7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
static MV_DFX_ACCESS interfaceMap[] =
{
/* Pipe Client*/
{ 0, 16 },
{ 3, 18 },
{ 1, 10 },
{ 3, 1 }
};
static GT_U8 bobKBwPerFreq[DDR_FREQ_LIMIT] =
{
0x3, /*DDR_FREQ_LOW_FREQ*/
0x4, /*DDR_FREQ_400*/
0x4, /*DDR_FREQ_533*/
0x5, /*DDR_FREQ_667*/
0x5, /*DDR_FREQ_800*/
0x5, /*DDR_FREQ_933,*/
0x5, /*DDR_FREQ_1066*/
0x3, /*DDR_FREQ_311*/
0x3, /*DDR_FREQ_333*/
0x4, /*DDR_FREQ_467*/
0x5, /*DDR_FREQ_850*/
0x5, /*DDR_FREQ_600*/
0x3, /*DDR_FREQ_300*/
0x5, /*DDR_FREQ_900*/
0x3 /*DDR_FREQ_360*/
};
static GT_U8 bobKRatePerFreq[DDR_FREQ_LIMIT] =
{
0x1, /*DDR_FREQ_LOW_FREQ,*/
0x2, /*DDR_FREQ_400,*/
0x2, /*DDR_FREQ_533,*/
0x2, /*DDR_FREQ_667,*/
0x2, /*DDR_FREQ_800,*/
0x3, /*DDR_FREQ_933,*/
0x3, /*DDR_FREQ_1066,*/
0x1, /*DDR_FREQ_311*/
0x1, /*DDR_FREQ_333*/
0x2, /*DDR_FREQ_467*/
0x2, /*DDR_FREQ_850*/
0x2, /*DDR_FREQ_600*/
0x1, /*DDR_FREQ_300*/
0x3, /*DDR_FREQ_900*/
0x1 /*DDR_FREQ_360*/
};
GT_U32 phy1ValTable[DDR_FREQ_LIMIT] =
{
0, /* DDR_FREQ_LOW_FREQ */
0xf, /* DDR_FREQ_400 */
0xf, /* DDR_FREQ_533 */
0xf, /* DDR_FREQ_667 */
0xc, /* DDR_FREQ_800 */
0x8, /* DDR_FREQ_933 */
0x8, /* DDR_FREQ_1066 */
0xf, /* DDR_FREQ_311 */
0xf, /* DDR_FREQ_333 */
0xf, /* DDR_FREQ_467 */
0xc, /*DDR_FREQ_850*/
0xf, /*DDR_FREQ_600*/
0xf, /*DDR_FREQ_300*/
0x8, /*DDR_FREQ_900*/
0xf /*DDR_FREQ_360*/
};
/* Bit mapping (for PBS) */
GT_U32 bobKDQbitMap2Phypin[] =
{
#warning "DQ mapping is updated for Interface4 only!" !!!
/* Interface 0 */
0,0,0,0,0,0,0,0 , /* dq[0:7] */
0,0,0,0,0,0,0,0 , /* dq[8:15] */
0,0,0,0,0,0,0,0 , /* dq[16:23] */
0,0,0,0,0,0,0,0 , /* dq[24:31] */
0,0,0,0,0,0,0,0 , /* dq[ECC] */
/* Interface 1 */
0,0,0,0,0,0,0,0 , /* dq[0:7] */
0,0,0,0,0,0,0,0 , /* dq[8:15] */
0,0,0,0,0,0,0,0 , /* dq[16:23] */
0,0,0,0,0,0,0,0 , /* dq[24:31] */
0,0,0,0,0,0,0,0 , /* dq[ECC] */
/* Interface 2 */
0,0,0,0,0,0,0,0 , /* dq[0:7] */
0,0,0,0,0,0,0,0 , /* dq[8:15] */
0,0,0,0,0,0,0,0 , /* dq[16:23] */
0,0,0,0,0,0,0,0 , /* dq[24:31] */
0,0,0,0,0,0,0,0 , /* dq[ECC] */
/* Interface 3 */
0,0,0,0,0,0,0,0 , /* dq[0:7] */
0,0,0,0,0,0,0,0 , /* dq[8:15] */
0,0,0,0,0,0,0,0 , /* dq[16:23] */
0,0,0,0,0,0,0,0 , /* dq[24:31] */
0,0,0,0,0,0,0,0 , /* dq[ECC] */
/* Interface 4 */
1,9,8,3,0,7,2,6 , /* dq[0:7] */
3,2,8,1,9,6,7,0 , /* dq[8:15] */
0,6,2,1,9,3,8,7 , /* dq[16:23] */
0,6,1,8,3,9,7,2 , /* dq[24:31] */
0,1,2,3,6,7,8,9 /* dq[ECC] */
};
#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
MV_HWS_TOPOLOGY_MAP bobKTopologyMap[] =
{
/* 1st board */
{
0x1f, /* active interfaces */
/*cs_mask, mirror, dqs_swap, ck_swap X PUPs speed_bin memory_width mem_size frequency casL casWL temperature */
{ {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} },
0xF /* Buses mask */
},
/* 2nd board */
{
0x1f, /* active interfaces */
/*cs_mask, mirror, dqs_swap, ck_swap X PUPs speed_bin memory_width mem_size frequency casL casWL temperature */
{ {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} ,
{{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 , 0 , MV_HWS_TEMP_HIGH} },
0xF /* Buses mask */
}
};
#endif
GT_U8 ddr3TipClockMode( GT_U32 frequency );
/************************** Server Access ******************************/
GT_STATUS ddr3TipBobKServerRegWrite
(
GT_U32 devNum,
GT_U32 regAddr,
GT_U32 dataValue
)
{
#ifdef ASIC_SIMULATION
/* avoid warnings */
devNum = devNum;
regAddr = regAddr;
dataValue = dataValue;
return GT_OK;
#else
return hwsServerRegSetFuncPtr(devNum, regAddr, dataValue);
#endif
}
GT_STATUS ddr3TipBobKServerRegRead
(
GT_U32 devNum,
GT_U32 regAddr,
GT_U32 *dataValue,
GT_U32 regMask
)
{
#ifdef ASIC_SIMULATION
/* avoid warnings */
devNum = devNum;
regAddr = regAddr;
regMask = regMask;
*dataValue = 0;
#else
hwsServerRegGetFuncPtr(devNum, regAddr, dataValue);
*dataValue = *dataValue & regMask;
#endif
return GT_OK;
}
/**********************************************************************************/
GT_STATUS ddr3TipBobKGetFreqConfig
(
GT_U8 devNum,
MV_HWS_DDR_FREQ freq,
MV_HWS_TIP_FREQ_CONFIG_INFO *freqConfigInfo
)
{
devNum = devNum; /* avoid warnings */
if (bobKBwPerFreq[freq] == 0xff)
{
return GT_NOT_SUPPORTED;
}
if (freqConfigInfo == NULL)
{
return GT_BAD_PARAM;
}
freqConfigInfo->bwPerFreq = bobKBwPerFreq[freq];
freqConfigInfo->ratePerFreq = bobKRatePerFreq[freq];
freqConfigInfo->isSupported = GT_TRUE;
return GT_OK;
}
/*****************************************************************************
Enable Pipe
******************************************************************************/
GT_STATUS ddr3TipPipeEnable
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_BOOL enable
)
{
GT_U32 dataValue, pipeEnableMask = 0;
if (enable == GT_FALSE)
{
pipeEnableMask = 0;
}
else
{
if (interfaceAccess == ACCESS_TYPE_MULTICAST)
{
pipeEnableMask = pipeMulticastMask;
}
else
{
pipeEnableMask = (1 << interfaceMap[interfaceId].pipe);
}
}
CHECK_STATUS(ddr3TipBobKRead(devNum, PIPE_ENABLE_ADDR, &dataValue, MASK_ALL_BITS));
dataValue = (dataValue & (~0xFF)) | pipeEnableMask;
CHECK_STATUS(ddr3TipBobKWrite(devNum, PIPE_ENABLE_ADDR, dataValue, MASK_ALL_BITS));
return GT_OK;
}
void ddr3TipIsUnicastAccess( GT_U8 devNum,GT_U32* interfaceId, MV_HWS_ACCESS_TYPE* interfaceAccess)
{
GT_U32 indexCnt, totalCnt = 0 , interfaceTmp = 0;
MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
if (*interfaceAccess == ACCESS_TYPE_MULTICAST)
{
for(indexCnt = 0; indexCnt < MAX_INTERFACE_NUM; indexCnt++)
{
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) != 0)
{
totalCnt++;
interfaceTmp = indexCnt;
continue;
}
}
if (totalCnt == 1) {
*interfaceAccess = ACCESS_TYPE_UNICAST;
*interfaceId = interfaceTmp;
}
}
}
/******************************************************************************
* Name: ddr3TipBobKSelectTMDdrController.
* Desc: Enable/Disable access to Marvell's server.
* Args: devNum - device number
* enable - whether to enable or disable the server
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKSelectTMDdrController
(
GT_U8 devNum,
GT_BOOL enable
)
{
GT_U32 interfaceId = 0, dataValue = 0;
for(interfaceId=0; interfaceId <MAX_INTERFACE_NUM ;interfaceId++)
{
ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_TRUE);
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) == 0)
{
/*disable in-active interfaces (so they won't be accessed upon multicast)*/
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), &dataValue, MASK_ALL_BITS));
dataValue &= ~0x40;
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), dataValue));
continue;
}
/* Enable relevant Pipe */
pipeMulticastMask |= (1 << interfaceMap[interfaceId].pipe);
/* multicast Macro is subscribed to Multicast 0x1D */
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), &dataValue, MASK_ALL_BITS));
dataValue |= 0x40;
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), dataValue));
ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_FALSE);
}
/* enable access to relevant pipes (according to the pipe mask) */
ddr3TipPipeEnable(devNum, ACCESS_TYPE_MULTICAST, interfaceId, GT_TRUE);
if (enable)
{
/* Enable DDR Tuning */
CHECK_STATUS(ddr3TipBobKWrite(devNum, READ_BUFFER_SELECT_REG, 0x8000, MASK_ALL_BITS));
/* configure duplicate CS */
CHECK_STATUS(ddr3TipBobKWrite(devNum, CS_ENABLE_REG, 0x4A/*Haim 0x42*/, MASK_ALL_BITS));
}
else
{
/* Disable DDR Tuning Select */
CHECK_STATUS(ddr3TipBobKWrite(devNum, CS_ENABLE_REG, 0x2, MASK_ALL_BITS));
CHECK_STATUS(ddr3TipBobKWrite(devNum, READ_BUFFER_SELECT_REG, 0,MASK_ALL_BITS));
}
return GT_OK;
}
/*****************************************************************************
Check if Dunit access is done
******************************************************************************/
GT_STATUS ddr3TipBobKIsAccessDone
(
GT_U8 devNum,
GT_32 interfaceId
)
{
GT_U32 rdData = 1, cnt = 0;
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CMD_REG), &rdData, MASK_ALL_BITS));
rdData &= 1;
while(rdData != 0)
{
if (cnt++ >= MAX_POLLING_ITERATIONS)
break;
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CMD_REG), &rdData, MASK_ALL_BITS));
rdData &= 1;
#ifdef ASIC_SIMULATION
rdData = 0;/* no more iterations needed */
#endif /*ASIC_SIMULATION*/
}
if (cnt < MAX_POLLING_ITERATIONS)
{
return GT_OK;
}
else
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO,("AccessDone fail: if = %d\n",interfaceId));
return GT_FAIL;
}
}
/******************************************************************************/
GT_STATUS ddr3TipBobKTMRead
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 *data,
GT_U32 mask
)
{
GT_U32 dataValue = 0, startIf, endIf;
MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
ddr3TipIsUnicastAccess(devNum, &interfaceId, &interfaceAccess);
if (interfaceAccess == ACCESS_TYPE_UNICAST)
{
startIf = interfaceId;
endIf = interfaceId;
}
else
{
startIf = 0;
endIf = MAX_INTERFACE_NUM-1;
}
for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
{
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) == 0)
{
continue;
}
ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_TRUE);
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CTRL_1_REG) ,TRAINING_ID));
/*working with XSB client InterfaceNum Write Interface ADDR as data to XSB address C*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_ADDRESS_REG), regAddr));
dataValue = ((GT_U32)(TARGET_INT << 19)) + (BYTE_EN << 11) + (BOBK_NUM_BYTES << 4) + (CMD_READ << 2) +(INTERNAL_ACCESS_PORT << 1) + EXECUTING;
/*Write Interface COMMAND as data to XSB address 8 */
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CMD_REG), dataValue));
CHECK_STATUS(ddr3TipBobKIsAccessDone(devNum, interfaceId));
/* consider that input data is always a vector, and for unicast the writing will be in the interface index in vector */
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_DATA_REG), &data[interfaceId], mask));
if (debugBobK >= 2)
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("DunitRead 0x%x: 0x%x (mask 0x%x)\n", regAddr, *data, mask));
}
/*ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_FALSE);*/
}
return GT_OK;
}
/******************************************************************************/
GT_STATUS ddr3TipBobKTMWrite
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 dataValue,
GT_U32 mask
)
{
GT_U32 dataCmd = 0, uiDataRead = 0, uiReadInterfaceId=0;
GT_U32 dataRead[MAX_INTERFACE_NUM];
GT_U32 startIf, endIf;
MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
ddr3TipIsUnicastAccess(devNum, &interfaceId, &interfaceAccess);
if (mask != MASK_ALL_BITS)
{
/* if all bits should be written there is no need for read-modify-write */
if (interfaceAccess == ACCESS_TYPE_MULTICAST)
{
CHECK_STATUS(ddr3TipGetFirstActiveIf(devNum, topologyMap->interfaceActiveMask, &uiReadInterfaceId));
}
else
{
uiReadInterfaceId = interfaceId;
}
if (debugBobK >= 2)
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("ddr3TipBobKTMWrite active interface = %d\n",uiReadInterfaceId));
}
CHECK_STATUS(ddr3TipBobKRead(devNum, regAddr, dataRead,MASK_ALL_BITS));
uiDataRead = dataRead[uiReadInterfaceId];
dataValue = (uiDataRead & (~mask)) | (dataValue & mask);
}
ddr3TipPipeEnable(devNum, interfaceAccess, interfaceId, GT_TRUE);
/* set the ID */
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_CTRL_1_REG) , TRAINING_ID));
/*working with XSB multicast client , Write Interface ADDR as data to XSB address C */
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_ADDRESS_REG), regAddr));
/*Write Interface DATA as data to XSB address 0x10.*/
if (debugBobK >= 1)
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Dunit Write: interface %d access %d Address 0x%x Data 0x%x\n", interfaceId, interfaceAccess, regAddr, dataValue));
}
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_DATA_REG), dataValue));
dataCmd = ((GT_U32)(TARGET_INT << 19)) + (BYTE_EN << 11) + (BOBK_NUM_BYTES << 4) + (CMD_WRITE << 2) + (INTERNAL_ACCESS_PORT << 1);
/*Write Interface COMMAND as data to XSB address 8
Execute an internal write to xBar port1 */
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_CMD_REG), dataCmd));
dataCmd |= EXECUTING;
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_CMD_REG), dataCmd));
/*check that write is completed; the test should be done per interface */
if (interfaceAccess == ACCESS_TYPE_MULTICAST)
{
startIf = 0;
endIf = MAX_INTERFACE_NUM-1;
}
else
{
startIf = interfaceId;
endIf = interfaceId;
}
for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_TRUE);
CHECK_STATUS(ddr3TipBobKIsAccessDone(devNum, interfaceId));
}
/* ddr3TipPipeEnable(devNum, interfaceAccess, interfaceId, GT_FALSE);*/
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipBobKWrite.
* Desc:
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKWrite
(
GT_U8 devNum,
GT_U32 regAddr,
GT_U32 dataValue,
GT_U32 mask
)
{
GT_U32 uiDataRead;
#ifdef WIN32
return GT_OK;
#endif
if (mask != MASK_ALL_BITS)
{
CHECK_STATUS(ddr3TipBobKRead(devNum, regAddr, &uiDataRead, MASK_ALL_BITS));
dataValue = (uiDataRead & (~mask)) | (dataValue & mask);
}
if (debugBobK >= 1)
{
mvPrintf("Dunit Write: Address 0x%x Data 0x%x\n", regAddr, dataValue);
}
MV_REG_WRITE(regAddr, dataValue);
if (debugBobK >= 2)
mvPrintf("write: 0x%x = 0x%x\n",regAddr,dataValue);
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipBobKRead.
* Desc:
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKRead
(
GT_U8 devNum,
GT_U32 regAddr,
GT_U32 *data,
GT_U32 mask
)
{
#ifdef WIN32
return GT_OK;
#endif
*data = MV_REG_READ(regAddr) & mask;
if (debugBobK >= 2)
{
mvPrintf("DunitRead 0x%x: 0x%x (mask 0x%x)\n", regAddr, *data, mask);
}
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipBobKIFWrite.
* Desc:
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKIFWrite
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 dataValue,
GT_U32 mask
)
{
if (interfaceAccess == ACCESS_TYPE_MULTICAST)
interfaceId = 4;
return(ddr3TipBobKWrite(devNum,regAddr,dataValue,mask));
}
/******************************************************************************
* Name: ddr3TipBobKIFRead.
* Desc:
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKIFRead
(
GT_U8 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 *data,
GT_U32 mask
)
{
if (interfaceAccess == ACCESS_TYPE_MULTICAST)
interfaceId = 4;
return ddr3TipBobKRead(devNum, regAddr, &data[interfaceId], mask);
}
/******************************************************************************
* Name: ddr3TipBobKSelectCpuDdrController.
* Desc: Enable/Disable access to Marvell's server.
* Args: devNum - device number
* enable - whether to enable or disable the server
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKSelectCPUDdrController
(
GT_U8 devNum,
GT_BOOL enable
)
{
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipInitBobKSilicon.
* Desc: init Training SW DB.
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
static GT_STATUS ddr3TipInitBobKSilicon
(
GT_U32 devNum,
GT_U32 boardId
)
{
MV_HWS_TIP_CONFIG_FUNC_DB configFunc;
MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
GT_TUNE_TRAINING_PARAMS tuneParams;
GT_U8 numOfBusPerInterface = 5;
if(topologyMap == NULL)
{
return GT_NOT_INITIALIZED;
}
#if 0
ddr3TipBobKGetInterfaceMap((GT_U8)devNum);
#endif
boardId = boardId; /* avoid warnings */
#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
configFunc.tipDunitReadFunc = ddr3TipBobKTMRead;
configFunc.tipDunitWriteFunc = ddr3TipBobKTMWrite;
configFunc.tipDunitMuxSelectFunc = ddr3TipBobKSelectTMDdrController;
#else
configFunc.tipDunitReadFunc = ddr3TipBobKIFRead;
configFunc.tipDunitWriteFunc = ddr3TipBobKIFWrite;
configFunc.tipDunitMuxSelectFunc = ddr3TipBobKSelectCPUDdrController;
#endif
configFunc.tipGetFreqConfigInfoFunc = ddr3TipBobKGetFreqConfig;
configFunc.tipSetFreqDividerFunc = ddr3TipBobKSetDivider;
configFunc.tipGetDeviceInfoFunc = ddr3TipBobKGetDeviceInfo;
configFunc.tipGetTemperature = NULL;
configFunc.tipGetClockRatio = ddr3TipClockMode;
mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
/* register bit mapping (for PBS) */
ddr3TipRegisterDqTable(devNum, bobKDQbitMap2Phypin);
/*Set device attributes*/
ddr3TipDevAttrInit(devNum);
ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_3);
ddr3TipDevAttrSet(devNum, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_NEGATIVE);
ddr3TipDevAttrSet(devNum, MV_ATTR_OCTET_PER_INTERFACE, numOfBusPerInterface);
ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_FALSE);
maskTuneFunc = (SET_LOW_FREQ_MASK_BIT |
LOAD_PATTERN_MASK_BIT |
SET_MEDIUM_FREQ_MASK_BIT |
WRITE_LEVELING_MASK_BIT |
WRITE_LEVELING_SUPP_MASK_BIT |
READ_LEVELING_MASK_BIT |
PBS_RX_MASK_BIT |
PBS_TX_MASK_BIT |
SET_TARGET_FREQ_MASK_BIT |
WRITE_LEVELING_TF_MASK_BIT |
WRITE_LEVELING_SUPP_TF_MASK_BIT |
READ_LEVELING_TF_MASK_BIT |
CENTRALIZATION_RX_MASK_BIT |
CENTRALIZATION_TX_MASK_BIT
);
/*Skip mid freq stages for 400Mhz DDR speed*/
if( (topologyMap->interfaceParams[firstActiveIf].memoryFreq == DDR_FREQ_400) ){
maskTuneFunc = ( WRITE_LEVELING_MASK_BIT |
LOAD_PATTERN_2_MASK_BIT |
READ_LEVELING_MASK_BIT |
CENTRALIZATION_RX_MASK_BIT |
CENTRALIZATION_TX_MASK_BIT);
}
if( ckDelay == MV_PARAMS_UNDEFINED )
ckDelay = 150;
delayEnable = 1;
caDelay = 0;
/* update DGL parameters */
tuneParams.ckDelay = ckDelay;
tuneParams.PhyReg3Val = 0xA;
tuneParams.gRttNom = 0x44;
tuneParams.gDic = 0x2;
tuneParams.uiODTConfig = 0x120012;
tuneParams.gZpriData = 123;
tuneParams.gZnriData = 123;
tuneParams.gZpriCtrl = 74;
tuneParams.gZnriCtrl = 74;
tuneParams.gZpodtData = 45;
tuneParams.gZnodtData = 45;
tuneParams.gZpodtCtrl = 45;
tuneParams.gZnodtCtrl = 45;
tuneParams.gRttWR = 0x0;
CHECK_STATUS(ddr3TipTuneTrainingParams(devNum, &tuneParams));
/* frequency and general parameters */
ddr3TipBobKGetMediumFreq(devNum, firstActiveIf, &mediumFreq);
initFreq = topologyMap->interfaceParams[firstActiveIf].memoryFreq;
freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq = 130;
dfsLowPhy1 = PhyReg1Val;
calibrationUpdateControl = 1;
return GT_OK;
}
/******************************************************************************
* Name: ddr3BobKUpdateTopologyMap.
* Desc:
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3BobKUpdateTopologyMap(GT_U32 devNum, MV_HWS_TOPOLOGY_MAP* topologyMap)
{
GT_U32 interfaceId;
MV_HWS_DDR_FREQ freq;
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("topologyMap->interfaceActiveMask is 0x%x\n", topologyMap->interfaceActiveMask));
#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
/* first check if TM is enabled. reading frequency will check if it's enabled or not
in case it's not, the function will exit with error */
CHECK_STATUS(ddr3TipTmGetInitFreq(devNum, &freq));
/* if interface 4 is active, check it's assignment and close it if it's for MSYS */
if(topologyMap->interfaceActiveMask & 0x10)
{
if(ddr3GetSdramAssignment((GT_U8)devNum) == MSYS_EN)
{
topologyMap->interfaceActiveMask &= ~0x10; /* remove interface 4 from mask */
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
("Warning: DDR IF 4 is allocated to MSYS (and was removed from TM IF list)\n"));
}
}
#endif
for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++) {
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) == GT_FALSE)
continue;
CHECK_STATUS(ddr3TipBobKGetInitFreq((GT_U8)devNum, interfaceId, &freq));
topologyMap->interfaceParams[interfaceId].memoryFreq = freq;
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("Update topology frequency for interface %d to %d\n",interfaceId, freq));
}
/* re-calc topology parameters according to topology updates (if needed) */
CHECK_STATUS(mvHwsDdr3TipLoadTopologyMap(devNum, topologyMap));
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipInitBobK.
* Desc: init Training SW DB and updates DDR topology.
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipInitBobK
(
GT_U32 devNum,
GT_U32 boardId
)
{
MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
if(NULL == topologyMap)
{
#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
/* for CPSS, since topology is not always initialized, it is
needed to set it to default topology */
topologyMap = &bobKTopologyMap[0];
#else
return GT_FAIL;
#endif
}
CHECK_STATUS(ddr3BobKUpdateTopologyMap(devNum, topologyMap));
ddr3TipInitBobKSilicon(devNum, boardId);
return GT_OK;
}
/******************************************************************************
* external read from memory
*/
GT_STATUS ddr3TipExtRead
(
GT_U32 devNum,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 numOfBursts,
GT_U32 *data
)
{
GT_U32 burstNum;
for(burstNum=0 ; burstNum < numOfBursts*8; burstNum++)
{
data[burstNum] = * (volatile unsigned int *) (regAddr + 4* burstNum);
}
return GT_OK;
}
/******************************************************************************
* external write to memory
*/
GT_STATUS ddr3TipExtWrite
(
GT_U32 devNum,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 numOfBursts,
GT_U32 *data
)
{
GT_U32 burstNum;
for(burstNum=0 ; burstNum < numOfBursts*8; burstNum++)
{
*(volatile unsigned int *) (regAddr+4*burstNum) = data[burstNum];
}
return GT_OK;
}
#if 0
/*****************************************************************************
Data Reset
******************************************************************************/
static GT_STATUS ddr3TipDataReset
(
GT_U32 devNum,
MV_HWS_ACCESS_TYPE interfaceAccess,
GT_U32 interfaceId
)
{
GT_STATUS retVal;
GT_U32 uiWordCnt;
for(uiWordCnt = 0; uiWordCnt < 8 ; uiWordCnt++)
{
/*Write Interface DATA as data to XSB address 0x10.*/
retVal = ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, interfaceAccess, XSB_DATA_REG+(uiWordCnt * 4)), 0xABCDEF12);
if (retVal != GT_OK)
{
return retVal;
}
}
return GT_OK;
}
/*****************************************************************************
XSB External read
******************************************************************************/
GT_STATUS ddr3TipExtRead
(
GT_U32 devNum,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 numOfBursts,
GT_U32 *data
)
{
GT_U32 burstNum, wordNum , dataValue;
GT_U32 cntPoll;
MV_HWS_ACCESS_TYPE accessType = ACCESS_TYPE_UNICAST;
/*DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("=== EXTERNAL READ ==="));*/
ddr3TipPipeEnable((GT_U8)devNum, accessType, interfaceId, GT_TRUE);
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_CTRL_0_REG) ,EXT_TRAINING_ID));
for(burstNum=0 ; burstNum < numOfBursts; burstNum++)
{
ddr3TipDataReset(devNum, ACCESS_TYPE_UNICAST, interfaceId);
/*working with XSB client InterfaceNum Write Interface ADDR as data to XSB address C*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_ADDRESS_REG + (burstNum * 32)), regAddr));
if (isCbeRequired == GT_TRUE)
{
/*CS_CBE_VALUE(0)*/
dataValue = CS_CBE_VALUE(0) << 19;
}
else
{
dataValue = (GT_U32)(TARGET_EXT << 19);
}
dataValue |= (BYTE_EN << 11) + (NUM_BYTES_IN_BURST << 4) + (ACCESS_EXT << 3);
/*Write Interface COMMAND as data to XSB address 8 */
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG), dataValue));
dataValue |= EXECUTING;
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG), dataValue));
for(cntPoll=0; cntPoll < MAX_POLLING_ITERATIONS; cntPoll++)
{
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BC2_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG), &dataValue, 0x1));
if (dataValue == 0)
break;
}
if (cntPoll >= MAX_POLLING_ITERATIONS)
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("No Done indication for DDR Read\n", dataValue));
return GT_NOT_READY;
}
for(wordNum = 0; wordNum < EXT_ACCESS_BURST_LENGTH /*s_uiNumOfBytesInBurst/4*/; wordNum++)
{
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_DATA_REG + (wordNum * 4)), &data[wordNum], MASK_ALL_BITS));
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("ddr3TipExtRead data 0x%x \n",data[wordNum]));
}
}
return GT_OK;
}
/*****************************************************************************
XSB External write
******************************************************************************/
GT_STATUS ddr3TipExtWrite
(
GT_U32 devNum,
GT_U32 interfaceId,
GT_U32 regAddr,
GT_U32 numOfBursts,
GT_U32 *addr
)
{
GT_U32 wordNum = 0, dataCmd = 0, burstNum=0, cntPoll = 0, dataValue = 0;
MV_HWS_ACCESS_TYPE accessType = ACCESS_TYPE_UNICAST;
ddr3TipPipeEnable((GT_U8)devNum, accessType, interfaceId, GT_TRUE);
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_CTRL_0_REG) ,EXT_TRAINING_ID ));
for(burstNum=0 ; burstNum < numOfBursts; burstNum++)
{
/*working with XSB multicast client , Write Interface ADDR as data to XSB address C */
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_ADDRESS_REG), regAddr + (burstNum * EXT_ACCESS_BURST_LENGTH * 4)));
for(wordNum = 0; wordNum < 8 ; wordNum++)
{
/*Write Interface DATA as data to XSB address 0x10.*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_DATA_REG + (wordNum * 4)), addr[wordNum]));
}
if (isCbeRequired == GT_TRUE)
{
dataCmd = CS_CBE_VALUE(0) << 19;
}
else
{
dataCmd = (GT_U32)(TARGET_EXT << 19);
}
dataCmd |= (BYTE_EN << 11) + (NUM_BYTES_IN_BURST << 4) + (ACCESS_EXT << 3) + EXT_MODE;
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_CMD_REG), dataCmd));
/* execute xsb write */
dataCmd |= 0x1;
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("ddr3TipExtWrite dataCmd 0x%x \n", dataCmd));
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BC2_XSB_MAPPING(interfaceId, accessType, XSB_CMD_REG), dataCmd));
for(cntPoll=0; cntPoll < MAX_POLLING_ITERATIONS; cntPoll++)
{
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BC2_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG), &dataValue, 0x1));
if (dataValue == 0)
break;
}
if (cntPoll >= MAX_POLLING_ITERATIONS)
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("No Done indication for DDR Write External\n", dataValue));
return GT_NOT_READY;
}
}
return GT_OK;
}
#endif
/******************************************************************************
* Name: ddr3GetSdramAssignment
* Desc: read S@R and return DDR3 assignment ( 0 = TM , 1 = MSYS )
* Args:
* Notes:
* Returns: required value
*/
DDR_IF_ASSIGNMENT ddr3GetSdramAssignment(GT_U8 devNum)
{
#if 0
GT_U32 data = 0; /* initialized for simulation */
/* Read sample at reset setting */
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_DEVICE_SAR1_REG_ADDR, &data, MASK_ALL_BITS));
data = (data >> BOBK_DEVICE_SAR1_MSYS_TM_SDRAM_SEL_OFFSET) & BOBK_DEVICE_SAR1_MSYS_TM_SDRAM_SEL_MASK;
return (data == 0) ? TM_EN : MSYS_EN;
#endif
return MSYS_EN;
}
/******************************************************************************/
/* PLL/Frequency Functionality */
/******************************************************************************/
/******************************************************************************
* Name: ddr3TipBonKSetDivider.
* Desc: Pll Divider
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKSetDivider
(
GT_U8 devNum,
GT_U32 interfaceId,
MV_HWS_DDR_FREQ frequency
)
{
if(interfaceId < 4)
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("TM set divider for interface %d\n",interfaceId));
return ddr3TipTmSetDivider(devNum, interfaceId, frequency);
}
else
{
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("CPU set divider for interface 4\n"));
return ddr3TipCpuSetDivider(devNum, interfaceId, frequency);
}
}
/******************************************************************************
* return 1 of core/DUNIT clock ration is 1 for given freq, 0 if clock ratios is 2:1
*/
GT_U8 ddr3TipClockMode( GT_U32 frequency )
{
if(frequency == DDR_FREQ_LOW_FREQ){
return 1;
}
else{
return 2;
}
}
/******************************************************************************
* Name: ddr3TipTmSetDivider.
* Desc: Pll Divider of The Trafic Manager Unit
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
static GT_STATUS ddr3TipTmSetDivider
(
GT_U8 devNum,
GT_U8 interfaceId,
MV_HWS_DDR_FREQ frequency
)
{
GT_U32 writeData, divider = 0, ratio;
MV_HWS_DDR_FREQ sarFreq;
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("TM PLL Config\n"));
/* calc SAR */
ddr3TipBobKGetInitFreq(devNum, interfaceId, &sarFreq);
divider = freqVal[sarFreq]/freqVal[frequency];
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("\nSAR value %d divider %d freqVal[%d] %d freqVal[%d] %d\n",
sarFreq, divider, sarFreq, freqVal[sarFreq], frequency, freqVal[frequency]));
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8264, &writeData, MASK_ALL_BITS ));
writeData |= ~0x1FF0C;
/*For regular freq(divider<=4) x2 the divider and ratio*/
ratio = (frequency == DDR_FREQ_LOW_FREQ)?(1):(2);
divider *= ratio;
writeData &= (0x3 << 2) | (divider << 8) | (divider << 12);
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F8264, writeData));
writeData &= (0x1 << 16);
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F8264, writeData));
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F82A8, &writeData, MASK_ALL_BITS));
writeData |= ~0x30;
writeData &= ratio << 4;
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F82A8, writeData));
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("\tTM PLL config Done\n"));
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipCpuSetDivider.
* Desc: Pll Divider of the CPU(msys) Unit
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
static GT_STATUS ddr3TipCpuSetDivider
(
GT_U8 devNum,
GT_U8 interfaceId,
MV_HWS_DDR_FREQ frequency
)
{
GT_U32 data = 0, value, divider = 0, divRatio;
MV_HWS_DDR_FREQ sarFreq;
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("CPU PLL Config\n"));
/* calc SAR */
ddr3TipBobKGetInitFreq(devNum, interfaceId, &sarFreq);
divider = freqVal[sarFreq]/freqVal[frequency];
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("\nSAR value %d divider %d freqVal[%d] %d freqVal[%d] %d\n",
sarFreq, divider, sarFreq, freqVal[sarFreq], frequency, freqVal[frequency]));
/* Configure Dunit to 1:1 in case of DLL off mode else 2:1*/
value = (ddr3TipClockMode(frequency) == 1)? 0 : 1;
CHECK_STATUS(ddr3TipBobKWrite(devNum, 0x1524, (value << 15), (1 << 15)));
/* Dunit training clock + 1:1/2:1 mode */
divRatio = (ddr3TipClockMode(frequency) << 16);
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0xF8298, &data, MASK_ALL_BITS ));
/*ddr_phy_clk_divider*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8298, R_MOD_W(divRatio, data, (0x3 << 16))));
divRatio = (frequency==initFreq)?(0):(1);
/*sel_pll_ddr_clk_div2*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8298, R_MOD_W( divRatio<<15, data, (0x1 << 5))));
/*cpu_pll_clkdiv_reload_smooth*/
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0xF8270, &data, MASK_ALL_BITS ));
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8270, R_MOD_W((0x7F<<11), data, (0x7F << 16))));
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0xF8268, &data, MASK_ALL_BITS ));
/*cpu_pll_clkdiv_relax_en*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8268, R_MOD_W(0x7F, data, 0x7F)));
/*cpu_pll_clkdiv_reset_mask*/
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8268, R_MOD_W((0x7F<<7), data, (0x7F << 7))));
/*cpu_pll_ddr_clkdiv_ratio_full*/
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0xF826C, &data, MASK_ALL_BITS ));
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF826C, R_MOD_W((divider<<12), data, (0x3F << 12))));
/*cpu_pll_clkdiv_reload_force*/
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0xF8268, &data, MASK_ALL_BITS ));
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8268, R_MOD_W((divider<<21), data, (0x7F << 21))));
/*cpu_pll_clkdiv_reload_ratio*/
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0xF8270, &data, MASK_ALL_BITS ));
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8270, R_MOD_W((0x1<<10), data, (0x1 << 10))));
CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8270, R_MOD_W(0, data, (0x1 << 10))));
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("\tCPU PLL config Done\n"));
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipBobKGetInitFreq.
* Desc: choose from where to extract the frequency (TM or CPU)
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
GT_STATUS ddr3TipBobKGetInitFreq
(
GT_U8 devNum,
GT_U32 interfaceId,
MV_HWS_DDR_FREQ* sarFreq
)
{
GT_STATUS res;
if(interfaceId < 4)
{
res = ddr3TipTmGetInitFreq(devNum, sarFreq);
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM frequency for interface %d is %d\n",interfaceId, *sarFreq));
}
else
{
res = ddr3TipCpuGetInitFreq(devNum, sarFreq);
}
return res;
}
/*****************************************************************************
TM interface frequency Get
******************************************************************************/
GT_STATUS ddr3TipTmGetInitFreq
(
GT_STATUS devNum,
MV_HWS_DDR_FREQ *freq
)
{
GT_U32 data;
/* calc SAR */
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8204 , &data, MASK_ALL_BITS));
data = (data >> 15) & 0x7;
#ifdef ASIC_SIMULATION
data = 2;
#endif
switch(data)
{
case 0:
/* TM is disabled */
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM Disabled\n"));
*freq = DDR_FREQ_LIMIT;
return GT_NOT_INITIALIZED;
case 1:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM DDR_FREQ_800\n"));
*freq = DDR_FREQ_800;
break;
case 2:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM DDR_FREQ_933\n"));
*freq = DDR_FREQ_933;
break;
case 3:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM DDR_FREQ_667\n"));
*freq = DDR_FREQ_667;
break;
default:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Error: ddr3TipTmGetInitFreq: Unknown Freq SAR value 0x%x\n", data));
*freq = DDR_FREQ_LIMIT;
return GT_BAD_PARAM;
}
return GT_OK;
}
/*****************************************************************************
CPU interface frequency Get
******************************************************************************/
static GT_STATUS ddr3TipCpuGetInitFreq
(
GT_STATUS devNum,
MV_HWS_DDR_FREQ *freq
)
{
GT_U32 data;
/* calc SAR */
CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, REG_DEVICE_SAR1_OVERRIDE_ADDR, /* in BOBK SAR should be read from REG_DEVICE_SAR1_OVERRIDE_ADDR since
read from REG_DEVICE_SAR1_ADDR register returns wrong value (0)*/
&data, MASK_ALL_BITS ));
mvPrintf("SAR1 is 0x%X\n", data);
data = (data >> PLL1_CNFIG_OFFSET) & PLL1_CNFIG_MASK;
switch(data)
{
case 0:
case 5:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_400\n"));
*freq = DDR_FREQ_400;
break;
case 1:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_533\n"));
*freq = DDR_FREQ_533;
break;
case 2:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_667\n"));
*freq = DDR_FREQ_667;
break;
case 3:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_800\n"));
*freq = DDR_FREQ_800;
break;
default:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Freq SAR Unknown\n"));
*freq = DDR_FREQ_LIMIT;
return GT_BAD_PARAM;
}
return GT_OK;
}
/******************************************************************************
* Name: ddr3TipBobKGetMediumFreq.
* Desc:
* Args:
* Notes:
* Returns: GT_OK if success, other error code if fail.
*/
static GT_STATUS ddr3TipBobKGetMediumFreq
(
GT_U32 devNum,
GT_U32 interfaceId,
MV_HWS_DDR_FREQ *freq
)
{
GT_U32 data;
/* calc SAR */
CHECK_STATUS(ddr3TipBobKRead(devNum, REG_DEVICE_SAR1_ADDR, &data, MASK_ALL_BITS ));
data = (data >> PLL1_CNFIG_OFFSET) & PLL1_CNFIG_MASK;
switch(data)
{
case 0:
case 5:
*freq = DDR_FREQ_400;
break;
case 2:
*freq = DDR_FREQ_333;
break;
case 3:
*freq = DDR_FREQ_400;
break;
default:
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Freq SAR Unknown\n"));
*freq = DDR_FREQ_LIMIT;
return GT_BAD_PARAM;
}
return GT_OK;
}
GT_STATUS ddr3TipBobKGetDeviceInfo
(
GT_U8 devNum,
MV_DDR3_DEVICE_INFO * infoPtr
)
{
devNum = devNum; /* avoid warnings */
infoPtr->deviceId = 0xFC00;
infoPtr->ckDelay = ckDelay;
return GT_OK;
}