sdram_init.c
来自「适合KS8695X」· C语言 代码 · 共 1,974 行 · 第 1/5 页
C
1,974 行
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");
printf ("RAM-Device_size is unsupported\n");
hang ();
}
/* SDRAM address control */
GT_REG_WRITE (SDRAM_ADDR_CONTROL, tmp);
DP (printf
("setting up sdram address control (0x1410) with: %08lx \n",
tmp));
/* ------------------------------------------------------------------------------ */
/* same settings for registerd & non-registerd DDR SDRAM */
DP (printf
("setting up sdram_timing_control_low (0x1408) with: %08x \n",
0x01501220));
/*ronen db64460 */
GT_REG_WRITE (SDRAM_TIMING_CONTROL_LOW, 0x01501220);
/* ------------------------------------------------------------------------------ */
/* 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 MV6indent: Standard input:1464: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: Standard input:1465: Warning:old style assignment ambiguity in "=*". Assuming "= *"
4460 */
tmp |= (1 << 26);
DP (printf
("Before Buffer assignment - sdram_conf (0x1400): %08x\n",
GTREGREAD (SDRAM_CONFIG)));
DP (printf
("After Buffer assignment - sdram_conf (0x1400): %08x\n",
GTREGREAD (SDRAM_CONFIG)));
/* SDRAM timing To_do: */
/* ------------------------------------------------------------------------------ */
/* ronen db64460 */
DP (printf
("setting up sdram_timing_control_high (0x140c) with: %08x \n",
0xc));
GT_REG_WRITE (SDRAM_TIMING_CONTROL_HIGH, 0xc);
DP (printf
("setting up sdram address pads control (0x14c0) with: %08x \n",
0x7d5014a));
GT_REG_WRITE (SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x7d5014a);
DP (printf
("setting up sdram data pads control (0x14c4) with: %08x \n",
0x7d5014a));
GT_REG_WRITE (SDRAM_DATA_PADS_CALIBRATION, 0x7d5014a);
/* ------------------------------------------------------------------------------ */
/* 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);
/* 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));
/* 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 realsize, total, check;
AUX_MEM_DIMM_INFO dimmInfo1;
AUX_MEM_DIMM_INFO dimmInfo2;
int nhr, bank_no;
ulong dest, memSpaceAttr;
/* 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);
/* ronen check correct set of DIMMS */
if (dimmInfo1.numOfModuleBanks && dimmInfo2.numOfModuleBanks) {
if (dimmInfo1.errorCheckType !=
dimmInfo2.errorCheckType)
printf ("***WARNNING***!!!! different ECC support of the DIMMS\n");
if (dimmInfo1.maxClSupported_DDR !=
dimmInfo2.maxClSupported_DDR)
printf ("***WARNNING***!!!! different CAL setting of the DIMMS\n");
if (dimmInfo1.registeredAddrAndControlInputs !=
dimmInfo2.registeredAddrAndControlInputs)
printf ("***WARNNING***!!!! different Registration setting of the DIMMS\n");
}
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;
}
if (dimmInfo1.numOfModuleBanks > 1) {
checkbank[1] = 1;
}
if (dimmInfo1.numOfModuleBanks > 2)
printf ("Error, SPD claims DIMM1 has >2 banks\n");
printf ("-- DIMM1 has %d banks\n", dimmInfo1.numOfModuleBanks);
if (dimmInfo2.numOfModuleBanks > 0) {
checkbank[2] = 1;
}
if (dimmInfo2.numOfModuleBanks > 1) {
checkbank[3] = 1;
}
if (dimmInfo2.numOfModuleBanks > 2)
printf ("Error, SPD claims DIMM2 has >2 banks\n");
printf ("-- DIMM2 has %d banks\n", dimmInfo2.numOfModuleBanks);
for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
/* skip over banks that are not populated */
if (!checkbank[bank_no])
continue;
/* ronen - realsize = dram_size((long int *)total, check); */
if (bank_no == 0 || bank_no == 1) {
if (checkbank[1] == 1)
realsize = dimmInfo1.size / 2;
else
realsize = dimmInfo1.size;
}
if (bank_no == 2 || bank_no == 3) {
if (checkbank[3] == 1)
realsize = dimmInfo2.size / 2;
else
realsize = dimmInfo2.size;
}
memory_map_bank (bank_no, total, realsize);
/* ronen - initialize the DRAM for ECC */
#ifdef CONFIG_MV64460_ECC
if ((dimmInfo1.errorCheckType != 0) &&
((dimmInfo2.errorCheckType != 0)
|| (dimmInfo2.numOfModuleBanks == 0))) {
printf ("ECC Initialization of Bank %d:", bank_no);
memSpaceAttr = ((~(BIT0 << bank_no)) & 0xf) << 8;
mvDmaSetMemorySpace (0, 0, memSpaceAttr, total,
realsize);
for (dest = total; dest < total + realsize;
dest += _8M) {
mvDmaTransfer (0, total, dest, _8M,
BIT8 /*DMA_DTL_128BYTES */ |
BIT3 /*DMA_HOLD_SOURCE_ADDR */
|
BIT11
/*DMA_BLOCK_TRANSFER_MODE */ );
while (mvDmaIsChannelActive (0));
}
printf (" PASS\n");
}
#endif
total += realsize;
}
/* ronen */
switch ((GTREGREAD (0x141c) >> 4) & 0x7) {
case 0x2:
printf ("CAS Latency = 2");
break;
case 0x3:
printf ("CAS Latency = 3");
break;
case 0x5:
printf ("CAS Latency = 1.5");
break;
case 0x6:
printf ("CAS Latency = 2.5");
break;
}
printf (" tRP = %d tRAS = %d tRCD=%d\n",
((GTREGREAD (0x1408) >> 8) & 0xf) + 1,
((GTREGREAD (0x1408) >> 20) & 0xf) + 1,
((GTREGREAD (0x1408) >> 4) & 0xf) + 1);
/* Setup Ethernet DMA Adress window to DRAM Area */
if (total > _256M)
printf ("*** ONLY the first 256MB DRAM memory are used out of the ");
else
printf ("Total SDRAM memory is ");
/* (cause all the 4 BATS are taken) */
return (total);
}
/* ronen- add Idma functions for usage of the ecc dram init. */
/*******************************************************************************
* mvDmaIsChannelActive - Checks if a engine is busy.
********************************************************************************/
int mvDmaIsChannelActive (int engine)
{
ulong data;
data = GTREGREAD (MV64460_DMA_CHANNEL0_CONTROL + 4 * engine);
if (data & BIT14 /*activity status */ ) {
return 1;
}
return 0;
}
/*******************************************************************************
* mvDmaSetMemorySpace - Set a DMA memory window for the DMA's address decoding
* map.
*******************************************************************************/
int mvDmaSetMemorySpace (ulong memSpace,
ulong memSpaceTarget,
ulong memSpaceAttr, ulong baseAddress, ulong size)
{
ulong temp;
/* The base address must be aligned to the size. */
if (baseAddress % size != 0) {
return 0;
}
if (size >= 0x10000 /*64K */ ) {
size &= 0xffff0000;
baseAddress = (baseAddress & 0xffff0000);
/* Set the new attributes */
GT_REG_WRITE (MV64460_DMA_BASE_ADDR_REG0 + memSpace * 8,
(baseAddress | memSpaceTarget | memSpaceAttr));
GT_REG_WRITE ((MV64460_DMA_SIZE_REG0 + memSpace * 8),
(size - 1) & 0xffff0000);
temp = GTREGREAD (MV64460_DMA_BASE_ADDR_ENABLE_REG);
GT_REG_WRITE (DMA_BASE_ADDR_ENABLE_REG,
(temp & ~(BIT0 << memSpace)));
return 1;
}
return 0;
}
/*******************************************************************************
* mvDmaTransfer - Transfer data from sourceAddr to destAddr on one of the 4
* DMA channels.
********************************************************************************/
int mvDmaTransfer (int engine, ulong sourceAddr,
ulong destAddr, ulong numOfBytes, ulong command)
{
ulong engOffReg = 0; /* Engine Offset Register */
if (numOfBytes > 0xffff) {
command = command | BIT31 /*DMA_16M_DESCRIPTOR_MODE */ ;
}
command = command | ((command >> 6) & 0x7);
engOffReg = engine * 4;
GT_REG_WRITE (MV64460_DMA_CHANNEL0_BYTE_COUNT + engOffReg,
numOfBytes);
GT_REG_WRITE (MV64460_DMA_CHANNEL0_SOURCE_ADDR + engOffReg,
sourceAddr);
GT_REG_WRITE (MV64460_DMA_CHANNEL0_DESTINATION_ADDR + engOffReg,
destAddr);
command =
command | BIT12 /*DMA_CHANNEL_ENABLE */ | BIT9
/*DMA_NON_CHAIN_MODE */ ;
/* Activate DMA engine By writting to mvDmaControlRegister */
GT_REG_WRITE (MV64460_DMA_CHANNEL0_CONTROL + engOffReg, command);
return 1;
}
/****************************************************************************************
* SDRAM INIT *
* This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb *
* This procedure fits only the Atlantis *
* *
*****************************
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?