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

📄 spd_sdram.c

📁 linux下的BOOT程序原码,有需要的可以来下,保证好用
💻 C
📖 第 1 页 / 共 4 页
字号:
	case 3:		tr0 |= SDRAM_TR0_SDRD_3_CLK;		break;	default:		tr0 |= SDRAM_TR0_SDRD_4_CLK;		break;	}#if 0	printf("tr0: %x\n", tr0);#endif	mtsdram(mem_tr0, tr0);}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 i, j, k;	unsigned long bxcr_num;	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;	unsigned long * membase;	PPC440_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;#ifdef DEBUG	printf("Starting memory test ");#endif	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)));			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++) {							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]));								break;							}							ppcDcbf((unsigned long)&(membase[j]));						}						if (j < NUMMEMWORDS) {							break;						}					}					/*					 * see if the rdclt value passed					 */					if (i < NUMMEMTESTS) {						break;					}				}			}			if (bxcr_num == MAXBXCR) {				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;					}				}			}		}#ifdef DEBUG		printf(".");#endif		if (window_found == TRUE) {			break;		}		tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;		rdclt_offset += dly_val;	}#ifdef DEBUG	printf("\n");#endif	/*	 * make sure we find the window	 */	if (window_found == FALSE) {		printf("ERROR: Cannot determine a common read delay.\n");		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 >= 0x60)		while (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);#if 0	printf("tr1: %x\n", tr1);#endif	/*	 * program SDRAM Timing Register 1 TR1	 */	mtsdram(mem_tr1, tr1);}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 bammboo, the following holds...	 * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0	 * 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	ctrl_bank_num[0] = 0;	ctrl_bank_num[1] = 1;	ctrl_bank_num[2] = 2;	ctrl_bank_num[3] = 3;#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);			/*			 * 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");				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");				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 * 1024 * 1024) * bank_size_id;				bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;			}		}	}	/* 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;		}	}	return(bank_base_addr);}void program_ecc (unsigned long	 num_bytes){	unsigned long bank_base_addr;	unsigned long current_address;	unsigned long end_address;	unsigned long address_increment;	unsigned long cfg0;	/*	 * get Memory Controller Options 0 data	 */	mfsdram(mem_cfg0, cfg0);	/*	 * reset the bank_base address	 */	bank_base_addr = CFG_SDRAM_BASE;	if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {		mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |			SDRAM_CFG0_MCHK_GEN);		if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) {			address_increment = 4;		} else {			address_increment = 8;		}		current_address = (unsigned long)(bank_base_addr);		end_address = (unsigned long)(bank_base_addr) + num_bytes;		while (current_address < end_address) {			*((unsigned long*)current_address) = 0x00000000;			current_address += address_increment;		}		mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |			SDRAM_CFG0_MCHK_CHK);	}}#endif /* CONFIG_440 */#endif /* CONFIG_SPD_EEPROM */

⌨️ 快捷键说明

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