|
|
|
@ -33,343 +33,9 @@ |
|
|
|
|
#include <asm/io.h> |
|
|
|
|
#include <ppc440.h> |
|
|
|
|
|
|
|
|
|
#include "sdram.h" |
|
|
|
|
extern int denali_wait_for_dlllock(void); |
|
|
|
|
extern void denali_core_search_data_eye(void); |
|
|
|
|
|
|
|
|
|
#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) || \ |
|
|
|
|
defined(CONFIG_DDR_DATA_EYE) |
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
|
|
|
* wait_for_dlllock. |
|
|
|
|
+----------------------------------------------------------------------------*/ |
|
|
|
|
static int wait_for_dlllock(void) |
|
|
|
|
{ |
|
|
|
|
unsigned long val; |
|
|
|
|
int wait = 0; |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Wait for the DCC master delay line to finish calibration |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_17); |
|
|
|
|
val = DDR0_17_DLLLOCKREG_UNLOCKED; |
|
|
|
|
|
|
|
|
|
while (wait != 0xffff) { |
|
|
|
|
val = mfdcr(ddrcfgd); |
|
|
|
|
if ((val & DDR0_17_DLLLOCKREG_MASK) == DDR0_17_DLLLOCKREG_LOCKED) |
|
|
|
|
/* dlllockreg bit on */ |
|
|
|
|
return 0; |
|
|
|
|
else |
|
|
|
|
wait++; |
|
|
|
|
} |
|
|
|
|
debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val); |
|
|
|
|
debug("Waiting for dlllockreg bit to raise\n"); |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_DDR_DATA_EYE) |
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
|
|
|
* wait_for_dram_init_complete. |
|
|
|
|
+----------------------------------------------------------------------------*/ |
|
|
|
|
int wait_for_dram_init_complete(void) |
|
|
|
|
{ |
|
|
|
|
unsigned long val; |
|
|
|
|
int wait = 0; |
|
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------+
|
|
|
|
|
* Wait for 'DRAM initialization complete' bit in status register |
|
|
|
|
* -------------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_00); |
|
|
|
|
|
|
|
|
|
while (wait != 0xffff) { |
|
|
|
|
val = mfdcr(ddrcfgd); |
|
|
|
|
if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6) |
|
|
|
|
/* 'DRAM initialization complete' bit */ |
|
|
|
|
return 0; |
|
|
|
|
else |
|
|
|
|
wait++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug("DRAM initialization complete bit in status register did not rise\n"); |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define NUM_TRIES 64 |
|
|
|
|
#define NUM_READS 10 |
|
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
|
|
|
* denali_core_search_data_eye. |
|
|
|
|
+----------------------------------------------------------------------------*/ |
|
|
|
|
void denali_core_search_data_eye(unsigned long memory_size) |
|
|
|
|
{ |
|
|
|
|
int k, j; |
|
|
|
|
u32 val; |
|
|
|
|
u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X; |
|
|
|
|
u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0; |
|
|
|
|
u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0; |
|
|
|
|
u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0; |
|
|
|
|
volatile u32 *ram_pointer; |
|
|
|
|
u32 test[NUM_TRIES] = { |
|
|
|
|
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, |
|
|
|
|
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, |
|
|
|
|
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, |
|
|
|
|
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, |
|
|
|
|
0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, |
|
|
|
|
0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, |
|
|
|
|
0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, |
|
|
|
|
0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, |
|
|
|
|
0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, |
|
|
|
|
0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, |
|
|
|
|
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, |
|
|
|
|
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, |
|
|
|
|
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, |
|
|
|
|
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, |
|
|
|
|
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, |
|
|
|
|
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 }; |
|
|
|
|
|
|
|
|
|
ram_pointer = (volatile u32 *)(CFG_SDRAM_BASE); |
|
|
|
|
|
|
|
|
|
for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) { |
|
|
|
|
/*for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) {*/ |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* De-assert 'start' parameter. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_02); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF; |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Set 'wr_dqs_shift' |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_09); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
|
|
|
|
| DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Set 'dqs_out_shift' = wr_dqs_shift + 32 |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
dqs_out_shift = wr_dqs_shift + 32; |
|
|
|
|
mtdcr(ddrcfga, DDR0_22); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
|
|
|
|
| DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
passing_cases = 0; |
|
|
|
|
|
|
|
|
|
for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64; dll_dqs_delay_X++) { |
|
|
|
|
/*for (dll_dqs_delay_X=1; dll_dqs_delay_X<128; dll_dqs_delay_X++) {*/ |
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Set 'dll_dqs_delay_X'. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
/* dll_dqs_delay_0 */ |
|
|
|
|
mtdcr(ddrcfga, DDR0_17); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK) |
|
|
|
|
| DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
/* dll_dqs_delay_1 to dll_dqs_delay_4 */ |
|
|
|
|
mtdcr(ddrcfga, DDR0_18); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
/* dll_dqs_delay_5 to dll_dqs_delay_8 */ |
|
|
|
|
mtdcr(ddrcfga, DDR0_19); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
ppcMsync(); |
|
|
|
|
ppcMbar(); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Assert 'start' parameter. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_02); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON; |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
ppcMsync(); |
|
|
|
|
ppcMbar(); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Wait for the DCC master delay line to finish calibration |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
if (wait_for_dlllock() != 0) { |
|
|
|
|
printf("dlllock did not occur !!!\n"); |
|
|
|
|
printf("denali_core_search_data_eye!!!\n"); |
|
|
|
|
printf("wr_dqs_shift = %d - dll_dqs_delay_X = %d\n", |
|
|
|
|
wr_dqs_shift, dll_dqs_delay_X); |
|
|
|
|
hang(); |
|
|
|
|
} |
|
|
|
|
ppcMsync(); |
|
|
|
|
ppcMbar(); |
|
|
|
|
|
|
|
|
|
if (wait_for_dram_init_complete() != 0) { |
|
|
|
|
printf("dram init complete did not occur !!!\n"); |
|
|
|
|
printf("denali_core_search_data_eye!!!\n"); |
|
|
|
|
printf("wr_dqs_shift = %d - dll_dqs_delay_X = %d\n", |
|
|
|
|
wr_dqs_shift, dll_dqs_delay_X); |
|
|
|
|
hang(); |
|
|
|
|
} |
|
|
|
|
udelay(100); /* wait 100us to ensure init is really completed !!! */ |
|
|
|
|
|
|
|
|
|
/* write values */ |
|
|
|
|
for (j=0; j<NUM_TRIES; j++) { |
|
|
|
|
ram_pointer[j] = test[j]; |
|
|
|
|
|
|
|
|
|
/* clear any cache at ram location */ |
|
|
|
|
__asm__("dcbf 0,%0": :"r" (&ram_pointer[j])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read values back */ |
|
|
|
|
for (j=0; j<NUM_TRIES; j++) { |
|
|
|
|
for (k=0; k<NUM_READS; k++) { |
|
|
|
|
/* clear any cache at ram location */ |
|
|
|
|
__asm__("dcbf 0,%0": :"r" (&ram_pointer[j])); |
|
|
|
|
|
|
|
|
|
if (ram_pointer[j] != test[j]) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read error */ |
|
|
|
|
if (k != NUM_READS) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* See if the dll_dqs_delay_X value passed.*/ |
|
|
|
|
if (j < NUM_TRIES) { |
|
|
|
|
/* Failed */ |
|
|
|
|
passing_cases = 0; |
|
|
|
|
/* break; */ |
|
|
|
|
} else { |
|
|
|
|
/* Passed */ |
|
|
|
|
if (passing_cases == 0) |
|
|
|
|
dll_dqs_delay_X_sw_val = dll_dqs_delay_X; |
|
|
|
|
passing_cases++; |
|
|
|
|
if (passing_cases >= max_passing_cases) { |
|
|
|
|
max_passing_cases = passing_cases; |
|
|
|
|
wr_dqs_shift_with_max_passing_cases = wr_dqs_shift; |
|
|
|
|
dll_dqs_delay_X_start_window = dll_dqs_delay_X_sw_val; |
|
|
|
|
dll_dqs_delay_X_end_window = dll_dqs_delay_X; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* De-assert 'start' parameter. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_02); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF; |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
} /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */ |
|
|
|
|
|
|
|
|
|
} /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */ |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Largest passing window is now detected. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
|
|
|
|
|
/* Compute dll_dqs_delay_X value */ |
|
|
|
|
dll_dqs_delay_X = (dll_dqs_delay_X_end_window + dll_dqs_delay_X_start_window) / 2; |
|
|
|
|
wr_dqs_shift = wr_dqs_shift_with_max_passing_cases; |
|
|
|
|
|
|
|
|
|
debug("DQS calibration - Window detected:\n"); |
|
|
|
|
debug("max_passing_cases = %d\n", max_passing_cases); |
|
|
|
|
debug("wr_dqs_shift = %d\n", wr_dqs_shift); |
|
|
|
|
debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X); |
|
|
|
|
debug("dll_dqs_delay_X window = %d - %d\n", |
|
|
|
|
dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* De-assert 'start' parameter. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_02); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF; |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Set 'wr_dqs_shift' |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_09); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
|
|
|
|
| DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
debug("DDR0_09=0x%08lx\n", val); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Set 'dqs_out_shift' = wr_dqs_shift + 32 |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
dqs_out_shift = wr_dqs_shift + 32; |
|
|
|
|
mtdcr(ddrcfga, DDR0_22); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
|
|
|
|
| DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
debug("DDR0_22=0x%08lx\n", val); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Set 'dll_dqs_delay_X'. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
/* dll_dqs_delay_0 */ |
|
|
|
|
mtdcr(ddrcfga, DDR0_17); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK) |
|
|
|
|
| DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
debug("DDR0_17=0x%08lx\n", val); |
|
|
|
|
|
|
|
|
|
/* dll_dqs_delay_1 to dll_dqs_delay_4 */ |
|
|
|
|
mtdcr(ddrcfga, DDR0_18); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
debug("DDR0_18=0x%08lx\n", val); |
|
|
|
|
|
|
|
|
|
/* dll_dqs_delay_5 to dll_dqs_delay_8 */ |
|
|
|
|
mtdcr(ddrcfga, DDR0_19); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X) |
|
|
|
|
| DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X); |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
debug("DDR0_19=0x%08lx\n", val); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Assert 'start' parameter. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
mtdcr(ddrcfga, DDR0_02); |
|
|
|
|
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON; |
|
|
|
|
mtdcr(ddrcfgd, val); |
|
|
|
|
|
|
|
|
|
ppcMsync(); |
|
|
|
|
ppcMbar(); |
|
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Wait for the DCC master delay line to finish calibration |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
if (wait_for_dlllock() != 0) { |
|
|
|
|
printf("dlllock did not occur !!!\n"); |
|
|
|
|
hang(); |
|
|
|
|
} |
|
|
|
|
ppcMsync(); |
|
|
|
|
ppcMbar(); |
|
|
|
|
|
|
|
|
|
if (wait_for_dram_init_complete() != 0) { |
|
|
|
|
printf("dram init complete did not occur !!!\n"); |
|
|
|
|
hang(); |
|
|
|
|
} |
|
|
|
|
udelay(100); /* wait 100us to ensure init is really completed !!! */ |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_DDR_DATA_EYE */ |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_NAND_SPL) |
|
|
|
|
/* Using cpu/ppc4xx/speed.c to calculate the bus frequency is too big
|
|
|
|
@ -428,14 +94,14 @@ long int initdram (int board_type) |
|
|
|
|
mtsdram(DDR0_44, 0x00000003); |
|
|
|
|
mtsdram(DDR0_02, 0x00000001); |
|
|
|
|
|
|
|
|
|
wait_for_dlllock(); |
|
|
|
|
denali_wait_for_dlllock(); |
|
|
|
|
#endif /* #ifndef CONFIG_NAND_U_BOOT */ |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_DDR_DATA_EYE |
|
|
|
|
/* -----------------------------------------------------------+
|
|
|
|
|
* Perform data eye search if requested. |
|
|
|
|
* ----------------------------------------------------------*/ |
|
|
|
|
denali_core_search_data_eye(CFG_MBYTES_SDRAM << 20); |
|
|
|
|
denali_core_search_data_eye(); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return (CFG_MBYTES_SDRAM << 20); |
|
|
|
|