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 + -
显示快捷键?