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