diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc8xxx/ddr/main.c')
| -rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/main.c | 65 | 
1 files changed, 56 insertions, 9 deletions
| diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index 7a8636de1..842bf1989 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -25,10 +25,6 @@ void fsl_ddr_set_lawbar(  		unsigned int ctrl_num);  void fsl_ddr_set_intl3r(const unsigned int granule_size); -/* processor specific function */ -extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, -				   unsigned int ctrl_num); -  #if defined(SPD_EEPROM_ADDRESS) || \      defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \      defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4) @@ -365,9 +361,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,  {  	unsigned int i, j;  	unsigned long long total_mem = 0; +	int assert_reset;  	fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;  	common_timing_params_t *timing_params = pinfo->common_timing_params; +	assert_reset = board_need_mem_reset();  	/* data bus width capacity adjust shift amount */  	unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS]; @@ -462,7 +460,20 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,  					timing_params[i].all_DIMMs_registered,  					&pinfo->memctl_opts[i],  					pinfo->dimm_params[i], i); +			/* +			 * For RDIMMs, JEDEC spec requires clocks to be stable +			 * before reset signal is deasserted. For the boards +			 * using fixed parameters, this function should be +			 * be called from board init file. +			 */ +			if (timing_params[i].all_DIMMs_registered) +				assert_reset = 1;  		} +		if (assert_reset) { +			debug("Asserting mem reset\n"); +			board_assert_mem_reset(); +		} +  	case STEP_ASSIGN_ADDRESSES:  		/* STEP 5:  Assign addresses to chip selects */  		check_interleaving_options(pinfo); @@ -504,7 +515,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,  				fsl_ddr_cfg_regs_t *reg = &ddr_reg[i];  				if (reg->cs[j].config & 0x80000000) {  					unsigned int end; -					end = reg->cs[j].bnds & 0xFFF; +					/* +					 * 0xfffffff is a special value we put +					 * for unused bnds +					 */ +					if (reg->cs[j].bnds == 0xffffffff) +						continue; +					end = reg->cs[j].bnds & 0xffff;  					if (end > max_end) {  						max_end = end;  					} @@ -531,6 +548,7 @@ phys_size_t fsl_ddr_sdram(void)  	unsigned int law_memctl = LAW_TRGT_IF_DDR_1;  	unsigned long long total_memory;  	fsl_ddr_info_t info; +	int deassert_reset;  	/* Reset info structure. */  	memset(&info, 0, sizeof(fsl_ddr_info_t)); @@ -559,7 +577,21 @@ phys_size_t fsl_ddr_sdram(void)  		}  	} -	/* Program configuration registers. */ +	/* +	 * Program configuration registers. +	 * JEDEC specs requires clocks to be stable before deasserting reset +	 * for RDIMMs. Clocks start after chip select is enabled and clock +	 * control register is set. During step 1, all controllers have their +	 * registers set but not enabled. Step 2 proceeds after deasserting +	 * reset through board FPGA or GPIO. +	 * For non-registered DIMMs, initialization can go through but it is +	 * also OK to follow the same flow. +	 */ +	deassert_reset = board_need_mem_reset(); +	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { +		if (info.common_timing_params[i].all_DIMMs_registered) +			deassert_reset = 1; +	}  	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {  		debug("Programming controller %u\n", i);  		if (info.common_timing_params[i].ndimms_present == 0) { @@ -567,8 +599,22 @@ phys_size_t fsl_ddr_sdram(void)  					"skipping programming\n", i);  			continue;  		} - -		fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i); +		/* +		 * The following call with step = 1 returns before enabling +		 * the controller. It has to finish with step = 2 later. +		 */ +		fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i, +					deassert_reset ? 1 : 0); +	} +	if (deassert_reset) { +		/* Use board FPGA or GPIO to deassert reset signal */ +		debug("Deasserting mem reset\n"); +		board_deassert_mem_reset(); +		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { +			/* Call with step = 2 to continue initialization */ +			fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), +						i, 2); +		}  	}  	/* program LAWs */ @@ -637,7 +683,8 @@ phys_size_t fsl_ddr_sdram(void)  #if !defined(CONFIG_PHYS_64BIT)  	/* Check for 4G or more.  Bad. */  	if (total_memory >= (1ull << 32)) { -		printf("Detected %lld MB of memory\n", total_memory >> 20); +		puts("Detected "); +		print_size(total_memory, " of memory\n");  		printf("       This U-Boot only supports < 4G of DDR\n");  		printf("       You could rebuild it with CONFIG_PHYS_64BIT\n");  		printf("       "); /* re-align to match init_func_ram print */ |