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

📄 44x_spd_ddr.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 3 页
字号:
			if ((attributes & 0x02) != 0x00) {				cfg0 |= SDRAM_CFG0_RDEN;			}			/*			 * program DDR SDRAM Data Width			 */			data_width =				(unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) +				(((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8);			if (data_width == 64 || data_width == 72) {				dimm_64bit = TRUE;				cfg0 |= SDRAM_CFG0_DMWD_64;			} else if (data_width == 32 || data_width == 40) {				dimm_32bit = TRUE;				cfg0 |= SDRAM_CFG0_DMWD_32;			} else {				printf("WARNING: DIMM with datawidth of %lu bits.\n",				       data_width);				printf("Only DIMMs with 32 or 64 bit datawidths supported.\n");				spd_ddr_init_hang ();			}			break;		}	}	/*	 * program Memory Data Error Checking	 */	if (ecc_enabled == TRUE) {		cfg0 |= SDRAM_CFG0_MCHK_GEN;	} else {		cfg0 |= SDRAM_CFG0_MCHK_NON;	}	/*	 * program Page Management Unit (0 == enabled)	 */	cfg0 &= ~SDRAM_CFG0_PMUD;	/*	 * program Memory Controller Options 0	 * Note: DCEN must be enabled after all DDR SDRAM controller	 * configuration registers get initialized.	 */	mtsdram(mem_cfg0, cfg0);}static void program_cfg1(unsigned long *dimm_populated,			 unsigned char *iic0_dimm_addr,			 unsigned long num_dimm_banks){	unsigned long cfg1;	mfsdram(mem_cfg1, cfg1);	/*	 * Self-refresh exit, disable PM	 */	cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN);	/*	 * program Memory Controller Options 1	 */	mtsdram(mem_cfg1, cfg1);}static void program_rtr(unsigned long *dimm_populated,			unsigned char *iic0_dimm_addr,			unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long bus_period_x_10;	unsigned long refresh_rate = 0;	unsigned char refresh_rate_type;	unsigned long refresh_interval;	unsigned long sdram_rtr;	PPC4xx_SYS_INFO sys_info;	/*	 * get the board info	 */	get_sys_info(&sys_info);	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);	for (dimm_num = 0;  dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] == TRUE) {			refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12);			switch (refresh_rate_type) {			case 0x00:				refresh_rate = 15625;				break;			case 0x01:				refresh_rate = 15625/4;				break;			case 0x02:				refresh_rate = 15625/2;				break;			case 0x03:				refresh_rate = 15626*2;				break;			case 0x04:				refresh_rate = 15625*4;				break;			case 0x05:				refresh_rate = 15625*8;				break;			default:				printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n",				       dimm_num);				printf("Replace the DIMM module with a supported DIMM.\n");				break;			}			break;		}	}	refresh_interval = refresh_rate * 10 / bus_period_x_10;	sdram_rtr = (refresh_interval & 0x3ff8) <<  16;	/*	 * program Refresh Timer Register (SDRAM0_RTR)	 */	mtsdram(mem_rtr, sdram_rtr);}static void program_tr0(unsigned long *dimm_populated,			 unsigned char *iic0_dimm_addr,			 unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long tr0;	unsigned char wcsbc;	unsigned char t_rp_ns;	unsigned char t_rcd_ns;	unsigned char t_ras_ns;	unsigned long t_rp_clk;	unsigned long t_ras_rcd_clk;	unsigned long t_rcd_clk;	unsigned long t_rfc_clk;	unsigned long plb_check;	unsigned char cas_bit;	unsigned long cas_index;	unsigned char cas_2_0_available;	unsigned char cas_2_5_available;	unsigned char cas_3_0_available;	unsigned long cycle_time_ns_x_10[3];	unsigned long tcyc_3_0_ns_x_10;	unsigned long tcyc_2_5_ns_x_10;	unsigned long tcyc_2_0_ns_x_10;	unsigned long tcyc_reg;	unsigned long bus_period_x_10;	PPC4xx_SYS_INFO sys_info;	unsigned long residue;	/*	 * get the board info	 */	get_sys_info(&sys_info);	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);	/*	 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits	 */	mfsdram(mem_tr0, tr0);	tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK |		 SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK |		 SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK |		 SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK);	/*	 * initialization	 */	wcsbc = 0;	t_rp_ns = 0;	t_rcd_ns = 0;	t_ras_ns = 0;	cas_2_0_available = TRUE;	cas_2_5_available = TRUE;	cas_3_0_available = TRUE;	tcyc_2_0_ns_x_10 = 0;	tcyc_2_5_ns_x_10 = 0;	tcyc_3_0_ns_x_10 = 0;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] == TRUE) {			wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15);			t_rp_ns	 = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2;			t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2;			t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30);			cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);			for (cas_index = 0; cas_index < 3; cas_index++) {				switch (cas_index) {				case 0:					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);					break;				case 1:					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23);					break;				default:					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25);					break;				}				if ((tcyc_reg & 0x0F) >= 10) {					printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n",					       dimm_num);					spd_ddr_init_hang ();				}				cycle_time_ns_x_10[cas_index] =					(((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F);			}			cas_index = 0;			if ((cas_bit & 0x80) != 0) {				cas_index += 3;			} else if ((cas_bit & 0x40) != 0) {				cas_index += 2;			} else if ((cas_bit & 0x20) != 0) {				cas_index += 1;			}			if (((cas_bit & 0x10) != 0) && (cas_index < 3)) {				tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index];				cas_index++;			} else {				if (cas_index != 0) {					cas_index++;				}				cas_3_0_available = FALSE;			}			if (((cas_bit & 0x08) != 0) || (cas_index < 3)) {				tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index];				cas_index++;			} else {				if (cas_index != 0) {					cas_index++;				}				cas_2_5_available = FALSE;			}			if (((cas_bit & 0x04) != 0) || (cas_index < 3)) {				tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index];				cas_index++;			} else {				if (cas_index != 0) {					cas_index++;				}				cas_2_0_available = FALSE;			}			break;		}	}	/*	 * Program SD_WR and SD_WCSBC fields	 */	tr0 |= SDRAM_TR0_SDWR_2_CLK;		    /* Write Recovery: 2 CLK */	switch (wcsbc) {	case 0:		tr0 |= SDRAM_TR0_SDWD_0_CLK;		break;	default:		tr0 |= SDRAM_TR0_SDWD_1_CLK;		break;	}	/*	 * Program SD_CASL field	 */	if ((cas_2_0_available == TRUE) &&	    (bus_period_x_10 >= tcyc_2_0_ns_x_10)) {		tr0 |= SDRAM_TR0_SDCL_2_0_CLK;	} else if ((cas_2_5_available == TRUE) &&		 (bus_period_x_10 >= tcyc_2_5_ns_x_10)) {		tr0 |= SDRAM_TR0_SDCL_2_5_CLK;	} else if ((cas_3_0_available == TRUE) &&		 (bus_period_x_10 >= tcyc_3_0_ns_x_10)) {		tr0 |= SDRAM_TR0_SDCL_3_0_CLK;	} else {		printf("ERROR: No supported CAS latency with the installed DIMMs.\n");		printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");		printf("Make sure the PLB speed is within the supported range.\n");		spd_ddr_init_hang ();	}	/*	 * Calculate Trp in clock cycles and round up if necessary	 * Program SD_PTA field	 */	t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION;	plb_check = ONE_BILLION * t_rp_clk / t_rp_ns;	if (sys_info.freqPLB != plb_check) {		t_rp_clk++;	}	switch ((unsigned long)t_rp_clk) {	case 0:	case 1:	case 2:		tr0 |= SDRAM_TR0_SDPA_2_CLK;		break;	case 3:		tr0 |= SDRAM_TR0_SDPA_3_CLK;		break;	default:		tr0 |= SDRAM_TR0_SDPA_4_CLK;		break;	}	/*	 * Program SD_CTP field	 */	t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION;	plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns);	if (sys_info.freqPLB != plb_check) {		t_ras_rcd_clk++;	}	switch (t_ras_rcd_clk) {	case 0:	case 1:	case 2:		tr0 |= SDRAM_TR0_SDCP_2_CLK;		break;	case 3:		tr0 |= SDRAM_TR0_SDCP_3_CLK;		break;	case 4:		tr0 |= SDRAM_TR0_SDCP_4_CLK;		break;	default:		tr0 |= SDRAM_TR0_SDCP_5_CLK;		break;	}	/*	 * Program SD_LDF field	 */	tr0 |= SDRAM_TR0_SDLD_2_CLK;	/*	 * Program SD_RFTA field	 * FIXME tRFC hardcoded as 75 nanoseconds	 */	t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75);	residue = sys_info.freqPLB % (ONE_BILLION / 75);	if (residue >= (ONE_BILLION / 150)) {		t_rfc_clk++;	}	switch (t_rfc_clk) {	case 0:	case 1:	case 2:	case 3:	case 4:	case 5:	case 6:		tr0 |= SDRAM_TR0_SDRA_6_CLK;		break;	case 7:		tr0 |= SDRAM_TR0_SDRA_7_CLK;		break;	case 8:		tr0 |= SDRAM_TR0_SDRA_8_CLK;		break;	case 9:		tr0 |= SDRAM_TR0_SDRA_9_CLK;		break;	case 10:		tr0 |= SDRAM_TR0_SDRA_10_CLK;		break;	case 11:		tr0 |= SDRAM_TR0_SDRA_11_CLK;		break;	case 12:		tr0 |= SDRAM_TR0_SDRA_12_CLK;		break;	default:		tr0 |= SDRAM_TR0_SDRA_13_CLK;		break;	}	/*	 * Program SD_RCD field	 */	t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION;	plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns;	if (sys_info.freqPLB != plb_check) {		t_rcd_clk++;	}	switch (t_rcd_clk) {	case 0:	case 1:	case 2:		tr0 |= SDRAM_TR0_SDRD_2_CLK;		break;	case 3:		tr0 |= SDRAM_TR0_SDRD_3_CLK;		break;	default:		tr0 |= SDRAM_TR0_SDRD_4_CLK;		break;	}	debug("tr0: %x\n", tr0);	mtsdram(mem_tr0, tr0);}static int short_mem_test(void){	unsigned long i, j;	unsigned long bxcr_num;	unsigned long *membase;	const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {

⌨️ 快捷键说明

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