342 lines
7.8 KiB
C
342 lines
7.8 KiB
C
|
/*******************************************************************************
|
||
|
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 "ddr2/mvDramIf.h"
|
||
|
#include "mvOs.h"
|
||
|
#include "mvBoardEnvLib.h"
|
||
|
#include "ddr2/mvDramIfRegs.h"
|
||
|
#include "mvCpuIfRegs.h"
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
#define DB(x) x
|
||
|
#else
|
||
|
#define DB(x)
|
||
|
#endif
|
||
|
|
||
|
extern void i2c_init(int speed, int slaveaddr);
|
||
|
extern void _start(void);
|
||
|
extern unsigned int mvCpuPclkGet(void);
|
||
|
extern void reset_cpu(void);
|
||
|
extern int dramBoot;
|
||
|
|
||
|
|
||
|
#ifdef MV_INC_DRAM_MFG_TEST
|
||
|
static MV_VOID mvDramMfgTrst(void);
|
||
|
static MV_STATUS mv_mem_test(MV_U32* pMem, MV_U32 pattern, MV_U32 count);
|
||
|
static MV_STATUS mv_mem_cmp(MV_U32* pMem, MV_U32 pattern, MV_U32 count);
|
||
|
#endif
|
||
|
|
||
|
MV_VOID mvIntrfaceWidthPrint(MV_VOID)
|
||
|
{
|
||
|
printf(" 16bit width");
|
||
|
}
|
||
|
|
||
|
MV_VOID mvIntrfaceParamPrint(MV_VOID)
|
||
|
{
|
||
|
MV_U32 temp;
|
||
|
|
||
|
printf("DRAM");
|
||
|
temp = MV_REG_READ(0x1400);
|
||
|
if (temp & BIT14)
|
||
|
{
|
||
|
printf(" (DDR3)");
|
||
|
switch((MV_REG_READ(0x15D0) >> 2) & 0xd)
|
||
|
{
|
||
|
case 0x4: printf(" CAS Latency = 5");
|
||
|
break;
|
||
|
case 0x8: printf(" CAS Latency = 6");
|
||
|
break;
|
||
|
case 0xC: printf(" CAS Latency = 7");
|
||
|
break;
|
||
|
default: printf(" unknown CAL ");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf(" (DDR2)");
|
||
|
switch((MV_REG_READ(0x141c) >> 4) & 0x7)
|
||
|
{
|
||
|
case 0x3: printf(" CAS Latency = 3");
|
||
|
break;
|
||
|
case 0x4: printf(" CAS Latency = 4");
|
||
|
break;
|
||
|
case 0x5: printf(" CAS Latency = 5");
|
||
|
break;
|
||
|
case 0x6: printf(" CAS Latency = 6");
|
||
|
break;
|
||
|
default: printf(" unknown CAL ");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
temp = MV_REG_READ(0x1408);
|
||
|
printf(" tRP = %d tRAS = %d tRCD=%d\n",
|
||
|
((temp >> 8) & 0xf) + 1, ((temp >> 16) & 0x10) + (temp & 0xf) + 1, ((temp >> 4) & 0xf) + 1);
|
||
|
}
|
||
|
|
||
|
int dram_init (void)
|
||
|
{
|
||
|
|
||
|
DECLARE_GLOBAL_DATA_PTR;
|
||
|
unsigned int i, dramTotalSize=0;
|
||
|
char name[20];
|
||
|
MV_32 memBase, temp;
|
||
|
|
||
|
mvCtrlModelRevNameGet(name);
|
||
|
printf("\nSoc: %s", name);
|
||
|
|
||
|
printf("CPU running @ %dMhz L2 running @ %dMhz\n", mvCpuPclkGet()/1000000, mvCpuL2ClkGet()/1000000);
|
||
|
#ifdef MV_TCLK_CALC
|
||
|
printf("SysClock = %dMhz , Calc TClock = %dMhz \n\n", CFG_BUS_CLK/1000000, CFG_TCLK/1000000);
|
||
|
#else
|
||
|
printf("SysClock = %dMhz , TClock = %dMhz \n\n", CFG_BUS_CLK/1000000, CFG_TCLK/1000000);
|
||
|
#endif
|
||
|
#if defined(MV_INC_BOARD_DDIM)
|
||
|
/* Call dramInit */
|
||
|
if (0 == (dramTotalSize = initdram(0)))
|
||
|
{
|
||
|
printf("DRAM Initialization Failed\n");
|
||
|
reset_cpu();
|
||
|
return (1);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
mvIntrfaceParamPrint();
|
||
|
|
||
|
for(i = 0; i< MV_DRAM_MAX_CS; i++)
|
||
|
{
|
||
|
#if !defined(MV_88F6082L) && defined(MV_88F6082)
|
||
|
if (mvCtrlModelRevGet() == MV_6082_A0_ID)
|
||
|
{
|
||
|
gd->bd->bi_dram[i].start = (i)?_16M:0;
|
||
|
gd->bd->bi_dram[i].size = _8M;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memBase = mvDramIfBankBaseGet(i);
|
||
|
if (MV_ERROR == memBase)
|
||
|
gd->bd->bi_dram[i].start = 0;
|
||
|
else
|
||
|
gd->bd->bi_dram[i].start = memBase;
|
||
|
|
||
|
gd->bd->bi_dram[i].size = mvDramIfBankSizeGet(i);
|
||
|
}
|
||
|
#else
|
||
|
memBase = mvDramIfBankBaseGet(i);
|
||
|
if (MV_ERROR == memBase)
|
||
|
gd->bd->bi_dram[i].start = 0;
|
||
|
else
|
||
|
gd->bd->bi_dram[i].start = memBase;
|
||
|
|
||
|
gd->bd->bi_dram[i].size = mvDramIfBankSizeGet(i);
|
||
|
#endif
|
||
|
dramTotalSize += gd->bd->bi_dram[i].size;
|
||
|
if (gd->bd->bi_dram[i].size)
|
||
|
{
|
||
|
printf("DRAM CS[%d] base 0x%08x ",i, gd->bd->bi_dram[i].start);
|
||
|
mvSizePrint(gd->bd->bi_dram[i].size);
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("DRAM Total ");
|
||
|
mvSizePrint(dramTotalSize);
|
||
|
mvIntrfaceWidthPrint();
|
||
|
printf("\n");
|
||
|
#ifdef MV_INC_DRAM_MFG_TEST
|
||
|
mvDramMfgTrst();
|
||
|
#endif
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#if defined(MV_INC_BOARD_DDIM)
|
||
|
|
||
|
/* u-boot interface function to SDRAM init - this is where all the
|
||
|
* controlling logic happens */
|
||
|
long int initdram(int board_type)
|
||
|
{
|
||
|
MV_VOIDFUNCPTR pRom;
|
||
|
MV_U32 forcedCl; /* Forced CAS Latency */
|
||
|
MV_U32 totalSize;
|
||
|
char * env;
|
||
|
MV_TWSI_ADDR slave;
|
||
|
|
||
|
/* r0 <- current position of code */
|
||
|
/* test if we run from flash or RAM */
|
||
|
if(dramBoot != 1)
|
||
|
{
|
||
|
slave.type = ADDR7_BIT;
|
||
|
slave.address = 0;
|
||
|
mvTwsiInit(CFG_I2C_SPEED, CFG_TCLK, &slave, 0);
|
||
|
|
||
|
/* Calculating MIN/MAX CAS latency according to user settings */
|
||
|
env = getenv("CASset");
|
||
|
|
||
|
if(env && (strcmp(env,"1.5") == 0))
|
||
|
{
|
||
|
forcedCl = 15;
|
||
|
}
|
||
|
else if(env && (strcmp(env,"2") == 0))
|
||
|
{
|
||
|
forcedCl = 20;
|
||
|
}
|
||
|
else if(env && (strcmp(env,"2.5") == 0))
|
||
|
{
|
||
|
forcedCl = 25;
|
||
|
}
|
||
|
else if(env && (strcmp(env,"3") == 0))
|
||
|
{
|
||
|
forcedCl = 30;
|
||
|
}
|
||
|
else if(env && (strcmp(env,"4") == 0))
|
||
|
{
|
||
|
forcedCl = 40;
|
||
|
}
|
||
|
else if(env && (strcmp(env,"5") == 0))
|
||
|
{
|
||
|
forcedCl = 50;
|
||
|
}
|
||
|
else if(env && (strcmp(env,"6") == 0))
|
||
|
{
|
||
|
forcedCl = 60;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
forcedCl = 0;
|
||
|
}
|
||
|
|
||
|
/* detect the dram configuartion parameters */
|
||
|
if (MV_OK != mvDramIfDetect(forcedCl,1))
|
||
|
{
|
||
|
printf("DRAM Auto Detection Failed! System Halt!\n");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* set the dram configuration */
|
||
|
/* Calculate jump address of _mvDramIfConfig() */
|
||
|
|
||
|
#if defined(MV_BOOTROM)
|
||
|
pRom = (MV_VOIDFUNCPTR)(((MV_VOIDFUNCPTR)_mvDramIfConfig - (MV_VOIDFUNCPTR)_start) +
|
||
|
(MV_VOIDFUNCPTR)CFG_MONITOR_BASE + (MV_VOIDFUNCPTR)MONITOR_HEADER_LEN);
|
||
|
#else
|
||
|
pRom = (MV_VOIDFUNCPTR)(((MV_VOIDFUNCPTR)_mvDramIfConfig - (MV_VOIDFUNCPTR)_start) +
|
||
|
(MV_VOIDFUNCPTR)CFG_MONITOR_BASE);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
(*pRom) (); /* Jump to _mvDramIfConfig*/
|
||
|
}
|
||
|
|
||
|
totalSize = mvDramIfSizeGet();
|
||
|
|
||
|
|
||
|
return(totalSize);
|
||
|
}
|
||
|
|
||
|
#endif /* #if defined(MV_INC_BOARD_DDIM) */
|
||
|
|
||
|
#ifdef MV_INC_DRAM_MFG_TEST
|
||
|
static MV_VOID mvDramMfgTrst(void)
|
||
|
{
|
||
|
|
||
|
/* Memory test */
|
||
|
DECLARE_GLOBAL_DATA_PTR;
|
||
|
unsigned int mem_len,i,j, pattern;
|
||
|
unsigned int *mem_start;
|
||
|
char *env;
|
||
|
|
||
|
env = getenv("enaPost");
|
||
|
if(!env || ( (strcmp(env,"Yes") == 0) || (strcmp(env,"yes") == 0) ) )
|
||
|
{
|
||
|
printf("Memory test pattern: ");
|
||
|
|
||
|
for (j = 0 ; j<2 ; j++)
|
||
|
{
|
||
|
|
||
|
switch(j){
|
||
|
case 0:
|
||
|
pattern=0x55555555;
|
||
|
printf("0x%X, ",pattern);
|
||
|
break;
|
||
|
case 1:
|
||
|
pattern=0xAAAAAAAA;
|
||
|
printf("0x%X, ",pattern);
|
||
|
break;
|
||
|
default:
|
||
|
pattern=0x0;
|
||
|
printf("0x%X, ",pattern);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
for(i = 0; i< MV_DRAM_MAX_CS; i++)
|
||
|
{
|
||
|
mem_start = (unsigned int *)gd->bd->bi_dram[i].start;
|
||
|
mem_len = gd->bd->bi_dram[i].size;
|
||
|
if (i == 0)
|
||
|
{
|
||
|
mem_start+= _4M;
|
||
|
mem_len-= _4M;
|
||
|
}
|
||
|
mem_len/=4;
|
||
|
if (MV_OK != mv_mem_test(mem_start, pattern, mem_len))
|
||
|
{
|
||
|
printf(" Fail!\n");
|
||
|
while(1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
printf(" Pass\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static MV_STATUS mv_mem_test(MV_U32* pMem, MV_U32 pattern, MV_U32 count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i=0 ; i< count ; i+=1)
|
||
|
*(pMem + i) = pattern;
|
||
|
|
||
|
if (MV_OK != mv_mem_cmp(pMem, pattern, count))
|
||
|
{
|
||
|
return MV_ERROR;
|
||
|
}
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
static MV_STATUS mv_mem_cmp(MV_U32* pMem, MV_U32 pattern, MV_U32 count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i=0 ; i< count ; i+=1)
|
||
|
{
|
||
|
if (*(pMem + i) != pattern)
|
||
|
{
|
||
|
printf("Fail\n");
|
||
|
printf("Test failed at 0x%x\n",(pMem + i));
|
||
|
return MV_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
#endif /* MV_INC_DRAM_MFG_TEST */
|