diff options
Diffstat (limited to 'cpu/mpc8xxx/ddr/main.c')
| -rw-r--r-- | cpu/mpc8xxx/ddr/main.c | 84 | 
1 files changed, 66 insertions, 18 deletions
| diff --git a/cpu/mpc8xxx/ddr/main.c b/cpu/mpc8xxx/ddr/main.c index ac4b80c3a..f1ad13286 100644 --- a/cpu/mpc8xxx/ddr/main.c +++ b/cpu/mpc8xxx/ddr/main.c @@ -44,10 +44,10 @@ extern void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,   *   * memory controller/documention  |industry   |this code  |signals   * -------------------------------|-----------|-----------|----------------- - * physical bank/bank             |rank       |rank       |chip select (CS) - * logical bank/sub-bank          |bank       |bank       |bank address (BA) - * page/row                       |row        |page       |row address - * ???                            |column     |column     |column address + * physical bank/bank		  |rank       |rank	  |chip select (CS) + * logical bank/sub-bank	  |bank       |bank	  |bank address (BA) + * page/row			  |row	      |page	  |row address + * ???				  |column     |column	  |column address   *   * The naming confusion is further exacerbated by the descriptions of the   * memory controller interleaving feature, where accesses are interleaved @@ -55,24 +55,24 @@ extern void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,   * CS0_CONFIG[INTLV_CTL] of each memory controller.   *   * memory controller documentation | number of chip selects - *                                 | per memory controller supported + *				   | per memory controller supported   * --------------------------------|----------------------------------------- - * cache line interleaving         | 1 (CS0 only) - * page interleaving               | 1 (CS0 only) - * bank interleaving               | 1 (CS0 only) - * superbank interleraving         | depends on bank (chip select) - *                                 |   interleraving [rank interleaving] - *                                 |   mode used on every memory controller + * cache line interleaving	   | 1 (CS0 only) + * page interleaving		   | 1 (CS0 only) + * bank interleaving		   | 1 (CS0 only) + * superbank interleraving	   | depends on bank (chip select) + *				   |   interleraving [rank interleaving] + *				   |   mode used on every memory controller   *   * Even further confusing is the existence of the interleaving feature   * _WITHIN_ each memory controller.  The feature is referred to in   * documentation as chip select interleaving or bank interleaving,   * although it is configured in the DDR_SDRAM_CFG field.   * - * Name of field                | documentation name    | this code + * Name of field		| documentation name	| this code   * -----------------------------|-----------------------|------------------ - * DDR_SDRAM_CFG[BA_INTLV_CTL]  | Bank (chip select)    | rank interleaving - *                              |  interleaving + * DDR_SDRAM_CFG[BA_INTLV_CTL]	| Bank (chip select)	| rank interleaving + *				|  interleaving   */  #ifdef DEBUG @@ -164,6 +164,24 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,  	}  	if (j == 2) {  		*memctl_interleaving = 1; + +		printf("\nMemory controller interleaving enabled: "); + +		switch (pinfo->memctl_opts[0].memctl_interleaving_mode) { +		case FSL_DDR_CACHE_LINE_INTERLEAVING: +			printf("Cache-line interleaving!\n"); +			break; +		case FSL_DDR_PAGE_INTERLEAVING: +			printf("Page interleaving!\n"); +			break; +		case FSL_DDR_BANK_INTERLEAVING: +			printf("Bank interleaving!\n"); +			break; +		case FSL_DDR_SUPERBANK_INTERLEAVING: +			printf("Super bank interleaving\n"); +		default: +			break; +		}  	}  	/* Check that all controllers are rank interleaving. */ @@ -175,10 +193,30 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,  	}  	if (j == 2) {  		*rank_interleaving = 1; + +		printf("Bank(chip-select) interleaving enabled: "); + +		switch (pinfo->memctl_opts[0].ba_intlv_ctl & +						FSL_DDR_CS0_CS1_CS2_CS3) { +		case FSL_DDR_CS0_CS1_CS2_CS3: +			printf("CS0+CS1+CS2+CS3\n"); +			break; +		case FSL_DDR_CS0_CS1: +			printf("CS0+CS1\n"); +			break; +		case FSL_DDR_CS2_CS3: +			printf("CS2+CS3\n"); +			break; +		case FSL_DDR_CS0_CS1_AND_CS2_CS3: +			printf("CS0+CS1 and CS2+CS3\n"); +		default: +			break; +		}  	}  	if (*memctl_interleaving) {  		phys_addr_t addr; +		phys_size_t total_mem_per_ctlr = 0;  		/*  		 * If interleaving between memory controllers, @@ -197,14 +235,18 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,  		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {  			addr = 0; +			pinfo->common_timing_params[i].base_address = +						(phys_addr_t)addr;  			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {  				unsigned long long cap  					= pinfo->dimm_params[i][j].capacity;  				pinfo->dimm_params[i][j].base_address = addr;  				addr += (phys_addr_t)(cap >> dbw_cap_adj[i]); +				total_mem_per_ctlr += cap >> dbw_cap_adj[i];  			}  		} +		pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr;  	} else {  		/*  		 * Simple linear assignment if memory @@ -270,7 +312,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)  				generic_spd_eeprom_t *spd =  					&(pinfo->spd_installed_dimms[i][j]);  				dimm_params_t *pdimm = -                                        &(pinfo->dimm_params[i][j]); +					&(pinfo->dimm_params[i][j]);  				retval = compute_dimm_parameters(spd, pdimm, i);  				if (retval == 2) { @@ -314,7 +356,8 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)  			 */  			populate_memctl_options(  					timing_params[i].all_DIMMs_registered, -					&pinfo->memctl_opts[i], i); +					&pinfo->memctl_opts[i], +					pinfo->dimm_params[i], i);  		}  	case STEP_ASSIGN_ADDRESSES: @@ -432,9 +475,14 @@ phys_size_t fsl_ddr_sdram(void)  			 */  			memctl_interleaved = 1;  		} else { -			printf("Error: memctl interleaving not " +			printf("Warning: memctl interleaving not "  				"properly configured on all controllers\n"); -			while (1); +			memctl_interleaved = 0; +			for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) +				info.memctl_opts[i].memctl_interleaving = 0; +			debug("Recomputing with memctl_interleaving off.\n"); +			total_memory = fsl_ddr_compute(&info, +						       STEP_ASSIGN_ADDRESSES);  		}  	} |