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

📄 4xx_ibm_ddr2_autocalib.c

📁 最新版的u-boot,2008-10-18发布
💻 C
📖 第 1 页 / 共 3 页
字号:
	curr_win_min = curr_win_max = 0;	best_win_min = best_win_max = 0;	for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) {		mfsdram(SDRAM_RQDC, rqdc_reg);		rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);		mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));		pass = 1;		for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {			mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);			/* Banks enabled */			if (bxcf & SDRAM_BXCF_M_BE_MASK) {				/* Bank is enabled */				membase = get_membase(bxcr_num);				pass &= short_mem_test(membase);			} /* if bank enabled */		} /* for bxcf_num */		/* If this value passed */		if (pass && !in_window) {			in_window = 1;			curr_win_min = curr_win_max = rqfd;		} else if (!pass && in_window) {			in_window = 0;		} else if (pass && in_window) {			curr_win_max = rqfd;		}		if (in_window) {			if ((curr_win_max - curr_win_min) >			    (best_win_max - best_win_min)) {				best_win_min = curr_win_min;				best_win_max = curr_win_max;			}			passed = 1;		}	} /* for rqfd */	if ((best_win_min == 0) && (best_win_max == 0))		passed = 0;	debug("RQFD Min: 0x%x\n", best_win_min);	debug("RQFD Max: 0x%x\n", best_win_max);	rqfd_average = ((best_win_min + best_win_max) / 2);	if (rqfd_average < 0)		rqfd_average = 0;	if (rqfd_average > SDRAM_RQDC_RQFD_MAX)		rqfd_average = SDRAM_RQDC_RQFD_MAX;	mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |					SDRAM_RQDC_RQFD_ENCODE(rqfd_average));	mfsdram(SDRAM_RQDC, rqdc_reg);	mfsdram(SDRAM_RFDC, rfdc_reg);	/*	 * Need to program RQDC before RFDC. The value is read above.	 * That is the reason why auto cal not work.	 * See, comments below.	 */	mtsdram(SDRAM_RQDC, rqdc_reg);	mtsdram(SDRAM_RFDC, rfdc_reg);	debug("RQDC: 0x%08X\n", rqdc_reg);	debug("RFDC: 0x%08X\n", rfdc_reg);	/* if something passed, then return the size of the largest window */	if (passed != 0) {		passed		= size;		cal->rqfd	= rqfd_average;		cal->rffd	= rffd_average;	}	return (uint)passed;}#endif /* defined(CONFIG_PPC4xx_DDR_METHOD_A) *//* * Default table for DDR auto-calibration of all * possible WRDTR and CLKTR values. * Table format is: *	 {SDRAM_WRDTR.[WDTR], SDRAM_CLKTR.[CKTR]} * * Table is terminated with {-1, -1} value pair. * * Board vendors can specify their own board specific subset of * known working {SDRAM_WRDTR.[WDTR], SDRAM_CLKTR.[CKTR]} value * pairs via a board defined ddr_scan_option() function. */struct sdram_timing full_scan_options[] = {	{0, 0}, {0, 1}, {0, 2}, {0, 3},	{1, 0}, {1, 1}, {1, 2}, {1, 3},	{2, 0}, {2, 1}, {2, 2}, {2, 3},	{3, 0}, {3, 1}, {3, 2}, {3, 3},	{4, 0}, {4, 1}, {4, 2}, {4, 3},	{5, 0}, {5, 1}, {5, 2}, {5, 3},	{6, 0}, {6, 1}, {6, 2}, {6, 3},	{-1, -1}};/*---------------------------------------------------------------------------+| DQS_calibration.+----------------------------------------------------------------------------*/u32 DQS_autocalibration(void){	u32 wdtr;	u32 clkp;	u32 result = 0;	u32 best_result = 0;	u32 best_rdcc;	struct ddrautocal ddrcal;	struct autocal_clks tcal;	ulong rfdc_reg;	ulong rqdc_reg;	u32 val;	int verbose_lvl = 0;	char *str;	char slash[] = "\\|/-\\|/-";	int loopi = 0;	struct sdram_timing *scan_list;#if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION)	int i;	char tmp[64];	/* long enough for environment variables */#endif	memset(&tcal, 0, sizeof(tcal));	ddr_scan_option((ulong)full_scan_options);	scan_list =	      (struct sdram_timing *)ddr_scan_option((ulong)full_scan_options);	mfsdram(SDRAM_MCOPT1, val);	if ((val & SDRAM_MCOPT1_MCHK_CHK_REP) == SDRAM_MCOPT1_MCHK_CHK_REP)		str = "ECC Auto calibration -";	else		str = "Auto calibration -";	puts(str);#if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION)	i = getenv_r("autocalib", tmp, sizeof(tmp));	if (i < 0)		strcpy(tmp, CONFIG_AUTOCALIB);	if (strcmp(tmp, "final") == 0) {		/* display the final autocalibration results only */		verbose_lvl = 1;	} else if (strcmp(tmp, "loop") == 0) {		/* display summary autocalibration info per iteration */		verbose_lvl = 2;	} else if (strcmp(tmp, "display") == 0) {		/* display full debug autocalibration window info. */		verbose_lvl = 3;	}#endif /* (DEBUG_PPC4xx_DDR_AUTOCALIBRATION) */	best_rdcc = (SDRAM_RDCC_RDSS_T4 >> 30);	while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) {		wdtr = scan_list->wrdtr;		clkp = scan_list->clktr;		mfsdram(SDRAM_WRDTR, val);		val &= ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK);		mtsdram(SDRAM_WRDTR, (val |			ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | (wdtr << 25))));		mtsdram(SDRAM_CLKTR, clkp << 30);		relock_memory_DLL();		putc('\b');		putc(slash[loopi++ % 8]);#ifdef DEBUG		debug("\n");		debug("*** --------------\n");		mfsdram(SDRAM_WRDTR, val);		debug("*** SDRAM_WRDTR set to 0x%08x\n", val);		mfsdram(SDRAM_CLKTR, val);		debug("*** SDRAM_CLKTR set to 0x%08x\n", val);#endif		debug("\n");		if (verbose_lvl > 2) {			printf("*** SDRAM_WRDTR (wdtr) set to %d\n", wdtr);			printf("*** SDRAM_CLKTR (clkp) set to %d\n", clkp);		}		memset(&ddrcal, 0, sizeof(ddrcal));		/*		 * DQS calibration.		 */		/*		 * program_DQS_calibration_method[A|B]() returns 0 if no		 * passing RFDC.[RFFD] window is found or returns the size		 * of the best passing window; in the case of a found passing		 * window, the ddrcal will contain the values of the best		 * window RQDC.[RQFD] and RFDC.[RFFD].		 */		/*		 * Call PPC4xx SDRAM DDR autocalibration methodA or methodB.		 * Default is methodB.		 * Defined the autocalibration method in the board specific		 * header file.		 * Please see include/configs/kilauea.h for an example for		 * a board specific implementation.		 */#if defined(CONFIG_PPC4xx_DDR_METHOD_A)		result = program_DQS_calibration_methodA(&ddrcal);#else		result = program_DQS_calibration_methodB(&ddrcal);#endif		sync();		/*		 * Clear potential errors resulting from auto-calibration.		 * If not done, then we could get an interrupt later on when		 * exceptions are enabled.		 */		set_mcsr(get_mcsr());		val = ddrcal.rdcc;	/* RDCC from the best passing window */		udelay(100);		if (verbose_lvl > 1) {			char *tstr;			switch ((val >> 30)) {			case 0:				if (result != 0)					tstr = "T1";				else					tstr = "N/A";				break;			case 1:				tstr = "T2";				break;			case 2:				tstr = "T3";				break;			case 3:				tstr = "T4";				break;			default:				tstr = "unknown";				break;			}			printf("** WRDTR(%d) CLKTR(%d), Wind (%d), best (%d), "			       "max-min(0x%04x)(0x%04x), RDCC: %s\n",				wdtr, clkp, result, best_result,				ddrcal.rffd_min, ddrcal.rffd_max, tstr);		}		/*		 * The DQS calibration "result" is either "0"		 * if no passing window was found, or is the		 * size of the RFFD passing window.		 */		if (result != 0) {			tcal.autocal.flags = 1;			debug("*** (%d)(%d) result passed window size: 0x%08x, "			      "rqfd = 0x%08x, rffd = 0x%08x, rdcc = 0x%08x\n",				wdtr, clkp, result, ddrcal.rqfd,				ddrcal.rffd, ddrcal.rdcc);			/*			 * Save the SDRAM_WRDTR and SDRAM_CLKTR			 * settings for the largest returned			 * RFFD passing window size.			 */			if (result > best_result) {				/*				 * want the lowest Read Sample Cycle Select				 */				val = (val & SDRAM_RDCC_RDSS_MASK) >> 30;				debug("*** (%d) (%d) current_rdcc, best_rdcc\n",							val, best_rdcc);				if (val <= best_rdcc) {					best_rdcc = val;					tcal.clocks.wrdtr = wdtr;					tcal.clocks.clktr = clkp;					tcal.clocks.rdcc = (val << 30);					tcal.autocal.rqfd = ddrcal.rqfd;					tcal.autocal.rffd = ddrcal.rffd;					best_result = result;					if (verbose_lvl > 2) {						printf("** (%d)(%d)  "						       "best result: 0x%04x\n",							wdtr, clkp,							best_result);						printf("** (%d)(%d)  "						       "best WRDTR: 0x%04x\n",							wdtr, clkp,							tcal.clocks.wrdtr);						printf("** (%d)(%d)  "						       "best CLKTR: 0x%04x\n",							wdtr, clkp,							tcal.clocks.clktr);						printf("** (%d)(%d)  "						       "best RQDC: 0x%04x\n",							wdtr, clkp,							tcal.autocal.rqfd);						printf("** (%d)(%d)  "						       "best RFDC: 0x%04x\n",							wdtr, clkp,							tcal.autocal.rffd);						printf("** (%d)(%d)  "						       "best RDCC: 0x%08x\n",							wdtr, clkp,							(u32)tcal.clocks.rdcc);						mfsdram(SDRAM_RTSR, val);						printf("** (%d)(%d)  best "						       "loop RTSR: 0x%08x\n",							wdtr, clkp, val);						mfsdram(SDRAM_FCSR, val);						printf("** (%d)(%d)  best "						       "loop FCSR: 0x%08x\n",							wdtr, clkp, val);					}				} /* if (val <= best_rdcc) */			} /* if (result >= best_result) */		} /* if (result != 0) */		scan_list++;	} /* while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) */	if (tcal.autocal.flags == 1) {		if (verbose_lvl > 0) {			printf("*** --------------\n");			printf("*** best_result window size: %d\n",							best_result);			printf("*** best_result WRDTR: 0x%04x\n",							tcal.clocks.wrdtr);			printf("*** best_result CLKTR: 0x%04x\n",							tcal.clocks.clktr);			printf("*** best_result RQFD: 0x%04x\n",							tcal.autocal.rqfd);			printf("*** best_result RFFD: 0x%04x\n",							tcal.autocal.rffd);			printf("*** best_result RDCC: 0x%04x\n",							tcal.clocks.rdcc);			printf("*** --------------\n");			printf("\n");		}		/*		 * if got best passing result window, then lock in the		 * best CLKTR, WRDTR, RQFD, and RFFD values		 */		mfsdram(SDRAM_WRDTR, val);		mtsdram(SDRAM_WRDTR, (val &		    ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) |		    ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC |					(tcal.clocks.wrdtr << 25)));		mtsdram(SDRAM_CLKTR, tcal.clocks.clktr << 30);		relock_memory_DLL();		mfsdram(SDRAM_RQDC, rqdc_reg);		rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);		mtsdram(SDRAM_RQDC, rqdc_reg |				SDRAM_RQDC_RQFD_ENCODE(tcal.autocal.rqfd));		mfsdram(SDRAM_RQDC, rqdc_reg);		debug("*** best_result: read value SDRAM_RQDC 0x%08x\n",				rqdc_reg);		mfsdram(SDRAM_RFDC, rfdc_reg);		rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);		mtsdram(SDRAM_RFDC, rfdc_reg |				SDRAM_RFDC_RFFD_ENCODE(tcal.autocal.rffd));		mfsdram(SDRAM_RFDC, rfdc_reg);		debug("*** best_result: read value SDRAM_RFDC 0x%08x\n",				rfdc_reg);		mfsdram(SDRAM_RDCC, val);		debug("***  SDRAM_RDCC 0x%08x\n", val);	} else {		/*		 * no valid windows were found		 */		printf("DQS memory calibration window can not be determined, "		       "terminating u-boot.\n");		ppc4xx_ibm_ddr2_register_dump();		spd_ddr_init_hang();	}	blank_string(strlen(str));	return 0;}#else /* defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */u32 DQS_autocalibration(void){	return 0;}#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */#endif /* defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) */

⌨️ 快捷键说明

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