sdram_init.c
来自「适合KS8695X」· C语言 代码 · 共 1,684 行 · 第 1/4 页
C
1,684 行
return 1;
}
/* delay line */
/* Program the GT with the discovered data */
if (info->registeredAddrAndControlInputs == true)
DP (printf
("Module is registered, but we do not support registered Modules !!!\n"));
/* delay line */
set_dfcdlInit (); /* may be its not needed */
DP (printf ("Delay line set done\n"));
/* set SDRAM mode NOP */ /* To_do check it */
GT_REG_WRITE (SDRAM_OPERATION, 0x5);
while (GTREGREAD (SDRAM_OPERATION) != 0) {
DP (printf
("\n*** SDRAM_OPERATION 1418: Module still busy ... please wait... ***\n"));
}
/* SDRAM configuration */
GT_REG_WRITE (SDRAM_CONFIG, 0x58200400);
DP (printf ("sdram_conf 0x1400: %08x\n", GTREGREAD (SDRAM_CONFIG)));
/* SDRAM open pages controll keep open as much as I can */
GT_REG_WRITE (SDRAM_OPEN_PAGES_CONTROL, 0x0);
DP (printf
("sdram_open_pages_controll 0x1414: %08x\n",
GTREGREAD (SDRAM_OPEN_PAGES_CONTROL)));
/* SDRAM D_UNIT_CONTROL_LOW 0x1404 */
tmp = (GTREGREAD (D_UNIT_CONTROL_LOW) & 0x01); /* Clock Domain Sync from power on reset */
if (tmp == 0)
DP (printf ("Core Signals are sync (by HW-Setting)!!!\n"));
else
DP (printf
("Core Signals syncs. are bypassed (by HW-Setting)!!!\n"));
/* SDRAM set CAS Lentency according to SPD information */
switch (info->memoryType) {
case SDRAM:
DP (printf ("### SD-RAM not supported yet !!!\n"));
hang ();
/* ToDo fill SD-RAM if needed !!!!! */
break;
case DDR:
DP (printf ("### SET-CL for DDR-RAM\n"));
switch (info->maxClSupported_DDR) {
case DDR_CL_3:
tmp_dunit_control_low = 0x3c000000; /* Read-Data sampled on falling edge of Clk */
tmp_sdram_mode = 0x32; /* CL=3 Burstlength = 4 */
DP (printf
("Max. CL is 3 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
break;
case DDR_CL_2_5:
if (tmp == 1) { /* clocks sync */
tmp_dunit_control_low = 0x24000000; /* Read-Data sampled on falling edge of Clk */
tmp_sdram_mode = 0x62; /* CL=2,5 Burstlength = 4 */
DP (printf
("Max. CL is 2,5s CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
} else { /* clk sync. bypassed */
tmp_dunit_control_low = 0x03000000; /* Read-Data sampled on rising edge of Clk */
tmp_sdram_mode = 0x62; /* CL=2,5 Burstlength = 4 */
DP (printf
("Max. CL is 2,5 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
}
break;
case DDR_CL_2:
if (tmp == 1) { /* Sync */
tmp_dunit_control_low = 0x03000000; /* Read-Data sampled on rising edge of Clk */
tmp_sdram_mode = 0x22; /* CL=2 Burstlength = 4 */
DP (printf
("Max. CL is 2s CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
} else { /* Not sync. */
tmp_dunit_control_low = 0x3b000000; /* Read-Data sampled on rising edge of Clk */
tmp_sdram_mode = 0x22; /* CL=2 Burstlength = 4 */
DP (printf
("Max. CL is 2 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
}
break;
case DDR_CL_1_5:
if (tmp == 1) { /* Sync */
tmp_dunit_control_low = 0x23000000; /* Read-Data sampled on falling edge of Clk */
tmp_sdram_mode = 0x52; /* CL=1,5 Burstlength = 4 */
DP (printf
("Max. CL is 1,5s CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
} else { /* not sync */
tmp_dunit_control_low = 0x1a000000; /* Read-Data sampled on rising edge of Clk */
tmp_sdram_mode = 0x52; /* CL=1,5 Burstlength = 4 */
DP (printf
("Max. CL is 1,5 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
}
break;
default:
printf ("Max. CL is out of range %d\n",
info->maxClSupported_DDR);
hang ();
break;
}
break;
}
/* Write results of CL detection procedure */
GT_REG_WRITE (SDRAM_MODE, tmp_sdram_mode);
/* set SDRAM mode SetCommand 0x1418 */
GT_REG_WRITE (SDRAM_OPERATION, 0x3);
while (GTREGREAD (SDRAM_OPERATION) != 0) {
DP (printf
("\n*** SDRAM_OPERATION 1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
}
/* SDRAM D_UNIT_CONTROL_LOW 0x1404 */
tmp = (GTREGREAD (D_UNIT_CONTROL_LOW) & 0x01); /* Clock Domain Sync from power on reset */
if (tmp != 1) { /*clocks are not sync */
/* asyncmode */
GT_REG_WRITE (D_UNIT_CONTROL_LOW,
(GTREGREAD (D_UNIT_CONTROL_LOW) & 0x7F) |
0x18110780 | tmp_dunit_control_low);
} else {
/* syncmode */
GT_REG_WRITE (D_UNIT_CONTROL_LOW,
(GTREGREAD (D_UNIT_CONTROL_LOW) & 0x7F) |
0x00110000 | tmp_dunit_control_low);
}
/* set SDRAM mode SetCommand 0x1418 */
GT_REG_WRITE (SDRAM_OPERATION, 0x3);
while (GTREGREAD (SDRAM_OPERATION) != 0) {
DP (printf
("\n*** SDRAM_OPERATION 1418 after D_UNIT_CONTROL_LOW: Module still busy ... please wait... ***\n"));
}
/*------------------------------------------------------------------------------ */
/* bank parameters */
/* SDRAM address decode register */
/* program this with the default value */
tmp = 0x02;
DP (printf ("drb_size (n*64Mbit): %d\n", info->drb_size));
switch (info->drb_size) {
case 1: /* 64 Mbit */
case 2: /* 128 Mbit */
DP (printf ("RAM-Device_size 64Mbit or 128Mbit)\n"));
tmp |= (0x00 << 4);
break;
case 4: /* 256 Mbit */
case 8: /* 512 Mbit */
DP (printf ("RAM-Device_size 256Mbit or 512Mbit)\n"));
tmp |= (0x01 << 4);
break;
case 16: /* 1 Gbit */
case 32: /* 2 Gbit */
DP (printf ("RAM-Device_size 1Gbit or 2Gbit)\n"));
tmp |= (0x02 << 4);
break;
default:
printf ("Error in dram size calculation\n");
DP (printf ("Assume: RAM-Device_size 1Gbit or 2Gbit)\n"));
tmp |= (0x02 << 4);
return 1;
}
/* SDRAM bank parameters */
/* the param registers for slot 1 (banks 2+3) are offset by 0x8 */
DP (printf
("setting up slot %d config with: %08lx \n", info->slot, tmp));
GT_REG_WRITE (SDRAM_ADDR_CONTROL, tmp);
/* ------------------------------------------------------------------------------ */
DP (printf
("setting up sdram_timing_control_low with: %08x \n",
0x11511220));
GT_REG_WRITE (SDRAM_TIMING_CONTROL_LOW, 0x11511220);
/* ------------------------------------------------------------------------------ */
/* SDRAM configuration */
tmp = GTREGREAD (SDRAM_CONFIG);
if (info->registeredAddrAndControlInputs
|| info->registeredDQMBinputs) {
tmp |= (1 << 17);
DP (printf
("SPD says: registered Addr. and Cont.: %d; registered DQMBinputs: %d\n",
info->registeredAddrAndControlInputs,
info->registeredDQMBinputs));
}
/* Use buffer 1 to return read data to the CPU
* Page 426 MV64360 */
tmp |= (1 << 26);
DP (printf
("Before Buffer assignment - sdram_conf: %08x\n",
GTREGREAD (SDRAM_CONFIG)));
DP (printf
("After Buffer assignment - sdram_conf: %08x\n",
GTREGREAD (SDRAM_CONFIG)));
/* SDRAM timing To_do: */
tmp = GTREGREAD (SDRAM_TIMING_CONTROL_HIGH);
DP (printf ("# sdram_timing_control_high is : %08lx \n", tmp));
/* SDRAM address decode register */
/* program this with the default value */
tmp = GTREGREAD (SDRAM_ADDR_CONTROL);
DP (printf
("SDRAM address control (before: decode): %08x ",
GTREGREAD (SDRAM_ADDR_CONTROL)));
GT_REG_WRITE (SDRAM_ADDR_CONTROL, (tmp | 0x2));
DP (printf
("SDRAM address control (after: decode): %08x\n",
GTREGREAD (SDRAM_ADDR_CONTROL)));
/* set the SDRAM configuration for each bank */
/* for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) */
{
i = info->slot;
DP (printf
("\n*** Running a MRS cycle for bank %d ***\n", i));
/* map the bank */
memory_map_bank (i, 0, GB / 4);
#if 1 /* test only */
/* set SDRAM mode */ /* To_do check it */
GT_REG_WRITE (SDRAM_OPERATION, 0x3);
check = GTREGREAD (SDRAM_OPERATION);
DP (printf
("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n",
check));
/* switch back to normal operation mode */
GT_REG_WRITE (SDRAM_OPERATION, 0);
check = GTREGREAD (SDRAM_OPERATION);
DP (printf
("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n",
check));
#endif /* test only */
/* unmap the bank */
memory_map_bank (i, 0, 0);
}
return 0;
}
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'. Some (not all) hardware errors are detected:
* - short between address lines
* - short between data lines
*/
long int
dram_size(long int *base, long int maxsize)
{
volatile long int *addr, *b=base;
long int cnt, val, save1, save2;
#define STARTVAL (1<<20) /* start test at 1M */
for (cnt = STARTVAL/sizeof(long); cnt < maxsize/sizeof(long); cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
save1=*addr; /* save contents of addr */
save2=*b; /* save contents of base */
*addr=cnt; /* write cnt to addr */
*b=0; /* put null at base */
/* check at base address */
if ((*b) != 0) {
*addr=save1; /* restore *addr */
*b=save2; /* restore *b */
return (0);
}
val = *addr; /* read *addr */
val = *addr; /* read *addr */
*addr=save1;
*b=save2;
if (val != cnt) {
DP(printf("Found %08x at Address %08x (failure)\n", (unsigned int)val, (unsigned int) addr));
/* fix boundary condition.. STARTVAL means zero */
if(cnt==STARTVAL/sizeof(long)) cnt=0;
return (cnt * sizeof(long));
}
}
return maxsize;
}
/* ------------------------------------------------------------------------- */
/* ppcboot interface function to SDRAM init - this is where all the
* controlling logic happens */
long int
initdram(int board_type)
{
int s0 = 0, s1 = 0;
int checkbank[4] = { [0 ... 3] = 0 };
ulong bank_no, realsize, total, check;
AUX_MEM_DIMM_INFO dimmInfo1;
AUX_MEM_DIMM_INFO dimmInfo2;
int nhr;
/* first, use the SPD to get info about the SDRAM/ DDRRAM */
/* check the NHR bit and skip mem init if it's already done */
nhr = get_hid0() & (1 << 16);
if (nhr) {
printf("Skipping SD- DDRRAM setup due to NHR bit being set\n");
} else {
/* DIMM0 */
s0 = check_dimm(0, &dimmInfo1);
/* DIMM1 */
s1 = check_dimm(1, &dimmInfo2);
memory_map_bank(0, 0, 0);
memory_map_bank(1, 0, 0);
memory_map_bank(2, 0, 0);
memory_map_bank(3, 0, 0);
if (dimmInfo1.numOfModuleBanks && setup_sdram(&dimmInfo1)) {
printf("Setup for DIMM1 failed.\n");
}
if (dimmInfo2.numOfModuleBanks && setup_sdram(&dimmInfo2)) {
printf("Setup for DIMM2 failed.\n");
}
/* set the NHR bit */
set_hid0(get_hid0() | (1 << 16));
}
/* next, size the SDRAM banks */
realsize = total = 0;
check = GB/4;
if (dimmInfo1.numOfModuleBanks > 0) {checkbank[0] = 1; printf("-- DIMM1 has 1 bank\n");}
if (dimmInfo1.numOfModuleBanks > 1) {checkbank[1] = 1; printf("-- DIMM1 has 2 banks\n");}
if (dimmInfo1.numOfModuleBanks > 2)
printf("Error, SPD claims DIMM1 has >2 banks\n");
if (dimmInfo2.numOfModuleBanks > 0) {checkbank[2] = 1; printf("-- DIMM2 has 1 bank\n");}
if (dimmInfo2.numOfModuleBanks > 1) {checkbank[3] = 1; printf("-- DIMM2 has 2 banks\n");}
if (dimmInfo2.numOfModuleBanks > 2)
printf("Error, SPD claims DIMM2 has >2 banks\n");
for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
/* skip over banks that are not populated */
if (! checkbank[bank_no])
continue;
if ((total + check) > CFG_GT_REGS)
check = CFG_GT_REGS - total;
memory_map_bank(bank_no, total, check);
realsize = dram_size((long int *)total, check);
memory_map_bank(bank_no, total, realsize);
total += realsize;
}
/* Setup Ethernet DMA Adress window to DRAM Area */
return(total);
}
/* ***************************************************************************************
! * SDRAM INIT *
! * This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb *
! * This procedure fits only the Atlantis *
! * *
! *************************************************************************************** */
/* ***************************************************************************************
! * DFCDL initialize MV643xx Design Considerations *
! * *
! *************************************************************************************** */
int set_dfcdlInit (void)
{
int i;
unsigned int dfcdl_word = 0x0000014f;
for (i = 0; i < 64; i++) {
GT_REG_WRITE (SRAM_DATA0, dfcdl_word);
}
GT_REG_WRITE (DFCDL_CONFIG0, 0x00300000); /* enable dynamic delay line updating */
return (0);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?