diff options
Diffstat (limited to 'cpu/ppc4xx/44x_spd_ddr2.c')
| -rw-r--r-- | cpu/ppc4xx/44x_spd_ddr2.c | 366 | 
1 files changed, 128 insertions, 238 deletions
| diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 2ab23365a..397530640 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -9,7 +9,7 @@   * Copyright (c) 2008 Nuovation System Designs, LLC   *   Grant Erickson <gerickson@nuovations.com> - * (C) Copyright 2007-2008 + * (C) Copyright 2007-2009   * Stefan Roese, DENX Software Engineering, sr@denx.de.   *   * COPYRIGHT   AMCC   CORPORATION 2004 @@ -86,8 +86,133 @@  /* disable caching on SDRAM */  #define MY_TLB_WORD2_I_ENABLE		TLB_WORD2_I_ENABLE  #endif /* CONFIG_4xx_DCACHE */ + +void dcbz_area(u32 start_address, u32 num_bytes);  #endif /* CONFIG_440 */ +#define MAXRANKS	4 +#define MAXBXCF		4 + +#define MULDIV64(m1, m2, d)	(u32)(((u64)(m1) * (u64)(m2)) / (u64)(d)) + +#if !defined(CONFIG_NAND_SPL) +/*-----------------------------------------------------------------------------+ + * sdram_memsize + *-----------------------------------------------------------------------------*/ +phys_size_t sdram_memsize(void) +{ +	phys_size_t mem_size; +	unsigned long mcopt2; +	unsigned long mcstat; +	unsigned long mb0cf; +	unsigned long sdsz; +	unsigned long i; + +	mem_size = 0; + +	mfsdram(SDRAM_MCOPT2, mcopt2); +	mfsdram(SDRAM_MCSTAT, mcstat); + +	/* DDR controller must be enabled and not in self-refresh. */ +	/* Otherwise memsize is zero. */ +	if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE) +	    && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT) +	    && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK)) +		== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) { +		for (i = 0; i < MAXBXCF; i++) { +			mfsdram(SDRAM_MB0CF + (i << 2), mb0cf); +			/* Banks enabled */ +			if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { +#if defined(CONFIG_440) +				sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK; +#else +				sdsz = mb0cf & SDRAM_RXBAS_SDSZ_MASK; +#endif +				switch(sdsz) { +				case SDRAM_RXBAS_SDSZ_8: +					mem_size+=8; +					break; +				case SDRAM_RXBAS_SDSZ_16: +					mem_size+=16; +					break; +				case SDRAM_RXBAS_SDSZ_32: +					mem_size+=32; +					break; +				case SDRAM_RXBAS_SDSZ_64: +					mem_size+=64; +					break; +				case SDRAM_RXBAS_SDSZ_128: +					mem_size+=128; +					break; +				case SDRAM_RXBAS_SDSZ_256: +					mem_size+=256; +					break; +				case SDRAM_RXBAS_SDSZ_512: +					mem_size+=512; +					break; +				case SDRAM_RXBAS_SDSZ_1024: +					mem_size+=1024; +					break; +				case SDRAM_RXBAS_SDSZ_2048: +					mem_size+=2048; +					break; +				case SDRAM_RXBAS_SDSZ_4096: +					mem_size+=4096; +					break; +				default: +					printf("WARNING: Unsupported bank size (SDSZ=0x%lx)!\n" +					       , sdsz); +					mem_size=0; +					break; +				} +			} +		} +	} + +	return mem_size << 20; +} + +/*-----------------------------------------------------------------------------+ + * is_ecc_enabled + *-----------------------------------------------------------------------------*/ +static unsigned long is_ecc_enabled(void) +{ +	unsigned long val; + +	mfsdram(SDRAM_MCOPT1, val); + +	return SDRAM_MCOPT1_MCHK_CHK_DECODE(val); +} + +/*-----------------------------------------------------------------------------+ + * board_add_ram_info + *-----------------------------------------------------------------------------*/ +void board_add_ram_info(int use_default) +{ +	PPC4xx_SYS_INFO board_cfg; +	u32 val; + +	if (is_ecc_enabled()) +		puts(" (ECC"); +	else +		puts(" (ECC not"); + +	get_sys_info(&board_cfg); + +#if defined(CONFIG_405EX) +	val = board_cfg.freqPLB; +#else +	mfsdr(SDR0_DDR0, val); +	val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1); +#endif +	printf(" enabled, %d MHz", (val * 2) / 1000000); + +	mfsdram(SDRAM_MMODE, val); +	val = (val & SDRAM_MMODE_DCL_MASK) >> 4; +	printf(", CL%d)", val); +} +#endif /* !CONFIG_NAND_SPL */ +  #if defined(CONFIG_SPD_EEPROM)  /*-----------------------------------------------------------------------------+ @@ -105,14 +230,10 @@  #define SDRAM_NONE	0  #define MAXDIMMS	2 -#define MAXRANKS	4 -#define MAXBXCF		4  #define MAX_SPD_BYTES	256   /* Max number of bytes on the DIMM's SPD EEPROM */  #define ONE_BILLION	1000000000 -#define MULDIV64(m1, m2, d)	(u32)(((u64)(m1) * (u64)(m2)) / (u64)(d)) -  #define CMD_NOP		(7 << 19)  #define CMD_PRECHARGE	(2 << 19)  #define CMD_REFRESH	(1 << 19) @@ -213,7 +334,6 @@ typedef enum ddr_cas_id {  /*-----------------------------------------------------------------------------+   * Prototypes   *-----------------------------------------------------------------------------*/ -static phys_size_t sdram_memsize(void);  static void get_spd_info(unsigned long *dimm_populated,  			 unsigned char *iic0_dimm_addr,  			 unsigned long num_dimm_banks); @@ -257,15 +377,11 @@ static void program_initplr(unsigned long *dimm_populated,  			    unsigned long num_dimm_banks,  			    ddr_cas_id_t selected_cas,  			    int write_recovery); -static unsigned long is_ecc_enabled(void);  #ifdef CONFIG_DDR_ECC  static void program_ecc(unsigned long *dimm_populated,  			unsigned char *iic0_dimm_addr,  			unsigned long num_dimm_banks,  			unsigned long tlb_word2_i_value); -static void program_ecc_addr(unsigned long start_address, -			     unsigned long num_bytes, -			     unsigned long tlb_word2_i_value);  #endif  #if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)  static void program_DQS_calibration(unsigned long *dimm_populated, @@ -278,7 +394,6 @@ static void	DQS_calibration_process(void);  #endif  #endif  int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -void dcbz_area(u32 start_address, u32 num_bytes);  static unsigned char spd_read(uchar chip, uint addr)  { @@ -292,79 +407,6 @@ static unsigned char spd_read(uchar chip, uint addr)  }  /*-----------------------------------------------------------------------------+ - * sdram_memsize - *-----------------------------------------------------------------------------*/ -static phys_size_t sdram_memsize(void) -{ -	phys_size_t mem_size; -	unsigned long mcopt2; -	unsigned long mcstat; -	unsigned long mb0cf; -	unsigned long sdsz; -	unsigned long i; - -	mem_size = 0; - -	mfsdram(SDRAM_MCOPT2, mcopt2); -	mfsdram(SDRAM_MCSTAT, mcstat); - -	/* DDR controller must be enabled and not in self-refresh. */ -	/* Otherwise memsize is zero. */ -	if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE) -	    && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT) -	    && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK)) -		== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) { -		for (i = 0; i < MAXBXCF; i++) { -			mfsdram(SDRAM_MB0CF + (i << 2), mb0cf); -			/* Banks enabled */ -			if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { -				sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK; - -				switch(sdsz) { -				case SDRAM_RXBAS_SDSZ_8: -					mem_size+=8; -					break; -				case SDRAM_RXBAS_SDSZ_16: -					mem_size+=16; -					break; -				case SDRAM_RXBAS_SDSZ_32: -					mem_size+=32; -					break; -				case SDRAM_RXBAS_SDSZ_64: -					mem_size+=64; -					break; -				case SDRAM_RXBAS_SDSZ_128: -					mem_size+=128; -					break; -				case SDRAM_RXBAS_SDSZ_256: -					mem_size+=256; -					break; -				case SDRAM_RXBAS_SDSZ_512: -					mem_size+=512; -					break; -				case SDRAM_RXBAS_SDSZ_1024: -					mem_size+=1024; -					break; -				case SDRAM_RXBAS_SDSZ_2048: -					mem_size+=2048; -					break; -				case SDRAM_RXBAS_SDSZ_4096: -					mem_size+=4096; -					break; -				default: -					printf("WARNING: Unsupported bank size (SDSZ=0x%lx)!\n" -					       , sdsz); -					mem_size=0; -					break; -				} -			} -		} -	} - -	return mem_size << 20; -} - -/*-----------------------------------------------------------------------------+   * initdram.  Initializes the 440SP Memory Queue and DDR SDRAM controller.   * Note: This routine runs from flash with a stack set up in the chip's   * sram space.  It is important that the routine does not require .sbss, .bss or @@ -643,26 +685,6 @@ static void get_spd_info(unsigned long *dimm_populated,  	}  } -void board_add_ram_info(int use_default) -{ -	PPC4xx_SYS_INFO board_cfg; -	u32 val; - -	if (is_ecc_enabled()) -		puts(" (ECC"); -	else -		puts(" (ECC not"); - -	get_sys_info(&board_cfg); - -	mfsdr(SDR0_DDR0, val); -	val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1); -	printf(" enabled, %d MHz", (val * 2) / 1000000); - -	mfsdram(SDRAM_MMODE, val); -	val = (val & SDRAM_MMODE_DCL_MASK) >> 4; -	printf(", CL%d)", val); -}  /*------------------------------------------------------------------   * For the memory DIMMs installed, this routine verifies that they @@ -2277,25 +2299,6 @@ static void program_memory_queue(unsigned long *dimm_populated,  #endif  } -/*-----------------------------------------------------------------------------+ - * is_ecc_enabled. - *-----------------------------------------------------------------------------*/ -static unsigned long is_ecc_enabled(void) -{ -	unsigned long dimm_num; -	unsigned long ecc; -	unsigned long val; - -	ecc = 0; -	/* loop through all the DIMM slots on the board */ -	for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) { -		mfsdram(SDRAM_MCOPT1, val); -		ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val)); -	} - -	return ecc; -} -  #ifdef CONFIG_DDR_ECC  /*-----------------------------------------------------------------------------+   * program_ecc. @@ -2305,9 +2308,6 @@ static void program_ecc(unsigned long *dimm_populated,  			unsigned long num_dimm_banks,  			unsigned long tlb_word2_i_value)  { -	unsigned long mcopt1; -	unsigned long mcopt2; -	unsigned long mcstat;  	unsigned long dimm_num;  	unsigned long ecc; @@ -2321,105 +2321,7 @@ static void program_ecc(unsigned long *dimm_populated,  	if (ecc == 0)  		return; -	if (sdram_memsize() > CONFIG_MAX_MEM_MAPPED) { -		printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n"); -		return; -	} - -	mfsdram(SDRAM_MCOPT1, mcopt1); -	mfsdram(SDRAM_MCOPT2, mcopt2); - -	if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) { -		/* DDR controller must be enabled and not in self-refresh. */ -		mfsdram(SDRAM_MCSTAT, mcstat); -		if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE) -		    && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT) -		    && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK)) -			== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) { - -			program_ecc_addr(0, sdram_memsize(), tlb_word2_i_value); -		} -	} - -	return; -} - -static void wait_ddr_idle(void) -{ -	u32 val; - -	do { -		mfsdram(SDRAM_MCSTAT, val); -	} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT); -} - -/*-----------------------------------------------------------------------------+ - * program_ecc_addr. - *-----------------------------------------------------------------------------*/ -static void program_ecc_addr(unsigned long start_address, -			     unsigned long num_bytes, -			     unsigned long tlb_word2_i_value) -{ -	unsigned long current_address; -	unsigned long end_address; -	unsigned long address_increment; -	unsigned long mcopt1; -	char str[] = "ECC generation -"; -	char slash[] = "\\|/-\\|/-"; -	int loop = 0; -	int loopi = 0; - -	current_address = start_address; -	mfsdram(SDRAM_MCOPT1, mcopt1); -	if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) { -		mtsdram(SDRAM_MCOPT1, -			(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN); -		sync(); -		eieio(); -		wait_ddr_idle(); - -		puts(str); -		if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) { -			/* ECC bit set method for non-cached memory */ -			if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32) -				address_increment = 4; -			else -				address_increment = 8; -			end_address = current_address + num_bytes; - -			while (current_address < end_address) { -				*((unsigned long *)current_address) = 0x00000000; -				current_address += address_increment; - -				if ((loop++ % (2 << 20)) == 0) { -					putc('\b'); -					putc(slash[loopi++ % 8]); -				} -			} - -		} else { -			/* ECC bit set method for cached memory */ -			dcbz_area(start_address, num_bytes); -			/* Write modified dcache lines back to memory */ -			clean_dcache_range(start_address, start_address + num_bytes); -		} - -		blank_string(strlen(str)); - -		sync(); -		eieio(); -		wait_ddr_idle(); - -		/* clear ECC error repoting registers */ -		mtsdram(SDRAM_ECCCR, 0xffffffff); -		mtdcr(0x4c, 0xffffffff); - -		mtsdram(SDRAM_MCOPT1, -			(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP); -		sync(); -		eieio(); -		wait_ddr_idle(); -	} +	do_program_ecc(tlb_word2_i_value);  }  #endif @@ -3106,7 +3008,7 @@ phys_size_t initdram(int board_type)  #endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */  #if defined(CONFIG_DDR_ECC) -	ecc_init(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20); +	do_program_ecc(0);  #endif /* defined(CONFIG_DDR_ECC) */  #if defined(CONFIG_440) @@ -3183,18 +3085,6 @@ void mtdcr_any(u32 dcr, u32 val)  	}  }  #endif /* defined(CONFIG_440) */ - -void blank_string(int size) -{ -	int i; - -	for (i = 0; i < size; i++) -		putc('\b'); -	for (i = 0; i < size; i++) -		putc(' '); -	for (i = 0; i < size; i++) -		putc('\b'); -}  #endif /* !defined(CONFIG_NAND_U_BOOT) &&  !defined(CONFIG_NAND_SPL) */  inline void ppc4xx_ibm_ddr2_register_dump(void) |