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 n_ranks; 30 u32 datarate_mhz_high; 31 u32 clk_adjust; 32 u32 cpo; 33 u32 write_data_delay; 34 u32 force_2T; 35 }; 36 37 /* 38 * This table contains all valid speeds we want to override with board 39 * specific parameters. datarate_mhz_high values need to be in ascending order 40 * for each n_ranks group. 41 */ 42 static const struct board_specific_parameters udimm0[] = { 43 /* 44 * memory controller 0 45 * num| hi| clk| cpo|wrdata|2T 46 * ranks| mhz|adjst| | delay| 47 */ 48 {2, 300, 4, 4, 2, 0}, 49 {2, 365, 4, 6, 2, 0}, 50 {2, 450, 4, 7, 2, 0}, 51 {2, 850, 4, 31, 2, 0}, 52 {1, 300, 4, 4, 2, 0}, 53 {1, 365, 4, 6, 2, 0}, 54 {1, 450, 4, 7, 2, 0}, 55 {1, 850, 4, 31, 2, 0}, 56 {} 57 }; 58 59 void fsl_ddr_board_options(memctl_options_t *popts, 60 dimm_params_t *pdimm, 61 unsigned int ctrl_num) 62 { 63 const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; 64 unsigned int i; 65 ulong ddr_freq; 66 67 if (ctrl_num != 0) /* we have only one controller */ 68 return; 69 for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 70 if (pdimm[i].n_ranks) 71 break; 72 } 73 if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) /* no DIMM */ 74 return; 75 76 pbsp = udimm0; 77 78 /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr 79 * freqency and n_banks specified in board_specific_parameters table. 80 */ 81 ddr_freq = get_ddr_freq(0) / 1000000; 82 while (pbsp->datarate_mhz_high) { 83 if (pbsp->n_ranks == pdimm[i].n_ranks) { 84 if (ddr_freq <= pbsp->datarate_mhz_high) { 85 popts->clk_adjust = pbsp->clk_adjust; 86 popts->cpo_override = pbsp->cpo; 87 popts->write_data_delay = 88 pbsp->write_data_delay; 89 popts->twoT_en = pbsp->force_2T; 90 goto found; 91 } 92 pbsp_highest = pbsp; 93 } 94 pbsp++; 95 } 96 97 if (pbsp_highest) { 98 printf("Error: board specific timing not found " 99 "for data rate %lu MT/s!\n" 100 "Trying to use the highest speed (%u) parameters\n", 101 ddr_freq, pbsp_highest->datarate_mhz_high); 102 popts->clk_adjust = pbsp_highest->clk_adjust; 103 popts->cpo_override = pbsp_highest->cpo; 104 popts->write_data_delay = pbsp_highest->write_data_delay; 105 popts->twoT_en = pbsp_highest->force_2T; 106 } else { 107 panic("DIMM is not supported by this board"); 108 } 109 110 found: 111 /* 112 * Factors to consider for half-strength driver enable: 113 * - number of DIMMs installed 114 */ 115 popts->half_strength_driver_enable = 0; 116 popts->DQS_config = 0; /* only true DQS signal is used on board */ 117 } 118