1 /* 2 * Copyright 2011 Freescale Semiconductor, Inc. 3 * 4 * See file CREDITS for list of people who contributed to this 5 * project. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23 #include <common.h> 24 25 #include <asm/fsl_ddr_sdram.h> 26 #include <asm/fsl_ddr_dimm_params.h> 27 28 struct board_specific_parameters { 29 u32 datarate_mhz_low; 30 u32 datarate_mhz_high; 31 u32 n_ranks; 32 u32 clk_adjust; 33 u32 cpo; 34 u32 write_data_delay; 35 u32 force_2T; 36 }; 37 38 const struct board_specific_parameters board_specific_parameters_udimm[][20] = { 39 { 40 /* 41 * memory controller 0 42 * lo| hi| num| clk| cpo|wrdata|2T 43 * mhz| mhz|ranks|adjst| | delay| 44 */ 45 { 0, 300, 2, 4, 4, 2, 0}, 46 {301, 365, 2, 4, 6, 2, 0}, 47 {366, 450, 2, 4, 7, 2, 0}, 48 {451, 850, 2, 4, 31, 2, 0}, 49 { 0, 300, 1, 4, 4, 2, 0}, 50 {301, 365, 1, 4, 6, 2, 0}, 51 {366, 450, 1, 4, 7, 2, 0}, 52 {451, 850, 1, 4, 31, 2, 0} 53 } 54 }; 55 56 void fsl_ddr_board_options(memctl_options_t *popts, 57 dimm_params_t *pdimm, 58 unsigned int ctrl_num) 59 { 60 const struct board_specific_parameters *pbsp; 61 u32 num_params; 62 u32 i, dimm_num; 63 ulong ddr_freq; 64 65 if (ctrl_num != 0) /* we have only one controller */ 66 return; 67 for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 68 if (pdimm[i].n_ranks) 69 break; 70 } 71 if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) /* no DIMM */ 72 return; 73 74 dimm_num = i; 75 pbsp = &(board_specific_parameters_udimm[ctrl_num][0]); 76 num_params = sizeof(board_specific_parameters_udimm[ctrl_num]) / 77 sizeof(board_specific_parameters_udimm[0][0]); 78 79 /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr 80 * freqency and n_banks specified in board_specific_parameters table. 81 */ 82 ddr_freq = get_ddr_freq(0) / 1000000; 83 for (i = 0; i < num_params; i++) { 84 if (ddr_freq >= pbsp->datarate_mhz_low && 85 ddr_freq <= pbsp->datarate_mhz_high && 86 pdimm[dimm_num].n_ranks == pbsp->n_ranks) { 87 popts->clk_adjust = pbsp->clk_adjust; 88 popts->cpo_override = pbsp->cpo; 89 popts->write_data_delay = pbsp->write_data_delay; 90 popts->twoT_en = pbsp->force_2T; 91 break; 92 } 93 pbsp++; 94 } 95 96 if (i == num_params) { 97 printf("Warning: board specific timing not found " 98 "for data rate %lu MT/s!\n", ddr_freq); 99 } 100 101 /* 102 * Factors to consider for half-strength driver enable: 103 * - number of DIMMs installed 104 */ 105 popts->half_strength_driver_enable = 0; 106 popts->DQS_config = 0; /* only true DQS signal is used on board */ 107 } 108