diff options
Diffstat (limited to 'cpu/mpc85xx')
| -rw-r--r-- | cpu/mpc85xx/cpu.c | 21 | ||||
| -rw-r--r-- | cpu/mpc85xx/cpu_init.c | 42 | ||||
| -rw-r--r-- | cpu/mpc85xx/spd_sdram.c | 1092 | ||||
| -rw-r--r-- | cpu/mpc85xx/start.S | 6 | ||||
| -rw-r--r-- | cpu/mpc85xx/tsec.c | 48 | ||||
| -rw-r--r-- | cpu/mpc85xx/tsec.h | 10 | 
6 files changed, 974 insertions, 245 deletions
| diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 4a1ccb05b..f7fe22e3e 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -38,6 +38,7 @@ int checkcpu (void)  	uint lcrr;		/* local bus clock ratio register */  	uint clkdiv;		/* clock divider portion of lcrr */  	uint pvr, svr; +	uint fam;  	uint ver;  	uint major, minor; @@ -60,6 +61,12 @@ int checkcpu (void)  	case SVR_8560:  		puts("8560");  		break; +	case SVR_8548: +		puts("8548"); +		break; +	case SVR_8548_E: +		puts("8548_E"); +		break;  	default:  		puts("Unknown");  		break; @@ -67,13 +74,14 @@ int checkcpu (void)  	printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);  	pvr = get_pvr(); +	fam = PVR_FAM(pvr);  	ver = PVR_VER(pvr);  	major = PVR_MAJ(pvr);  	minor = PVR_MIN(pvr);  	printf("Core:  "); -	switch (ver) { -	case PVR_VER(PVR_85xx): +	switch (fam) { +	case PVR_FAM(PVR_85xx):  	    puts("E500");  	    break;  	default: @@ -84,7 +92,7 @@ int checkcpu (void)  	get_sys_info(&sysinfo); -	puts("Clocks Configuration:\n"); +	puts("Clock Configuration:\n");  	printf("       CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);  	printf("CCB:%4lu MHz,\n", sysinfo.freqSystemBus / 1000000);  	printf("       DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000); @@ -101,6 +109,13 @@ int checkcpu (void)  #endif  	clkdiv = lcrr & 0x0f;  	if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { +#ifdef CONFIG_MPC8548 +		/* +		 * Yes, the entire PQ38 family use the same +		 * bit-representation for twice the clock divider values. +		 */ +		 clkdiv *= 2; +#endif  		printf("LBC:%4lu MHz\n",  		       sysinfo.freqSystemBus / 1000000 / clkdiv);  	} else { diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 79ea91f22..efde9cc31 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -178,42 +178,58 @@ void cpu_init_f (void)  #endif  } +  /* - * We initialize L2 as cache here. + * Initialize L2 as cache. + * + * The newer 8548, etc, parts have twice as much cache, but + * use the same bit-encoding as the older 8555, etc, parts. + * + * FIXME: Use PVR_VER(pvr) == 1 test here instead of SVR_VER()?   */ -int cpu_init_r (void) + +int cpu_init_r(void)  {  #if defined(CONFIG_L2_CACHE) -	volatile immap_t    *immap = (immap_t *)CFG_IMMR; +	volatile immap_t *immap = (immap_t *)CFG_IMMR;  	volatile ccsr_l2cache_t *l2cache = &immap->im_l2cache; -	volatile uint temp; +	volatile uint cache_ctl; +	uint svr, ver; + +	svr = get_svr(); +	ver = SVR_VER(svr);  	asm("msync;isync"); -	temp = l2cache->l2ctl; -	temp &= 0x30000000; -	switch ( temp ) { +	cache_ctl = l2cache->l2ctl; + +	switch (cache_ctl & 0x30000000) {  	case 0x20000000: -		printf ("L2 cache 256KB:"); +		if (ver == SVR_8548 || ver == SVR_8548_E) { +			printf ("L2 cache 512KB:"); +		} else { +			printf ("L2 cache 256KB:"); +		}  		break;  	case 0x00000000:  	case 0x10000000:  	case 0x30000000:  	default: -		printf ("L2 cache unknown size. Check the silicon!\n"); +		printf ("L2 cache unknown size (0x%08x)\n", cache_ctl);  		return -1;  	}  	asm("msync;isync");  	l2cache->l2ctl = 0x68000000; /* invalidate */ -	temp = l2cache->l2ctl; +	cache_ctl = l2cache->l2ctl;  	asm("msync;isync"); +  	l2cache->l2ctl = 0xa8000000; /* enable 256KB L2 cache */ -	temp = l2cache->l2ctl; +	cache_ctl = l2cache->l2ctl;  	asm("msync;isync"); -	printf("enabled\n"); +	printf(" enabled\n");  #else -	printf("L2:    disabled.\n"); +	printf("L2 cache: disabled\n");  #endif  	return 0; diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c index 5a1dbe2b5..049ba67e4 100644 --- a/cpu/mpc85xx/spd_sdram.c +++ b/cpu/mpc85xx/spd_sdram.c @@ -28,10 +28,11 @@  #include <spd.h>  #include <asm/mmu.h> -#if defined(CONFIG_DDR_ECC) -extern void dma_init (void); + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +extern void dma_init(void);  extern uint dma_check(void); -extern int  dma_xfer (void *dest, uint count, void *src); +extern int dma_xfer(void *dest, uint count, void *src);  #endif  #ifdef CONFIG_SPD_EEPROM @@ -40,6 +41,9 @@ extern int  dma_xfer (void *dest, uint count, void *src);  #define CFG_READ_SPD	i2c_read  #endif +static unsigned int setup_laws_and_tlbs(unsigned int memsize); + +  /*   * Convert picoseconds into clock cycles (rounding up if needed).   */ @@ -57,311 +61,829 @@ picos_to_clk(int picos)  	return clks;  } + +/* + * Calculate the Density of each Physical Rank. + * Returned size is in bytes. + * + * Study these table from Byte 31 of JEDEC SPD Spec. + * + *		DDR I	DDR II + *	Bit	Size	Size + *	---	-----	------ + *	7 high	512MB	512MB + *	6	256MB	256MB + *	5	128MB	128MB + *	4	 64MB	 16GB + *	3	 32MB	  8GB + *	2	 16MB	  4GB + *	1	  2GB	  2GB + *	0 low	  1GB	  1GB + * + * Reorder Table to be linear by stripping the bottom + * 2 or 5 bits off and shifting them up to the top. + */ +  unsigned int -banksize(unsigned char row_dens) +compute_banksize(unsigned int mem_type, unsigned char row_dens)  { -	return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24; +	unsigned int bsize; + +	if (mem_type == SPD_MEMTYPE_DDR) { +		/* Bottom 2 bits up to the top. */ +		bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24; +		debug("DDR: DDR I rank density = 0x%08x\n", bsize); +	} else { +		/* Bottom 5 bits up to the top. */ +		bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27; +		debug("DDR: DDR II rank density = 0x%08x\n", bsize); +	} +	return bsize;  } + +/* + * Convert a two-nibble BCD value into a cycle time. + * While the spec calls for nano-seconds, picos are returned. + * + * This implements the tables for bytes 9, 23 and 25 for both + * DDR I and II.  No allowance for distinguishing the invalid + * fields absent for DDR I yet present in DDR II is made. + * (That is, cycle times of .25, .33, .66 and .75 ns are + * allowed for both DDR II and I.) + */ + +unsigned int +convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) +{ +	/* +	 * Table look up the lower nibble, allow DDR I & II. +	 */ +	unsigned int tenths_ps[16] = { +		0, +		100, +		200, +		300, +		400, +		500, +		600, +		700, +		800, +		900, +		250, +		330,	/* FIXME: Is 333 better/valid? */ +		660,	/* FIXME: Is 667 better/valid? */ +		750, +		0,	/* undefined */ +		0	/* undefined */ +	}; + +	unsigned int whole_ns = (spd_val & 0xF0) >> 4; +	unsigned int tenth_ns = spd_val & 0x0F; +	unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns]; + +	return ps; +} + +  long int  spd_sdram(void)  {  	volatile immap_t *immap = (immap_t *)CFG_IMMR;  	volatile ccsr_ddr_t *ddr = &immap->im_ddr; -	volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm; +	volatile ccsr_gur_t *gur = &immap->im_gur;  	spd_eeprom_t spd; -	unsigned tmp, tmp1; +	unsigned int n_ranks; +	unsigned int rank_density; +	unsigned int odt_rd_cfg, odt_wr_cfg; +	unsigned int odt_cfg, mode_odt_enable; +	unsigned int dqs_cfg; +	unsigned char twr_clk, twtr_clk, twr_auto_clk; +	unsigned int tCKmin_ps, tCKmax_ps; +	unsigned int max_data_rate, effective_data_rate; +	unsigned int busfreq; +	unsigned sdram_cfg;  	unsigned int memsize; -	unsigned int tlb_size; -	unsigned int law_size; -	unsigned char caslat; -	unsigned int ram_tlb_index; -	unsigned int ram_tlb_address; +	unsigned char caslat, caslat_ctrl; +	unsigned int trfc, trfc_clk, trfc_low, trfc_high; +	unsigned int trcd_clk; +	unsigned int trtp_clk; +	unsigned char cke_min_clk; +	unsigned char add_lat; +	unsigned char wr_lat; +	unsigned char wr_data_delay; +	unsigned char four_act; +	unsigned char cpo; +	unsigned char burst_len; +	unsigned int mode_caslat; +	unsigned char sdram_type; +	unsigned char d_init; -	CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd)); +	/* +	 * Read SPD information. +	 */ +	CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) &spd, sizeof(spd)); -	if (spd.nrows > 2) { -		puts("DDR:Only two chip selects are supported on ADS.\n"); +	/* +	 * Check for supported memory module types. +	 */ +	if (spd.mem_type != SPD_MEMTYPE_DDR && +	    spd.mem_type != SPD_MEMTYPE_DDR2) { +		printf("Unable to locate DDR I or DDR II module.\n" +		       "    Fundamental memory type is 0x%0x\n", +		       spd.mem_type);  		return 0;  	} -	if (spd.nrow_addr < 12 -	    || spd.nrow_addr > 14 -	    || spd.ncol_addr < 8 -	    || spd.ncol_addr > 11) { -		puts("DDR:Row or Col number unsupported.\n"); +	/* +	 * These test gloss over DDR I and II differences in interpretation +	 * of bytes 3 and 4, but irrelevantly.  Multiple asymmetric banks +	 * are not supported on DDR I; and not encoded on DDR II. +	 * +	 * Also note that the 8548 controller can support: +	 *    12 <= nrow <= 16 +	 * and +	 *     8 <= ncol <= 11 (still, for DDR) +	 *     6 <= ncol <=  9 (for FCRAM) +	 */ +	if (spd.nrow_addr < 12 || spd.nrow_addr > 14) { +		printf("DDR: Unsupported number of Row Addr lines: %d.\n", +		       spd.nrow_addr); +		return 0; +	} +	if (spd.ncol_addr < 8 || spd.ncol_addr > 11) { +		printf("DDR: Unsupported number of Column Addr lines: %d.\n", +		       spd.ncol_addr); +		return 0; +	} + +	/* +	 * Determine the number of physical banks controlled by +	 * different Chip Select signals.  This is not quite the +	 * same as the number of DIMM modules on the board.  Feh. +	 */ +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		n_ranks = spd.nrows; +	} else { +		n_ranks = (spd.nrows & 0x7) + 1; +	} + +	debug("DDR: number of ranks = %d\n", n_ranks); + +	if (n_ranks > 2) { +		printf("DDR: Only 2 chip selects are supported: %d\n", +		       n_ranks);  		return 0;  	} -	ddr->cs0_bnds = (banksize(spd.row_dens) >> 24) - 1; +	/* +	 * Adjust DDR II IO voltage biasing.  It just makes it work. +	 */ +	if (spd.mem_type == SPD_MEMTYPE_DDR2) { +		gur->ddrioovcr = (0 +				  | 0x80000000		/* Enable */ +				  | 0x10000000		/* VSEL to 1.8V */ +				  ); +	} + +	/* +	 * Determine the size of each Rank in bytes. +	 */ +	rank_density = compute_banksize(spd.mem_type, spd.row_dens); + + +	/* +	 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg +	 */ +	ddr->cs0_bnds = (rank_density >> 24) - 1; + +	/* +	 * ODT configuration recommendation from DDR Controller Chapter. +	 */ +	odt_rd_cfg = 0;			/* Never assert ODT */ +	odt_wr_cfg = 0;			/* Never assert ODT */ +	if (spd.mem_type == SPD_MEMTYPE_DDR2) { +		odt_wr_cfg = 1;		/* Assert ODT on writes to CS0 */ +#if 0 +		/* FIXME: How to determine the number of dimm modules? */ +		if (n_dimm_modules == 2) { +			odt_rd_cfg = 1;	/* Assert ODT on reads to CS0 */ +		} +#endif +	} +  	ddr->cs0_config = ( 1 << 31 +			    | (odt_rd_cfg << 20) +			    | (odt_wr_cfg << 16)  			    | (spd.nrow_addr - 12) << 8  			    | (spd.ncol_addr - 8) );  	debug("\n"); -	debug("cs0_bnds = 0x%08x\n",ddr->cs0_bnds); -	debug("cs0_config = 0x%08x\n",ddr->cs0_config); +	debug("DDR: cs0_bnds   = 0x%08x\n", ddr->cs0_bnds); +	debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config); -	if (spd.nrows == 2) { -		ddr->cs1_bnds = ( (banksize(spd.row_dens) >> 8) -				  | ((banksize(spd.row_dens) >> 23) - 1) ); +	if (n_ranks == 2) { +		/* +		 * Eg: Bounds: 0x0f00_0000 to 0x1e0000_0000, second 256 Meg +		 */ +		ddr->cs1_bnds = ( (rank_density >> 8) +				  | ((rank_density >> (24 - 1)) - 1) );  		ddr->cs1_config = ( 1<<31 -				    | (spd.nrow_addr-12) << 8 -				    | (spd.ncol_addr-8) ); -		debug("cs1_bnds = 0x%08x\n",ddr->cs1_bnds); -		debug("cs1_config = 0x%08x\n",ddr->cs1_config); +				    | (odt_rd_cfg << 20) +				    | (odt_wr_cfg << 16) +				    | (spd.nrow_addr - 12) << 8 +				    | (spd.ncol_addr - 8) ); +		debug("DDR: cs1_bnds   = 0x%08x\n", ddr->cs1_bnds); +		debug("DDR: cs1_config = 0x%08x\n", ddr->cs1_config);  	} -	if (spd.mem_type != 0x07) { -		puts("No DDR module found!\n"); + +	/* +	 * Find the largest CAS by locating the highest 1 bit +	 * in the spd.cas_lat field.  Translate it to a DDR +	 * controller field value: +	 * +	 *	CAS Lat	DDR I	DDR II	Ctrl +	 *	Clocks	SPD Bit	SPD Bit	Value +	 *	-------	-------	-------	----- +	 *	1.0	0		0001 +	 *	1.5	1		0010 +	 *	2.0	2	2	0011 +	 *	2.5	3		0100 +	 *	3.0	4	3	0101 +	 *	3.5	5		0110 +	 *	4.0		4	0111 +	 *	4.5			1000 +	 *	5.0		5	1001 +	 */ +	caslat = __ilog2(spd.cas_lat); +	if ((spd.mem_type == SPD_MEMTYPE_DDR) +	    && (caslat > 5)) { +		printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat); +		return 0; + +	} else if (spd.mem_type == SPD_MEMTYPE_DDR2 +		   && (caslat < 2 || caslat > 5)) { +		printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n", +		       spd.cas_lat);  		return 0;  	} +	debug("DDR: caslat SPD bit is %d\n", caslat);  	/* -	 * Figure out memory size in Megabytes. +	 * Calculate the Maximum Data Rate based on the Minimum Cycle time. +	 * The SPD clk_cycle field (tCKmin) is measured in tenths of +	 * nanoseconds and represented as BCD.  	 */ -	memsize = spd.nrows * banksize(spd.row_dens) / 0x100000; +	tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle); +	debug("DDR: tCKmin = %d ps\n", tCKmin_ps);  	/* -	 * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord. +	 * Double-data rate, scaled 1000 to picoseconds, and back down to MHz.  	 */ -	law_size = 19 + __ilog2(memsize); +	max_data_rate = 2 * 1000 * 1000 / tCKmin_ps; +	debug("DDR: Module max data rate = %d Mhz\n", max_data_rate); +  	/* -	 * Determine size of each TLB1 entry. +	 * Adjust the CAS Latency to allow for bus speeds that +	 * are slower than the DDR module.  	 */ -	switch (memsize) { -	case 16: -	case 32: -		tlb_size = BOOKE_PAGESZ_16M; -		break; -	case 64: -	case 128: -		tlb_size = BOOKE_PAGESZ_64M; -		break; -	case 256: -	case 512: -	case 1024: -	case 2048: -		tlb_size = BOOKE_PAGESZ_256M; -		break; -	default: -		puts("DDR: only 16M,32M,64M,128M,256M,512M,1G and 2G DDR I are supported.\n"); +	busfreq = get_bus_freq(0) / 1000000;	/* MHz */ + +	effective_data_rate = max_data_rate; +	if (busfreq < 90) { +		/* DDR rate out-of-range */ +		puts("DDR: platform frequency is not fit for DDR rate\n"); +		return 0; + +	} else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) { +		/* +		 * busfreq 90~230 range, treated as DDR 200. +		 */ +		effective_data_rate = 200; +		if (spd.clk_cycle3 == 0xa0)	/* 10 ns */ +			caslat -= 2; +		else if (spd.clk_cycle2 == 0xa0) +			caslat--; + +	} else if (230 <= busfreq && busfreq < 280 && max_data_rate >= 280) { +		/* +		 * busfreq 230~280 range, treated as DDR 266. +		 */ +		effective_data_rate = 266; +		if (spd.clk_cycle3 == 0x75)	/* 7.5 ns */ +			caslat -= 2; +		else if (spd.clk_cycle2 == 0x75) +			caslat--; + +	} else if (280 <= busfreq && busfreq < 350 && max_data_rate >= 350) { +		/* +		 * busfreq 280~350 range, treated as DDR 333. +		 */ +		effective_data_rate = 333; +		if (spd.clk_cycle3 == 0x60)	/* 6.0 ns */ +			caslat -= 2; +		else if (spd.clk_cycle2 == 0x60) +			caslat--; + +	} else if (350 <= busfreq && busfreq < 460 && max_data_rate >= 460) { +		/* +		 * busfreq 350~460 range, treated as DDR 400. +		 */ +		effective_data_rate = 400; +		if (spd.clk_cycle3 == 0x50)	/* 5.0 ns */ +			caslat -= 2; +		else if (spd.clk_cycle2 == 0x50) +			caslat--; + +	} else if (460 <= busfreq && busfreq < 560 && max_data_rate >= 560) { +		/* +		 * busfreq 460~560 range, treated as DDR 533. +		 */ +		effective_data_rate = 533; +		if (spd.clk_cycle3 == 0x3D)	/* 3.75 ns */ +			caslat -= 2; +		else if (spd.clk_cycle2 == 0x3D) +			caslat--; + +	} else if (560 <= busfreq && busfreq < 700 && max_data_rate >= 700) { +		/* +		 * busfreq 560~700 range, treated as DDR 667. +		 */ +		effective_data_rate = 667; +		if (spd.clk_cycle3 == 0x30)	/* 3.0 ns */ +			caslat -= 2; +		else if (spd.clk_cycle2 == 0x30) +			caslat--; + +	} else if (700 <= busfreq) { +		/* +		 * DDR rate out-of-range +		 */ +		printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n", +		     busfreq, max_data_rate);  		return 0; -		break;  	} +  	/* -	 * Configure DDR TLB1 entries. -	 * Starting at TLB1 8, use no more than 8 TLB1 entries. +	 * Convert caslat clocks to DDR controller value. +	 * Force caslat_ctrl to be DDR Controller field-sized.  	 */ -	ram_tlb_index = 8; -	ram_tlb_address = (unsigned int)CFG_DDR_SDRAM_BASE; -	while (ram_tlb_address < (memsize * 1024 * 1024) -	      && ram_tlb_index < 16) { -		mtspr(MAS0, TLB1_MAS0(1, ram_tlb_index, 0)); -		mtspr(MAS1, TLB1_MAS1(1, 1, 0, 0, tlb_size)); -		mtspr(MAS2, TLB1_MAS2(E500_TLB_EPN(ram_tlb_address), -				      0, 0, 0, 0, 0, 0, 0, 0)); -		mtspr(MAS3, TLB1_MAS3(E500_TLB_RPN(ram_tlb_address), -				      0, 0, 0, 0, 0, 1, 0, 1, 0, 1)); -		asm volatile("isync;msync;tlbwe;isync"); +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		caslat_ctrl = (caslat + 1) & 0x07; +	} else { +		caslat_ctrl =  (2 * caslat - 1) & 0x0f; +	} -		debug("DDR:MAS0=0x%08x\n", TLB1_MAS0(1, ram_tlb_index, 0)); -		debug("DDR:MAS1=0x%08x\n", TLB1_MAS1(1, 1, 0, 0, tlb_size)); -		debug("DDR:MAS2=0x%08x\n", -		      TLB1_MAS2(E500_TLB_EPN(ram_tlb_address), -				0, 0, 0, 0, 0, 0, 0, 0)); -		debug("DDR:MAS3=0x%08x\n", -		      TLB1_MAS3(E500_TLB_RPN(ram_tlb_address), -				0, 0, 0, 0, 0, 1, 0, 1, 0, 1)); +	debug("DDR: effective data rate is %d MHz\n", effective_data_rate); +	debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n", +	      caslat, caslat_ctrl); -		ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2)); -		ram_tlb_index++; +	/* +	 * Timing Config 0. +	 * Avoid writing for DDR I.  The new PQ38 DDR controller +	 * dreams up non-zero default values to be backwards compatible. +	 */ +	if (spd.mem_type == SPD_MEMTYPE_DDR2) { +		unsigned char taxpd_clk = 8;		/* By the book. */ +		unsigned char tmrd_clk = 2;		/* By the book. */ +		unsigned char act_pd_exit = 2;		/* Empirical? */ +		unsigned char pre_pd_exit = 6;		/* Empirical? */ + +		ddr->timing_cfg_0 = (0 +			| ((act_pd_exit & 0x7) << 20)	/* ACT_PD_EXIT */ +			| ((pre_pd_exit & 0x7) << 16)	/* PRE_PD_EXIT */ +			| ((taxpd_clk & 0xf) << 8)	/* ODT_PD_EXIT */ +			| ((tmrd_clk & 0xf) << 0)	/* MRS_CYC */ +			); +#if 0 +		ddr->timing_cfg_0 |= 0xaa000000;	/* extra cycles */ +#endif +		debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); + +	} else { +#if 0 +		/* +		 * Force extra cycles with 0xaa bits. +		 * Incidentally supply the dreamt-up backwards compat value! +		 */ +		ddr->timing_cfg_0 = 0x00110105;	/* backwards compat value */ +		ddr->timing_cfg_0 |= 0xaa000000;	/* extra cycles */ +		debug("DDR: HACK timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); +#endif  	} +  	/* -	 * Set up LAWBAR for all of DDR. +	 * Some Timing Config 1 values now. +	 * Sneak Extended Refresh Recovery in here too.  	 */ -	ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff); -	ecm->lawar1 = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size)); -	debug("DDR:LAWBAR1=0x%08x\n", ecm->lawbar1); -	debug("DDR:LARAR1=0x%08x\n", ecm->lawar1);  	/* -	 * find the largest CAS +	 * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD, +	 * use conservative value. +	 * For DDR II, they are bytes 36 and 37, in quarter nanos.  	 */ -	if(spd.cas_lat & 0x40) { -		caslat = 7; -	} else if (spd.cas_lat & 0x20) { -		caslat = 6; -	} else if (spd.cas_lat & 0x10) { -		caslat = 5; -	} else if (spd.cas_lat & 0x08) { -		caslat = 4; -	} else if (spd.cas_lat & 0x04) { -		caslat = 3; -	} else if (spd.cas_lat & 0x02) { -		caslat = 2; -	} else if (spd.cas_lat & 0x01) { -		caslat = 1; + +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		twr_clk = 3;	/* Clocks */ +		twtr_clk = 1;	/* Clocks */  	} else { -		puts("DDR:no valid CAS Latency information.\n"); -		return 0; +		twr_clk = picos_to_clk(spd.twr * 250); +		twtr_clk = picos_to_clk(spd.twtr * 250);  	} -	tmp = 20000 / (((spd.clk_cycle & 0xF0) >> 4) * 10 -		       + (spd.clk_cycle & 0x0f)); -	debug("DDR:Module maximum data rate is: %dMhz\n", tmp); +	/* +	 * Calculate Trfc, in picos. +	 * DDR I:  Byte 42 straight up in ns. +	 * DDR II: Byte 40 and 42 swizzled some, in ns. +	 */ +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		trfc = spd.trfc * 1000;		/* up to ps */ +	} else { +		unsigned int byte40_table_ps[8] = { +			0, +			250, +			330, +			500, +			660, +			750, +			0, +			0 +		}; -	tmp1 = get_bus_freq(0) / 1000000; -	if (tmp1 < 230 && tmp1 >= 90 && tmp >= 230) { -		/* 90~230 range, treated as DDR 200 */ -		if (spd.clk_cycle3 == 0xa0) -			caslat -= 2; -		else if(spd.clk_cycle2 == 0xa0) -			caslat--; -	} else if (tmp1 < 280 && tmp1 >= 230 && tmp >= 280) { -		/* 230-280 range, treated as DDR 266 */ -		if (spd.clk_cycle3 == 0x75) -			caslat -= 2; -		else if (spd.clk_cycle2 == 0x75) -			caslat--; -	} else if (tmp1 < 350 && tmp1 >= 280 && tmp >= 350) { -		/* 280~350 range, treated as DDR 333 */ -		if (spd.clk_cycle3 == 0x60) -			caslat -= 2; -		else if (spd.clk_cycle2 == 0x60) -			caslat--; -	} else if (tmp1 < 90 || tmp1 >= 350) { -		/* DDR rate out-of-range */ -		puts("DDR:platform frequency is not fit for DDR rate\n"); -		return 0; +		trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000 +			+ byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7];  	} +	trfc_clk = picos_to_clk(trfc);  	/* -	 * note: caslat must also be programmed into ddr->sdram_mode -	 * register. -	 * -	 * note: WRREC(Twr) and WRTORD(Twtr) are not in SPD, -	 * use conservative value here. +	 * Trcd, Byte 29, from quarter nanos to ps and clocks. +	 */ +	trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7; + +	/* +	 * Convert trfc_clk to DDR controller fields.  DDR I should +	 * fit in the REFREC field (16-19) of TIMING_CFG_1, but the +	 * 8548 controller has an extended REFREC field of three bits. +	 * The controller automatically adds 8 clocks to this value, +	 * so preadjust it down 8 first before splitting it up. +	 */ +	trfc_low = (trfc_clk - 8) & 0xf; +	trfc_high = ((trfc_clk - 8) >> 4) & 0x3; + +	/* +	 * Sneak in some Extended Refresh Recovery.  	 */ +	ddr->ext_refrec = (trfc_high << 16); +	debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec); +  	ddr->timing_cfg_1 = -	    (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) | -	     ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) | -	     ((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) | -	     ((caslat & 0x07) << 16 ) | -	     (((picos_to_clk(spd.sset[6] * 1000) - 8) & 0x0f) << 12 ) | -	     ( 0x300 ) | -	     ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1); +	    (0 +	     | ((picos_to_clk(spd.trp * 250) & 0x07) << 28)	/* PRETOACT */ +	     | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24)	/* ACTTOPRE */ +	     | (trcd_clk << 20)					/* ACTTORW */ +	     | (caslat_ctrl << 16)				/* CASLAT */ +	     | (trfc_low << 12)					/* REFEC */ +	     | ((twr_clk & 0x07) << 8)				/* WRRREC */ +	     | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4)	/* ACTTOACT */ +	     | ((twtr_clk & 0x07) << 0)				/* WRTORD */ +	     ); -	ddr->timing_cfg_2 = 0x00000800; +	debug("DDR: timing_cfg_1  = 0x%08x\n", ddr->timing_cfg_1); -	debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1); -	debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);  	/* -	 * Only DDR I is supported -	 * DDR I and II have different mode-register-set definition +	 * Timing_Config_2 +	 * Was: 0x00000800;  	 */ -	/* burst length is always 4 */ -	switch(caslat) { -	case 2: -		ddr->sdram_mode = 0x52; /* 1.5 */ -		break; -	case 3: -		ddr->sdram_mode = 0x22; /* 2.0 */ -		break; -	case 4: -		ddr->sdram_mode = 0x62; /* 2.5 */ -		break; -	case 5: -		ddr->sdram_mode = 0x32; /* 3.0 */ -		break; -	default: -		puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n"); -		return 0; +	/* +	 * Additive Latency +	 * For DDR I, 0. +	 * For DDR II, with ODT enabled, use "a value" less than ACTTORW, +	 * which comes from Trcd, and also note that: +	 *	add_lat + caslat must be >= 4 +	 */ +	add_lat = 0; +	if (spd.mem_type == SPD_MEMTYPE_DDR2 +	    && (odt_wr_cfg || odt_rd_cfg) +	    && (caslat < 4)) { +		add_lat = 4 - caslat; +		if (add_lat > trcd_clk) { +			add_lat = trcd_clk - 1; +		}  	} -	debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode); -	switch(spd.refresh) { -	case 0x00: -	case 0x80: -		tmp = picos_to_clk(15625000); -		break; -	case 0x01: -	case 0x81: -		tmp = picos_to_clk(3900000); -		break; -	case 0x02: -	case 0x82: -		tmp = picos_to_clk(7800000); -		break; -	case 0x03: -	case 0x83: -		tmp = picos_to_clk(31300000); -		break; -	case 0x04: -	case 0x84: -		tmp = picos_to_clk(62500000); -		break; -	case 0x05: -	case 0x85: -		tmp = picos_to_clk(125000000); -		break; -	default: -		tmp = 0x512; -		break; +	/* +	 * Write Data Delay +	 * Historically 0x2 == 4/8 clock delay. +	 * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266. +	 */ +	wr_data_delay = 3; + +	/* +	 * Write Latency +	 * Read to Precharge +	 * Minimum CKE Pulse Width. +	 * Four Activate Window +	 */ +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		/* +		 * This is a lie.  It should really be 1, but if it is +		 * set to 1, bits overlap into the old controller's +		 * otherwise unused ACSM field.  If we leave it 0, then +		 * the HW will magically treat it as 1 for DDR 1.  Oh Yea. +		 */ +		wr_lat = 0; + +		trtp_clk = 2;		/* By the book. */ +		cke_min_clk = 1;	/* By the book. */ +		four_act = 1;		/* By the book. */ + +	} else { +		wr_lat = caslat - 1; + +		/* Convert SPD value from quarter nanos to picos. */ +		trtp_clk = picos_to_clk(spd.trtp * 250); + +		cke_min_clk = 3;	/* By the book. */ +		four_act = picos_to_clk(37500);	/* By the book. 1k pages? */ +	} + +	/* +	 * Empirically set ~MCAS-to-preamble override for DDR 2. +	 * Your milage will vary. +	 */ +	cpo = 0; +	if (spd.mem_type == SPD_MEMTYPE_DDR2) { +		if (effective_data_rate == 266 || effective_data_rate == 333) { +			cpo = 0x7;		/* READ_LAT + 5/4 */ +		} else if (effective_data_rate == 400) { +			cpo = 0x9;		/* READ_LAT + 7/4 */ +		} else { +			/* Pure speculation */ +			cpo = 0xb; +		} +	} + +	ddr->timing_cfg_2 = (0 +		| ((add_lat & 0x7) << 28)		/* ADD_LAT */ +		| ((cpo & 0x1f) << 23)			/* CPO */  +		| ((wr_lat & 0x7) << 19)		/* WR_LAT */ +		| ((trtp_clk & 0x7) << 13)		/* RD_TO_PRE */ +		| ((wr_data_delay & 0x7) << 10)		/* WR_DATA_DELAY */ +		| ((cke_min_clk & 0x7) << 6)		/* CKE_PLS */ +		| ((four_act & 0x1f) << 0)		/* FOUR_ACT */ +		); + +	debug("DDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); + + +	/* +	 * Determine the Mode Register Set. +	 * +	 * This is nominally part specific, but it appears to be +	 * consistent for all DDR I devices, and for all DDR II devices. +	 * +	 *     caslat must be programmed +	 *     burst length is always 4 +	 *     burst type is sequential +	 * +	 * For DDR I: +	 *     operating mode is "normal" +	 * +	 * For DDR II: +	 *     other stuff +	 */ + +	mode_caslat = 0; + +	/* +	 * Table lookup from DDR I or II Device Operation Specs. +	 */ +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		if (1 <= caslat && caslat <= 4) { +			unsigned char mode_caslat_table[4] = { +				0x5,	/* 1.5 clocks */ +				0x2,	/* 2.0 clocks */ +				0x6,	/* 2.5 clocks */ +				0x3	/* 3.0 clocks */ +			}; +			mode_caslat = mode_caslat_table[caslat - 1]; +		} else { +			puts("DDR I: Only CAS Latencies of 1.5, 2.0, " +			     "2.5 and 3.0 clocks are supported.\n"); +			return 0; +		} + +	} else { +		if (2 <= caslat && caslat <= 5) { +			mode_caslat = caslat; +		} else { +			puts("DDR II: Only CAS Latencies of 2.0, 3.0, " +			     "4.0 and 5.0 clocks are supported.\n"); +			return 0; +		} +	} + +	/* +	 * Encoded Burst Lenght of 4. +	 */ +	burst_len = 2;			/* Fiat. */ + +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		twr_auto_clk = 0;	/* Historical */ +	} else { +		/* +		 * Determine tCK max in picos.  Grab tWR and convert to picos. +		 * Auto-precharge write recovery is: +		 *	WR = roundup(tWR_ns/tCKmax_ns). +		 * +		 * Ponder: Is twr_auto_clk different than twr_clk? +		 */ +		tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax); +		twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps; +	} + + +	/* +	 * Mode Reg in bits 16 ~ 31, +	 * Extended Mode Reg 1 in bits 0 ~ 15. +	 */ +	mode_odt_enable = 0x0;			/* Default disabled */ +	if (odt_wr_cfg || odt_rd_cfg) { +		/* +		 * Bits 6 and 2 in Extended MRS(1) +		 * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules. +		 * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module. +		 */ +		mode_odt_enable = 0x40;		/* 150 Ohm */  	} +	ddr->sdram_mode = +		(0 +		 | (add_lat << (16 + 3))	/* Additive Latency in EMRS1 */ +		 | (mode_odt_enable << 16)	/* ODT Enable in EMRS1 */ +		 | (twr_auto_clk << 9)		/* Write Recovery Autopre */ +		 | (mode_caslat << 4)		/* caslat */ +		 | (burst_len << 0)		/* Burst length */ +		 ); + +	debug("DDR: sdram_mode   = 0x%08x\n", ddr->sdram_mode); + + +	/* +	 * Clear EMRS2 and EMRS3. +	 */ +	ddr->sdram_mode_2 = 0; +	debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2); + +  	/* -	 * Set BSTOPRE to 0x100 for page mode -	 * If auto-charge is used, set BSTOPRE = 0 +	 * Determine Refresh Rate.  Ignore self refresh bit on DDR I. +	 * Table from SPD Spec, Byte 12, converted to picoseconds and +	 * filled in with "default" normal values.  	 */ -	ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100; -	debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval); +	{ +		unsigned int refresh_clk; +		unsigned int refresh_time_ns[8] = { +			15625000,	/* 0 Normal    1.00x */ +			3900000,	/* 1 Reduced    .25x */ +			7800000,	/* 2 Extended   .50x */ +			31300000,	/* 3 Extended  2.00x */ +			62500000,	/* 4 Extended  4.00x */ +			125000000,	/* 5 Extended  8.00x */ +			15625000,	/* 6 Normal    1.00x  filler */ +			15625000,	/* 7 Normal    1.00x  filler */ +		}; + +		refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]); + +		/* +		 * Set BSTOPRE to 0x100 for page mode +		 * If auto-charge is used, set BSTOPRE = 0 +		 */ +		ddr->sdram_interval = +			(0 +			 | (refresh_clk & 0x3fff) << 16 +			 | 0x100 +			 ); +		debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval); +	}  	/*  	 * Is this an ECC DDR chip? +	 * But don't mess with it if the DDR controller will init mem.  	 */ -#if defined(CONFIG_DDR_ECC) +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)  	if (spd.config == 0x02) {  		ddr->err_disable = 0x0000000d;  		ddr->err_sbe = 0x00ff0000;  	} -	debug("DDR:err_disable=0x%08x\n", ddr->err_disable); -	debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe); +	debug("DDR: err_disable = 0x%08x\n", ddr->err_disable); +	debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe);  #endif -	asm("sync;isync;msync"); +	asm("sync;isync;msync");  	udelay(500); -#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL -	/* Setup the clock control (8555 and later) -	 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 -	 * SDRAM_CLK_CNTL[5-7] = Clock Adjust == 3 (3/4 cycle late) +	/* +	 * SDRAM Cfg 2 +	 */ + +	/* +	 * When ODT is enabled, Chap 9 suggests asserting ODT to +	 * internal IOs only during reads. +	 */ +	odt_cfg = 0; +	if (odt_rd_cfg | odt_wr_cfg) { +		odt_cfg = 0x2;		/* ODT to IOs during reads */ +	} + +	/* +	 * Try to use differential DQS with DDR II.  	 */ -	ddr->sdram_clk_cntl = 0x83000000; +	if (spd.mem_type == SPD_MEMTYPE_DDR) { +		dqs_cfg = 0;		/* No Differential DQS for DDR I */ +	} else { +		dqs_cfg = 0x1;		/* Differential DQS for DDR II */ +	} + +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +	/* +	 * Use the DDR controller to auto initialize memory. +	 */ +	d_init = 1; +	ddr->sdram_data_init = CONFIG_MEM_INIT_VALUE; +	debug("DDR: ddr_data_init = 0x%08x\n", ddr->sdram_data_init); +#else +	/* +	 * Memory will be initialized via DMA, or not at all. +	 */ +	d_init = 0;	 +#endif + +	ddr->sdram_cfg_2 = (0 +			    | (dqs_cfg << 26)	/* Differential DQS */ +			    | (odt_cfg << 21)	/* ODT */ +			    | (d_init << 4)	/* D_INIT auto init DDR */ +			    ); + +	debug("DDR: sdram_cfg_2  = 0x%08x\n", ddr->sdram_cfg_2); + + +#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL +	{ +		unsigned char clk_adjust; + +		/* +		 * Setup the clock control. +		 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 +		 * SDRAM_CLK_CNTL[5-7] = Clock Adjust +		 *	0110	3/4 cycle late +		 *	0111	7/8 cycle late +		 */ +		if (spd.mem_type == SPD_MEMTYPE_DDR) { +			clk_adjust = 0x6; +		} else { +			clk_adjust = 0x7; +		} + +		ddr->sdram_clk_cntl = (0 +			       | 0x80000000 +			       | (clk_adjust << 23) +			       ); +		debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl); +	}  #endif  	/* -	 * Figure out the settings for the sdram_cfg register.  Build up -	 * the entire register in 'tmp' before writing since the write into -	 * the register will actually enable the memory controller, and all -	 * settings must be done before enabling. +	 * Figure out the settings for the sdram_cfg register. +	 * Build up the entire register in 'sdram_cfg' before writing +	 * since the write into the register will actually enable the +	 * memory controller; all settings must be done before enabling.  	 *  	 * sdram_cfg[0]   = 1 (ddr sdram logic enable)  	 * sdram_cfg[1]   = 1 (self-refresh-enable) -	 * sdram_cfg[6:7] = 2 (SDRAM type = DDR SDRAM) +	 * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM) +	 *			010 DDR 1 SDRAM +	 *			011 DDR 2 SDRAM  	 */ -	tmp = 0xc2000000; +	sdram_type = (spd.mem_type == SPD_MEMTYPE_DDR) ? 2 : 3; +	sdram_cfg = (0 +		     | (1 << 31)			/* Enable */ +		     | (1 << 30)			/* Self refresh */ +		     | (sdram_type << 24)		/* SDRAM type */ +		     );  	/*  	 * sdram_cfg[3] = RD_EN - registered DIMM enable  	 *   A value of 0x26 indicates micron registered DIMMS (micron.com)  	 */ -	if (spd.mod_attr == 0x26) { -		tmp |= 0x10000000; +	if (spd.mem_type == SPD_MEMTYPE_DDR && spd.mod_attr == 0x26) { +		sdram_cfg |= 0x10000000;		/* RD_EN */  	}  #if defined(CONFIG_DDR_ECC) @@ -369,7 +891,7 @@ spd_sdram(void)  	 * If the user wanted ECC (enabled via sdram_cfg[2])  	 */  	if (spd.config == 0x02) { -		tmp |= 0x20000000; +		sdram_cfg |= 0x20000000;		/* ECC_EN */  	}  #endif @@ -385,27 +907,160 @@ spd_sdram(void)  			/*  			 * Enable 2T timing by setting sdram_cfg[16].  			 */ -			tmp |= 0x8000; +			sdram_cfg |= 0x8000;		/* 2T_EN */  #endif  		}  	} -	ddr->sdram_cfg = tmp; +	/* +	 * 200 painful micro-seconds must elapse between +	 * the DDR clock setup and the DDR config enable. +	 */ +	udelay(200); + +	/* +	 * Go! +	 */ +	ddr->sdram_cfg = sdram_cfg;  	asm("sync;isync;msync");  	udelay(500); -	debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg); +	debug("DDR: sdram_cfg   = 0x%08x\n", ddr->sdram_cfg); + + +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +	/* +	 * Poll until memory is initialized. +	 * 512 Meg at 400 might hit this 200 times or so. +	 */ +	while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) { +		udelay(1000); +	} +#endif + + +	/* +	 * Figure out memory size in Megabytes. +	 */ +	memsize = n_ranks * rank_density / 0x100000; + +	/* +	 * Establish Local Access Window and TLB mappings for DDR memory. +	 */ +	memsize = setup_laws_and_tlbs(memsize); +	if (memsize == 0) { +		return 0; +	}  	return memsize * 1024 * 1024;  } + + +/* + * Setup Local Access Window and TLB1 mappings for the requested + * amount of memory.  Returns the amount of memory actually mapped + * (usually the original request size), or 0 on error. + */ + +static unsigned int +setup_laws_and_tlbs(unsigned int memsize) +{ +	volatile immap_t *immap = (immap_t *)CFG_IMMR; +	volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm; +	unsigned int tlb_size; +	unsigned int law_size; +	unsigned int ram_tlb_index; +	unsigned int ram_tlb_address; + +	/* +	 * Determine size of each TLB1 entry. +	 */ +	switch (memsize) { +	case 16: +	case 32: +		tlb_size = BOOKE_PAGESZ_16M; +		break; +	case 64: +	case 128: +		tlb_size = BOOKE_PAGESZ_64M; +		break; +	case 256: +	case 512: +	case 1024: +	case 2048: +		tlb_size = BOOKE_PAGESZ_256M; +		break; +	default: +		puts("DDR: only 16M,32M,64M,128M,256M,512M,1G and 2G are supported.\n"); + +		/* +		 * The memory was not able to be mapped. +		 */ +		return 0; +		break; +	} + +	/* +	 * Configure DDR TLB1 entries. +	 * Starting at TLB1 8, use no more than 8 TLB1 entries. +	 */ +	ram_tlb_index = 8; +	ram_tlb_address = (unsigned int)CFG_DDR_SDRAM_BASE; +	while (ram_tlb_address < (memsize * 1024 * 1024) +	      && ram_tlb_index < 16) { +		mtspr(MAS0, TLB1_MAS0(1, ram_tlb_index, 0)); +		mtspr(MAS1, TLB1_MAS1(1, 1, 0, 0, tlb_size)); +		mtspr(MAS2, TLB1_MAS2(E500_TLB_EPN(ram_tlb_address), +				      0, 0, 0, 0, 0, 0, 0, 0)); +		mtspr(MAS3, TLB1_MAS3(E500_TLB_RPN(ram_tlb_address), +				      0, 0, 0, 0, 0, 1, 0, 1, 0, 1)); +		asm volatile("isync;msync;tlbwe;isync"); + +		debug("DDR: MAS0=0x%08x\n", TLB1_MAS0(1, ram_tlb_index, 0)); +		debug("DDR: MAS1=0x%08x\n", TLB1_MAS1(1, 1, 0, 0, tlb_size)); +		debug("DDR: MAS2=0x%08x\n", +		      TLB1_MAS2(E500_TLB_EPN(ram_tlb_address), +				0, 0, 0, 0, 0, 0, 0, 0)); +		debug("DDR: MAS3=0x%08x\n", +		      TLB1_MAS3(E500_TLB_RPN(ram_tlb_address), +				0, 0, 0, 0, 0, 1, 0, 1, 0, 1)); + +		ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2)); +		ram_tlb_index++; +	} + + +	/* +	 * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23.  Fnord. +	 */ +	law_size = 19 + __ilog2(memsize); + +	/* +	 * Set up LAWBAR for all of DDR. +	 */ +	ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); +	ecm->lawar1 = (LAWAR_EN +		       | LAWAR_TRGT_IF_DDR +		       | (LAWAR_SIZE & law_size)); +	debug("DDR: LAWBAR1=0x%08x\n", ecm->lawbar1); +	debug("DDR: LARAR1=0x%08x\n", ecm->lawar1); + +	/* +	 * Confirm that the requested amount of memory was mapped. +	 */ +	return memsize; +} +  #endif /* CONFIG_SPD_EEPROM */ -#if defined(CONFIG_DDR_ECC) +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +  /*   * Initialize all of memory for ECC, then enable errors.   */ +  void  ddr_enable_ecc(unsigned int dram_size)  { @@ -420,7 +1075,7 @@ ddr_enable_ecc(unsigned int dram_size)  		if (((unsigned int)p & 0x1f) == 0) {  			ppcDcbz((unsigned long) p);  		} -		*p = (unsigned int)0xdeadbeef; +		*p = (unsigned int)CONFIG_MEM_INIT_VALUE;  		if (((unsigned int)p & 0x1c) == 0x1c) {  			ppcDcbf((unsigned long) p);  		} @@ -454,7 +1109,10 @@ ddr_enable_ecc(unsigned int dram_size)  	/*  	 * Enable errors for ECC.  	 */ +	debug("DMA DDR: err_disable = 0x%08x\n", ddr->err_disable);  	ddr->err_disable = 0x00000000;  	asm("sync;isync;msync"); +	debug("DMA DDR: err_disable = 0x%08x\n", ddr->err_disable);  } -#endif	/* CONFIG_DDR_ECC */ + +#endif	/* CONFIG_DDR_ECC  && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */ diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 7bca008b5..dd8189931 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -174,6 +174,9 @@ _start_e500:  	mtspr	BUCSR,r0	/* disable branch prediction */  	mtspr	MAS4,r0  	mtspr	MAS6,r0 +#if defined(CONFIG_ENABLE_36BIT_PHYS) +	mtspr	MAS7,r0 +#endif  	isync  	/* Setup interrupt vectors */ @@ -358,6 +361,9 @@ _start:  	/* Enable Time Base and Select Time Base Clock */  	lis	r0,HID0_EMCP@h		/* Enable machine check */  	ori	r0,r0,0x4000		/* time base is processor clock */ +#if defined(CONFIG_ENABLE_36BIT_PHYS) +	ori	r0,r0,0x0080		/* enable MAS7 updates */ +#endif  	mtspr	HID0,r0  #if defined(CONFIG_ADDR_STREAMING) diff --git a/cpu/mpc85xx/tsec.c b/cpu/mpc85xx/tsec.c index d327a6dec..5ac633432 100644 --- a/cpu/mpc85xx/tsec.c +++ b/cpu/mpc85xx/tsec.c @@ -35,7 +35,7 @@ typedef volatile struct rtxbd {  struct tsec_info_struct {  	unsigned int phyaddr; -	unsigned int gigabit; +	u32 flags;  	unsigned int phyregidx;  }; @@ -48,8 +48,9 @@ struct tsec_info_struct {   *  phyaddr - The address of the PHY which is attached to   *	the given device.   * - *  gigabit - This variable indicates whether the device - *	supports gigabit speed ethernet + *  flags - This variable indicates whether the device + *	supports gigabit speed ethernet, and whether it should be + *	in reduced mode.   *   *  phyregidx - This variable specifies which ethernet device   *	controls the MII Management registers which are connected @@ -70,23 +71,32 @@ struct tsec_info_struct {   */  static struct tsec_info_struct tsec_info[] = {  #ifdef CONFIG_MPC85XX_TSEC1 -	{TSEC1_PHY_ADDR, 1, TSEC1_PHYIDX}, +	{TSEC1_PHY_ADDR, TSEC_GIGABIT, TSEC1_PHYIDX},  #else  	{ 0, 0, 0},  #endif  #ifdef CONFIG_MPC85XX_TSEC2 -	{TSEC2_PHY_ADDR, 1, TSEC2_PHYIDX}, +	{TSEC2_PHY_ADDR, TSEC_GIGABIT, TSEC2_PHYIDX},  #else  	{ 0, 0, 0},  #endif  #ifdef CONFIG_MPC85XX_FEC  	{FEC_PHY_ADDR, 0, FEC_PHYIDX},  #else +#    ifdef CONFIG_MPC85XX_TSEC3 +	{TSEC3_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC3_PHYIDX}, +#    else  	{ 0, 0, 0}, +#    endif +#    ifdef CONFIG_MPC85XX_TSEC4 +	{TSEC4_PHY_ADDR, TSEC_REDUCED, TSEC4_PHYIDX}, +#    else +	{ 0, 0, 0}, +#    endif  #endif  }; -#define MAXCONTROLLERS 3 +#define MAXCONTROLLERS	(4)  static int relocated = 0; @@ -115,7 +125,7 @@ static void relocate_cmds(void);  /* Initialize device structure. Returns success if PHY   * initialization succeeded (i.e. if it recognizes the PHY)   */ -int tsec_initialize(bd_t *bis, int index) +int tsec_initialize(bd_t *bis, int index, char *devname)  {  	struct eth_device* dev;  	int i; @@ -139,9 +149,9 @@ int tsec_initialize(bd_t *bis, int index)  			tsec_info[index].phyregidx*TSEC_SIZE);  	priv->phyaddr = tsec_info[index].phyaddr; -	priv->gigabit = tsec_info[index].gigabit; +	priv->flags = tsec_info[index].flags; -	sprintf(dev->name, "ENET%d", index); +	sprintf(dev->name, devname);  	dev->iobase = 0;  	dev->priv   = priv;  	dev->init   = tsec_init; @@ -318,7 +328,7 @@ static int init_phy(struct eth_device *dev)  /* For 10/100, the value is slightly different */  uint mii_cr_init(uint mii_reg, struct tsec_private *priv)  { -	if(priv->gigabit) +	if(priv->flags & TSEC_GIGABIT)  		return MIIM_CONTROL_INIT;  	else  		return MIIM_CR_INIT; @@ -438,6 +448,13 @@ uint mii_cis8204_fixled(uint mii_reg, struct tsec_private *priv)  	return MIIM_CIS8204_SLEDCON_INIT;  } +uint mii_cis8204_setmode(uint mii_reg, struct tsec_private *priv) +{ +	if (priv->flags & TSEC_REDUCED) +		return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII; +	else +		return MIIM_CIS8204_EPHYCON_INIT; +}  /* Initialized required registers to appropriate values, zeroing   * those we don't care about (unless zero is bad, in which case, @@ -507,6 +524,15 @@ static void adjust_link(struct eth_device *dev)  			case 10:  				regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF))  					| MACCFG2_MII); + +				/* If We're in reduced mode, we +				 * need to say whether we're 10 +				 * or 100 MB. */ +				if ((priv->speed == 100)  +						&& (priv->flags & TSEC_REDUCED)) +					regs->ecntrl |= ECNTRL_R100; +				else +					regs->ecntrl &= ~(ECNTRL_R100);  				break;  			default:  				printf("%s: Speed was bad\n", dev->name); @@ -731,7 +757,7 @@ struct phy_info phy_info_cis8204 = {  		/* Configure some basic stuff */  		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},  		{MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT, &mii_cis8204_fixled}, -		{MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, NULL}, +		{MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, &mii_cis8204_setmode},  		{miim_end,}  	},  	(struct phy_cmd[]) { /* startup */ diff --git a/cpu/mpc85xx/tsec.h b/cpu/mpc85xx/tsec.h index e24351a2e..d1c70aa89 100644 --- a/cpu/mpc85xx/tsec.h +++ b/cpu/mpc85xx/tsec.h @@ -51,6 +51,7 @@  #define ECNTRL_INIT_SETTINGS	0x00001000  #define ECNTRL_TBI_MODE         0x00000020 +#define ECNTRL_R100		0x00000008  #define miim_end -2  #define miim_read -1 @@ -107,6 +108,7 @@  /* Cicada 8204 Extended PHY Control Register 1 */  #define MIIM_CIS8204_EPHY_CON		0x17  #define MIIM_CIS8204_EPHYCON_INIT	0x0006 +#define MIIM_CIS8204_EPHYCON_RGMII	0x1000  /* Cicada 8204 Serial LED Control Register */  #define MIIM_CIS8204_SLED_CON		0x1b @@ -424,12 +426,18 @@ typedef struct tsec  	uint	resc00[256];  } tsec_t; +#define TSEC_GIGABIT (1) + +/* This flag currently only has + * meaning if we're using the eTSEC */ +#define TSEC_REDUCED (1 << 1) +  struct tsec_private {  	volatile tsec_t *regs;  	volatile tsec_t *phyregs;  	struct phy_info *phyinfo;  	uint phyaddr; -	uint gigabit; +	u32 flags;  	uint link;  	uint duplexity;  	uint speed; |