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

📄 44x_spd_ddr.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,		 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},		{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,		 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},		{0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,		 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},		{0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,		 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},		{0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,		 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},		{0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,		 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},		{0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,		 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},		{0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,		 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}};	for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {		mtdcr(memcfga, mem_b0cr + (bxcr_num << 2));		if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {			/* Bank is enabled */			membase = (unsigned long*)				(mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);			/*			 * Run the short memory test			 */			for (i = 0; i < NUMMEMTESTS; i++) {				for (j = 0; j < NUMMEMWORDS; j++) {					/* printf("bank enabled base:%x\n", &membase[j]); */					membase[j] = test[i][j];					ppcDcbf((unsigned long)&(membase[j]));				}				for (j = 0; j < NUMMEMWORDS; j++) {					if (membase[j] != test[i][j]) {						ppcDcbf((unsigned long)&(membase[j]));						return 0;					}					ppcDcbf((unsigned long)&(membase[j]));				}				if (j < NUMMEMWORDS)					return 0;			}			/*			 * see if the rdclt value passed			 */			if (i < NUMMEMTESTS)				return 0;		}	}	return 1;}static void program_tr1(void){	unsigned long tr0;	unsigned long tr1;	unsigned long cfg0;	unsigned long ecc_temp;	unsigned long dlycal;	unsigned long dly_val;	unsigned long k;	unsigned long max_pass_length;	unsigned long current_pass_length;	unsigned long current_fail_length;	unsigned long current_start;	unsigned long rdclt;	unsigned long rdclt_offset;	long max_start;	long max_end;	long rdclt_average;	unsigned char window_found;	unsigned char fail_found;	unsigned char pass_found;	PPC4xx_SYS_INFO sys_info;	/*	 * get the board info	 */	get_sys_info(&sys_info);	/*	 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits	 */	mfsdram(mem_tr1, tr1);	tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK |		 SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK);	mfsdram(mem_tr0, tr0);	if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) &&	    (sys_info.freqPLB > 100000000)) {		tr1 |= SDRAM_TR1_RDSS_TR2;		tr1 |= SDRAM_TR1_RDSL_STAGE3;		tr1 |= SDRAM_TR1_RDCD_RCD_1_2;	} else {		tr1 |= SDRAM_TR1_RDSS_TR1;		tr1 |= SDRAM_TR1_RDSL_STAGE2;		tr1 |= SDRAM_TR1_RDCD_RCD_0_0;	}	/*	 * save CFG0 ECC setting to a temporary variable and turn ECC off	 */	mfsdram(mem_cfg0, cfg0);	ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK;	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON);	/*	 * get the delay line calibration register value	 */	mfsdram(mem_dlycal, dlycal);	dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;	max_pass_length = 0;	max_start = 0;	max_end = 0;	current_pass_length = 0;	current_fail_length = 0;	current_start = 0;	rdclt_offset = 0;	window_found = FALSE;	fail_found = FALSE;	pass_found = FALSE;	debug("Starting memory test ");	for (k = 0; k < NUMHALFCYCLES; k++) {		for (rdclt = 0; rdclt < dly_val; rdclt++) {			/*			 * Set the timing reg for the test.			 */			mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));			if (short_mem_test()) {				if (fail_found == TRUE) {					pass_found = TRUE;					if (current_pass_length == 0) {						current_start = rdclt_offset + rdclt;					}					current_fail_length = 0;					current_pass_length++;					if (current_pass_length > max_pass_length) {						max_pass_length = current_pass_length;						max_start = current_start;						max_end = rdclt_offset + rdclt;					}				}			} else {				current_pass_length = 0;				current_fail_length++;				if (current_fail_length >= (dly_val>>2)) {					if (fail_found == FALSE) {						fail_found = TRUE;					} else if (pass_found == TRUE) {						window_found = TRUE;						break;					}				}			}		}		debug(".");		if (window_found == TRUE) {			break;		}		tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;		rdclt_offset += dly_val;	}	debug("\n");	/*	 * make sure we find the window	 */	if (window_found == FALSE) {		printf("ERROR: Cannot determine a common read delay.\n");		spd_ddr_init_hang ();	}	/*	 * restore the orignal ECC setting	 */	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp);	/*	 * set the SDRAM TR1 RDCD value	 */	tr1 &= ~SDRAM_TR1_RDCD_MASK;	if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) {		tr1 |= SDRAM_TR1_RDCD_RCD_1_2;	} else {		tr1 |= SDRAM_TR1_RDCD_RCD_0_0;	}	/*	 * set the SDRAM TR1 RDCLT value	 */	tr1 &= ~SDRAM_TR1_RDCT_MASK;	while (max_end >= (dly_val << 1)) {		max_end -= (dly_val << 1);		max_start -= (dly_val << 1);	}	rdclt_average = ((max_start + max_end) >> 1);	if (rdclt_average < 0) {		rdclt_average = 0;	}	if (rdclt_average >= dly_val) {		rdclt_average -= dly_val;		tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;	}	tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);	debug("tr1: %x\n", tr1);	/*	 * program SDRAM Timing Register 1 TR1	 */	mtsdram(mem_tr1, tr1);}static unsigned long program_bxcr(unsigned long *dimm_populated,				  unsigned char *iic0_dimm_addr,				  unsigned long num_dimm_banks){	unsigned long dimm_num;	unsigned long bank_base_addr;	unsigned long cr;	unsigned long i;	unsigned long j;	unsigned long temp;	unsigned char num_row_addr;	unsigned char num_col_addr;	unsigned char num_banks;	unsigned char bank_size_id;	unsigned long ctrl_bank_num[MAXBANKS];	unsigned long bx_cr_num;	unsigned long largest_size_index;	unsigned long largest_size;	unsigned long current_size_index;	BANKPARMS bank_parms[MAXBXCR];	unsigned long sorted_bank_num[MAXBXCR]; /* DDR Controller bank number table (sorted by size) */	unsigned long sorted_bank_size[MAXBXCR]; /* DDR Controller bank size table (sorted by size)*/	/*	 * Set the BxCR regs.  First, wipe out the bank config registers.	 */	for (bx_cr_num = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {		mtdcr(memcfga, mem_b0cr + (bx_cr_num << 2));		mtdcr(memcfgd, 0x00000000);		bank_parms[bx_cr_num].bank_size_bytes = 0;	}#ifdef CONFIG_BAMBOO	/*	 * This next section is hardware dependent and must be programmed	 * to match the hardware.  For bamboo, the following holds...	 * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 (soldered onboard)	 * 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1	 * 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1	 * 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3	 * ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM	 */	ctrl_bank_num[0] = 0;	ctrl_bank_num[1] = 1;	ctrl_bank_num[2] = 3;#else	/*	 * Ocotea, Ebony and the other IBM/AMCC eval boards have	 * 2 DIMM slots with each max 2 banks	 */	ctrl_bank_num[0] = 0;	ctrl_bank_num[1] = 2;#endif	/*	 * reset the bank_base address	 */	bank_base_addr = CFG_SDRAM_BASE;	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {		if (dimm_populated[dimm_num] == TRUE) {			num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3);			num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);			num_banks    = spd_read(iic0_dimm_addr[dimm_num], 5);			bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);			debug("DIMM%d: row=%d col=%d banks=%d\n", dimm_num,			      num_row_addr, num_col_addr, num_banks);			/*			 * Set the SDRAM0_BxCR regs			 */			cr = 0;			switch (bank_size_id) {			case 0x02:				cr |= SDRAM_BXCR_SDSZ_8;				break;			case 0x04:				cr |= SDRAM_BXCR_SDSZ_16;				break;			case 0x08:				cr |= SDRAM_BXCR_SDSZ_32;				break;			case 0x10:				cr |= SDRAM_BXCR_SDSZ_64;				break;			case 0x20:				cr |= SDRAM_BXCR_SDSZ_128;				break;			case 0x40:				cr |= SDRAM_BXCR_SDSZ_256;				break;			case 0x80:				cr |= SDRAM_BXCR_SDSZ_512;				break;			default:				printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",				       dimm_num);				printf("ERROR: Unsupported value for the banksize: %d.\n",				       bank_size_id);				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();			}			switch (num_col_addr) {			case 0x08:				cr |= SDRAM_BXCR_SDAM_1;				break;			case 0x09:				cr |= SDRAM_BXCR_SDAM_2;				break;			case 0x0A:				cr |= SDRAM_BXCR_SDAM_3;				break;			case 0x0B:				cr |= SDRAM_BXCR_SDAM_4;				break;			default:				printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",				       dimm_num);				printf("ERROR: Unsupported value for number of "				       "column addresses: %d.\n", num_col_addr);				printf("Replace the DIMM module with a supported DIMM.\n\n");				spd_ddr_init_hang ();			}			/*			 * enable the bank			 */			cr |= SDRAM_BXCR_SDBE;			for (i = 0; i < num_banks; i++) {				bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =					(4 << 20) * bank_size_id;				bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;				debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n",				      dimm_num, i, ctrl_bank_num[dimm_num]+i,				      bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes);			}		}	}	/* Initialize sort tables */	for (i = 0; i < MAXBXCR; i++) {		sorted_bank_num[i] = i;		sorted_bank_size[i] = bank_parms[i].bank_size_bytes;	}	for (i = 0; i < MAXBXCR-1; i++) {		largest_size = sorted_bank_size[i];		largest_size_index = 255;		/* Find the largest remaining value */		for (j = i + 1; j < MAXBXCR; j++) {			if (sorted_bank_size[j] > largest_size) {				/* Save largest remaining value and its index */				largest_size = sorted_bank_size[j];				largest_size_index = j;			}		}		if (largest_size_index != 255) {			/* Swap the current and largest values */			current_size_index = sorted_bank_num[largest_size_index];			sorted_bank_size[largest_size_index] = sorted_bank_size[i];			sorted_bank_size[i] = largest_size;			sorted_bank_num[largest_size_index] = sorted_bank_num[i];			sorted_bank_num[i] = current_size_index;		}	}	/* Set the SDRAM0_BxCR regs thanks to sort tables */	for (bx_cr_num = 0, bank_base_addr = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {		if (bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes) {			mtdcr(memcfga, mem_b0cr + (sorted_bank_num[bx_cr_num] << 2));			temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK |						  SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE);			temp = temp | (bank_base_addr & SDRAM_BXCR_SDBA_MASK) |				bank_parms[sorted_bank_num[bx_cr_num]].cr;			mtdcr(memcfgd, temp);			bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;			debug("SDRAM0_B%dCR=0x%08lx\n", sorted_bank_num[bx_cr_num], temp);		}	}	return(bank_base_addr);}#endif /* CONFIG_SPD_EEPROM */

⌨️ 快捷键说明

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