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

📄 4xx_ibm_ddr2_autocalib.c

📁 最新版的u-boot,2008-10-18发布
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c * This SPD SDRAM detection code supports AMCC PPC44x cpu's with a * DDR2 controller (non Denali Core). Those currently are: * * 405:		405EX * 440/460:	440SP/440SPe/460EX/460GT/460SX * * (C) Copyright 2008 Applied Micro Circuits Corporation * Adam Graham  <agraham@amcc.com> * * (C) Copyright 2007-2008 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * COPYRIGHT   AMCC   CORPORATION 2004 * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * *//* define DEBUG for debugging output (obviously ;-)) */#undef DEBUG#include <common.h>#include <ppc4xx.h>#include <asm/io.h>#include <asm/processor.h>#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)/* * Only compile the DDR auto-calibration code for NOR boot and * not for NAND boot (NAND SPL and NAND U-Boot - NUB) */#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)#define MAXBXCF			4#define SDRAM_RXBAS_SHIFT_1M	20#if defined(CFG_DECREMENT_PATTERNS)#define NUMMEMTESTS		24#else#define NUMMEMTESTS		8#endif /* CFG_DECREMENT_PATTERNS */#define NUMLOOPS		1	/* configure as you deem approporiate */#define NUMMEMWORDS		16/* Private Structure Definitions */struct autocal_regs {	u32 rffd;	u32 rqfd;};struct ddrautocal {	u32 rffd;	u32 rffd_min;	u32 rffd_max;	u32 rffd_size;	u32 rqfd;	u32 rqfd_size;	u32 rdcc;	u32 flags;};struct sdram_timing {	u32 wrdtr;	u32 clktr;};struct sdram_timing_clks {	u32 wrdtr;	u32 clktr;	u32 rdcc;	u32 flags;};struct autocal_clks {	struct sdram_timing_clks clocks;	struct ddrautocal	 autocal;};/*--------------------------------------------------------------------------+ * Prototypes *--------------------------------------------------------------------------*/#if defined(CONFIG_PPC4xx_DDR_METHOD_A)static u32 DQS_calibration_methodA(struct ddrautocal *);static u32 program_DQS_calibration_methodA(struct ddrautocal *);#elsestatic u32 DQS_calibration_methodB(struct ddrautocal *);static u32 program_DQS_calibration_methodB(struct ddrautocal *);#endifstatic int short_mem_test(u32 *);/* * To provide an interface for board specific config values in this common * DDR setup code, we implement he "weak" default functions here. They return * the default value back to the caller. * * Please see include/configs/yucca.h for an example fora board specific * implementation. */#if !defined(CONFIG_SPD_EEPROM)u32 __ddr_wrdtr(u32 default_val){	return default_val;}u32 ddr_wrdtr(u32) __attribute__((weak, alias("__ddr_wrdtr")));u32 __ddr_clktr(u32 default_val){	return default_val;}u32 ddr_clktr(u32) __attribute__((weak, alias("__ddr_clktr")));/* * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed */void __spd_ddr_init_hang(void){	hang();}voidspd_ddr_init_hang(void) __attribute__((weak, alias("__spd_ddr_init_hang")));#endif /* defined(CONFIG_SPD_EEPROM) */ulong __ddr_scan_option(ulong default_val){	return default_val;}ulong ddr_scan_option(ulong) __attribute__((weak, alias("__ddr_scan_option")));static u32 *get_membase(int bxcr_num){	ulong bxcf;	u32 *membase;#if defined(SDRAM_R0BAS)	/* BAS from Memory Queue rank reg. */	membase =	    (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)));	bxcf = 0;	/* just to satisfy the compiler */#else	/* BAS from SDRAM_MBxCF mem rank reg. */	mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);	membase = (u32 *)((bxcf & 0xfff80000) << 3);#endif	return membase;}static inline void ecc_clear_status_reg(void){	mtsdram(SDRAM_ECCCR, 0xffffffff);#if defined(SDRAM_R0BAS)	mtdcr(SDRAM_ERRSTATLL, 0xffffffff);#endif}/* * Reset and relock memory DLL after SDRAM_CLKTR change */static inline void relock_memory_DLL(void){	u32 reg;	mtsdram(SDRAM_MCOPT2, SDRAM_MCOPT2_IPTR_EXECUTE);	do {		mfsdram(SDRAM_MCSTAT, reg);	} while (!(reg & SDRAM_MCSTAT_MIC_COMP));	mfsdram(SDRAM_MCOPT2, reg);	mtsdram(SDRAM_MCOPT2, reg | SDRAM_MCOPT2_DCEN_ENABLE);}static int ecc_check_status_reg(void){	u32 ecc_status;	/*	 * Compare suceeded, now check	 * if got ecc error. If got an	 * ecc error, then don't count	 * this as a passing value	 */	mfsdram(SDRAM_ECCCR, ecc_status);	if (ecc_status != 0x00000000) {		/* clear on error */		ecc_clear_status_reg();		/* ecc check failure */		return 0;	}	ecc_clear_status_reg();	sync();	return 1;}/* return 1 if passes, 0 if fail */static int short_mem_test(u32 *base_address){	int i, j, l;	u32 ecc_mode = 0;	ulong test[NUMMEMTESTS][NUMMEMWORDS] = {	/* 0 */	{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,		 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,		 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,		 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},	/* 1 */	{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,		 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,		 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,		 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},	/* 2 */	{0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,		 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,		 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,		 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},	/* 3 */	{0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,		 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,		 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,		 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},	/* 4 */	{0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,		 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,		 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,		 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},	/* 5 */	{0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,		 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,		 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,		 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},	/* 6 */	{0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,		 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,		 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,		 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},	/* 7 */	{0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,		 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,		 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,		 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55},#if defined(CFG_DECREMENT_PATTERNS)	/* 8 */	{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,		 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,		 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,		 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},	/* 9 */	{0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,		 0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,		 0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,		 0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe},	/* 10 */{0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,		 0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,		 0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,		 0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd},	/* 11 */{0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,		 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,		 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,		 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc},	/* 12 */{0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,		 0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,		 0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,		 0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb},	/* 13 */{0xfffafffa, 0xfffafffa, 0xfffffffa, 0xfffafffa,		 0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa,		 0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa,		 0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa},	/* 14 */{0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,		 0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,		 0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,		 0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9},	/* 15 */{0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,		 0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,		 0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,		 0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8},	/* 16 */{0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,		 0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,		 0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,		 0xfff7ffff, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7},	/* 17 */{0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,		 0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,		 0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,		 0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7},	/* 18 */{0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,		 0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,		 0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,		 0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5},	/* 19 */{0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,		 0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,		 0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,		 0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4},	/* 20 */{0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,		 0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,		 0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,		 0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3},	/* 21 */{0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,		 0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,		 0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,		 0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2},	/* 22 */{0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,		 0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,		 0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,		 0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1},	/* 23 */{0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,		 0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,		 0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,		 0xfff0fff0, 0xfff0fffe, 0xfff0fff0, 0xfff0fff0},#endif /* CFG_DECREMENT_PATTERNS */								 };	mfsdram(SDRAM_MCOPT1, ecc_mode);	if ((ecc_mode & SDRAM_MCOPT1_MCHK_CHK_REP) ==						SDRAM_MCOPT1_MCHK_CHK_REP) {		ecc_clear_status_reg();		sync();		ecc_mode = 1;	} else {		ecc_mode = 0;	}	/*	 * Run the short memory test.	 */	for (i = 0; i < NUMMEMTESTS; i++) {		for (j = 0; j < NUMMEMWORDS; j++) {			base_address[j] = test[i][j];			ppcDcbf((ulong)&(base_address[j]));		}		sync();		for (l = 0; l < NUMLOOPS; l++) {			for (j = 0; j < NUMMEMWORDS; j++) {				if (base_address[j] != test[i][j]) {					ppcDcbf((u32)&(base_address[j]));					return 0;				} else {					if (ecc_mode) {						if (!ecc_check_status_reg())							return 0;					}				}				ppcDcbf((u32)&(base_address[j]));			} /* for (j = 0; j < NUMMEMWORDS; j++) */			sync();		} /* for (l=0; l<NUMLOOPS; l++) */	}	return 1;}#if defined(CONFIG_PPC4xx_DDR_METHOD_A)/*-----------------------------------------------------------------------------+| program_DQS_calibration_methodA.+-----------------------------------------------------------------------------*/static u32 program_DQS_calibration_methodA(struct ddrautocal *ddrcal){	u32 pass_result = 0;#ifdef DEBUG	ulong temp;	mfsdram(SDRAM_RDCC, temp);	debug("<%s>SDRAM_RDCC=0x%08x\n", __func__, temp);#endif	pass_result = DQS_calibration_methodA(ddrcal);	return pass_result;}/* * DQS_calibration_methodA() * * Autocalibration Method A * *  ARRAY [Entire DQS Range] DQS_Valid_Window ;    initialized to all zeros *  ARRAY [Entire FDBK Range] FDBK_Valid_Window;   initialized to all zeros *  MEMWRITE(addr, expected_data); *  for (i = 0; i < Entire DQS Range; i++) {       RQDC.RQFD *      for (j = 0; j < Entire FDBK Range; j++) {  RFDC.RFFD *         MEMREAD(addr, actual_data); *         if (actual_data == expected_data) { *             DQS_Valid_Window[i] = 1;            RQDC.RQFD *             FDBK_Valid_Window[i][j] = 1;        RFDC.RFFD *         } *      } *  } */static u32 DQS_calibration_methodA(struct ddrautocal *cal){	ulong rfdc_reg;	ulong rffd;	ulong rqdc_reg;	ulong rqfd;	u32 *membase;	ulong bxcf;	int rqfd_average;

⌨️ 快捷键说明

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