blob: f51cf7070a01f4515e50ed5f2f056d4856aab4e5 [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 "ddr2_3/mvDramIf.h"
#include "mvOs.h"
#include "mvBoardEnvLib.h"
#include "ddr2_3/mvDramIfRegs.h"
#include "mvCpuIfRegs.h"
#include "cpu/mvCpu.h"
#include "xor/mvXor.h"
#include "sys/mvCpuIf.h"
#ifdef DEBUG
#define DB(x) x
#else
#define DB(x)
#endif
extern void _start(void);
extern void reset_cpu(ulong addr);
extern int dramBoot;
MV_U32 mvDramIfHwSizeGetFromWindows(MV_VOID);
#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 mvDramScrubbing(void);
MV_VOID mvIntrfaceWidthPrint(MV_VOID)
{
printf(" 16bit width");
}
MV_VOID mvIntrfaceParamPrint(MV_VOID)
{
MV_U32 temp;
printf("DRAM");
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);
}
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
gd->ram_size = (phys_size_t)mvDramIfHwSizeGetFromWindows();
#ifdef MV_INC_DRAM_MFG_TEST
mvDramMfgTrst();
#endif
#if defined(MV88F78X60) && !defined(CONFIG_MACH_AVANTA_LP_FPGA)
mvDramScrubbing();
#endif
return 0;
}
/*******************************************************************************
* mvDramIfHwSizeGetFromWindows - Get DRAM size from windows configuration
*
* DESCRIPTION:
* Get DRAM size from windows configuration
* Currently reading only Fast Path windows
*
*******************************************************************************/
MV_U32 mvDramIfHwSizeGetFromWindows(MV_VOID)
{
#if !defined(CONFIG_MACH_AVANTA_LP_FPGA)
MV_U32 base = 0;
MV_U32 size, cs, totalSize = 0, sizeRegVal;
for (cs = 0; cs < SDRAM_MAX_CS; cs++) {
size = MV_REG_READ(SDRAM_WIN_CTRL_REG(cs));
if (size & SDRAMWCR_ENABLE) {
size = size & SDRAMWCR_SIZE_MASK;
if ((size > 0) && (base < SDRAM_MAX_ADDR)) {
size |= ~(SDRAMWCR_SIZE_MASK);
/* Check if out of max window size and resize the window */
if (base + size > SDRAM_MAX_ADDR)
size = SDRAM_MAX_ADDR - base - 1;
base += (size + 1);
totalSize += size;
}
}
}
/* Dram size alignment fix */
sizeRegVal = (totalSize & SDRAMWCR_SIZE_MASK) >> SDRAMWCR_SIZE_OFFS; /* sizeregVal = ( amount of 16mb chunks -1 ) */
totalSize = (sizeRegVal + 1) * SDRAMWCR_SIZE_ALLIGNMENT; /* size = alined size (num of 16mb chunks * 16mb) */
/* Dram size alignment fix*/
return totalSize;
#else
return CONFIG_SYS_FPGA_DRAM_SIZE;
#endif
}
void dram_init_banksize(void)
{
int cs;
/* Set all CS as one bank to pass to Linux */
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_dram[0].size = gd->ram_size;
for (cs = 1; cs < CONFIG_NR_DRAM_BANKS; cs++) {
gd->bd->bi_dram[cs].start = 0;
gd->bd->bi_dram[cs].size = 0;
}
for (cs = 0; cs < CONFIG_NR_DRAM_BANKS; cs++) {
MV_U64 memBase64 = 0;
MV_CPU_DEC_WIN addrDecWin;
if ((mvCpuIfTargetWinGet(SDRAM_CS0 + cs, &addrDecWin) == MV_OK) &&
(addrDecWin.enable == MV_TRUE)) {
/* Now, get the full DRAM config for LPAE. */
/* For LPAE, we want to read the DRAM CS sizes from the CPU address decode windows, in order to get the
** complete size of the DRAM (And not only the part visible to UBoot).
*/
memBase64 = (MV_U64)(addrDecWin.addrWin.baseLow |
(MV_U64)((MV_U64)addrDecWin.addrWin.baseHigh << 32));
gd->dram_hw_info[cs].start = memBase64;
gd->dram_hw_info[cs].size = (MV_U64)addrDecWin.addrWin.size;
}
}
}
#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(0, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_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)CONFIG_SYS_MONITOR_BASE + (MV_VOIDFUNCPTR)MONITOR_HEADER_LEN);
#else
pRom = (MV_VOIDFUNCPTR)(((MV_VOIDFUNCPTR)_mvDramIfConfig - (MV_VOIDFUNCPTR)_start) +
(MV_VOIDFUNCPTR)CONFIG_SYS_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 */