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

📄 44x_spd_ddr2.c

📁 u-boot1.3德国DENX小组开发的用于多种嵌入式CPU的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * Make sure I2C controller is initialized	 * before continuing.	 */	/* switch to correct I2C bus */	I2C_SET_BUS(CFG_SPD_BUS_NUM);	i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);	/*------------------------------------------------------------------	 * Clear out the serial presence detect buffers.	 * Perform IIC reads from the dimm.  Fill in the spds.	 * Check to see if the dimm slots are populated	 *-----------------------------------------------------------------*/	get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Check the memory type for the dimms plugged.	 *-----------------------------------------------------------------*/	check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Check the frequency supported for the dimms plugged.	 *-----------------------------------------------------------------*/	check_frequency(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Check the total rank number.	 *-----------------------------------------------------------------*/	check_rank_number(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Check the voltage type for the dimms plugged.	 *-----------------------------------------------------------------*/	check_voltage_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Program SDRAM controller options 2 register	 * Except Enabling of the memory controller.	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_MCOPT2, val);	mtsdram(SDRAM_MCOPT2,		(val &		 ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_PMEN_MASK |		   SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_XSRP_MASK |		   SDRAM_MCOPT2_ISIE_MASK))		| (SDRAM_MCOPT2_SREN_ENTER | SDRAM_MCOPT2_PMEN_DISABLE |		   SDRAM_MCOPT2_IPTR_IDLE | SDRAM_MCOPT2_XSRP_ALLOW |		   SDRAM_MCOPT2_ISIE_ENABLE));	/*------------------------------------------------------------------	 * Program SDRAM controller options 1 register	 * Note: Does not enable the memory controller.	 *-----------------------------------------------------------------*/	program_copt1(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Set the SDRAM Controller On Die Termination Register	 *-----------------------------------------------------------------*/	program_codt(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Program SDRAM refresh register.	 *-----------------------------------------------------------------*/	program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Program SDRAM mode register.	 *-----------------------------------------------------------------*/	program_mode(dimm_populated, iic0_dimm_addr, num_dimm_banks,		     &selected_cas, &write_recovery);	/*------------------------------------------------------------------	 * Set the SDRAM Write Data/DM/DQS Clock Timing Reg	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_WRDTR, val);	mtsdram(SDRAM_WRDTR, (val & ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) |		ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV));	/*------------------------------------------------------------------	 * Set the SDRAM Clock Timing Register	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_CLKTR, val);	mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) |		ddr_clktr(SDRAM_CLKTR_CLKP_0_DEG));	/*------------------------------------------------------------------	 * Program the BxCF registers.	 *-----------------------------------------------------------------*/	program_bxcf(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Program SDRAM timing registers.	 *-----------------------------------------------------------------*/	program_tr(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Set the Extended Mode register	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_MEMODE, val);	mtsdram(SDRAM_MEMODE,		(val & ~(SDRAM_MEMODE_DIC_MASK  | SDRAM_MEMODE_DLL_MASK |			 SDRAM_MEMODE_RTT_MASK | SDRAM_MEMODE_DQS_MASK)) |		(SDRAM_MEMODE_DIC_NORMAL | SDRAM_MEMODE_DLL_ENABLE		 | SDRAM_MEMODE_RTT_150OHM | SDRAM_MEMODE_DQS_ENABLE));	/*------------------------------------------------------------------	 * Program Initialization preload registers.	 *-----------------------------------------------------------------*/	program_initplr(dimm_populated, iic0_dimm_addr, num_dimm_banks,			selected_cas, write_recovery);	/*------------------------------------------------------------------	 * Delay to ensure 200usec have elapsed since reset.	 *-----------------------------------------------------------------*/	udelay(400);	/*------------------------------------------------------------------	 * Set the memory queue core base addr.	 *-----------------------------------------------------------------*/	program_memory_queue(dimm_populated, iic0_dimm_addr, num_dimm_banks);	/*------------------------------------------------------------------	 * Program SDRAM controller options 2 register	 * Enable the memory controller.	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_MCOPT2, val);	mtsdram(SDRAM_MCOPT2,		(val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_DCEN_MASK |			 SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_ISIE_MASK)) |		(SDRAM_MCOPT2_DCEN_ENABLE | SDRAM_MCOPT2_IPTR_EXECUTE));	/*------------------------------------------------------------------	 * Wait for SDRAM_CFG0_DC_EN to complete.	 *-----------------------------------------------------------------*/	do {		mfsdram(SDRAM_MCSTAT, val);	} while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP);	/* get installed memory size */	dram_size = sdram_memsize();	/* and program tlb entries for this size (dynamic) */	/*	 * Program TLB entries with caches enabled, for best performace	 * while auto-calibrating and ECC generation	 */	program_tlb(0, 0, dram_size, 0);	/*------------------------------------------------------------------	 * DQS calibration.	 *-----------------------------------------------------------------*/	program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks);#ifdef CONFIG_DDR_ECC	/*------------------------------------------------------------------	 * If ecc is enabled, initialize the parity bits.	 *-----------------------------------------------------------------*/	program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, 0);#endif	/*	 * Now after initialization (auto-calibration and ECC generation)	 * remove the TLB entries with caches enabled and program again with	 * desired cache functionality	 */	remove_tlb(0, dram_size);	program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE);	ppc440sp_sdram_register_dump();	return dram_size;}static void get_spd_info(unsigned long *dimm_populated,			 unsigned char *iic0_dimm_addr,			 unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long dimm_found;	unsigned char num_of_bytes;	unsigned char total_size;	dimm_found = FALSE;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		num_of_bytes = 0;		total_size = 0;		num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);		debug("\nspd_read(0x%x) returned %d\n",		      iic0_dimm_addr[dimm_num], num_of_bytes);		total_size = spd_read(iic0_dimm_addr[dimm_num], 1);		debug("spd_read(0x%x) returned %d\n",		      iic0_dimm_addr[dimm_num], total_size);		if ((num_of_bytes != 0) && (total_size != 0)) {			dimm_populated[dimm_num] = TRUE;			dimm_found = TRUE;			debug("DIMM slot %lu: populated\n", dimm_num);		} else {			dimm_populated[dimm_num] = FALSE;			debug("DIMM slot %lu: Not populated\n", dimm_num);		}	}	if (dimm_found == FALSE) {		printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");		spd_ddr_init_hang ();	}}void board_add_ram_info(int use_default){	PPC440_SYS_INFO board_cfg;	u32 val;	if (is_ecc_enabled())		puts(" (ECC");	else		puts(" (ECC not");	get_sys_info(&board_cfg);	mfsdr(SDR0_DDR0, val);	val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);	printf(" enabled, %d MHz", (val * 2) / 1000000);	mfsdram(SDRAM_MMODE, val);	val = (val & SDRAM_MMODE_DCL_MASK) >> 4;	printf(", CL%d)", val);}/*------------------------------------------------------------------ * For the memory DIMMs installed, this routine verifies that they * really are DDR specific DIMMs. *-----------------------------------------------------------------*/static void check_mem_type(unsigned long *dimm_populated,			   unsigned char *iic0_dimm_addr,			   unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long dimm_type;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] == TRUE) {			dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);			switch (dimm_type) {			case 1:				printf("ERROR: Standard Fast Page Mode DRAM DIMM detected in "				       "slot %d.\n", (unsigned int)dimm_num);				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			case 2:				printf("ERROR: EDO DIMM detected in slot %d.\n",				       (unsigned int)dimm_num);				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			case 3:				printf("ERROR: Pipelined Nibble DIMM detected in slot %d.\n",				       (unsigned int)dimm_num);				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			case 4:				printf("ERROR: SDRAM DIMM detected in slot %d.\n",				       (unsigned int)dimm_num);				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			case 5:				printf("ERROR: Multiplexed ROM DIMM detected in slot %d.\n",				       (unsigned int)dimm_num);				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			case 6:				printf("ERROR: SGRAM DIMM detected in slot %d.\n",				       (unsigned int)dimm_num);				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			case 7:				debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num);				dimm_populated[dimm_num] = SDRAM_DDR1;				break;			case 8:				debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num);				dimm_populated[dimm_num] = SDRAM_DDR2;				break;			default:				printf("ERROR: Unknown DIMM detected in slot %d.\n",				       (unsigned int)dimm_num);				printf("Only DDR1 and DDR2 SDRAM DIMMs are supported.\n");				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();				break;			}		}	}	for (dimm_num = 1; dimm_num < num_dimm_banks; dimm_num++) {		if ((dimm_populated[dimm_num-1] != SDRAM_NONE)		    && (dimm_populated[dimm_num]   != SDRAM_NONE)		    && (dimm_populated[dimm_num-1] != dimm_populated[dimm_num])) {			printf("ERROR: DIMM's DDR1 and DDR2 type can not be mixed.\n");			spd_ddr_init_hang ();		}	}}/*------------------------------------------------------------------ * For the memory DIMMs installed, this routine verifies that * frequency previously calculated is supported. *-----------------------------------------------------------------*/static void check_frequency(unsigned long *dimm_populated,			    unsigned char *iic0_dimm_addr,			    unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long tcyc_reg;	unsigned long cycle_time;	unsigned long calc_cycle_time;	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));	/*	 * calc_cycle_time is calculated from DDR frequency set by board/chip	 * and is expressed in multiple of 10 picoseconds	 * to match the way DIMM cycle time is calculated below.	 */	calc_cycle_time = MULDIV64(ONE_BILLION, 100, sdram_freq);	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] != SDRAM_NONE) {			tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);			/*			 * Byte 9, Cycle time for CAS Latency=X, is split into two nibbles:			 * the higher order nibble (bits 4-7) designates the cycle time			 * to a granularity of 1ns;			 * the value presented by the lower order nibble (bits 0-3)			 * has a granularity of .1ns and is added to the value designated			 * by the higher nibble. In addition, four lines of the lower order			 * nibble are assigned to support +.25,+.33, +.66 and +.75.			 */			 /* Convert from hex to decimal */			if ((tcyc_reg & 0x0F) == 0x0D)				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 75;			else if ((tcyc_reg & 0x0F) == 0x0C)				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 66;			else if ((tcyc_reg & 0x0F) == 0x0B)				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 33;			else if ((tcyc_reg & 0x0F) == 0x0A)				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 25;			else				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) +					((tcyc_reg & 0x0F)*10);			debug("cycle_time=%d [10 picoseconds]\n", cycle_time);			if  (cycle_time > (calc_cycle_time + 10)) {				/*				 * the provided sdram cycle_time is too small				 * for the available DIMM cycle_time.				 * The additionnal 100ps is here to accept a small incertainty.				 */				printf("ERROR: DRAM DIMM detected with cycle_time %d ps in "				       "slot %d \n while calculated cycle time is %d ps.\n",				       (unsigned int)(cycle_time*10),				       (unsigned int)dimm_num,				       (unsigned int)(calc_cycle_time*10));				printf("Replace the DIMM, or change DDR frequency via "				       "strapping bits.\n\n");				spd_ddr_init_hang ();			}		}	}}/*------------------------------------------------------------------ * For the memory DIMMs installed, this routine verifies two * ranks/banks maximum are availables. *-----------------------------------------------------------------*/static void check_rank_number(unsigned long *dimm_populated,			      unsigned char *iic0_dimm_addr,			      unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long dimm_rank;	unsigned long total_rank = 0;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] != SDRAM_NONE) {			dimm_rank = spd_read(iic0_dimm_addr[dimm_num], 5);			if (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08)				dimm_rank = (dimm_rank & 0x0F) +1;			else				dimm_rank = dimm_rank & 0x0F;

⌨️ 快捷键说明

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