sdram_init.c
来自「适合KS8695X」· C语言 代码 · 共 1,974 行 · 第 1/5 页
C
1,974 行
/* calculating the sdram density */
for (i = 0;
i < dimmInfo->numOfRowAddresses + dimmInfo->numOfColAddresses;
i++) {
density = density * 2;
}
dimmInfo->deviceDensity = density * dimmInfo->numOfBanksOnEachDevice *
dimmInfo->sdramWidth;
dimmInfo->numberOfDevices =
(dimmInfo->dataWidth / dimmInfo->sdramWidth) *
dimmInfo->numOfModuleBanks;
devicesForErrCheck =
(dimmInfo->dataWidth - 64) / dimmInfo->sdramWidth;
if ((dimmInfo->errorCheckType == 0x1)
|| (dimmInfo->errorCheckType == 0x2)
|| (dimmInfo->errorCheckType == 0x3)) {
dimmInfo->size =
(dimmInfo->deviceDensity / 8) *
(dimmInfo->numberOfDevices -
/* ronen on the 1G dimm we get wrong value. (was devicesForErrCheck) */
dimmInfo->numberOfDevices / 8);
} else {
dimmInfo->size =
(dimmInfo->deviceDensity / 8) *
dimmInfo->numberOfDevices;
}
/* compute the module DRB size */
tmp = (1 <<
(dimmInfo->numOfRowAddresses + dimmInfo->numOfColAddresses));
tmp *= dimmInfo->numOfModuleBanks;
tmp *= dimmInfo->sdramWidth;
tmp = tmp >> 24; /* div by 0x4000000 (64M) */
dimmInfo->drb_size = (uchar) tmp;
DP (printf ("Module DRB size (n*64Mbit): %d\n", dimmInfo->drb_size));
/* try a CAS latency of 3 first... */
/* bit 1 is CL2, bit 2 is CL3 */
supp_cal = (dimmInfo->suportedCasLatencies & 0x6) >> 1;
cal_val = 0;
if (supp_cal & 3) {
if (NS10to10PS (data[9]) <= tmemclk)
cal_val = 3;
}
/* then 2... */
if (supp_cal & 2) {
if (NS10to10PS (data[23]) <= tmemclk)
cal_val = 2;
}
DP (printf ("cal_val = %d\n", cal_val));
/* bummer, did't work... */
if (cal_val == 0) {
DP (printf ("Couldn't find a good CAS latency\n"));
hang ();
return 0;
}
return true;
#endif
}
/* sets up the GT properly with information passed in */
int setup_sdram (AUX_MEM_DIMM_INFO * info)
{
ulong tmp, check;
ulong tmp_sdram_mode = 0; /* 0x141c */
ulong tmp_dunit_control_low = 0; /* 0x1404 */
int i;
/* added 8/21/2003 P. Marchese */
unsigned int sdram_config_reg;
/* added 10/10/2003 P. Marchese */
ulong sdram_chip_size;
/* sanity checking */
if (!info->numOfModuleBanks) {
printf ("setup_sdram called with 0 banks\n");
return 1;
}
/* 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 */
/* added 8/21/2003 P. Marchese */
/* code allows usage of registered DIMMS */
/* figure out the memory refresh internal */
switch (info->RefreshInterval) {
case 0x0:
case 0x80: /* refresh period is 15.625 usec */
sdram_config_reg =
(unsigned int) (((float) 15.625 * (float) CFG_BUS_HZ)
/ (float) 1000000.0);
break;
case 0x1:
case 0x81: /* refresh period is 3.9 usec */
sdram_config_reg =
(unsigned int) (((float) 3.9 * (float) CFG_BUS_HZ) /
(float) 1000000.0);
break;
case 0x2:
case 0x82: /* refresh period is 7.8 usec */
sdram_config_reg =
(unsigned int) (((float) 7.8 * (float) CFG_BUS_HZ) /
(float) 1000000.0);
break;
case 0x3:
case 0x83: /* refresh period is 31.3 usec */
sdram_config_reg =
(unsigned int) (((float) 31.3 * (float) CFG_BUS_HZ) /
(float) 1000000.0);
break;
case 0x4:
case 0x84: /* refresh period is 62.5 usec */
sdram_config_reg =
(unsigned int) (((float) 62.5 * (float) CFG_BUS_HZ) /
(float) 1000000.0);
break;
case 0x5:
case 0x85: /* refresh period is 125 usec */
sdram_config_reg =
(unsigned int) (((float) 125 * (float) CFG_BUS_HZ) /
(float) 1000000.0);
break;
default: /* refresh period undefined */
printf ("DRAM refresh period is unknown!\n");
printf ("Aborting DRAM setup with an error\n");
hang ();
break;
}
DP (printf ("calculated refresh interval %0x\n", sdram_config_reg));
/* make sure the refresh value is only 14 bits */
if (sdram_config_reg > 0x1fff)
sdram_config_reg = 0x1fff;
DP (printf ("adjusted refresh interval %0x\n", sdram_config_reg));
/* we want physical bank interleaving and */
/* virtual bank interleaving enabled so do nothing */
/* since these bits need to be zero to enable the interleaving */
/* registered DRAM ? */
if (info->registeredAddrAndControlInputs == 1) {
/* it's registered DRAM, so set the reg. DRAM bit */
sdram_config_reg = sdram_config_reg | BIT17;
DP (printf ("Enabling registered DRAM bit\n"));
}
/* turn on DRAM ECC? */
#ifdef CONFIG_MV64460_ECC
if (info->errorCheckType == 0x2) {
/* DRAM has ECC, so turn it on */
sdram_config_reg = sdram_config_reg | BIT18;
DP (printf ("Enabling ECC\n"));
}
#endif
/* set the data DQS pin configuration */
switch (info->sdramWidth) {
case 0x4: /* memory is x4 */
sdram_config_reg = sdram_config_reg | BIT20 | BIT21;
DP (printf ("Data DQS pins set for 16 pins\n"));
break;
case 0x8: /* memory is x8 or x16 */
case 0x10:
sdram_config_reg = sdram_config_reg | BIT21;
DP (printf ("Data DQS pins set for 8 pins\n"));
break;
case 0x20: /* memory is x32 */
/* both bits are cleared for x32 so nothing to do */
DP (printf ("Data DQS pins set for 2 pins\n"));
break;
default: /* memory width unsupported */
printf ("DRAM chip width is unknown!\n");
printf ("Aborting DRAM setup with an error\n");
hang ();
break;
}
/*ronen db64460 */
/* perform read buffer assignments */
/* we are going to use the Power-up defaults */
/* bit 27 = PCI bus #0 = buffer 0 */
/* bit 28 = PCI bus #1 = buffer 0 */
/* bit 29 = MPSC = buffer 0 */
/* bit 30 = IDMA = buffer 0 */
/* bit 31 = Gigabit = buffer 0 */
sdram_config_reg = sdram_config_reg | 0x58000000;
sdram_config_reg = sdram_config_reg & 0xffffff00;
/* bit 14 FBSplit = FCRAM controller bsplit enable. */
/* bit 15 vw = FCRAM Variable write length enable. */
/* bit 16 DType = Dram Type (0 = FCRAM,1 = Standard) */
sdram_config_reg = sdram_config_reg | BIT14 | BIT15;
/* write the value into the SDRAM configuration register */
GT_REG_WRITE (SDRAM_CONFIG, sdram_config_reg);
DP (printf ("sdram_conf 0x1400: %08x\n", GTREGREAD (SDRAM_CONFIG)));
/* SDRAM open pages control 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 Latency according to SPD information */
switch (info->memoryType) {
case SDRAM:
printf ("### SD-RAM not supported !!!\n");
printf ("Aborting!!!\n");
hang ();
/* ToDo fill SD-RAM if needed !!!!! */
break;
/* Calculate the settings for SDRAM mode and Dunit control low registers */
/* Values set according to technical bulletin TB-92 rev. c */
case DDR:
DP (printf ("### SET-CL for DDR-RAM\n"));
/* ronen db64460 - change the tmp_dunit_control_low setting!!! */
switch (info->maxClSupported_DDR) {
case DDR_CL_3:
tmp_sdram_mode = 0x32; /* CL=3 Burstlength = 4 */
if (tmp == 1) { /* clocks sync */
if (info->registeredAddrAndControlInputs == 1) /* registerd DDR SDRAM? */
tmp_dunit_control_low = 0x05110051;
else
tmp_dunit_control_low = 0x24110051;
DP (printf
("Max. CL is 3 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
printf ("Warnning: DRAM ClkSync was never tested(db64460)!!!!!\n");
} else { /* clk sync. bypassed */
if (info->registeredAddrAndControlInputs == 1) /* registerd DDR SDRAM? */
tmp_dunit_control_low = 0xC5000540;
else
tmp_dunit_control_low = 0xC4000540;
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:
tmp_sdram_mode = 0x62; /* CL=2.5 Burstlength = 4 */
if (tmp == 1) { /* clocks sync */
if (info->registeredAddrAndControlInputs == 1) /* registerd DDR SDRAM? */
tmp_dunit_control_low = 0x25110051;
else
tmp_dunit_control_low = 0x24110051;
DP (printf
("Max. CL is 2.5 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
printf ("Warnning: DRAM ClkSync was never tested(db64460)!!!!!\n");
} else { /* clk sync. bypassed */
if (info->registeredAddrAndControlInputs == 1) { /* registerd DDR SDRAM? */
tmp_dunit_control_low = 0xC5000540;
/* printf("CL = 2.5, Clock Unsync'ed, Dunit Control Low register setting undefined\n");1 */
/* printf("Aborting!!!\n");1 */
/* hang();1 */
} else
tmp_dunit_control_low = 0xC4000540;
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:
tmp_sdram_mode = 0x22; /* CL=2 Burstlength = 4 */
if (tmp == 1) { /* clocks sync */
if (info->registeredAddrAndControlInputs == 1) /* registerd DDR SDRAM? */
tmp_dunit_control_low = 0x04110051;
else
tmp_dunit_control_low = 0x03110051;
DP (printf
("Max. CL is 2 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
printf ("Warnning: DRAM ClkSync was never tested(db64460)!!!!!\n");
} else { /* clk sync. bypassed */
if (info->registeredAddrAndControlInputs == 1) { /* registerd DDR SDRAM? */
/*printf("CL = 2, Clock Unsync'ed, Dunit Control Low register setting undefined\n");1 */
/*printf("Aborting!!!\n");1 */
/*hang();1 */
tmp_dunit_control_low = 0xC4000540;
} else
tmp_dunit_control_low = 0xC3000540;;
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:
tmp_sdram_mode = 0x52; /* CL=1.5 Burstlength = 4 */
if (tmp == 1) { /* clocks sync */
if (info->registeredAddrAndControlInputs == 1) /* registerd DDR SDRAM? */
tmp_dunit_control_low = 0x24110051;
else
tmp_dunit_control_low = 0x23110051;
DP (printf
("Max. CL is 1.5 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
tmp_sdram_mode, tmp_dunit_control_low));
printf ("Warnning: DRAM ClkSync was never tested(db64460)!!!!!\n");
} else { /* clk sync. bypassed */
if (info->registeredAddrAndControlInputs == 1) { /* registerd DDR SDRAM? */
/*printf("CL = 1.5, Clock Unsync'ed, Dunit Control Low register setting undefined\n");1 */
/*printf("Aborting!!!\n");1 */
/*hang();1 */
tmp_dunit_control_low = 0xC4000540;
} else
tmp_dunit_control_low = 0xC3000540;
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;
} /* end DDR switch */
break;
} /* end CL switch */
/* Write results of CL detection procedure */
/* set SDRAM mode reg. 0x141c */
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 0x1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
}
/* SDRAM D_UNIT_CONTROL_LOW 0x1404 */
GT_REG_WRITE (D_UNIT_CONTROL_LOW, 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 0x1410 */
/* program this with the default value */
tmp = 0x02; /* power-up default address select decoding value */
DP (printf ("drb_size (n*64Mbit): %d\n", info->drb_size));
/* figure out the DRAM chip size */
sdram_chip_size =
(1 << (info->numOfRowAddresses + info->numOfColAddresses));
sdram_chip_size *= info->sdramWidth;
sdram_chip_size *= 4;
DP (printf ("computed sdram chip size is %#lx\n", sdram_chip_size));
/* divide sdram chip size by 64 Mbits */
sdram_chip_size = sdram_chip_size / 0x4000000;
switch (sdram_chip_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 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?