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

📄 44x_spd_ddr2.c

📁 u-boot1.3德国DENX小组开发的用于多种嵌入式CPU的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (dimm_rank > MAXRANKS) {				printf("ERROR: DRAM DIMM detected with %d ranks in "				       "slot %d is not supported.\n", dimm_rank, dimm_num);				printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();			} else				total_rank += dimm_rank;		}		if (total_rank > MAXRANKS) {			printf("ERROR: DRAM DIMM detected with a total of %d ranks "			       "for all slots.\n", (unsigned int)total_rank);			printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);			printf("Remove one of the DIMM modules.\n\n");			spd_ddr_init_hang ();		}	}}/*------------------------------------------------------------------ * only support 2.5V modules. * This routine verifies this. *-----------------------------------------------------------------*/static void check_voltage_type(unsigned long *dimm_populated,			       unsigned char *iic0_dimm_addr,			       unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long voltage_type;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] != SDRAM_NONE) {			voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);			switch (voltage_type) {			case 0x00:				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");				printf("This DIMM is 5.0 Volt/TTL.\n");				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",				       (unsigned int)dimm_num);				spd_ddr_init_hang ();				break;			case 0x01:				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");				printf("This DIMM is LVTTL.\n");				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",				       (unsigned int)dimm_num);				spd_ddr_init_hang ();				break;			case 0x02:				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");				printf("This DIMM is 1.5 Volt.\n");				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",				       (unsigned int)dimm_num);				spd_ddr_init_hang ();				break;			case 0x03:				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");				printf("This DIMM is 3.3 Volt/TTL.\n");				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",				       (unsigned int)dimm_num);				spd_ddr_init_hang ();				break;			case 0x04:				/* 2.5 Voltage only for DDR1 */				break;			case 0x05:				/* 1.8 Voltage only for DDR2 */				break;			default:				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",				       (unsigned int)dimm_num);				spd_ddr_init_hang ();				break;			}		}	}}/*-----------------------------------------------------------------------------+ * program_copt1. *-----------------------------------------------------------------------------*/static void program_copt1(unsigned long *dimm_populated,			  unsigned char *iic0_dimm_addr,			  unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long mcopt1;	unsigned long ecc_enabled;	unsigned long ecc = 0;	unsigned long data_width = 0;	unsigned long dimm_32bit;	unsigned long dimm_64bit;	unsigned long registered = 0;	unsigned long attribute = 0;	unsigned long buf0, buf1; /* TODO: code to be changed for IOP1.6 to support 4 DIMMs */	unsigned long bankcount;	unsigned long ddrtype;	unsigned long val;#ifdef CONFIG_DDR_ECC	ecc_enabled = TRUE;#else	ecc_enabled = FALSE;#endif	dimm_32bit = FALSE;	dimm_64bit = FALSE;	buf0 = FALSE;	buf1 = FALSE;	/*------------------------------------------------------------------	 * Set memory controller options reg 1, SDRAM_MCOPT1.	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_MCOPT1, val);	mcopt1 = val & ~(SDRAM_MCOPT1_MCHK_MASK | SDRAM_MCOPT1_RDEN_MASK |			 SDRAM_MCOPT1_PMU_MASK  | SDRAM_MCOPT1_DMWD_MASK |			 SDRAM_MCOPT1_UIOS_MASK | SDRAM_MCOPT1_BCNT_MASK |			 SDRAM_MCOPT1_DDR_TYPE_MASK | SDRAM_MCOPT1_RWOO_MASK |			 SDRAM_MCOPT1_WOOO_MASK | SDRAM_MCOPT1_DCOO_MASK |			 SDRAM_MCOPT1_DREF_MASK);	mcopt1 |= SDRAM_MCOPT1_QDEP;	mcopt1 |= SDRAM_MCOPT1_PMU_OPEN;	mcopt1 |= SDRAM_MCOPT1_RWOO_DISABLED;	mcopt1 |= SDRAM_MCOPT1_WOOO_DISABLED;	mcopt1 |= SDRAM_MCOPT1_DCOO_DISABLED;	mcopt1 |= SDRAM_MCOPT1_DREF_NORMAL;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] != SDRAM_NONE) {			/* test ecc support */			ecc = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 11);			if (ecc != 0x02) /* ecc not supported */				ecc_enabled = FALSE;			/* test bank count */			bankcount = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 17);			if (bankcount == 0x04) /* bank count = 4 */				mcopt1 |= SDRAM_MCOPT1_4_BANKS;			else /* bank count = 8 */				mcopt1 |= SDRAM_MCOPT1_8_BANKS;			/* test DDR type */			ddrtype = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2);			/* test for buffered/unbuffered, registered, differential clocks */			registered = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 20);			attribute = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 21);			/* TODO: code to be changed for IOP1.6 to support 4 DIMMs */			if (dimm_num == 0) {				if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */					mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE;				if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */					mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE;				if (registered == 1) { /* DDR2 always buffered */					/* TODO: what about above  comments ? */					mcopt1 |= SDRAM_MCOPT1_RDEN;					buf0 = TRUE;				} else {					/* TODO: the mask 0x02 doesn't match Samsung def for byte 21. */					if ((attribute & 0x02) == 0x00) {						/* buffered not supported */						buf0 = FALSE;					} else {						mcopt1 |= SDRAM_MCOPT1_RDEN;						buf0 = TRUE;					}				}			}			else if (dimm_num == 1) {				if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */					mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE;				if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */					mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE;				if (registered == 1) {					/* DDR2 always buffered */					mcopt1 |= SDRAM_MCOPT1_RDEN;					buf1 = TRUE;				} else {					if ((attribute & 0x02) == 0x00) {						/* buffered not supported */						buf1 = FALSE;					} else {						mcopt1 |= SDRAM_MCOPT1_RDEN;						buf1 = TRUE;					}				}			}			/* Note that for DDR2 the byte 7 is reserved, but OK to keep code as is. */			data_width = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 6) +				(((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 7)) << 8);			switch (data_width) {			case 72:			case 64:				dimm_64bit = TRUE;				break;			case 40:			case 32:				dimm_32bit = TRUE;				break;			default:				printf("WARNING: Detected a DIMM with a data width of %d bits.\n",				       data_width);				printf("Only DIMMs with 32 or 64 bit DDR-SDRAM widths are supported.\n");				break;			}		}	}	/* verify matching properties */	if ((dimm_populated[0] != SDRAM_NONE) && (dimm_populated[1] != SDRAM_NONE)) {		if (buf0 != buf1) {			printf("ERROR: DIMM's buffered/unbuffered, registered, clocking don't match.\n");			spd_ddr_init_hang ();		}	}	if ((dimm_64bit == TRUE) && (dimm_32bit == TRUE)) {		printf("ERROR: Cannot mix 32 bit and 64 bit DDR-SDRAM DIMMs together.\n");		spd_ddr_init_hang ();	}	else if ((dimm_64bit == TRUE) && (dimm_32bit == FALSE)) {		mcopt1 |= SDRAM_MCOPT1_DMWD_64;	} else if ((dimm_64bit == FALSE) && (dimm_32bit == TRUE)) {		mcopt1 |= SDRAM_MCOPT1_DMWD_32;	} else {		printf("ERROR: Please install only 32 or 64 bit DDR-SDRAM DIMMs.\n\n");		spd_ddr_init_hang ();	}	if (ecc_enabled == TRUE)		mcopt1 |= SDRAM_MCOPT1_MCHK_GEN;	else		mcopt1 |= SDRAM_MCOPT1_MCHK_NON;	mtsdram(SDRAM_MCOPT1, mcopt1);}/*-----------------------------------------------------------------------------+ * program_codt. *-----------------------------------------------------------------------------*/static void program_codt(unsigned long *dimm_populated,			 unsigned char *iic0_dimm_addr,			 unsigned long num_dimm_banks){	unsigned long codt;	unsigned long modt0 = 0;	unsigned long modt1 = 0;	unsigned long modt2 = 0;	unsigned long modt3 = 0;	unsigned char dimm_num;	unsigned char dimm_rank;	unsigned char total_rank = 0;	unsigned char total_dimm = 0;	unsigned char dimm_type = 0;	unsigned char firstSlot = 0;	/*------------------------------------------------------------------	 * Set the SDRAM Controller On Die Termination Register	 *-----------------------------------------------------------------*/	mfsdram(SDRAM_CODT, codt);	codt |= (SDRAM_CODT_IO_NMODE		 & (~SDRAM_CODT_DQS_SINGLE_END		    & ~SDRAM_CODT_CKSE_SINGLE_END		    & ~SDRAM_CODT_FEEBBACK_RCV_SINGLE_END		    & ~SDRAM_CODT_FEEBBACK_DRV_SINGLE_END));	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] != SDRAM_NONE) {			dimm_rank = (unsigned long)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;				dimm_type = SDRAM_DDR2;			} else {				dimm_rank = dimm_rank & 0x0F;				dimm_type = SDRAM_DDR1;			}			total_rank += dimm_rank;			total_dimm++;			if ((dimm_num == 0) && (total_dimm == 1))				firstSlot = TRUE;			else				firstSlot = FALSE;		}	}	if (dimm_type == SDRAM_DDR2) {		codt |= SDRAM_CODT_DQS_1_8_V_DDR2;		if ((total_dimm == 1) && (firstSlot == TRUE)) {			if (total_rank == 1) {				codt |= CALC_ODT_R(0);				modt0 = CALC_ODT_W(0);				modt1 = 0x00000000;				modt2 = 0x00000000;				modt3 = 0x00000000;			}			if (total_rank == 2) {				codt |= CALC_ODT_R(0) | CALC_ODT_R(1);				modt0 = CALC_ODT_W(0);				modt1 = CALC_ODT_W(0);				modt2 = 0x00000000;				modt3 = 0x00000000;			}		} else if ((total_dimm == 1) && (firstSlot != TRUE)) {			if (total_rank == 1) {				codt |= CALC_ODT_R(2);				modt0 = 0x00000000;				modt1 = 0x00000000;				modt2 = CALC_ODT_W(2);				modt3 = 0x00000000;			}			if (total_rank == 2) {				codt |= CALC_ODT_R(2) | CALC_ODT_R(3);				modt0 = 0x00000000;				modt1 = 0x00000000;				modt2 = CALC_ODT_W(2);				modt3 = CALC_ODT_W(2);			}		}		if (total_dimm == 2) {			if (total_rank == 2) {				codt |= CALC_ODT_R(0) | CALC_ODT_R(2);				modt0 = CALC_ODT_RW(2);				modt1 = 0x00000000;				modt2 = CALC_ODT_RW(0);				modt3 = 0x00000000;			}			if (total_rank == 4) {				codt |= CALC_ODT_R(0) | CALC_ODT_R(1) |					CALC_ODT_R(2) | CALC_ODT_R(3);				modt0 = CALC_ODT_RW(2);				modt1 = 0x00000000;				modt2 = CALC_ODT_RW(0);				modt3 = 0x00000000;			}		}	} else {		codt |= SDRAM_CODT_DQS_2_5_V_DDR1;		modt0 = 0x00000000;		modt1 = 0x00000000;		modt2 = 0x00000000;		modt3 = 0x00000000;		if (total_dimm == 1) {			if (total_rank == 1)				codt |= 0x00800000;			if (total_rank == 2)				codt |= 0x02800000;		}		if (total_dimm == 2) {			if (total_rank == 2)				codt |= 0x08800000;			if (total_rank == 4)				codt |= 0x2a800000;		}	}	debug("nb of dimm %d\n", total_dimm);	debug("nb of rank %d\n", total_rank);	if (total_dimm == 1)		debug("dimm in slot %d\n", firstSlot);	mtsdram(SDRAM_CODT, codt);	mtsdram(SDRAM_MODT0, modt0);	mtsdram(SDRAM_MODT1, modt1);	mtsdram(SDRAM_MODT2, modt2);	mtsdram(SDRAM_MODT3, modt3);}/*-----------------------------------------------------------------------------+ * program_initplr. *-----------------------------------------------------------------------------*/static void program_initplr(unsigned long *dimm_populated,			    unsigned char *iic0_dimm_addr,			    unsigned long num_dimm_banks,			    ddr_cas_id_t selected_cas,			    int write_recovery){	u32 cas = 0;	u32 odt = 0;	u32 ods = 0;	u32 mr;	u32 wr;	u32 emr;	u32 emr2;	u32 emr3;	int dimm_num;	int total_dimm = 0;	/******************************************************	 ** Assumption: if more than one DIMM, all DIMMs are the same	 **		as already checked in check_memory_type	 ******************************************************/	if ((dimm_populated[0] == SDRAM_DDR1) || (dimm_populated[1] == SDRAM_DDR1)) {		mtsdram(SDRAM_INITPLR0, 0x81B80000);		mtsdram(SDRAM_INITPLR1, 0x81900400);		mtsdram(SDRAM_INITPLR2, 0x81810000);		mtsdram(SDRAM_INITPLR3, 0xff800162);		mtsdram(SDRAM_INITPLR4, 0x81900400);		mtsdram(SDRAM_INITPLR5, 0x86080000);		mtsdram(SDRAM_INITPLR6, 0x86080000);		mtsdram(SDRAM_INITPLR7, 0x81000062);	} else if ((dimm_populated[0] == SDRAM_DDR2) || (dimm_populated[1] == SDRAM_DDR2)) {		switch (selected_cas) {		case DDR_CAS_3:			cas = 3 << 4;			break;

⌨️ 快捷键说明

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