blob: 96610d1b8d8526292830f4ceb57866494ed8cb80 [file] [log] [blame]
/*******************************************************************************
Copyright (C) Marvell International Ltd. and its affiliates
********************************************************************************
Marvell GPL License Option
If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File in accordance with the terms and conditions of the General
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
available along with the File in the license.txt file or by writing to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
DISCLAIMED. The GPL License provides additional details about this warranty
disclaimer.
*******************************************************************************/
#include <config.h>
#include <common.h>
#include <command.h>
#include <pci.h>
#include <net.h>
#include "mvCommon.h"
#include "ctrlEnv/mvCtrlEnvLib.h"
#include "boardEnv/mvBoardEnvLib.h"
#include "cpu/mvCpu.h"
#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
#if defined(MV_INC_BOARD_NOR_FLASH)
#include "norflash/mvFlash.h"
#endif
#if defined(MV_INCLUDE_GIG_ETH)
#include "eth-phy/mvEthPhy.h"
#endif
#if defined(MV_INCLUDE_PEX)
#include "pex/mvPex.h"
#endif
#if defined(MV_INCLUDE_PDMA)
#include "pdma/mvPdma.h"
#include "mvSysPdmaApi.h"
#endif
#if defined(MV_INCLUDE_XOR)
#include "xor/mvXorRegs.h"
#include "xor/mvXor.h"
#endif
#if defined(MV_INCLUDE_PMU)
#include "pmu/mvPmuRegs.h"
#endif
#include "cntmr/mvCntmrRegs.h"
#if defined(CONFIG_CMD_BSP)
/******************************************************************************
* Category - General
* Functionality- The commands allows the user to view the contents of the MV
* internal registers and modify them.
* Need modifications (Yes/No) - no
*****************************************************************************/
int ir_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
MV_U32 regNum = 0x0, regVal, regValTmp, res;
MV_8 regValBin[40];
MV_8 cmd[40];
int i,j = 0, flagm = 0;
extern MV_8 console_buffer[];
if( argc == 2 ) {
regNum = simple_strtoul( argv[1], NULL, 16 );
}
else {
printf( "Usage:\n%s\n", cmdtp->usage );
return 0;
}
regVal = MV_REG_READ( regNum + INTER_REGS_BASE);
regValTmp = regVal;
printf( "Internal register 0x%x value : 0x%x\n ",regNum, regVal );
printf( "\n 31 24 16 8 0" );
printf( "\n | | | | |\nOLD: " );
for( i = 31 ; i >= 0 ; i-- ) {
if( regValTmp > 0 ) {
res = regValTmp % 2;
regValTmp = (regValTmp - res) / 2;
if( res == 0 )
regValBin[i] = '0';
else
regValBin[i] = '1';
}
else
regValBin[i] = '0';
}
for( i = 0 ; i < 32 ; i++ ) {
printf( "%c", regValBin[i] );
if( (((i+1) % 4) == 0) && (i > 1) && (i < 31) )
printf( "-" );
}
readline( "\nNEW: " );
strcpy(cmd, console_buffer);
if( (cmd[0] == '0') && (cmd[1] == 'x') ) {
regVal = simple_strtoul( cmd, NULL, 16 );
flagm=1;
}
else {
for( i = 0 ; i < 40 ; i++ ) {
if(cmd[i] == '\0')
break;
if( i == 4 || i == 9 || i == 14 || i == 19 || i == 24 || i == 29 || i == 34 )
continue;
if( cmd[i] == '1' ) {
regVal = regVal | (0x80000000 >> j);
flagm = 1;
}
else if( cmd[i] == '0' ) {
regVal = regVal & (~(0x80000000 >> j));
flagm = 1;
}
j++;
}
}
if( flagm == 1 ) {
MV_REG_WRITE( regNum + INTER_REGS_BASE, regVal );
printf( "\nNew value = 0x%x\n\n", MV_REG_READ(regNum +
INTER_REGS_BASE) );
}
return 1;
}
U_BOOT_CMD(
ir, 2, 1, ir_cmd,
"ir - reading and changing MV internal register values.\n",
" address\n"
"\tDisplays the contents of the internal register in 2 forms, hex and binary.\n"
"\tIt's possible to change the value by writing a hex value beginning with \n"
"\t0x or by writing 0 or 1 in the required place. \n"
"\tPressing enter without any value keeps the value unchanged.\n"
);
/******************************************************************************
* Category - General
* Functionality- Display temperature from sensor.
* Need modifications (Yes/No) - no
*****************************************************************************/
int temperature_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
printf("Junction Temprature (Tj) = %d\n", mvCtrlGetJuncTemp());
return 1;
}
U_BOOT_CMD(
temp, 1, 1, temperature_cmd,
"temp - Display the device temperature.\n",
" \n \tDisplay the device temperature as read from the internal sensor.\n"
);
int reset_count_cmd(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
MV_U32 resetCount, resetLimit;
char *bootcmd, *tmpStr = getenv("reset_count");
char countStr[10];
resetCount = tmpStr ? simple_strtoul(tmpStr, NULL, 16) : 0;
tmpStr = getenv("reset_limit");
resetLimit = tmpStr ? simple_strtoul(tmpStr, NULL, 10) : 0;
if( (resetLimit > 0) && (resetCount >= resetLimit)){
printf("Reset limit reached, Creset stopped.\n Reset reset_count or reset_limit to continue\n");
return 1;
}
/* in 1st time, save original boot command in 'bootcmd_Creset' env varialble */
if (resetCount == 0) {
bootcmd = getenv("bootcmd");
setenv("bootcmd_Creset", bootcmd);
/* replace boot command with 'Creset' or 'Creset boot' */
if( argc >= 2 && strcmp( argv[1], "boot") == 0)
setenv("bootcmd", "Creset boot");
else
setenv("bootcmd", "Creset");
}
printf("\nreset_count = %d\n" , resetCount);
sprintf(countStr, "%x", ++resetCount);
setenv("reset_count", countStr);
run_command("saveenv", 0);
/* if requested 'Creset boot' run boot command instead of reset */
if( argc >= 2 && strcmp( argv[1], "boot") == 0)
run_command("run bootcmd_Creset", 0);
else
run_command("reset", 0);
return 1;
}
U_BOOT_CMD(Creset, 2, 1, reset_count_cmd,
"Creset - Run 'reset' or boot command in a loop, while counting.\n",
" \n"
" \t'Creset' - loop and count reset tries:\n"
" \t'Creset boot' - loop and count boot tries:\n\n"
" \tto restart count, set count value to 1, save, and run boot:\n"
" \t'setenv reset_count 1; saveenv; boot;'\n"
" \t'to limit resets sequence set reset_limit to limit value'\n"
);
#if defined(MV_INCLUDE_PMU)
/******************************************************************************
* Category - General
* Functionality- Display temperature from sensor.
* Need modifications (Yes/No) - no
*****************************************************************************/
int volt_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U32 reg = 0, reg1 = 0;
MV_U32 value = 0;
int i = 0;
char *cmd, *s;
if (argc < 2)
goto usage;
cmd = argv[1];
if (strncmp(cmd, "cpu", 3) != 0 && strncmp(cmd, "core", 4) != 0)
goto usage;
reg = MV_REG_READ(PMU_TEMP_DIOD_CTRL0_REG);
reg |= PMU_TDC0_SEL_IP_MODE_MASK;
MV_REG_WRITE(PMU_TEMP_DIOD_CTRL0_REG, PMU_TDC0_SEL_IP_MODE_MASK);
if (strncmp(cmd, "cpu", 3) == 0) {
reg = MV_REG_READ(PMU_TEMP_DIOD_CTRL0_REG);
reg &= ~(PMU_TDC0_SEL_VSEN_MASK);
MV_REG_WRITE(PMU_TEMP_DIOD_CTRL0_REG, reg);
}
if (strncmp(cmd, "core", 3) == 0) {
reg = MV_REG_READ(PMU_TEMP_DIOD_CTRL0_REG);
reg |= PMU_TDC0_SEL_VSEN_MASK;
MV_REG_WRITE(PMU_TEMP_DIOD_CTRL0_REG, reg);
}
udelay(1000);
/* Verify that the temperature is valid */
reg = MV_REG_READ(PMU_TEMP_DIOD_CTRL1_REG);
if ((reg & PMU_TDC1_TEMP_VLID_MASK) == 0x0)
{
printf("Error reading voltage\n");
}
else
{
reg1 = MV_REG_READ(PMU_THERMAL_MNGR_REG);
reg1 = ((reg1 >> 1) & 0x1FF);
for (i = 0; i < 16; i++)
{
/* Read the thermal sensor looking for two successive readings that differ in LSB only */
reg = MV_REG_READ(PMU_THERMAL_MNGR_REG);
reg = ((reg >> 1) & 0x1FF);
if (((reg ^ reg1) & 0x1FE) == 0x0)
break;
/* save the current reading for the next iteration */
reg1 = reg;
}
value = ((reg + 241)*10000/39619);
if (i == 16)
printf("Voltage sensor is unstable: could not get two identical successive readings\n");
else
printf("Voltage (V) = %d.%d, Register Value = 0x%08X\n", value/100, value%100, reg);
}
return 0;
usage:
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
U_BOOT_CMD(
volt, 2, 1, volt_cmd,
"volt - Display the cpu / core voltage.\n",
"volt cpu - display the cpu voltage\n"
"volt core - display the core voltage\n"
);
#endif /* #if defined(MV_INCLUDE_PMU) */
/******************************************************************************
* Functional only when using Lauterbach to load image into DRAM
* Category - DEBUG
* Functionality- Display the array of registers the u-boot write to.
*
*****************************************************************************/
#if defined(REG_DEBUG)
int reg_arry[4096][2];
int reg_arry_index = 0;
int print_registers( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int i;
printf("Register display\n");
for (i=0; i < reg_arry_index; i++)
printf("Reg no %d addr 0x%x = 0x%08x\n", i, reg_arry[i][0], reg_arry[i][1]);
return 1;
}
U_BOOT_CMD(
printreg, 1, 1, print_registers,
"printreg - Display the register array the u-boot write to.\n",
" \n"
"\tDisplay the register array the u-boot write to.\n"
);
#endif
#if defined(MV_INCLUDE_GIG_ETH)
/******************************************************************************
* Category - Etherent
* Functionality- Display PHY ports status (using SMI access).
* Need modifications (Yes/No) - No
*****************************************************************************/
int sg_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U32 port;
for( port = 0 ; port < mvCtrlEthMaxPortGet(); port++ ) {
printf( "PHY %d :\n", port );
printf( "---------\n" );
mvEthPhyPrintStatus((MV_U32)mvBoardPhyAddrGet(port) );
printf("\n");
}
return 1;
}
U_BOOT_CMD(
sg, 1, 1, sg_cmd,
"sg - scanning the PHYs status\n",
" \n"
"\tScan all the Gig port PHYs and display their Duplex, Link, Speed and AN status.\n"
);
#endif /* #if defined(MV_INCLUDE_GIG_ETH) */
#if defined(MV_INCLUDE_PDMA)
/******************************************************************************
* Category - PDMA
* Functionality- Perform a PDMA transaction
* Need modifications (Yes/No) - No
*****************************************************************************/
int mvPdma_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
MV_8 cmd[20];
extern MV_8 console_buffer[];
MV_U32 src, dst, byteCount;
MV_PDMA_CHANNEL chan;
/* get PDMA channel */
/* source address */
while(1) {
readline( "Source Address: " );
strcpy( cmd, console_buffer );
src = simple_strtoul( cmd, NULL, 16 );
if( src == 0xffffffff ) printf( "Bad address !!!\n" );
else break;
}
/* desctination address */
while(1) {
readline( "Destination Address: " );
strcpy(cmd, console_buffer);
dst = simple_strtoul( cmd, NULL, 16 );
if( dst == 0xffffffff ) printf("Bad address !!!\n");
else break;
}
/* byte count */
while(1) {
readline( "Byte Count (up to 8KByte (0 - 0x1FFF)): " );
strcpy( cmd, console_buffer );
byteCount = simple_strtoul( cmd, NULL, 16 );
if( (byteCount >= 0x2000) || (byteCount == 0) ) printf("Bad value !!!\n");
else break;
}
if (mvPdmaChanAlloc(MV_PDMA_MEMORY, 0, &chan) != MV_OK) {
printf("Error allocating PDMA channel\n");
return 0;
}
/* wait for previous transfer completion */
while(mvPdmaChannelStateGet(&chan) == MV_PDMA_CHANNEL_RUNNING);
/* issue the transfer */
if (mvPdmaChanTransfer(&chan, MV_PDMA_MEM_TO_MEM, src, dst, byteCount, 0) != MV_OK) {
printf("Error with PDMA transfer\n");
}
/* wait for completion */
while(mvPdmaChannelStateGet(&chan) == MV_PDMA_CHANNEL_RUNNING);
if (mvPdmaChanFree(&chan) != MV_OK) {
printf("Error freeing PDMA channel\n");
return 0;
}
printf( "Done...\n" );
return 1;
}
U_BOOT_CMD(
pdma, 1, 1, mvPdma_cmd,
"pdma - Perform PDMA\n",
" \n"
"\tPerform PDMA memory to memory transaction with the parameters given by the user.\n"
);
#endif /* #if defined(MV_INCLUDE_PDMA) */
#if defined(MV_INCLUDE_XOR)
/******************************************************************************
* Category - DMA
* Functionality- Perform a DMA transaction using the XOR engine
* Need modifications (Yes/No) - No
*****************************************************************************/
#define XOR_TIMEOUT 0x8000000
struct xor_channel_t
{
MV_CRC_DMA_DESC *pDescriptor;
MV_ULONG descPhyAddr;
};
#define XOR_CAUSE_DONE_MASK(chan) ((BIT0|BIT1) << (chan * 16) )
void xor_waiton_eng(int chan)
{
int timeout = 0;
while(!(MV_REG_READ(XOR_CAUSE_REG(XOR_UNIT(chan))) & XOR_CAUSE_DONE_MASK(XOR_CHAN(chan))))
{
if(timeout > XOR_TIMEOUT)
goto timeout;
timeout++;
}
timeout = 0;
while(mvXorStateGet(chan) != MV_IDLE)
{
if(timeout > XOR_TIMEOUT)
goto timeout;
timeout++;
}
/* Clear int */
MV_REG_WRITE(XOR_CAUSE_REG(XOR_UNIT(chan)), ~(XOR_CAUSE_DONE_MASK(XOR_CHAN(chan))));
timeout:
if(timeout > XOR_TIMEOUT)
{
printf("ERR: XOR eng got timedout!!\n");
}
return;
}
int mvDma_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
MV_8 cmd[20], c;
extern MV_8 console_buffer[];
MV_U32 chan, src, dst, byteCount, ctrlLo, ctrlOvrrid;
MV_UNIT_WIN_INFO win;
struct xor_channel_t channel;
MV_U8 *pVirt = (MV_U8*)mvOsIoUncachedAlignedMalloc(NULL, 32, sizeof(MV_XOR_DESC),
&(channel.descPhyAddr), NULL);
MV_BOOL err;
/* XOR channel */
if( argc == 2 )
chan = simple_strtoul( argv[1], NULL, 16 );
else
chan = 0;
/* source address */
while(1) {
readline( "Physical Source Address (must be cache-line aligned): " );
strcpy( cmd, console_buffer );
src = simple_strtoul( cmd, NULL, 16 );
if ((src == 0xffffffff) || (src & 0x1F)) printf( "Bad address !!!\n" );
else break;
}
/* desctination address */
while(1) {
readline( "Physical Destination Address (must be cache-line aligned): " );
strcpy(cmd, console_buffer);
dst = simple_strtoul( cmd, NULL, 16 );
if ((dst == 0xffffffff) || (dst & 0x1F)) printf("Bad address !!!\n");
else break;
}
/* byte count */
while(1) {
readline( "Byte Count (up to (16M-1), must be a multiple of the cache-line): " );
strcpy( cmd, console_buffer );
byteCount = simple_strtoul( cmd, NULL, 16 );
if( (byteCount > 0xffffff) || (byteCount == 0) ) printf("Bad value !!!\n");
else break;
}
/* compose the command */
ctrlLo = (1 << XEXCR_REG_ACC_PROTECT_OFFS);
#if defined(MV_CPU_BE)
ctrlLo |= (XEXCR_DES_SWP_MASK);
/* | (1 << XEXCR_DRD_RES_SWP_OFFS)
| (1 << XEXCR_DWR_REQ_SWP_OFFS);
*/
#endif
/* set data transfer limit */
while(1) {
printf( "Source Data transfer limit(DTL):\n" );
printf( "(2) 32 bytes at a time.\n" );
printf( "(3) 64 bytes at a time.\n" );
printf( "(4) 128 bytes at a time.\n" );
c = getc();
printf( "%c\n", c );
err = MV_FALSE;
switch( c ) {
case 13: /* Enter */
ctrlLo |= (2 << XEXCR_SRC_BURST_LIMIT_OFFS);
printf( "32 bytes at a time.\n" );
break;
case '2':
ctrlLo |= (2 << XEXCR_SRC_BURST_LIMIT_OFFS);
break;
case '3':
ctrlLo |= (3 << XEXCR_SRC_BURST_LIMIT_OFFS);
break;
case '4':
ctrlLo |= (4 << XEXCR_SRC_BURST_LIMIT_OFFS);
break;
default:
printf( "Bad value !!!\n" );
err = MV_TRUE;
}
if( !err ) break;
}
while(1) {
printf( "Destination Data transfer limit(DTL):\n" );
printf( "(2) 32 bytes at a time.\n" );
printf( "(3) 64 bytes at a time.\n" );
printf( "(4) 128 bytes at a time.\n" );
c = getc();
printf( "%c\n", c );
err = MV_FALSE;
switch( c ) {
case 13: /* Enter */
ctrlLo |= (2 << XEXCR_DST_BURST_LIMIT_OFFS);
printf( "32 bytes at a time.\n" );
break;
case '2':
ctrlLo |= (2 << XEXCR_DST_BURST_LIMIT_OFFS);
break;
case '3':
ctrlLo |= (3 << XEXCR_DST_BURST_LIMIT_OFFS);
break;
case '4':
ctrlLo |= (4 << XEXCR_DST_BURST_LIMIT_OFFS);
break;
default:
printf( "Bad value !!!\n" );
err = MV_TRUE;
}
if( !err ) break;
}
/* set ovveride source option */
/* read the override control register */
ctrlOvrrid = MV_REG_READ(XOR_OVERRIDE_CTRL_REG(chan));
ctrlOvrrid &= ~((1 << XEAOCR_SA0OVR_EN_OFFS) |
(3 << XEAOCR_SA0OVRPTR_OFFS) |
(1 << XEAOCR_DA0OVR_EN_OFFS) |
(3 << XEAOCR_DA0OVRPTR_OFFS));
while(1) {
printf( "Override Source:\n" );
printf( "(9) - no override (default)\n" );
mvXorTargetWinRead( chan,0, &win );
printf( "Win0 base=%08x, size=%llx, Attrib=0x%x, ID=%d\n",
win.addrWin.baseLow, win.addrWin.size,win.attrib, win.targetId);
printf( "(0) - use Win0 (%s)\n",mvCtrlTargetNameGet(win.targetId));
mvXorTargetWinRead( chan,1, &win );
printf( "Win1 base=%08x, size=%llx, Attrib=0x%x, ID=%d\n",
win.addrWin.baseLow, win.addrWin.size,win.attrib, win.targetId);
printf( "(1) - use Win1 (%s)\n",mvCtrlTargetNameGet(win.targetId));
mvXorTargetWinRead( chan,2, &win );
printf( "(2) - use Win2 (%s)\n",mvCtrlTargetNameGet(win.targetId));
mvXorTargetWinRead( chan,3, &win );
printf( "(3) - use Win3 (%s)\n",mvCtrlTargetNameGet(win.targetId));
c = getc();
printf( "%c\n", c );
err = MV_FALSE;
switch( c ) {
case 13: /* Enter */
case '9':
printf( "No override\n" );
break;
case '0':
case '1':
case '2':
case '3':
ctrlOvrrid |= (1 << XEAOCR_SA0OVR_EN_OFFS) |
((c - '0') << XEAOCR_SA0OVRPTR_OFFS);
break;
default:
printf("Bad value !!!\n");
err = MV_TRUE;
}
if( !err ) break;
}
/* set override destination option */
while(1) {
printf( "Override Destination:\n" );
printf( "(9) - no override (default)\n" );
mvXorTargetWinRead( chan,0, &win );
printf( "(0) - use Win0 (%s)\n",mvCtrlTargetNameGet(win.targetId));
mvXorTargetWinRead( chan,1, &win );
printf( "(1) - use Win1 (%s)\n",mvCtrlTargetNameGet(win.targetId));
mvXorTargetWinRead( chan,2, &win );
printf( "(2) - use Win2 (%s)\n",mvCtrlTargetNameGet(win.targetId));
mvXorTargetWinRead( chan,3, &win );
printf( "(3) - use Win3 (%s)\n",mvCtrlTargetNameGet(win.targetId));
c = getc();
printf( "%c\n", c );
err = MV_FALSE;
switch( c ) {
case 13: /* Enter */
case '9':
printf( "No override\n" );
break;
case '0':
case '1':
case '2':
case '3':
ctrlOvrrid |= (1 << XEAOCR_DA0OVR_EN_OFFS) |
((c - '0') << XEAOCR_DA0OVRPTR_OFFS);
break;
default:
printf("Bad value !!!\n");
err = MV_TRUE;
}
if( !err ) break;
}
/* wait for previous transfer completion */
while (mvXorStateGet(chan) != MV_IDLE);
mvXorCtrlSet( chan, ctrlLo );
/* save the override control register */
MV_REG_WRITE(XOR_OVERRIDE_CTRL_REG(chan), ctrlOvrrid);
/* build the channel descriptor */
channel.pDescriptor = (MV_CRC_DMA_DESC *)pVirt;
channel.pDescriptor->srcAdd0 = src;
channel.pDescriptor->srcAdd1 = 0;
channel.pDescriptor->destAdd = dst;
channel.pDescriptor->byteCnt = byteCount;
channel.pDescriptor->nextDescPtr = 0;
channel.pDescriptor->status = BIT31;
channel.pDescriptor->descCommand = 0x0;
/* issue the transfer */
if (mvXorTransfer(chan, MV_DMA, channel.descPhyAddr) != MV_OK)
printf("Error in DMA(XOR) Operation\n");
/* wait for completion */
xor_waiton_eng(chan);
mvOsIoUncachedAlignedFree(NULL, sizeof(MV_XOR_DESC), channel.descPhyAddr, pVirt, 0);
printf( "Done...\n" );
return 1;
}
U_BOOT_CMD(
dma, 1, 1, mvDma_cmd,
"dma - Perform DMA using the XOR engine\n",
" \n"
"\tPerform DMA transaction with the parameters given by the user.\n"
);
#endif /* #if defined(MV_INCLUDE_XOR) */
/******************************************************************************
* Category - Memory
* Functionality- Displays the MV's Memory map
* Need modifications (Yes/No) - Yes
*****************************************************************************/
int displayMemoryMap_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
mvCtrlAddrDecShow();
return 1;
}
U_BOOT_CMD(
map, 1, 1, displayMemoryMap_cmd,
"map - Display address decode windows\n",
" \n"
"\tDisplay controller address decode windows: CPU, PCI, Gig, DMA, XOR and COMM\n"
);
/******************************************************************************
* Category - MonExt
*****************************************************************************/
int printTempMsg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
printf("This command allocated for monitor extinction\n");
return 1;
}
U_BOOT_CMD(
tempCmd0, 1, 1, printTempMsg,
"tempCmd - This command allocated for monitor extinction\n",
" "
);
U_BOOT_CMD(
tempCmd1, 1, 1, printTempMsg,
"tempCmd - This command allocated for monitor extinction\n",
" "
);
U_BOOT_CMD(
tempCmd2, 1, 1, printTempMsg,
"tempCmd - This command allocated for monitor extinction\n",
" "
);
U_BOOT_CMD(
tempCmd3, 1, 1, printTempMsg,
"tempCmd - This command allocated for monitor extinction\n",
" "
);
#if defined(MV_INC_BOARD_DDIM)
/******************************************************************************
* Category - Memory
* Functionality- Displays the SPD information for a givven dimm
* Need modifications (Yes/No) -
*****************************************************************************/
int dimminfo_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int num = 0;
if (argc > 1) {
num = simple_strtoul (argv[1], NULL, 10);
}
printf("*********************** DIMM%d *****************************\n",num);
dimmSpdPrint(num);
printf("************************************************************\n");
return 1;
}
U_BOOT_CMD(
ddimm, 2, 1, dimminfo_cmd,
"ddimm - Display SPD Dimm Info\n",
" [0/1]\n"
"\tDisplay Dimm 0/1 SPD information.\n"
);
/******************************************************************************
* Category - Memory
* Functionality- Copy the SPD information of dimm 0 to dimm 1
* Need modifications (Yes/No) -
*****************************************************************************/
int spdcpy_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
printf("Copy DIMM 0 SPD data into DIMM 1 SPD...");
if (MV_OK != dimmSpdCpy())
printf("\nDIMM SPD copy fail!\n");
else
printf("Done\n");
return 1;
}
U_BOOT_CMD(
spdcpy, 2, 1, spdcpy_cmd,
"spdcpy - Copy Dimm 0 SPD to Dimm 1 SPD \n",
""
""
);
#endif /* #if defined(MV_INC_BOARD_DDIM) */
#ifdef CONFIG_MV_XSMI
#include "eth-phy/mvEthPhyXsmi.h"
#include "ctrlEnv/mvCtrlNetCompLib.h"
int xsmi_phy_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U16 phyReg;
if (argc < 4) {
printf("command need three arguments\n");
cmd_usage(cmdtp);
return 1;
}
/* NSS need to be enabled before each access and disabled right after,
in order to access the PHY registers via PSS window */
mvNetComplexNssSelect(1);
mvEthPhyXsmiRegRead(simple_strtoul(argv[1], NULL, 16),
simple_strtoul(argv[2], NULL, 16),
simple_strtoul(argv[3], NULL, 16), &phyReg);
mvNetComplexNssSelect(0);
printf("0x%x\n", phyReg);
return 1;
}
U_BOOT_CMD(
xsmiPhyRead, 4, 4, xsmi_phy_read_cmd,
"xsmiPhyRead - Read Phy register through XSMI interface\n",
" <Phy Address> <Dev Address> <Reg Offset>. \n"
"\tRead the Phy register through XSMI interface. \n"
);
int xsmi_phy_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
if (argc < 5) {
printf("command need four arguments\n");
cmd_usage(cmdtp);
return 1;
}
/* NSS need to be enabled before each access and disabled right after,
in order to access the PHY registers via PSS window */
mvNetComplexNssSelect(1);
mvEthPhyXsmiRegWrite(simple_strtoul(argv[1], NULL, 16),
simple_strtoul(argv[2], NULL, 16),
simple_strtoul(argv[3], NULL, 16),
simple_strtoul(argv[4], NULL, 16));
mvNetComplexNssSelect(0);
return 1;
}
U_BOOT_CMD(
xsmiPhyWrite, 5, 5, xsmi_phy_write_cmd,
"xsmiPhyWrite - Write Phy register through XSMI interface\n",
" <Phy Address> <Dev Address> <Reg Offset> <Value>. \n"
"\tWrite to Phy register through XSMI interface. \n"
);
#endif /* CONFIG_MV_XSMI */
#if defined(MV_INCLUDE_GIG_ETH)
#include "eth-phy/mvEthPhy.h"
int phy_dump_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
/* bitmask of registers we print */
static unsigned int page_regs[] = {
/*32222222222211111111110000000000*/ /* reg 31->0 */
/*10987654321098765432109876543210*/
0b00000100101111111000011111111111, /* page 0 */
0b00000111101011111000000111111111,
0b00000000001111010000000000000000,
0b00000000000011110000000000000000,
0b00001111101111110000000001110011,
0b00011111101111110000000000000000,
0b00000111100101110000000000000000,
0b00011110001111110000000000000000,
0b00000000000000001111111100000111,
0b00000000000000000000000000101111,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000001111111100111111,
0b00000000000000000000000000000000,
0b00000000000000001100000100001111, /* page 14 */
};
MV_U16 phyReg;
int phy = simple_strtoul( argv[1], NULL, 16 );
int i, j;
int num_pages = sizeof page_regs / sizeof *page_regs;
unsigned int* pp;
printf(" "); // %2d:
for (i = 0; i < num_pages; i++) {
printf(" %4d", i);
}
printf("\n");
for (i = 0; i < 32; i++) {
unsigned int todo = 0;
printf("%2d:", i);
for (j = 0, pp = page_regs; j < num_pages; j++, pp++) {
unsigned int p = *pp;
p >>= i;
if (!(p & 1)) {
printf(" %4s", "-");
} else {
mvEthPhyRegWrite(phy, 0x16, j); // page
mvEthPhyRegRead(phy, i, &phyReg);
printf(" %04x", phyReg);
}
p >>= 1;
todo |= p;
}
printf("\n");
if (todo == 0)
break;
}
return 1;
}
U_BOOT_CMD(
phydump, 2, 2, phy_dump_cmd,
"phydump - dump all Phy registers\n",
" Phy_address. \n"
"\tDump the Phy registers. \n"
);
int phy_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U16 phyReg;
mvEthPhyRegRead(simple_strtoul( argv[1], NULL, 16 ),
simple_strtoul( argv[2], NULL, 16), &phyReg);
printf ("0x%x\n", phyReg);
return 1;
}
U_BOOT_CMD(
phyRead, 3, 3, phy_read_cmd,
"phyRead - Read Phy register\n",
" Phy_address Phy_offset. \n"
"\tRead the Phy register. \n"
);
int phy_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
mvEthPhyRegWrite(simple_strtoul( argv[1], NULL, 16 ),
simple_strtoul( argv[2], NULL, 16 ),
simple_strtoul( argv[3], NULL, 16 ));
return 1;
}
U_BOOT_CMD(
phyWrite, 4, 4, phy_write_cmd,
"phyWrite - Write Phy register\n",
" Phy_address Phy_offset value.\n"
"\tWrite to the Phy register.\n"
);
#if defined(MV_INCLUDE_SWITCH)
#include "ethSwitch/mvSwitch.h"
int switch_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U16 phyReg;
mvEthSwitchRegRead(simple_strtoul( argv[1], NULL, 16 ),
simple_strtoul( argv[2], NULL, 16), simple_strtoul( argv[3], NULL, 16 ), &phyReg);
printf ("0x%x\n", phyReg);
return 1;
}
U_BOOT_CMD(
switchRegRead, 4, 4, switch_read_cmd,
"switchRegRead - Read switch register\n",
" Port_number Phy_address Phy_offset. \n"
"\tRead the switch register. \n"
);
int switch_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
mvEthSwitchRegWrite(simple_strtoul( argv[1], NULL, 16 ),
simple_strtoul( argv[2], NULL, 16 ), simple_strtoul( argv[3], NULL, 16 ),
simple_strtoul( argv[4], NULL, 16 ));
return 1;
}
U_BOOT_CMD(
switchRegWrite, 5, 5, switch_write_cmd,
"switchRegWrite - Write switch register\n",
" Port_number Phy_address Phy_offset value.\n"
"\tWrite to the switch register.\n"
);
int switch_phy_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U16 phyReg;
mvEthSwitchPhyRegRead(simple_strtoul( argv[1], NULL, 16 ), simple_strtoul( argv[2], NULL, 16 ),
simple_strtoul( argv[3], NULL, 16 ), &phyReg);
printf ("0x%x\n", phyReg);
return 1;
}
U_BOOT_CMD(
switchPhyRegRead, 4, 4, switch_phy_read_cmd,
"- Read switch register\n",
" SW_on_port Port_number Phy_offset. \n"
"\tRead the switch register. \n"
);
int switch_phy_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
mvEthSwitchPhyRegWrite(simple_strtoul( argv[1], NULL, 16 ),
simple_strtoul( argv[2], NULL, 16 ), simple_strtoul( argv[3], NULL, 16 ),
simple_strtoul( argv[4], NULL, 16 ));
return 1;
}
U_BOOT_CMD(
switchPhyRegWrite, 5, 4, switch_phy_write_cmd,
"- Write switch register\n",
" SW_on_port Port_number Phy_offset value.\n"
"\tWrite to the switch register.\n"
);
int switch_cntread_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U16 data;
MV_U32 port;
MV_U32 i;
port = simple_strtoul(argv[1], NULL, 16);
printf("Switch on port = %d.\n", port);
for(i = 0; i < 7; i++) {
/* Set egress counter */
mvEthSwitchRegWrite(port, 0x1B, 0x1D, 0xC400 | ((i + 1) << 5) | 0xE);
do {
mvEthSwitchRegRead(port, 0x1B, 0x1D, &data);
} while(data & 0x8000);
/* Read egress counter */
mvEthSwitchRegRead(port, 0x1B, 0x1F, &data);
printf("Port %d: Egress 0x%x, Ingress ", i, data);
/* Set ingress counter */
mvEthSwitchRegWrite(port, 0x1B, 0x1D, 0xC400 | ((i + 1) << 5) | 0x0);
do {
mvEthSwitchRegRead(port, 0x1B, 0x1D, &data);
} while(data & 0x8000);
/* Read egress counter */
mvEthSwitchRegRead(port, 0x1B, 0x1F, &data);
printf("0x%x.\n", data);
}
/* Clear all counters */
mvEthSwitchRegWrite(port, 0x1B, 0x1D, 0x94C0);
do {
mvEthSwitchRegRead(port, 0x1B, 0x1D, &data);
} while(data & 0x8000);
return 1;
}
U_BOOT_CMD(
switchCountersRead, 2, 2, switch_cntread_cmd,
"switchCntPrint - Read switch port counters.\n",
" MAC_Port. \n"
"\tRead the switch ports counters. \n"
);
#elif defined(MV_SWITCH_ADDRESS_COMPLETION) /* MV_INCLUDE_SWITCH */
#define SWITCH_REGS_BASE_ADDR_MASK 0xFC000000
#define SWITCH_ADDR_COMPL_MSB_VAL(addr) ((addr >> 24) & 0xFF)
#define SWITCH_ADDR_COMPL_SHIFT(addr) (((addr >> 24) & 0x3) << 3)
#define SWITCH_BUS_ADDR(addr) ((~SWITCH_REGS_BASE_ADDR_MASK & addr) |\
(SWITCH_WIN_BASE_ADDR_GET() & SWITCH_REGS_BASE_ADDR_MASK))
/*******************************************************************************
* SWITCH_WIN_BASE_ADDR_GET
*
* DESCRIPTION:
* This function returns the base address of switch registers window
*
*
* RETURN:
* base address of switch registers window
*
*******************************************************************************/
static __inline MV_U32 SWITCH_WIN_BASE_ADDR_GET(MV_VOID)
{
static MV_U32 baseAddr;
baseAddr = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(SWITCH_WIN_ID));
return baseAddr;
}
/*******************************************************************************
* SWITCH_ADDR_COMPL_SET
*
* DESCRIPTION:
* This function configures address completion register
*
* INPUT:
* addr - the address to access indirectly
*
*******************************************************************************/
static __inline MV_STATUS SWITCH_ADDR_COMPL_SET(MV_U32 addr)
{
MV_U32 rVal;
/* Configure address completion region REG using SERDES memory window */
rVal = MV_MEMIO32_READ(SWITCH_WIN_BASE_ADDR_GET());
rVal &= ~(0xFF << SWITCH_ADDR_COMPL_SHIFT(addr));
rVal |= SWITCH_ADDR_COMPL_MSB_VAL(addr) << SWITCH_ADDR_COMPL_SHIFT(addr);
MV_MEMIO32_WRITE(SWITCH_WIN_BASE_ADDR_GET(), rVal);
return MV_OK;
}
/*******************************************************************************
* mvSwitchRegisterGet
*
* DESCRIPTION:
* This function reads switch register with address completion
*
* INPUT:
* address - the address to read indirectly
* mask - mask of the read data
*
* OUTPUT:
* data - the register's data value
*
*
*******************************************************************************/
void mvSwitchRegisterGet(MV_U32 address, MV_U32 *data, MV_U32 mask)
{
SWITCH_ADDR_COMPL_SET(address); /* Only MSB is important, serdes number offset does not matter */
*data = MV_MEMIO32_READ(SWITCH_BUS_ADDR(address)) & mask;
}
/*******************************************************************************
* switchRegRead
*
* DESCRIPTION:
* This command reads switch register with address completion
*
*******************************************************************************/
int switch_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
MV_U32 regVal;
mvSwitchRegisterGet(simple_strtoul(argv[1], NULL, 16), &regVal, 0xFFFF);
printf ("0x%x\n", regVal);
return 1;
}
U_BOOT_CMD(
switchRegRead, 2, 2, switch_read_cmd,
"switchRegRead - Read switch register, using Address completion\n",
" Reg_offset. \n"
"\tRead the switch register, using Address completion. \n"
);
/*******************************************************************************
* mvSwitchRegisterSet
*
* DESCRIPTION:
* This function writes to switch register with address completion
*
* address - the address to write to indirectly
* data - the data to write
* mask - mask of the write data
*
*******************************************************************************/
void mvSwitchRegisterSet(MV_U32 address, MV_U32 data, MV_U32 mask)
{
MV_U32 regData;
if ((mask & 0xFFFF) != 0xFFFF) { /* since switch registers are 16 bits - check only the relevant bits */
mvSwitchRegisterGet(address, &regData, ~mask);
regData |= (data & mask);
} else
regData = data;
SWITCH_ADDR_COMPL_SET(address); /* Only MSB is important, serdes number offset does not matter */
MV_MEMIO32_WRITE(SWITCH_BUS_ADDR(address), regData);
}
/*******************************************************************************
* switchRegWrite
*
* DESCRIPTION:
* This command writes to switch register with address completion
*
*******************************************************************************/
int switch_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
mvSwitchRegisterSet(simple_strtoul(argv[1], NULL, 16), simple_strtoul(argv[2], NULL, 16), 0xFFFF);
return 1;
}
U_BOOT_CMD(
switchRegWrite, 3, 3, switch_write_cmd,
"switchRegWrite - Write to switch register, using Address completion\n",
" Reg_offset Reg_data. \n"
"\tWrite to the switch register, using Address completion. \n"
);
#endif /* MV_SWITCH_ADDRESS_COMPLETION */
#endif /* #if defined(MV_INCLUDE_GIG_ETH) */
#define REG_SDRAM_CONFIG_ADDR 0x1400
#define REG_DDR3_RANK_CTRL_ADDR 0x15E0
#define REG_READ_DATA_SAMPLE_DELAYS_ADDR 0x1538
#define REG_READ_DATA_READY_DELAYS_ADDR 0x153C
#define REG_PHY_REGISTRY_FILE_ACCESS_ADDR 0x16A0
#define REG_PHY_DATA 0
#define REG_PHY_CTRL 1
/******************************************************************************
* Category - DDR3 Training
* Functionality- The commands prints the results of the DDR3 Training
* Need modifications (Yes/No) - no
*****************************************************************************/
#ifdef MV_DDR_TRAINING_CMD_NEW_TIP
unsigned int trainingReadPhyReg(int uiRegAddr, int uiPup, int type)
{
unsigned int uiReg;
unsigned int addrLow = 0x3F & uiRegAddr;
unsigned int addrHi = ((0xC0 & uiRegAddr) >> 6);
uiReg = (1 << 31) + (uiPup << 22) + (type << 26) + (addrHi << 28) + (addrLow << 16);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg&0x7FFFFFFF);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg);
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << 31));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR);
uiReg = uiReg & 0xFFFF;
return uiReg;
}
int training_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
MV_U32 uiCsEna,uiCs,uiReg,uiPup,uiPhase,uiDelay,
uiRdRdyDly,uiRdSmplDly,uiDq, uiCentralTxRes, uiCentralRxRes;
MV_U32 uiPupNum;
uiCsEna = MV_REG_READ(REG_DDR3_RANK_CTRL_ADDR) & 0xF;
printf("DDR3 Training results: \n");
uiPupNum = 5;
for (uiCs = 0; uiCs < 4; uiCs++) {
if (uiCsEna & (1 << uiCs)) {
printf("CS: %d \n", uiCs);
for(uiPup = 0; uiPup < uiPupNum; uiPup++) {
uiReg = trainingReadPhyReg(0 + uiCs*4,uiPup, REG_PHY_DATA);
uiPhase = (uiReg >> 6) & 0x7;
uiDelay = uiReg & 0x1F;
printf("Write Leveling: PUP: %d, Phase: %d, Delay: %d\n",uiPup,uiPhase,uiDelay);
}
for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
uiReg = trainingReadPhyReg(2 + uiCs*4,uiPup, REG_PHY_DATA);
uiPhase = (uiReg >> 6) & 0x7;
uiDelay = uiReg & 0x1F;
printf("Read Leveling: PUP: %d, Phase: %d, Delay: %d\n",uiPup, uiPhase, uiDelay);
}
uiRdRdyDly = ((MV_REG_READ(REG_READ_DATA_READY_DELAYS_ADDR) >> (8*uiCs)) & 0x1F);
uiRdSmplDly = ((MV_REG_READ(REG_READ_DATA_SAMPLE_DELAYS_ADDR) >> (8*uiCs)) & 0x1F);
printf("Read Sample Delay:\t%d\n",uiRdSmplDly);
printf("Read Ready Delay:\t%d\n",uiRdRdyDly);
/* PBS */
if (uiCs == 0) {
for (uiPup=0;uiPup<uiPupNum;uiPup++) {
for (uiDq = 0; uiDq < 10 ;uiDq++) {
if (uiDq == 9)
uiDq++;
uiReg = trainingReadPhyReg(0x10+uiDq+uiCs*0x12,uiPup, REG_PHY_DATA);
uiDelay = uiReg & 0x1F;
if (uiDq == 0)
printf("PBS TX: PUP: %d: ", uiPup);
printf("%d ", uiDelay);
}
printf("\n");
}
for(uiPup=0; uiPup < uiPupNum; uiPup++) {
for(uiDq = 0; uiDq < 9; uiDq++) {
uiReg = trainingReadPhyReg(0x50+uiDq+uiCs*0x12,uiPup, REG_PHY_DATA);
uiDelay = uiReg & 0x1F;
if (uiDq == 0)
printf("PBS RX: PUP: %d: ", uiPup);
printf("%d ", uiDelay);
}
printf("\n");
}
}
/*Read Centralization windows sizes for Scratch PHY registers*/
for(uiPup = 0; uiPup < uiPupNum; uiPup++)
{
uiReg = trainingReadPhyReg(0xC0+uiCs,uiPup, REG_PHY_DATA);
uiCentralRxRes = uiReg >> 5;
uiCentralTxRes = uiReg & 0x1F;
printf("Central window size for PUP %d is %d(RX) and %d(TX)\n", uiPup, uiCentralRxRes, uiCentralTxRes);
}
}
}
return 1;
}
#else
int training_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
#define REG_PHY_OP_OFFS 31
#define REG_PHY_CS_OFFS 16
#define REG_PHY_PUP_OFFS 22
#define CENTRAL_RESULTS_PUP0 0x1504
#define CENTRAL_RESULTS_PUP1 0x150C
#define CENTRAL_RESULTS_PUP2 0x1514
#define CENTRAL_RESULTS_PUP3 0x151C
MV_U32 uiCsEna,uiCs,uiReg,uiPup,uiPhase,uiDelay,
uiDQS,uiRdRdyDly,uiRdSmplDly,uiDq;
MV_U32 uiPupNum;
uiCsEna = MV_REG_READ(REG_DDR3_RANK_CTRL_ADDR) & 0xF;
printf("DDR3 Training results: \n");
uiPupNum = 4;
for (uiCs = 0; uiCs < 4; uiCs++) {
if (uiCsEna & (1 << uiCs)) {
printf("CS: %d \n", uiCs);
for(uiPup = 0; uiPup < uiPupNum; uiPup++) {
uiReg = (1 << REG_PHY_OP_OFFS) | (uiPup << REG_PHY_PUP_OFFS) | ((0x4*uiCs) << REG_PHY_CS_OFFS);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg); /* 0x16A0 */
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << REG_PHY_OP_OFFS));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */
uiPhase = (uiReg >> 6) & 0x7;
uiDelay = uiReg & 0x1F;
uiReg = (1 << REG_PHY_OP_OFFS) | (uiPup << REG_PHY_PUP_OFFS) | ((0x4*uiCs+0x1) << REG_PHY_CS_OFFS);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg); /* 0x16A0 */
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << REG_PHY_OP_OFFS));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */
uiDQS = (uiReg & 0x3F) - uiDelay;
printf("Write Leveling: PUP: %d, Phase: %d, Delay: %d, DQS: %d \n",uiPup,uiPhase,uiDelay,uiDQS);
}
for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
uiReg = (1 << REG_PHY_OP_OFFS) | (uiPup << REG_PHY_PUP_OFFS) | ((0x4*uiCs+0x2) << REG_PHY_CS_OFFS);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg); /* 0x16A0 */
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << REG_PHY_OP_OFFS));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */
uiPhase = (uiReg >> 6) & 0x7;
uiDelay = uiReg & 0x1F;
uiReg = (1 << REG_PHY_OP_OFFS) | (uiPup << REG_PHY_PUP_OFFS) | ((0x4*uiCs+0x3) << REG_PHY_CS_OFFS);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg); /* 0x16A0 */
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << REG_PHY_OP_OFFS));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */
uiDQS = uiReg & 0x3F;
printf("Read Leveling: PUP: %d, Phase: %d, Delay: %d, DQS: %d \n",uiPup, uiPhase, uiDelay, uiDQS);
}
uiRdRdyDly = ((MV_REG_READ(REG_READ_DATA_READY_DELAYS_ADDR) >> (8*uiCs)) & 0x1F);
uiRdSmplDly = ((MV_REG_READ(REG_READ_DATA_SAMPLE_DELAYS_ADDR) >> (8*uiCs)) & 0x1F);
printf("Read Sample Delay:\t%d\n",uiRdSmplDly);
printf("Read Ready Delay:\t%d\n",uiRdRdyDly);
/* PBS */
if (uiCs == 0) {
for (uiPup=0;uiPup<uiPupNum;uiPup++) {
for (uiDq = 0; uiDq < 10 ;uiDq++) {
if (uiDq == 9)
uiDq++;
uiReg = (1 << REG_PHY_OP_OFFS) | (uiPup << REG_PHY_PUP_OFFS) | ((0x10+uiDq) << REG_PHY_CS_OFFS);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg); /* 0x16A0 */
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << REG_PHY_OP_OFFS));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */
uiDelay = uiReg & 0x1F;
if (uiDq == 0)
printf("PBS TX: PUP: %d: ", uiPup);
if (uiDq < 8)
printf("DQ:%d-%d,", uiDq, uiDelay);
else if (uiDq == 8)
printf("\nPBS TX: PUP: %d, DQS-%d \n", uiPup, uiDelay);
else
printf("PBS TX: PUP: %d, DM-%d \n", uiPup, uiDelay);
}
}
for(uiPup=0; uiPup < uiPupNum; uiPup++) {
for(uiDq = 0; uiDq < 9; uiDq++) {
uiReg = (1 << REG_PHY_OP_OFFS) | (uiPup << REG_PHY_PUP_OFFS) | ((0x30+uiDq) << REG_PHY_CS_OFFS);
MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg); /* 0x16A0 */
do {
uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << REG_PHY_OP_OFFS));
} while (uiReg); /* Wait for '0' to mark the end of the transaction */
uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */
uiDelay = uiReg & 0x1F;
if (uiDq == 0)
printf("PBS RX: PUP: %d: ", uiPup);
if (uiDq < 8)
printf("DQ:%d-%d,", uiDq, uiDelay);
if (uiDq == 8)
printf("\nPBS RX: PUP: %d, DQS-%d \n", uiPup, uiDelay);
}
}
}
}
}
return 1;
}
#endif
U_BOOT_CMD(
training, 1, 1, training_cmd,
"training - prints the results of the DDR3 Training.\n",""
);
#ifdef MV_DDR_TRAINING_CMD_NEW_TIP
#define WL_PHY_REG (0x0)
#define WRITE_CENTRALIZATION_PHY_REG (0x1)
#define RL_PHY_REG (0x2)
#define READ_CENTRALIZATION_PHY_REG (0x3)
#define RESULT_DB_PHY_REG_ADDR 0xC0
#define PAD_CONFIG_PHY_REG (0xA8)
/******************************************************************************
* Category - DDR3 Training
* Functionality- The commands prints the row data of stability results for DDR3 Training
* Need modifications (Yes/No) - no
*****************************************************************************/
MV_U32 dminPhyRegTable[20][2] = {
{0 ,0xC0},
{0 ,0xC1},
{0 ,0xC2},
{0 ,0xC3},
{0 ,0xC4},
{1 ,0xC0},
{1 ,0xC1},
{1 ,0xC2},
{1 ,0xC3},
{1 ,0xC4},
{2 ,0xC0},
{2 ,0xC1},
{2 ,0xC2},
{2 ,0xC3},
{2 ,0xC4},
{0 ,0xC5},
{1 ,0xC5},
{2 ,0xC5},
{0 ,0xC6},
{1 ,0xC6}};
int trainingStability_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
MV_U32 uiCsEna, interfaceId=0, csindex = 0,busId=0, padIndex=0;
MV_U32 regData, regData1;
uiCsEna = MV_REG_READ(REG_DDR3_RANK_CTRL_ADDR) & 0xF;
/*Title print*/
for(interfaceId = 0; interfaceId < 1; interfaceId++)
{
printf("Title: I/F# , Tj,CalibrationN0,CalibrationP0,CalibrationN1,CalibrationP1,CalibrationN2,CalibrationP2,");
for(csindex = 0; csindex < 4; csindex++)
{
if (!(uiCsEna & (1 << csindex))) continue;
printf("CS%d , ",csindex);
for(busId = 0; busId < 5; busId++)
{
#ifdef CONFIG_DDR3/*DDR3*/
printf("VWTx,VWRx,WL_tot,WL_ADLL,WL_PH,RL_Tot,RL_ADLL,RL_PH,RL_Smp,CenTx,CenRx,Vref,DQVref,");
#else/*DDR4*/
printf("DminTx,AreaTx,DminRx,AreaRx,WL_tot,WL_ADLL,WL_PH,RL_Tot,RL_ADLL,RL_PH,RL_Smp,CenTx,CenRx,Vref,DQVref,");
#endif
#ifdef CONFIG_DDR3
#else
for(padIndex = 0; padIndex < 10; padIndex++)
{
printf("DC-Pad%d,",padIndex);
}
#endif
for(padIndex = 0; padIndex < 10; padIndex++)
{
printf("PBSTx-Pad%d,",padIndex);
}
for(padIndex = 0; padIndex < 10; padIndex++)
{
printf("PBSRx-Pad%d,",padIndex);
}
}
}
}
printf("\n");
/*Data print*/
for(interfaceId = 0; interfaceId < 1; interfaceId++)
{
printf("Data: %d,%d,",interfaceId,mvCtrlGetJuncTemp());//add Junction Temperature
regData = MV_REG_READ(0x14C8);
printf("%d,%d,",((regData&0x3F0)>>4),((regData&0xFC00)>>10));
regData = MV_REG_READ(0x17C8);
printf("%d,%d,",((regData&0x3F0)>>4),((regData&0xFC00)>>10));
regData = MV_REG_READ(0x1DC8);
printf("%d,%d,",((regData&0x3F0000)>>16),((regData&0xFC00000)>>22));
for(csindex = 0; csindex < 4; csindex++)
{
if (!(uiCsEna & (1 << csindex))) continue;
printf("CS%d , ",csindex);
for(busId = 0; busId <5; busId++)
{
#ifdef CONFIG_DDR3/*DDR3*/
regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex,busId, REG_PHY_DATA);
printf("%d,%d,",(regData&0x1F),((regData&0x3E0)>>5));
#else/*DDR4*/
/*DminTx, areaTX*/
regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex,busId, REG_PHY_DATA);
regData1 = trainingReadPhyReg(dminPhyRegTable[csindex*5+busId][1],dminPhyRegTable[csindex*5+busId][0], REG_PHY_CTRL);
printf("%d,%d,",2*(regData1&0xFF),regData);
/*DminRx, areaRX*/
regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex+4,busId, REG_PHY_DATA);
regData1 = trainingReadPhyReg(dminPhyRegTable[csindex*5+busId][1],dminPhyRegTable[csindex*5+busId][0], REG_PHY_CTRL);
printf("%d,%d,",2*(regData1>>8),regData);
#endif
/*WL*/
regData = trainingReadPhyReg(WL_PHY_REG+csindex*4,busId, REG_PHY_DATA);
printf("%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32,(regData&0x1F),(regData&0x1C0)>>6);
/*RL*/
regData1 = MV_REG_READ(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
regData1 = (regData1&(0xF<<(4*csindex))) >> (4*csindex);
regData = trainingReadPhyReg(RL_PHY_REG+csindex*4,busId, REG_PHY_DATA);
printf("%d,%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32 + regData1*64,(regData&0x1F),((regData&0x1C0)>>6),regData1);
/*Centralization*/
regData = trainingReadPhyReg(WRITE_CENTRALIZATION_PHY_REG+csindex*4,busId, REG_PHY_DATA);
printf("%d,",(regData&0x3F));
regData = trainingReadPhyReg(READ_CENTRALIZATION_PHY_REG+csindex*4,busId, REG_PHY_DATA);
printf("%d,",(regData&0x1F));
/*Vref */
regData = trainingReadPhyReg(PAD_CONFIG_PHY_REG+csindex,busId, REG_PHY_DATA);
printf("%d,",(regData&0x7));
/*DQVref*/
/* Need to add the Read Function from device*/
printf("%d,",0);
#ifndef CONFIG_DDR3
for(padIndex = 0; padIndex < 11; padIndex++)
{
regData = trainingReadPhyReg(0xD0+12*csindex+padIndex,busId, REG_PHY_DATA);
printf("%d,",(regData&0x3F));
}
#endif
for(padIndex = 0; padIndex < 11; padIndex++)
{
regData = trainingReadPhyReg(0x10+16*csindex+padIndex,busId, REG_PHY_DATA);
printf("%d,",(regData&0x3F));
}
for(padIndex = 0; padIndex < 11; padIndex++)
{
regData = trainingReadPhyReg(0x50+16*csindex+padIndex,busId, REG_PHY_DATA);
printf("%d,",(regData&0x3F));
}
}
}
}
printf("\n");
return MV_OK;
}
U_BOOT_CMD(
trainingStability, 1, 1, trainingStability_cmd,
"training - prints the results of the DDR3 Training.\n",""
);
#endif/*NewTip*/
#endif /* MV_TINY */
int whoAmI_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
{
printf("cpu #: %d", whoAmI());
return 1;
}
U_BOOT_CMD(
whoAmI, 2, 1, whoAmI_cmd,
"- reading CPU ID\n",
""
);