⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 44x_spd_ddr2.c

📁 u-boot1.3德国DENX小组开发的用于多种嵌入式CPU的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
	unsigned long sdram_freq;	unsigned long sdr_ddrpll;	unsigned long val;	/*------------------------------------------------------------------	 * Get the board configuration info.	 *-----------------------------------------------------------------*/	get_sys_info(&board_cfg);	/*------------------------------------------------------------------	 * Set the SDRAM Refresh Timing Register, SDRAM_RTR	 *-----------------------------------------------------------------*/	mfsdr(SDR0_DDR0, sdr_ddrpll);	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));	max_refresh_rate = 0;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] != SDRAM_NONE) {			refresh_rate_type = spd_read(iic0_dimm_addr[dimm_num], 12);			refresh_rate_type &= 0x7F;			switch (refresh_rate_type) {			case 0:				refresh_rate =  15625;				break;			case 1:				refresh_rate =   3906;				break;			case 2:				refresh_rate =   7812;				break;			case 3:				refresh_rate =  31250;				break;			case 4:				refresh_rate =  62500;				break;			case 5:				refresh_rate = 125000;				break;			default:				refresh_rate = 0;				printf("ERROR: DIMM %d unsupported refresh rate/type.\n",				       (unsigned int)dimm_num);				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			}			max_refresh_rate = max(max_refresh_rate, refresh_rate);		}	}	rint = MULDIV64(sdram_freq, max_refresh_rate, ONE_BILLION);	mfsdram(SDRAM_RTR, val);	mtsdram(SDRAM_RTR, (val & ~SDRAM_RTR_RINT_MASK) |		(SDRAM_RTR_RINT_ENCODE(rint)));}/*------------------------------------------------------------------ * This routine programs the SDRAM_TRx registers. *-----------------------------------------------------------------*/static void program_tr(unsigned long *dimm_populated,		       unsigned char *iic0_dimm_addr,		       unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long sdram_ddr1;	unsigned long t_rp_ns;	unsigned long t_rcd_ns;	unsigned long t_rrd_ns;	unsigned long t_ras_ns;	unsigned long t_rc_ns;	unsigned long t_rfc_ns;	unsigned long t_wpc_ns;	unsigned long t_wtr_ns;	unsigned long t_rpc_ns;	unsigned long t_rp_clk;	unsigned long t_rcd_clk;	unsigned long t_rrd_clk;	unsigned long t_ras_clk;	unsigned long t_rc_clk;	unsigned long t_rfc_clk;	unsigned long t_wpc_clk;	unsigned long t_wtr_clk;	unsigned long t_rpc_clk;	unsigned long sdtr1, sdtr2, sdtr3;	unsigned long ddr_check;	unsigned long sdram_freq;	unsigned long sdr_ddrpll;	PPC440_SYS_INFO board_cfg;	/*------------------------------------------------------------------	 * Get the board configuration info.	 *-----------------------------------------------------------------*/	get_sys_info(&board_cfg);	mfsdr(SDR0_DDR0, sdr_ddrpll);	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));	/*------------------------------------------------------------------	 * Handle the timing.  We need to find the worst case timing of all	 * the dimm modules installed.	 *-----------------------------------------------------------------*/	t_rp_ns = 0;	t_rrd_ns = 0;	t_rcd_ns = 0;	t_ras_ns = 0;	t_rc_ns = 0;	t_rfc_ns = 0;	t_wpc_ns = 0;	t_wtr_ns = 0;	t_rpc_ns = 0;	sdram_ddr1 = TRUE;	/* loop through all the DIMM slots on the board */	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		/* If a dimm is installed in a particular slot ... */		if (dimm_populated[dimm_num] != SDRAM_NONE) {			if (dimm_populated[dimm_num] == SDRAM_DDR2)				sdram_ddr1 = TRUE;			else				sdram_ddr1 = FALSE;			t_rcd_ns = max(t_rcd_ns, spd_read(iic0_dimm_addr[dimm_num], 29) >> 2);			t_rrd_ns = max(t_rrd_ns, spd_read(iic0_dimm_addr[dimm_num], 28) >> 2);			t_rp_ns  = max(t_rp_ns,  spd_read(iic0_dimm_addr[dimm_num], 27) >> 2);			t_ras_ns = max(t_ras_ns, spd_read(iic0_dimm_addr[dimm_num], 30));			t_rc_ns  = max(t_rc_ns,  spd_read(iic0_dimm_addr[dimm_num], 41));			t_rfc_ns = max(t_rfc_ns, spd_read(iic0_dimm_addr[dimm_num], 42));		}	}	/*------------------------------------------------------------------	 * Set the SDRAM Timing Reg 1, SDRAM_TR1	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_SDTR1, sdtr1);	sdtr1 &= ~(SDRAM_SDTR1_LDOF_MASK | SDRAM_SDTR1_RTW_MASK |		   SDRAM_SDTR1_WTWO_MASK | SDRAM_SDTR1_RTRO_MASK);	/* default values */	sdtr1 |= SDRAM_SDTR1_LDOF_2_CLK;	sdtr1 |= SDRAM_SDTR1_RTW_2_CLK;	/* normal operations */	sdtr1 |= SDRAM_SDTR1_WTWO_0_CLK;	sdtr1 |= SDRAM_SDTR1_RTRO_1_CLK;	mtsdram(SDRAM_SDTR1, sdtr1);	/*------------------------------------------------------------------	 * Set the SDRAM Timing Reg 2, SDRAM_TR2	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_SDTR2, sdtr2);	sdtr2 &= ~(SDRAM_SDTR2_RCD_MASK  | SDRAM_SDTR2_WTR_MASK |		   SDRAM_SDTR2_XSNR_MASK | SDRAM_SDTR2_WPC_MASK |		   SDRAM_SDTR2_RPC_MASK  | SDRAM_SDTR2_RP_MASK  |		   SDRAM_SDTR2_RRD_MASK);	/*	 * convert t_rcd from nanoseconds to ddr clocks	 * round up if necessary	 */	t_rcd_clk = MULDIV64(sdram_freq, t_rcd_ns, ONE_BILLION);	ddr_check = MULDIV64(ONE_BILLION, t_rcd_clk, t_rcd_ns);	if (sdram_freq != ddr_check)		t_rcd_clk++;	switch (t_rcd_clk) {	case 0:	case 1:		sdtr2 |= SDRAM_SDTR2_RCD_1_CLK;		break;	case 2:		sdtr2 |= SDRAM_SDTR2_RCD_2_CLK;		break;	case 3:		sdtr2 |= SDRAM_SDTR2_RCD_3_CLK;		break;	case 4:		sdtr2 |= SDRAM_SDTR2_RCD_4_CLK;		break;	default:		sdtr2 |= SDRAM_SDTR2_RCD_5_CLK;		break;	}	if (sdram_ddr1 == TRUE) { /* DDR1 */		if (sdram_freq < 200000000) {			sdtr2 |= SDRAM_SDTR2_WTR_1_CLK;			sdtr2 |= SDRAM_SDTR2_WPC_2_CLK;			sdtr2 |= SDRAM_SDTR2_RPC_2_CLK;		} else {			sdtr2 |= SDRAM_SDTR2_WTR_2_CLK;			sdtr2 |= SDRAM_SDTR2_WPC_3_CLK;			sdtr2 |= SDRAM_SDTR2_RPC_2_CLK;		}	} else { /* DDR2 */		/* loop through all the DIMM slots on the board */		for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {			/* If a dimm is installed in a particular slot ... */			if (dimm_populated[dimm_num] != SDRAM_NONE) {				t_wpc_ns = max(t_wtr_ns, spd_read(iic0_dimm_addr[dimm_num], 36) >> 2);				t_wtr_ns = max(t_wtr_ns, spd_read(iic0_dimm_addr[dimm_num], 37) >> 2);				t_rpc_ns = max(t_rpc_ns, spd_read(iic0_dimm_addr[dimm_num], 38) >> 2);			}		}		/*		 * convert from nanoseconds to ddr clocks		 * round up if necessary		 */		t_wpc_clk = MULDIV64(sdram_freq, t_wpc_ns, ONE_BILLION);		ddr_check = MULDIV64(ONE_BILLION, t_wpc_clk, t_wpc_ns);		if (sdram_freq != ddr_check)			t_wpc_clk++;		switch (t_wpc_clk) {		case 0:		case 1:		case 2:			sdtr2 |= SDRAM_SDTR2_WPC_2_CLK;			break;		case 3:			sdtr2 |= SDRAM_SDTR2_WPC_3_CLK;			break;		case 4:			sdtr2 |= SDRAM_SDTR2_WPC_4_CLK;			break;		case 5:			sdtr2 |= SDRAM_SDTR2_WPC_5_CLK;			break;		default:			sdtr2 |= SDRAM_SDTR2_WPC_6_CLK;			break;		}		/*		 * convert from nanoseconds to ddr clocks		 * round up if necessary		 */		t_wtr_clk = MULDIV64(sdram_freq, t_wtr_ns, ONE_BILLION);		ddr_check = MULDIV64(ONE_BILLION, t_wtr_clk, t_wtr_ns);		if (sdram_freq != ddr_check)			t_wtr_clk++;		switch (t_wtr_clk) {		case 0:		case 1:			sdtr2 |= SDRAM_SDTR2_WTR_1_CLK;			break;		case 2:			sdtr2 |= SDRAM_SDTR2_WTR_2_CLK;			break;		case 3:			sdtr2 |= SDRAM_SDTR2_WTR_3_CLK;			break;		default:			sdtr2 |= SDRAM_SDTR2_WTR_4_CLK;			break;		}		/*		 * convert from nanoseconds to ddr clocks		 * round up if necessary		 */		t_rpc_clk = MULDIV64(sdram_freq, t_rpc_ns, ONE_BILLION);		ddr_check = MULDIV64(ONE_BILLION, t_rpc_clk, t_rpc_ns);		if (sdram_freq != ddr_check)			t_rpc_clk++;		switch (t_rpc_clk) {		case 0:		case 1:		case 2:			sdtr2 |= SDRAM_SDTR2_RPC_2_CLK;			break;		case 3:			sdtr2 |= SDRAM_SDTR2_RPC_3_CLK;			break;		default:			sdtr2 |= SDRAM_SDTR2_RPC_4_CLK;			break;		}	}	/* default value */	sdtr2 |= SDRAM_SDTR2_XSNR_16_CLK;	/*	 * convert t_rrd from nanoseconds to ddr clocks	 * round up if necessary	 */	t_rrd_clk = MULDIV64(sdram_freq, t_rrd_ns, ONE_BILLION);	ddr_check = MULDIV64(ONE_BILLION, t_rrd_clk, t_rrd_ns);	if (sdram_freq != ddr_check)		t_rrd_clk++;	if (t_rrd_clk == 3)		sdtr2 |= SDRAM_SDTR2_RRD_3_CLK;	else		sdtr2 |= SDRAM_SDTR2_RRD_2_CLK;	/*	 * convert t_rp from nanoseconds to ddr clocks	 * round up if necessary	 */	t_rp_clk = MULDIV64(sdram_freq, t_rp_ns, ONE_BILLION);	ddr_check = MULDIV64(ONE_BILLION, t_rp_clk, t_rp_ns);	if (sdram_freq != ddr_check)		t_rp_clk++;	switch (t_rp_clk) {	case 0:	case 1:	case 2:	case 3:		sdtr2 |= SDRAM_SDTR2_RP_3_CLK;		break;	case 4:		sdtr2 |= SDRAM_SDTR2_RP_4_CLK;		break;	case 5:		sdtr2 |= SDRAM_SDTR2_RP_5_CLK;		break;	case 6:		sdtr2 |= SDRAM_SDTR2_RP_6_CLK;		break;	default:		sdtr2 |= SDRAM_SDTR2_RP_7_CLK;		break;	}	mtsdram(SDRAM_SDTR2, sdtr2);	/*------------------------------------------------------------------	 * Set the SDRAM Timing Reg 3, SDRAM_TR3	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_SDTR3, sdtr3);	sdtr3 &= ~(SDRAM_SDTR3_RAS_MASK  | SDRAM_SDTR3_RC_MASK |		   SDRAM_SDTR3_XCS_MASK | SDRAM_SDTR3_RFC_MASK);	/*	 * convert t_ras from nanoseconds to ddr clocks	 * round up if necessary	 */	t_ras_clk = MULDIV64(sdram_freq, t_ras_ns, ONE_BILLION);	ddr_check = MULDIV64(ONE_BILLION, t_ras_clk, t_ras_ns);	if (sdram_freq != ddr_check)		t_ras_clk++;	sdtr3 |= SDRAM_SDTR3_RAS_ENCODE(t_ras_clk);	/*	 * convert t_rc from nanoseconds to ddr clocks	 * round up if necessary	 */	t_rc_clk = MULDIV64(sdram_freq, t_rc_ns, ONE_BILLION);	ddr_check = MULDIV64(ONE_BILLION, t_rc_clk, t_rc_ns);	if (sdram_freq != ddr_check)		t_rc_clk++;	sdtr3 |= SDRAM_SDTR3_RC_ENCODE(t_rc_clk);	/* default xcs value */	sdtr3 |= SDRAM_SDTR3_XCS;	/*	 * convert t_rfc from nanoseconds to ddr clocks	 * round up if necessary	 */	t_rfc_clk = MULDIV64(sdram_freq, t_rfc_ns, ONE_BILLION);	ddr_check = MULDIV64(ONE_BILLION, t_rfc_clk, t_rfc_ns);	if (sdram_freq != ddr_check)		t_rfc_clk++;	sdtr3 |= SDRAM_SDTR3_RFC_ENCODE(t_rfc_clk);	mtsdram(SDRAM_SDTR3, sdtr3);}/*-----------------------------------------------------------------------------+ * program_bxcf. *-----------------------------------------------------------------------------*/static void program_bxcf(unsigned long *dimm_populated,			 unsigned char *iic0_dimm_addr,			 unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long num_col_addr;	unsigned long num_ranks;	unsigned long num_banks;	unsigned long mode;	unsigned long ind_rank;	unsigned long ind;	unsigned long ind_bank;	unsigned long bank_0_populated;	/*------------------------------------------------------------------	 * Set the BxCF regs.  First, wipe out the bank config registers.	 *-----------------------------------------------------------------*/	mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF);	mtdcr(SDRAMC_CFGDATA, 0x00000000);	mtdcr(SDRAMC_CFGADDR, SDRAM_MB1CF);	mtdcr(SDRAMC_CFGDATA, 0x00000000);	mtdcr(SDRAMC_CFGADDR, SDRAM_MB2CF);	mtdcr(SDRAMC_CFGDATA, 0x00000000);	mtdcr(SDRAMC_CFGADDR, SDRAM_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -